From arigo at codespeak.net Sat Aug 1 16:32:48 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Aug 2009 16:32:48 +0200 (CEST) Subject: [pypy-svn] r66721 - pypy/branch/pyjitpl5/pypy/jit/tl/tla Message-ID: <20090801143248.40583169E1F@codespeak.net> Author: arigo Date: Sat Aug 1 16:32:47 2009 New Revision: 66721 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tla/ (props changed) Log: fixeol From arigo at codespeak.net Sat Aug 1 16:37:44 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Aug 2009 16:37:44 +0200 (CEST) Subject: [pypy-svn] r66722 - in pypy/branch/pyjitpl5/pypy: jit/backend/llgraph jit/backend/x86/test jit/metainterp/test module/pypyjit module/signal rpython/lltypesystem translator/c/src Message-ID: <20090801143744.B20CD169E0C@codespeak.net> Author: arigo Date: Sat Aug 1 16:37:44 2009 New Revision: 66722 Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_del.py (contents, props changed) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rffi.py pypy/branch/pyjitpl5/pypy/translator/c/src/signals.h Log: Improve the code generated for ActionFlag().get() and set(), at the end of every loop in the case of PyPy. Now we generate just a "getfield_raw(Const(...), 'value')" instead of a whole "call". Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 1 16:37:44 2009 @@ -616,7 +616,7 @@ def op_getfield_raw(self, fielddescr, struct): if fielddescr.typeinfo == 'p': - return do_getfield_raw_ptr(struct, fielddescr.ofs) + return do_getfield_raw_ptr(struct, fielddescr.ofs, self.memocast) else: return do_getfield_raw_int(struct, fielddescr.ofs, self.memocast) @@ -646,7 +646,8 @@ def op_setfield_raw(self, fielddescr, struct, newvalue): if fielddescr.typeinfo == 'p': - do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) + do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, + self.memocast) else: do_setfield_raw_int(struct, fielddescr.ofs, newvalue, self.memocast) @@ -793,10 +794,17 @@ def cast_from_int(TYPE, x, memocast): if isinstance(TYPE, lltype.Ptr): - return llmemory.cast_adr_to_ptr(cast_int_to_adr(memocast, x), TYPE) + if isinstance(x, (int, long)): + x = cast_int_to_adr(memocast, x) + return llmemory.cast_adr_to_ptr(x, TYPE) elif TYPE == llmemory.Address: - return cast_int_to_adr(memocast, x) + if isinstance(x, (int, long)): + x = cast_int_to_adr(memocast, x) + assert lltype.typeOf(x) == llmemory.Address + return x else: + if lltype.typeOf(x) == llmemory.Address: + x = cast_adr_to_int(memocast, x) return lltype.cast_primitive(TYPE, x) def cast_to_ptr(x): @@ -1001,13 +1009,13 @@ def do_getfield_raw_int(struct, fieldnum, memocast): STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = llmemory.cast_adr_to_ptr(struct, lltype.Ptr(STRUCT)) + ptr = cast_from_int(lltype.Ptr(STRUCT), struct, memocast) x = getattr(ptr, fieldname) return cast_to_int(x, memocast) -def do_getfield_raw_ptr(struct, fieldnum): +def do_getfield_raw_ptr(struct, fieldnum, memocast): STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = llmemory.cast_adr_to_ptr(struct, lltype.Ptr(STRUCT)) + ptr = cast_from_int(lltype.Ptr(STRUCT), struct, memocast) x = getattr(ptr, fieldname) return cast_to_ptr(x) @@ -1049,14 +1057,14 @@ def do_setfield_raw_int(struct, fieldnum, newvalue, memocast): STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = llmemory.cast_adr_to_ptr(struct, lltype.Ptr(STRUCT)) + ptr = cast_from_int(lltype.Ptr(STRUCT), struct, memocast) FIELDTYPE = getattr(STRUCT, fieldname) newvalue = cast_from_int(FIELDTYPE, newvalue, memocast) setattr(ptr, fieldname, newvalue) -def do_setfield_raw_ptr(struct, fieldnum, newvalue): +def do_setfield_raw_ptr(struct, fieldnum, newvalue, memocast): STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = llmemory.cast_adr_to_ptr(struct, lltype.Ptr(STRUCT)) + ptr = cast_from_int(lltype.Ptr(STRUCT), struct, memocast) FIELDTYPE = getattr(STRUCT, fieldname) newvalue = cast_from_ptr(FIELDTYPE, newvalue) setattr(ptr, fieldname, newvalue) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Sat Aug 1 16:37:44 2009 @@ -324,7 +324,8 @@ struct = self.cast_int_to_adr(args[0].getint()) if fielddescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getfield_raw_ptr(struct, - fielddescr.ofs)) + fielddescr.ofs, + self.memo_cast)) else: return history.BoxInt(llimpl.do_getfield_raw_int(struct, fielddescr.ofs, @@ -376,7 +377,8 @@ struct = self.cast_int_to_adr(args[0].getint()) if fielddescr.typeinfo == 'p': newvalue = args[1].getptr_base() - llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) + llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, + self.memo_cast) else: newvalue = args[1].getint() llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue, Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_del.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_del.py Sat Aug 1 16:37:44 2009 @@ -0,0 +1,9 @@ + +import py +from pypy.jit.backend.x86.test.test_basic import Jit386Mixin +from pypy.jit.metainterp.test.test_del import DelTests + +class TestDel(Jit386Mixin, DelTests): + # for the individual tests see + # ====> ../../../metainterp/test/test_del.py + pass Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py Sat Aug 1 16:37:44 2009 @@ -26,6 +26,22 @@ 'guard_true': 1, 'jump': 1}) + def test_signal_action(self): + from pypy.module.signal.interp_signal import SignalActionFlag + action = SignalActionFlag() + # + myjitdriver = JitDriver(greens = [], reds = ['n']) + # + def f(n): + while n > 0: + myjitdriver.can_enter_jit(n=n) + myjitdriver.jit_merge_point(n=n) + n -= 1 + if action.get() != 0: + break + self.meta_interp(f, [20]) + self.check_loops(getfield_raw=1, call=0, call_pure=0) + class TestLLtype(DelTests, LLJitMixin): pass Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py Sat Aug 1 16:37:44 2009 @@ -47,6 +47,7 @@ return False if mod.startswith('pypy.module.'): if (not mod.startswith('pypy.module.pypyjit.') and + not mod.startswith('pypy.module.signal.') and not mod.startswith('pypy.module.micronumpy.')): return False Modified: pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py (original) +++ pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py Sat Aug 1 16:37:44 2009 @@ -25,7 +25,7 @@ include_dirs = [str(py.path.local(autopath.pypydir).join('translator', 'c'))], export_symbols = ['pypysig_poll', 'pypysig_default', 'pypysig_ignore', 'pypysig_setflag', - 'pypysig_get_occurred', 'pypysig_set_occurred'], + 'pypysig_getaddr_occurred'], ) def external(name, args, result, **kwds): @@ -38,17 +38,23 @@ # don't bother releasing the GIL around a call to pypysig_poll: it's # pointless and a performance issue -pypysig_get_occurred = external('pypysig_get_occurred', [], - lltype.Signed, _nowrapper=True) -pypysig_set_occurred = external('pypysig_set_occurred', [lltype.Signed], - lltype.Void, _nowrapper=True) +# don't use rffi.LONGP because the JIT doesn't support raw arrays so far +LONG_STRUCT = lltype.Struct('LONG_STRUCT', ('value', lltype.Signed)) + +pypysig_getaddr_occurred = external('pypysig_getaddr_occurred', [], + lltype.Ptr(LONG_STRUCT), _nowrapper=True, + pure_function=True) c_alarm = external('alarm', [rffi.INT], rffi.INT) c_pause = external('pause', [], rffi.INT) class SignalActionFlag(AbstractActionFlag): - get = staticmethod(pypysig_get_occurred) - set = staticmethod(pypysig_set_occurred) + def get(self): + p = pypysig_getaddr_occurred() + return p.value + def set(self, value): + p = pypysig_getaddr_occurred() + p.value = value class CheckSignalAction(AsyncAction): Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rffi.py Sat Aug 1 16:37:44 2009 @@ -58,7 +58,7 @@ compilation_info=ExternalCompilationInfo(), sandboxsafe=False, threadsafe='auto', canraise=False, _nowrapper=False, calling_conv='c', - oo_primitive=None): + oo_primitive=None, pure_function=False): """Build an external function that will invoke the C function 'name' with the given 'args' types and 'result' type. @@ -79,6 +79,8 @@ ext_type = lltype.FuncType(args, result) if _callable is None: _callable = ll2ctypes.LL2CtypesCallable(ext_type, calling_conv) + if pure_function: + _callable._pure_function_ = True kwds = {} if oo_primitive: kwds['oo_primitive'] = oo_primitive Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/signals.h ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/src/signals.h (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/src/signals.h Sat Aug 1 16:37:44 2009 @@ -75,16 +75,12 @@ /* some C tricks to get/set the variable as efficiently as possible: use macros when compiling as a stand-alone program, but still export a function with the correct name for testing */ -#undef pypysig_get_occurred -#undef pypysig_set_occurred -long pypysig_get_occurred(void); -void pypysig_set_occurred(long x); +#undef pypysig_getaddr_occurred +char *pypysig_getaddr_occurred(void); #ifndef PYPY_NOT_MAIN_FILE -long pypysig_get_occurred(void) { return pypysig_occurred; } -void pypysig_set_occurred(long x) { pypysig_occurred = x; } +char *pypysig_getaddr_occurred(void) { return &pypysig_occurred; } #endif -#define pypysig_get_occurred() (pypysig_occurred) -#define pypysig_set_occurred(x) (pypysig_occurred=(x)) +#define pypysig_getaddr_occurred() ((char *)(&pypysig_occurred)) /************************************************************/ /* Implementation */ From arigo at codespeak.net Sat Aug 1 18:04:02 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Aug 2009 18:04:02 +0200 (CEST) Subject: [pypy-svn] r66723 - in pypy/branch/pyjitpl5/pypy/jit: backend/x86 backend/x86/test metainterp/test Message-ID: <20090801160402.0C93216854F@codespeak.net> Author: arigo Date: Sat Aug 1 18:04:01 2009 New Revision: 66723 Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_del.py (contents, props changed) pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_del.py (contents, props changed) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py Log: Tests and fix -- actually the x86 backend did not handle setfield_raw fully. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sat Aug 1 18:04:01 2009 @@ -1010,8 +1010,12 @@ self.eventually_free_vars(op.args) self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc]) - #def consider_setfield_raw(...): - # like consider_setfield_gc(), except without write barrier support + def consider_setfield_raw(self, op, ignored): + base_loc = self.make_sure_var_in_reg(op.args[0], op.args) + value_loc = self.make_sure_var_in_reg(op.args[1], op.args) + ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) + self.eventually_free_vars(op.args) + self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc]) def consider_strsetitem(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Sat Aug 1 18:04:01 2009 @@ -495,6 +495,8 @@ v = rffi.cast(rffi.USHORT, vbox.getint()) rffi.cast(rffi.CArrayPtr(rffi.USHORT), gcref)[ofs/2] = v elif size == WORD: + if lltype.typeOf(gcref) is lltype.Signed: + ptr = False # xxx can't handle write barriers for setfield_raw if ptr: ptr = vbox.getptr(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_del.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_del.py Sat Aug 1 18:04:01 2009 @@ -0,0 +1,9 @@ + +import py +from pypy.jit.metainterp.test import test_zrpy_del +from pypy.jit.backend.x86.test.test_zrpy_slist import Jit386Mixin + +class TestDel(Jit386Mixin, test_zrpy_del.TestLLDels): + # for the individual tests see + # ====> ../../../metainterp/test/test_del.py + pass Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py Sat Aug 1 18:04:01 2009 @@ -18,6 +18,7 @@ x = Foo() Foo() n -= 1 + return 42 self.meta_interp(f, [20]) self.check_loops({'call': 2, # calls to a helper function 'guard_no_exception': 2, # follows the calls @@ -30,15 +31,21 @@ from pypy.module.signal.interp_signal import SignalActionFlag action = SignalActionFlag() # - myjitdriver = JitDriver(greens = [], reds = ['n']) + myjitdriver = JitDriver(greens = [], reds = ['n', 'x']) + class X: + pass # def f(n): + x = X() while n > 0: - myjitdriver.can_enter_jit(n=n) - myjitdriver.jit_merge_point(n=n) + myjitdriver.can_enter_jit(n=n, x=x) + myjitdriver.jit_merge_point(n=n, x=x) + x.foo = n n -= 1 if action.get() != 0: break + action.set(0) + return 42 self.meta_interp(f, [20]) self.check_loops(getfield_raw=1, call=0, call_pure=0) Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_del.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_del.py Sat Aug 1 18:04:01 2009 @@ -0,0 +1,7 @@ +import py +from pypy.jit.metainterp.test import test_del +from pypy.jit.metainterp.test.test_zrpy_basic import LLInterpJitMixin + +class TestLLDels(test_del.DelTests, LLInterpJitMixin): + pass + # ==========> test_del.py From arigo at codespeak.net Sat Aug 1 20:27:22 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Aug 2009 20:27:22 +0200 (CEST) Subject: [pypy-svn] r66724 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090801182722.5833D169E0A@codespeak.net> Author: arigo Date: Sat Aug 1 20:27:20 2009 New Revision: 66724 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py Log: * Very minor space saving. * Update the TODO about the need for major space savings here. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO Sat Aug 1 20:27:20 2009 @@ -8,6 +8,6 @@ * long term: memory management of the compiled code (free old code) -* 'resume_info' should be shared (see pyjitpl.py) +* save space on all the guard operations (see resume.py) * support threads again Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py Sat Aug 1 20:27:20 2009 @@ -78,7 +78,7 @@ self._make_virtual(virtualbox, vinfo, fieldboxes) def make_varray(self, virtualbox, arraydescr, itemboxes): - vinfo = VArrayInfo(arraydescr, len(itemboxes)) + vinfo = VArrayInfo(arraydescr) self._make_virtual(virtualbox, vinfo, itemboxes) def _make_virtual(self, virtualbox, vinfo, fieldboxes): @@ -167,18 +167,18 @@ descr=self.typedescr) class VArrayInfo(AbstractVirtualInfo): - def __init__(self, arraydescr, length): + def __init__(self, arraydescr): self.arraydescr = arraydescr - self.length = length #self.fieldnums = ... def allocate(self, metainterp): + length = len(self.fieldnums) return metainterp.execute_and_record(rop.NEW_ARRAY, - [ConstInt(self.length)], + [ConstInt(length)], descr=self.arraydescr) def setfields(self, metainterp, box, fn_decode_box): - for i in range(self.length): + for i in range(len(self.fieldnums)): itembox = fn_decode_box(self.fieldnums[i]) metainterp.execute_and_record(rop.SETARRAYITEM_GC, [box, ConstInt(i), itembox], From arigo at codespeak.net Sat Aug 1 20:48:08 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Aug 2009 20:48:08 +0200 (CEST) Subject: [pypy-svn] r66725 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090801184808.E14B816840E@codespeak.net> Author: arigo Date: Sat Aug 1 20:48:08 2009 New Revision: 66725 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py Log: Update TODO. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO Sat Aug 1 20:48:08 2009 @@ -2,9 +2,7 @@ * support floats -* fix bugs in virtualizables, but think first - -* kill empty pairs setup_exception_block/teardown_exception_block +* virtualizables: fix 'test_external_read_sometimes' * long term: memory management of the compiled code (free old code) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py Sat Aug 1 20:48:08 2009 @@ -7,7 +7,7 @@ # because it needs to support optimize.py which encodes virtuals with # arbitrary cycles. -# XXX I guess that building the data so that it is compact as possible +# XXX I guess that building the data so that it is as compact as possible # on the 'storage' object would be a big win. From arigo at codespeak.net Sun Aug 2 12:48:34 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Aug 2009 12:48:34 +0200 (CEST) Subject: [pypy-svn] r66726 - in pypy/branch/pyjitpl5/pypy/jit/backend: test x86 Message-ID: <20090802104834.15FCA168471@codespeak.net> Author: arigo Date: Sun Aug 2 12:48:33 2009 New Revision: 66726 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: Fix backend/x86/test/test_operations. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Sun Aug 2 12:48:33 2009 @@ -739,7 +739,7 @@ descrfld_y) assert s.y == a # - RS = lltype.Struct('S', ('x', lltype.Char), ('y', lltype.Ptr(A))) + RS = lltype.Struct('S', ('x', lltype.Char)) #, ('y', lltype.Ptr(A))) descrfld_rx = cpu.fielddescrof(RS, 'x') rs = lltype.malloc(RS, immortal=True) rs.x = '?' @@ -754,19 +754,21 @@ descrfld_rx) assert rs.x == '!' # - descrfld_ry = cpu.fielddescrof(RS, 'y') - rs.y = a - x = cpu.do_getfield_raw( - [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], - descrfld_ry) - assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a - # - rs.y = lltype.nullptr(A) - cpu.do_setfield_raw( - [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), x], - descrfld_ry) - assert rs.y == a + ### we don't support in the JIT for now GC pointers + ### stored inside non-GC structs. + #descrfld_ry = cpu.fielddescrof(RS, 'y') + #rs.y = a + #x = cpu.do_getfield_raw( + # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], + # descrfld_ry) + #assert isinstance(x, BoxPtr) + #assert x.getptr(lltype.Ptr(A)) == a + # + #rs.y = lltype.nullptr(A) + #cpu.do_setfield_raw( + # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), x], + # descrfld_ry) + #assert rs.y == a # descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Sun Aug 2 12:48:33 2009 @@ -495,9 +495,9 @@ v = rffi.cast(rffi.USHORT, vbox.getint()) rffi.cast(rffi.CArrayPtr(rffi.USHORT), gcref)[ofs/2] = v elif size == WORD: - if lltype.typeOf(gcref) is lltype.Signed: - ptr = False # xxx can't handle write barriers for setfield_raw if ptr: + assert lltype.typeOf(gcref) is not lltype.Signed, ( + "can't handle write barriers for setfield_raw") ptr = vbox.getptr(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) From arigo at codespeak.net Sun Aug 2 13:05:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Aug 2009 13:05:25 +0200 (CEST) Subject: [pypy-svn] r66727 - pypy/trunk/pypy/objspace/std/test Message-ID: <20090802110525.AC3F6168458@codespeak.net> Author: arigo Date: Sun Aug 2 13:05:23 2009 New Revision: 66727 Modified: pypy/trunk/pypy/objspace/std/test/test_shadowtracking.py Log: Improve reporting of the error, in an attempt to figure out what the rare problem is. Modified: pypy/trunk/pypy/objspace/std/test/test_shadowtracking.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_shadowtracking.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_shadowtracking.py Sun Aug 2 13:05:23 2009 @@ -210,7 +210,7 @@ for name in names] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): - assert count[0] >= 5 + assert count[0] >= 5, str((name, count)) def test_mutating_bases(self): class C(object): From arigo at codespeak.net Sun Aug 2 18:56:46 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Aug 2009 18:56:46 +0200 (CEST) Subject: [pypy-svn] r66728 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090802165646.323A3168458@codespeak.net> Author: arigo Date: Sun Aug 2 18:56:44 2009 New Revision: 66728 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_resume.py Log: * Dumping of all the storage.rd_xxx attributes. * Use None instead of a new empty list for rd_virtuals. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resume.py Sun Aug 2 18:56:44 2009 @@ -10,6 +10,8 @@ # XXX I guess that building the data so that it is as compact as possible # on the 'storage' object would be a big win. +debug = False + class ResumeDataBuilder(object): @@ -44,6 +46,8 @@ storage.rd_nums = self.nums[:] storage.rd_consts = self.consts[:] storage.rd_virtuals = None + if debug: + dump_storage(storage) return self.liveboxes @@ -109,12 +113,16 @@ if num >= 0: box = self.original_liveboxes[num] storage.rd_nums[i] = self._getboxindex(box) - storage.rd_virtuals = self.virtuals[:] - for i in range(len(storage.rd_virtuals)): - vinfo = storage.rd_virtuals[i] - fieldboxes = self.vfieldboxes[i] - vinfo.fieldnums = [self._getboxindex(box) for box in fieldboxes] + if len(self.virtuals) > 0: + storage.rd_virtuals = self.virtuals[:] + for i in range(len(storage.rd_virtuals)): + vinfo = storage.rd_virtuals[i] + fieldboxes = self.vfieldboxes[i] + vinfo.fieldnums = [self._getboxindex(box) + for box in fieldboxes] storage.rd_consts = self.consts[:] + if debug: + dump_storage(storage) return liveboxes def _getboxindex(self, box): @@ -157,6 +165,12 @@ return metainterp.execute_and_record(rop.NEW_WITH_VTABLE, [self.known_class]) + def repr_rpython(self): + return 'VirtualInfo("%s", %s, %s)' % ( + self.known_class, + ['"%s"' % (fd,) for fd in self.fielddescrs], + self.fieldnums) + class VStructInfo(AbstractVirtualStructInfo): def __init__(self, typedescr, fielddescrs): AbstractVirtualStructInfo.__init__(self, fielddescrs) @@ -166,6 +180,12 @@ return metainterp.execute_and_record(rop.NEW, [], descr=self.typedescr) + def repr_rpython(self): + return 'VStructInfo("%s", %s, %s)' % ( + self.typedescr, + ['"%s"' % (fd,) for fd in self.fielddescrs], + self.fieldnums) + class VArrayInfo(AbstractVirtualInfo): def __init__(self, arraydescr): self.arraydescr = arraydescr @@ -184,6 +204,10 @@ [box, ConstInt(i), itembox], descr=self.arraydescr) + def repr_rpython(self): + return 'VArrayInfo("%s", %s)' % (self.arraydescr, + self.fieldnums) + class ResumeDataReader(object): i_frame_infos = 0 @@ -231,3 +255,24 @@ frame_info = self.frame_infos[self.i_frame_infos] self.i_frame_infos += 1 return frame_info + +# ____________________________________________________________ + +def dump_storage(storage): + "For profiling only." + import os + from pypy.rlib import objectmodel + fd = os.open('log.storage', os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0666) + os.write(fd, 'Log(%d, [\n' % objectmodel.compute_unique_id(storage)) + for frame_info in storage.rd_frame_infos: + os.write(fd, '\t("%s", %d, %d),\n' % frame_info) + os.write(fd, '\t],\n\t%s,\n' % (storage.rd_nums,)) + os.write(fd, '\t[\n') + for const in storage.rd_consts: + os.write(fd, '\t"%s",\n' % (const.repr_rpython(),)) + os.write(fd, '\t], [\n') + if storage.rd_virtuals is not None: + for virtual in storage.rd_virtuals: + os.write(fd, '\t%s,\n' % (virtual.repr_rpython(),)) + os.write(fd, '\t])\n') + os.close(fd) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_resume.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_resume.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_resume.py Sun Aug 2 18:56:44 2009 @@ -42,18 +42,18 @@ storage = Storage() # builder = ResumeDataBuilder() - builder.generate_frame_info(1, 2) - builder.generate_frame_info(3, 4) + builder.generate_frame_info(1, 2, 5) + builder.generate_frame_info(3, 4, 7) liveboxes = builder.finish(storage) assert liveboxes == [] # reader = ResumeDataReader(storage, liveboxes) assert reader.has_more_frame_infos() fi = reader.consume_frame_info() - assert fi == (1, 2) + assert fi == (1, 2, 5) assert reader.has_more_frame_infos() fi = reader.consume_frame_info() - assert fi == (3, 4) + assert fi == (3, 4, 7) assert not reader.has_more_frame_infos() From fijal at codespeak.net Mon Aug 3 14:09:47 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 3 Aug 2009 14:09:47 +0200 (CEST) Subject: [pypy-svn] r66729 - in pypy/trunk/pypy/translator/c: . test Message-ID: <20090803120947.0BBE8168411@codespeak.net> Author: fijal Date: Mon Aug 3 14:09:46 2009 New Revision: 66729 Modified: pypy/trunk/pypy/translator/c/dlltool.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/test/test_dlltool.py Log: A bit of logic that makes targets built using dlltool to be standalone Modified: pypy/trunk/pypy/translator/c/dlltool.py ============================================================================== --- pypy/trunk/pypy/translator/c/dlltool.py (original) +++ pypy/trunk/pypy/translator/c/dlltool.py Mon Aug 3 14:09:46 2009 @@ -6,6 +6,7 @@ class CLibraryBuilder(CBuilder): standalone = False + split = True def __init__(self, *args, **kwds): self.functions = kwds.pop('functions') Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Mon Aug 3 14:09:46 2009 @@ -101,6 +101,7 @@ c_source_filename = None _compiled = False modulename = None + split = False def __init__(self, translator, entrypoint, config, gcpolicy=None): self.translator = translator @@ -231,7 +232,8 @@ assert not self.config.translation.instrument self.eci, cfile, extra = gen_source(db, modulename, targetdir, self.eci, - defines = defines) + defines = defines, + split=self.split) else: pfname = db.get(pf) if self.config.translation.instrument: @@ -428,9 +430,10 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args=''): + def cmdexec(self, args='', env=None): assert self._compiled - res = self.translator.platform.execute(self.executable_name, args) + res = self.translator.platform.execute(self.executable_name, args, + env=env) if res.returncode != 0: raise Exception("Returned %d" % (res.returncode,)) return res.out @@ -515,7 +518,7 @@ self.path = None self.namespace = NameManager() - def set_strategy(self, path): + def set_strategy(self, path, split=True): all_nodes = list(self.database.globalcontainers()) # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] @@ -526,7 +529,8 @@ else: othernodes.append(node) # for now, only split for stand-alone programs. - if self.database.standalone: + #if self.database.standalone: + if split: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes @@ -817,7 +821,7 @@ files, eci = eci.get_module_files() return eci, filename, sg.getextrafiles() + list(files) -def gen_source(database, modulename, targetdir, eci, defines={}): +def gen_source(database, modulename, targetdir, eci, defines={}, split=False): assert not database.standalone if isinstance(targetdir, str): targetdir = py.path.local(targetdir) @@ -852,7 +856,9 @@ # 2) Implementation of functions and global structures and arrays # sg = SourceGenerator(database, preimplementationlines) - sg.set_strategy(targetdir) + sg.set_strategy(targetdir, split) + if split: + database.prepare_inline_helpers() sg.gen_readable_parts_of_source(f) gen_startupcode(f, database) Modified: pypy/trunk/pypy/translator/c/test/test_dlltool.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_dlltool.py (original) +++ pypy/trunk/pypy/translator/c/test/test_dlltool.py Mon Aug 3 14:09:46 2009 @@ -1,6 +1,7 @@ from pypy.translator.c.dlltool import DLLDef from ctypes import CDLL +import py class TestDLLTool(object): def test_basic(self): @@ -15,3 +16,14 @@ dll = CDLL(str(so)) assert dll.f(3) == 3 assert dll.b(10) == 12 + + def test_split_criteria(self): + def f(x): + return x + + def b(x): + return x + 2 + + d = DLLDef('lib', [(f, [int]), (b, [int])]) + so = d.compile() + assert py.path.local(so).dirpath().join('implement.c').check() From fijal at codespeak.net Mon Aug 3 18:41:06 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 3 Aug 2009 18:41:06 +0200 (CEST) Subject: [pypy-svn] r66731 - pypy/branch/pyjitpl5-floats Message-ID: <20090803164106.968F71683D0@codespeak.net> Author: fijal Date: Mon Aug 3 18:41:06 2009 New Revision: 66731 Added: pypy/branch/pyjitpl5-floats/ - copied from r66730, pypy/branch/pyjitpl5/ Log: A branch to experiment with floating-point operation support From fijal at codespeak.net Tue Aug 4 06:11:52 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:11:52 +0200 (CEST) Subject: [pypy-svn] r66732 - pypy/branch/pyjitpl5-floats Message-ID: <20090804041152.1050B1683BE@codespeak.net> Author: fijal Date: Tue Aug 4 06:11:50 2009 New Revision: 66732 Removed: pypy/branch/pyjitpl5-floats/ Log: Remove wrongly created branch From fijal at codespeak.net Tue Aug 4 06:13:31 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:13:31 +0200 (CEST) Subject: [pypy-svn] r66733 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090804041331.AD03F1683BE@codespeak.net> Author: fijal Date: Tue Aug 4 06:13:31 2009 New Revision: 66733 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Log: Do a smart thing - have a list of operations with automatically assigned numbers. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Tue Aug 4 06:13:31 2009 @@ -93,115 +93,121 @@ # ____________________________________________________________ - -class rop(object): - """The possible names of the ResOperations.""" - - _FINAL_FIRST = 1 - JUMP = 1 - FAIL = 2 - _FINAL_LAST = 3 - - _GUARD_FIRST = 8 # ----- start of guard operations ----- - _GUARD_FOLDABLE_FIRST = 8 - GUARD_TRUE = 8 - GUARD_FALSE = 9 - GUARD_VALUE = 10 - GUARD_CLASS = 11 - _GUARD_FOLDABLE_LAST = 11 - GUARD_NO_EXCEPTION = 13 - GUARD_EXCEPTION = 14 - _GUARD_LAST = 14 # ----- end of guard operations ----- - - _NOSIDEEFFECT_FIRST = 19 # ----- start of no_side_effect operations ----- - _ALWAYS_PURE_FIRST = 19 # ----- start of always_pure operations ----- - OOSEND_PURE = 19 # ootype operation - CALL_PURE = 20 - # - CAST_INT_TO_PTR = 21 - CAST_PTR_TO_INT = 22 - INT_ADD = 30 - INT_SUB = 31 - INT_MUL = 32 - INT_FLOORDIV = 33 - INT_MOD = 34 - INT_AND = 35 - INT_OR = 36 - INT_XOR = 37 - INT_RSHIFT = 38 - INT_LSHIFT = 39 - UINT_RSHIFT = 44 - # - _COMPARISON_FIRST = 45 - INT_LT = 45 - INT_LE = 46 - INT_EQ = 47 - INT_NE = 48 - INT_GT = 49 - INT_GE = 50 - UINT_LT = 51 - UINT_LE = 52 - UINT_GT = 55 - UINT_GE = 56 - _COMPARISON_LAST = 56 - # - INT_IS_TRUE = 60 - INT_NEG = 61 - INT_INVERT = 62 - BOOL_NOT = 63 - # - SAME_AS = 64 # gets a Const, turns it into a Box - # - OONONNULL = 70 - OOISNULL = 71 - OOIS = 72 - OOISNOT = 73 - # - ARRAYLEN_GC = 77 - STRLEN = 78 - STRGETITEM = 79 - GETFIELD_GC_PURE = 80 - GETFIELD_RAW_PURE = 81 - GETARRAYITEM_GC_PURE = 82 - UNICODELEN = 83 - UNICODEGETITEM = 84 +_oplist = [ + '_FINAL_FIRST', + 'JUMP', + 'FAIL', + '_FINAL_LAST', + + '_GUARD_FIRST', + '_GUARD_FOLDABLE_FIRST', + 'GUARD_TRUE', + 'GUARD_FALSE', + 'GUARD_VALUE', + 'GUARD_CLASS', + '_GUARD_FOLDABLE_LAST', + 'GUARD_NO_EXCEPTION', + 'GUARD_EXCEPTION', + '_GUARD_LAST', # ----- end of guard operations ----- + + '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations ----- + '_ALWAYS_PURE_FIRST', # ----- start of always_pure operations ----- + 'OOSEND_PURE', # ootype operation + 'CALL_PURE', + # + 'CAST_INT_TO_PTR', + 'CAST_PTR_TO_INT', + 'INT_ADD', + 'INT_SUB', + 'INT_MUL', + 'INT_FLOORDIV', + 'INT_MOD', + 'INT_AND', + 'INT_OR', + 'INT_XOR', + 'INT_RSHIFT', + 'INT_LSHIFT', + 'UINT_RSHIFT', + # + '_COMPARISON_FIRST', + 'INT_LT', + 'INT_LE', + 'INT_EQ', + 'INT_NE', + 'INT_GT', + 'INT_GE', + 'UINT_LT', + 'UINT_LE', + 'UINT_GT', + 'UINT_GE', + '_COMPARISON_LAST', + # + 'INT_IS_TRUE', + 'INT_NEG', + 'INT_INVERT', + 'BOOL_NOT', + # + 'SAME_AS', # gets a Const, turns it into a Box + # + 'OONONNULL', + 'OOISNULL', + 'OOIS', + 'OOISNOT', + # + 'ARRAYLEN_GC', + 'STRLEN', + 'STRGETITEM', + 'GETFIELD_GC_PURE', + 'GETFIELD_RAW_PURE', + 'GETARRAYITEM_GC_PURE', + 'UNICODELEN', + 'UNICODEGETITEM', # # ootype operations - OOIDENTITYHASH = 85 - INSTANCEOF = 86 - SUBCLASSOF = 87 - # - _ALWAYS_PURE_LAST = 87 # ----- end of always_pure operations ----- - - GETARRAYITEM_GC = 120 - GETFIELD_GC = 121 - GETFIELD_RAW = 122 - NEW = 123 - NEW_WITH_VTABLE = 124 - NEW_ARRAY = 125 - _NOSIDEEFFECT_LAST = 129 # ----- end of no_side_effect operations ----- - - SETARRAYITEM_GC = 133 - SETFIELD_GC = 134 - SETFIELD_RAW = 135 - NEWSTR = 136 - STRSETITEM = 137 - UNICODESETITEM = 138 - NEWUNICODE = 139 - RUNTIMENEW = 140 # ootype operation - - _CANRAISE_FIRST = 150 # ----- start of can_raise operations ----- - CALL = 150 - OOSEND = 151 # ootype operation - # - _OVF_FIRST = 152 - INT_ADD_OVF = 152 - INT_SUB_OVF = 153 - INT_MUL_OVF = 154 - _OVF_LAST = 160 - _CANRAISE_LAST = 160 # ----- end of can_raise operations ----- - _LAST = 160 # for the backend to add more internal operations + 'OOIDENTITYHASH', + 'INSTANCEOF', + 'SUBCLASSOF', + # + '_ALWAYS_PURE_LAST', # ----- end of always_pure operations ----- + + 'GETARRAYITEM_GC', + 'GETFIELD_GC', + 'GETFIELD_RAW', + 'NEW', + 'NEW_WITH_VTABLE', + 'NEW_ARRAY', + '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- + + 'SETARRAYITEM_GC', + 'SETFIELD_GC', + 'SETFIELD_RAW', + 'NEWSTR', + 'STRSETITEM', + 'UNICODESETITEM', + 'NEWUNICODE', + 'RUNTIMENEW', # ootype operation + + '_CANRAISE_FIRST', # ----- start of can_raise operations ----- + 'CALL', + 'OOSEND', # ootype operation + # + '_OVF_FIRST', + 'INT_ADD_OVF', + 'INT_SUB_OVF', + 'INT_MUL_OVF', + '_OVF_LAST', + '_CANRAISE_LAST', # ----- end of can_raise operations ----- + '_LAST', # for the backend to add more internal operations +] + +class rop(object): + pass +i = 0 +for opname in _oplist: + setattr(rop, opname, i) + i += 1 +del _oplist opname = {} # mapping numbers to the original names, for debugging for _key, _value in rop.__dict__.items(): From fijal at codespeak.net Tue Aug 4 06:13:56 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:13:56 +0200 (CEST) Subject: [pypy-svn] r66734 - pypy/branch/pyjitpl5-floats Message-ID: <20090804041356.921C21683BE@codespeak.net> Author: fijal Date: Tue Aug 4 06:13:56 2009 New Revision: 66734 Added: pypy/branch/pyjitpl5-floats/ - copied from r66733, pypy/branch/pyjitpl5/ Log: A branch to experiment with FPU support in JIT From fijal at codespeak.net Tue Aug 4 06:18:10 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:18:10 +0200 (CEST) Subject: [pypy-svn] r66735 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp Message-ID: <20090804041810.C28DC1683BE@codespeak.net> Author: fijal Date: Tue Aug 4 06:18:10 2009 New Revision: 66735 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/resoperation.py Log: absolute minimum for floats - boxes and operations (binary only so far) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/executor.py Tue Aug 4 06:18:10 2009 @@ -1,13 +1,13 @@ """This implements pyjitpl's execution of operations. """ -import py +import py, math from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask -from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr -from pypy.jit.metainterp.history import INT, PTR, OBJ +from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr, BoxFloat +from pypy.jit.metainterp.history import INT, PTR, OBJ, ConstFloat, FLOAT from pypy.jit.metainterp.resoperation import rop @@ -55,6 +55,29 @@ # ---------- +def do_float_neg(cpu, args, descr=None): + return ConstFloat(-args[0].getfloat()) + +def do_float_abs(cpu, args, descr=None): + return ConstFloat(math.abs(args[0].getfloat())) + +def do_float_is_true(cpu, args, descr=None): + return ConstInt(bool(args[0].getfloat())) + +def do_float_add(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() + args[1].getfloat()) + +def do_float_sub(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() - args[1].getfloat()) + +def do_float_mul(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() * args[1].getfloat()) + +def do_float_truediv(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() / args[1].getfloat()) + +# ---------- + def do_int_lt(cpu, args, descr=None): return ConstInt(args[0].getint() < args[1].getint()) @@ -87,6 +110,26 @@ # ---------- +def do_float_lt(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() < args[1].getfloat()) + +def do_float_le(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() <= args[1].getfloat()) + +def do_float_eq(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() == args[1].getfloat()) + +def do_float_ne(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() != args[1].getfloat()) + +def do_float_gt(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() > args[1].getfloat()) + +def do_float_ge(cpu, args, descr=None): + return ConstFloat(args[0].getfloat() >= args[1].getfloat()) + +# ---------- + def do_int_is_true(cpu, args, descr=None): return ConstInt(bool(args[0].getint())) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/history.py Tue Aug 4 06:18:10 2009 @@ -19,12 +19,15 @@ INT = 'i' PTR = 'p' OBJ = 'o' +FLOAT = 'f' def getkind(TYPE): if TYPE is lltype.Void: return "void" elif isinstance(TYPE, lltype.Primitive): - if TYPE in (lltype.Float, lltype.SingleFloat): + if TYPE is lltype.Float: + return 'float' + if TYPE is lltype.SingleFloat: raise NotImplementedError("type %s not supported" % TYPE) # XXX fix this for oo... if rffi.sizeof(TYPE) > rffi.sizeof(lltype.Signed): @@ -76,6 +79,9 @@ def getint(self): raise NotImplementedError + def getfloat(self): + raise NotImplementedError + def getptr_base(self): raise NotImplementedError @@ -280,6 +286,26 @@ def repr_rpython(self): return repr_rpython(self, 'ca') +class ConstFloat(Const): + type = FLOAT + _attrs_ = ('value',) + + def __init__(self, floatval): + assert isinstance(floatval, float) + self.value = floatval + + def getfloat(self): + return self.value + + def _getrepr_(self): + return self.value + + def repr_rpython(self): + return repr_rpython(self, 'cf') + + def __hash__(self): + return hash(self.value) + class ConstPtr(Const): type = PTR value = lltype.nullptr(llmemory.GCREF.TO) @@ -393,10 +419,7 @@ def __str__(self): if not hasattr(self, '_str'): try: - if self.type == INT: - t = 'i' - else: - t = 'p' + t = self.type except AttributeError: t = 'b' self._str = '%s%d' % (t, Box._counter) @@ -444,6 +467,23 @@ changevalue_int = __init__ +class BoxFloat(Box): + type = FLOAT + _attrs_ = ('value',) + + def __init__(self, floatval=0.0): + assert isinstance(floatval, float) + self.value = floatval + + def getfloat(self): + return self.value + + def _getrepr_(self): + return self.value + + def repr_rpython(self): + return repr_rpython(self, 'bf') + class BoxPtr(Box): type = PTR _attrs_ = ('value',) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/resoperation.py Tue Aug 4 06:18:10 2009 @@ -128,6 +128,10 @@ 'INT_RSHIFT', 'INT_LSHIFT', 'UINT_RSHIFT', + 'FLOAT_ADD', + 'FLOAT_SUB', + 'FLOAT_MUL', + 'FLOAT_TRUEDIV', # '_COMPARISON_FIRST', 'INT_LT', From fijal at codespeak.net Tue Aug 4 06:18:28 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:18:28 +0200 (CEST) Subject: [pypy-svn] r66736 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test Message-ID: <20090804041828.E12A41683D0@codespeak.net> Author: fijal Date: Tue Aug 4 06:18:28 2009 New Revision: 66736 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py Log: support for fdd boxes Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py Tue Aug 4 06:18:28 2009 @@ -4,7 +4,7 @@ """ from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\ - ConstAddr, ConstObj, ConstPtr, Box, BoxObj + ConstAddr, ConstObj, ConstPtr, Box, BoxObj, BoxFloat, ConstFloat from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype @@ -15,7 +15,6 @@ class ParseError(Exception): pass - class Boxes(object): pass @@ -66,6 +65,9 @@ # integer box = BoxInt() _box_counter_more_than(elem[1:]) + elif elem.startswith('f'): + box = BoxFloat() + _box_counter_more_than(elem[1:]) elif elem.startswith('p'): # pointer if getattr(self.cpu, 'is_oo', False): @@ -98,27 +100,30 @@ try: return ConstInt(int(arg)) except ValueError: - if arg.startswith('ConstClass('): - name = arg[len('ConstClass('):-1] - if self.type_system == 'lltype': - return ConstAddr(llmemory.cast_ptr_to_adr(self.consts[name]), - self.cpu) - else: - return ConstObj(ootype.cast_to_object(self.consts[name])) - elif arg == 'None': - return None - elif arg == 'NULL': - if self.type_system == 'lltype': - return ConstPtr(ConstPtr.value) - else: - return ConstObj(ConstObj.value) - elif arg.startswith('ConstPtr('): - name = arg[len('ConstPtr('):-1] - if self.type_system == 'lltype': - return ConstPtr(self.boxkinds[name]) - else: - return ConstObj(self.boxkinds[name]) - return self.vars[arg] + try: + return ConstFloat(float(arg)) + except ValueError: + if arg.startswith('ConstClass('): + name = arg[len('ConstClass('):-1] + if self.type_system == 'lltype': + return ConstAddr(llmemory.cast_ptr_to_adr(self.consts[name]), + self.cpu) + else: + return ConstObj(ootype.cast_to_object(self.consts[name])) + elif arg == 'None': + return None + elif arg == 'NULL': + if self.type_system == 'lltype': + return ConstPtr(ConstPtr.value) + else: + return ConstObj(ConstObj.value) + elif arg.startswith('ConstPtr('): + name = arg[len('ConstPtr('):-1] + if self.type_system == 'lltype': + return ConstPtr(self.boxkinds[name]) + else: + return ConstObj(self.boxkinds[name]) + return self.vars[arg] def parse_op(self, line): num = line.find('(') Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py Tue Aug 4 06:18:28 2009 @@ -3,7 +3,7 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.jit.metainterp.resoperation import rop -from pypy.jit.metainterp.history import AbstractDescr, BoxInt +from pypy.jit.metainterp.history import AbstractDescr, BoxInt, BoxFloat def test_basic_parse(): x = """ @@ -101,3 +101,14 @@ loop = parse(x, None, {}, boxkinds={'sum': BoxInt}) b = loop.getboxes() assert isinstance(b.sum0, BoxInt) + +def test_float(): + x = ''' + [f0] + f1 = float_add(f0, 1.5) + ''' + loop = parse(x, None, {}) + b = loop.getboxes() + assert isinstance(b.f0, BoxFloat) + assert isinstance(b.f1, BoxFloat) + From fijal at codespeak.net Tue Aug 4 06:18:52 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:18:52 +0200 (CEST) Subject: [pypy-svn] r66737 - in pypy/branch/pyjitpl5-floats/pypy/jit/backend: llgraph llgraph/test test Message-ID: <20090804041852.617231683BF@codespeak.net> Author: fijal Date: Tue Aug 4 06:18:51 2009 New Revision: 66737 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Log: basic float tests and llgraph support Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py Tue Aug 4 06:18:51 2009 @@ -7,8 +7,9 @@ import sys from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, ConstObj, - BoxInt, BoxPtr, BoxObj) +from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, + ConstObj, + BoxInt, BoxPtr, BoxObj, BoxFloat) from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.module.support import LLSupport, OOSupport @@ -69,6 +70,10 @@ 'int_add_ovf' : (('int', 'int'), 'int'), 'int_sub_ovf' : (('int', 'int'), 'int'), 'int_mul_ovf' : (('int', 'int'), 'int'), + 'float_add' : (('float', 'float'), 'float'), + 'float_sub' : (('float', 'float'), 'float'), + 'float_mul' : (('float', 'float'), 'float'), + 'float_truediv' : (('float', 'float'), 'float'), 'bool_not' : (('bool',), 'bool'), 'uint_add' : (('int', 'int'), 'int'), 'uint_sub' : (('int', 'int'), 'int'), @@ -91,20 +96,20 @@ 'ooisnot' : (('ptr', 'ptr'), 'bool'), 'instanceof' : (('ptr',), 'bool'), 'subclassof' : (('ptr', 'ptr'), 'bool'), - 'setfield_gc' : (('ptr', 'intorptr'), None), - 'getfield_gc' : (('ptr',), 'intorptr'), - 'getfield_gc_pure': (('ptr',), 'intorptr'), - 'setfield_raw' : (('ptr', 'intorptr'), None), - 'getfield_raw' : (('ptr',), 'intorptr'), - 'getfield_raw_pure': (('ptr',), 'intorptr'), - 'setarrayitem_gc' : (('ptr', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ptr', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ptr', 'int'), 'intorptr'), + 'setfield_gc' : (('ptr', 'any'), None), + 'getfield_gc' : (('ptr',), 'any'), + 'getfield_gc_pure': (('ptr',), 'any'), + 'setfield_raw' : (('ptr', 'any'), None), + 'getfield_raw' : (('ptr',), 'any'), + 'getfield_raw_pure': (('ptr',), 'any'), + 'setarrayitem_gc' : (('ptr', 'int', 'any'), None), + 'getarrayitem_gc' : (('ptr', 'int'), 'any'), + 'getarrayitem_gc_pure' : (('ptr', 'int'), 'any'), 'arraylen_gc' : (('ptr',), 'int'), - 'call' : (('ptr', 'varargs'), 'intorptr'), - 'call_pure' : (('ptr', 'varargs'), 'intorptr'), - 'oosend' : (('varargs',), 'intorptr'), - 'oosend_pure' : (('varargs',), 'intorptr'), + 'call' : (('ptr', 'varargs'), 'any'), + 'call_pure' : (('ptr', 'varargs'), 'any'), + 'oosend' : (('varargs',), 'any'), + 'oosend_pure' : (('varargs',), 'any'), 'guard_true' : (('bool',), None), 'guard_false' : (('bool',), None), 'guard_value' : (('int', 'int'), None), @@ -209,13 +214,15 @@ return '[%s]' % (', '.join(res_l)) def repr1(x, tp, memocast): - if tp == "intorptr": + if tp == "any": TYPE = lltype.typeOf(x) if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': tp = "ptr" + elif TYPE is lltype.Float: + tp = 'float' else: tp = "int" - if tp == 'int': + if tp == 'int' or tp == 'float': return str(x) elif tp == 'void': return '---' @@ -264,6 +271,16 @@ _variables.append(v) return r +def compile_start_float_var(loop): + loop = _from_opaque(loop) + assert not loop.operations + v = Variable() + v.concretetype = lltype.Float + loop.inputargs.append(v) + r = len(_variables) + _variables.append(v) + return r + def compile_start_ptr_var(loop): loop = _from_opaque(loop) assert not loop.operations @@ -307,6 +324,13 @@ op = loop.operations[-1] op.args.append(const) +def compile_add_float_const(loop, value): + loop = _from_opaque(loop) + const = Constant(value) + const.concretetype = lltype.Float + op = loop.operations[-1] + op.args.append(const) + def compile_add_ptr_const(loop, value, TYPE=llmemory.GCREF): loop = _from_opaque(loop) const = Constant(value) @@ -324,6 +348,16 @@ _variables.append(v) return r +def compile_add_float_result(loop): + loop = _from_opaque(loop) + v = Variable() + v.concretetype = lltype.Float + op = loop.operations[-1] + op.result = v + r = len(_variables) + _variables.append(v) + return r + def compile_add_ptr_result(loop, TYPE=llmemory.GCREF): loop = _from_opaque(loop) v = Variable() @@ -413,6 +447,8 @@ RESTYPE = op.result.concretetype if RESTYPE is lltype.Signed: x = self.as_int(result) + elif RESTYPE is lltype.Float: + x = self.as_float(result) elif RESTYPE is llmemory.GCREF: x = self.as_ptr(result) elif RESTYPE is ootype.Object: @@ -473,6 +509,9 @@ def as_int(self, x): return cast_to_int(x, self.memocast) + def as_float(self, x): + return x + def as_ptr(self, x): return cast_to_ptr(x) @@ -507,6 +546,8 @@ for x in args: if type(x) is int: boxedargs.append(BoxInt(x)) + elif type(x) is float: + boxedargs.append(BoxFloat(x)) elif isinstance(ootype.typeOf(x), ootype.OOType): boxedargs.append(BoxObj(ootype.cast_to_object(x))) else: @@ -601,6 +642,8 @@ def op_getarrayitem_gc(self, arraydescr, array, index): if arraydescr.typeinfo == 'p': return do_getarrayitem_gc_ptr(array, index) + elif arraydescr.typeinfo == 'f': + return do_getarrayitem_gc_float(array, index) else: return do_getarrayitem_gc_int(array, index, self.memocast) @@ -634,6 +677,8 @@ def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): if arraydescr.typeinfo == 'p': do_setarrayitem_gc_ptr(array, index, newvalue) + elif arraydescr.typeinfo == 'f': + do_setarrayitem_gc_float(array, index, newvalue) else: do_setarrayitem_gc_int(array, index, newvalue, self.memocast) @@ -836,20 +881,18 @@ frame.env[loop.inputargs[i]] = _future_values[i] del _future_values[:] -def set_future_value_int(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) - -def set_future_value_ptr(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) - -def set_future_value_obj(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) +def _new_set_future_value(name): + def set_future_value(index, value): + del _future_values[index:] + assert len(_future_values) == index + _future_values.append(value) + set_future_value.func_name = name + return set_future_value + +set_future_value_ptr = _new_set_future_value('set_future_value_ptr') +set_future_value_obj = _new_set_future_value('set_future_value_obj') +set_future_value_float = _new_set_future_value('set_future_value_float') +set_future_value_int = _new_set_future_value('set_future_value_int') def frame_execute(frame): frame = _from_opaque(frame) @@ -875,6 +918,10 @@ frame = _from_opaque(frame) return frame.fail_args[num] +def frame_float_getvalue(frame, num): + frame = _from_opaque(frame) + return frame.fail_args[num] + def frame_ptr_getvalue(frame, num): frame = _from_opaque(frame) result = frame.fail_args[num] @@ -991,6 +1038,10 @@ array = array._obj.container return cast_to_int(array.getitem(index), memocast) +def do_getarrayitem_gc_float(array, index): + array = array._obj.container + return array.getitem(index) + def do_getarrayitem_gc_ptr(array, index): array = array._obj.container return cast_to_ptr(array.getitem(index)) @@ -1035,6 +1086,11 @@ newvalue = cast_from_int(ITEMTYPE, newvalue, memocast) array.setitem(index, newvalue) +def do_setarrayitem_gc_float(array, index, newvalue): + array = array._obj.container + ITEMTYPE = lltype.typeOf(array).OF + array.setitem(index, newvalue) + def do_setarrayitem_gc_ptr(array, index, newvalue): array = array._obj.container ITEMTYPE = lltype.typeOf(array).OF Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/runner.py Tue Aug 4 06:18:51 2009 @@ -116,6 +116,8 @@ var2index[box] = llimpl.compile_start_int_var(c) elif isinstance(box, history.BoxPtr): var2index[box] = llimpl.compile_start_ptr_var(c) + elif isinstance(box, history.BoxFloat): + var2index[box] = llimpl.compile_start_float_var(c) elif self.is_oo and isinstance(box, history.BoxObj): var2index[box] = llimpl.compile_start_obj_var(c) else: @@ -140,6 +142,8 @@ llimpl.compile_add_var(c, var2index[x]) elif isinstance(x, history.ConstInt): llimpl.compile_add_int_const(c, x.value) + elif isinstance(x, history.ConstFloat): + llimpl.compile_add_float_const(c, x.value) elif isinstance(x, history.ConstPtr): llimpl.compile_add_ptr_const(c, x.value) elif isinstance(x, history.ConstAddr): @@ -156,6 +160,8 @@ if x is not None: if isinstance(x, history.BoxInt): var2index[x] = llimpl.compile_add_int_result(c) + elif isinstance(x, history.BoxFloat): + var2index[x] = llimpl.compile_add_float_result(c) elif isinstance(x, history.BoxPtr): var2index[x] = llimpl.compile_add_ptr_result(c) elif self.is_oo and isinstance(x, history.BoxObj): @@ -187,6 +193,9 @@ def set_future_value_int(self, index, intvalue): llimpl.set_future_value_int(index, intvalue) + def set_future_value_float(self, index, floatval): + llimpl.set_future_value_float(index, floatval) + def set_future_value_ptr(self, index, ptrvalue): llimpl.set_future_value_ptr(index, ptrvalue) @@ -196,6 +205,9 @@ def get_latest_value_int(self, index): return llimpl.frame_int_getvalue(self.latest_frame, index) + def get_latest_value_float(self, index): + return llimpl.frame_float_getvalue(self.latest_frame, index) + def get_latest_value_ptr(self, index): return llimpl.frame_ptr_getvalue(self.latest_frame, index) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/test/test_llgraph.py Tue Aug 4 06:18:51 2009 @@ -219,6 +219,8 @@ class TestLLTypeLLGraph(LLtypeBackendTest, LLGraphTests): + # for individual tests look + # ====> ../../test/runner_test.py from pypy.jit.backend.llgraph.runner import LLtypeCPU as cpu_type ## these tests never worked Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Tue Aug 4 06:18:51 2009 @@ -2,7 +2,7 @@ import py, sys, random from pypy.jit.metainterp.history import (BoxInt, Box, BoxPtr, TreeLoop, ConstInt, ConstPtr, BoxObj, - ConstObj) + ConstObj, BoxFloat, ConstFloat) from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.typesystem import deref from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass @@ -20,6 +20,9 @@ if isinstance(box, BoxInt): self.cpu.set_future_value_int(j, box.getint()) j += 1 + elif isinstance(box, BoxFloat): + self.cpu.set_future_value_float(j, box.getfloat()) + j += 1 elif isinstance(box, BoxPtr): self.cpu.set_future_value_ptr(j, box.getptr_base()) j += 1 @@ -35,6 +38,8 @@ return BoxInt(self.cpu.get_latest_value_int(0)) elif result_type == 'ptr': return BoxPtr(self.cpu.get_latest_value_ptr(0)) + elif result_type == 'float': + return BoxFloat(self.cpu.get_latest_value_float(0)) elif result_type == 'void': return None else: @@ -48,6 +53,8 @@ result = BoxInt() elif result_type == 'ptr': result = BoxPtr() + elif result_type == 'float': + result = BoxFloat() else: raise ValueError(result_type) if result is None: @@ -154,6 +161,27 @@ 'int') assert res.value == z + def test_binary_float_operations(self): + for opnum, testcases in [ + (rop.FLOAT_ADD, [(10.0, -2.5, 7.5)]), + (rop.FLOAT_SUB, [(-1., 1., -2.)]), + (rop.FLOAT_MUL, [(-3.5, 3.5, -12.25)]), + # exact equality, platform floats + (rop.FLOAT_TRUEDIV, [(-2., -3., -2./-3.)]), + ]: + for x, y, z in testcases: + res = self.execute_operation(opnum, [BoxFloat(x), BoxFloat(y)], + 'float') + assert res.value == z + res = self.execute_operation(opnum, [ConstFloat(x), + BoxFloat(y)], + 'float') + assert res.value == z + res = self.execute_operation(opnum, [BoxFloat(x), + ConstFloat(y)], + 'float') + assert res.value == z + def test_compare_operations(self): random_numbers = [-sys.maxint-1, -1, 0, 1, sys.maxint] def pick(): @@ -480,6 +508,18 @@ 'int', descr=arraydescr) assert r.value == 1 + def test_array_float(self): + a_box, A = self.alloc_array_of(lltype.Float, 24) + arraydescr = self.cpu.arraydescrof(A) + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(13), + BoxFloat(3.5)], + 'void', descr=arraydescr) + assert r is None + r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(13)], + 'float', descr=arraydescr) + assert r.value == 3.5 + + def test_string_basic(self): s_box = self.alloc_string("hello\xfe") r = self.execute_operation(rop.STRLEN, [s_box], 'int') From fijal at codespeak.net Tue Aug 4 06:19:16 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:19:16 +0200 (CEST) Subject: [pypy-svn] r66738 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test Message-ID: <20090804041916.995681683BF@codespeak.net> Author: fijal Date: Tue Aug 4 06:19:16 2009 New Revision: 66738 Removed: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc.py Log: remove outdated test, regalloc2 will take it's place From fijal at codespeak.net Tue Aug 4 06:21:13 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 4 Aug 2009 06:21:13 +0200 (CEST) Subject: [pypy-svn] r66739 - in pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86: . test Message-ID: <20090804042113.BC02E1683BF@codespeak.net> Author: fijal Date: Tue Aug 4 06:21:13 2009 New Revision: 66739 Added: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/support.py (contents, props changed) pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_support.py (contents, props changed) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/gc.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Log: Absolutely minimum support for floats. IN-PROGRESS, more tests in test_regalloc2 are needed for different cases. Also only couple of floats operations are supported and not say CALL with float args. The idea is that we only use the stack top (st0) so far and ignore other registers. We might as well want to use SSE2 instead of x87 operations (as they're superset of features), so it might be just temporary Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py Tue Aug 4 06:21:13 2009 @@ -1,7 +1,7 @@ import sys, os import ctypes from pypy.jit.backend.x86 import symbolic -from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR +from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR, FLOAT from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -14,6 +14,7 @@ from pypy.jit.backend.x86.ri386 import * from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.support import AbstractLogger +from pypy.jit.backend.x86.support import ListOfFloats # our calling convention - we pass three first args as edx, ecx and eax # and the rest stays on the stack @@ -103,6 +104,8 @@ MAX_FAIL_BOXES, zero=True) self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF), MAX_FAIL_BOXES, zero=True) + self.fail_boxes_float = lltype.malloc(lltype.GcArray(lltype.Float), + MAX_FAIL_BOXES, zero=True) def make_sure_mc_exists(self): if self.mc is None: @@ -110,10 +113,13 @@ rffi.cast(lltype.Signed, self.fail_boxes_int) # workaround rffi.cast(lltype.Signed, self.fail_boxes_ptr) # workaround + rffi.cast(lltype.Signed, self.fail_boxes_float) # workaround self.fail_box_int_addr = rffi.cast(lltype.Signed, lltype.direct_arrayitems(self.fail_boxes_int)) self.fail_box_ptr_addr = rffi.cast(lltype.Signed, lltype.direct_arrayitems(self.fail_boxes_ptr)) + self.fail_box_float_addr = rffi.cast(lltype.Signed, + lltype.direct_arrayitems(self.fail_boxes_float)) self.logger.create_log() # we generate the loop body in 'mc' @@ -160,7 +166,7 @@ self.gcrootmap = gc_ll_descr.gcrootmap if self.gcrootmap: self.gcrootmap.initialize() - + self.floatmap = ListOfFloats() def _compute_longest_fail_op(self, ops): max_so_far = 0 @@ -223,16 +229,24 @@ for i in range(len(arglocs)): loc = arglocs[i] if not isinstance(loc, REG): - if args[i].type == PTR: - # This uses XCHG to put zeroes in fail_boxes_ptr after - # reading them - self.mc.XOR(ecx, ecx) - self.mc.XCHG(ecx, addr_add(imm(self.fail_box_ptr_addr), - imm(i*WORD))) + if args[i].type == FLOAT: + self.mc.MOV(ecx, addr_add(imm(self.fail_box_float_addr), + imm(i*2*WORD))) + self.mc.MOV(stack_pos(loc.position + 1, 1), ecx) + self.mc.MOV(ecx, addr_add(imm(self.fail_box_float_addr), + imm((i*2 + 1) * WORD))) + self.mc.MOV(stack_pos(loc.position, 1), ecx) else: - self.mc.MOV(ecx, addr_add(imm(self.fail_box_int_addr), - imm(i*WORD))) - self.mc.MOV(loc, ecx) + if args[i].type == PTR: + # This uses XCHG to put zeroes in fail_boxes_ptr after + # reading them + self.mc.XOR(ecx, ecx) + self.mc.XCHG(ecx, addr_add(imm(self.fail_box_ptr_addr), + imm(i*WORD))) + else: + self.mc.MOV(ecx, addr_add(imm(self.fail_box_int_addr), + imm(i*WORD))) + self.mc.MOV(loc, ecx) for i in range(len(arglocs)): loc = arglocs[i] if isinstance(loc, REG): @@ -266,6 +280,12 @@ regalloc_store = regalloc_load + def regalloc_load_float(self, from_loc, to_loc): + self.mc.FLDL(from_loc) + + def regalloc_store_float(self, from_loc, to_loc): + self.mc.FSTPL(to_loc) + def regalloc_push(self, loc): self.mc.PUSH(loc) @@ -392,6 +412,16 @@ genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B") genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A") + def _binop_float(opname): + def genop_binary_float(self, op, arglocs, resultloc): + getattr(self.mc, opname)(arglocs[1]) + return genop_binary_float + + genop_float_add = _binop_float('FADDL') + genop_float_sub = _binop_float('FSUBL') + genop_float_mul = _binop_float('FMULL') + genop_float_truediv = _binop_float('FDIVL') + # for now all chars are being considered ints, although we should make # a difference at some point xxx_genop_char_eq = genop_int_eq @@ -505,6 +535,8 @@ if scale.value == 0: self.mc.MOVZX(resloc, addr8_add(base_loc, ofs_loc, ofs.value, scale.value)) + elif scale.value == 3: + self.mc.FLDL(addr64_add(base_loc, ofs_loc, ofs.value, scale.value)) elif scale.value == 2: self.mc.MOV(resloc, addr_add(base_loc, ofs_loc, ofs.value, scale.value)) @@ -537,6 +569,10 @@ if scale_loc.value == 2: self.mc.MOV(addr_add(base_loc, ofs_loc, baseofs.value, scale_loc.value), value_loc) + elif scale_loc.value == 3: + assert value_loc is st0 + self.mc.FSTPL(addr64_add(base_loc, ofs_loc, baseofs.value, + scale_loc.value)) elif scale_loc.value == 0: self.mc.MOV(addr8_add(base_loc, ofs_loc, baseofs.value, scale_loc.value), lower_byte(value_loc)) @@ -700,7 +736,7 @@ self.mc = oldmc return addr - def generate_failure(self, op, locs, exc): + def generate_failure(self, op, locs, exc, regalloc): pos = self.mc.tell() for i in range(len(locs)): loc = locs[i] @@ -713,12 +749,28 @@ for i in range(len(locs)): loc = locs[i] if not isinstance(loc, REG): - if op.args[i].type == PTR: - base = self.fail_box_ptr_addr + if op.args[i].type == FLOAT: + base = self.fail_box_float_addr + if loc is st0: + self.mc.FSTPL(addr64_add(imm(base), imm(i*2*WORD))) + regalloc.st0 = None + else: + assert isinstance(loc, MODRM) + start = stack_pos(loc.position, 1) + next = stack_pos(loc.position + 1, 1) + self.mc.MOV(eax, start) + self.mc.MOV(addr_add(imm(base), imm((i*2 + 1)*WORD)), + eax) + self.mc.MOV(eax, next) + self.mc.MOV(addr_add(imm(base), imm(2*i*WORD)), + eax) else: - base = self.fail_box_int_addr - self.mc.MOV(eax, loc) - self.mc.MOV(addr_add(imm(base), imm(i*WORD)), eax) + if op.args[i].type == PTR: + base = self.fail_box_ptr_addr + else: + base = self.fail_box_int_addr + self.mc.MOV(eax, loc) + self.mc.MOV(addr_add(imm(base), imm(i*WORD)), eax) if self.debug_markers: self.mc.MOV(eax, imm(pos)) self.mc.MOV(addr_add(imm(self.fail_box_int_addr), @@ -772,7 +824,7 @@ else: x = arglocs[0] if isinstance(x, MODRM): - x = stack_pos(x.position) + x = stack_pos(x.position, 1) self.mc.CALL(x) self.mark_gc_roots() self.mc.ADD(esp, imm(WORD * extra_on_stack)) @@ -879,6 +931,20 @@ else: return memSIB16(reg_or_imm1, reg_or_imm2, scale, offset) +def addr64_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0): + if isinstance(reg_or_imm1, IMM32): + if isinstance(reg_or_imm2, IMM32): + return heap64(reg_or_imm1.value + (offset << scale) + + reg_or_imm2.value) + else: + return memSIB64(None, reg_or_imm2, scale, reg_or_imm1.value + offset) + else: + if isinstance(reg_or_imm2, IMM32): + return mem64(reg_or_imm1, (offset << scale) + reg_or_imm2.value) + else: + return memSIB64(reg_or_imm1, reg_or_imm2, scale, offset) + + def addr_add_const(reg_or_imm1, offset): if isinstance(reg_or_imm1, IMM32): return heap(reg_or_imm1.value + offset) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/gc.py Tue Aug 4 06:21:13 2009 @@ -46,7 +46,7 @@ def arraydescrof(self, A, translate_support_code): basesize, itemsize, ofs_length = symbolic.get_array_token(A, translate_support_code) - assert rffi.sizeof(A.OF) in [1, 2, WORD] + assert rffi.sizeof(A.OF) in [1, 2, WORD, 2*WORD] # assert ofs_length == 0 --- but it's symbolic... if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc': ptr = True @@ -355,7 +355,7 @@ def arraydescrof(self, A, translate_support_code): assert translate_support_code, "required with the framework GC" basesize, itemsize, ofs_length = symbolic.get_array_token(A, True) - assert rffi.sizeof(A.OF) in [1, 2, WORD] + assert rffi.sizeof(A.OF) in [1, 2, WORD, 2*WORD] # assert ofs_length == self.array_length_ofs --- but it's symbolics... if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc': ptr = True Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py Tue Aug 4 06:21:13 2009 @@ -3,7 +3,8 @@ """ from pypy.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr, - ResOperation, ConstAddr, BoxPtr) + ResOperation, ConstAddr, BoxPtr, + INT, PTR, FLOAT, ConstFloat) from pypy.jit.backend.x86.ri386 import * from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi, rstr from pypy.rlib.objectmodel import we_are_translated @@ -17,6 +18,16 @@ REGS = [eax, ecx, edx] WORD = 4 +_sizes = { + # in WORDs + INT : 1, + FLOAT : 2, + PTR : 1, + } + +def sizeofbox(box): + return _sizes[box.type] + class ImplementConstantOverflow(Exception): """ This exception is raised when someone uses the result of GUARD_EXCEPTION(overflowerror). I think codewriter should @@ -41,20 +52,6 @@ return {} return checkdict() -def convert_to_imm(c): - if isinstance(c, ConstInt): - return imm(c.value) - elif isinstance(c, ConstPtr): - if we_are_translated() and c.value and rgc.can_move(c.value): - print "convert_to_imm: ConstPtr needs special care" - raise AssertionError - return imm(rffi.cast(lltype.Signed, c.value)) - elif isinstance(c, ConstAddr): - return imm(ll2ctypes.cast_adr_to_int(c.value)) - else: - print "convert_to_imm: got a %s" % c - raise AssertionError - class RegAlloc(object): max_stack_depth = 0 exc = False @@ -78,9 +75,10 @@ #if guard_op: # loop_consts, sd = self._start_from_guard_op(guard_op, mp, jump) #else: - loop_consts, sd = self._compute_loop_consts(tree.inputargs, jump) + loop_consts = self._compute_loop_consts(tree.inputargs, jump) self.loop_consts = loop_consts - self.current_stack_depth = sd + self.current_stack_depth = -1 + self.st0 = None else: self._rewrite_const_ptrs(guard_op.suboperations) guard_op.inputargs = None @@ -108,6 +106,7 @@ jump_or_fail = guard_op.suboperations[-1] self.loop_consts = {} self.tree = regalloc.tree + self.st0 = regalloc.st0 if jump_or_fail.opnum == rop.FAIL: self.jump_reg_candidates = {} else: @@ -117,6 +116,7 @@ def _create_jump_reg_candidates(self, jump): self.jump_reg_candidates = {} + # XXX disabled, note return for i in range(len(jump.args)): arg = jump.args[i] @@ -128,6 +128,23 @@ return RegAlloc(self.assembler, None, self.translate_support_code, self, guard_op) + def const_to_operand(self, c): + if isinstance(c, ConstInt): + return imm(c.value) + elif isinstance(c, ConstPtr): + if we_are_translated() and c.value and rgc.can_move(c.value): + print "const_to_operand: ConstPtr needs special care" + raise AssertionError + return imm(rffi.cast(lltype.Signed, c.value)) + elif isinstance(c, ConstAddr): + return imm(ll2ctypes.cast_adr_to_int(c.value)) + elif isinstance(c, ConstFloat): + addr = self.assembler.floatmap.getaddr(c.getfloat()) + return heap64(addr) + else: + print "const_to_operand: got a %s" % c + raise AssertionError + # def _start_from_guard_op(self, guard_op, mp, jump): # xxx # rev_stack_binds = {} @@ -190,7 +207,7 @@ # arg in self.stack_bindings): # self.stack_bindings[jarg] = stack_pos(i) # self.dirty_stack[jarg] = True - return loop_consts, len(inputargs) + return loop_consts def _check_invariants(self): if not we_are_translated(): @@ -216,11 +233,23 @@ self.assembler.dump('%s <- %s(%s)' % (to_loc, v, from_loc)) self.assembler.regalloc_load(from_loc, to_loc) + def load_float(self, v, from_loc, to_loc): + assert to_loc is st0 + if not we_are_translated(): + self.assembler.dump('%s <- %s(%s)' % (to_loc, v, from_loc)) + self.assembler.regalloc_load_float(from_loc, to_loc) + def Store(self, v, from_loc, to_loc): if not we_are_translated(): self.assembler.dump('%s(%s) -> %s' % (v, from_loc, to_loc)) self.assembler.regalloc_store(from_loc, to_loc) + def store_float(self, v, from_loc, to_loc): + assert from_loc is st0 + if not we_are_translated(): + self.assembler.dump('%s(%s) -> %s' % (v, from_loc, to_loc)) + self.assembler.regalloc_store_float(from_loc, to_loc) + def Perform(self, op, arglocs, result_loc): if not we_are_translated(): self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs)) @@ -274,7 +303,7 @@ # load/store places operations = tree.operations self.position = -1 - self.process_inputargs(tree) + self.current_stack_depth = self.process_inputargs(tree) self._walk_operations(operations) def walk_guard_ops(self, inputargs, operations, exc): @@ -313,7 +342,8 @@ else: nothing = oplist[op.opnum](self, op, None) assert nothing is None # temporary, remove me - self.eventually_free_var(op.result) + if op.result is not None: + self.eventually_free_var(op.result) self._check_invariants() else: self.eventually_free_vars(op.args) @@ -418,7 +448,7 @@ def try_allocate_reg(self, v, selected_reg=None): if isinstance(v, Const): - return convert_to_imm(v) + return self.const_to_operand(v) if selected_reg is not None: res = self.reg_bindings.get(v, None) if res: @@ -461,11 +491,11 @@ if selected_reg or not imm_fine: # this means we cannot have it in IMM, eh if selected_reg in self.free_regs: - self.Load(v, convert_to_imm(v), selected_reg) + self.Load(v, self.const_to_operand(v), selected_reg) return selected_reg if selected_reg is None and self.free_regs: loc = self.free_regs.pop() - self.Load(v, convert_to_imm(v), loc) + self.Load(v, self.const_to_operand(v), loc) return loc v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg) loc = self.loc(v_to_spill) @@ -478,9 +508,9 @@ self.Store(v_to_spill, loc, newloc) del self.reg_bindings[v_to_spill] self.free_regs.append(loc) - self.Load(v, convert_to_imm(v), loc) + self.Load(v, self.const_to_operand(v), loc) return loc - return convert_to_imm(v) + return self.const_to_operand(v) def force_allocate_reg(self, v, forbidden_vars, selected_reg=None): if isinstance(v, Const): @@ -525,7 +555,7 @@ try: res = self.stack_bindings[v] except KeyError: - newloc = stack_pos(self.current_stack_depth) + newloc = stack_pos(self.current_stack_depth, sizeofbox(v)) self.stack_bindings[v] = newloc self.current_stack_depth += 1 res = newloc @@ -560,9 +590,14 @@ self.reg_bindings[to_v] = reg def eventually_free_var(self, v): - if isinstance(v, Const) or v not in self.reg_bindings: + assert v is not None + if (isinstance(v, Const) or + (v not in self.reg_bindings and v is not self.st0)): return if v not in self.longevity or self.longevity[v][1] <= self.position: + if v is self.st0: + self.st0 = None + return self.free_regs.append(self.reg_bindings[v]) del self.reg_bindings[v] @@ -571,8 +606,11 @@ self.eventually_free_var(v) def loc(self, v): + assert v is not None # nonsense if isinstance(v, Const): - return convert_to_imm(v) + return self.const_to_operand(v) + if v is self.st0: + return st0 try: return self.reg_bindings[v] except KeyError: @@ -656,12 +694,37 @@ loc = self.reg_bindings[result_v] return loc + def force_float_result_in_reg(self, result, v): + if self.st0 is v: + if self.longevity[v][1] > self.position: + self.store_float(v, st0, self.stack_loc(v)) + else: + if self.st0 is not None: + self.store_float(self.st0, st0, self.stack_loc(self.st0)) + self.load_float(v, self.loc(v), st0) + self.st0 = result + + def force_float_in_reg(self, v): + if self.st0 is v: + return + if self.st0 is not None: + self.store_float(self.st0, st0, self.stack_loc(self.st0)) + self.load_float(v, self.loc(v), st0) + self.st0 = v + + def force_allocate_float_reg(self, v): + if self.st0 is not None: + self.store_float(self.st0, st0, self.stack_loc(self.st0)) + self.st0 = v + return st0 + def process_inputargs(self, tree): # XXX we can sort out here by longevity if we need something # more optimal inputargs = tree.inputargs locs = [None] * len(inputargs) jump = tree.operations[-1] + stackdepth = 0 if jump.opnum != rop.JUMP: jump = None elif jump.jump_target is not tree: @@ -671,7 +734,9 @@ arg = inputargs[i] assert not isinstance(arg, Const) reg = None - if arg not in self.loop_consts and self.longevity[arg][1] > -1: + boxsize = sizeofbox(arg) + if (arg not in self.loop_consts and self.longevity[arg][1] > -1 and + boxsize == WORD): # only allocate regs for WORD size reg = self.try_allocate_reg(arg) if reg: locs[i] = reg @@ -682,13 +747,15 @@ # jarg = jump.args[i] # self.jump_reg_candidates[jarg] = reg else: - loc = stack_pos(i) + loc = stack_pos(stackdepth, boxsize) self.stack_bindings[arg] = loc locs[i] = loc + stackdepth += boxsize # otherwise we have it saved on stack, so no worry tree.arglocs = locs self.assembler.make_merge_point(tree, locs) self.eventually_free_vars(inputargs) + return stackdepth def regalloc_for_guard(self, guard_op): return self.copy(guard_op) @@ -706,7 +773,7 @@ def consider_fail(self, op, ignored): # make sure all vars are on stack locs = [self.loc(arg) for arg in op.args] - self.assembler.generate_failure(op, locs, self.exc) + self.assembler.generate_failure(op, locs, self.exc, self) self.eventually_free_vars(op.args) def consider_guard_no_exception(self, op, ignored): @@ -790,6 +857,18 @@ consider_int_and = _consider_binop consider_int_or = _consider_binop consider_int_xor = _consider_binop + + def _consider_binop_float(self, op, ignored): + x = op.args[0] + locx = self.loc(x) + self.force_float_result_in_reg(op.result, x) + self.Perform(op, [st0, self.loc(op.args[1])], st0) + self.eventually_free_vars(op.args) + + consider_float_add = _consider_binop_float + consider_float_sub = _consider_binop_float + consider_float_mul = _consider_binop_float + consider_float_truediv = _consider_binop_float def _consider_binop_ovf(self, op, guard_op): loc, argloc = self._consider_binop_part(op, None) @@ -798,7 +877,8 @@ self.perform_with_guard(op, guard_op, regalloc, [loc, argloc], loc, overflow=True) self.eventually_free_vars(guard_op.inputargs) - self.eventually_free_var(guard_op.result) + if guard_op.result is not None: + self.eventually_free_var(guard_op.result) consider_int_mul_ovf = _consider_binop_ovf consider_int_sub_ovf = _consider_binop_ovf @@ -813,7 +893,7 @@ def consider_int_lshift(self, op, ignored): if isinstance(op.args[1], Const): - loc2 = convert_to_imm(op.args[1]) + loc2 = self.const_to_operand(op.args[1]) else: loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx) loc1 = self.force_result_in_reg(op.result, op.args[0], op.args) @@ -1029,8 +1109,13 @@ def consider_setarrayitem_gc(self, op, ignored): scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) - value_loc = self.make_sure_var_in_reg(op.args[2], op.args) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) + if scale > 2: + # float number... + self.force_float_in_reg(op.args[2]) + value_loc = st0 + else: + value_loc = self.make_sure_var_in_reg(op.args[2], op.args) if ptr: gc_ll_descr = self.assembler.cpu.gc_ll_descr gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) @@ -1052,7 +1137,11 @@ base_loc = self.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) self.eventually_free_vars(op.args) - result_loc = self.force_allocate_reg(op.result, []) + if scale == 3: + # float + result_loc = self.force_allocate_float_reg(op.result) + else: + result_loc = self.force_allocate_reg(op.result, []) self.Perform(op, [base_loc, ofs_loc, imm(scale), imm(ofs)], result_loc) consider_getfield_raw = consider_getfield_gc @@ -1164,9 +1253,9 @@ # write the code that moves the correct value into 'res', in two # steps: generate a pair PUSH (immediately) / POP (later) if isinstance(src, MODRM): - src = stack_pos(src.position) + src = stack_pos(src.position, 1) if isinstance(res, MODRM): - res = stack_pos(res.position) + res = stack_pos(res.position, 1) self.assembler.regalloc_push(src) later_pops.append(res) extra_on_stack += 1 @@ -1188,8 +1277,17 @@ num = getattr(rop, name.upper()) oplist[num] = value -def stack_pos(i): - res = mem(ebp, -WORD * (1 + i)) +class WrongSizeForStackPos(Exception): + pass + +def stack_pos(i, size): + if size == 1: + res = mem(ebp, -WORD * (1 + i)) + elif size == 2: + res = mem64(ebp, -WORD * (i + 2)) + else: + raise WrongSizeForStackPos() + assert isinstance(res, MODRM) res.position = i return res Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py Tue Aug 4 06:21:13 2009 @@ -455,15 +455,27 @@ FADDP = Instruction() FADDP.mode0(['\xDE\xC1']) +FADDL = Instruction() +FADDL.mode1(MODRM64, ['\xDC', modrm(1)]) + FSUBP = Instruction() FSUBP.mode0(['\xDE\xE1']) +FSUBL = Instruction() +FSUBL.mode1(MODRM64, ['\xDC', orbyte(4<<3), modrm(1)]) + FMULP = Instruction() FMULP.mode0(['\xDE\xC9']) +FMULL = Instruction() +FMULL.mode1(MODRM64, ['\xDC', orbyte(1<<3), modrm(1)]) + FDIVP = Instruction() FDIVP.mode0(['\xDE\xF1']) +FDIVL = Instruction() +FDIVL.mode1(MODRM64, ['\xDC', orbyte(6<<3), modrm(1)]) + FCHS = Instruction() FCHS.mode0(['\xD9\xE0']) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py Tue Aug 4 06:21:13 2009 @@ -281,6 +281,10 @@ assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_int[index] = intvalue + def set_future_value_float(self, index, floatval): + assert index < MAX_FAIL_BOXES, "overflow!" + self.assembler.fail_boxes_float[index] = floatval + def set_future_value_ptr(self, index, ptrvalue): assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_ptr[index] = ptrvalue @@ -288,6 +292,9 @@ def get_latest_value_int(self, index): return self.assembler.fail_boxes_int[index] + def get_latest_value_float(self, index): + return self.assembler.fail_boxes_float[index] + def get_latest_value_ptr(self, index): ptrvalue = self.assembler.fail_boxes_ptr[index] # clear after reading Added: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/support.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/support.py Tue Aug 4 06:21:13 2009 @@ -0,0 +1,46 @@ + +from pypy.rpython.lltypesystem import lltype, rffi + +CHUNK_SIZE = 100 + +TP = rffi.CArray(lltype.Float) + +class Chunk(object): + def __init__(self, basesize): + self.ll_array = lltype.malloc(TP, basesize, flavor='raw') + self.size = 0 + +class ListOfFloats(object): + def __init__(self, basesize=CHUNK_SIZE): + self.basesize = basesize + self.chunks = [] + self.size = 0 + self.dict = {} + + def length(self): + return self.size + + def append(self, item): + size = self.size + if not size % self.basesize: + self.chunks.append(Chunk(self.basesize)) + self.chunks[-1].ll_array[size % self.basesize] = item + self.size = size + 1 + return size + + def getitem(self, index): + mod = index % self.basesize + return self.chunks[index // self.basesize].ll_array[mod] + + def get(self, item): + index = self.dict.get(item, -1) + if index == -1: + index = self.append(item) + self.dict[item] = index + return index + + def getaddr(self, item): + index = self.get(item) + base = self.chunks[index // self.basesize].ll_array + baseaddr = rffi.cast(lltype.Signed, base) + return baseaddr + (index % self.basesize) * rffi.sizeof(lltype.Float) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Tue Aug 4 06:21:13 2009 @@ -3,6 +3,53 @@ BoxPtr, ConstPtr, TreeLoop from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.runner import CPU +from pypy.jit.metainterp.test.oparser import parse +from pypy.jit.metainterp.test.oparser import parse + +class TestRegalloc(object): + namespace = {} + type_system = 'lltype' + cpu = CPU(None, None) + + def parse(self, s, boxkinds=None): + return parse(s, self.cpu, self.namespace, + type_system=self.type_system, + boxkinds=boxkinds) + + def interpret(self, ops, args): + loop = self.parse(ops) + self.cpu.compile_operations(loop) + for i, arg in enumerate(args): + if isinstance(arg, int): + self.cpu.set_future_value_int(i, arg) + elif isinstance(arg, float): + self.cpu.set_future_value_float(i, arg) + else: + raise NotImplementedError("Arg: %s" % arg) + self.cpu.execute_operations(loop) + + def getfloat(self, index): + return self.cpu.get_latest_value_float(index) + + def test_float_add(self): + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + fail(f2) + ''' + z = 3.5 + self.interpret(ops, [1.5, 2.5]) + assert self.getfloat(0) == 4.0 + + def test_float_add_spill(self): + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + f3 = float_add(1.5, f2) + fail(f3) + ''' + self.interpret(ops, [1.5, 2.5]) + assert self.getfloat(0) == 5.5 def test_bug_rshift(): v1 = BoxInt() Added: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_support.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_support.py Tue Aug 4 06:21:13 2009 @@ -0,0 +1,44 @@ + +from pypy.jit.backend.x86.support import ListOfFloats +from pypy.rpython.lltypesystem import rffi, lltype + +def test_append(): + x = ListOfFloats(2) + assert x.length() == 0 + assert len(x.chunks) == 0 + x.append(3.0) + x.append(2.0) + assert x.length() == 2 + assert len(x.chunks) == 1 + x.append(1.0) + assert x.length() == 3 + assert len(x.chunks) == 2 + assert x.chunks[0].ll_array[0] == 3.0 + assert x.chunks[0].ll_array[1] == 2.0 + assert x.chunks[1].ll_array[0] == 1.0 + +def test_getitem(): + x = ListOfFloats(2) + assert x.append(3.0) == 0 + assert x.append(2.0) == 1 + assert x.append(1.0) == 2 + assert x.getitem(0) == 3.0 + assert x.getitem(1) == 2.0 + assert x.getitem(2) == 1.0 + +def test_get(): + x = ListOfFloats(2) + assert x.get(0.0) == 0 + assert x.get(0.0) == 0 + assert x.get(0.5) == 1 + assert x.get(0.0) == 0 + assert x.get(2.0) == 2 + +def test_getaddr(): + x = ListOfFloats(2) + base = x.getaddr(0.0) + assert x.getaddr(0.0) == base + assert x.getaddr(1.0) - base == rffi.sizeof(lltype.Float) + + + From cfbolz at codespeak.net Wed Aug 5 15:58:23 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 5 Aug 2009 15:58:23 +0200 (CEST) Subject: [pypy-svn] r66748 - in pypy/branch/shrink-multidict/pypy: interpreter module/__builtin__ module/__builtin__/test objspace/std objspace/std/test translator/goal Message-ID: <20090805135823.19901168027@codespeak.net> Author: cfbolz Date: Wed Aug 5 15:58:19 2009 New Revision: 66748 Modified: pypy/branch/shrink-multidict/pypy/interpreter/baseobjspace.py pypy/branch/shrink-multidict/pypy/interpreter/typedef.py pypy/branch/shrink-multidict/pypy/module/__builtin__/interp_classobj.py pypy/branch/shrink-multidict/pypy/module/__builtin__/test/test_classobj.py pypy/branch/shrink-multidict/pypy/objspace/std/celldict.py pypy/branch/shrink-multidict/pypy/objspace/std/dictbucket.py pypy/branch/shrink-multidict/pypy/objspace/std/dictmultiobject.py pypy/branch/shrink-multidict/pypy/objspace/std/dictobject.py pypy/branch/shrink-multidict/pypy/objspace/std/dicttype.py pypy/branch/shrink-multidict/pypy/objspace/std/marshal_impl.py pypy/branch/shrink-multidict/pypy/objspace/std/objspace.py pypy/branch/shrink-multidict/pypy/objspace/std/test/test_celldict.py pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictmultiobject.py pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictobject.py pypy/branch/shrink-multidict/pypy/objspace/std/test/test_shadowtracking.py pypy/branch/shrink-multidict/pypy/objspace/std/typeobject.py pypy/branch/shrink-multidict/pypy/translator/goal/gcbench.py Log: experimental: remove a level of indirection in the non-fallback case of multidicts. Instead of having an .implementation link from W_DictMultiObject to the currently used implementation, make one subclass per former implementation class. Each such instance has a .fallback link which is None by default but points to another such instance when the implementation needs to change. This makes all instances a bit smaller, however so far it seems to lead to some percent performance degradation (in the hard-to-measure region). Modified: pypy/branch/shrink-multidict/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/shrink-multidict/pypy/interpreter/baseobjspace.py Wed Aug 5 15:58:19 2009 @@ -19,6 +19,7 @@ in a 'normal' object space like StdObjSpace.""" __slots__ = () _settled_ = True + user_overridden_class = False def getdict(self): return None Modified: pypy/branch/shrink-multidict/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/interpreter/typedef.py (original) +++ pypy/branch/shrink-multidict/pypy/interpreter/typedef.py Wed Aug 5 15:58:19 2009 @@ -224,6 +224,8 @@ if "user" in features: # generic feature needed by all subcls class Proto(object): + user_overridden_class = True + def getclass(self, space): return self.w__class__ @@ -287,30 +289,20 @@ def user_setup(self, space, w_subtype): self.space = space self.w__class__ = w_subtype - if space.config.objspace.std.withsharingdict: - from pypy.objspace.std import dictmultiobject - self.w__dict__ = dictmultiobject.W_DictMultiObject(space, - sharing=True) - elif space.config.objspace.std.withshadowtracking: - from pypy.objspace.std import dictmultiobject - self.w__dict__ = dictmultiobject.W_DictMultiObject(space) - self.w__dict__.implementation = \ - dictmultiobject.ShadowDetectingDictImplementation( - space, w_subtype) - else: - self.w__dict__ = space.newdict() + self.w__dict__ = space.DictObjectCls.allocate_and_init_instance( + space, instance=True, classofinstance=w_subtype) self.user_setup_slots(w_subtype.nslots) def setclass(self, space, w_subtype): # only used by descr_set___class__ self.w__class__ = w_subtype if space.config.objspace.std.withshadowtracking: - self.w__dict__.implementation.set_shadows_anything() + self.w__dict__.set_shadows_anything() def getdictvalue_attr_is_in_class(self, space, w_name): w_dict = self.w__dict__ if space.config.objspace.std.withshadowtracking: - if not w_dict.implementation.shadows_anything(): + if not w_dict.shadows_anything(): return None return space.finditem(w_dict, w_name) Modified: pypy/branch/shrink-multidict/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/branch/shrink-multidict/pypy/module/__builtin__/interp_classobj.py Wed Aug 5 15:58:19 2009 @@ -303,12 +303,8 @@ class W_InstanceObject(Wrappable): def __init__(self, space, w_class, w_dict=None): if w_dict is None: - if space.config.objspace.std.withsharingdict: - from pypy.objspace.std import dictmultiobject - w_dict = dictmultiobject.W_DictMultiObject(space, - sharing=True) - else: - w_dict = space.newdict() + w_dict = space.DictObjectCls.allocate_and_init_instance( + space, instance=True) assert isinstance(w_class, W_ClassObject) self.w_class = w_class self.w_dict = w_dict Modified: pypy/branch/shrink-multidict/pypy/module/__builtin__/test/test_classobj.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/module/__builtin__/test/test_classobj.py (original) +++ pypy/branch/shrink-multidict/pypy/module/__builtin__/test/test_classobj.py Wed Aug 5 15:58:19 2009 @@ -772,8 +772,7 @@ def is_sharing(space, w_inst): from pypy.objspace.std.dictmultiobject import SharedDictImplementation, W_DictMultiObject w_d = w_inst.getdict() - return space.wrap(isinstance(w_d, W_DictMultiObject) and - isinstance(w_d.implementation, SharedDictImplementation)) + return space.wrap(isinstance(w_d, SharedDictImplementation)) cls.w_is_sharing = cls.space.wrap(gateway.interp2app(is_sharing)) Modified: pypy/branch/shrink-multidict/pypy/objspace/std/celldict.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/celldict.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/celldict.py Wed Aug 5 15:58:19 2009 @@ -1,4 +1,3 @@ -from pypy.objspace.std.dictmultiobject import DictImplementation from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash @@ -14,12 +13,16 @@ def __repr__(self): return "" % (self.w_value, ) -class ModuleDictImplementation(DictImplementation): +class ModuleDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.content = {} self.unshadowed_builtins = {} + def clear(self): + self.content = None + self.unshadowed_builtins = None + def getcell(self, key, make_new=True): try: return self.content[key] @@ -43,14 +46,14 @@ w_value = cell.invalidate() cell = impl.content[name] = ModuleCell(w_value) - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): - return self.setitem_str(w_key, w_value) + return self.impl_setitem_str(w_key, w_value) else: - return self._as_rdict().setitem(w_key, w_value) + return self._as_rdict().impl_setitem(w_key, w_value) - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): name = self.space.str_w(w_key) self.getcell(name).w_value = w_value @@ -60,7 +63,7 @@ return self - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): @@ -72,12 +75,12 @@ elif _is_sane_hash(space, w_key_type): raise KeyError else: - return self._as_rdict().delitem(w_key) + return self._as_rdict().impl_delitem(w_key) - def length(self): + def impl_length(self): return len(self.content) - def get(self, w_lookup): + def impl_getitem(self, w_lookup): space = self.space w_lookup_type = space.type(w_lookup) if space.is_w(w_lookup_type, space.w_str): @@ -88,25 +91,25 @@ elif _is_sane_hash(space, w_lookup_type): return None else: - return self._as_rdict().get(w_lookup) + return self._as_rdict().impl_getitem(w_lookup) - def iteritems(self): + def impl_iteritems(self): return ModuleDictItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return ModuleDictKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return ModuleDictValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): space = self.space return [space.wrap(key) for key in self.content.iterkeys()] - def values(self): + def impl_values(self): return [cell.w_value for cell in self.content.itervalues()] - def items(self): + def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), cell.w_value]) for (key, cell) in self.content.iteritems()] @@ -114,7 +117,7 @@ def _as_rdict(self): newimpl = self.space.DefaultDictImpl(self.space) for k, cell in self.content.iteritems(): - newimpl.setitem(self.space.wrap(k), cell.w_value) + newimpl.impl_setitem(self.space.wrap(k), cell.w_value) cell.invalidate() for k in self.unshadowed_builtins: self.invalidate_unshadowed_builtin(k) @@ -208,8 +211,8 @@ return holder.getcache(space, code, w_globals) def getimplementation(w_dict): - if type(w_dict) is W_DictMultiObject: - return w_dict.implementation + if type(w_dict) is ModuleDictImplementation and w_dict.fallback is None: + return w_dict else: return None Modified: pypy/branch/shrink-multidict/pypy/objspace/std/dictbucket.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/dictbucket.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/dictbucket.py Wed Aug 5 15:58:19 2009 @@ -1,4 +1,4 @@ -from pypy.objspace.std.dictmultiobject import DictImplementation +from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.objspace.std.dictmultiobject import IteratorImplementation @@ -13,13 +13,16 @@ DISTRIBUTE = 9 -class BucketDictImplementation(DictImplementation): +class BucketDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.len = 0 self.table = [None] * 4 + def release_content(self): + self.table = None + def __repr__(self): bs = [] for node in self.table: @@ -30,7 +33,7 @@ bs.append(str(count)) return "%s<%s>" % (self.__class__.__name__, ', '.join(bs)) - def get(self, w_key): + def impl_getitem(self, w_key): space = self.space hash = space.hash_w(w_key) index = (hash * DISTRIBUTE) & (len(self.table) - 1) @@ -41,7 +44,7 @@ node = node.next return None - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): space = self.space hash = space.hash_w(w_key) index = (hash * DISTRIBUTE) & (len(self.table) - 1) @@ -57,10 +60,10 @@ self._resize() return self - def setitem_str(self, w_key, w_value, shadows_type=True): - return self.setitem(w_key, w_value) + def impl_setitem_str(self, w_key, w_value, shadows_type=True): + return self.impl_setitem(w_key, w_value) - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space hash = space.hash_w(w_key) index = (hash * DISTRIBUTE) & (len(self.table) - 1) @@ -82,7 +85,7 @@ node = node.next raise KeyError - def length(self): + def impl_length(self): return self.len def _resize(self): @@ -99,14 +102,14 @@ node = next self.table = newtable - def iteritems(self): + def impl_iteritems(self): return BucketDictItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return BucketDictKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return BucketDictValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): result_w = [] for node in self.table: while node is not None: @@ -114,7 +117,7 @@ node = node.next return result_w - def values(self): + def impl_values(self): result_w = [] for node in self.table: while node is not None: @@ -122,7 +125,7 @@ node = node.next return result_w - def items(self): + def impl_items(self): space = self.space result_w = [] for node in self.table: Modified: pypy/branch/shrink-multidict/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/dictmultiobject.py Wed Aug 5 15:58:19 2009 @@ -22,52 +22,112 @@ ) -# DictImplementation lattice +class W_DictMultiObject(W_Object): + from pypy.objspace.std.dicttype import dict_typedef as typedef -# a dictionary starts with an EmptyDictImplementation, and moves down -# in this list: -# -# EmptyDictImplementation -# / \ -# SmallStrDictImplementation SmallDictImplementation -# | | -# StrDictImplementation | -# \ / -# RDictImplementation -# -# (in addition, any dictionary can go back to EmptyDictImplementation) + fallback = None -class DictImplementation(object): - - def get(self, w_lookup): + def allocate_and_init_instance(space, w_type=None, module=False, + instance=False, classofinstance=None): + if w_type is None: + w_type = space.w_dict + if space.config.objspace.std.withcelldict and module: + from pypy.objspace.std.celldict import ModuleDictImplementation + w_self = space.allocate_instance(ModuleDictImplementation, w_type) + ModuleDictImplementation.__init__(w_self, space) + elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and module: + w_self = space.allocate_instance(WaryDictImplementation, w_type) + WaryDictImplementation.__init__(w_self, space) + elif space.config.objspace.std.withdictmeasurement: + w_self = space.allocate_instance(MeasuringDictImplementation, w_type) + MeasuringDictImplementation.__init__(w_self, space) + elif space.config.objspace.std.withsharingdict and instance: + w_self = space.allocate_instance(SharedDictImplementation, w_type) + SharedDictImplementation.__init__(w_self, space) + elif (space.config.objspace.std.withshadowtracking and instance and + classofinstance is not None): + w_self = ShadowDetectingDictImplementation(space, classofinstance) + else: + # XXX what is the right choice here? + w_self = space.allocate_instance(EmptyDictImplementation, w_type) + EmptyDictImplementation.__init__(w_self, space) + return w_self + allocate_and_init_instance = staticmethod(allocate_and_init_instance) + + def initialize_content(w_self, list_pairs_w): + for w_k, w_v in list_pairs_w: + w_self.setitem(w_k, w_v) + + def initialize_from_strdict_shared(w_self, strdict): + # XXX quite bad + impl = StrDictImplementation(w_self.space) + impl.content = strdict + w_self.release_content() + w_self.fallback = impl + + def __repr__(w_self): + """ representation for debugging purposes """ + return "%s(%s)" % (w_self.__class__.__name__, w_self.fallback) + + def unwrap(w_dict, space): + result = {} + items = w_dict.items() + for w_pair in items: + key, val = space.unwrap(w_pair) + result[key] = val + return result + + def missing_method(w_dict, space, w_key): + if not space.is_w(space.type(w_dict), space.w_dict): + w_missing = space.lookup(w_dict, "__missing__") + if w_missing is None: + return None + return space.call_function(w_missing, w_dict, w_key) + else: + return None + + def get(w_dict, w_key, w_default): + w_value = w_dict.getitem(w_key) + if w_value is not None: + return w_value + else: + return w_default + + def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True): + w_dict.setitem_str(w_key, w_value, shadows_type) + + # _________________________________________________________________ + # implementation methods + + def impl_getitem(self, w_lookup): #return w_value or None raise NotImplementedError("abstract base class") - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): #return implementation raise NotImplementedError("abstract base class") - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): #return implementation raise NotImplementedError("abstract base class") - def delitem(self, w_key): + def impl_delitem(self, w_key): #return implementation raise NotImplementedError("abstract base class") - def length(self): + def impl_length(self): raise NotImplementedError("abstract base class") - def iteritems(self): + def impl_iteritems(self): raise NotImplementedError("abstract base class") - def iterkeys(self): + def impl_iterkeys(self): raise NotImplementedError("abstract base class") - def itervalues(self): + def impl_itervalues(self): raise NotImplementedError("abstract base class") - def keys(self): - iterator = self.iterkeys() + def impl_keys(self): + iterator = self.impl_iterkeys() result = [] while 1: w_key = iterator.next() @@ -75,8 +135,8 @@ result.append(w_key) else: return result - def values(self): - iterator = self.itervalues() + def impl_values(self): + iterator = self.impl_itervalues() result = [] while 1: w_value = iterator.next() @@ -84,8 +144,8 @@ result.append(w_value) else: return result - def items(self): - iterator = self.iteritems() + def impl_items(self): + iterator = self.impl_iteritems() result = [] while 1: w_item = iterator.next() @@ -94,20 +154,89 @@ else: return result -# the following method only makes sense when the option to use the -# CALL_LIKELY_BUILTIN opcode is set. Otherwise it won't even be seen -# by the annotator - def get_builtin_indexed(self, i): + # the following method only makes sense when the option to use the + # CALL_LIKELY_BUILTIN opcode is set. Otherwise it won't even be seen + # by the annotator + def impl_get_builtin_indexed(self, i): w_key = self.space.wrap(OPTIMIZED_BUILTINS[i]) - return self.get(w_key) + return self.impl_getitem(w_key) -# this method will only be seen whan a certain config option is used - def shadows_anything(self): + # this method will only be seen whan a certain config option is used + def impl_shadows_anything(self): return True - def set_shadows_anything(self): + def impl_set_shadows_anything(self): + pass + + def release_content(self): pass +implementation_methods = [ + ("getitem", False), + ("length", False), + ("setitem_str", True), + ("setitem", True), + ("delitem", True), + ("iteritems", False), + ("itervalues", False), + ("iterkeys", False), + ("items", False), + ("values", False), + ("keys", False), + ("get_builtin_indexed", False), + ("shadows_anything", False), + ("set_shadows_anything", False), +] + + +def _make_normal_method(name): + def implementation_method(self, *args): + if self.fallback: + self = self.fallback + assert self.fallback is None + return getattr(self, name)(*args) + return implementation_method + +def _make_switching_method(name): + def implementation_method(self, *args): + orig = self + if self.fallback: + self = self.fallback + assert self.fallback is None + newimpl = getattr(self, name)(*args) + if newimpl is not self: + orig.release_content() + orig.fallback = newimpl + return implementation_method + +def _install_methods(): + for name, is_switching in implementation_methods: + implname = "impl_" + name + if is_switching: + func = _make_switching_method(implname) + else: + func = _make_normal_method(implname) + setattr(W_DictMultiObject, name, func) +_install_methods() + + +registerimplementation(W_DictMultiObject) + +# DictImplementation lattice + +# a dictionary starts with an EmptyDictImplementation, and moves down +# in this list: +# +# EmptyDictImplementation +# / \ +# SmallStrDictImplementation SmallDictImplementation +# | | +# StrDictImplementation | +# \ / +# RDictImplementation +# +# (in addition, any dictionary can go back to EmptyDictImplementation) + # Iterator Implementation base classes @@ -148,11 +277,12 @@ # concrete subclasses of the above -class EmptyDictImplementation(DictImplementation): +# XXX needs to go? +class EmptyDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space - def get(self, w_lookup): + def impl_getitem(self, w_lookup): space = self.space if not _is_str(space, w_lookup) and not _is_sane_hash(space, space.type(w_lookup)): @@ -160,23 +290,24 @@ space.hash(w_lookup) return None - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): space = self.space if _is_str(space, w_key): if space.config.objspace.std.withsmalldicts: return SmallStrDictImplementation(space, w_key, w_value) else: - return StrDictImplementation(space).setitem_str(w_key, w_value) + return StrDictImplementation(space).impl_setitem_str(w_key, w_value) else: if space.config.objspace.std.withsmalldicts: return SmallDictImplementation(space, w_key, w_value) else: - return space.DefaultDictImpl(space).setitem(w_key, w_value) - def setitem_str(self, w_key, w_value, shadows_type=True): - return StrDictImplementation(self.space).setitem_str(w_key, w_value) + return space.DefaultDictImpl(space).impl_setitem(w_key, w_value) + + def impl_setitem_str(self, w_key, w_value, shadows_type=True): + return StrDictImplementation(self.space).impl_setitem_str(w_key, w_value) #return SmallStrDictImplementation(self.space, w_key, w_value) - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space if not _is_str(space, w_key) and not _is_sane_hash(space, space.type(w_key)): @@ -184,21 +315,21 @@ space.hash(w_key) raise KeyError - def length(self): + def impl_length(self): return 0 - def iteritems(self): + def impl_iteritems(self): return EmptyIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return EmptyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return EmptyIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): return [] - def values(self): + def impl_values(self): return [] - def items(self): + def impl_items(self): return [] @@ -214,7 +345,7 @@ def __repr__(self): return '<%r, %r, %r>'%(self.hash, self.w_key, self.w_value) -class SmallDictImplementation(DictImplementation): +class SmallDictImplementation(W_DictMultiObject): # XXX document the invariants here! def __init__(self, space, w_key, w_value): @@ -225,6 +356,9 @@ self.entries[0].w_value = w_value self.valid = 1 + def release_content(self): + self.entries = None + def _lookup(self, w_key): hash = self.space.hash_w(w_key) i = 0 @@ -244,23 +378,23 @@ entry = self.entries[i] if entry.w_value is None: break - newimpl.setitem(entry.w_key, entry.w_value) + newimpl.impl_setitem(entry.w_key, entry.w_value) i += 1 return newimpl - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): entry = self._lookup(w_key) if entry.w_value is None: if self.valid == 4: - return self._convert_to_rdict().setitem(w_key, w_value) + return self._convert_to_rdict().impl_setitem(w_key, w_value) self.valid += 1 entry.w_value = w_value return self - def setitem_str(self, w_key, w_value, shadows_type=True): - return self.setitem(w_key, w_value) + def impl_setitem_str(self, w_key, w_value, shadows_type=True): + return self.impl_setitem(w_key, w_value) - def delitem(self, w_key): + def impl_delitem(self, w_key): entry = self._lookup(w_key) if entry.w_value is not None: for i in range(self.entries.index(entry), self.valid): @@ -275,27 +409,27 @@ entry.w_key = None raise KeyError - def length(self): + def impl_length(self): return self.valid - def get(self, w_lookup): + def impl_getitem(self, w_lookup): entry = self._lookup(w_lookup) val = entry.w_value if val is None: entry.w_key = None return val - def iteritems(self): - return self._convert_to_rdict().iteritems() - def iterkeys(self): - return self._convert_to_rdict().iterkeys() - def itervalues(self): - return self._convert_to_rdict().itervalues() + def impl_iteritems(self): + return self._convert_to_rdict().impl_iteritems() + def impl_iterkeys(self): + return self._convert_to_rdict().impl_iterkeys() + def impl_itervalues(self): + return self._convert_to_rdict().impl_itervalues() - def keys(self): + def impl_keys(self): return [self.entries[i].w_key for i in range(self.valid)] - def values(self): + def impl_values(self): return [self.entries[i].w_value for i in range(self.valid)] - def items(self): + def impl_items(self): return [self.space.newtuple([e.w_key, e.w_value]) for e in [self.entries[i] for i in range(self.valid)]] @@ -307,7 +441,7 @@ def __repr__(self): return '<%r, %r, %r>'%(self.hash, self.key, self.w_value) -class SmallStrDictImplementation(DictImplementation): +class SmallStrDictImplementation(W_DictMultiObject): # XXX document the invariants here! def __init__(self, space, w_key, w_value): @@ -318,6 +452,9 @@ self.entries[0].w_value = w_value self.valid = 1 + def release_content(self): + self.entries = None + def _lookup(self, key): assert isinstance(key, str) _hash = hash(key) @@ -337,7 +474,7 @@ entry = self.entries[i] if entry.w_value is None: break - newimpl.setitem(self.space.wrap(entry.key), entry.w_value) + newimpl.impl_setitem(self.space.wrap(entry.key), entry.w_value) i += 1 return newimpl @@ -355,12 +492,12 @@ i += 1 return newimpl - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): if not _is_str(self.space, w_key): - return self._convert_to_rdict().setitem(w_key, w_value) - return self.setitem_str(w_key, w_value) + return self._convert_to_rdict().impl_setitem(w_key, w_value) + return self.impl_setitem_str(w_key, w_value) - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): entry = self._lookup(self.space.str_w(w_key)) if entry.w_value is None: if self.valid == 4: @@ -369,7 +506,7 @@ entry.w_value = w_value return self - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): @@ -389,12 +526,12 @@ elif _is_sane_hash(self.space, w_key_type): raise KeyError else: - return self._convert_to_rdict().delitem(w_key) + return self._convert_to_rdict().impl_delitem(w_key) - def length(self): + def impl_length(self): return self.valid - def get(self, w_lookup): + def impl_getitem(self, w_lookup): space = self.space w_lookup_type = space.type(w_lookup) if space.is_w(w_lookup_type, space.w_str): @@ -406,41 +543,44 @@ elif _is_sane_hash(self.space, w_lookup_type): return None else: - return self._convert_to_rdict().get(w_lookup) + return self._convert_to_rdict().impl_getitem(w_lookup) - def iteritems(self): - return self._convert_to_rdict().iteritems() - def iterkeys(self): - return self._convert_to_rdict().iterkeys() - def itervalues(self): - return self._convert_to_rdict().itervalues() + def impl_iteritems(self): + return self._convert_to_rdict().impl_iteritems() + def impl_iterkeys(self): + return self._convert_to_rdict().impl_iterkeys() + def impl_itervalues(self): + return self._convert_to_rdict().impl_itervalues() - def keys(self): + def impl_keys(self): return [self.space.wrap(self.entries[i].key) for i in range(self.valid)] - def values(self): + def impl_values(self): return [self.entries[i].w_value for i in range(self.valid)] - def items(self): + def impl_items(self): return [self.space.newtuple([self.space.wrap(e.key), e.w_value]) for e in [self.entries[i] for i in range(self.valid)]] -class StrDictImplementation(DictImplementation): +class StrDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.content = {} - - def setitem(self, w_key, w_value): + + def release_content(self): + self.content = None + + def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): - return self.setitem_str(w_key, w_value) + return self.impl_setitem_str(w_key, w_value) else: - return self._as_rdict().setitem(w_key, w_value) + return self._as_rdict().impl_setitem(w_key, w_value) - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): self.content[self.space.str_w(w_key)] = w_value return self - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): @@ -452,12 +592,12 @@ elif _is_sane_hash(space, w_key_type): raise KeyError else: - return self._as_rdict().delitem(w_key) + return self._as_rdict().impl_delitem(w_key) - def length(self): + def impl_length(self): return len(self.content) - def get(self, w_lookup): + def impl_getitem(self, w_lookup): space = self.space # -- This is called extremely often. Hack for performance -- if type(w_lookup) is space.StringObjectCls: @@ -469,25 +609,25 @@ elif _is_sane_hash(space, w_lookup_type): return None else: - return self._as_rdict().get(w_lookup) + return self._as_rdict().impl_getitem(w_lookup) - def iteritems(self): + def impl_iteritems(self): return StrItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return StrKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return StrValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): space = self.space return [space.wrap(key) for key in self.content.iterkeys()] - def values(self): + def impl_values(self): return self.content.values() - def items(self): + def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), w_value]) for (key, w_value) in self.content.iteritems()] @@ -496,7 +636,7 @@ def _as_rdict(self): newimpl = self.space.DefaultDictImpl(self.space) for k, w_v in self.content.items(): - newimpl.setitem(self.space.wrap(k), w_v) + newimpl.impl_setitem(self.space.wrap(k), w_v) return newimpl # the following are very close copies of the base classes above @@ -548,29 +688,35 @@ else: self._shadows_anything = False - def setitem_str(self, w_key, w_value, shadows_type=True): + def release_content(self): + StrDictImplementation.release_content(self) + self.w_type = None + self.original_version_tag = None + + + def impl_setitem_str(self, w_key, w_value, shadows_type=True): if shadows_type: self._shadows_anything = True - return StrDictImplementation.setitem_str( + return StrDictImplementation.impl_setitem_str( self, w_key, w_value, shadows_type) - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): if not self._shadows_anything: w_obj = self.w_type.lookup(space.str_w(w_key)) if w_obj is not None: self._shadows_anything = True - return StrDictImplementation.setitem_str( + return StrDictImplementation.impl_setitem_str( self, w_key, w_value, False) else: - return self._as_rdict().setitem(w_key, w_value) + return self._as_rdict().impl_setitem(w_key, w_value) - def shadows_anything(self): + def impl_shadows_anything(self): return (self._shadows_anything or self.w_type.version_tag is not self.original_version_tag) - def set_shadows_anything(self): + def impl_set_shadows_anything(self): self._shadows_anything = True class WaryDictImplementation(StrDictImplementation): @@ -578,7 +724,11 @@ StrDictImplementation.__init__(self, space) self.shadowed = [None] * len(BUILTIN_TO_INDEX) - def setitem_str(self, w_key, w_value, shadows_type=True): + def release_content(self): + StrDictImplementation.release_content(self) + self.shadowed = None + + def impl_setitem_str(self, w_key, w_value, shadows_type=True): key = self.space.str_w(w_key) i = BUILTIN_TO_INDEX.get(key, -1) if i != -1: @@ -586,7 +736,7 @@ self.content[key] = w_value return self - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): @@ -599,50 +749,53 @@ elif _is_sane_hash(space, w_key_type): raise KeyError else: - return self._as_rdict().delitem(w_key) + return self._as_rdict().impl_delitem(w_key) - def get_builtin_indexed(self, i): + def impl_get_builtin_indexed(self, i): return self.shadowed[i] -class RDictImplementation(DictImplementation): +class RDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.content = r_dict(space.eq_w, space.hash_w) + def release_content(self): + self.content = None + def __repr__(self): return "%s<%s>" % (self.__class__.__name__, self.content) - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): self.content[w_key] = w_value return self - def setitem_str(self, w_key, w_value, shadows_type=True): - return self.setitem(w_key, w_value) + def impl_setitem_str(self, w_key, w_value, shadows_type=True): + return self.impl_setitem(w_key, w_value) - def delitem(self, w_key): + def impl_delitem(self, w_key): del self.content[w_key] if self.content: return self else: return self.space.emptydictimpl - def length(self): + def impl_length(self): return len(self.content) - def get(self, w_lookup): + def impl_getitem(self, w_lookup): return self.content.get(w_lookup, None) - def iteritems(self): + def impl_iteritems(self): return RDictItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return RDictKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return RDictValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): return self.content.keys() - def values(self): + def impl_values(self): return self.content.values() - def items(self): + def impl_items(self): return [self.space.newtuple([w_key, w_val]) for w_key, w_val in self.content.iteritems()] @@ -722,14 +875,18 @@ self.empty_structure.propagating = True -class SharedDictImplementation(DictImplementation): +class SharedDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.structure = space.fromcache(State).empty_structure self.entries = [] - def get(self, w_lookup): + def release_content(self): + self.structure = None + self.entries = None + + def impl_getitem(self, w_lookup): space = self.space w_lookup_type = space.type(w_lookup) if space.is_w(w_lookup_type, space.w_str): @@ -741,16 +898,16 @@ elif _is_sane_hash(space, w_lookup_type): return None else: - return self._as_rdict().get(w_lookup) + return self._as_rdict().impl_getitem(w_lookup) - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): - return self.setitem_str(w_key, w_value) + return self.impl_setitem_str(w_key, w_value) else: - return self._as_rdict().setitem(w_key, w_value) + return self._as_rdict().impl_setitem(w_key, w_value) - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): m = ~len(self.structure.other_structs) key = self.space.str_w(w_key) i = self.structure.keys.get(key, m) @@ -758,7 +915,7 @@ self.entries[i] = w_value return self if not self.structure.propagating: - return self._as_rdict(as_strdict=True).setitem_str(w_key, w_value) + return self._as_rdict(as_strdict=True).impl_setitem_str(w_key, w_value) if i == m: new_structure = self.structure.new_structure(key) else: @@ -770,7 +927,7 @@ assert self.structure.keys[key] >= 0 return self - def delitem(self, w_key): + def impl_delitem(self, w_key): space = self.space w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): @@ -780,34 +937,34 @@ self.entries.pop() self.structure = self.structure.back_struct return self - return self._as_rdict().delitem(w_key) + return self._as_rdict().impl_delitem(w_key) elif _is_sane_hash(space, w_key_type): raise KeyError else: - return self._as_rdict().delitem(w_key) + return self._as_rdict().impl_delitem(w_key) - def length(self): + def impl_length(self): return self.structure.length - def iteritems(self): + def impl_iteritems(self): return SharedItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): return SharedKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): return SharedValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): space = self.space return [space.wrap(key) for (key, item) in self.structure.keys.iteritems() if item >= 0] - def values(self): + def impl_values(self): return self.entries[:] - def items(self): + def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), self.entries[item]]) for (key, item) in self.structure.keys.iteritems() @@ -820,7 +977,7 @@ newimpl = self.space.DefaultDictImpl(self.space) for k, i in self.structure.keys.items(): if i >= 0: - newimpl.setitem_str(self.space.wrap(k), self.entries[i]) + newimpl.impl_setitem_str(self.space.wrap(k), self.entries[i]) return newimpl @@ -922,13 +1079,16 @@ def __del__(self): self.info.lifetime = time.time() - self.info.createtime -class MeasuringDictImplementation(DictImplementation): +class MeasuringDictImplementation(W_DictMultiObject): def __init__(self, space): self.space = space self.content = r_dict(space.eq_w, space.hash_w) self.info = DictInfo() self.thing_with_del = OnTheWayOut(self.info) + def release_content(self): + raise NotImplementedError("should never be called") + def __repr__(self): return "%s<%s>" % (self.__class__.__name__, self.content) @@ -948,7 +1108,7 @@ else: self.info.misses += 1 - def setitem(self, w_key, w_value): + def impl_setitem(self, w_key, w_value): if not self.info.seen_non_string_in_write and not self._is_str(w_key): self.info.seen_non_string_in_write = True self.info.size_on_non_string_seen_in_write = len(self.content) @@ -957,10 +1117,10 @@ self.content[w_key] = w_value self.info.maxcontents = max(self.info.maxcontents, len(self.content)) return self - def setitem_str(self, w_key, w_value, shadows_type=True): + def impl_setitem_str(self, w_key, w_value, shadows_type=True): self.info.setitem_strs += 1 - return self.setitem(w_key, w_value) - def delitem(self, w_key): + return self.impl_setitem(w_key, w_value) + def impl_delitem(self, w_key): if not self.info.seen_non_string_in_write \ and not self.info.seen_non_string_in_read_first \ and not self._is_str(w_key): @@ -971,36 +1131,36 @@ del self.content[w_key] return self - def length(self): + def impl_length(self): self.info.lengths += 1 return len(self.content) - def get(self, w_lookup): + def impl_getitem(self, w_lookup): self.info.gets += 1 self._read(w_lookup) return self.content.get(w_lookup, None) - def iteritems(self): + def impl_iteritems(self): self.info.iteritems += 1 self.info.iterations += 1 return RDictItemIteratorImplementation(self.space, self) - def iterkeys(self): + def impl_iterkeys(self): self.info.iterkeys += 1 self.info.iterations += 1 return RDictKeyIteratorImplementation(self.space, self) - def itervalues(self): + def impl_itervalues(self): self.info.itervalues += 1 self.info.iterations += 1 return RDictValueIteratorImplementation(self.space, self) - def keys(self): + def impl_keys(self): self.info.keys += 1 self.info.listings += 1 return self.content.keys() - def values(self): + def impl_values(self): self.info.values += 1 self.info.listings += 1 return self.content.values() - def items(self): + def impl_items(self): self.info.items += 1 self.info.listings += 1 return [self.space.newtuple([w_key, w_val]) @@ -1034,78 +1194,11 @@ os.close(fd) os.write(2, "Reporting done.\n") -class W_DictMultiObject(W_Object): - from pypy.objspace.std.dicttype import dict_typedef as typedef - - def __init__(w_self, space, module=False, sharing=False): - if space.config.objspace.std.withcelldict and module: - from pypy.objspace.std.celldict import ModuleDictImplementation - w_self.implementation = ModuleDictImplementation(space) - elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and module: - w_self.implementation = WaryDictImplementation(space) - elif space.config.objspace.std.withdictmeasurement: - w_self.implementation = MeasuringDictImplementation(space) - elif space.config.objspace.std.withsharingdict and sharing: - w_self.implementation = SharedDictImplementation(space) - else: - w_self.implementation = space.emptydictimpl - w_self.space = space - - def initialize_content(w_self, list_pairs_w): - impl = w_self.implementation - for w_k, w_v in list_pairs_w: - impl = impl.setitem(w_k, w_v) - w_self.implementation = impl - - def initialize_from_strdict_shared(w_self, strdict): - impl = StrDictImplementation(w_self.space) - impl.content = strdict - w_self.implementation = impl - - def __repr__(w_self): - """ representation for debugging purposes """ - return "%s(%s)" % (w_self.__class__.__name__, w_self.implementation) - - def unwrap(w_dict, space): - result = {} - items = w_dict.implementation.items() - for w_pair in items: - key, val = space.unwrap(w_pair) - result[key] = val - return result - - def missing_method(w_dict, space, w_key): - if not space.is_w(space.type(w_dict), space.w_dict): - w_missing = space.lookup(w_dict, "__missing__") - if w_missing is None: - return None - return space.call_function(w_missing, w_dict, w_key) - else: - return None - - def len(w_self): - return w_self.implementation.length() - - def get(w_dict, w_key, w_default): - w_value = w_dict.implementation.get(w_key) - if w_value is not None: - return w_value - else: - return w_default - - def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True): - w_dict.implementation = w_dict.implementation.setitem_str( - w_key, w_value, shadows_type) - -registerimplementation(W_DictMultiObject) - def init__DictMulti(space, w_dict, __args__): w_src, w_kwds = __args__.parse('dict', (['seq_or_map'], None, 'kwargs'), # signature - [W_DictMultiObject(space)]) # default argument - # w_dict.implementation = space.emptydictimpl - # ^^^ disabled only for CPython compatibility + [W_DictMultiObject.allocate_and_init_instance(space)]) # default argument if space.findattr(w_src, space.wrap("keys")) is None: list_of_w_pairs = space.unpackiterable(w_src) for w_pair in list_of_w_pairs: @@ -1114,7 +1207,7 @@ raise OperationError(space.w_ValueError, space.wrap("dict() takes a sequence of pairs")) w_k, w_v = pair - w_dict.implementation = w_dict.implementation.setitem(w_k, w_v) + w_dict.setitem(w_k, w_v) else: if space.is_true(w_src): from pypy.objspace.std.dicttype import update1 @@ -1124,7 +1217,7 @@ update1(space, w_dict, w_kwds) def getitem__DictMulti_ANY(space, w_dict, w_lookup): - w_value = w_dict.implementation.get(w_lookup) + w_value = w_dict.getitem(w_lookup) if w_value is not None: return w_value @@ -1135,51 +1228,51 @@ space.raise_key_error(w_lookup) def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue): - w_dict.implementation = w_dict.implementation.setitem(w_newkey, w_newvalue) + w_dict.setitem(w_newkey, w_newvalue) def delitem__DictMulti_ANY(space, w_dict, w_lookup): try: - w_dict.implementation = w_dict.implementation.delitem(w_lookup) + w_dict.delitem(w_lookup) except KeyError: space.raise_key_error(w_lookup) def len__DictMulti(space, w_dict): - return space.wrap(w_dict.implementation.length()) + return space.wrap(w_dict.length()) def contains__DictMulti_ANY(space, w_dict, w_lookup): - return space.newbool(w_dict.implementation.get(w_lookup) is not None) + return space.newbool(w_dict.getitem(w_lookup) is not None) dict_has_key__DictMulti_ANY = contains__DictMulti_ANY def iter__DictMulti(space, w_dict): - return W_DictMultiIterObject(space, w_dict.implementation.iterkeys()) + return W_DictMultiIterObject(space, w_dict.iterkeys()) def eq__DictMulti_DictMulti(space, w_left, w_right): if space.is_w(w_left, w_right): return space.w_True - if w_left.implementation.length() != w_right.implementation.length(): + if w_left.length() != w_right.length(): return space.w_False - iteratorimplementation = w_left.implementation.iteritems() + iteratorimplementation = w_left.iteritems() while 1: w_item = iteratorimplementation.next() if w_item is None: break w_key = space.getitem(w_item, space.wrap(0)) w_val = space.getitem(w_item, space.wrap(1)) - w_rightval = w_right.implementation.get(w_key) + w_rightval = w_right.getitem(w_key) if w_rightval is None: return space.w_False if not space.eq_w(w_val, w_rightval): return space.w_False return space.w_True -def characterize(space, aimpl, bimpl): +def characterize(space, w_a, w_b): """ (similar to CPython) returns the smallest key in acontent for which b's value is different or absent and this value """ w_smallest_diff_a_key = None w_its_value = None - iteratorimplementation = aimpl.iteritems() + iteratorimplementation = w_a.iteritems() while 1: w_item = iteratorimplementation.next() if w_item is None: @@ -1187,7 +1280,7 @@ w_key = space.getitem(w_item, space.wrap(0)) w_val = space.getitem(w_item, space.wrap(1)) if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)): - w_bvalue = bimpl.get(w_key) + w_bvalue = w_b.getitem(w_key) if w_bvalue is None: w_its_value = w_val w_smallest_diff_a_key = w_key @@ -1199,18 +1292,16 @@ def lt__DictMulti_DictMulti(space, w_left, w_right): # Different sizes, no problem - leftimpl = w_left.implementation - rightimpl = w_right.implementation - if leftimpl.length() < rightimpl.length(): + if w_left.length() < w_right.length(): return space.w_True - if leftimpl.length() > rightimpl.length(): + if w_left.length() > w_right.length(): return space.w_False # Same size - w_leftdiff, w_leftval = characterize(space, leftimpl, rightimpl) + w_leftdiff, w_leftval = characterize(space, w_left, w_right) if w_leftdiff is None: return space.w_False - w_rightdiff, w_rightval = characterize(space, rightimpl, leftimpl) + w_rightdiff, w_rightval = characterize(space, w_right, w_left) if w_rightdiff is None: # w_leftdiff is not None, w_rightdiff is None return space.w_True @@ -1223,30 +1314,32 @@ def dict_copy__DictMulti(space, w_self): from pypy.objspace.std.dicttype import update1 - w_new = W_DictMultiObject(space) + w_new = W_DictMultiObject.allocate_and_init_instance(space) update1(space, w_new, w_self) return w_new def dict_items__DictMulti(space, w_self): - return space.newlist(w_self.implementation.items()) + return space.newlist(w_self.items()) def dict_keys__DictMulti(space, w_self): - return space.newlist(w_self.implementation.keys()) + return space.newlist(w_self.keys()) def dict_values__DictMulti(space, w_self): - return space.newlist(w_self.implementation.values()) + return space.newlist(w_self.values()) def dict_iteritems__DictMulti(space, w_self): - return W_DictMultiIterObject(space, w_self.implementation.iteritems()) + return W_DictMultiIterObject(space, w_self.iteritems()) def dict_iterkeys__DictMulti(space, w_self): - return W_DictMultiIterObject(space, w_self.implementation.iterkeys()) + return W_DictMultiIterObject(space, w_self.iterkeys()) def dict_itervalues__DictMulti(space, w_self): - return W_DictMultiIterObject(space, w_self.implementation.itervalues()) + return W_DictMultiIterObject(space, w_self.itervalues()) def dict_clear__DictMulti(space, w_self): - w_self.implementation = space.emptydictimpl + # XXX what to do here? + w_self.release_content() + w_self.fallback = space.emptydictimpl def dict_get__DictMulti_ANY_ANY(space, w_dict, w_lookup, w_default): return w_dict.get(w_lookup, w_default) @@ -1256,21 +1349,21 @@ len_defaults = len(defaults) if len_defaults > 1: raise OperationError(space.w_TypeError, space.wrap("pop expected at most 2 arguments, got %d" % (1 + len_defaults, ))) - w_item = w_dict.implementation.get(w_key) + w_item = w_dict.getitem(w_key) if w_item is None: if len_defaults > 0: return defaults[0] else: space.raise_key_error(w_key) else: - w_dict.implementation.delitem(w_key) + w_dict.delitem(w_key) return w_item from pypy.objspace.std.dictobject import dictrepr def repr__DictMulti(space, w_dict): - if w_dict.implementation.length() == 0: + if w_dict.length() == 0: return space.wrap('{}') ec = space.getexecutioncontext() w_currently_in_repr = ec._py_repr Modified: pypy/branch/shrink-multidict/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/dictobject.py Wed Aug 5 15:58:19 2009 @@ -15,6 +15,15 @@ w_self.content = w_otherdict.content.copy() w_self.space = space + def allocate_and_init_instance(space, w_type=None, module=False, + instance=False, classofinstance=None): + if w_type is None: + w_type = space.w_dict + w_obj = space.allocate_instance(W_DictObject, w_type) + W_DictObject.__init__(w_obj, space) + return w_obj + allocate_and_init_instance = staticmethod(allocate_and_init_instance) + def initialize_content(w_self, list_pairs_w): for w_k, w_v in list_pairs_w: w_self.content[w_k] = w_v @@ -36,7 +45,7 @@ result[space.unwrap(w_key)] = space.unwrap(w_value) return result - def len(w_self): + def length(w_self): return len(w_self.content) def get(w_dict, w_lookup, w_default): Modified: pypy/branch/shrink-multidict/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/dicttype.py Wed Aug 5 15:58:19 2009 @@ -141,8 +141,7 @@ # ____________________________________________________________ def descr__new__(space, w_dicttype, __args__): - w_obj = space.allocate_instance(space.DictObjectCls, w_dicttype) - space.DictObjectCls.__init__(w_obj, space) + w_obj = space.DictObjectCls.allocate_and_init_instance(space, w_dicttype) return w_obj # ____________________________________________________________ Modified: pypy/branch/shrink-multidict/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/marshal_impl.py Wed Aug 5 15:58:19 2009 @@ -342,7 +342,7 @@ def marshal_w__DictMulti(space, w_dict, m): m.start(TYPE_DICT) - for w_tuple in w_dict.implementation.items(): + for w_tuple in w_dict.items(): w_key, w_value = space.viewiterable(w_tuple, 2) m.put_w_obj(w_key) m.put_w_obj(w_value) Modified: pypy/branch/shrink-multidict/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/objspace.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/objspace.py Wed Aug 5 15:58:19 2009 @@ -141,13 +141,13 @@ w_globals = f.w_globals num = oparg >> 8 assert isinstance(w_globals, W_DictMultiObject) - w_value = w_globals.implementation.get_builtin_indexed(num) + w_value = w_globals.get_builtin_indexed(num) if w_value is None: builtins = f.get_builtin() assert isinstance(builtins, Module) w_builtin_dict = builtins.w_dict assert isinstance(w_builtin_dict, W_DictMultiObject) - w_value = w_builtin_dict.implementation.get_builtin_indexed(num) + w_value = w_builtin_dict.get_builtin_indexed(num) ## if w_value is not None: ## print "CALL_LIKELY_BUILTIN fast" if w_value is None: @@ -590,10 +590,7 @@ return W_ListObject(list_w) def newdict(self, module=False): - if self.config.objspace.std.withmultidict and module: - from pypy.objspace.std.dictmultiobject import W_DictMultiObject - return W_DictMultiObject(self, module=True) - return self.DictObjectCls(self) + return self.DictObjectCls.allocate_and_init_instance(self, module=module) def newslice(self, w_start, w_end, w_step): return W_SliceObject(w_start, w_end, w_step) @@ -747,13 +744,21 @@ def finditem(self, w_obj, w_key): # performance shortcut to avoid creating the OperationError(KeyError) - if type(w_obj) is self.DictObjectCls: + if (self.config.objspace.std.withmultidict and + isinstance(w_obj, self.DictObjectCls) and + not w_obj.user_overridden_class) or ( + not self.config.objspace.std.withmultidict and + type(w_obj) is self.DictObjectCls): return w_obj.get(w_key, None) return ObjSpace.finditem(self, w_obj, w_key) def set_str_keyed_item(self, w_obj, w_key, w_value, shadows_type=True): # performance shortcut to avoid creating the OperationError(KeyError) - if type(w_obj) is self.DictObjectCls: + if (self.config.objspace.std.withmultidict and + isinstance(w_obj, self.DictObjectCls) and + not w_obj.user_overridden_class) or ( + not self.config.objspace.std.withmultidict and + type(w_obj) is self.DictObjectCls): w_obj.set_str_keyed_item(w_key, w_value, shadows_type) else: self.setitem(w_obj, w_key, w_value) Modified: pypy/branch/shrink-multidict/pypy/objspace/std/test/test_celldict.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/test/test_celldict.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/test/test_celldict.py Wed Aug 5 15:58:19 2009 @@ -26,7 +26,7 @@ def rescue_builtins(space): w_dict = space.builtin.getdict() content = {} - for key, cell in w_dict.implementation.content.iteritems(): + for key, cell in w_dict.content.iteritems(): newcell = ModuleCell() newcell.w_value = cell.w_value content[key] = newcell @@ -35,9 +35,9 @@ cls.w_rescue_builtins = cls.space.wrap(rescue_builtins) def restore_builtins(space): w_dict = space.builtin.getdict() - if not isinstance(w_dict.implementation, ModuleDictImplementation): - w_dict.implementation = ModuleDictImplementation(space) - w_dict.implementation.content = stored_builtins.pop() + assert isinstance(w_dict, ModuleDictImplementation) + w_dict.content = stored_builtins.pop() + w_dict.fallback = None restore_builtins = gateway.interp2app(restore_builtins) cls.w_restore_builtins = cls.space.wrap(restore_builtins) Modified: pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictmultiobject.py Wed Aug 5 15:58:19 2009 @@ -16,7 +16,7 @@ space = self.space w = space.wrap d = {"a": w(1), "b": w(2)} - w_d = space.DictObjectCls(space) + w_d = space.DictObjectCls.allocate_and_init_instance(space) w_d.initialize_from_strdict_shared(d) assert self.space.eq_w(space.getitem(w_d, w("a")), w(1)) assert self.space.eq_w(space.getitem(w_d, w("b")), w(2)) @@ -130,7 +130,7 @@ def test_stressdict(self): from random import randint - d = self.space.DictObjectCls(self.space) + d = self.space.DictObjectCls.allocate_and_init_instance(self.space) N = 10000 pydict = {} for i in range(N): @@ -160,51 +160,51 @@ return self.ImplementionClass(self.space) def test_setitem(self): - assert self.impl.setitem(self.string, 1000) is self.impl - assert self.impl.length() == 1 - assert self.impl.get(self.string) == 1000 + assert self.impl.impl_setitem(self.string, 1000) is self.impl + assert self.impl.impl_length() == 1 + assert self.impl.impl_getitem(self.string) == 1000 def test_setitem_str(self): - assert self.impl.setitem_str(self.space.str_w(self.string), 1000) is self.impl - assert self.impl.length() == 1 - assert self.impl.get(self.string) == 1000 + assert self.impl.impl_setitem_str(self.space.str_w(self.string), 1000) is self.impl + assert self.impl.impl_length() == 1 + assert self.impl.impl_getitem(self.string) == 1000 def test_delitem(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - assert self.impl.length() == 2 - newimpl = self.impl.delitem(self.string) - assert self.impl.length() == 1 + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + assert self.impl.impl_length() == 2 + newimpl = self.impl.impl_delitem(self.string) + assert self.impl.impl_length() == 1 assert newimpl is self.impl - newimpl = self.impl.delitem(self.string2) - assert self.impl.length() == 0 + newimpl = self.impl.impl_delitem(self.string2) + assert self.impl.impl_length() == 0 assert isinstance(newimpl, self.EmptyClass) def test_keys(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - keys = self.impl.keys() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + keys = self.impl.impl_keys() keys.sort() assert keys == [self.string, self.string2] def test_values(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - values = self.impl.values() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + values = self.impl.impl_values() values.sort() assert values == [1000, 2000] def test_items(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - items = self.impl.items() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + items = self.impl.impl_items() items.sort() assert items == zip([self.string, self.string2], [1000, 2000]) def test_iterkeys(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - iteratorimplementation = self.impl.iterkeys() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + iteratorimplementation = self.impl.impl_iterkeys() keys = [] while 1: key = iteratorimplementation.next() @@ -215,9 +215,9 @@ assert keys == [self.string, self.string2] def test_itervalues(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - iteratorimplementation = self.impl.itervalues() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + iteratorimplementation = self.impl.impl_itervalues() values = [] while 1: value = iteratorimplementation.next() @@ -228,9 +228,9 @@ assert values == [1000, 2000] def test_iteritems(self): - self.impl.setitem(self.string, 1000) - self.impl.setitem(self.string2, 2000) - iteratorimplementation = self.impl.iteritems() + self.impl.impl_setitem(self.string, 1000) + self.impl.impl_setitem(self.string2, 2000) + iteratorimplementation = self.impl.impl_iteritems() items = [] while 1: item = iteratorimplementation.next() @@ -243,8 +243,8 @@ def test_devolve(self): impl = self.impl for x in xrange(100): - impl = impl.setitem(self.space.str_w(str(x)), x) - impl = impl.setitem(x, x) + impl = impl.impl_setitem(self.space.str_w(str(x)), x) + impl = impl.impl_setitem(x, x) assert isinstance(impl, self.DevolvedClass) class TestStrDictImplementation(TestRDictImplementation): Modified: pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/test/test_dictobject.py Wed Aug 5 15:58:19 2009 @@ -8,13 +8,13 @@ def test_empty(self): space = self.space - d = self.space.DictObjectCls(space) + d = self.space.DictObjectCls.allocate_and_init_instance(space) assert not self.space.is_true(d) def test_nonempty(self): space = self.space wNone = space.w_None - d = self.space.DictObjectCls(space) + d = self.space.DictObjectCls.allocate_and_init_instance(space) d.initialize_content([(wNone, wNone)]) assert space.is_true(d) i = space.getitem(d, wNone) @@ -25,7 +25,7 @@ space = self.space wk1 = space.wrap('key') wone = space.wrap(1) - d = self.space.DictObjectCls(space) + d = self.space.DictObjectCls.allocate_and_init_instance(space) d.initialize_content([(space.wrap('zero'),space.wrap(0))]) space.setitem(d,wk1,wone) wback = space.getitem(d,wk1) @@ -34,7 +34,7 @@ def test_delitem(self): space = self.space wk1 = space.wrap('key') - d = self.space.DictObjectCls(space) + d = self.space.DictObjectCls.allocate_and_init_instance(space) d.initialize_content( [(space.wrap('zero'),space.wrap(0)), (space.wrap('one'),space.wrap(1)), (space.wrap('two'),space.wrap(2))]) @@ -127,7 +127,7 @@ space = self.space w = space.wrap d = {"a": w(1), "b": w(2)} - w_d = space.DictObjectCls(space) + w_d = space.DictObjectCls.allocate_and_init_instance(space) w_d.initialize_from_strdict_shared(d) assert self.space.eq_w(space.getitem(w_d, w("a")), w(1)) assert self.space.eq_w(space.getitem(w_d, w("b")), w(2)) @@ -489,6 +489,10 @@ def type(self, w_obj): return type(w_obj) w_str = str + w_dict = dict + def allocate_instance(self, cls, w_type): + from pypy.rlib.objectmodel import instantiate + return instantiate(cls) class Config: pass @@ -499,6 +503,7 @@ FakeSpace.config.objspace.std.withdictmeasurement = False FakeSpace.config.objspace.std.withsharingdict = False FakeSpace.config.objspace.std.withsmalldicts = False +FakeSpace.config.objspace.std.withshadowtracking = False FakeSpace.config.objspace.std.withcelldict = False FakeSpace.config.objspace.opcodes = Config() FakeSpace.config.objspace.opcodes.CALL_LIKELY_BUILTIN = False @@ -512,7 +517,7 @@ def test_stressdict(self): from random import randint - d = self.space.DictObjectCls(self.space) + d = self.space.DictObjectCls.allocate_and_init_instance(self.space) N = 10000 pydict = {} for i in range(N): Modified: pypy/branch/shrink-multidict/pypy/objspace/std/test/test_shadowtracking.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/test/test_shadowtracking.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/test/test_shadowtracking.py Wed Aug 5 15:58:19 2009 @@ -13,15 +13,15 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): a.g = "foo" """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): a.f = "foo" """) - assert w_inst.w__dict__.implementation.shadows_anything() + assert w_inst.w__dict__.shadows_anything() def test_shadowing_via__dict__(self): space = self.space @@ -32,15 +32,15 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): a.__dict__["g"] = "foo" """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): a.__dict__["f"] = "foo" """) - assert w_inst.w__dict__.implementation.shadows_anything() + assert w_inst.w__dict__.shadows_anything() def test_changing__dict__(self): space = self.space @@ -51,11 +51,11 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): a.__dict__ = {} """) - assert w_inst.w__dict__.implementation.shadows_anything() + assert w_inst.w__dict__.shadows_anything() def test_changing__class__(self): space = self.space @@ -66,14 +66,14 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() space.appexec([w_inst], """(a): class B(object): def g(self): return 42 a.__class__ = B """) - assert w_inst.w__dict__.implementation.shadows_anything() + assert w_inst.w__dict__.shadows_anything() def test_changing_the_type(self): space = self.space @@ -84,13 +84,13 @@ a.x = 72 return a """) - assert not w_inst.w__dict__.implementation.shadows_anything() + assert not w_inst.w__dict__.shadows_anything() w_x = space.appexec([w_inst], """(a): a.__class__.x = 42 return a.x """) assert space.unwrap(w_x) == 72 - assert w_inst.w__dict__.implementation.shadows_anything() + assert w_inst.w__dict__.shadows_anything() class AppTestShadowTracking(object): def setup_class(cls): Modified: pypy/branch/shrink-multidict/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/shrink-multidict/pypy/objspace/std/typeobject.py Wed Aug 5 15:58:19 2009 @@ -246,7 +246,7 @@ if w_self.lazyloaders: w_self._freeze_() # force un-lazification space = w_self.space - newdic = space.DictObjectCls(space) + newdic = space.DictObjectCls.allocate_and_init_instance(space) newdic.initialize_from_strdict_shared(w_self.dict_w) return W_DictProxyObject(newdic) Modified: pypy/branch/shrink-multidict/pypy/translator/goal/gcbench.py ============================================================================== --- pypy/branch/shrink-multidict/pypy/translator/goal/gcbench.py (original) +++ pypy/branch/shrink-multidict/pypy/translator/goal/gcbench.py Wed Aug 5 15:58:19 2009 @@ -87,9 +87,21 @@ else: return Node(make_tree(depth-1), make_tree(depth-1)) +def get_memory_usage(): + import os + pid = os.getpid() + f = file("/proc/%s/status" % (pid, )) + lines = f.readlines() + f.close() + for l in lines: + if l.startswith("VmData:\t"): + return int(l[len("VmData:\t"):-len(" kB")]) + print "\n".join(lines) + assert 0 + def print_diagnostics(): "ought to print free/total memory" - pass + print "total memory:", get_memory_usage() def time_construction(depth): niters = num_iters(depth) From arigo at codespeak.net Thu Aug 6 12:41:01 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Aug 2009 12:41:01 +0200 (CEST) Subject: [pypy-svn] r66751 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090806104101.861E2168025@codespeak.net> Author: arigo Date: Thu Aug 6 12:40:59 2009 New Revision: 66751 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Log: Restore gdb debugging of lists of operations: when running "python resoperation.py" it prints the current mapping of names to numbers. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Thu Aug 6 12:40:59 2009 @@ -205,6 +205,8 @@ i = 0 for opname in _oplist: + if __name__ == '__main__': + print '%30s = %d' % (opname, i) # print out the table when run directly setattr(rop, opname, i) i += 1 del _oplist From cfbolz at codespeak.net Fri Aug 7 17:07:54 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 7 Aug 2009 17:07:54 +0200 (CEST) Subject: [pypy-svn] r66753 - pypy/extradoc/talk/techtalk_dlr2009 Message-ID: <20090807150754.DEDCD168018@codespeak.net> Author: cfbolz Date: Fri Aug 7 17:07:53 2009 New Revision: 66753 Added: pypy/extradoc/talk/techtalk_dlr2009/ Log: A directory for the tech talk at the DLR (Deutsches Zentrum f?r Luft- und Raumfahrt) that I'll give next week. From cfbolz at codespeak.net Fri Aug 7 19:16:52 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 7 Aug 2009 19:16:52 +0200 (CEST) Subject: [pypy-svn] r66754 - pypy/extradoc/talk/techtalk_dlr2009 Message-ID: <20090807171652.0A754168019@codespeak.net> Author: cfbolz Date: Fri Aug 7 19:16:51 2009 New Revision: 66754 Added: pypy/extradoc/talk/techtalk_dlr2009/Makefile pypy/extradoc/talk/techtalk_dlr2009/author.latex pypy/extradoc/talk/techtalk_dlr2009/dynlang.png - copied unchanged from r66752, pypy/extradoc/talk/ecoop2009-tutorial/dynlang.png pypy/extradoc/talk/techtalk_dlr2009/stylesheet.latex pypy/extradoc/talk/techtalk_dlr2009/talk.txt (contents, props changed) pypy/extradoc/talk/techtalk_dlr2009/title.latex Log: talk content. mostly stolen from the dyla talk, a lot also from europython Added: pypy/extradoc/talk/techtalk_dlr2009/Makefile ============================================================================== --- (empty file) +++ pypy/extradoc/talk/techtalk_dlr2009/Makefile Fri Aug 7 19:16:51 2009 @@ -0,0 +1,18 @@ +# you can find rst2beamer.py here: +# http://codespeak.net/svn/user/antocuni/bin/rst2beamer.py + +# WARNING: to work, it needs this patch for docutils +# https://sourceforge.net/tracker/?func=detail&atid=422032&aid=1459707&group_id=38414 + +talk.pdf: talk.txt author.latex title.latex stylesheet.latex + rst2beamer.py --stylesheet=stylesheet.latex --documentoptions=14pt talk.txt talk.latex --output-encoding=utf8|| exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit + sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + pdflatex talk.latex || exit + pdflatex talk.latex || exit + +view: talk.pdf + evince talk.pdf & + +xpdf: talk.pdf + xpdf talk.pdf & Added: pypy/extradoc/talk/techtalk_dlr2009/author.latex ============================================================================== --- (empty file) +++ pypy/extradoc/talk/techtalk_dlr2009/author.latex Fri Aug 7 19:16:51 2009 @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy: A Flexible Virtual Machine for Python and Other Dynamic Languages]{PyPy: A Flexible VM for Python} +\author[cfbolz] +{Carl Friedrich Bolz} + +\institute{University of D?sseldorf} +\date{DLR Tech Talk, 11.08.09} Added: pypy/extradoc/talk/techtalk_dlr2009/stylesheet.latex ============================================================================== --- (empty file) +++ pypy/extradoc/talk/techtalk_dlr2009/stylesheet.latex Fri Aug 7 19:16:51 2009 @@ -0,0 +1,10 @@ +\usetheme{Boadilla} +\setbeamercovered{transparent} +\setbeamertemplate{navigation symbols}{} + +\definecolor{darkgreen}{rgb}{0, 0.5, 0.0} +\newcommand{\docutilsrolegreen}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\docutilsrolered}[1]{\color{red}#1\normalcolor} + +\newcommand{\green}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\red}[1]{\color{red}#1\normalcolor} Added: pypy/extradoc/talk/techtalk_dlr2009/talk.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/techtalk_dlr2009/talk.txt Fri Aug 7 19:16:51 2009 @@ -0,0 +1,349 @@ +.. include:: beamerdefs.txt + +========== +PyPy Talk +========== + +What is PyPy +=================================== + +- An alternate Python virtual machine for C/Posix, + for .NET and for Java + +- More generally, a way to implement interpreters + for various languages + +Talk Outline +=============== + +- In-depth motivation for PyPy +- PyPy's Approach to VM Construction +- Status of PyPy's Python Implementation +- PyPy's JIT Compiler + +Common Approaches to Language Implementation +============================================= + +- Using C/C++ (potentially disguised as another language) + + - CPython + - Ruby + - Most JavaScript VMs (V8, TraceMonkey, Squirrelfish) + - but also: Scheme48, Squeak + +- Building on top of a general-purpose OO VM + + - Jython, IronPython + - JRuby, IronRuby + - various Prolog, Lisp, even Smalltalk implementations + + +Writing VMs is (Still) Hard +============================ + +- good VMs for dynamic languages are very hard +- when writing one, it is very hard to reconcile + + - performance + - simplicity, maintainability + - flexibility, features + +- this is particularly true in an Open Source / research context + +Python Case +============ + +- **CPython** is a simple maintainable but slow VM, using a simple bytecode + interpreter +- **Stackless** is a more featureful fork of CPython that was never merged for maintainability reasons +- **Psyco** is a very complex JIT compiler for Python, which speeds up Python a lot + + +Early Design Decisions +======================== + +fixing of early design decisions: + +- when writing a VM in C, some things have to be decided up front +- examples are things like memory model, GC, threading model, etc. +- decisions manifest throughout the source code +- extremely hard to change later + + +Python case +============== + +- reference counting +- OS threads + +Compilers are a bad encoding of Semantics +========================================= + +- to reach good performance levels, dynamic compilation is often needed +- a compiler (obviously) needs to encode language semantics +- this encoding is often obscure and hard to change + +Python Case +============ + +- Psyco is a dynamic compiler for Python +- synchronizing with CPython's rapid development is a lot of effort +- many of CPython's new features not supported well + +Implementing Languages on Top of OO VMs +======================================== + +- users wish to have easy interoperation with the general-purpose OO VMs used +- by the industry (JVM, CLR) +- therefore re-implementations of the language on the OO VMs are started +- more implementations! +- implementing on top of an OO VM has its own set of benefits of problems + +Python Case +============= + +- *Jython* is a Python-to-Java-bytecode compiler +- *IronPython* is a Python-to-CLR-bytecode compiler +- both are slightly incompatible with the newest CPython version + +Benefits of implementing on top of OO VMs +=========================================== + +- higher level of implementation +- the VM supplies a GC and mostly a JIT +- better interoperability than what the C level provides + +Python Case +============ + +- both Jython and IronPython integrate well with their host OO VM +- Jython has free threading + + +The problems of OO VMs +======================= +- most immediate problem: it can be hard to map + concepts of the dynamic language to the host OO VM + +- performance is often not improved, and can be very bad, because of the + semantic mismatch between the dynamic language and the host VM + +Python Case +============ + +- Jython about 5 times slower than CPython +- IronPython is about as fast as CPython (but some stack introspection + features missing) + +- Python has very different semantics for method calls than Java + +PyPy's Approach to VM Construction +================================== + +**Goal: achieve flexibility, simplicity and performance together** + +- Approach: auto-generate VMs from high-level descriptions of the language +- ... using meta-programming techniques and *aspects* +- high-level description: an interpreter written in a high-level language + (called *RPython*) +- ... which we translate (i.e. compile) to a VM running in various target + environments, like C/Posix, CLR, JVM + +PyPy's approach to VM construction +================================== + +.. image:: dynlang.png + :scale: 50 + +What is RPython +=============== + +- RPython is a subset of Python +- subset chosen in such a way that type-inference can be performed +- still a high-level language (unlike SLang or PreScheme) +- ...really a subset, can't give a small example of code that + doesn't just look like Python :-) +- fundamental restriction: no type mixing: ``l = [1, "string"]`` does not work + +Auto-generating VMs +=================== + +- we need a custom \emph{translation toolchain} to compile the interpreter + to a full VM +- many aspects of the final VM are orthogonal from the interpreter source: + they are inserted during translation + +|pause| + +Examples: + +- Garbage Collection strategy +- Threading models (e.g. coroutines with CPS...) +- non-trivial translation aspect: auto-generating a dynamic compiler from +- the interpreter + +Good Points of the Approach +=========================== + +**Simplicity:** + +- dynamic languages can be implemented in a high level language +- separation of language semantics from low-level details +- a single-source-fits-all interpreter: + + - runs everywhere with the same semantics + - no outdated implementations, no ties to any standard platform + - less duplication of efforts + + +Good Points of the Approach +=========================== + +**Flexibility** at all levels: + +- when writing the interpreter (high-level languages rule!) +- when adapting the translation toolchain as necessary + to break abstraction barriers + +Examples: + +- boxed integer objects, represented as tagged pointers +- manual system-level RPython code + +Good Points of the Approach +=========================== + +**Performance:** + +- "reasonable" performance: between 0.8 and 4 times slower than CPython +- can generate a dynamic compiler from the interpreter (see end of talk) + + +Drawbacks / Open Issues / Further Work +====================================== + +- writing the translation toolchain in the first place takes lots of effort + (but it can be reused) +- writing a good GC is still necessary. The current one's are ok, but not great. +- generating a dynamic compiler is hard (working on this since quite a while) + + +Status of Python Interpreter +============================= + +- 1.1 release +- more than two years of work +- compatible to Python 2.5.2 (even most the obscure bits) +- supporting ctypes, SQLite +- well tested on Win/Linux 32 bit (but OS X and 64 bit should work as well) +- running major packages unmodified +- easy_install/distutils working + +Software PyPy Can Run +====================== + +- Django +- Pylons +- Twisted & Nevow +- pure python should just work +- BitTorrent +- PyPy translation toolchain +- py lib +- sympy +- various smaller things, templating engines + +Obscure details that people rely on +======================================= + +- non-string keys in __dict__ of types +- exact naming of a list comprehension variable +- relying on untested and undocumented private stuff +- exact message matching in exception catching + code + +- refcounting details:: + + s = open(filename).read() + +Conclusion on Compatibility +============================ + +- lessons learned: *there is no feature obscure enough for people + not to rely on it.* + +- pypy-c interpreter probably the most compatible to CPython 2.5 + +- main blocker for running apps will be missing external modules + + +Speed +======== + +- we're something between 0.8-4x slower than + CPython on various benchmarks without JIT + +- our JIT will be quite fast ? we think 5x faster than now is a realistic goal + +- Idea for the JIT: don't write the JIT by hand, but auto-generate one + +- Should make it possible to apply it to other languages + +Speed - JIT generator +===================== + +- language agnostic translation aspect +- JIT automatically generated +- needs a number of hints by the interpreter author +- 5th generation of the JIT: using trace-based techniques +- x86 and CLI/.NET backends +- very easy to port to x86-64 (contributions welcome!) + +Main ideas (1) +=============== + +- 80/20 rule +- 80% of the time is spent in 20% of the code +- Optimize only that 20% + + +Main ideas (2) +=============== + +- That 20% has to be composed of *loops* +- Recognize **hot** loops +- Optimize hot loops +- Compile to native code +- Execute :-) + +Speed - Current Status +======================= + +- 20-30x faster on micro-benchmarks +- nice proof of concept +- completely separated from the interpreter +- a bit of time (and funding) needed to speed up large python programs +- hope to get a release with "a JIT" out beginning next year + + +Conclusion +============ + +- PyPy is a general environment to implement dynamic languages +- Python implementation fairly complete, covers CPython 2.5 features +- JIT generator is getting somewhere, slowly + + +Contact / Q&A +========================== + +Carl Friedrich Bolz at Heinrich-Heine-Universit?t D?sseldorf + +PyPy: http://codespeak.net/pypy + +Blog: http://morepypy.blogspot.com + +.. raw:: latex + + \begin{figure}[h] + \scalebox{0.8}{\includegraphics[width=80px]{../img/py-web.png}} + \end{figure} Added: pypy/extradoc/talk/techtalk_dlr2009/title.latex ============================================================================== --- (empty file) +++ pypy/extradoc/talk/techtalk_dlr2009/title.latex Fri Aug 7 19:16:51 2009 @@ -0,0 +1,5 @@ +\begin{titlepage} +\begin{figure}[h] +\includegraphics[width=80px]{../img/py-web.png} +\end{figure} +\end{titlepage} From fijal at codespeak.net Sat Aug 8 10:40:03 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 8 Aug 2009 10:40:03 +0200 (CEST) Subject: [pypy-svn] r66755 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/test Message-ID: <20090808084003.CCC93168010@codespeak.net> Author: fijal Date: Sat Aug 8 10:40:01 2009 New Revision: 66755 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Log: float fields tests Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Sat Aug 8 10:40:01 2009 @@ -341,6 +341,23 @@ 'ptr', descr=fielddescr2) assert res.value == null_const.value + def test_field_float(self): + f_box, _ = self.alloc_instance(self.F) + intfielddescr = self.cpu.fielddescrof(self.F, 'intfield') + floatfielddescr = self.cpu.fielddescrof(self.F, 'floatfield') + i = BoxInt(3) + f = BoxFloat(3.5) + self.execute_operation(rop.SETFIELD_GC, [f_box, i], 'void', + descr=intfielddescr) + self.execute_operation(rop.SETFIELD_GC, [f_box, f], 'void', + descr=floatfielddescr) + res = self.execute_operation(rop.GETFIELD_GC, [f_box], 'int', + descr=intfielddescr) + assert res.value == 3 + res = self.execute_operation(rop.GETFIELD_GC, [f_box], 'float', + descr=floatfielddescr) + assert res.value == 3.5 + def test_passing_guards(self): for (opname, args) in [(rop.GUARD_TRUE, [BoxInt(1)]), (rop.GUARD_FALSE, [BoxInt(0)]), @@ -585,6 +602,8 @@ ('next', lltype.Ptr(S))) U = lltype.GcStruct('U', ('parent', T), ('next', lltype.Ptr(S))) + F = lltype.GcStruct('F', ('intfield', lltype.Signed), + ('floatfield', lltype.Float)) def alloc_instance(self, T): From fijal at codespeak.net Sat Aug 8 10:40:43 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 8 Aug 2009 10:40:43 +0200 (CEST) Subject: [pypy-svn] r66756 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph Message-ID: <20090808084043.5200B168010@codespeak.net> Author: fijal Date: Sat Aug 8 10:40:42 2009 New Revision: 66756 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py Log: Make llgraph backend pass those tests Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py Sat Aug 8 10:40:42 2009 @@ -652,6 +652,8 @@ def op_getfield_gc(self, fielddescr, struct): if fielddescr.typeinfo == 'p': return do_getfield_gc_ptr(struct, fielddescr.ofs) + elif fielddescr.typeinfo == 'f': + return do_getfield_gc_float(struct, fielddescr.ofs) else: return do_getfield_gc_int(struct, fielddescr.ofs, self.memocast) @@ -660,6 +662,8 @@ def op_getfield_raw(self, fielddescr, struct): if fielddescr.typeinfo == 'p': return do_getfield_raw_ptr(struct, fielddescr.ofs, self.memocast) + elif fielddescr.typeinfo == 'f': + xxx else: return do_getfield_raw_int(struct, fielddescr.ofs, self.memocast) @@ -685,6 +689,8 @@ def op_setfield_gc(self, fielddescr, struct, newvalue): if fielddescr.typeinfo == 'p': do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) + elif fielddescr.typeinfo == 'f': + do_setfield_gc_float(struct, fielddescr.ofs, newvalue) else: do_setfield_gc_int(struct, fielddescr.ofs, newvalue, self.memocast) @@ -693,6 +699,8 @@ if fielddescr.typeinfo == 'p': do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memocast) + elif fielddescr.typeinfo == 'f': + xxx else: do_setfield_raw_int(struct, fielddescr.ofs, newvalue, self.memocast) @@ -1058,6 +1066,12 @@ x = getattr(ptr, fieldname) return cast_to_ptr(x) +def do_getfield_gc_float(struct, fieldnum): + STRUCT, fieldname = symbolic.TokenToField[fieldnum] + ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) + x = getattr(ptr, fieldname) + return x + def do_getfield_raw_int(struct, fieldnum, memocast): STRUCT, fieldname = symbolic.TokenToField[fieldnum] ptr = cast_from_int(lltype.Ptr(STRUCT), struct, memocast) @@ -1104,6 +1118,11 @@ newvalue = cast_from_int(FIELDTYPE, newvalue, memocast) setattr(ptr, fieldname, newvalue) +def do_setfield_gc_float(struct, fieldnum, newvalue): + STRUCT, fieldname = symbolic.TokenToField[fieldnum] + ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) + setattr(ptr, fieldname, newvalue) + def do_setfield_gc_ptr(struct, fieldnum, newvalue): STRUCT, fieldname = symbolic.TokenToField[fieldnum] ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) From fijal at codespeak.net Sat Aug 8 10:42:41 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 8 Aug 2009 10:42:41 +0200 (CEST) Subject: [pypy-svn] r66757 - in pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86: . test Message-ID: <20090808084241.46FAD168010@codespeak.net> Author: fijal Date: Sat Aug 8 10:42:40 2009 New Revision: 66757 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_runner.py Log: Some progress on floats. sort out encoding tests and suffixes of operations. Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py Sat Aug 8 10:42:40 2009 @@ -281,10 +281,10 @@ regalloc_store = regalloc_load def regalloc_load_float(self, from_loc, to_loc): - self.mc.FLDL(from_loc) + self.mc.FLD(from_loc) def regalloc_store_float(self, from_loc, to_loc): - self.mc.FSTPL(to_loc) + self.mc.FSTP(to_loc) def regalloc_push(self, loc): self.mc.PUSH(loc) @@ -417,10 +417,10 @@ getattr(self.mc, opname)(arglocs[1]) return genop_binary_float - genop_float_add = _binop_float('FADDL') - genop_float_sub = _binop_float('FSUBL') - genop_float_mul = _binop_float('FMULL') - genop_float_truediv = _binop_float('FDIVL') + genop_float_add = _binop_float('FADD') + genop_float_sub = _binop_float('FSUB') + genop_float_mul = _binop_float('FMUL') + genop_float_truediv = _binop_float('FDIV') # for now all chars are being considered ints, although we should make # a difference at some point @@ -523,6 +523,9 @@ self.mc.MOVZX(resloc, addr8_add(base_loc, ofs_loc)) elif size == WORD: self.mc.MOV(resloc, addr_add(base_loc, ofs_loc)) + elif size == 2*WORD: + assert resloc is st0 + self.mc.FST(addr64_add(base_loc, ofs_loc)) else: raise NotImplementedError("getfield size = %d" % size) @@ -536,7 +539,7 @@ self.mc.MOVZX(resloc, addr8_add(base_loc, ofs_loc, ofs.value, scale.value)) elif scale.value == 3: - self.mc.FLDL(addr64_add(base_loc, ofs_loc, ofs.value, scale.value)) + self.mc.FLD(addr64_add(base_loc, ofs_loc, ofs.value, scale.value)) elif scale.value == 2: self.mc.MOV(resloc, addr_add(base_loc, ofs_loc, ofs.value, scale.value)) @@ -553,6 +556,9 @@ size = size_loc.value if size == WORD: self.mc.MOV(addr_add(base_loc, ofs_loc), value_loc) + elif size == 2*WORD: + assert value_loc is st0 + self.mc.FST(addr64_add(base_loc, ofs_loc)) elif size == 2: raise NotImplementedError("shorts and friends") self.mc.MOV(addr16_add(base_loc, ofs_loc), lower_2_bytes(value_loc)) @@ -571,7 +577,7 @@ scale_loc.value), value_loc) elif scale_loc.value == 3: assert value_loc is st0 - self.mc.FSTPL(addr64_add(base_loc, ofs_loc, baseofs.value, + self.mc.FST(addr64_add(base_loc, ofs_loc, baseofs.value, scale_loc.value)) elif scale_loc.value == 0: self.mc.MOV(addr8_add(base_loc, ofs_loc, baseofs.value, @@ -746,14 +752,15 @@ else: base = self.fail_box_int_addr self.mc.MOV(addr_add(imm(base), imm(i*WORD)), loc) + freed_float = False for i in range(len(locs)): loc = locs[i] if not isinstance(loc, REG): if op.args[i].type == FLOAT: base = self.fail_box_float_addr if loc is st0: - self.mc.FSTPL(addr64_add(imm(base), imm(i*2*WORD))) - regalloc.st0 = None + self.mc.FSTP(addr64_add(imm(base), imm(i*2*WORD))) + freed_float = True else: assert isinstance(loc, MODRM) start = stack_pos(loc.position, 1) @@ -783,6 +790,8 @@ guard_index = self.cpu.make_guard_index(op) self.mc.MOV(eax, imm(guard_index)) #if self.gcrootmap: + if regalloc.st0 is not None and not freed_float: + self.pop_float_stack() self.mc.POP(ebp) self.mc.RET() @@ -835,6 +844,9 @@ genop_call_pure = genop_call + def pop_float_stack(self): + self.mc.FDECSTP() + def not_implemented_op_discard(self, op, arglocs): print "not implemented operation: %s" % op.getopname() raise NotImplementedError Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py Sat Aug 8 10:42:40 2009 @@ -61,6 +61,7 @@ # variables that have place in register self.assembler = assembler self.translate_support_code = translate_support_code + self.pop_float_stack = False if regalloc is None: self._rewrite_const_ptrs(tree.operations) self.tree = tree @@ -597,6 +598,7 @@ if v not in self.longevity or self.longevity[v][1] <= self.position: if v is self.st0: self.st0 = None + self.pop_float_stack = True return self.free_regs.append(self.reg_bindings[v]) del self.reg_bindings[v] @@ -799,22 +801,6 @@ self.eventually_free_vars(op.args) self.eventually_free_var(box) - #def consider_guard2(self, op, ignored): - # loc1, ops1 = self.make_sure_var_in_reg(op.args[0], []) - # loc2, ops2 = self.make_sure_var_in_reg(op.args[1], []) - # locs = [self.loc(arg) for arg in op.liveboxes] - # self.eventually_free_vars(op.args + op.liveboxes) - # return ops1 + ops2 + [PerformDiscard(op, [loc1, loc2] + locs)] - - #consider_guard_lt = consider_guard2 - #consider_guard_le = consider_guard2 - #consider_guard_eq = consider_guard2 - #consider_guard_ne = consider_guard2 - #consider_guard_gt = consider_guard2 - #consider_guard_ge = consider_guard2 - #consider_guard_is = consider_guard2 - #consider_guard_isnot = consider_guard2 - def consider_guard_value(self, op, ignored): x = self.loc(op.args[0]) if not (isinstance(x, REG) or isinstance(op.args[1], Const)): @@ -860,9 +846,12 @@ def _consider_binop_float(self, op, ignored): x = op.args[0] - locx = self.loc(x) self.force_float_result_in_reg(op.result, x) - self.Perform(op, [st0, self.loc(op.args[1])], st0) + if op.args[0] is op.args[1]: + loc1 = st0 + else: + loc1 = self.loc(op.args[1]) + self.Perform(op, [st0, loc1], st0) self.eventually_free_vars(op.args) consider_float_add = _consider_binop_float @@ -1082,8 +1071,13 @@ def consider_setfield_gc(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) - value_loc = self.make_sure_var_in_reg(op.args[1], op.args) ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) + if size_loc.value == 2*WORD: + # float + self.force_float_in_reg(op.args[1]) + value_loc = st0 + else: + value_loc = self.make_sure_var_in_reg(op.args[1], op.args) if ptr: gc_ll_descr = self.assembler.cpu.gc_ll_descr gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) @@ -1110,6 +1104,7 @@ scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) + self.eventually_free_vars(op.args) if scale > 2: # float number... self.force_float_in_reg(op.args[2]) @@ -1119,7 +1114,6 @@ if ptr: gc_ll_descr = self.assembler.cpu.gc_ll_descr gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) - self.eventually_free_vars(op.args) self.PerformDiscard(op, [base_loc, ofs_loc, value_loc, imm(scale), imm(ofs)]) @@ -1127,7 +1121,10 @@ ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) self.eventually_free_vars(op.args) - result_loc = self.force_allocate_reg(op.result, []) + if size_loc.value == 2*WORD: + result_loc = self.force_allocate_float_reg(op.result) + else: + result_loc = self.force_allocate_reg(op.result, []) self.Perform(op, [base_loc, ofs_loc, size_loc], result_loc) consider_getfield_gc_pure = consider_getfield_gc @@ -1147,18 +1144,6 @@ consider_getfield_raw = consider_getfield_gc consider_getarrayitem_gc_pure = consider_getarrayitem_gc - def _consider_listop(self, op, ignored): - return self._call(op, [self.loc(arg) for arg in op.args]) - - xxx_consider_getitem = _consider_listop - xxx_consider_len = _consider_listop - xxx_consider_append = _consider_listop - xxx_consider_pop = _consider_listop - xxx_consider_setitem = _consider_listop - xxx_consider_newlist = _consider_listop - xxx_consider_insert = _consider_listop - xxx_consider_listnonzero = _consider_listop - def _same_as(self, op, ignored): x = op.args[0] if isinstance(x, Const): Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386.py Sat Aug 8 10:42:40 2009 @@ -25,7 +25,7 @@ return '' % self.num def assembler(self): - raise TypeError("Float registers should not appear in assembler") + return '%%st(%d)' % self.num class ST0(FLOATREG): num=0 class ST1(FLOATREG): num=1 @@ -233,6 +233,7 @@ registers = [eax, ecx, edx, ebx, esp, ebp, esi, edi] registers8 = [al, cl, dl, bl, ah, ch, dh, bh] +floatregisters = [st0] for r in registers + registers8: r.bitmask = 1 << r.op Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/ri386setup.py Sat Aug 8 10:42:40 2009 @@ -33,6 +33,8 @@ DH: [(DH, None), (REG8, None), (MODRM8, reg2modrm8)], BH: [(BH, None), (REG8, None), (MODRM8, reg2modrm8)], + ST0: [(ST0, None), (FLOATREG, None)], + REG: [(REG, None), (MODRM, reg2modrm)], REG8: [(REG8, None), (MODRM8, reg2modrm8)], @@ -80,6 +82,18 @@ lines.append('orbyte = %s' % value) return True +class floatregister(operand): + def __init__(self, op): + self.op = op + + def eval(self, lines, has_orbyte): + value = 'arg%d.num' % self.op + if has_orbyte: + lines.append('orbyte |= %s' % value) + else: + lines.append('orbyte = %s' % value) + return True + class modrm(operand): def eval(self, lines, has_orbyte): expr = 'arg%d.byte' % self.op @@ -449,32 +463,36 @@ # ------------------------- floating point instructions ------------------ -FLDL = Instruction() -FLDL.mode1(MODRM64, ['\xDD', modrm(1)]) +FLD = Instruction() +FLD.mode1(MODRM64, ['\xDD', modrm(1)]) -FADDP = Instruction() -FADDP.mode0(['\xDE\xC1']) +FADD = Instruction() +FADD.mode1(MODRM64, ['\xDC', modrm(1)]) +FADD.mode1(FLOATREG, ['\xD8', floatregister(1), '\xC0']) -FADDL = Instruction() -FADDL.mode1(MODRM64, ['\xDC', modrm(1)]) +FDECSTP = Instruction() +FDECSTP.mode0(['\xD9\xF6']) FSUBP = Instruction() FSUBP.mode0(['\xDE\xE1']) -FSUBL = Instruction() -FSUBL.mode1(MODRM64, ['\xDC', orbyte(4<<3), modrm(1)]) +FSUB = Instruction() +FSUB.mode1(MODRM64, ['\xDC', orbyte(4<<3), modrm(1)]) +FSUB.mode1(FLOATREG, ['\xD8', floatregister(1), '\xE0']) FMULP = Instruction() FMULP.mode0(['\xDE\xC9']) -FMULL = Instruction() -FMULL.mode1(MODRM64, ['\xDC', orbyte(1<<3), modrm(1)]) +FMUL = Instruction() +FMUL.mode1(MODRM64, ['\xDC', orbyte(1<<3), modrm(1)]) +FMUL.mode1(FLOATREG, ['\xD8', floatregister(1), '\xC8']) FDIVP = Instruction() FDIVP.mode0(['\xDE\xF1']) -FDIVL = Instruction() -FDIVL.mode1(MODRM64, ['\xDC', orbyte(6<<3), modrm(1)]) +FDIV = Instruction() +FDIV.mode1(MODRM64, ['\xDC', orbyte(6<<3), modrm(1)]) +FDIV.mode1(FLOATREG, ['\xD8', floatregister(1), '\xF0']) FCHS = Instruction() FCHS.mode0(['\xD9\xE0']) @@ -495,19 +513,10 @@ FUCOMPP = Instruction() FUCOMPP.mode0(['\xDA\xE9']) -FSTPL = Instruction() -FSTPL.mode1(MODRM64, ['\xDD', orbyte(3<<3), modrm(1)]) -FSTL = Instruction() -FSTL.mode1(MODRM64, ['\xDD', orbyte(2<<3), modrm(1)]) - -FISTP = Instruction() -FISTP.mode1(MODRM, ['\xDB', orbyte(3<<3), modrm(1)]) - -FILD = Instruction() -FILD.mode1(MODRM, ['\xDB', orbyte(0<<3), modrm(1)]) - -FNSTCW = Instruction() -FNSTCW.mode1(MODRM, ['\xD9', orbyte(7<<3), modrm(1)]) +FSTP = Instruction() +FSTP.mode1(MODRM64, ['\xDD', orbyte(3<<3), modrm(1)]) +FST = Instruction() +FST.mode1(MODRM64, ['\xDD', orbyte(2<<3), modrm(1)]) # ------------------------- end of floating point ------------------------ Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py Sat Aug 8 10:42:40 2009 @@ -666,7 +666,7 @@ pass ofs, size = symbolic.get_field_token(S, fieldname, self.translate_support_code) - assert rffi.sizeof(getattr(S, fieldname)) in [1, 2, WORD] + assert rffi.sizeof(getattr(S, fieldname)) in [1, 2, WORD, 2*WORD] if (isinstance(getattr(S, fieldname), lltype.Ptr) and getattr(S, fieldname).TO._gckind == 'gc'): ptr = True Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Sat Aug 8 10:42:40 2009 @@ -31,6 +31,9 @@ def getfloat(self, index): return self.cpu.get_latest_value_float(index) + def getint(self, index): + return self.cpu.get_latest_value_int(index) + def test_float_add(self): ops = ''' [f0, f1] @@ -51,6 +54,18 @@ self.interpret(ops, [1.5, 2.5]) assert self.getfloat(0) == 5.5 + def test_float_failure_with_stack_pop(self): + ops = ''' + [f0, i1] + f2 = float_add(f0, f0) + guard_true(i1) + fail(i1) + f3 = float_add(f2, f2) + fail(f3) + ''' + self.interpret(ops, [1.5, 0]) + assert self.getint(0) == 0 + def test_bug_rshift(): v1 = BoxInt() v2 = BoxInt() Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Sat Aug 8 10:42:40 2009 @@ -44,7 +44,7 @@ i386.REL32: 4, } -suffixes = {0:'', 1:'b', 2:'w', 4:'l'} +suffixes = {0:'', 1:'b', 2:'w', 4:'l', 8:'l'} def reg_tests(): return i386.registers[:] @@ -52,6 +52,9 @@ def reg8_tests(): return i386.registers8[:] +def floatreg_tests(): + return i386.floatregisters[:] + def imm8_tests(): v = [-128,-1,0,1,127] + [random.randrange(-127, 127) for i in range(COUNT1)] return map(i386.imm8, v) @@ -85,9 +88,6 @@ def modrm_tests(): return i386.registers + [pick1(i386.memSIB) for i in range(COUNT2)] -def modrm_noreg_tests(): - return [pick1(i386.memSIB) for i in range(COUNT2)] - def modrm64_tests(): return [pick1(i386.memSIB64) for i in range(COUNT2)] @@ -115,6 +115,7 @@ i386.REG: reg_tests, i386.MODRM: modrm_tests, + i386.FLOATREG: floatreg_tests, i386.MODRM64: modrm64_tests, i386.IMM32: imm32_tests, i386.REG8: reg8_tests, @@ -136,9 +137,8 @@ suffix = "" all = instr.as_all_suffixes for m, extra in args: - if m in (i386.MODRM, i386.MODRM8) or all: - if not instrname == 'FNSTCW': - suffix = suffixes[sizes[m]] + suffix + if m in (i386.MODRM, i386.MODRM8, i386.MODRM64) or all: + suffix = suffixes[sizes[m]] + suffix following = "" if instr.indirect: suffix = "" @@ -191,10 +191,7 @@ def rec_test_all(instrname, modes, args=[]): if modes: m = modes[0] - if instrname.startswith('F') and m is i386.MODRM: - lst = modrm_noreg_tests() - else: - lst = tests[m]() + lst = tests[m]() random.shuffle(lst) result = [] for extra in lst: Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_runner.py Sat Aug 8 10:42:40 2009 @@ -353,6 +353,7 @@ for a, b in boxes: for guard in guards: for op in all: + print "NEXT" res = BoxInt() ops = [ ResOperation(op, [a, b], res), From fijal at codespeak.net Sat Aug 8 10:44:39 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 8 Aug 2009 10:44:39 +0200 (CEST) Subject: [pypy-svn] r66758 - pypy/branch/pyjitpl5-floats/pypy/rpython/lltypesystem Message-ID: <20090808084439.74B89168010@codespeak.net> Author: fijal Date: Sat Aug 8 10:44:38 2009 New Revision: 66758 Modified: pypy/branch/pyjitpl5-floats/pypy/rpython/lltypesystem/ll2ctypes.py Log: Move creation of a pointer class a bit up. This speeds up x86 jit backend tests by about 10x, but I'm not sure it's 100% correct. Any other options? Modified: pypy/branch/pyjitpl5-floats/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/rpython/lltypesystem/ll2ctypes.py Sat Aug 8 10:44:38 2009 @@ -109,6 +109,7 @@ assert max_n >= 0 ITEM = A.OF ctypes_item = get_ctypes_type(ITEM, delayed_builders) + PtrType = ctypes.POINTER(sys.maxint/64 * ctypes_item) class CArray(ctypes.Structure): if not A._hints.get('nolength'): @@ -128,7 +129,6 @@ _malloc = classmethod(_malloc) def _indexable(self, index): - PtrType = ctypes.POINTER((index+1) * ctypes_item) p = ctypes.cast(ctypes.pointer(self.items), PtrType) return p.contents From benjamin at codespeak.net Mon Aug 10 18:17:48 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 10 Aug 2009 18:17:48 +0200 (CEST) Subject: [pypy-svn] r66764 - in pypy/trunk/pypy/translator: . test Message-ID: <20090810161748.7CED816800E@codespeak.net> Author: benjamin Date: Mon Aug 10 18:17:45 2009 New Revision: 66764 Modified: pypy/trunk/pypy/translator/geninterplevel.py pypy/trunk/pypy/translator/test/snippet.py pypy/trunk/pypy/translator/test/test_geninterp.py Log: fix using properties with geninterp Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Mon Aug 10 18:17:45 2009 @@ -982,7 +982,7 @@ globname = self.nameof(self.moddict) self.initcode.append('space.setitem(%s, space.new_interned_str("__builtins__"), ' 'space.builtin.w_dict)' % globname) - self.initcode.append('%s = space.eval("property(%s)", %s, %s. hidden_applevel=True)' %( + self.initcode.append('%s = space.eval("property(%s)", %s, %s, hidden_applevel=True)' %( name, origin, globname, globname) ) self.initcode.append('space.delitem(%s, space.new_interned_str("__builtins__"))' % globname) Modified: pypy/trunk/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/pypy/translator/test/snippet.py (original) +++ pypy/trunk/pypy/translator/test/snippet.py Mon Aug 10 18:17:45 2009 @@ -675,7 +675,21 @@ raise Exc(x) except Exception, e: return e.args[0] - + + +class HaveProp(object): + + def __init__(self, v): + self.v = v + + def _hi(self): + "HaveProp._hi" + return self.v + hi = property(_hi) + + +def run_prop(v): + return HaveProp(v).hi # --------------------(Currently) Non runnable Functions --------------------- Modified: pypy/trunk/pypy/translator/test/test_geninterp.py ============================================================================== --- pypy/trunk/pypy/translator/test/test_geninterp.py (original) +++ pypy/trunk/pypy/translator/test/test_geninterp.py Mon Aug 10 18:17:45 2009 @@ -304,3 +304,7 @@ fn = self.build_interpfunc(snippet.exception_subclass_sanity) result = fn(7) assert result == 7 + + def test_property(self): + fn = self.build_interpfunc(snippet.run_prop) + assert fn(23) == 23 From benjamin at codespeak.net Mon Aug 10 21:13:03 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 10 Aug 2009 21:13:03 +0200 (CEST) Subject: [pypy-svn] r66765 - pypy/trunk/pypy/rpython/memory/gc Message-ID: <20090810191303.1F17C16800E@codespeak.net> Author: benjamin Date: Mon Aug 10 21:12:59 2009 New Revision: 66765 Modified: pypy/trunk/pypy/rpython/memory/gc/semispace.py Log: hopefully a helpful comment Modified: pypy/trunk/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/semispace.py Mon Aug 10 21:12:59 2009 @@ -212,6 +212,11 @@ start_time = 0 # Help the flow space start_usage = 0 # Help the flow space #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing)) + + # Switch the spaces. We copy everything over to the empty space + # (self.fromspace at the beginning of the collection), and clear the old + # one (self.tospace at the beginning). Their purposes will be reversed + # for the next collection. tospace = self.fromspace fromspace = self.tospace self.fromspace = fromspace From fijal at codespeak.net Tue Aug 11 10:40:53 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 11 Aug 2009 10:40:53 +0200 (CEST) Subject: [pypy-svn] r66769 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/test Message-ID: <20090811084053.2D1C316800B@codespeak.net> Author: fijal Date: Tue Aug 11 10:40:51 2009 New Revision: 66769 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Log: Some tests for float as call arg Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/test/runner_test.py Tue Aug 11 10:40:51 2009 @@ -106,6 +106,22 @@ 'int', descr=calldescr) assert res.value == ord('B') + def test_call_float(self): + from pypy.rpython.annlowlevel import llhelper + cpu = self.cpu + def func(f1, f2): + print f1, f2 + return f1 + f2*10.0 + FPTR = self.Ptr(self.FuncType([lltype.Float] * 2, lltype.Float)) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(deref(FPTR), deref(FPTR).ARGS, + deref(FPTR).RESULT) + res = self.execute_operation(rop.CALL, + [self.get_funcbox(cpu, func_ptr), + BoxFloat(3.5), BoxFloat(4.5)], + 'float', descr=calldescr) + assert res.value == func(3.5, 4.5) + def test_executor(self): cpu = self.cpu x = execute(cpu, rop.INT_ADD, [BoxInt(100), ConstInt(42)]) From fijal at codespeak.net Tue Aug 11 10:43:19 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 11 Aug 2009 10:43:19 +0200 (CEST) Subject: [pypy-svn] r66770 - in pypy/branch/pyjitpl5-floats/pypy/jit/backend: llgraph x86 x86/test Message-ID: <20090811084319.1141F16800B@codespeak.net> Author: fijal Date: Tue Aug 11 10:43:18 2009 New Revision: 66770 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Log: Support for float calls (still work in-progress, see test_regalloc2) Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/llgraph/llimpl.py Tue Aug 11 10:43:18 2009 @@ -711,6 +711,8 @@ err_result = None elif calldescr.typeinfo == 'p': err_result = lltype.nullptr(llmemory.GCREF.TO) + elif calldescr.typeinfo == 'f': + err_result = 0.0 else: assert calldescr.typeinfo == 'i' err_result = 0 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/assembler.py Tue Aug 11 10:43:18 2009 @@ -826,8 +826,15 @@ for i in range(len(op.args) - 1, 0, -1): v = op.args[i] loc = arglocs[i] - self.mc.PUSH(loc) - extra_on_stack += 1 + if isinstance(loc, MODRM64): + self.mc.PUSH(stack_pos(loc.position, 1)) + self.mc.PUSH(stack_pos(loc.position + 1, 1)) + extra_on_stack += 2 + elif loc is st0: + xxx + else: + self.mc.PUSH(loc) + extra_on_stack += 1 if isinstance(op.args[0], Const): x = rel32(op.args[0].getint()) else: Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py Tue Aug 11 10:43:18 2009 @@ -955,22 +955,23 @@ pass # otherwise it's clean - def sync_var_if_survives(self, v): - if self.longevity[v][1] > self.position: - self.sync_var(v) - def _call(self, op, arglocs, force_store=[]): # we need to store all variables which are now in registers for v, reg in self.reg_bindings.items(): if self.longevity[v][1] > self.position or v in force_store: self.sync_var(v) self.reg_bindings = newcheckdict() - if op.result is not None: + resloc = eax + if op.result is not None and sizeofbox(op.result) == 1: self.reg_bindings[op.result] = eax self.free_regs = [reg for reg in REGS if reg is not eax] else: + if op.result is not None: + assert op.result.type == FLOAT + self.st0 = op.result + resloc = st0 self.free_regs = REGS[:] - self.Perform(op, arglocs, eax) + self.Perform(op, arglocs, resloc) def consider_call(self, op, ignored): from pypy.jit.backend.x86.runner import CPU386 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/runner.py Tue Aug 11 10:43:18 2009 @@ -638,11 +638,6 @@ return self._descr_caches[cachekey] except KeyError: pass - for argtype in argtypes: - if rffi.sizeof(argtype) > WORD: - raise NotImplementedError("bigger than lltype.Signed") - if resulttype is not lltype.Void and rffi.sizeof(resulttype) > WORD: - raise NotImplementedError("bigger than lltype.Signed") if resulttype is lltype.Void: size = 0 else: Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Tue Aug 11 10:43:18 2009 @@ -4,10 +4,10 @@ from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.runner import CPU from pypy.jit.metainterp.test.oparser import parse -from pypy.jit.metainterp.test.oparser import parse class TestRegalloc(object): - namespace = {} + namespace = { + } type_system = 'lltype' cpu = CPU(None, None) @@ -66,6 +66,15 @@ self.interpret(ops, [1.5, 0]) assert self.getint(0) == 0 + def test_float_call_st0_sync(self): + py.test.skip("XXX finish") + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + call(f2, descr=calldescr) + ''' + xxx + def test_bug_rshift(): v1 = BoxInt() v2 = BoxInt() From pedronis at codespeak.net Tue Aug 11 12:27:32 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 12:27:32 +0200 (CEST) Subject: [pypy-svn] r66771 - pypy/trunk/pypy/translator/test Message-ID: <20090811102732.C4EAB16800B@codespeak.net> Author: pedronis Date: Tue Aug 11 12:27:30 2009 New Revision: 66771 Modified: pypy/trunk/pypy/translator/test/snippet.py Log: make the test work in 2.4 too (for the buildbot which really needs to be upgraded) Modified: pypy/trunk/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/pypy/translator/test/snippet.py (original) +++ pypy/trunk/pypy/translator/test/snippet.py Tue Aug 11 12:27:30 2009 @@ -683,9 +683,8 @@ self.v = v def _hi(self): - "HaveProp._hi" return self.v - hi = property(_hi) + hi = property(_hi, doc="HaveProp._hi") def run_prop(v): From pedronis at codespeak.net Tue Aug 11 12:45:07 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 12:45:07 +0200 (CEST) Subject: [pypy-svn] r66774 - pypy/branch/use-py1.0.0 Message-ID: <20090811104507.2A9EC16800B@codespeak.net> Author: pedronis Date: Tue Aug 11 12:45:06 2009 New Revision: 66774 Added: pypy/branch/use-py1.0.0/ - copied from r66773, pypy/trunk/ Log: hopefully short-lived branch to move to use py 1.0.0 From pedronis at codespeak.net Tue Aug 11 12:47:39 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 12:47:39 +0200 (CEST) Subject: [pypy-svn] r66775 - pypy/branch/use-py1.0.0 Message-ID: <20090811104739.8011716800B@codespeak.net> Author: pedronis Date: Tue Aug 11 12:47:39 2009 New Revision: 66775 Modified: pypy/branch/use-py1.0.0/ (props changed) Log: switch the external to point to py/dist (a tag would be better) From pedronis at codespeak.net Tue Aug 11 14:03:39 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 14:03:39 +0200 (CEST) Subject: [pypy-svn] r66776 - in pypy/branch/use-py1.0.0/pypy: . doc Message-ID: <20090811120339.8641216800B@codespeak.net> Author: pedronis Date: Tue Aug 11 14:03:35 2009 New Revision: 66776 Modified: pypy/branch/use-py1.0.0/pypy/conftest.py pypy/branch/use-py1.0.0/pypy/doc/conftest.py Log: adapt contests Modified: pypy/branch/use-py1.0.0/pypy/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/conftest.py Tue Aug 11 14:03:35 2009 @@ -29,25 +29,22 @@ option = py.test.config.option -class PyPyTestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy options") - group.addoption('--view', action="store_true", dest="view", default=False, - help="view translation tests' flow graphs with Pygame") - group.addoption('-A', '--runappdirect', action="store_true", - default=False, dest="runappdirect", - help="run applevel tests directly on python interpreter (not through PyPy)") - group.addoption('--direct', action="store_true", - default=False, dest="rundirect", - help="run pexpect tests directly") - group.addoption('-P', '--platform', action="callback", type="string", - default="host", callback=_set_platform, - help="set up tests to use specified platform as compile/run target") - - def pytest_funcarg__space(self, pyfuncitem): - return gettestobjspace() - -ConftestPlugin = PyPyTestPlugin +def pytest_addoption(parser): + group = parser.addgroup("pypy options") + group.addoption('--view', action="store_true", dest="view", default=False, + help="view translation tests' flow graphs with Pygame") + group.addoption('-A', '--runappdirect', action="store_true", + default=False, dest="runappdirect", + help="run applevel tests directly on python interpreter (not through PyPy)") + group.addoption('--direct', action="store_true", + default=False, dest="rundirect", + help="run pexpect tests directly") + group.addoption('-P', '--platform', action="callback", type="string", + default="host", callback=_set_platform, + help="set up tests to use specified platform as compile/run target") + +def pytest_funcarg__space(request): + return gettestobjspace() _SPACECACHE={} def gettestobjspace(name=None, **kwds): Modified: pypy/branch/use-py1.0.0/pypy/doc/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/doc/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/doc/conftest.py Tue Aug 11 14:03:35 2009 @@ -5,28 +5,25 @@ pytest_plugins = "pytest_restdoc" -class PyPyDocPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-doc options") - group.addoption('--pypy-doctests', action="store_true", - dest="pypy_doctests", default=False, - help="enable doctests in .txt files") - group.addoption('--generate-redirections', - action="store_true", dest="generateredirections", - default=True, help="Generate redirecting HTML files") +def pytest_addoption(parser): + group = parser.addgroup("pypy-doc options") + group.addoption('--pypy-doctests', action="store_true", + dest="pypy_doctests", default=False, + help="enable doctests in .txt files") + group.addoption('--generate-redirections', + action="store_true", dest="generateredirections", + default=True, help="Generate redirecting HTML files") - def pytest_configure(self, config): - self.config = config - register_config_role(docdir) - - def pytest_doctest_prepare_content(self, content): - if not self.config.getvalue("pypy_doctests"): - py.test.skip("specify --pypy-doctests to run doctests") - l = [] - for line in content.split("\n"): - if line.find('>>>>') != -1: - line = "" - l.append(line) - return "\n".join(l) +def pytest_configure(config): + register_config_role(docdir) + +def pytest_doctest_prepare_content(content): + if not py.test.config.getvalue("pypy_doctests"): + py.test.skip("specify --pypy-doctests to run doctests") + l = [] + for line in content.split("\n"): + if line.find('>>>>') != -1: + line = "" + l.append(line) + return "\n".join(l) -ConftestPlugin = PyPyDocPlugin From pedronis at codespeak.net Tue Aug 11 14:08:11 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 14:08:11 +0200 (CEST) Subject: [pypy-svn] r66777 - in pypy/branch/use-py1.0.0/pypy/translator: cli jvm Message-ID: <20090811120811.D7DFF16800B@codespeak.net> Author: pedronis Date: Tue Aug 11 14:08:10 2009 New Revision: 66777 Modified: pypy/branch/use-py1.0.0/pypy/translator/cli/conftest.py pypy/branch/use-py1.0.0/pypy/translator/jvm/conftest.py Log: adapt more contests Modified: pypy/branch/use-py1.0.0/pypy/translator/cli/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/translator/cli/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/translator/cli/conftest.py Tue Aug 11 14:08:10 2009 @@ -1,19 +1,18 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-cli options") - group.addoption('--source', action="store_true", dest="source", default=False, - help="only generate IL source, don't compile") - group.addoption('--wd', action="store_true", dest="wd", default=False, - help="store temporary files in the working directory") - group.addoption('--stdout', action="store_true", dest="stdout", default=False, - help="print the generated IL code to stdout, too") - group.addoption('--nostop', action="store_true", dest="nostop", default=False, - help="don't stop on warning. The generated IL code could not compile") - group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, - help="don't wrap exceptions but let them to flow out of the entry point") - group.addoption('--verify', action="store_true", dest="verify", default=False, - help="check that compiled executables are verifiable") - group.addoption('--norun', action='store_true', dest="norun", default=False, - help="don't run the compiled executable") - group.addoption('--trace', action='store_true', dest='trace', default=False, - help='Trace execution of generated code') +def pytest_addoption(parser): + group = parser.addgroup("pypy-cli options") + group.addoption('--source', action="store_true", dest="source", default=False, + help="only generate IL source, don't compile") + group.addoption('--wd', action="store_true", dest="wd", default=False, + help="store temporary files in the working directory") + group.addoption('--stdout', action="store_true", dest="stdout", default=False, + help="print the generated IL code to stdout, too") + group.addoption('--nostop', action="store_true", dest="nostop", default=False, + help="don't stop on warning. The generated IL code could not compile") + group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, + help="don't wrap exceptions but let them to flow out of the entry point") + group.addoption('--verify', action="store_true", dest="verify", default=False, + help="check that compiled executables are verifiable") + group.addoption('--norun', action='store_true', dest="norun", default=False, + help="don't run the compiled executable") + group.addoption('--trace', action='store_true', dest='trace', default=False, + help='Trace execution of generated code') Modified: pypy/branch/use-py1.0.0/pypy/translator/jvm/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/translator/jvm/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/translator/jvm/conftest.py Tue Aug 11 14:08:10 2009 @@ -1,18 +1,22 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-jvm options") - group.addoption('--java', action='store', dest='java', default='java', - help='Define the java executable to use') - group.addoption('--javac', action='store', dest='javac', default='javac', - help='Define the javac executable to use') - group.addoption('--jasmin', action='store', dest='java', default='java', - help='Define the jasmin script to use') - group.addoption('--noassemble', action='store_true', dest="noasm", default=False, - help="don't assemble jasmin files") - group.addoption('--package', action='store', dest='package', default='pypy', - help='Package to output generated classes into') -## group.addoption('--trace', action='store_true', dest='trace', default=False, -## help='Trace execution of generated code') - group.addoption('--byte-arrays', action='store_true', dest='byte-arrays', - default=False, help='Use byte arrays rather than native strings') + +def pytest_addoption(parser): + group = parser.addgroup("pypy-jvm options") + group.addoption('--java', action='store', dest='java', default='java', + help='Define the java executable to use') + group.addoption('--javac', action='store', dest='javac', + default='javac', + help='Define the javac executable to use') + group.addoption('--jasmin', action='store', dest='java', default='java', + help='Define the jasmin script to use') + group.addoption('--noassemble', action='store_true', dest="noasm", + default=False, + help="don't assemble jasmin files") + group.addoption('--package', action='store', dest='package', + default='pypy', + help='Package to output generated classes into') + + group.addoption('--byte-arrays', action='store_true', + dest='byte-arrays', + default=False, + help='Use byte arrays rather than native strings') From pedronis at codespeak.net Tue Aug 11 15:23:43 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 15:23:43 +0200 (CEST) Subject: [pypy-svn] r66778 - in pypy/branch/use-py1.0.0/pypy: . objspace/std tool/test Message-ID: <20090811132343.E6FEF16800B@codespeak.net> Author: pedronis Date: Tue Aug 11 15:23:42 2009 New Revision: 66778 Modified: pypy/branch/use-py1.0.0/pypy/conftest.py pypy/branch/use-py1.0.0/pypy/objspace/std/fake.py pypy/branch/use-py1.0.0/pypy/tool/test/test_conftest1.py pypy/branch/use-py1.0.0/pypy/tool/test/test_pytestsupport.py Log: fixes, fix fakedexceptionf or 2.5, also make sure app_test_blow does what it intended Modified: pypy/branch/use-py1.0.0/pypy/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/conftest.py Tue Aug 11 15:23:42 2009 @@ -29,6 +29,8 @@ option = py.test.config.option +#pytest_option_capture = 'no' + def pytest_addoption(parser): group = parser.addgroup("pypy options") group.addoption('--view', action="store_true", dest="view", default=False, @@ -316,10 +318,10 @@ raise AppError, AppError(appexcinfo), tb raise - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if excinfo.errisinstance(AppError): excinfo = excinfo.value.excinfo - return super(PyPyTestFunction, self).repr_failure(excinfo, outerr) + return super(PyPyTestFunction, self).repr_failure(excinfo) _pygame_imported = False Modified: pypy/branch/use-py1.0.0/pypy/objspace/std/fake.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/objspace/std/fake.py (original) +++ pypy/branch/use-py1.0.0/pypy/objspace/std/fake.py Tue Aug 11 15:23:42 2009 @@ -103,7 +103,7 @@ unwrap_spec=[baseobjspace.ObjSpace, baseobjspace.W_Root, argument.Arguments]) - if cpy_type.__base__ is not object: + if cpy_type.__base__ is not object and not issubclass(cpy_type, Exception): assert cpy_type.__base__ is basestring, cpy_type from pypy.objspace.std.basestringtype import basestring_typedef base = basestring_typedef Modified: pypy/branch/use-py1.0.0/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/tool/test/test_conftest1.py (original) +++ pypy/branch/use-py1.0.0/pypy/tool/test/test_conftest1.py Tue Aug 11 15:23:42 2009 @@ -11,7 +11,7 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('test_something', 'test_method') + assert repevent.item.name in ('test_something', 'test_method') def test_select_applevel(self, testdir): sorter = testdir.inline_run("-k", "applevel", innertest) @@ -19,14 +19,14 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('app_test_something', 'test_method_app') + assert repevent.item.name in ('app_test_something', 'test_method_app') def test_appdirect(self, testdir): sorter = testdir.inline_run(innertest, '-k', 'applevel', '--runappdirect') passed, skipped, failed = sorter.listoutcomes() assert len(passed) == 2 print passed - names = [x.colitem.name for x in passed] + names = [x.item.name for x in passed] assert 'app_test_something' in names assert 'test_method_app' in names Modified: pypy/branch/use-py1.0.0/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/branch/use-py1.0.0/pypy/tool/test/test_pytestsupport.py Tue Aug 11 15:23:42 2009 @@ -90,7 +90,6 @@ else: py.test.fail("did not raise!") assert "PicklingError" in appex.exconly() - assert "SomeMessage" in appex.exconly() class AppTestWithWrappedInterplevelAttributes: def setup_class(cls): @@ -134,9 +133,9 @@ def test_one(self): pass """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.passed - sfn = ev.colitem.safe_filename() + sfn = ev.item.safe_filename() print sfn assert sfn == 'test_safe_filename_test_safe_filename_ExpectTestOne_paren_test_one_1.py' @@ -151,11 +150,11 @@ def test_app_test_blow(testdir): conftestpath.copy(testdir.tmpdir) - sorter = testdir.inline_runsource(""" -class AppTestBlow: - def test_one(self): - exec 'blow' + sorter = testdir.inline_runsource("""class AppTestBlow: + def test_one(self): exec 'blow' """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.failed + assert 'NameError' in ev.longrepr.reprcrash.message + assert 'blow' in ev.longrepr.reprcrash.message From pedronis at codespeak.net Tue Aug 11 15:25:15 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 15:25:15 +0200 (CEST) Subject: [pypy-svn] r66779 - pypy/branch/use-py1.0.0/pypy Message-ID: <20090811132515.6C98116800C@codespeak.net> Author: pedronis Date: Tue Aug 11 15:25:15 2009 New Revision: 66779 Modified: pypy/branch/use-py1.0.0/pypy/conftest.py Log: unwanted Modified: pypy/branch/use-py1.0.0/pypy/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/conftest.py Tue Aug 11 15:25:15 2009 @@ -29,8 +29,6 @@ option = py.test.config.option -#pytest_option_capture = 'no' - def pytest_addoption(parser): group = parser.addgroup("pypy options") group.addoption('--view', action="store_true", dest="view", default=False, From pedronis at codespeak.net Tue Aug 11 15:28:36 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 15:28:36 +0200 (CEST) Subject: [pypy-svn] r66780 - pypy/branch/use-py1.0.0/pypy/lang/js/test/ecma Message-ID: <20090811132836.E1B1A16800C@codespeak.net> Author: pedronis Date: Tue Aug 11 15:28:36 2009 New Revision: 66780 Modified: pypy/branch/use-py1.0.0/pypy/lang/js/test/ecma/conftest.py Log: adapt js/test/ecma conftest Modified: pypy/branch/use-py1.0.0/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/lang/js/test/ecma/conftest.py Tue Aug 11 15:28:36 2009 @@ -11,20 +11,17 @@ rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] -class EcmatestPlugin: - def pytest_addoption(self, parser): - parser.addoption('--ecma', - action="store_true", dest="ecma", default=False, - help="run js interpreter ecma tests" - ) - - def pytest_collect_file(self, path, parent): - if path.ext == ".js" and path.basename not in exclusionlist: - if not parent.config.option.ecma: - py.test.skip("ECMA tests disabled, run with --ecma") - return JSTestFile(path, parent=parent) - -ConftestPlugin = EcmatestPlugin +def pytest_addoption(parser): + parser.addoption('--ecma', + action="store_true", dest="ecma", default=False, + help="run js interpreter ecma tests" + ) + +def pytest_collect_file(path, parent): + if path.ext == ".js" and path.basename not in exclusionlist: + if not parent.config.option.ecma: + py.test.skip("ECMA tests disabled, run with --ecma") + return JSTestFile(path, parent=parent) class JSTestFile(py.test.collect.File): def init_interp(cls): From pedronis at codespeak.net Tue Aug 11 15:35:31 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 15:35:31 +0200 (CEST) Subject: [pypy-svn] r66781 - pypy/branch/use-py1.0.0/dotviewer Message-ID: <20090811133531.6EF9316800B@codespeak.net> Author: pedronis Date: Tue Aug 11 15:35:30 2009 New Revision: 66781 Modified: pypy/branch/use-py1.0.0/dotviewer/conftest.py Log: adapt dotviewer conftest Modified: pypy/branch/use-py1.0.0/dotviewer/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/dotviewer/conftest.py (original) +++ pypy/branch/use-py1.0.0/dotviewer/conftest.py Tue Aug 11 15:35:30 2009 @@ -1,8 +1,9 @@ import py -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("dotviever") - group.addoption('--pygame', action="store_true", - dest="pygame", default=False, - help="allow interactive tests using Pygame") +def pytest_addoption(parser): + group = parser.addgroup("dotviever") + group.addoption('--pygame', action="store_true", + dest="pygame", default=False, + help="allow interactive tests using Pygame") + +option = py.test.config.option From pedronis at codespeak.net Tue Aug 11 15:39:15 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 15:39:15 +0200 (CEST) Subject: [pypy-svn] r66782 - pypy/branch/use-py1.0.0/lib-python Message-ID: <20090811133915.86A5616800B@codespeak.net> Author: pedronis Date: Tue Aug 11 15:39:15 2009 New Revision: 66782 Modified: pypy/branch/use-py1.0.0/lib-python/conftest.py Log: adapt conftest Modified: pypy/branch/use-py1.0.0/lib-python/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/lib-python/conftest.py (original) +++ pypy/branch/use-py1.0.0/lib-python/conftest.py Tue Aug 11 15:39:15 2009 @@ -27,18 +27,16 @@ # Interfacing/Integrating with py.test's collection process # -class LibPythonPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("complicance testing options") - group.addoption('-T', '--timeout', action="store", type="string", - default="1000", dest="timeout", - help="fail a test module after the given timeout. " - "specify in seconds or 'NUMmp' aka Mega-Pystones") - group.addoption('--pypy', action="store", type="string", - dest="pypy", help="use given pypy executable to run lib-python tests. " - "This will run the tests directly (i.e. not through py.py)") +def pytest_addoption(parser): + group = parser.addgroup("complicance testing options") + group.addoption('-T', '--timeout', action="store", type="string", + default="1000", dest="timeout", + help="fail a test module after the given timeout. " + "specify in seconds or 'NUMmp' aka Mega-Pystones") + group.addoption('--pypy', action="store", type="string", + dest="pypy", help="use given pypy executable to run lib-python tests. " + "This will run the tests directly (i.e. not through py.py)") -ConftestPlugin = LibPythonPlugin option = py.test.config.option def gettimeout(): From pedronis at codespeak.net Tue Aug 11 18:04:55 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 18:04:55 +0200 (CEST) Subject: [pypy-svn] r66783 - pypy/branch/use-py1.0.0/pypy Message-ID: <20090811160455.B8B0316800C@codespeak.net> Author: pedronis Date: Tue Aug 11 18:04:53 2009 New Revision: 66783 Modified: pypy/branch/use-py1.0.0/pypy/conftest.py Log: workaround, do we still need the lib/py symlink Modified: pypy/branch/use-py1.0.0/pypy/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/conftest.py Tue Aug 11 18:04:53 2009 @@ -15,7 +15,13 @@ pytest_plugins = "resultlog", rsyncdirs = ['.', '../lib-python', '../demo'] rsyncignore = ['_cache'] - + +# XXX workaround for a py.test bug clashing with lib/py bug +# do we really need the latter? +empty_conftest = type(sys)('conftest') +empty_conftest.__file__ = "?" +sys.modules['pypy.lib.py.conftest'] = empty_conftest + # PyPy's command line extra options (these are added # to py.test's standard options) # From pedronis at codespeak.net Tue Aug 11 18:06:31 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 11 Aug 2009 18:06:31 +0200 (CEST) Subject: [pypy-svn] r66784 - pypy/branch/use-py1.0.0/pypy Message-ID: <20090811160631.B5E3D16800C@codespeak.net> Author: pedronis Date: Tue Aug 11 18:06:30 2009 New Revision: 66784 Modified: pypy/branch/use-py1.0.0/pypy/conftest.py Log: fix comment Modified: pypy/branch/use-py1.0.0/pypy/conftest.py ============================================================================== --- pypy/branch/use-py1.0.0/pypy/conftest.py (original) +++ pypy/branch/use-py1.0.0/pypy/conftest.py Tue Aug 11 18:06:30 2009 @@ -16,7 +16,7 @@ rsyncdirs = ['.', '../lib-python', '../demo'] rsyncignore = ['_cache'] -# XXX workaround for a py.test bug clashing with lib/py bug +# XXX workaround for a py.test bug clashing with lib/py symlink # do we really need the latter? empty_conftest = type(sys)('conftest') empty_conftest.__file__ = "?" From benjamin at codespeak.net Tue Aug 11 20:09:09 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 11 Aug 2009 20:09:09 +0200 (CEST) Subject: [pypy-svn] r66785 - pypy/trunk/pypy/interpreter Message-ID: <20090811180909.DCE4E16800F@codespeak.net> Author: benjamin Date: Tue Aug 11 20:09:07 2009 New Revision: 66785 Modified: pypy/trunk/pypy/interpreter/pyframe.py Log: fix name in comment Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Aug 11 20:09:07 2009 @@ -22,7 +22,7 @@ """Represents a frame for a regular Python function that needs to be interpreted. - See also pyopcode.PyStandardFrame and pynestedscope.PyNestedScopeFrame. + See also pyopcode.PyStandardFrame and nestedscope.PyNestedScopeFrame. Public fields: * 'space' is the object space this frame is running in From pedronis at codespeak.net Wed Aug 12 09:55:16 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 12 Aug 2009 09:55:16 +0200 (CEST) Subject: [pypy-svn] r66786 - pypy/branch/use-py1.0.0 Message-ID: <20090812075516.845F316800D@codespeak.net> Author: pedronis Date: Wed Aug 12 09:55:15 2009 New Revision: 66786 Modified: pypy/branch/use-py1.0.0/ (props changed) Log: pin down py/dist revision From pedronis at codespeak.net Wed Aug 12 10:07:11 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 12 Aug 2009 10:07:11 +0200 (CEST) Subject: [pypy-svn] r66787 - in pypy/trunk: . dotviewer lib-python pypy pypy/doc pypy/lang/js/test/ecma pypy/objspace/std pypy/tool/test pypy/translator/cli pypy/translator/jvm Message-ID: <20090812080711.01AA9168003@codespeak.net> Author: pedronis Date: Wed Aug 12 10:07:09 2009 New Revision: 66787 Modified: pypy/trunk/ (props changed) pypy/trunk/dotviewer/ (props changed) pypy/trunk/dotviewer/conftest.py pypy/trunk/lib-python/ (props changed) pypy/trunk/lib-python/conftest.py pypy/trunk/pypy/ (props changed) pypy/trunk/pypy/conftest.py pypy/trunk/pypy/doc/conftest.py pypy/trunk/pypy/lang/js/test/ecma/conftest.py pypy/trunk/pypy/objspace/std/fake.py pypy/trunk/pypy/tool/test/test_conftest1.py pypy/trunk/pypy/tool/test/test_pytestsupport.py pypy/trunk/pypy/translator/cli/conftest.py pypy/trunk/pypy/translator/jvm/conftest.py Log: merging use-py1.0.0 branch, changes to switch using py.lib 1.0 final Modified: pypy/trunk/dotviewer/conftest.py ============================================================================== --- pypy/trunk/dotviewer/conftest.py (original) +++ pypy/trunk/dotviewer/conftest.py Wed Aug 12 10:07:09 2009 @@ -1,8 +1,9 @@ import py -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("dotviever") - group.addoption('--pygame', action="store_true", - dest="pygame", default=False, - help="allow interactive tests using Pygame") +def pytest_addoption(parser): + group = parser.addgroup("dotviever") + group.addoption('--pygame', action="store_true", + dest="pygame", default=False, + help="allow interactive tests using Pygame") + +option = py.test.config.option Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Wed Aug 12 10:07:09 2009 @@ -27,18 +27,16 @@ # Interfacing/Integrating with py.test's collection process # -class LibPythonPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("complicance testing options") - group.addoption('-T', '--timeout', action="store", type="string", - default="1000", dest="timeout", - help="fail a test module after the given timeout. " - "specify in seconds or 'NUMmp' aka Mega-Pystones") - group.addoption('--pypy', action="store", type="string", - dest="pypy", help="use given pypy executable to run lib-python tests. " - "This will run the tests directly (i.e. not through py.py)") +def pytest_addoption(parser): + group = parser.addgroup("complicance testing options") + group.addoption('-T', '--timeout', action="store", type="string", + default="1000", dest="timeout", + help="fail a test module after the given timeout. " + "specify in seconds or 'NUMmp' aka Mega-Pystones") + group.addoption('--pypy', action="store", type="string", + dest="pypy", help="use given pypy executable to run lib-python tests. " + "This will run the tests directly (i.e. not through py.py)") -ConftestPlugin = LibPythonPlugin option = py.test.config.option def gettimeout(): Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Wed Aug 12 10:07:09 2009 @@ -15,7 +15,13 @@ pytest_plugins = "resultlog", rsyncdirs = ['.', '../lib-python', '../demo'] rsyncignore = ['_cache'] - + +# XXX workaround for a py.test bug clashing with lib/py symlink +# do we really need the latter? +empty_conftest = type(sys)('conftest') +empty_conftest.__file__ = "?" +sys.modules['pypy.lib.py.conftest'] = empty_conftest + # PyPy's command line extra options (these are added # to py.test's standard options) # @@ -29,25 +35,22 @@ option = py.test.config.option -class PyPyTestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy options") - group.addoption('--view', action="store_true", dest="view", default=False, - help="view translation tests' flow graphs with Pygame") - group.addoption('-A', '--runappdirect', action="store_true", - default=False, dest="runappdirect", - help="run applevel tests directly on python interpreter (not through PyPy)") - group.addoption('--direct', action="store_true", - default=False, dest="rundirect", - help="run pexpect tests directly") - group.addoption('-P', '--platform', action="callback", type="string", - default="host", callback=_set_platform, - help="set up tests to use specified platform as compile/run target") - - def pytest_funcarg__space(self, pyfuncitem): - return gettestobjspace() - -ConftestPlugin = PyPyTestPlugin +def pytest_addoption(parser): + group = parser.addgroup("pypy options") + group.addoption('--view', action="store_true", dest="view", default=False, + help="view translation tests' flow graphs with Pygame") + group.addoption('-A', '--runappdirect', action="store_true", + default=False, dest="runappdirect", + help="run applevel tests directly on python interpreter (not through PyPy)") + group.addoption('--direct', action="store_true", + default=False, dest="rundirect", + help="run pexpect tests directly") + group.addoption('-P', '--platform', action="callback", type="string", + default="host", callback=_set_platform, + help="set up tests to use specified platform as compile/run target") + +def pytest_funcarg__space(request): + return gettestobjspace() _SPACECACHE={} def gettestobjspace(name=None, **kwds): @@ -319,10 +322,10 @@ raise AppError, AppError(appexcinfo), tb raise - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if excinfo.errisinstance(AppError): excinfo = excinfo.value.excinfo - return super(PyPyTestFunction, self).repr_failure(excinfo, outerr) + return super(PyPyTestFunction, self).repr_failure(excinfo) _pygame_imported = False Modified: pypy/trunk/pypy/doc/conftest.py ============================================================================== --- pypy/trunk/pypy/doc/conftest.py (original) +++ pypy/trunk/pypy/doc/conftest.py Wed Aug 12 10:07:09 2009 @@ -5,28 +5,25 @@ pytest_plugins = "pytest_restdoc" -class PyPyDocPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-doc options") - group.addoption('--pypy-doctests', action="store_true", - dest="pypy_doctests", default=False, - help="enable doctests in .txt files") - group.addoption('--generate-redirections', - action="store_true", dest="generateredirections", - default=True, help="Generate redirecting HTML files") +def pytest_addoption(parser): + group = parser.addgroup("pypy-doc options") + group.addoption('--pypy-doctests', action="store_true", + dest="pypy_doctests", default=False, + help="enable doctests in .txt files") + group.addoption('--generate-redirections', + action="store_true", dest="generateredirections", + default=True, help="Generate redirecting HTML files") - def pytest_configure(self, config): - self.config = config - register_config_role(docdir) - - def pytest_doctest_prepare_content(self, content): - if not self.config.getvalue("pypy_doctests"): - py.test.skip("specify --pypy-doctests to run doctests") - l = [] - for line in content.split("\n"): - if line.find('>>>>') != -1: - line = "" - l.append(line) - return "\n".join(l) +def pytest_configure(config): + register_config_role(docdir) + +def pytest_doctest_prepare_content(content): + if not py.test.config.getvalue("pypy_doctests"): + py.test.skip("specify --pypy-doctests to run doctests") + l = [] + for line in content.split("\n"): + if line.find('>>>>') != -1: + line = "" + l.append(line) + return "\n".join(l) -ConftestPlugin = PyPyDocPlugin Modified: pypy/trunk/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/trunk/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/trunk/pypy/lang/js/test/ecma/conftest.py Wed Aug 12 10:07:09 2009 @@ -11,20 +11,17 @@ rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] -class EcmatestPlugin: - def pytest_addoption(self, parser): - parser.addoption('--ecma', - action="store_true", dest="ecma", default=False, - help="run js interpreter ecma tests" - ) - - def pytest_collect_file(self, path, parent): - if path.ext == ".js" and path.basename not in exclusionlist: - if not parent.config.option.ecma: - py.test.skip("ECMA tests disabled, run with --ecma") - return JSTestFile(path, parent=parent) - -ConftestPlugin = EcmatestPlugin +def pytest_addoption(parser): + parser.addoption('--ecma', + action="store_true", dest="ecma", default=False, + help="run js interpreter ecma tests" + ) + +def pytest_collect_file(path, parent): + if path.ext == ".js" and path.basename not in exclusionlist: + if not parent.config.option.ecma: + py.test.skip("ECMA tests disabled, run with --ecma") + return JSTestFile(path, parent=parent) class JSTestFile(py.test.collect.File): def init_interp(cls): Modified: pypy/trunk/pypy/objspace/std/fake.py ============================================================================== --- pypy/trunk/pypy/objspace/std/fake.py (original) +++ pypy/trunk/pypy/objspace/std/fake.py Wed Aug 12 10:07:09 2009 @@ -103,7 +103,7 @@ unwrap_spec=[baseobjspace.ObjSpace, baseobjspace.W_Root, argument.Arguments]) - if cpy_type.__base__ is not object: + if cpy_type.__base__ is not object and not issubclass(cpy_type, Exception): assert cpy_type.__base__ is basestring, cpy_type from pypy.objspace.std.basestringtype import basestring_typedef base = basestring_typedef Modified: pypy/trunk/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_conftest1.py (original) +++ pypy/trunk/pypy/tool/test/test_conftest1.py Wed Aug 12 10:07:09 2009 @@ -11,7 +11,7 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('test_something', 'test_method') + assert repevent.item.name in ('test_something', 'test_method') def test_select_applevel(self, testdir): sorter = testdir.inline_run("-k", "applevel", innertest) @@ -19,14 +19,14 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('app_test_something', 'test_method_app') + assert repevent.item.name in ('app_test_something', 'test_method_app') def test_appdirect(self, testdir): sorter = testdir.inline_run(innertest, '-k', 'applevel', '--runappdirect') passed, skipped, failed = sorter.listoutcomes() assert len(passed) == 2 print passed - names = [x.colitem.name for x in passed] + names = [x.item.name for x in passed] assert 'app_test_something' in names assert 'test_method_app' in names Modified: pypy/trunk/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/trunk/pypy/tool/test/test_pytestsupport.py Wed Aug 12 10:07:09 2009 @@ -90,7 +90,6 @@ else: py.test.fail("did not raise!") assert "PicklingError" in appex.exconly() - assert "SomeMessage" in appex.exconly() class AppTestWithWrappedInterplevelAttributes: def setup_class(cls): @@ -134,9 +133,9 @@ def test_one(self): pass """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.passed - sfn = ev.colitem.safe_filename() + sfn = ev.item.safe_filename() print sfn assert sfn == 'test_safe_filename_test_safe_filename_ExpectTestOne_paren_test_one_1.py' @@ -151,11 +150,11 @@ def test_app_test_blow(testdir): conftestpath.copy(testdir.tmpdir) - sorter = testdir.inline_runsource(""" -class AppTestBlow: - def test_one(self): - exec 'blow' + sorter = testdir.inline_runsource("""class AppTestBlow: + def test_one(self): exec 'blow' """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.failed + assert 'NameError' in ev.longrepr.reprcrash.message + assert 'blow' in ev.longrepr.reprcrash.message Modified: pypy/trunk/pypy/translator/cli/conftest.py ============================================================================== --- pypy/trunk/pypy/translator/cli/conftest.py (original) +++ pypy/trunk/pypy/translator/cli/conftest.py Wed Aug 12 10:07:09 2009 @@ -1,19 +1,18 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-cli options") - group.addoption('--source', action="store_true", dest="source", default=False, - help="only generate IL source, don't compile") - group.addoption('--wd', action="store_true", dest="wd", default=False, - help="store temporary files in the working directory") - group.addoption('--stdout', action="store_true", dest="stdout", default=False, - help="print the generated IL code to stdout, too") - group.addoption('--nostop', action="store_true", dest="nostop", default=False, - help="don't stop on warning. The generated IL code could not compile") - group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, - help="don't wrap exceptions but let them to flow out of the entry point") - group.addoption('--verify', action="store_true", dest="verify", default=False, - help="check that compiled executables are verifiable") - group.addoption('--norun', action='store_true', dest="norun", default=False, - help="don't run the compiled executable") - group.addoption('--trace', action='store_true', dest='trace', default=False, - help='Trace execution of generated code') +def pytest_addoption(parser): + group = parser.addgroup("pypy-cli options") + group.addoption('--source', action="store_true", dest="source", default=False, + help="only generate IL source, don't compile") + group.addoption('--wd', action="store_true", dest="wd", default=False, + help="store temporary files in the working directory") + group.addoption('--stdout', action="store_true", dest="stdout", default=False, + help="print the generated IL code to stdout, too") + group.addoption('--nostop', action="store_true", dest="nostop", default=False, + help="don't stop on warning. The generated IL code could not compile") + group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, + help="don't wrap exceptions but let them to flow out of the entry point") + group.addoption('--verify', action="store_true", dest="verify", default=False, + help="check that compiled executables are verifiable") + group.addoption('--norun', action='store_true', dest="norun", default=False, + help="don't run the compiled executable") + group.addoption('--trace', action='store_true', dest='trace', default=False, + help='Trace execution of generated code') Modified: pypy/trunk/pypy/translator/jvm/conftest.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/conftest.py (original) +++ pypy/trunk/pypy/translator/jvm/conftest.py Wed Aug 12 10:07:09 2009 @@ -1,18 +1,22 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-jvm options") - group.addoption('--java', action='store', dest='java', default='java', - help='Define the java executable to use') - group.addoption('--javac', action='store', dest='javac', default='javac', - help='Define the javac executable to use') - group.addoption('--jasmin', action='store', dest='java', default='java', - help='Define the jasmin script to use') - group.addoption('--noassemble', action='store_true', dest="noasm", default=False, - help="don't assemble jasmin files") - group.addoption('--package', action='store', dest='package', default='pypy', - help='Package to output generated classes into') -## group.addoption('--trace', action='store_true', dest='trace', default=False, -## help='Trace execution of generated code') - group.addoption('--byte-arrays', action='store_true', dest='byte-arrays', - default=False, help='Use byte arrays rather than native strings') + +def pytest_addoption(parser): + group = parser.addgroup("pypy-jvm options") + group.addoption('--java', action='store', dest='java', default='java', + help='Define the java executable to use') + group.addoption('--javac', action='store', dest='javac', + default='javac', + help='Define the javac executable to use') + group.addoption('--jasmin', action='store', dest='java', default='java', + help='Define the jasmin script to use') + group.addoption('--noassemble', action='store_true', dest="noasm", + default=False, + help="don't assemble jasmin files") + group.addoption('--package', action='store', dest='package', + default='pypy', + help='Package to output generated classes into') + + group.addoption('--byte-arrays', action='store_true', + dest='byte-arrays', + default=False, + help='Use byte arrays rather than native strings') From pedronis at codespeak.net Wed Aug 12 10:25:58 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 12 Aug 2009 10:25:58 +0200 (CEST) Subject: [pypy-svn] r66788 - in pypy/branch/pyjitpl5: . demo/tproxy dotviewer lib-python pypy pypy/doc pypy/jit pypy/jit/backend/test pypy/jit/tl pypy/lang/js/test/ecma pypy/module/pypyjit/test pypy/objspace/std pypy/tool/test pypy/translator/cli pypy/translator/jvm Message-ID: <20090812082558.514E616800C@codespeak.net> Author: pedronis Date: Wed Aug 12 10:25:57 2009 New Revision: 66788 Modified: pypy/branch/pyjitpl5/ (props changed) pypy/branch/pyjitpl5/demo/tproxy/persistence.py (props changed) pypy/branch/pyjitpl5/dotviewer/ (props changed) pypy/branch/pyjitpl5/dotviewer/conftest.py pypy/branch/pyjitpl5/lib-python/ (props changed) pypy/branch/pyjitpl5/lib-python/conftest.py pypy/branch/pyjitpl5/pypy/ (props changed) pypy/branch/pyjitpl5/pypy/conftest.py pypy/branch/pyjitpl5/pypy/doc/conftest.py pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py pypy/branch/pyjitpl5/pypy/jit/conftest.py pypy/branch/pyjitpl5/pypy/jit/tl/conftest.py pypy/branch/pyjitpl5/pypy/lang/js/test/ecma/conftest.py pypy/branch/pyjitpl5/pypy/module/pypyjit/test/conftest.py pypy/branch/pyjitpl5/pypy/objspace/std/fake.py pypy/branch/pyjitpl5/pypy/tool/test/test_conftest1.py pypy/branch/pyjitpl5/pypy/tool/test/test_pytestsupport.py pypy/branch/pyjitpl5/pypy/translator/cli/conftest.py pypy/branch/pyjitpl5/pypy/translator/jvm/conftest.py Log: merge changes to switch to using py.lib 1.0 final, also changes to the jit related conftests Modified: pypy/branch/pyjitpl5/dotviewer/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/dotviewer/conftest.py (original) +++ pypy/branch/pyjitpl5/dotviewer/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,8 +1,9 @@ import py -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("dotviever") - group.addoption('--pygame', action="store_true", - dest="pygame", default=False, - help="allow interactive tests using Pygame") +def pytest_addoption(parser): + group = parser.addgroup("dotviever") + group.addoption('--pygame', action="store_true", + dest="pygame", default=False, + help="allow interactive tests using Pygame") + +option = py.test.config.option Modified: pypy/branch/pyjitpl5/lib-python/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/lib-python/conftest.py (original) +++ pypy/branch/pyjitpl5/lib-python/conftest.py Wed Aug 12 10:25:57 2009 @@ -27,18 +27,16 @@ # Interfacing/Integrating with py.test's collection process # -class LibPythonPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("complicance testing options") - group.addoption('-T', '--timeout', action="store", type="string", - default="1000", dest="timeout", - help="fail a test module after the given timeout. " - "specify in seconds or 'NUMmp' aka Mega-Pystones") - group.addoption('--pypy', action="store", type="string", - dest="pypy", help="use given pypy executable to run lib-python tests. " - "This will run the tests directly (i.e. not through py.py)") +def pytest_addoption(parser): + group = parser.addgroup("complicance testing options") + group.addoption('-T', '--timeout', action="store", type="string", + default="1000", dest="timeout", + help="fail a test module after the given timeout. " + "specify in seconds or 'NUMmp' aka Mega-Pystones") + group.addoption('--pypy', action="store", type="string", + dest="pypy", help="use given pypy executable to run lib-python tests. " + "This will run the tests directly (i.e. not through py.py)") -ConftestPlugin = LibPythonPlugin option = py.test.config.option def gettimeout(): Modified: pypy/branch/pyjitpl5/pypy/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/conftest.py Wed Aug 12 10:25:57 2009 @@ -15,7 +15,13 @@ pytest_plugins = "resultlog", rsyncdirs = ['.', '../lib-python', '../demo'] rsyncignore = ['_cache'] - + +# XXX workaround for a py.test bug clashing with lib/py symlink +# do we really need the latter? +empty_conftest = type(sys)('conftest') +empty_conftest.__file__ = "?" +sys.modules['pypy.lib.py.conftest'] = empty_conftest + # PyPy's command line extra options (these are added # to py.test's standard options) # @@ -29,25 +35,22 @@ option = py.test.config.option -class PyPyTestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy options") - group.addoption('--view', action="store_true", dest="view", default=False, - help="view translation tests' flow graphs with Pygame") - group.addoption('-A', '--runappdirect', action="store_true", - default=False, dest="runappdirect", - help="run applevel tests directly on python interpreter (not through PyPy)") - group.addoption('--direct', action="store_true", - default=False, dest="rundirect", - help="run pexpect tests directly") - group.addoption('-P', '--platform', action="callback", type="string", - default="host", callback=_set_platform, - help="set up tests to use specified platform as compile/run target") - - def pytest_funcarg__space(self, pyfuncitem): - return gettestobjspace() - -ConftestPlugin = PyPyTestPlugin +def pytest_addoption(parser): + group = parser.addgroup("pypy options") + group.addoption('--view', action="store_true", dest="view", default=False, + help="view translation tests' flow graphs with Pygame") + group.addoption('-A', '--runappdirect', action="store_true", + default=False, dest="runappdirect", + help="run applevel tests directly on python interpreter (not through PyPy)") + group.addoption('--direct', action="store_true", + default=False, dest="rundirect", + help="run pexpect tests directly") + group.addoption('-P', '--platform', action="callback", type="string", + default="host", callback=_set_platform, + help="set up tests to use specified platform as compile/run target") + +def pytest_funcarg__space(request): + return gettestobjspace() _SPACECACHE={} def gettestobjspace(name=None, **kwds): @@ -319,10 +322,10 @@ raise AppError, AppError(appexcinfo), tb raise - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if excinfo.errisinstance(AppError): excinfo = excinfo.value.excinfo - return super(PyPyTestFunction, self).repr_failure(excinfo, outerr) + return super(PyPyTestFunction, self).repr_failure(excinfo) _pygame_imported = False Modified: pypy/branch/pyjitpl5/pypy/doc/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/doc/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/doc/conftest.py Wed Aug 12 10:25:57 2009 @@ -5,28 +5,25 @@ pytest_plugins = "pytest_restdoc" -class PyPyDocPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-doc options") - group.addoption('--pypy-doctests', action="store_true", - dest="pypy_doctests", default=False, - help="enable doctests in .txt files") - group.addoption('--generate-redirections', - action="store_true", dest="generateredirections", - default=True, help="Generate redirecting HTML files") +def pytest_addoption(parser): + group = parser.addgroup("pypy-doc options") + group.addoption('--pypy-doctests', action="store_true", + dest="pypy_doctests", default=False, + help="enable doctests in .txt files") + group.addoption('--generate-redirections', + action="store_true", dest="generateredirections", + default=True, help="Generate redirecting HTML files") - def pytest_configure(self, config): - self.config = config - register_config_role(docdir) - - def pytest_doctest_prepare_content(self, content): - if not self.config.getvalue("pypy_doctests"): - py.test.skip("specify --pypy-doctests to run doctests") - l = [] - for line in content.split("\n"): - if line.find('>>>>') != -1: - line = "" - l.append(line) - return "\n".join(l) +def pytest_configure(config): + register_config_role(docdir) + +def pytest_doctest_prepare_content(content): + if not py.test.config.getvalue("pypy_doctests"): + py.test.skip("specify --pypy-doctests to run doctests") + l = [] + for line in content.split("\n"): + if line.find('>>>>') != -1: + line = "" + l.append(line) + return "\n".join(l) -ConftestPlugin = PyPyDocPlugin Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py Wed Aug 12 10:25:57 2009 @@ -2,33 +2,31 @@ option = py.test.config.option -class RandomRunnerPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup('random test options') - group.addoption('--random-seed', action="store", type="int", - default=random.randrange(0, 10000), - dest="randomseed", - help="choose a fixed random seed") - group.addoption('--backend', action="store", - default='llgraph', - choices=['llgraph', 'minimal', 'x86'], - dest="backend", - help="select the backend to run the functions with") - group.addoption('--block-length', action="store", type="int", - default=30, - dest="block_length", - help="insert up to this many operations in each test") - group.addoption('--n-vars', action="store", type="int", - default=10, - dest="n_vars", - help="supply this many randomly-valued arguments to " - "the function") - group.addoption('--repeat', action="store", type="int", - default=15, - dest="repeat", - help="run the test this many times"), - group.addoption('--output', '-O', action="store", type="str", - default="", dest="output", - help="dump output to a file") +def pytest_addoption(parser): + group = parser.addgroup('random test options') + group.addoption('--random-seed', action="store", type="int", + default=random.randrange(0, 10000), + dest="randomseed", + help="choose a fixed random seed") + group.addoption('--backend', action="store", + default='llgraph', + choices=['llgraph', 'minimal', 'x86'], + dest="backend", + help="select the backend to run the functions with") + group.addoption('--block-length', action="store", type="int", + default=30, + dest="block_length", + help="insert up to this many operations in each test") + group.addoption('--n-vars', action="store", type="int", + default=10, + dest="n_vars", + help="supply this many randomly-valued arguments to " + "the function") + group.addoption('--repeat', action="store", type="int", + default=15, + dest="repeat", + help="run the test this many times"), + group.addoption('--output', '-O', action="store", type="str", + default="", dest="output", + help="dump output to a file") -ConftestPlugin = RandomRunnerPlugin Modified: pypy/branch/pyjitpl5/pypy/jit/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,17 +1,13 @@ import py - option = py.test.config.option -class JitTestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("JIT options") - group.addoption('--slow', action="store_true", - default=False, dest="run_slow_tests", - help="run all the compiled tests (instead of just a few)") - group.addoption('--viewloops', action="store_true", - default=False, dest="viewloops", - help="show only the compiled loops") - +def pytest_addoption(parser): + group = parser.addgroup("JIT options") + group.addoption('--slow', action="store_true", + default=False, dest="run_slow_tests", + help="run all the compiled tests (instead of just a few)") + group.addoption('--viewloops', action="store_true", + default=False, dest="viewloops", + help="show only the compiled loops") -ConftestPlugin = JitTestPlugin Modified: pypy/branch/pyjitpl5/pypy/jit/tl/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,5 +1,5 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypyjit.py options") - group.addoption('--ootype', action="store_true", dest="ootype", default=False, - help="use ootype") +def pytest_addoption(parser): + group = parser.addgroup("pypyjit.py options") + group.addoption('--ootype', action="store_true", dest="ootype", + default=False, + help="use ootype") Modified: pypy/branch/pyjitpl5/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/lang/js/test/ecma/conftest.py Wed Aug 12 10:25:57 2009 @@ -11,20 +11,17 @@ rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] -class EcmatestPlugin: - def pytest_addoption(self, parser): - parser.addoption('--ecma', - action="store_true", dest="ecma", default=False, - help="run js interpreter ecma tests" - ) - - def pytest_collect_file(self, path, parent): - if path.ext == ".js" and path.basename not in exclusionlist: - if not parent.config.option.ecma: - py.test.skip("ECMA tests disabled, run with --ecma") - return JSTestFile(path, parent=parent) - -ConftestPlugin = EcmatestPlugin +def pytest_addoption(parser): + parser.addoption('--ecma', + action="store_true", dest="ecma", default=False, + help="run js interpreter ecma tests" + ) + +def pytest_collect_file(path, parent): + if path.ext == ".js" and path.basename not in exclusionlist: + if not parent.config.option.ecma: + py.test.skip("ECMA tests disabled, run with --ecma") + return JSTestFile(path, parent=parent) class JSTestFile(py.test.collect.File): def init_interp(cls): Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/test/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,7 +1,5 @@ -class PyPyJitTestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypyjit options") - group.addoption("--pypy-c", action="store", default=None, dest="pypy_c", - help="the location of the JIT enabled pypy-c") +def pytest_addoption(parser): + group = parser.addgroup("pypyjit options") + group.addoption("--pypy-c", action="store", default=None, dest="pypy_c", + help="the location of the JIT enabled pypy-c") -ConftestPlugin = PyPyJitTestPlugin Modified: pypy/branch/pyjitpl5/pypy/objspace/std/fake.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/fake.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/fake.py Wed Aug 12 10:25:57 2009 @@ -103,7 +103,7 @@ unwrap_spec=[baseobjspace.ObjSpace, baseobjspace.W_Root, argument.Arguments]) - if cpy_type.__base__ is not object: + if cpy_type.__base__ is not object and not issubclass(cpy_type, Exception): assert cpy_type.__base__ is basestring, cpy_type from pypy.objspace.std.basestringtype import basestring_typedef base = basestring_typedef Modified: pypy/branch/pyjitpl5/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/tool/test/test_conftest1.py (original) +++ pypy/branch/pyjitpl5/pypy/tool/test/test_conftest1.py Wed Aug 12 10:25:57 2009 @@ -11,7 +11,7 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('test_something', 'test_method') + assert repevent.item.name in ('test_something', 'test_method') def test_select_applevel(self, testdir): sorter = testdir.inline_run("-k", "applevel", innertest) @@ -19,14 +19,14 @@ assert len(passed) == 2 assert not skipped and not failed for repevent in passed: - assert repevent.colitem.name in ('app_test_something', 'test_method_app') + assert repevent.item.name in ('app_test_something', 'test_method_app') def test_appdirect(self, testdir): sorter = testdir.inline_run(innertest, '-k', 'applevel', '--runappdirect') passed, skipped, failed = sorter.listoutcomes() assert len(passed) == 2 print passed - names = [x.colitem.name for x in passed] + names = [x.item.name for x in passed] assert 'app_test_something' in names assert 'test_method_app' in names Modified: pypy/branch/pyjitpl5/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/branch/pyjitpl5/pypy/tool/test/test_pytestsupport.py Wed Aug 12 10:25:57 2009 @@ -90,7 +90,6 @@ else: py.test.fail("did not raise!") assert "PicklingError" in appex.exconly() - assert "SomeMessage" in appex.exconly() class AppTestWithWrappedInterplevelAttributes: def setup_class(cls): @@ -134,9 +133,9 @@ def test_one(self): pass """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.passed - sfn = ev.colitem.safe_filename() + sfn = ev.item.safe_filename() print sfn assert sfn == 'test_safe_filename_test_safe_filename_ExpectTestOne_paren_test_one_1.py' @@ -151,11 +150,11 @@ def test_app_test_blow(testdir): conftestpath.copy(testdir.tmpdir) - sorter = testdir.inline_runsource(""" -class AppTestBlow: - def test_one(self): - exec 'blow' + sorter = testdir.inline_runsource("""class AppTestBlow: + def test_one(self): exec 'blow' """) - ev, = sorter.getnamed("itemtestreport") + ev, = sorter.getreports("pytest_runtest_logreport") assert ev.failed + assert 'NameError' in ev.longrepr.reprcrash.message + assert 'blow' in ev.longrepr.reprcrash.message Modified: pypy/branch/pyjitpl5/pypy/translator/cli/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/cli/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/cli/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,19 +1,18 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-cli options") - group.addoption('--source', action="store_true", dest="source", default=False, - help="only generate IL source, don't compile") - group.addoption('--wd', action="store_true", dest="wd", default=False, - help="store temporary files in the working directory") - group.addoption('--stdout', action="store_true", dest="stdout", default=False, - help="print the generated IL code to stdout, too") - group.addoption('--nostop', action="store_true", dest="nostop", default=False, - help="don't stop on warning. The generated IL code could not compile") - group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, - help="don't wrap exceptions but let them to flow out of the entry point") - group.addoption('--verify', action="store_true", dest="verify", default=False, - help="check that compiled executables are verifiable") - group.addoption('--norun', action='store_true', dest="norun", default=False, - help="don't run the compiled executable") - group.addoption('--trace', action='store_true', dest='trace', default=False, - help='Trace execution of generated code') +def pytest_addoption(parser): + group = parser.addgroup("pypy-cli options") + group.addoption('--source', action="store_true", dest="source", default=False, + help="only generate IL source, don't compile") + group.addoption('--wd', action="store_true", dest="wd", default=False, + help="store temporary files in the working directory") + group.addoption('--stdout', action="store_true", dest="stdout", default=False, + help="print the generated IL code to stdout, too") + group.addoption('--nostop', action="store_true", dest="nostop", default=False, + help="don't stop on warning. The generated IL code could not compile") + group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, + help="don't wrap exceptions but let them to flow out of the entry point") + group.addoption('--verify', action="store_true", dest="verify", default=False, + help="check that compiled executables are verifiable") + group.addoption('--norun', action='store_true', dest="norun", default=False, + help="don't run the compiled executable") + group.addoption('--trace', action='store_true', dest='trace', default=False, + help='Trace execution of generated code') Modified: pypy/branch/pyjitpl5/pypy/translator/jvm/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/jvm/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/jvm/conftest.py Wed Aug 12 10:25:57 2009 @@ -1,18 +1,22 @@ -class ConftestPlugin: - def pytest_addoption(self, parser): - group = parser.addgroup("pypy-jvm options") - group.addoption('--java', action='store', dest='java', default='java', - help='Define the java executable to use') - group.addoption('--javac', action='store', dest='javac', default='javac', - help='Define the javac executable to use') - group.addoption('--jasmin', action='store', dest='java', default='java', - help='Define the jasmin script to use') - group.addoption('--noassemble', action='store_true', dest="noasm", default=False, - help="don't assemble jasmin files") - group.addoption('--package', action='store', dest='package', default='pypy', - help='Package to output generated classes into') -## group.addoption('--trace', action='store_true', dest='trace', default=False, -## help='Trace execution of generated code') - group.addoption('--byte-arrays', action='store_true', dest='byte-arrays', - default=False, help='Use byte arrays rather than native strings') + +def pytest_addoption(parser): + group = parser.addgroup("pypy-jvm options") + group.addoption('--java', action='store', dest='java', default='java', + help='Define the java executable to use') + group.addoption('--javac', action='store', dest='javac', + default='javac', + help='Define the javac executable to use') + group.addoption('--jasmin', action='store', dest='java', default='java', + help='Define the jasmin script to use') + group.addoption('--noassemble', action='store_true', dest="noasm", + default=False, + help="don't assemble jasmin files") + group.addoption('--package', action='store', dest='package', + default='pypy', + help='Package to output generated classes into') + + group.addoption('--byte-arrays', action='store_true', + dest='byte-arrays', + default=False, + help='Use byte arrays rather than native strings') From pedronis at codespeak.net Wed Aug 12 10:28:09 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 12 Aug 2009 10:28:09 +0200 (CEST) Subject: [pypy-svn] r66789 - pypy/branch/use-py1.0.0 Message-ID: <20090812082809.988DE16800C@codespeak.net> Author: pedronis Date: Wed Aug 12 10:28:08 2009 New Revision: 66789 Removed: pypy/branch/use-py1.0.0/ Log: removed merged branch From cfbolz at codespeak.net Wed Aug 12 13:17:40 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 12 Aug 2009 13:17:40 +0200 (CEST) Subject: [pypy-svn] r66790 - pypy/extradoc/talk/techtalk_dlr2009 Message-ID: <20090812111740.E73C816800F@codespeak.net> Author: cfbolz Date: Wed Aug 12 13:17:39 2009 New Revision: 66790 Modified: pypy/extradoc/talk/techtalk_dlr2009/author.latex pypy/extradoc/talk/techtalk_dlr2009/talk.txt Log: talk as given Modified: pypy/extradoc/talk/techtalk_dlr2009/author.latex ============================================================================== --- pypy/extradoc/talk/techtalk_dlr2009/author.latex (original) +++ pypy/extradoc/talk/techtalk_dlr2009/author.latex Wed Aug 12 13:17:39 2009 @@ -1,6 +1,6 @@ \definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} -\title[PyPy: A Flexible Virtual Machine for Python and Other Dynamic Languages]{PyPy: A Flexible VM for Python} +\title[PyPy: A Flexible VM for Python]{PyPy: A Flexible Virtual Machine for Python and Other Dynamic Languages} \author[cfbolz] {Carl Friedrich Bolz} Modified: pypy/extradoc/talk/techtalk_dlr2009/talk.txt ============================================================================== --- pypy/extradoc/talk/techtalk_dlr2009/talk.txt (original) +++ pypy/extradoc/talk/techtalk_dlr2009/talk.txt Wed Aug 12 13:17:39 2009 @@ -7,11 +7,12 @@ What is PyPy =================================== -- An alternate Python virtual machine for C/Posix, - for .NET and for Java +- An alternate Python implementation + +- running both in C/Posix, on top of .NET and the JVM -- More generally, a way to implement interpreters - for various languages +- More generally, an environment to implement interpreters for various + (dynamic) languages Talk Outline =============== @@ -31,6 +32,8 @@ - Most JavaScript VMs (V8, TraceMonkey, Squirrelfish) - but also: Scheme48, Squeak +|pause| + - Building on top of a general-purpose OO VM - Jython, IronPython @@ -168,7 +171,7 @@ Auto-generating VMs =================== -- we need a custom \emph{translation toolchain} to compile the interpreter +- we need a custom **translation toolchain** to compile the interpreter to a full VM - many aspects of the final VM are orthogonal from the interpreter source: they are inserted during translation @@ -223,7 +226,7 @@ ====================================== - writing the translation toolchain in the first place takes lots of effort - (but it can be reused) + (but it can be reused) - writing a good GC is still necessary. The current one's are ok, but not great. - generating a dynamic compiler is hard (working on this since quite a while) @@ -232,12 +235,13 @@ ============================= - 1.1 release -- more than two years of work +- more than two years of work over 1.0 - compatible to Python 2.5.2 (even most the obscure bits) - supporting ctypes, SQLite - well tested on Win/Linux 32 bit (but OS X and 64 bit should work as well) - running major packages unmodified - easy_install/distutils working +- runs on Nokia's Maemo devices Software PyPy Can Run ====================== @@ -245,7 +249,7 @@ - Django - Pylons - Twisted & Nevow -- pure python should just work +- pure Python should just work - BitTorrent - PyPy translation toolchain - py lib @@ -255,7 +259,7 @@ Obscure details that people rely on ======================================= -- non-string keys in __dict__ of types +- non-string keys in ``__dict__`` of types - exact naming of a list comprehension variable - relying on untested and undocumented private stuff - exact message matching in exception catching @@ -275,6 +279,15 @@ - main blocker for running apps will be missing external modules +Extra Features +=============== + +features that CPython doesn't have: + + - stackless support, including pickling of threadlets + - lazy evaluation + - transparent proxies + - ... Speed ======== @@ -301,6 +314,7 @@ Main ideas (1) =============== +- tracing JIT compiler (like Mozilla's TraceMonkey) - 80/20 rule - 80% of the time is spent in 20% of the code - Optimize only that 20% @@ -321,7 +335,7 @@ - 20-30x faster on micro-benchmarks - nice proof of concept - completely separated from the interpreter -- a bit of time (and funding) needed to speed up large python programs +- a bit of time (and funding) needed to speed up large Python programs - hope to get a release with "a JIT" out beginning next year @@ -332,11 +346,16 @@ - Python implementation fairly complete, covers CPython 2.5 features - JIT generator is getting somewhere, slowly +.. raw:: latex -Contact / Q&A + \begin{figure}[h] + \scalebox{0.8}{\includegraphics[width=80px]{../img/py-web.png}} + \end{figure} + +Contact ========================== -Carl Friedrich Bolz at Heinrich-Heine-Universit?t D?sseldorf +Carl Friedrich Bolz at the Heinrich-Heine-Universit?t D?sseldorf: http://codespeak.net/~cfbolz PyPy: http://codespeak.net/pypy @@ -347,3 +366,18 @@ \begin{figure}[h] \scalebox{0.8}{\includegraphics[width=80px]{../img/py-web.png}} \end{figure} + + +Questions? +============ + +- PyPy is a general environment to implement dynamic languages +- Python implementation fairly complete, covers CPython 2.5 features +- JIT generator is getting somewhere, slowly + + +.. raw:: latex + + \begin{figure}[h] + \scalebox{0.8}{\includegraphics[width=80px]{../img/py-web.png}} + \end{figure} From magcius at codespeak.net Wed Aug 12 18:49:50 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Wed, 12 Aug 2009 18:49:50 +0200 (CEST) Subject: [pypy-svn] r66795 - pypy/branch/avm Message-ID: <20090812164950.91E0F168019@codespeak.net> Author: magcius Date: Wed Aug 12 18:49:49 2009 New Revision: 66795 Removed: pypy/branch/avm/ Log: Remove old branch. From magcius at codespeak.net Wed Aug 12 18:50:48 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Wed, 12 Aug 2009 18:50:48 +0200 (CEST) Subject: [pypy-svn] r66796 - pypy/branch/avm Message-ID: <20090812165048.EA70E168019@codespeak.net> Author: magcius Date: Wed Aug 12 18:50:48 2009 New Revision: 66796 Added: pypy/branch/avm/ - copied from r66795, pypy/trunk/ Log: Create new branch. From magcius at codespeak.net Thu Aug 13 00:29:08 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Thu, 13 Aug 2009 00:29:08 +0200 (CEST) Subject: [pypy-svn] r66798 - in pypy/branch/avm: ctypes_configure demo dotviewer lib-python/2.5.2 lib-python/2.5.2/ctypes/macholib lib-python/2.5.2/idlelib lib-python/2.5.2/lib-tk lib-python/2.5.2/plat-aix3 lib-python/2.5.2/plat-aix4 lib-python/2.5.2/plat-beos5 lib-python/2.5.2/plat-darwin lib-python/2.5.2/plat-freebsd2 lib-python/2.5.2/plat-freebsd3 lib-python/2.5.2/plat-generic lib-python/2.5.2/plat-irix5 lib-python/2.5.2/plat-irix6 lib-python/2.5.2/plat-linux2 lib-python/2.5.2/plat-mac lib-python/2.5.2/plat-mac/Carbon lib-python/2.5.2/plat-netbsd1 lib-python/2.5.2/plat-next3 lib-python/2.5.2/plat-sunos5 lib-python/2.5.2/plat-unixware7 lib-python/2.5.2/test lib-python/modified-2.5.2 lib-python/modified-2.5.2/ctypes/macholib lib-python/modified-2.5.2/test pypy pypy/bin pypy/doc pypy/lang/gameboy/debug pypy/lang/gameboy/profiling/evaluation pypy/lang/js pypy/lang/js/test/ecma pypy/lang/js/test/ecma/ExecutionContexts pypy/lang/malbolge pypy/lang/malbolge/examples pypy/lang/prolog/interpreter pypy/lang/scheme pypy/lang/smalltalk pypy/lib/app_test pypy/lib/test2 pypy/module/unicodedata pypy/rlib/rcairo pypy/rlib/rcairo/test pypy/rpython/tool pypy/tool pypy/tool/pytest pypy/translator/avm1 pypy/translator/avm1/test pypy/translator/c/gcc pypy/translator/goal pypy/translator/microbench pypy/translator/microbench/pybench pypy/translator/sandbox Message-ID: <20090812222908.A158916801D@codespeak.net> Author: magcius Date: Thu Aug 13 00:29:02 2009 New Revision: 66798 Added: pypy/branch/avm/pypy/translator/avm1/ pypy/branch/avm/pypy/translator/avm1/authoring.py pypy/branch/avm/pypy/translator/avm1/avm.py pypy/branch/avm/pypy/translator/avm1/avm1.py pypy/branch/avm/pypy/translator/avm1/avm1gen.py pypy/branch/avm/pypy/translator/avm1/constant.py pypy/branch/avm/pypy/translator/avm1/database.py pypy/branch/avm/pypy/translator/avm1/genavm.py pypy/branch/avm/pypy/translator/avm1/records.py pypy/branch/avm/pypy/translator/avm1/swf.py pypy/branch/avm/pypy/translator/avm1/tags.py pypy/branch/avm/pypy/translator/avm1/test/ pypy/branch/avm/pypy/translator/avm1/test/autopath.py pypy/branch/avm/pypy/translator/avm1/test/bootstrap.py pypy/branch/avm/pypy/translator/avm1/test/browsertest.py pypy/branch/avm/pypy/translator/avm1/test/harness.py pypy/branch/avm/pypy/translator/avm1/test/runtest.py pypy/branch/avm/pypy/translator/avm1/test/test_harness.py pypy/branch/avm/pypy/translator/avm1/test/test_int.py pypy/branch/avm/pypy/translator/avm1/test/test_weakref.py Modified: pypy/branch/avm/ctypes_configure/configure.py (contents, props changed) pypy/branch/avm/demo/bpnn.py (contents, props changed) pypy/branch/avm/dotviewer/dotviewer.py (contents, props changed) pypy/branch/avm/dotviewer/graphserver.py (contents, props changed) pypy/branch/avm/dotviewer/sshgraphserver.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/UserString.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/base64.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/cProfile.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/cgi.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/ctypes/macholib/fetch_macholib (contents, props changed) pypy/branch/avm/lib-python/2.5.2/idlelib/idle.bat (contents, props changed) pypy/branch/avm/lib-python/2.5.2/keyword.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/lib-tk/Tix.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/mailbox.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/mimify.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/pdb.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-aix3/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-aix4/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-beos5/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-darwin/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-freebsd2/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-freebsd3/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-generic/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/AL.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/CD.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/CL.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/CL_old.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/DEVICE.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/ERRNO.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/FILE.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/FL.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/GET.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/GL.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/GLWS.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/IN.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/IOCTL.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/SV.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/WAIT.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/cddb.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/cdplayer.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/flp.doc (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/flp.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/jpeg.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/panel.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/panelparser.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/readcd.doc (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/readcd.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix5/torgb.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-irix6/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-linux2/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CG.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/appletrunner.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-mac/bundlebuilder.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-netbsd1/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-next3/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-sunos5/IN.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-sunos5/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/plat-unixware7/regen (contents, props changed) pypy/branch/avm/lib-python/2.5.2/platform.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/profile.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/pydoc.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/quopri.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/runpy.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/smtpd.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/smtplib.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/symbol.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/tabnanny.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/pystone.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/re_tests.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/regrtest.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_aepack.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_al.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_array.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_binascii.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_binhex.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_bsddb.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_cd.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_cl.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_cmath.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_crypt.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_dbm.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_dl.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_errno.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_fcntl.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_gdbm.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_gl.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_grp.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_htmlparser.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_imageop.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_imgfile.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_strftime.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_userstring.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/test/test_wsgiref.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/token.py (contents, props changed) pypy/branch/avm/lib-python/2.5.2/uu.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/ctypes/macholib/fetch_macholib (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/mailbox.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/platform.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/pydoc.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/test/regrtest.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/test/test_array.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/test/test_dbm.py (contents, props changed) pypy/branch/avm/lib-python/modified-2.5.2/uu.py (contents, props changed) pypy/branch/avm/pypy/bin/carbonpython.py (contents, props changed) pypy/branch/avm/pypy/bin/checkmodule.py (contents, props changed) pypy/branch/avm/pypy/bin/dotviewer.py (contents, props changed) pypy/branch/avm/pypy/bin/py.py (contents, props changed) pypy/branch/avm/pypy/bin/pyrolog.py (contents, props changed) pypy/branch/avm/pypy/bin/reportstaticdata.py (contents, props changed) pypy/branch/avm/pypy/bin/translatorshell.py (contents, props changed) pypy/branch/avm/pypy/doc/parse_logs.py (contents, props changed) pypy/branch/avm/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (contents, props changed) pypy/branch/avm/pypy/lang/gameboy/profiling/evaluation/run.sh (contents, props changed) pypy/branch/avm/pypy/lang/js/commit (contents, props changed) pypy/branch/avm/pypy/lang/js/driver.py (contents, props changed) pypy/branch/avm/pypy/lang/js/js_interactive.py (contents, props changed) pypy/branch/avm/pypy/lang/js/test/ecma/ExecutionContexts/10.1.3-2.js (contents, props changed) pypy/branch/avm/pypy/lang/js/test/ecma/README (contents, props changed) pypy/branch/avm/pypy/lang/malbolge/examples/99bottles.mbs (contents, props changed) pypy/branch/avm/pypy/lang/malbolge/examples/copy.mbs (contents, props changed) pypy/branch/avm/pypy/lang/malbolge/examples/hello-world.mbs (contents, props changed) pypy/branch/avm/pypy/lang/malbolge/malbolge.py (contents, props changed) pypy/branch/avm/pypy/lang/prolog/interpreter/interactive.py (contents, props changed) pypy/branch/avm/pypy/lang/scheme/interactive.py (contents, props changed) pypy/branch/avm/pypy/lang/smalltalk/find_untested_bytecodes.sh (contents, props changed) pypy/branch/avm/pypy/lang/smalltalk/find_untested_prims.sh (contents, props changed) pypy/branch/avm/pypy/lib/app_test/test_binascii.py (contents, props changed) pypy/branch/avm/pypy/lib/test2/pickledtasklet.py (contents, props changed) pypy/branch/avm/pypy/module/unicodedata/generate_unicodedb.py (contents, props changed) pypy/branch/avm/pypy/rlib/rcairo/ll_cairo.py (contents, props changed) pypy/branch/avm/pypy/rlib/rcairo/test/test_ll_cairo.py (contents, props changed) pypy/branch/avm/pypy/rpython/tool/genrffi.py (contents, props changed) pypy/branch/avm/pypy/rpython/tool/rffi_platform.py (contents, props changed) pypy/branch/avm/pypy/test_all.py (contents, props changed) pypy/branch/avm/pypy/tool/fixeol (contents, props changed) pypy/branch/avm/pypy/tool/pytest/genreportdata.py (contents, props changed) pypy/branch/avm/pypy/translator/c/gcc/trackgcroot.py (contents, props changed) pypy/branch/avm/pypy/translator/goal/bench-cronjob.py (contents, props changed) pypy/branch/avm/pypy/translator/goal/launch-bench-cronjob.sh (contents, props changed) pypy/branch/avm/pypy/translator/goal/translate.py (contents, props changed) pypy/branch/avm/pypy/translator/microbench/microbench.py (contents, props changed) pypy/branch/avm/pypy/translator/microbench/pybench/platform.py (contents, props changed) pypy/branch/avm/pypy/translator/microbench/pybench/pybench.py (contents, props changed) pypy/branch/avm/pypy/translator/sandbox/interact.py (contents, props changed) pypy/branch/avm/pypy/translator/sandbox/pypy_interact.py (contents, props changed) Log: Test Modified: pypy/branch/avm/ctypes_configure/configure.py ============================================================================== Modified: pypy/branch/avm/demo/bpnn.py ============================================================================== Modified: pypy/branch/avm/dotviewer/dotviewer.py ============================================================================== Modified: pypy/branch/avm/dotviewer/graphserver.py ============================================================================== Modified: pypy/branch/avm/dotviewer/sshgraphserver.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/UserString.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/base64.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/cProfile.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/cgi.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/ctypes/macholib/fetch_macholib ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/idlelib/idle.bat ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/keyword.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/lib-tk/Tix.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/mailbox.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/mimify.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/pdb.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-aix3/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-aix4/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-beos5/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-darwin/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-freebsd2/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-freebsd3/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-generic/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/AL.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/CD.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/CL.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/CL_old.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/DEVICE.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/ERRNO.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/FILE.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/FL.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/GET.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/GL.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/GLWS.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/IN.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/IOCTL.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/SV.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/WAIT.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/cddb.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/cdplayer.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/flp.doc ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/flp.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/jpeg.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/panel.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/panelparser.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/readcd.doc ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/readcd.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix5/torgb.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-irix6/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-linux2/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CG.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/appletrunner.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-mac/bundlebuilder.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-netbsd1/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-next3/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-sunos5/IN.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-sunos5/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/plat-unixware7/regen ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/platform.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/profile.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/pydoc.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/quopri.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/runpy.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/smtpd.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/smtplib.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/symbol.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/tabnanny.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/pystone.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/re_tests.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/regrtest.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_aepack.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_al.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_array.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_binascii.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_binhex.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_bsddb.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_cd.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_cl.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_cmath.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_crypt.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_dbm.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_dl.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_errno.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_fcntl.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_gdbm.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_gl.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_grp.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_htmlparser.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_imageop.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_imgfile.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_strftime.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_userstring.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/test/test_wsgiref.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/token.py ============================================================================== Modified: pypy/branch/avm/lib-python/2.5.2/uu.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/ctypes/macholib/fetch_macholib ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/mailbox.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/platform.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/pydoc.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/test/regrtest.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/test/test_array.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/test/test_dbm.py ============================================================================== Modified: pypy/branch/avm/lib-python/modified-2.5.2/uu.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/carbonpython.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/checkmodule.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/dotviewer.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/py.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/pyrolog.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/reportstaticdata.py ============================================================================== Modified: pypy/branch/avm/pypy/bin/translatorshell.py ============================================================================== Modified: pypy/branch/avm/pypy/doc/parse_logs.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/gameboy/profiling/evaluation/run.sh ============================================================================== Modified: pypy/branch/avm/pypy/lang/js/commit ============================================================================== Modified: pypy/branch/avm/pypy/lang/js/driver.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/js/js_interactive.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/js/test/ecma/ExecutionContexts/10.1.3-2.js ============================================================================== Modified: pypy/branch/avm/pypy/lang/js/test/ecma/README ============================================================================== Modified: pypy/branch/avm/pypy/lang/malbolge/examples/99bottles.mbs ============================================================================== Modified: pypy/branch/avm/pypy/lang/malbolge/examples/copy.mbs ============================================================================== Modified: pypy/branch/avm/pypy/lang/malbolge/examples/hello-world.mbs ============================================================================== Modified: pypy/branch/avm/pypy/lang/malbolge/malbolge.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/prolog/interpreter/interactive.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/scheme/interactive.py ============================================================================== Modified: pypy/branch/avm/pypy/lang/smalltalk/find_untested_bytecodes.sh ============================================================================== Modified: pypy/branch/avm/pypy/lang/smalltalk/find_untested_prims.sh ============================================================================== Modified: pypy/branch/avm/pypy/lib/app_test/test_binascii.py ============================================================================== Modified: pypy/branch/avm/pypy/lib/test2/pickledtasklet.py ============================================================================== Modified: pypy/branch/avm/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== Modified: pypy/branch/avm/pypy/rlib/rcairo/ll_cairo.py ============================================================================== Modified: pypy/branch/avm/pypy/rlib/rcairo/test/test_ll_cairo.py ============================================================================== Modified: pypy/branch/avm/pypy/rpython/tool/genrffi.py ============================================================================== Modified: pypy/branch/avm/pypy/rpython/tool/rffi_platform.py ============================================================================== Modified: pypy/branch/avm/pypy/test_all.py ============================================================================== Modified: pypy/branch/avm/pypy/tool/fixeol ============================================================================== Modified: pypy/branch/avm/pypy/tool/pytest/genreportdata.py ============================================================================== Added: pypy/branch/avm/pypy/translator/avm1/authoring.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/authoring.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,46 @@ + +from pypy.translator.avm.tags import ShapeWithStyle +from pypy.translator.avm.records import StyleChangeRecord, CurvedEdgeRecord, StraightEdgeRecord + +class Circle(object): + + def __init__(self, x, y, radius, linestyle, fillstyle0, fillstyle1): + self.x = x + self.y = y + self.radius = radius + self.linestyle = linestyle + self.fillstyle0 = fillstyle0 + self.fillstyle1 = fillstyle1 + + def to_shape(self): + shape = ShapeWithStyle() + + if self.linestyle: shape.add_line_style(self.linestyle) + if self.fillstyle0: shape.add_fill_style(self.fillstyle0) + if self.fillstyle1: shape.add_fill_style(self.fillstyle1) + + # Precalculated: + # math.tan(math.radians(22.5)) = 0.41421356237309503 + # math.sin(math.radians(45)) = 0.70710678118654746 + + c = self.radius * 0.41421356237309503 + a = self.radius * 0.70710678118654746 - c + + shape.add_shape_record(StyleChangeRecord(self.x + self.radius, self.y, self.linestyle, self.fillstyle0, self.fillstyle1)) + # 0 to PI/2 + shape.add_shape_record(CurvedEdgeRecord(0, -c, -a, -a)) + shape.add_shape_record(CurvedEdgeRecord(-a, -a, -c, 0)) + + # PI/2 to PI + shape.add_shape_record(CurvedEdgeRecord(-c, 0, -a, a)) + shape.add_shape_record(CurvedEdgeRecord(-a, a, 0, c)) + + # PI to 3PI/2 + shape.add_shape_record(CurvedEdgeRecord(0, c, a, a)) + shape.add_shape_record(CurvedEdgeRecord(a, a, c, 0)) + + # 3PI/2 to 2PI + shape.add_shape_record(CurvedEdgeRecord(c, 0, a, -a)) + shape.add_shape_record(CurvedEdgeRecord(a, -a, 0, -c)) + + return shape Added: pypy/branch/avm/pypy/translator/avm1/avm.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/avm.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,66 @@ + +import py, os + +from pypy.rpython.rmodel import inputconst +from pypy.rpython.typesystem import getfunctionptr +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.ootypesystem import ootype +from pypy.tool.udir import udir +from pypy.translator.avm.log import log +from pypy.translator.avm.asmgen import AsmGen +from pypy.translator.avm.avm1types import AVM1TypeSystem +#from pypy.translator.js.opcodes import opcodes +from pypy.translator.avm.function import Function +from pypy.translator.avm.database import LowLevelDatabase +from pypy.translator.avm import bootstrap + +from pypy.translator.oosupport.genoo import GenOO +from heapq import heappush, heappop + + +class AVM1(GenOO): + TypeSystem = AVM1TypeSystem + Function = Function + Database = LowLevelDatabase + + def __init__(self, translator, function=[], stackless=False, compress=False, \ + logging=False, use_debug=False): + if not isinstance(function, list): + functions = [functions] + GenOO.__init__(self, udir, translator, None) + + pending_graphs = [ translator.annotator.bookeeeper.getdesc(f).cachedgraph(None) for f in functions ] + for graph in pending_graphs: + self.db.pending_function(graph) + + self.db.translator = translator + self.use_debug = use_debug + self.assembly_name = self.translator.graphs[0].name + self.tmpfile = udir.join(self.assembly_name + '.swf') + + def stack_optimization(self): + pass + + def gen_pendings(self): + while self.db._pending_nodes: + node = self.db.pending_nodes.pop() + to_render = [] + nparent = node + while nparent-order != 0: + nparent = nparent.parent + to_render.append(nparent) + to_render.reverse() + for i in to_render: + i.render(self.ilasm) + + def create_assembler(self): + return bootstrap.create_assembler(self.assembly_name) + + def generate_swf(self): + self.ilasm = self.create_assembler() + self.fix_names() + self.gen_entrypoint() + while self.db._pending_nodes: + self.gen_pendings() + self.db.gen_constants(self.ilasm, self.db._pending_nodes) + # self.ilasm.close() Added: pypy/branch/avm/pypy/translator/avm1/avm1.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/avm1.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,649 @@ + +# AVM1 = ActionScript Virtual Machine 1 +# Used for ActionScript 1 and 2 + +from pypy.translator.avm.util import BitStream +from collections import namedtuple +import struct + +DataType = namedtuple("DataType", "id name size") + +STRING = DataType(0, "string", "Z") +FLOAT = DataType(1, "float", "f") +NULL = DataType(2, "null", "!") +UNDEFINED = DataType(3, "undefined", "!") +REGISTER = DataType(4, "register", "B") +BOOLEAN = DataType(5, "boolean", "B") +DOUBLE = DataType(6, "double", "d") +INTEGER = DataType(7, "integer", "l") +CONSTANT8 = DataType(8, "constant 8", "B") +CONSTANT16 = DataType(9, "constant 16", "H") + +class Index(object): + def __init__(self, index): + self.index = index + +class Value(object): + def __init__(self, value): + self.value = value + +class Null(object): + type = NULL + +class Undefined(object): + type = UNDEFINED + +class ConstantIndexDescriptor(object): + def __get__(self, obj, objtype): + return CONSTANT8 if obj.index < 256 else CONSTANT16 + +class Constant(Index): + type = ConstantIndexDescriptor() + +class Register(object): + type = REGISTER + +class RegisterByIndex(Register, Index): + pass + +class RegisterByValue(Register, Value): + pass + +class Action(object): + + ACTION_NAME = "NotImplemented" + ACTION_ID = 0x00 + + offset = 0 + label_name = "" + + def serialize(self): + inner_data = self.gen_data() + outer_data = self.gen_outer_data() + header = struct.pack(" 0 and action.ACTION_NAME == "ActionPush" and self.actions[-1].ACTION_NAME == "ActionPush": + old_action = self.actions[-1] + old_len = len(old_action) + self.actions[-1].values.extend(action.values) + self.current_offset += len(old_action) - old_len + return old_action + + # Two nots negate. Take them out. + if action.ACTION_NAME == "ActionNot" and action.ACTION_NAME == "ActionNot": + self.actions.pop() + self.current_offset -= 1 # len(ShortAction) is 1 + return None + + if not isinstance(action, Block): # Don't add block length until we've finalized. + self.current_offset += len(action) + + self.actions.append(action) + return action + + def serialize(self): + if len(self.code) > 0: + return self.code + bytes = [] + for action in self.actions: + action.get_block_props_late(self) + bytes += action.serialize() + if self.insert_end: + bytes += "\0" + self.code = "".join(bytes) + return self.code + + def new_label(self): + self.label_count += 1 + name = Block.AUTO_LABEL_TEMPLATE % self.label_count + self.labels[name] = -1 + return name + + def set_label_here(self, name): + self.labels[name] = self.current_offset + + def new_label_here(self): + name = self.new_label() + self.labels[name] = self.current_offset + return name + +class ActionCall(Action): + ACTION_NAME = "ActionCall" + ACTION_ID = 0x9e + +class ActionDefineFunction(Action, Block): + ACTION_NAME = "ActionDefineFunction" + ACTION_ID = 0x9b + FUNCTION_TYPE = 1 + + def __init__(self, toplevel, name, parameters): + Block.__init__(self, toplevel, False) + self.function_name = name + self.params = parameters + + def gen_data(self): + self.block_data = Block.serialize(self) + bytes = [self.function_name, "\0", struct.pack("H", len(self.params))] + bytes += [p + "\0" for p in self.params] + bytes += struct.pack("H", len(self.block_data)) + return "".join(bytes) + + def gen_outer_data(self): + return self.block_data + +class ActionDefineFunction2(Action, Block): + ACTION_NAME = "ActionDefineFunction2" + ACTION_ID = 0x8e + MAX_REGISTERS = 256 + FUNCTION_TYPE = 2 + + def __init__(self, toplevel, name, parameters): + Block.__init__(self, toplevel, False) + self.function_name = name + self.params = parameters + + # Flags + self.preload_parent = False + self.preload_root = False + self.suppress_super = True + self.preload_super = False + self.suppress_args = False + self.preload_args = True + self.suppress_this = True + self.preload_this = False + self.preload_global = False + self.eval_flags() + + def eval_flags(self): # WARNING! eval_flags will clear registers! + # bits = BitStream() + # bits.write_bit_value(self.flags, 16) + # bits.rewind() + # preload_parent = bits.read_bit() + # preload_root = bits.read_bit() + # suppress_super = bits.read_bit() + # preload_super = bits.read_bit() + # suppress_args = bits.read_bit() + # preload_args = bits.read_bit() + # suppress_this = bits.read_bit() + # preload_this = bits.read_bit() + # bits.cursor += 7 # skip over 7 Reserved bits + # preload_global = bits.read_bit() + + self.registers = [None] + + # According to the docs, this is the order of register allocation. + if self.preload_this: self.registers.append("this") + if self.preload_args: self.registers.append("arguments") + if self.preload_super: self.registers.append("super") + if self.preload_root: self.registers.append("_root") + if self.preload_parent: self.registers.append("_parent") + if self.preload_global: self.registers.append("_global") + + for name in self.params: + self.registers.append(name) + + def gen_data(self): + + bits = BitStream() + bits.write_bit(self.preload_parent) + bits.write_bit(self.preload_root) + bits.write_bit(self.suppress_super) + bits.write_bit(self.preload_super) + bits.write_bit(self.suppress_args) + bits.write_bit(self.preload_args) + bits.write_bit(self.suppress_this) + bits.write_bit(self.preload_this) + bits.zero_fill(7) # skip over 7 Reserved bits + bits.write_bit(self.preload_global) + + self.block_data = Block.serialize(self) + bytes = [self.function_name, "\0", + struct.pack("HB", len(self.params), len(self.registers)-1), + bits.serialize()] + + for name in self.params: + bytes += [chr(self.registers.index(name)), name, "\0"] + + bytes += [struct.pack("H", len(self.block_data))] + return "".join(bytes) + + def gen_outer_data(self): + return self.block_data + +class ActionGetURL(Action): + ACTION_NAME = "ActionGetURL" + ACTION_ID = 0x83 + + def __init__(self, url, target=""): + self.url = url + self.target = target + + def gen_data(self): + return "%s\0%s\0" % (self.url, self.target) + +class ActionGetURL2(Action): + ACTION_NAME = "ActionGetURL2" + ACTION_ID = 0x9a + + METHODS = {"": 0, "GET": 1, "POST": 2} + + def __init__(self, method, load_target=False, load_variables=False): + self.method = method + self.load_target = load_target + self.load_variables = load_variables + + def gen_data(self): + # The SWF 10 spec document is incorrect. + # method goes at the low end + # and the flags at the high end + bits = BitStream() + bits.write_bit(self.load_variables) + bits.write_bit(self.load_target) + bits.zero_fill(4) + bits.write_int_value(self.METHODS[self.method.upper()], 2) + return bits.serialize() + +class ActionGotoFrame(Action): + ACTION_NAME = "ActionGotoFrame" + ACTION_ID = 0x81 + + def __init__(self, index): + self.index = index + + def gen_data(self): + return struct.pack("H", self.index) + +class ActionGotoFrame2(Action): + ACTION_NAME = "ActionGotoFrame2" + ACTION_ID = 0x9f + + def __init__(self, play=False, scene_bias=0): + self.play = play + self.scene_bias = scene_bias + + def gen_data(self): + bits = BitStream() + bits.zero_fill(6) + bits.write_bit(self.scene_bias > 0) + bits.write_bit(self.play) + + if self.scene_bias > 0: + return bits.serialize() + struct.pack(" 0: + self.branch_offset = block.labels[self.branch_label] - self.offset + + def gen_data(self): + return struct.pack("H", self.branch_offset) + +class ActionJump(BranchingActionBase): + ACTION_NAME = "ActionJump" + ACTION_ID = 0x99 + +class ActionIf(BranchingActionBase): + ACTION_NAME = "ActionIf" + ACTION_ID = 0x9d + +class ActionPush(Action): + ACTION_NAME = "ActionPush" + ACTION_ID = 0x96 + + def __init__(self, *args): + self.values = [] + self.add_element(*args) + + def add_element(self, element): + if hasattr(element, "__iter__") and not isinstance(element, basestring): + for e in element: + self.add_element(e) + if isinstance(element, (Null, Undefined)): + self.values.append((0, element.type)) + elif isinstance(element, basestring): + self.values.append((element, STRING)) + elif isinstance(element, bool): + self.values.append((element, BOOLEAN)) + elif isinstance(element, int): + self.values.append((element, INTEGER)) + elif isinstance(element, float): + if element > 0xFFFFFFFF: + self.values.append((element, DOUBLE)) + else: + self.values.append((element, FLOAT)) + elif isinstance(element, Index): + self.values.append((element.index, element.type)) + elif isinstance(element, RegisterByValue): + self.values.append((element.value, RegisterByValue)) + + def get_block_props_early(self, block): + for index, (value, type) in enumerate(self.values): + if type == STRING: + constant_index = block.constants.add_constant(value) + self.values[index] = (constant_index, CONSTANT8 if constant_index < 256 else CONSTANT16) + elif type == RegisterByValue: + register_index = block.find_register(value) + if register_index < 0: + raise ValueError("register value '%s' not found in registers at this point" % value) + self.values[index] = (register_index, REGISTER) + + def gen_data(self): + bytes = [] + for value, type in self.values: + bytes += chr(type.id) + if type.size == "Z": + bytes += [value, "\0"] + elif type.size != "!": + bytes += struct.pack("<"+type.size, value) + return "".join(bytes) + +class ActionSetTarget(Action): + ACTION_NAME = "ActionSetTarget" + ACTION_ID = 0x8b + + def __init__(self, target): + self.target = target + + def gen_data(self): + return self.target + "\0" + +class ActionStoreRegister(Action): + ACTION_NAME = "ActionStoreRegister" + ACTION_ID = 0x87 + + def __init__(self, index): + self.index = index + + def gen_data(self): + return chr(self.index) + +class ActionTry(Action): + ACTION_NAME = "ActionTry" + ACTION_ID = 0x8f + + def __init__(self, catch_object, try_block=None, catch_block=None, finally_block=None): + + self.catch_object = catch_object + + self.try_block = try_block or Block() + self.catch_block = catch_block or Block() + self.finally_block = finally_block or Block() + + def gen_data(self): + has_catch_block = len(self.catch_block.actions) > 0 + bits = BitStream() + bits.zero_fill(5) + bits.write_bit(isinstance(self.catch_object, Register)) + bits.write_bit(len(self.finally_block.actions) > 0) + bits.write_bit(has_catch_block) + bytes = [bits.serialize()] + bytes += [struct.pack("HHH", len(self.try_block) + 5 if has_catch_block else 0, len(self.catch_block), len(self.finally_block))] + bytes += self.catch_object.index if isinstance(self.catch_object, Register) else (self.catch_object + "\0") + return "".join(bytes) + + def gen_outer_data(self): + bytes = [self.try_block.serialize()] + if len(self.catch_block.actions) > 0: + bytes += ActionJump(len(self.catch_block)).serialize() + bytes += self.catch_block.serialize() + bytes += self.finally_block.serialize() + +class ActionWaitForFrame(Action): + ACTION_NAME = "ActionWaitForFrame" + ACTION_ID = 0x8a + + def __init__(self, index, skip_count=0): + self.index = index + self.skip_count = skip_count + + def gen_data(self): + return struct.pack("HB", self.index, self.skip_count) + +class ActionWaitForFrame2(Action): + ACTION_NAME = "ActionWaitForFrame2" + ACTION_ID = 0x8d + + def __init__(self, skip_count=0): + self.skip_count = skip_count + + def gen_data(self): + return chr(self.skip_count) + +class ActionWith(Action): + ACTION_NAME = "ActionWith" + ACTION_ID = 0x94 + + def __init__(self, with_block): + self.block = with_block or Block() + + def gen_data(self): + return struct.pack("H", len(self.block)) + self.block.serialize() + +def make_short_action(value, name): + + def __len__(self): + return 1 # 1 (Action ID) + + def serialize(self): + return chr(self.ACTION_ID) + + return type(name, (Action,), dict(ACTION_ID=value, ACTION_NAME=name, + __len__=__len__, serialize=serialize)) + +ActionNextFrame = make_short_action(0x04, "ActionNextFrame") +ActionPreviousFrame = make_short_action(0x05, "ActionPreviousFrame") +ActionPlay = make_short_action(0x06, "ActionPlay") +ActionStop = make_short_action(0x07, "ActionStop") +ActionToggleQuality = make_short_action(0x08, "ActionToggleQuality") +ActionStopSounds = make_short_action(0x09, "ActionStopSounds") +ActionAdd = make_short_action(0x0a, "ActionAdd") +ActionSubtract = make_short_action(0x0b, "ActionSubtract") +ActionMultiply = make_short_action(0x0c, "ActionMultiply") +ActionDivide = make_short_action(0x0d, "ActionDivide") +ActionEquals = make_short_action(0x0e, "ActionEquals") +ActionLess = make_short_action(0x0f, "ActionLess") +ActionAnd = make_short_action(0x10, "ActionAnd") +ActionOr = make_short_action(0x11, "ActionOr") +ActionNot = make_short_action(0x12, "ActionNot") +ActionStringEquals = make_short_action(0x13, "ActionStringEquals") +ActionStringLength = make_short_action(0x14, "ActionStringLength") +ActionStringExtract = make_short_action(0x15, "ActionStringExtract") +ActionPop = make_short_action(0x17, "ActionPop") +ActionToInteger = make_short_action(0x18, "ActionToInteger") +ActionGetVariable = make_short_action(0x1c, "ActionGetVariable") +ActionSetVariable = make_short_action(0x1d, "ActionSetVariable") +ActionSetTarget2 = make_short_action(0x20, "ActionSetTarget2") +ActionStringAdd = make_short_action(0x21, "ActionStringAdd") +ActionGetProperty = make_short_action(0x22, "ActionGetProperty") +ActionSetProperty = make_short_action(0x23, "ActionSetProperty") +ActionCloneSprite = make_short_action(0x24, "ActionCloneSprite") +ActionRemoveSprite = make_short_action(0x25, "ActionRemoveSprite") +ActionTrace = make_short_action(0x26, "ActionTrace") +ActionStartDrag = make_short_action(0x27, "ActionStartDrag") +ActionEndDrag = make_short_action(0x28, "ActionEndDrag") +ActionStringLess = make_short_action(0x29, "ActionStringLess") +ActionThrow = make_short_action(0x2a, "ActionThrow") +ActionCastOp = make_short_action(0x2b, "ActionCastOp") +ActionImplementsOp = make_short_action(0x2c, "ActionImplementsOp") +ActionRandomNumber = make_short_action(0x30, "ActionRandomNumber") +ActionMBStringLength = make_short_action(0x31, "ActionMBStringLength") +ActionCharToAscii = make_short_action(0x32, "ActionCharToAscii") +ActionAsciiToChar = make_short_action(0x33, "ActionAsciiToChar") +ActionGetTime = make_short_action(0x34, "ActionGetTime") +ActionMBStringExtract = make_short_action(0x35, "ActionMBStringExtract") +ActionMBCharToAscii = make_short_action(0x36, "ActionMBCharToAscii") +ActionMBAsciiToChar = make_short_action(0x37, "ActionMBAsciiToChar") +ActionDelVar = make_short_action(0x3a, "ActionDelVar") +ActionDelThreadVars = make_short_action(0x3b, "ActionDelThreadVars") +ActionDefineLocalVal = make_short_action(0x3c, "ActionDefineLocalVal") +ActionCallFunction = make_short_action(0x3d, "ActionCallFunction") +ActionReturn = make_short_action(0x3e, "ActionReturn") +ActionModulo = make_short_action(0x3f, "ActionModulo") +ActionNewObject = make_short_action(0x40, "ActionNewObject") +ActionDefineLocal = make_short_action(0x41, "ActionDefineLocal") +ActionInitArray = make_short_action(0x42, "ActionInitArray") +ActionInitObject = make_short_action(0x43, "ActionInitObject") +ActionTypeof = make_short_action(0x44, "ActionTypeof") +ActionGetTargetPath = make_short_action(0x45, "ActionGetTargetPath") +ActionEnumerate = make_short_action(0x46, "ActionEnumerate") +ActionTypedAdd = make_short_action(0x47, "ActionTypedAdd") +ActionTypedLessThan = make_short_action(0x48, "ActionTypedLessThan") +ActionTypedEquals = make_short_action(0x49, "ActionTypedEquals") +ActionConvertToNumber = make_short_action(0x4a, "ActionConvertToNumber") +ActionConvertToString = make_short_action(0x4b, "ActionConvertToString") +ActionDuplicate = make_short_action(0x4c, "ActionDuplicate") +ActionSwap = make_short_action(0x4d, "ActionSwap") +ActionGetMember = make_short_action(0x4e, "ActionGetMember") +ActionSetMember = make_short_action(0x4f, "ActionSetMember") +ActionIncrement = make_short_action(0x50, "ActionIncrement") +ActionDecrement = make_short_action(0x51, "ActionDecrement") +ActionCallMethod = make_short_action(0x52, "ActionCallMethod") +ActionCallNewMethod = make_short_action(0x53, "ActionCallNewMethod") +ActionBitAnd = make_short_action(0x60, "ActionBitAnd") +ActionBitOr = make_short_action(0x61, "ActionBitOr") +ActionBitXor = make_short_action(0x62, "ActionBitXor") +ActionShiftLeft = make_short_action(0x63, "ActionShiftLeft") +ActionShiftRight = make_short_action(0x64, "ActionShiftRight") +ActionShiftUnsigned = make_short_action(0x65, "ActionShiftUnsigned") +ActionStrictEquals = make_short_action(0x66, "ActionStrictEquals") +ActionGreater = make_short_action(0x67, "ActionGreater") +ActionStringGreater = make_short_action(0x68, "ActionStringGreater") +ActionExtends = make_short_action(0x69, "ActionExtends") Added: pypy/branch/avm/pypy/translator/avm1/avm1gen.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,310 @@ + +""" backend generator routines +""" + +from pypy.translator.avm import avm1 +from collections import namedtuple + +Scope = namedtuple("Scope", "block parent callback stack") + +def make_variable(name): + if isinstance(name, Variable): + return name + return Variable(name) + +class StackDummy(object): + def __init__(self, name): + self.name = name + +class Variable(StackDummy): + def __str__(self): + return 'Variable(name="%s")' % self.name + __repr__ = __str__ + + def __add__(self, other): + if isinstance(other, StackDummy): + other = other.name + return Variable("CONCAT %r %r" % (self.name, other)) + + def __radd__(self, other): + if isinstance(other, StackDummy): + other = other.name + return Variable("CONCAT %r %r" % (other, self.name)) + + +class Function(StackDummy): + pass + +class AVM1Gen(object): + """ AVM1 'assembler' generator routines """ + + def __getattribute__(self, name): + return object.__getattribute__(self, name) + + def __init__(self, block=None): + self.block = block or avm1.Block(None, True) + self.scope = Scope(self.block, None, None, []) + self.action(self.block.constants) + + def new_label(self): + return self.scope.block.new_label() + + def push_stack(self, *values): + print "PUSHSTACK:", values + for element in values: + if isinstance(element, avm1.RegisterByIndex): + element = Variable(self.scope.block.registers[element.index]) + elif isinstance(element, avm1.RegisterByValue): + element = Variable(element.value) + self.scope.stack.append(element) + + def pop_stack(self, n=1): + v = [self.scope.stack.pop() for i in xrange(n)] + print "POPSTACK:", v + return v + + def store_register(self, name, index=-1): + index = self.scope.block.store_register(name, index) + self.action(avm1.ActionStoreRegister(index)) + return index + + def find_register(self, name): + return self.scope.block.find_register(name) + + def action(self, action): + return self.scope.block.add_action(action) + + def enter_scope(self, new_code_obj, exit_callback=None): + self.scope = Scope(new_code_obj, self.scope, exit_callback, []) + + def in_function(self): + return self.scope.block.FUNCTION_TYPE + + def exit_scope(self): + block_len = self.finalize_block(self.scope.block) + exit_callback = self.scope.callback + + # Go up to the parent scope. + self.scope = self.scope.parent + + self.scope.block.current_offset += block_len + if exit_callback is not None: + exit_callback() + + def finalize_block(self, block): + for label, branch_block in block.branch_blocks.iteritems(): + if not branch_block.is_sealed(): + raise Exception, "Branch block hasn't been finalized" + # Set the label. + block.labels[label] = block.current_offset + # Add the actions, which updates current_offset + for act in branch_block.actions: + block.add_action(act) + return block.seal() + + def begin_function(self, name, arglist): + self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, name, arglist))) + + def begin_prototype_method(self, function_name, _class, arglist): + def exit_callback(block): + self.set_member() + self.push_const(function_name, "prototype", _class) + self.get_variable() + self.get_member() + self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback) + self.push_stack(Function(function_name)) + + def set_variable(self): + value, name = self.pop_stack(2) + print "SETVARIABLE: %r = %r" % (name, value) + if isinstance(name, Variable): + name = name.name + assert isinstance(name, basestring) + if self.find_register(name) >= 0: + self.store_register(name) + self.action(avm1.ActionSetVariable()) + + def get_variable(self): + name, = self.pop_stack() + print "GETVARIABLE: %s" % (name,) + self.action(avm1.ActionGetVariable()) + self.push_stack(make_variable(name)) + + def set_member(self): + self.action(avm1.ActionSetMember()) + self.pop_stack(3) + + def get_member(self): + self.action(avm1.ActionGetMember()) + value, name, obj = self.pop_stack(3) + print "GETMEMBER:", value, name, obj + self.push_stack(Variable("%s.%s") % obj, name) + + def push_reg_index(self, index): + self.push_const(avm1.RegisterByIndex(index)) + + def push_arg(self, v): + assert self.in_function() > 0, "avm1gen::push_arg called while not in function scope." + self.push_local(v) + +# def push_value(self, v): +# self.action(avm1.ActionPush(v.name)) + + def push_var(self, v): + k = self.find_register(v) + if k >= 0: + self.push_reg_index(k) + else: + self.push_const(v) + self.get_variable() + index = self.store_register(v) + + def push_this(self): + self.push_var("this") + + def push_local(self, v): + self.push_var(v.name) + + def push_const(self, *v): + self.push_stack(*v) + return self.action(avm1.ActionPush(v)) + + def push_undefined(self): + self.push_const(avm1.Undefined) + + def push_null(self): + self.push_const(avm1.Null) + + def return_stmt(self): + self.pop_stack() + self.action(avm1.ActionReturn()) + + def swap(self): + a, b = self.pop_stack(2) + self.push_stack(b, a) + self.action(avm1.ActionSwap()) + + def is_equal(self, value=None): + if value is not None: + self.push_const(value) + self.action(avm1.ActionEquals()) + self.pop_stack(2) + + def is_not_equal(self, value=None): + self.is_equal(value) + self.action(avm1.ActionNot()) + self.pop_stack(2) + + def init_object(self, members=None): + self.push_const(members.iteritems(), len(members)) + self.action(avm1.ActionInitObject()) + self.pop_stack(2) + + def init_array(self, members=None): + self.push_const(members, len(members)) + self.pop_stack(2) + self.action(avm1.ActionInitArray()) + + # Assumes the args and number of args are on the stack. + def call_function(self, func_name): + self.push_const(func_name) + self.action(avm1.ActionCallFunction()) + name, nargs = self.pop_stack() + self.pop_stack(nargs) + self.push_stack(Variable("%s_RETURN" % func_name)) + + def call_function_constargs(self, func_name, *args): + p = self.push_const(*reversed((func_name, len(args))+args)) + self.action(avm1.ActionCallFunction()) + self.pop_stack(2+len(args)) + self.push_stack(Variable("%s_RETURN" % func_name)) + + # Assumes the args and number of args and ScriptObject are on the stack. + def call_method(self, func_name): + self.push_const(func_name) + self.action(avm1.ActionCallMethod()) + name, obj, nargs = self.pop_stack(3) + self.pop_stack(nargs) + self.push_stack(Variable("%s.%s_RETURN" % (obj.name, name))) + + # Assumes the args and number of args are on the stack. + def call_method_constvar(self, _class, func_name): + self.push_var(_class) + self.call_method() + + # Boolean value should be on stack when this is called + def branch_if_true(self, label=""): + if len(label) == 0: + label = self.new_label() + self.scope.block.branch_blocks[label] = avm1.Block(self.block, False) + self.action(avm1.ActionIf(label)) + self.pop_stack() + return (label, self.scope.block.branch_blocks[label]) + + # Assumes the value is on the stack. + def set_proto_field(self, objname, member_name): + self.push_const("prototype") + self.push_var(objname) + self.get_member() + self.swap() + self.push_const(member_name) + self.swap() + self.set_member() + + # Assumes the value is on the stack. + def set_static_field(self, objname, member_name): + self.push_var(objname) + self.swap() + self.push_const(member_name) + self.swap() + self.set_member() + + # If no args are passed then it is assumed that the args and number of args are on the stack. + def newobject_constthis(self, obj, *args): + if len(args) > 0: + self.push_const(args, len(args), obj) + else: + self.push_const(obj) + self.newobject() + + + def newobject(self): + self.action(avm1.ActionNewObject()) + _, nargs = self.pop_stack() + self.pop_stack(nargs) + + # FIXME: will refactor later + #load_str = load_const + + def begin_switch_varname(self, varname): + self.push_var(varname) + self.switch_register = self.store_register(varname) + + def write_case(self, testee): + self.push_const(avm1.RegisterByIndex(self.switch_register), testee) + self.action(avm1.ActionStrictEquals()) + self.pop_stack(2) + if len(self.case_label) < 1: + self.case_label, self.case_block = self.branch_if_true() + else: + self.branch_if_true(self.case_label) + + def write_break(self): + self.exit_scope() + self.case_flag = False + self.case_block = None + + def enter_case_branch(self): + self.enter_scope(self.case_block) + + def throw(self): # Assumes the value to be thrown is on the stack. + self.action(avm1.ActionThrow()) + self.pop_stack() + + def concat_string(self): + self.action(avm1.ActionTypedAdd()) + self.push_stack(self.pop_stack()[0] + self.pop_stack()[0]) + + #def extends(self): + # pass + Added: pypy/branch/avm/pypy/translator/avm1/constant.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/constant.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,43 @@ + +from pypy.translator.oosupport.constant import BaseConstantGenerator + +CONST_OBJNAME = "PYPY_INTERNAL_CONSTANTS" + +DEBUG_CONST_INIT = False +DEBUG_CONST_INIT_VERBOSE = False +SERIALIZE = False + +# ______________________________________________________________________ +# Constant Generators +# +# Different generators implementing different techniques for loading +# constants (Static fields, singleton fields, etc) + +class AVM1ConstGenerator(BaseConstantGenerator): + """ + AVM1 constant generator. It implements the oosupport + constant generator in terms of the AVM1 virtual machine. + """ + + def __init__(self, db): + BaseConstantGenerator.__init__(self, db) + self.cts = db.genoo.TypeSystem(db) + + def _begin_gen_constants(self, asmgen, all_constants): + self.asmgen = asmgen + self.asmgen.init_object() + self.asmgen.store_register(CONST_OBJNAME) + self.asmgen.push_const(CONST_OBJNAME) + self.asmgen.set_variable() + return asmgen + + # _________________________________________________________________ + # OOSupport interface + + def push_constant(self, gen, const): + gen.asmgen.push_var(CONST_OBJNAME) + gen.asmgen.push_const(const.name) + gen.asmgen.get_member() + + def _store_constant(self, gen, const): + gen.asmgen.set_static_field(CONST_OBJNAME, const.name) Added: pypy/branch/avm/pypy/translator/avm1/database.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/database.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,130 @@ +import string +from pypy.translator.avm.class_ import Class +from pypy.translator.avm.delegate import Delegate +from pypy.translator.avm.cts import types +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.ootypesystem.module import ll_os +from pypy.translator.oosupport.database import Database as OODatabase + +try: + set +except NameError: + from sets import Set as set + +class LowLevelDatabase(OODatabase): + def __init__(self, genoo): + OODatabase.__init__(self, genoo) + self.classes = {} # INSTANCE --> class_name + self.classnames = set() # (namespace, name) + self.recordnames = {} # RECORD --> name + self.functions = {} # graph --> function_name + self.methods = {} # graph --> method_name + self.consts = {} # value --> AbstractConst + self.delegates = {} # StaticMethod --> type_name + self.const_count = Counter() # store statistics about constants + + def next_count(self): + return self.unique() + + def _default_record_name(self, RECORD): + trans = string.maketrans('[]<>(), :', '_________') + name = ['Record'] + # XXX: refactor this: we need a proper way to ensure unique names + for f_name, (FIELD_TYPE, f_default) in RECORD._fields.iteritems(): + type_name = FIELD_TYPE._short_name().translate(trans) + name.append(f_name) + name.append(type_name) + + return '__'.join(name) + + def _default_class_name(self, INSTANCE): + parts = INSTANCE._name.rsplit('.', 1) + if len(parts) == 2: + return parts + else: + return None, parts[0] + + def pending_function(self, graph, functype=None): + if functype is None: + function = self.genoo.Function(self, graph) + else: + function = functype(self, graph) + self.pending_node(function) + return function.get_name() + + def pending_class(self, INSTANCE): + try: + return self.classes[INSTANCE] + except KeyError: + pass + + if isinstance(INSTANCE, dotnet.NativeInstance): + self.classes[INSTANCE] = INSTANCE._name + return INSTANCE._name + else: + namespace, name = self._default_class_name(INSTANCE) + name = self.get_unique_class_name(namespace, name) + if namespace is None: + full_name = name + else: + full_name = '%s.%s' % (namespace, name) + self.classes[INSTANCE] = full_name + cls = Class(self, INSTANCE, namespace, name) + self.pending_node(cls) + return full_name + + def pending_record(self, RECORD): + try: + return BUILTIN_RECORDS[RECORD] + except KeyError: + pass + try: + return self.recordnames[RECORD] + except KeyError: + pass + name = self._default_record_name(RECORD) + name = self.get_unique_class_name(None, name) + self.recordnames[RECORD] = name + r = Record(self, RECORD, name) + self.pending_node(r) + return name + + def record_function(self, graph, name): + self.functions[graph] = name + + def graph_name(self, graph): + # XXX: graph name are not guaranteed to be unique + return self.functions.get(graph, None) + + def get_unique_class_name(self, namespace, name): + base_name = name + i = 0 + while (namespace, name) in self.classnames: + name = '%s_%d' % (base_name, i) + i+= 1 + self.classnames.add((namespace, name)) + return name + + def class_name(self, INSTANCE): + if INSTANCE is ootype.ROOT: + return types.object.classname() + try: + NATIVE_INSTANCE = INSTANCE._hints['NATIVE_INSTANCE'] + return NATIVE_INSTANCE._name + except KeyError: + return self.classes[INSTANCE] + + def get_record_name(self, RECORD): + try: + return BUILTIN_RECORDS[RECORD] + except KeyError: + return self.recordnames[RECORD] + + def record_delegate(self, TYPE): + try: + return self.delegates[TYPE] + except KeyError: + name = 'StaticMethod__%d' % len(self.delegates) + self.delegates[TYPE] = name + self.pending_node(Delegate(self, TYPE, name)) + return name Added: pypy/branch/avm/pypy/translator/avm1/genavm.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/genavm.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,21 @@ +import sys +import shutil + +import py +from py.compat import subprocess +from pypy.config.config import Config +from pypy.translator.oosupport.genoo import GenOO +from pypy.translator.cli import conftest +from pypy.translator.cli.avm1gen import AVM1Gen + +class GenAVM1(GenOO): + + ConstantGenerator = constant.AVM1ConstGenerator + + def __init__(self, tmpdir, translator, entrypoint, config=None, exctrans=False): + GenOO.__init__(self, tmpdir, translator, entrypoint, config, exctrans) + self.assembly_name = entrypoint.get_name() + self.const_stat = str(tmpdir.join('const_stat')) + + def create_assembler(self): + return AVM1Gen() Added: pypy/branch/avm/pypy/translator/avm1/records.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/records.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,737 @@ + +from pypy.translator.avm.util import BitStream +from math import log, ceil, sqrt + +def serialize_style_list(lst): + bits = BitStream() + + if len(lst) <= 0xFF: + bits.write_bit_value(len(lst), 8) + else: + bits.write_bit_value(0xFF, 8) + bits.write_bit_value(len(lst), 16) + + for style in lst: + bits += style.serialize() + + return bits + +def nbits(n, *a): + return int(ceil(log(max(1, n, *a), 2))) + +def nbits_abs(n, *a): + return nbits(abs(n), *(abs(n) for n in a)) + +def style_list_bits(lst): + return nbits(len(lst)) + +def clamp(n, minimum, maximum): + return max(minimum, min(n, maximum)) + +class RecordHeader(object): + + def __init__(self, type, length): + self.type = type + self.length = length + + def serialize(self): + bits = BitStream() + bits.write_int_value(self.type, 10) + if self.length < 0x3F: + bits.write_int_value(self.length, 6) + else: + bits.write_int_value(0x3F, 6) + bits.write_int_value(self.length, 32) + return bits + + def parse(self, bitstream): + self.type = bitstream.read_bit_value(10) + self.length = bitstream.read_bit_value(6) + if self.length >= 0x3F: + self.length = bitstream.read_bit_value(32) + +class _EndShapeRecord(object): + + def __call__(self, *a, **b): + pass + + def serialize(self): + bitstream = BitStream() + bitstream.zero_fill(6) + return bitstream + +EndShapeRecord = _EndShapeRecord() + +class Rect(object): + + def __init__(self, XMin=0, XMax=0, YMin=0, YMax=0): + self.XMin = XMin + self.XMax = XMax + self.YMin = YMin + self.YMax = YMax + + def union(self, rect, *rects): + r = Rect(min(self.XMin, rect.XMin), + max(self.XMax, rect.XMax), + min(self.YMin, rect.YMin), + max(self.YMax, rect.YMax)) + if len(rects) > 0: + return r.union(*rects) + return r + + def serialize(self): + if self.XMin > self.XMax or self.YMin > self.YMax: + raise ValueError, "Maximum values in a RECT must be larger than the minimum values." + + # Find our values in twips. + twpXMin = self.XMin * 20 + twpXMax = self.XMax * 20 + twpYMin = self.YMin * 20 + twpYMax = self.YMax * 20 + + # Find the number of bits required to store the longest + # value, then add one to account for the sign bit. + NBits = nbits_abs(twpXMin, twpXMax, twpYMin, twpYMax)+1 + + if NBits > 31: + raise ValueError, "Number of bits per value field cannot exceede 31." + + # And write out our bits. + bits = BitStream() + bits.write_int_value(NBits, 5) + bits.write_int_value(twpXMin, NBits) + bits.write_int_value(twpXMax, NBits) + bits.write_int_value(twpYMin, NBits) + bits.write_int_value(twpYMax, NBits) + + return bits + + def parse(self, bitstream): + + NBits = bitstream.read_bit_value(5) + self.XMin = bitstream.read_bit_value(NBits) + self.XMax = bitstream.read_bit_value(NBits) + self.YMin = bitstream.read_bit_value(NBits) + self.YMax = bitstream.read_bit_value(NBits) + +class XY(object): + + def __init__(self, X=0, Y=0): + self.X = 0 + self.Y = 0 + + def serialize(self): + # Convert to twips plz. + twpX = self.X * 20 + twpY = self.Y * 20 + + # Find the number of bits required to store the longest + # value, then add one to account for the sign bit. + NBits = nbits_abs(twpX, twpY) + + bits = BitStream() + bits.write_int_value(NBits, 5) + bits.write_int_value(twpX, NBits) + bits.write_int_value(twpY, NBits) + + return bits + + def parse(self, bitstream): + + NBits = bitstream.read_bit_value(5) + self.X = bitstream.read_bit_value(NBits) + self.Y = bitstream.read_bit_value(NBits) + +class RGB(object): + + def __init__(self, color): + self.color = color & 0xFFFFFF + + def serialize(self): + bits = BitStream() + bits.write_int_value(self.color, 24) + return bits + + def parse(self, bitstream): + self.color = bitstream.read_bit_value(24) + +class RGBA(RGB): + + def __init__(self, color, alpha=1.0): + super(RGBA, self).__init__(color) + self.alpha = alpha + + def serialize(self): + bits = RGB.serialize(self) + + from pypy.translator.avm.tags import DefineShape + + # If we are in a DefineShape and the version does not support + # alpha (DefineShape1 or DefineShape2), don't use alpha! + if DefineShape._current_variant not in (1, 2): + bits.write_int_value(int(self.alpha * 0xFF), 8) + + return bits + + def parse(self, bitstream): + RGB.parse(self, bitstream) + self.alpha = bitstream.read_bit_value(8) / 0xFF + +class CXForm(object): + has_alpha = False + def __init__(self, rmul=1, gmul=1, bmul=1, radd=0, gadd=0, badd=0): + self.rmul = rmul + self.gmul = gmul + self.bmul = bmul + self.amul = 1 + self.radd = radd + self.gadd = gadd + self.badd = badd + self.aadd = 0 + + def serialize(self): + has_add_terms = self.radd != 0 or self.gadd != 0 or self.badd != 0 or self.aadd != 0 + has_mul_terms = self.rmul != 1 or self.gmul != 1 or self.bmul != 1 or self.amul != 1 + + rm = abs(self.rmul * 256) + gm = abs(self.gmul * 256) + bm = abs(self.bmul * 256) + am = abs(self.amul * 256) + + ro = clamp(self.radd, -255, 255) + go = clamp(self.gadd, -255, 255) + bo = clamp(self.badd, -255, 255) + ao = clamp(self.aadd, -225, 255) + + NBits = 0 + if has_mul_terms: NBits = nbits_abs(rm, gm, bm, am) + if has_add_terms: NBits = max(NBits, nbits_abs(ro, go, bo, ao)) + + bits = BitStream() + bits.write_int_value(NBits, 4) + + if has_mul_terms: + bits.write_int_value(rm, NBits) + bits.write_int_value(gm, NBits) + bits.write_int_value(bm, NBits) + if self.has_alpha: bits.write_int_value(am, NBits) + + if has_add_terms: + bits.write_int_value(ro, NBits) + bits.write_int_value(go, NBits) + bits.write_int_value(bo, NBits) + if self.has_alpha: bits.write_int_value(ao, NBits) + + return bits + +class CXFormWithAlpha(CXForm): + has_alpha = True + def __init__(self, rmul=1, gmul=1, bmul=1, amul=1, radd=0, gadd=0, badd=0, aadd=0): + super(self, CXFormWithAlpha).__init__(rmul, gmul, bmul, radd, gadd, badd) + self.amul = amul + self.aadd = aadd + +class Matrix(object): + + def __init__(self, a=1, b=0, c=0, d=1, tx=0, ty=0): + self.a, self.b, self.c, self.d, self.tx, self.ty = a, b, c, d, tx, ty + + def serialize(self): + + def write_prefixed_values(a, b): + NBits = nbits(a, b) + bits.write_int_value(NBits, 5) + bits.write_int_value(a, NBits) + bits.write_int_value(b, NBits) + + bits = BitStream() + if self.a != 1 or self.d != 1: # HasScale + bits.write_bit(True) + write_prefixed_values(self.a, self.d) + else: + bits.write_bit(False) + + if self.b != 0 or self.c != 0: # HasRotate + bits.write_bit(True) + write_prefixed_values(self.b, self.c) + else: + bits.write_bit(False) + + write_prefixed_values(self.tx * 20, self.ty * 20) + return bits + +class Shape(object): + + def __init__(self): + self.shapes = [] + + self.edge_bounds = Rect() + self.shape_bounds = Rect() + + self.has_scaling = False + self.has_non_scaling = False + + self.bounds_calculated = False + + def add_shape_record(self, shape): + self.shapes.append(shape) + self.bounds_calculated = False + + def add_shape(self, shape): + self.shapes.expand(shape.shapes) + self.bounds_calculated = False + + def serialize(self): + if EndShapeRecord not in self.shapes: + self.shapes.append(EndShapeRecord()) + + bits = BitStream() + + bits.write_int_value(0, 8) # NumFillBits and NumLineBits + for record in self.shapes: + bits += record.serialize() + + return bits + + def calculate_bounds(self): + + if self.bounds_calculated: + return + + last = 0, 0 + style = None + for record in self.shapes: + last, (self.shape_bounds, self.edge_bounds), (has_scale, has_non_scale, style) = \ + record.calculate_bounds(last, self.shape_bounds, self.edge_bounds, style) + if has_scale: + self.has_scaling = True + if has_non_scale: + self.has_non_scaling = True + + self.bounds_calculated = True + +class ShapeWithStyle(Shape): + + def __init__(self, fills=None, strokes=None): + super(self, ShapeWithStyle).__init__(self) + self.fills = fills or [] + self.strokes = strokes or [] + + def add_fill_style(self, style): + style.parent = self.fills + self.fills.append(style) + + def add_line_style(self, style): + style.parent = self.strokes + self.strokes.append(style) + + def add_shape(self, shape): + Shape.add_shape(self, shape) + try: + self.fills += shape.fills + self.strokes += shape.strokes + except AttributeError: + pass + + def serialize(self): + bits = BitStream() + bits += serialize_style_list(self.fills) + bits += serialize_style_list(self.strokes) + bits.write_int_value(style_list_bits(self.fills), 4) + bits.write_int_value(style_list_bits(self.strokes), 4) + return bits + +class LineStyle(object): + + caps = "round" + + def __init__(self, width=1, color=0, alpha=1.0): + self.width = width + self.color = RGBA(color, alpha) + + @property + def index(self): + return self.parent.find(self) + + def serialize(self): + bits = BitStream() + bits.write_int_value(self.width * 20, 16) + bits += self.color.serialize() + return bits + +class LineStyle2(LineStyle): + + def __init__(self, width=1, fillstyle=None, pixel_hinting=False, scale_mode=None, caps="round", joints="round", miter_limit=3): + + color, alpha, self.fillstyle = 0, 1.0, None + + if isinstance(fillstyle, RGBA): + color = fillstyle.color + alpha = fillstyle.alpha + elif isinstance(fillstyle, RGB): + color = fillstyle.color + elif isinstance(fillstyle, int): + if fillstyle > 0xFFFFFF: + color = fillstyle & 0xFFFFFF + alpha = fillstyle >> 6 & 0xFF + else: + color = fillstyle + elif isinstance(fillstyle, FillStyleSolidFill): + color = fillstyle.color.color + alpha = fillstyle.color.alpha + elif isinstance(fillstyle, FillStyle): + self.fillstyle = fillstyle + + super(self, LineStyle2).__init__(self, width, color, alpha) + self.pixel_hinting = pixel_hinting + self.h_scale = (scale_mode == "normal" or scale_mode == "horizontal") + self.v_scale = (scale_mode == "normal" or scale_mode == "vertical") + + if caps == "square": self.caps = 2 + elif caps == None: self.caps = 1 + elif caps == "round": self.caps = 0 + else: + raise ValueError, "Invalid cap style '%s'." % caps + + if joints == "miter": self.joints = 2 + elif joints == "bevel": self.joints = 1 + elif joints == "round": self.joints = 0 + + self.miter_limit = miter_limit + + def serialize(self): + + bits = BitStream() + bits.write_int_value(self.width * 20, 8) + bits.write_int_value(self.width * 20 >> 8, 8) + + bits.write_int_value(self.caps, 2) + bits.write_int_value(self.joints, 2) + bits.write_bit(self.fillstyle is not None); + bits.write_bit(self.h_scale) + bits.write_bit(self.v_scale) + bits.write_bit(self.pixel_hinting) + + if self.joints == 2: + bits.write_fixed_value(self.miter_limit, 16, True) + + if self.fillstyle: + bits.write_bits(self.fillstyle.serialize()) + else: + bits.write_bits(self.color.serialize()) + + return bits + + def cap_style_logic(self, style, last, delta): + # Half thickness (radius of round cap; diameter is thickness) + off = style.width / 2.0 + dx, dy = delta + lx, ly = last + + if style.caps == "round": + r = Rect() + r.XMin = cmp(dx, 0) * off + r.YMin = cmp(dy, 0) * off + r.XMax = r.XMin + dx + r.YMax = r.XMax + dy + return r + + if style.caps == "square": + + # Account for the length of the caps. + dellen = sqrt(dx*dx + dy*dy) # Delta length + norm = (dellen+off*2)/dellen # Extra length + dx *= norm # Add the extra length + dy *= norm + sqx, sqy = delta # Square cap offset + norm = off/dellen # Offset amount + sqx *= norm # Position offsets. + sqy *= norm + + # And offset the position. + lx -= sqx + ly -= sqy + + # Right-hand normal to vector delta relative to (0, 0). + p1x, p1y = (-dy, dx) + norm = sqrt(p1x*p1x + p1y*p1y) + p1x /= norm + p1y /= norm + + # Left-hand normal to vector delta relative to (0, 0) + p2x, p2y = (-p1x, -p1y) + + # Right-hand normal to vector delta relative to delta. + p3x, p3y = (p1x + dx, p1y + dy) + + # Left-hand normal to vector delta relative to delta. + p4x, p4y = (p2x + dx, p2y + dy) + + return Rect( + min(p1x, p2x, p3x, p4x) + lx, + max(p1x, p2x, p3x, p4x) + lx, + min(p1y, p2y, p3y, p4y) + ly, + max(p1y, p2y, p3y, p4y) + ly) + +class FillStyle(object): + + TYPE = -1 + + @property + def index(self): + return self.parent.find(self) + + def serialize(self): + bits = BitStream() + bits.write_int_value(self.TYPE, 8) + bits += self.serialize_inner() + return bits + +class FillStyleSolidFill(object): + + def __init_(self, color, alpha=1.0): + self.color = RGBA(color, alpha) + + def serialize_inner(self): + return self.color.serialize() + +class GradRecord(object): + + def __init__(self, ratio, color, alpha=1.0): + self.ratio = ratio + self.color = RGBA(color, alpha) + + def serialize(self): + bits = BitStream() + bits.write_int_value(self.ratio, 8) + bits += self.color.serialize() + return bits + +class Gradient(object): + + def __init__(self, grads, spread="pad", interpolation="rgb", focalpoint=0): + import operator + grads.sort(key=operator.attrgetter("ratio")) + self.grads = grads + self.spread = spread + self.interpolation = interpolation + self.focalpoint = focalpoint + + @classmethod + def from_begin_gradient_fill(cls, colors, alphas, ratios, spread, interpolation, focalpoint): + grads = [GradRecord(*t) for t in zip(ratios, colors, alphas)] + return cls(grads, spread, interpolation, focalpoint) + +class StraightEdgeRecord(object): + + def __init__(self, delta_x, delta_y): + self.delta_x = delta_x + self.delta_y = delta_y + self.bounds_calculated = False + + def serialize(self): + + bits = BitStream() + + if self.delta_x == 0 and self.delta_y == 0: + return bits + + bits.write_bit(True) # TypeFlag + bits.write_bit(True) # StraightFlag + + X = self.delta_x * 20 + Y = self.delta_y * 20 + + NBits = nbits_abs(X, Y) + + if NBits > 15: + raise ValueError("Number of bits per value field cannot exceed 15") + + bits.write_int_value(NBits, 4) + NBits += 2 + if X == 0: + # Vertical Line + bits.write_bit(False) # GeneralLineFlag + bits.write_bit(True) # VerticalLineFlag + bits.write_int_value(Y, NBits) + elif Y == 0: + # Horizontal Line + bits.write_bit(False) # GeneralLineFlag + bits.write_bit(True) # HorizontalLineFlag + bits.write_int_value(X, NBits) + else: + # General Line + bits.write_bit(True) # GeneralLineFlag + bits.write_int_value(X, NBits) + bits.write_int_value(Y, NBits) + + return bits + + def calculate_bounds(self, last, shape_bounds, edge_bounds, style): + rect = Rect(last[0], last[1], self.delta_x, self.delta_y) + return ((self.delta_x, self.delta_y), + (shape_bounds.union(rect), + edge_bounds.union(LineStyle2.cap_style_logic(style, + last, (self.delta_x, self.delta_y)))), + (False, False, style)) + + +class CurvedEdgeRecord(object): + + def __init__(self, controlx, controly, anchorx, anchory): + self.controlx = controlx + self.controly = controly + self.anchorx = anchorx + self.anchory = anchory + + def serialize(self): + + bits = BitStream() + + if self.delta_x == 0 and self.delta_y == 0: + return bits + + bits.write_bit(True) # TypeFlag + bits.write_bit(False) # StraightFlag + + cX = self.controlx * 20 + cY = self.controly * 20 + aX = self.anchorx * 20 + aY = self.anchory * 20 + + NBits = nbits_abs(cX, cY, aX, aY) + + if NBits > 15: + raise ValueError("Number of bits per value field cannot exceed 15") + + bits.write_int_value(NBits, 4) + NBits += 2 + bits.write_int_value(cX, NBits) + bits.write_int_value(cY, NBits) + bits.write_int_value(aX, NBits) + bits.write_int_value(aY, NBits) + return bits + + def _get_x(self, t): + return self.controlx * 2 * (1-t) * t + self.anchorx * t * t; + + def _get_y(self, t): + return self.controly * 2 * (1-t) * t + self.anchory * t * t; + + def _get_p(self, t): + return (self._get_x(t), self._get_y(t)) + + def calculate_bounds(self, last, shape_bounds, edge_bounds, style): + union = Rect(0, 0, 0, 0) + # CurvedEdgeRecord Bounds + # Formulas somewhat based on + # http://code.google.com/p/bezier/source/browse/trunk/bezier/src/flash/geom/Bezier.as + # Maths here may be incorrect + + # extremumX = last.x - 2 * control.x + anchor.x + # extremumX = last.x - 2 * ( controlDeltaX - last.x ) + anchorDeltaX - last.x + # extremumX = (last.x - last.x) - 2 * ( controlDeltaX - last.x ) + anchorDeltaX + # extremumX = -2 * ( controlDeltaX - last.x ) + anchorDeltaX + + # For the case of last.[x/y] = 0, we can use the formula below. + + x = -2 * self.controlx + self.anchorx + t = -self.controlx / x + p = self._get_x(t) + + if t <= 0 or t >= 1: + union.XMin = last[0] + min(self.anchorx, 0) + union.XMax = union.XMin + max(self.anchorx, 0) + else: + union.XMin = min(p, 0, self.anchorx + last[0]) + union.XMax = union.XMin + max(p - last[0], 0, self.anchorx) + + y = -2 * self.controly + self.anchory + t = -self.controly / y + p = self._get_y(t) + + if t <= 0 or t >= 1: + union.YMin = last[1] + min(self.anchory, 0) + union.YMax = union.YMin + max(self.anchory, 0) + else: + union.YMin = min(p, 0, self.anchory + last[1]) + union.YMax = union.YMin + max(p - last[0], 0, self.anchorY) + + # CapStyle logic: + + # Assume that p0 is last (start anchor), + # p1 is control, and p2 is (end) anchor. + + # Get some small increments in the segment to + # find somewhat of a slope derivative type thing. + + # We should be able to pass these two line deltas + # into LineStyle2.cap_style_logic and union the + # results. + + slope1 = self._get_p(0.01) + slope2 = (self.anchorx - self._get_x(0.99), self.anchory - self._get_y(0.99)) + end_cap_rect = LineStyle2.cap_style_logic(style, last, slope2) + start_cap_rect = LineStyle2.cap_style_logic(style, last, slope1) + + return ((self.anchorx, self.anchory), + (shape_bounds.union(union), + edge_bounds.union(union, start_cap_rect, end_cap_rect)), + (False, False, style)) + +class StyleChangeRecord(object): + + def __init__(self, delta_x, delta_y, linestyle=None, + fillstyle0=None, fillstyle1=None, + fillstyles=None, linestyles=None): + + self.delta_x = delta_x + self.delta_y = delta_y + self.linestyle = linestyle + self.fillstyle0 = fillstyle0 + self.fillstyle1 = fillstyle1 + self.fillstyles = fillstyles + self.linestyles = linestyles + + def serialize(self): + bits = BitStream() + if self.fillstyle0 is not None and self.fillstyle1 is not None and \ + self.fillstyle0.parent != self.fillstyle1.parent: + raise ValueError("fillstyle0 and fillstyle1 do not have the same parent!") + + fsi0 = 0 if self.fillstyle0 is None else self.fillstyle0.index + fsi1 = 0 if self.fillstyle1 is None else self.fillstyle1.index + lsi = 0 if self.linestyle is None else self.linestyle.index + + fbit = 0 if self.fillstyle0 is None else style_list_bits(self.fillstyle0.parent) + lbit = 0 if self.linestyle is None else style_list_bits(self.linestyle.parent) + + from pypy.translator.avm.tags import DefineShape + + new_styles = ((DefineShape._current_variant > 1) and + ((self.linestyles != None and len(self.linestyles) > 0) or + (self.fillstyles != None and len(self.fillstyles) > 0))) + + bits.write_bit(False) # TypeFlag + bits.write_bit(new_styles) # StateNewStyles + bits.write_bit(lsi > 0) # StateLineStyle + bits.write_bit(fsi0 > 0) # StateFillStyle0 + bits.write_bit(fsi1 > 0) # StateFillStyle1 + + move_flag = self.delta_x != 0 or self.delta_y != 0 + + if move_flag: + bits += XY(self.delta_x, self.delta_y).serialize() + + if fsi0 > 0: bits.write_int_value(fsi0, fbit) # FillStyle0 + if fsi1 > 0: bits.write_int_value(fsi1, fbit) # FillStyle1 + if lsi > 0: bits.write_int_value(lsi, lbit) # LineStyle + + if new_styles: + bits += ShapeWithStyle._serialize_style_list(self.fillstyles) # FillStyles + bits += ShapeWithStyle._serialize_style_list(self.linestyles) # LineStyles + + bits.write_int_value(style_list_bits(self.fillstyles), 4) # FillBits + bits.write_int_value(style_list_bits(self.linestyles), 4) # LineBits + + return bits Added: pypy/branch/avm/pypy/translator/avm1/swf.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/swf.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,58 @@ + +import struct + +from pypy.translator.avm.util import BitStream +from pypy.translator.avm.records import Rect + +class SwfData(object): + + def __init__(self, width=600, height=400, fps=24, compress=False, version=10): + self.width = width + self.height = height + self.fps = fps + self.compress = compress + self.version = version + self.frame_count = 1 + + self.tags = [] + + def __getitem__(self, i): + return self.tags.__getitem__(i) + + def __iadd__(self, other): + if hasattr(other, "TAG_TYPE"): + self.add_tag(other) + else: + self.add_tags(other) + return self + + def add_tag(self, tag): + if self.version > tag.TAG_MIN_VERSION: + self.tags.append(tag) + + def add_tags(self, tag_container): + if hasattr(tag_container, "tags"): + self.tags += tag_container.tags + else: + self.tags += tag_container + + def serialize(self): + + header = self._gen_header() + data = self._gen_data_stub() + data += ''.join(tag.serialize() for tag in self.tags) + + header[2] = struct.pack("> 8) & 0xFFFF, self.color & 0xFF) + +class DoAction(SwfTag, Block): + + TAG_TYPE = 12 + TAG_MIN_VERSION = 3 + + def __init__(self): + Block.__init__(self, None, True) + + def serialize_data(self): + return Block.serialize(self) + +class DefineShape(SwfTag): + + TAG_TYPE = 2 + TAG_MIN_VERSION = 1 + TAG_VARIANT = 1 + + _current_variant = None + + def __init__(self, shapes=None, shapeid=None): + self.shapes = ShapeWithStyle() if shapes is None else shapes + if shapeid is None: + global next_character_id + self.shapeid = next_character_id + next_character_id += 1 + else: + self.shapeid = shapeid + + def serialize_data(self): + self.shapes.calculate_bounds() + DefineShape._current_variant = self.TAG_VARIANT + bytes = struct.pack(" + +PyPy AVM Backend Test Case: %s + + + + + + +""" + + crossdomain_xml=""" + +""" + +def parse_result(string): + if string == "true": + return True + elif string == "false": + return False + elif string == "null" or string == "undefined": + return None + elif string.isdigit(): + return int(string) + return string + +class TestCase(object): + def __init__(self, name, swfdata, testcount): + self.name = name + self.swfdata = swfdata + self.results = [] + self.testcount = testcount + +class TestHandler(BaseHTTPRequestHandler): + """The HTTP handler class that provides the tests and handles results""" + + def do_GET(self): + testcase = self.server.testcase + if self.path == "/test.html": + data = config.html_page % (testcase.name, testcase.swfdata.width, testcase.swfdata.height) + mime = 'text/html' + elif self.path == "/test.swf": + data = testcase.swfdata.serialize() + mime = 'application/x-shockwave-flash' + elif self.path == "/crossdomain.xml": + data = config.crossdomain_xml + mime = 'text/xml' + self.serve_data(mime, data) + + def do_POST(self): + if self.path == "/test.result": + form = parse_qs(self.rfile.read(int(self.headers['content-length']))) + self.server.testcase.results.append(parse_result(form['result'][0])) + + def serve_data(self, content_type, data): + self.send_response(200) + self.send_header("Content-type", content_type) + self.send_header("Content-length", len(data)) + self.end_headers() + self.wfile.write(data) + +class BrowserTest(object): + """The browser driver""" + + def start_server(self, port, testcase): + server_address = ('', port) + self.httpd = HTTPServer(server_address, TestHandler) + self.httpd.testcase = testcase + + def get_result(self): + testcase = self.httpd.testcase + while len(testcase.results) < testcase.testcount: + self.httpd.handle_request() + return self.httpd.testcase.results + +def browsertest(name, swfdata, testcount): + testcase = TestCase(str(name), swfdata, testcount) + driver = BrowserTest() + driver.start_server(config.http_port, testcase) + webbrowser.open('http://localhost:%d/test.html' % config.http_port) + + return driver.get_result() Added: pypy/branch/avm/pypy/translator/avm1/test/harness.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/harness.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,70 @@ + +from pypy.translator.avm.test import browsertest as b +from pypy.translator.avm import avm1 as a, avm1gen as g, swf as s, tags as t, records as r + +class TestHarness(object): + def __init__(self, name): + self.testname = name + self.in_test = False + self.expected = [] + self.swf = s.SwfData() + self.swf.add_tag(t.SetBackgroundColor(0x333333)) + self.swf.add_tag(t.DefineEditText(r.Rect(0, 0, 0, 0), "txt", + "Testing %s." % (name,), color=r.RGBA(0xFFFFFF))) + self.swf.add_tag(t.PlaceObject(1, 2)) + self.actions = g.AVM1Gen(t.DoAction()) + self.swf.add_tag(self.actions.block) + self.swf.add_tag(t.ShowFrame()) + self.swf.add_tag(t.End()) + + def print_text(self, text): + self.actions.push_const("txt", "\n" + text) + self.actions.push_var("txt") + self.actions.swap() + self.actions.concat_string() + self.actions.set_variable() + + def print_var(self, prefix, varname): + self.actions.push_const("txt") + self.actions.push_var("txt") + self.actions.push_const("\n" + prefix) + self.actions.push_var(varname) + self.actions.concat_string() + self.actions.concat_string() + self.actions.set_variable() + + def print_stack(self, prefix): + self.actions.push_const("txt") + self.actions.swap() + self.actions.push_var("txt") + self.actions.swap() + self.actions.push_const("\n" + prefix) + self.actions.swap() + self.actions.concat_string() + self.actions.concat_string() + self.actions.set_variable() + + def start_test(self, name): + assert not self.in_test + self.in_test = True + self.print_text("Running test %s." % name) + self.actions.push_const("result") + + def finish_test(self, expected): + # result value is on the stack, + # followed by the string "result" + assert self.in_test + self.in_test = False + self.expected.append(expected) + self.actions.set_variable() + self.print_var("Got: ", "result") + self.actions.push_const("/test.result", "") # URL, target + self.actions.action(a.ActionGetURL2("POST", True, True)) + + def do_test(self): + assert not self.in_test + with open("test.swf", "w") as f: + f.write(self.swf.serialize()) + results = b.browsertest(self.testname, self.swf, len(self.expected)) + for e, r in zip(self.expected, results): + assert e == r Added: pypy/branch/avm/pypy/translator/avm1/test/runtest.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/runtest.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,171 @@ +import platform + +import py +from pypy.translator.translator import TranslationContext +from pypy.rpython.test.tool import BaseRtypingTest, OORtypeMixin +from pypy.rpython.lltypesystem.lltype import typeOf +from pypy.rpython.ootypesystem import ootype +from pypy.annotation.model import lltype_to_annotation +from pypy.translator.backendopt.all import backend_optimizations +from pypy.translator.backendopt.checkvirtual import check_virtual_methods +from pypy.translator.oosupport.support import patch_os, unpatch_os +from pypy.translator.avm.test.harness import TestHarness + +def translate_space_op(gen, op): + if op.opname == "cast_int_to_char": + gen.push_arg(op.args[0]) + gen.push_const(1) + gen.push_var("String") + gen.call_method("fromCharCode") + +def compile_function(func, name, annotation=[], graph=None, backendopt=True, + auto_raise_exc=False, exctrans=False, + annotatorpolicy=None, nowrap=False): + olddefs = patch_os() + gen = _build_gen(func, annotation, name, graph, backendopt, + exctrans, annotatorpolicy, nowrap) + unpatch_os(olddefs) # restore original values + return gen + +def _build_gen(func, annotation, name, graph=None, backendopt=True, exctrans=False, + annotatorpolicy=None, nowrap=False): + try: + func = func.im_func + except AttributeError: + pass + t = TranslationContext() + if graph is not None: + graph.func = func + ann = t.buildannotator(policy=annotatorpolicy) + inputcells = [ann.typeannotation(an) for an in annotation] + ann.build_graph_types(graph, inputcells) + t.graphs.insert(0, graph) + else: + ann = t.buildannotator(policy=annotatorpolicy) + ann.build_types(func, annotation) + + t.buildrtyper(type_system="ootype").specialize() + if backendopt: + check_virtual_methods(ootype.ROOT) + backend_optimizations(t) + + main_graph = t.graphs[0] + + harness = TestHarness(name) + harness.actions.begin_function(main_graph.name, [v.name for v in main_graph.getargs()]) + for op in main_graph.startblock.operations: + translate_space_op(harness.actions, op) + harness.actions.return_stmt() + harness.actions.exit_scope() + + return harness + +class StructTuple(tuple): + def __getattr__(self, name): + if name.startswith('item'): + i = int(name[len('item'):]) + return self[i] + else: + raise AttributeError, name + +class OOList(list): + def ll_length(self): + return len(self) + + def ll_getitem_fast(self, i): + return self[i] + +class InstanceWrapper: + def __init__(self, class_name): + self.class_name = class_name + +class ExceptionWrapper: + def __init__(self, class_name): + self.class_name = class_name + + def __repr__(self): + return 'ExceptionWrapper(%s)' % repr(self.class_name) + +class AVM1Test(BaseRtypingTest, OORtypeMixin): + def __init__(self): + self._func = None + self._ann = None + self._harness = None + self._test_count = 1 + + def _compile(self, fn, args, ann=None, backendopt=True, auto_raise_exc=False, exctrans=False): + if ann is None: + ann = [lltype_to_annotation(typeOf(x)) for x in args] + if self._func is fn and self._ann == ann: + return self._harness + else: + self._harness = compile_function(fn, self.__class__.__name__, ann, + backendopt=backendopt, + auto_raise_exc=auto_raise_exc, + exctrans=exctrans) + self._func = fn + self._ann = ann + return self._harness + + def _skip_win(self, reason): + if platform.system() == 'Windows': + py.test.skip('Windows --> %s' % reason) + + def _skip_powerpc(self, reason): + if platform.processor() == 'powerpc': + py.test.skip('PowerPC --> %s' % reason) + + def _skip_llinterpreter(self, reason, skipLL=True, skipOO=True): + pass + + def _get_backendopt(self, backendopt): + if backendopt is None: + backendopt = getattr(self, 'backendopt', True) # enable it by default + return backendopt + + def interpret(self, fn, args, expected=None, annotation=None, backendopt=None, exctrans=False): + backendopt = self._get_backendopt(backendopt) + harness = self._compile(fn, args, annotation, backendopt=backendopt, exctrans=exctrans) + harness.start_test("%d" % self._test_count) + self._test_count += 1 + harness.actions.call_function_constargs(fn.func_name, *args) + harness.finish_test(expected) + + def do_test(self): + self._harness.do_test() + + def interpret_raises(self, exception, fn, args, backendopt=None, exctrans=False): + import exceptions # needed by eval + backendopt = self._get_backendopt(backendopt) + try: + self.interpret(fn, args, backendopt=backendopt, exctrans=exctrans) + except ExceptionWrapper, ex: + assert issubclass(eval(ex.class_name), exception) + else: + assert False, 'function did raise no exception at all' + + float_eq = BaseRtypingTest.float_eq_approx + + def is_of_type(self, x, type_): + return True # we can't really test the type + + def ll_to_string(self, s): + return s + + def ll_to_unicode(self, s): + return s + + def ll_to_list(self, l): + return l + + def ll_to_tuple(self, t): + return t + + def class_name(self, value): + return value.class_name.split(".")[-1] + + def is_of_instance_type(self, val): + return isinstance(val, InstanceWrapper) + + def read_attr(self, obj, name): + py.test.skip('read_attr not supported on gencli tests') Added: pypy/branch/avm/pypy/translator/avm1/test/test_harness.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_harness.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,14 @@ +import autopath + +from pypy.translator.avm.test import browsertest, harness as h +from pypy.translator.avm import avm1 as a + +def test_harness(): + harness = h.TestHarness("harness") + harness.start_test("harness") + harness.actions.add_action(a.ActionPush(True)) + harness.finish_test(True) + harness.do_test() + +if __name__ == "__main__": + test_harness() Added: pypy/branch/avm/pypy/translator/avm1/test/test_int.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_int.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,21 @@ +import autopath +import py +from pypy.translator.avm.test.runtest import AVM1Test +from pypy.rpython.test.test_rint import BaseTestRint + +class TestAVM1Int(AVM1Test, BaseTestRint): + def test_char_constant(self): + def dummyfn(i): + return chr(i) + self.interpret(dummyfn, [ord(' ')], ' ') + self.interpret(dummyfn, [ord('a')], 'a') + self.do_test() + + def test_rarithmetic(self): + pass # it doesn't make sense here + + div_mod_iteration_count = 20 + + +if __name__ == "__main__": + TestAVM1Int().test_char_constant() Added: pypy/branch/avm/pypy/translator/avm1/test/test_weakref.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_weakref.py Thu Aug 13 00:29:02 2009 @@ -0,0 +1,6 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rweakref import BaseTestRweakref + +class TestCliWeakRef(CliTest, BaseTestRweakref): + pass Modified: pypy/branch/avm/pypy/translator/c/gcc/trackgcroot.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/goal/bench-cronjob.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/goal/launch-bench-cronjob.sh ============================================================================== Modified: pypy/branch/avm/pypy/translator/goal/translate.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/microbench/microbench.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/microbench/pybench/platform.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/microbench/pybench/pybench.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/sandbox/interact.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/sandbox/pypy_interact.py ============================================================================== From magcius at codespeak.net Thu Aug 13 00:29:19 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Thu, 13 Aug 2009 00:29:19 +0200 (CEST) Subject: [pypy-svn] r66799 - in pypy/branch/avm/pypy/translator/avm1: . test Message-ID: <20090812222919.668F6168020@codespeak.net> Author: magcius Date: Thu Aug 13 00:29:18 2009 New Revision: 66799 Added: pypy/branch/avm/pypy/translator/avm1/__init__.py pypy/branch/avm/pypy/translator/avm1/conftest.py pypy/branch/avm/pypy/translator/avm1/metavm.py pypy/branch/avm/pypy/translator/avm1/node.py pypy/branch/avm/pypy/translator/avm1/opcodes.py pypy/branch/avm/pypy/translator/avm1/test/__init__.py pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py pypy/branch/avm/pypy/translator/avm1/types.py pypy/branch/avm/pypy/translator/avm1/util.py Removed: pypy/branch/avm/pypy/translator/avm1/avm.py Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py pypy/branch/avm/pypy/translator/avm1/avm1gen.py pypy/branch/avm/pypy/translator/avm1/constant.py pypy/branch/avm/pypy/translator/avm1/database.py pypy/branch/avm/pypy/translator/avm1/genavm.py pypy/branch/avm/pypy/translator/avm1/tags.py pypy/branch/avm/pypy/translator/avm1/test/browsertest.py pypy/branch/avm/pypy/translator/avm1/test/harness.py pypy/branch/avm/pypy/translator/avm1/test/runtest.py pypy/branch/avm/pypy/translator/avm1/test/test_int.py Log: Merge commit 'avm1/master' Added: pypy/branch/avm/pypy/translator/avm1/__init__.py ============================================================================== Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1.py Thu Aug 13 00:29:18 2009 @@ -19,35 +19,12 @@ CONSTANT8 = DataType(8, "constant 8", "B") CONSTANT16 = DataType(9, "constant 16", "H") -class Index(object): - def __init__(self, index): - self.index = index - -class Value(object): - def __init__(self, value): - self.value = value - -class Null(object): - type = NULL - -class Undefined(object): - type = UNDEFINED - -class ConstantIndexDescriptor(object): - def __get__(self, obj, objtype): - return CONSTANT8 if obj.index < 256 else CONSTANT16 - -class Constant(Index): - type = ConstantIndexDescriptor() - -class Register(object): - type = REGISTER - -class RegisterByIndex(Register, Index): - pass - -class RegisterByValue(Register, Value): - pass +preload = dict(this="preload_this", + arguments="preload_args", + super="preload_super", + _root="preload_root", + _parent="preload_parent", + _global="preload_global") class Action(object): @@ -128,7 +105,7 @@ self.insert_end = insert_end self.labels = {} - self.branch_blocks = {} + self.branch_blocks = [] self.actions = [] self.current_offset = 0 @@ -174,6 +151,9 @@ def add_action(self, action): if self._sealed: raise SealedBlockError("Block is sealed. Cannot add new actions") + + assert isinstance(action, Action) + self.code = "" # Dirty the code. action.offset = self.current_offset action.get_block_props_early(self) @@ -187,7 +167,7 @@ return old_action # Two nots negate. Take them out. - if action.ACTION_NAME == "ActionNot" and action.ACTION_NAME == "ActionNot": + if len(self.actions) > 0 and action.ACTION_NAME == "ActionNot" and self.actions[-1].ACTION_NAME == "ActionNot": self.actions.pop() self.current_offset -= 1 # len(ShortAction) is 1 return None @@ -199,10 +179,16 @@ return action def serialize(self): + if not self._sealed: + raise SealedBlockError("Block must be sealed before it can be serialized") if len(self.code) > 0: return self.code bytes = [] + block_offset = 0 for action in self.actions: + if isinstance(action, Block): + block_offset += len(action) + action.offset += block_offset action.get_block_props_late(self) bytes += action.serialize() if self.insert_end: @@ -258,46 +244,47 @@ Block.__init__(self, toplevel, False) self.function_name = name self.params = parameters + self.preload_register_count = 1 # Start at 1. # Flags + self.registers = [None] self.preload_parent = False self.preload_root = False self.suppress_super = True self.preload_super = False - self.suppress_args = False - self.preload_args = True + self.suppress_args = True + self.preload_args = False self.suppress_this = True self.preload_this = False self.preload_global = False self.eval_flags() - - def eval_flags(self): # WARNING! eval_flags will clear registers! - # bits = BitStream() - # bits.write_bit_value(self.flags, 16) - # bits.rewind() - # preload_parent = bits.read_bit() - # preload_root = bits.read_bit() - # suppress_super = bits.read_bit() - # preload_super = bits.read_bit() - # suppress_args = bits.read_bit() - # preload_args = bits.read_bit() - # suppress_this = bits.read_bit() - # preload_this = bits.read_bit() - # bits.cursor += 7 # skip over 7 Reserved bits - # preload_global = bits.read_bit() + + for name in parameters: + self.registers.append(name) - self.registers = [None] + def eval_flags(self): # According to the docs, this is the order of register allocation. - if self.preload_this: self.registers.append("this") - if self.preload_args: self.registers.append("arguments") - if self.preload_super: self.registers.append("super") - if self.preload_root: self.registers.append("_root") - if self.preload_parent: self.registers.append("_parent") - if self.preload_global: self.registers.append("_global") + if self.preload_this and "this" not in self.registers: + self.suppress_this = False + self.registers.insert(1, "this") + + if self.preload_args and "arguments" not in self.registers: + self.suppress_args = False + self.registers.insert(2, "arguments") + + if self.preload_super and "super" not in self.registers: + self.suppress_super = False + self.registers.insert(3, "super") + + if self.preload_root and "_root" not in self.registers: + self.registers.insert(4, "_root") + + if self.preload_parent and "_parent" not in self.registers: + self.registers.insert(5, "_parent") - for name in self.params: - self.registers.append(name) + if self.preload_global and "_global" not in self.registers: + self.registers.insert(6, "_global") def gen_data(self): @@ -315,7 +302,7 @@ self.block_data = Block.serialize(self) bytes = [self.function_name, "\0", - struct.pack("HB", len(self.params), len(self.registers)-1), + struct.pack("HB", len(self.params), len(self.registers)), bits.serialize()] for name in self.params: @@ -411,10 +398,11 @@ def get_block_props_late(self, block): if len(self.branch_label) > 0: - self.branch_offset = block.labels[self.branch_label] - self.offset + print "BRANCH:", self.branch_label, block.labels[self.branch_label], self.offset + self.branch_offset = block.labels[self.branch_label] - self.offset - len(self) def gen_data(self): - return struct.pack("H", self.branch_offset) + return struct.pack("h", self.branch_offset) class ActionJump(BranchingActionBase): ACTION_NAME = "ActionJump" @@ -433,37 +421,20 @@ self.add_element(*args) def add_element(self, element): - if hasattr(element, "__iter__") and not isinstance(element, basestring): - for e in element: - self.add_element(e) - if isinstance(element, (Null, Undefined)): - self.values.append((0, element.type)) - elif isinstance(element, basestring): - self.values.append((element, STRING)) - elif isinstance(element, bool): - self.values.append((element, BOOLEAN)) - elif isinstance(element, int): - self.values.append((element, INTEGER)) - elif isinstance(element, float): - if element > 0xFFFFFFFF: - self.values.append((element, DOUBLE)) - else: - self.values.append((element, FLOAT)) - elif isinstance(element, Index): - self.values.append((element.index, element.type)) - elif isinstance(element, RegisterByValue): - self.values.append((element.value, RegisterByValue)) - + if hasattr(element, "__iter__") and not isinstance(element, (basestring, tuple)): + for t in element: + self.add_element(t) + else: + if element in (NULL, UNDEFINED): + element = (None, element) + assert isinstance(element, tuple) + self.values.append(element) + def get_block_props_early(self, block): for index, (value, type) in enumerate(self.values): if type == STRING: constant_index = block.constants.add_constant(value) self.values[index] = (constant_index, CONSTANT8 if constant_index < 256 else CONSTANT16) - elif type == RegisterByValue: - register_index = block.find_register(value) - if register_index < 0: - raise ValueError("register value '%s' not found in registers at this point" % value) - self.values[index] = (register_index, REGISTER) def gen_data(self): bytes = [] @@ -511,13 +482,16 @@ has_catch_block = len(self.catch_block.actions) > 0 bits = BitStream() bits.zero_fill(5) - bits.write_bit(isinstance(self.catch_object, Register)) + bits.write_bit(isinstance(self.catch_object, int)) bits.write_bit(len(self.finally_block.actions) > 0) bits.write_bit(has_catch_block) bytes = [bits.serialize()] - bytes += [struct.pack("HHH", len(self.try_block) + 5 if has_catch_block else 0, len(self.catch_block), len(self.finally_block))] - bytes += self.catch_object.index if isinstance(self.catch_object, Register) else (self.catch_object + "\0") - return "".join(bytes) + bytes += [struct.pack("3H", + len(self.try_block) + 5 if has_catch_block else 0, + len(self.catch_block), + len(self.finally_block))] + bytes += [self.catch_object, "" if isinstance(self.catch_object, int) else "\0"] + return bytes def gen_outer_data(self): bytes = [self.try_block.serialize()] @@ -556,17 +530,28 @@ def gen_data(self): return struct.pack("H", len(self.block)) + self.block.serialize() - -def make_short_action(value, name): + +SHORT_ACTIONS = {} + +# turns NextFrame into next_frame +def make_underlined(name): + return ''.join('_' + c.lower() if c.isupper() else c for c in name)[1:] + +def make_short_action(value, name, push_count=0): def __len__(self): return 1 # 1 (Action ID) def serialize(self): return chr(self.ACTION_ID) + + act = type(name, (Action,), dict(ACTION_ID=value, ACTION_NAME=name, push_count=push_count, + __len__=__len__, serialize=serialize)) + + SHORT_ACTIONS[name[6:].lower()] = act + SHORT_ACTIONS[make_underlined(name[6:])] = act - return type(name, (Action,), dict(ACTION_ID=value, ACTION_NAME=name, - __len__=__len__, serialize=serialize)) + return act ActionNextFrame = make_short_action(0x04, "ActionNextFrame") ActionPreviousFrame = make_short_action(0x05, "ActionPreviousFrame") @@ -574,29 +559,29 @@ ActionStop = make_short_action(0x07, "ActionStop") ActionToggleQuality = make_short_action(0x08, "ActionToggleQuality") ActionStopSounds = make_short_action(0x09, "ActionStopSounds") -ActionAdd = make_short_action(0x0a, "ActionAdd") -ActionSubtract = make_short_action(0x0b, "ActionSubtract") -ActionMultiply = make_short_action(0x0c, "ActionMultiply") -ActionDivide = make_short_action(0x0d, "ActionDivide") -ActionEquals = make_short_action(0x0e, "ActionEquals") -ActionLess = make_short_action(0x0f, "ActionLess") -ActionAnd = make_short_action(0x10, "ActionAnd") -ActionOr = make_short_action(0x11, "ActionOr") +ActionAdd = make_short_action(0x0a, "ActionAdd", -1) +ActionSubtract = make_short_action(0x0b, "ActionSubtract", -1) +ActionMultiply = make_short_action(0x0c, "ActionMultiply", -1) +ActionDivide = make_short_action(0x0d, "ActionDivide", -1) +ActionEquals = make_short_action(0x0e, "ActionEquals", -1) +ActionLess = make_short_action(0x0f, "ActionLess", -1) +ActionAnd = make_short_action(0x10, "ActionAnd", -1) +ActionOr = make_short_action(0x11, "ActionOr", -1) ActionNot = make_short_action(0x12, "ActionNot") -ActionStringEquals = make_short_action(0x13, "ActionStringEquals") +ActionStringEquals = make_short_action(0x13, "ActionStringEquals", -1) ActionStringLength = make_short_action(0x14, "ActionStringLength") ActionStringExtract = make_short_action(0x15, "ActionStringExtract") -ActionPop = make_short_action(0x17, "ActionPop") +ActionPop = make_short_action(0x17, "ActionPop", -1) ActionToInteger = make_short_action(0x18, "ActionToInteger") ActionGetVariable = make_short_action(0x1c, "ActionGetVariable") -ActionSetVariable = make_short_action(0x1d, "ActionSetVariable") +ActionSetVariable = make_short_action(0x1d, "ActionSetVariable", -2) ActionSetTarget2 = make_short_action(0x20, "ActionSetTarget2") -ActionStringAdd = make_short_action(0x21, "ActionStringAdd") -ActionGetProperty = make_short_action(0x22, "ActionGetProperty") -ActionSetProperty = make_short_action(0x23, "ActionSetProperty") +ActionStringAdd = make_short_action(0x21, "ActionStringAdd", -1) +ActionGetProperty = make_short_action(0x22, "ActionGetProperty", -1) +ActionSetProperty = make_short_action(0x23, "ActionSetProperty", -3) ActionCloneSprite = make_short_action(0x24, "ActionCloneSprite") ActionRemoveSprite = make_short_action(0x25, "ActionRemoveSprite") -ActionTrace = make_short_action(0x26, "ActionTrace") +ActionTrace = make_short_action(0x26, "ActionTrace", -1) ActionStartDrag = make_short_action(0x27, "ActionStartDrag") ActionEndDrag = make_short_action(0x28, "ActionEndDrag") ActionStringLess = make_short_action(0x29, "ActionStringLess") @@ -616,7 +601,7 @@ ActionDefineLocalVal = make_short_action(0x3c, "ActionDefineLocalVal") ActionCallFunction = make_short_action(0x3d, "ActionCallFunction") ActionReturn = make_short_action(0x3e, "ActionReturn") -ActionModulo = make_short_action(0x3f, "ActionModulo") +ActionModulo = make_short_action(0x3f, "ActionModulo", -1) ActionNewObject = make_short_action(0x40, "ActionNewObject") ActionDefineLocal = make_short_action(0x41, "ActionDefineLocal") ActionInitArray = make_short_action(0x42, "ActionInitArray") @@ -624,26 +609,26 @@ ActionTypeof = make_short_action(0x44, "ActionTypeof") ActionGetTargetPath = make_short_action(0x45, "ActionGetTargetPath") ActionEnumerate = make_short_action(0x46, "ActionEnumerate") -ActionTypedAdd = make_short_action(0x47, "ActionTypedAdd") -ActionTypedLessThan = make_short_action(0x48, "ActionTypedLessThan") -ActionTypedEquals = make_short_action(0x49, "ActionTypedEquals") +ActionTypedAdd = make_short_action(0x47, "ActionTypedAdd", -1) +ActionTypedLess = make_short_action(0x48, "ActionTypedLess", -1) +ActionTypedEquals = make_short_action(0x49, "ActionTypedEquals", -1) ActionConvertToNumber = make_short_action(0x4a, "ActionConvertToNumber") ActionConvertToString = make_short_action(0x4b, "ActionConvertToString") -ActionDuplicate = make_short_action(0x4c, "ActionDuplicate") +ActionDuplicate = make_short_action(0x4c, "ActionDuplicate", 1) ActionSwap = make_short_action(0x4d, "ActionSwap") -ActionGetMember = make_short_action(0x4e, "ActionGetMember") -ActionSetMember = make_short_action(0x4f, "ActionSetMember") +ActionGetMember = make_short_action(0x4e, "ActionGetMember", -1) +ActionSetMember = make_short_action(0x4f, "ActionSetMember", -3) ActionIncrement = make_short_action(0x50, "ActionIncrement") ActionDecrement = make_short_action(0x51, "ActionDecrement") ActionCallMethod = make_short_action(0x52, "ActionCallMethod") ActionCallNewMethod = make_short_action(0x53, "ActionCallNewMethod") -ActionBitAnd = make_short_action(0x60, "ActionBitAnd") -ActionBitOr = make_short_action(0x61, "ActionBitOr") -ActionBitXor = make_short_action(0x62, "ActionBitXor") -ActionShiftLeft = make_short_action(0x63, "ActionShiftLeft") -ActionShiftRight = make_short_action(0x64, "ActionShiftRight") -ActionShiftUnsigned = make_short_action(0x65, "ActionShiftUnsigned") -ActionStrictEquals = make_short_action(0x66, "ActionStrictEquals") -ActionGreater = make_short_action(0x67, "ActionGreater") -ActionStringGreater = make_short_action(0x68, "ActionStringGreater") +ActionBitAnd = make_short_action(0x60, "ActionBitAnd", -1) +ActionBitOr = make_short_action(0x61, "ActionBitOr", -1) +ActionBitXor = make_short_action(0x62, "ActionBitXor", -1) +ActionShiftLeft = make_short_action(0x63, "ActionShiftLeft", -1) +ActionShiftRight = make_short_action(0x64, "ActionShiftRight", -1) +ActionShiftUnsigned = make_short_action(0x65, "ActionShiftUnsigned", -1) +ActionStrictEquals = make_short_action(0x66, "ActionStrictEquals", -1) +ActionGreater = make_short_action(0x67, "ActionGreater", -1) +ActionStringGreater = make_short_action(0x68, "ActionStringGreater", -1) ActionExtends = make_short_action(0x69, "ActionExtends") Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1gen.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py Thu Aug 13 00:29:18 2009 @@ -2,10 +2,33 @@ """ backend generator routines """ -from pypy.translator.avm import avm1 +from pypy.objspace.flow import model as flowmodel +from pypy.rpython.ootypesystem import ootype +from pypy.translator.avm import avm1, types +from pypy.translator.oosupport.treebuilder import SubOperation +from pypy.translator.oosupport.metavm import Generator as OOGenerator, InstructionList +from pypy.translator.oosupport.constant import push_constant from collections import namedtuple -Scope = namedtuple("Scope", "block parent callback stack") +ClassName = namedtuple("ClassName", "namespace classname") +Scope = namedtuple("Scope", "block parent callback islabel") + +def render_sub_op(sub_op, db, generator): + op = sub_op.op + instr_list = db.genoo.opcodes.get(op.opname, None) + assert instr_list is not None, 'Unknown opcode: %s ' % op + assert isinstance(instr_list, InstructionList) + # Don't do that, please + #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 + db.cts.lltype_to_cts(op.result.concretetype) + for v in op.args: + db.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(generator, op) + # now the value is on the stack def make_variable(name): if isinstance(name, Variable): @@ -24,63 +47,77 @@ def __add__(self, other): if isinstance(other, StackDummy): other = other.name - return Variable("CONCAT %r %r" % (self.name, other)) + return Variable("ADD %r %r" % (self.name, other)) def __radd__(self, other): - if isinstance(other, StackDummy): - other = other.name - return Variable("CONCAT %r %r" % (other, self.name)) - + return other + self + +class ScriptObject(StackDummy): + pass class Function(StackDummy): pass -class AVM1Gen(object): +class AVM1Gen(OOGenerator): """ AVM1 'assembler' generator routines """ - - def __getattribute__(self, name): - return object.__getattribute__(self, name) def __init__(self, block=None): + self.stack = [] + self.namespaces = {} self.block = block or avm1.Block(None, True) - self.scope = Scope(self.block, None, None, []) + self.scope = Scope(self.block, None, None, False) self.action(self.block.constants) - + self.ilasm = self + def new_label(self): - return self.scope.block.new_label() + return self.fn_block.new_label() def push_stack(self, *values): print "PUSHSTACK:", values for element in values: - if isinstance(element, avm1.RegisterByIndex): - element = Variable(self.scope.block.registers[element.index]) - elif isinstance(element, avm1.RegisterByValue): - element = Variable(element.value) - self.scope.stack.append(element) + self.stack.append(element) + + @property + def fn_block(self): + if self.scope.islabel: + return self.scope.parent.block + return self.scope.block def pop_stack(self, n=1): - v = [self.scope.stack.pop() for i in xrange(n)] + v = [self.stack.pop() for i in xrange(n)] print "POPSTACK:", v return v def store_register(self, name, index=-1): - index = self.scope.block.store_register(name, index) + index = self.fn_block.store_register(name, index) self.action(avm1.ActionStoreRegister(index)) return index def find_register(self, name): - return self.scope.block.find_register(name) + print "FINDING REGISTER:", name + return self.fn_block.find_register(name) def action(self, action): return self.scope.block.add_action(action) - def enter_scope(self, new_code_obj, exit_callback=None): - self.scope = Scope(new_code_obj, self.scope, exit_callback, []) - + def set_label(self, label): + print "SETLABEL:", label + + if self.scope.islabel: + self.exit_scope() + + label, block = self._branch_start(label) + self.enter_scope(block, islabel=True) + + def enter_scope(self, new_code_obj, exit_callback=None, islabel=False): + print "ENTERSCOPE" + self.scope = Scope(new_code_obj, self.scope, exit_callback, islabel) + def in_function(self): - return self.scope.block.FUNCTION_TYPE + return self.fn_block.FUNCTION_TYPE def exit_scope(self): + print "EXITSCOPE" block_len = self.finalize_block(self.scope.block) exit_callback = self.scope.callback @@ -92,56 +129,87 @@ exit_callback() def finalize_block(self, block): - for label, branch_block in block.branch_blocks.iteritems(): - if not branch_block.is_sealed(): - raise Exception, "Branch block hasn't been finalized" + for label, branch_block in block.branch_blocks: + if not branch_block.sealed: + branch_block.seal() + # Set the label. block.labels[label] = block.current_offset + + print label, block.current_offset + # Add the actions, which updates current_offset for act in branch_block.actions: + block.add_action(act) return block.seal() + + # def begin_namespace(self, _namespace): + # n = _namespace.split('.') + # namespace = self.namespaces + # if n[0] not in self.namespaces: + # self.namespaces[n[0]] = {} + # self.push_const(n[0]) + # self.init_object() + # self.set_variable() + # self.push_var(n[0]) + # for ns in n[1:]: + # if not ns in namespace: + # namespace[ns] = {} + # namespace = namespace[ns] + # self.push_const(ns) + # self.init_object() + # self.set_member() def begin_function(self, name, arglist): self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, name, arglist))) - - def begin_prototype_method(self, function_name, _class, arglist): + + def begin_static_method(self, function_name, _class, arglist): def exit_callback(block): self.set_member() - self.push_const(function_name, "prototype", _class) - self.get_variable() - self.get_member() + self.load(_class) + self.push_const(function_name) self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback) self.push_stack(Function(function_name)) + def begin_method(self, function_name, _class, arglist): + def exit_callback(block): + self.set_member() + self.load(_class) + self.push_const("prototype") + self.get_member() + self.push_const(function_name) + self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback) + self.push_stack(Function(function_name)) + def set_variable(self): value, name = self.pop_stack(2) print "SETVARIABLE: %r = %r" % (name, value) if isinstance(name, Variable): name = name.name assert isinstance(name, basestring) - if self.find_register(name) >= 0: + if self.find_register(name) >= 0 and self.in_function() == 2: self.store_register(name) self.action(avm1.ActionSetVariable()) def get_variable(self): name, = self.pop_stack() - print "GETVARIABLE: %s" % (name,) + print "GETVARIABLE:", name self.action(avm1.ActionGetVariable()) self.push_stack(make_variable(name)) def set_member(self): self.action(avm1.ActionSetMember()) self.pop_stack(3) - + def get_member(self): self.action(avm1.ActionGetMember()) - value, name, obj = self.pop_stack(3) - print "GETMEMBER:", value, name, obj + name, obj = self.pop_stack(2) + print "GETMEMBER:", name, obj self.push_stack(Variable("%s.%s") % obj, name) def push_reg_index(self, index): - self.push_const(avm1.RegisterByIndex(index)) + self.action(avm1.ActionPush((index, avm1.REGISTER))) def push_arg(self, v): assert self.in_function() > 0, "avm1gen::push_arg called while not in function scope." @@ -152,12 +220,20 @@ def push_var(self, v): k = self.find_register(v) + print k if k >= 0: + self.push_stack(v) self.push_reg_index(k) else: + if self.in_function() == 2: + if v in avm1.preload: + setattr(self.scope.block, avm1.preload[v]) + self.scope.block.eval_flags() + return self.push_var(v) self.push_const(v) self.get_variable() - index = self.store_register(v) + if self.in_function() == 2: + self.store_register(v) def push_this(self): self.push_var("this") @@ -165,17 +241,12 @@ def push_local(self, v): self.push_var(v.name) - def push_const(self, *v): - self.push_stack(*v) - return self.action(avm1.ActionPush(v)) - - def push_undefined(self): - self.push_const(avm1.Undefined) - - def push_null(self): - self.push_const(avm1.Null) + def push_const(self, *args): + self.push_stack(*args) + self.action(avm1.ActionPush(types.pytype_to_avm1(v) for v in args)) def return_stmt(self): + print "RETURNSTMT" self.pop_stack() self.action(avm1.ActionReturn()) @@ -195,15 +266,19 @@ self.action(avm1.ActionNot()) self.pop_stack(2) - def init_object(self, members=None): - self.push_const(members.iteritems(), len(members)) + def init_object(self, members={}): + self.push_const(*members.items()) + self.push_const(len(members)) self.action(avm1.ActionInitObject()) - self.pop_stack(2) + self.pop_stack(self.pop_stack()[0]) + self.push_stack(ScriptObject("object")) - def init_array(self, members=None): - self.push_const(members, len(members)) - self.pop_stack(2) + def init_array(self, members=[]): + self.push_const(members) + self.push_const(len(members)) self.action(avm1.ActionInitArray()) + self.pop_stack(self.pop_stack()[0]) + self.push_stack(ScriptObject("array")) # Assumes the args and number of args are on the stack. def call_function(self, func_name): @@ -220,7 +295,7 @@ self.push_stack(Variable("%s_RETURN" % func_name)) # Assumes the args and number of args and ScriptObject are on the stack. - def call_method(self, func_name): + def call_method_n(self, func_name): self.push_const(func_name) self.action(avm1.ActionCallMethod()) name, obj, nargs = self.pop_stack(3) @@ -230,34 +305,25 @@ # Assumes the args and number of args are on the stack. def call_method_constvar(self, _class, func_name): self.push_var(_class) - self.call_method() - - # Boolean value should be on stack when this is called - def branch_if_true(self, label=""): - if len(label) == 0: - label = self.new_label() - self.scope.block.branch_blocks[label] = avm1.Block(self.block, False) - self.action(avm1.ActionIf(label)) - self.pop_stack() - return (label, self.scope.block.branch_blocks[label]) + self.call_method_n(func_name) # Assumes the value is on the stack. - def set_proto_field(self, objname, member_name): - self.push_const("prototype") - self.push_var(objname) - self.get_member() - self.swap() - self.push_const(member_name) - self.swap() - self.set_member() + # def set_proto_field(self, objname, member_name): + # self.push_const("prototype") + # self.push_var(objname) + # self.get_member() + # self.swap() + # self.push_const(member_name) + # self.swap() + # self.set_member() # Assumes the value is on the stack. - def set_static_field(self, objname, member_name): - self.push_var(objname) - self.swap() - self.push_const(member_name) - self.swap() - self.set_member() + # def set_static_field(self, objname, member_name): + # self.push_var(objname) + # self.swap() + # self.push_const(member_name) + # self.swap() + # self.set_member() # If no args are passed then it is assumed that the args and number of args are on the stack. def newobject_constthis(self, obj, *args): @@ -270,8 +336,9 @@ def newobject(self): self.action(avm1.ActionNewObject()) - _, nargs = self.pop_stack() - self.pop_stack(nargs) + name, nargs = self.pop_stack() + args = self.pop_stack(nargs) + self.push_stack(ScriptObject(name)) # FIXME: will refactor later #load_str = load_const @@ -300,11 +367,135 @@ def throw(self): # Assumes the value to be thrown is on the stack. self.action(avm1.ActionThrow()) self.pop_stack() + + # oosupport Generator routines + def emit(self, op): + a = avm1.SHORT_ACTIONS[op] + if a.push_count > 0: + a.push_stack(StackDummy("Generated by %r" % op)) + elif a.push_count < 0: + self.pop_stack(-a.push_count) + self.action(a()) + + def pop(self, TYPE): + self.action(avm1.ActionPop()) + self.pop_stack() - def concat_string(self): - self.action(avm1.ActionTypedAdd()) - self.push_stack(self.pop_stack()[0] + self.pop_stack()[0]) + def dup(self, TYPE): + self.action(avm1.ActionDuplicate()) + self.push_stack([self.pop_stack()] * 2) + + def load(self, v): + print v, type(v) + if hasattr(v, "__iter__") and not isinstance(v, basestring): + for i in v: + self.load(v) + elif isinstance(v, ClassName): + if v.namespace: + ns = v.namespace.split('.') + self.push_var(ns[0]) + for i in ns[:0:-1]: + self.push_const(i) + self.get_member() + else: + self.push_var(v.classname) + elif isinstance(v, flowmodel.Variable): + if v.concretetype is ootype.Void: + return # ignore it + elif self.load_variable_hook(v): + return + else: + self.push_local(v) + elif isinstance(v, flowmodel.Constant): + push_constant(self.db, v.concretetype, v.value, self) + elif isinstance(v, SubOperation): + render_sub_op(v, self.db, self) + else: + self.push_const(v) + #self.push_var(v) + + def load_variable_hook(self, v): + return False - #def extends(self): + #def downcast(self, TYPE): + # pass + + #def getclassobject(self, OOINSTANCE): # pass + + #def instantiate(self): + # pass + + #def instanceof(self, TYPE): + # pass + + def _make_label(self, label): + print "MAKE LABEL:", label + if label == "" or label is None: + label = self.new_label() + + blocks = dict(self.fn_block.branch_blocks) + + if label in self.fn_block.branch_blocks: + block = blocks[label] + else: + block = avm1.Block(self.block, False) + self.fn_block.branch_blocks.append((label, block)) + return (label, block) + + def _branch_start(self, label): + return self._make_label(label) + + # Boolean value should be on stack when this is called + def branch_unconditionally(self, label): + print "BRANCH TO:", label + label, block = self._branch_start(label) + self.action(avm1.ActionJump(label)) + return label, block + + def branch_conditionally(self, iftrue, label): + label, block = self._branch_start(label) + if not iftrue: + self.action(avm1.ActionNot()) + self.action(avm1.ActionIf(label)) + self.pop_stack() + return label, block + + def branch_if_equal(self, label): + label, block = self._branch_start(label) + self.action(avm1.ActionEquals()) + self.action(avm1.ActionIf(label)) + self.pop_stack(2) + return label, block + + def call_graph(self, graph): + self.call_function(graph.func_name) + + def call_method(self, OOCLASS, method_name): + pass + + def call_oostring(self, OOTYPE): + self.action(avm1.ActionConvertToString()) + + call_oounicode = call_oostring + + # def new(self, TYPE): + # pass + + def oonewarray(self, TYPE, length): + self.newobject_constthis("Array", 1) + + def push_null(self, TYPE=None): + self.action(avm1.ActionPush(avm1.NULL)) + self + + def push_undefined(self): + self.action(avm1.ActionPush(avm1.UNDEFINED)) + self.push_stack(avm1.UNDEFINED) + + def push_primitive_constant(self, TYPE, value): + if TYPE is ootype.Void: + self.push_undefined() + else: + self.push_const(value) Added: pypy/branch/avm/pypy/translator/avm1/conftest.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/conftest.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,19 @@ +class ConftestPlugin: + def pytest_addoption(self, parser): + group = parser.addgroup("pypy-avm options") + # group.addoption('--source', action="store_true", dest="source", default=False, + # help="only generate IL source, don't compile") + # group.addoption('--wd', action="store_true", dest="wd", default=False, + # help="store temporary files in the working directory") + # group.addoption('--stdout', action="store_true", dest="stdout", default=False, + # help="print the generated IL code to stdout, too") + # group.addoption('--nostop', action="store_true", dest="nostop", default=False, + # help="don't stop on warning. The generated IL code could not compile") + # group.addoption('--nowrap', action="store_true", dest="nowrap", default=False, + # help="don't wrap exceptions but let them to flow out of the entry point") + # group.addoption('--verify', action="store_true", dest="verify", default=False, + # help="check that compiled executables are verifiable") + # group.addoption('--norun', action='store_true', dest="norun", default=False, + # help="don't run the compiled executable") + # group.addoption('--trace', action='store_true', dest='trace', default=False, + # help='Trace execution of generated code') Modified: pypy/branch/avm/pypy/translator/avm1/constant.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/constant.py (original) +++ pypy/branch/avm/pypy/translator/avm1/constant.py Thu Aug 13 00:29:18 2009 @@ -25,11 +25,14 @@ def _begin_gen_constants(self, asmgen, all_constants): self.asmgen = asmgen + self.asmgen.push_const(CONST_OBJNAME) self.asmgen.init_object() self.asmgen.store_register(CONST_OBJNAME) - self.asmgen.push_const(CONST_OBJNAME) self.asmgen.set_variable() return asmgen + + def _end_gen_constants(self, a, b): + pass # _________________________________________________________________ # OOSupport interface Modified: pypy/branch/avm/pypy/translator/avm1/database.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/database.py (original) +++ pypy/branch/avm/pypy/translator/avm1/database.py Thu Aug 13 00:29:18 2009 @@ -1,9 +1,6 @@ -import string -from pypy.translator.avm.class_ import Class -from pypy.translator.avm.delegate import Delegate -from pypy.translator.avm.cts import types +#from pypy.translator.avm.class_ import Class from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.module import ll_os +from pypy.translator.cli.support import Counter from pypy.translator.oosupport.database import Database as OODatabase try: @@ -16,7 +13,6 @@ OODatabase.__init__(self, genoo) self.classes = {} # INSTANCE --> class_name self.classnames = set() # (namespace, name) - self.recordnames = {} # RECORD --> name self.functions = {} # graph --> function_name self.methods = {} # graph --> method_name self.consts = {} # value --> AbstractConst @@ -26,17 +22,6 @@ def next_count(self): return self.unique() - def _default_record_name(self, RECORD): - trans = string.maketrans('[]<>(), :', '_________') - name = ['Record'] - # XXX: refactor this: we need a proper way to ensure unique names - for f_name, (FIELD_TYPE, f_default) in RECORD._fields.iteritems(): - type_name = FIELD_TYPE._short_name().translate(trans) - name.append(f_name) - name.append(type_name) - - return '__'.join(name) - def _default_class_name(self, INSTANCE): parts = INSTANCE._name.rsplit('.', 1) if len(parts) == 2: @@ -52,42 +37,26 @@ self.pending_node(function) return function.get_name() - def pending_class(self, INSTANCE): - try: - return self.classes[INSTANCE] - except KeyError: - pass + # def pending_class(self, INSTANCE): + # try: + # return self.classes[INSTANCE] + # except KeyError: + # pass - if isinstance(INSTANCE, dotnet.NativeInstance): - self.classes[INSTANCE] = INSTANCE._name - return INSTANCE._name - else: - namespace, name = self._default_class_name(INSTANCE) - name = self.get_unique_class_name(namespace, name) - if namespace is None: - full_name = name - else: - full_name = '%s.%s' % (namespace, name) - self.classes[INSTANCE] = full_name - cls = Class(self, INSTANCE, namespace, name) - self.pending_node(cls) - return full_name - - def pending_record(self, RECORD): - try: - return BUILTIN_RECORDS[RECORD] - except KeyError: - pass - try: - return self.recordnames[RECORD] - except KeyError: - pass - name = self._default_record_name(RECORD) - name = self.get_unique_class_name(None, name) - self.recordnames[RECORD] = name - r = Record(self, RECORD, name) - self.pending_node(r) - return name + # if isinstance(INSTANCE, dotnet.NativeInstance): + # self.classes[INSTANCE] = INSTANCE._name + # return INSTANCE._name + # else: + # namespace, name = self._default_class_name(INSTANCE) + # name = self.get_unique_class_name(namespace, name) + # if namespace is None: + # full_name = name + # else: + # full_name = '%s.%s' % (namespace, name) + # self.classes[INSTANCE] = full_name + # cls = Class(self, INSTANCE, namespace, name) + # self.pending_node(cls) + # return full_name def record_function(self, graph, name): self.functions[graph] = name @@ -113,18 +82,3 @@ return NATIVE_INSTANCE._name except KeyError: return self.classes[INSTANCE] - - def get_record_name(self, RECORD): - try: - return BUILTIN_RECORDS[RECORD] - except KeyError: - return self.recordnames[RECORD] - - def record_delegate(self, TYPE): - try: - return self.delegates[TYPE] - except KeyError: - name = 'StaticMethod__%d' % len(self.delegates) - self.delegates[TYPE] = name - self.pending_node(Delegate(self, TYPE, name)) - return name Modified: pypy/branch/avm/pypy/translator/avm1/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm1/genavm.py Thu Aug 13 00:29:18 2009 @@ -1,21 +1,38 @@ -import sys -import shutil import py -from py.compat import subprocess -from pypy.config.config import Config from pypy.translator.oosupport.genoo import GenOO -from pypy.translator.cli import conftest -from pypy.translator.cli.avm1gen import AVM1Gen +from pypy.translator.avm.avm1gen import AVM1Gen +from pypy.translator.avm.constant import AVM1ConstGenerator +from pypy.translator.avm.database import LowLevelDatabase +from pypy.translator.avm.function import Function +from pypy.translator.avm.opcodes import opcodes +from pypy.translator.avm.types import AVM1TypeSystem class GenAVM1(GenOO): - ConstantGenerator = constant.AVM1ConstGenerator + opcodes = opcodes + Function = Function + Database = LowLevelDatabase + TypeSystem = AVM1TypeSystem + ConstantGenerator = AVM1ConstGenerator + def __init__(self, tmpdir, translator, entrypoint, config=None, exctrans=False): GenOO.__init__(self, tmpdir, translator, entrypoint, config, exctrans) - self.assembly_name = entrypoint.get_name() self.const_stat = str(tmpdir.join('const_stat')) + self.ilasm = None def create_assembler(self): return AVM1Gen() + + def generate_source(self): + if self.ilasm is None: + self.ilasm = self.create_assembler() + self.fix_names() + self.gen_entrypoint() + self.gen_pendings() + self.db.gen_constants(self.ilasm) + + # Don't do treebuilding stuff + def stack_optimization(self): + pass Added: pypy/branch/avm/pypy/translator/avm1/metavm.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/metavm.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,68 @@ + +from pypy.rpython.ootypesystem import ootype +from pypy.translator.oosupport.metavm import MicroInstruction +from pypy.translator.avm.avm1gen import StackDummy + +class _SetField(MicroInstruction): + def render(self, generator, op): + this, field, value = op.args + + if value.concretetype is ootype.Void: + return + + generator.load(this) + generator.load(field) + generator.load(value) + generator.set_member() + +class _GetField(MicroInstruction): + def render(self, generator, op): + + if op.result.concretetype is ootype.Void: + return + + this, field = op.args + generator.load(this) + generator.load(field) + generator.get_member() + +class _StoreResultStart(MicroInstruction): + def render(self, generator, op): + print "STORERESULT START:", op.result.name + generator.push_const(op.result.name) + +class _StoreResultEnd(MicroInstruction): + def render(self, generator, op): + print "STORERESULT END:", op.result.name + generator.set_variable() + + +class _PushArgsForFunctionCall(MicroInstruction): + def render(self, generator, op): + args = op.args + for arg in args: + print arg, type(arg) + generator.load(arg) + generator.push_const(len(args)) + +class CallConstantMethod(MicroInstruction): + def __init__(self, obj, func_name): + self.obj = obj + self.func_name = func_name + + def render(self, generator, op): + generator.push_var(self.obj) + generator.call_method_n(self.func_name) + +class PushConst(MicroInstruction): + def __init__(self, *args): + self.args = args + + def render(self, generator, op): + generator.push_const(*self.args) + +PushArgsForFunctionCall = _PushArgsForFunctionCall() +StoreResultStart = _StoreResultStart() +StoreResultEnd = _StoreResultEnd() +GetField = _GetField() +SetField = _SetField() Added: pypy/branch/avm/pypy/translator/avm1/node.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/node.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,9 @@ +class Node(object): + def get_name(self): + pass + + def dependencies(self): + pass + + def render(self, ilasm): + pass Added: pypy/branch/avm/pypy/translator/avm1/opcodes.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/opcodes.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,140 @@ + +from pypy.translator.oosupport import metavm as om +from pypy.translator.avm import metavm as am, avm1 as a + +DoNothing = [om.PushAllArgs] + +misc_ops = { + 'new': [om.New], + 'runtimenew': [om.RuntimeNew], + 'oosetfield': [am.SetField], + 'oogetfield': [am.GetField], +# 'oosend': am.CallMethod +} + +unary_ops = { + 'same_as': DoNothing, + 'bool_not': 'not', + 'int_neg': 'negate', + 'int_neg_ovf': 'negate', + 'int_abs': [am.PushArgsForFunctionCall, am.CallConstantMethod("Math", "abs")], + + 'cast_int_to_char': [am.PushArgsForFunctionCall, am.CallConstantMethod("String", "fromCharCode")], + 'cast_int_to_unichar': [am.PushArgsForFunctionCall, am.CallConstantMethod("String", "fromCharCode")], + 'cast_int_to_float': DoNothing, + 'cast_int_to_longlong': DoNothing, + 'cast_int_to_uint': DoNothing, + 'cast_int_to_long': DoNothing, + 'cast_uint_to_float': DoNothing, + 'cast_uint_to_longlong': DoNothing, + 'cast_uint_to_int' : DoNothing, + 'cast_uint_to_long': DoNothing, + + 'cast_bool_to_int': 'convert_to_number', + 'cast_bool_to_uint': 'convert_to_number', + 'cast_bool_to_float': 'convert_to_number', + + +} + +binary_ops = { + 'int_add': 'typed_add', + 'int_sub': 'subtract', + 'int_mul': 'multiply', + 'int_floordiv': [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")], + 'int_mod': 'modulo', + 'int_lt': 'typed_less', + 'int_le': [om.PushAllArgs, 'greater', 'not'], + 'int_eq': 'typed_equals', + 'int_ne': [om.PushAllArgs, 'typed_equals', 'not'], + 'int_gt': 'greater', + 'int_ge': [om.PushAllArgs, 'typed_less', 'not'], + + 'int_and': 'bit_and', + 'int_or': 'bit_or', + 'int_lshift': 'shift_left', + 'int_rshift': 'shift_right', + 'int_xor': 'bit_xor', + + 'uint_add': 'typed_add', + 'uint_sub': 'subtract', + 'uint_mul': 'multiply', + 'uint_floordiv': [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")], + 'uint_mod': 'modulo', + 'uint_lt': 'typed_less', + 'uint_le': [om.PushAllArgs, 'greater', 'not'], + 'uint_eq': 'typed_equals', + 'uint_ne': [om.PushAllArgs, 'typed_equals', 'not'], + 'uint_gt': 'greater', + 'uint_ge': [om.PushAllArgs, 'typed_less', 'not'], + + 'uint_and': 'bit_and', + 'uint_or': 'bit_or', + 'uint_lshift': 'shift_left', + 'uint_rshift': 'shift_right', + 'uint_xor': 'bit_xor', + + 'float_add': 'typed_add', + 'float_sub': 'subtract', + 'float_mul': 'multiply', + 'float_floordiv': [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")], + 'float_mod': 'modulo', + 'float_lt': 'typed_less', + 'float_le': [om.PushAllArgs, 'greater', 'not'], + 'float_eq': 'typed_equals', + 'float_ne': [om.PushAllArgs, 'typed_equals', 'not'], + 'float_gt': 'greater', + 'float_ge': [om.PushAllArgs, 'typed_less', 'not'], + + 'float_and': 'bit_and', + 'float_or': 'bit_or', + 'float_lshift': 'shift_left', + 'float_rshift': 'shift_right', + 'float_xor': 'bit_xor', + + 'llong_add': 'typed_add', + 'llong_sub': 'subtract', + 'llong_mul': 'multiply', + 'llong_floordiv': [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")], + 'llong_mod': 'modulo', + 'llong_lt': 'typed_less', + 'llong_le': [om.PushAllArgs, 'greater', 'not'], + 'llong_eq': 'typed_equals', + 'llong_ne': [om.PushAllArgs, 'typed_equals', 'not'], + 'llong_gt': 'greater', + 'llong_ge': [om.PushAllArgs, 'typed_less', 'not'], + + 'llong_and': 'bit_and', + 'llong_or': 'bit_or', + 'llong_lshift': 'shift_left', + 'llong_rshift': 'shift_right', + 'llong_xor': 'bit_xor', + + 'ullong_add': 'typed_add', + 'ullong_sub': 'subtract', + 'ullong_mul': 'multiply', + 'ullong_floordiv': [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")], + 'ullong_mod': 'modulo', + 'ullong_lt': 'typed_less', + 'ullong_le': [om.PushAllArgs, 'greater', 'not'], + 'ullong_eq': 'typed_equals', + 'ullong_ne': [om.PushAllArgs, 'typed_equals', 'not'], + 'ullong_gt': 'greater', + 'ullong_ge': [om.PushAllArgs, 'typed_less', 'not'], + 'ullong_lshift': 'shift_left', + 'ullong_rshift': 'shift_right', +} + +opcodes = misc_ops.copy() +opcodes.update(unary_ops) +opcodes.update(binary_ops) + +for key, value in opcodes.iteritems(): + if isinstance(value, str): + value = [am.StoreResultStart, om.PushAllArgs, value, am.StoreResultEnd] + if am.StoreResultStart not in value: + value.insert(0, am.StoreResultStart) + if am.StoreResultEnd not in value: + value.append(am.StoreResultEnd) + value = om.InstructionList(value) + opcodes[key] = value Modified: pypy/branch/avm/pypy/translator/avm1/tags.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/tags.py (original) +++ pypy/branch/avm/pypy/translator/avm1/tags.py Thu Aug 13 00:29:18 2009 @@ -3,6 +3,7 @@ from pypy.translator.avm.records import RecordHeader, ShapeWithStyle, Matrix, CXForm from pypy.translator.avm.avm1 import Block +from pypy.translator.avm.util import BitStream next_character_id = 1 @@ -117,12 +118,42 @@ return (struct.pack(" + """ @@ -29,18 +30,15 @@ return True elif string == "false": return False - elif string == "null" or string == "undefined": - return None - elif string.isdigit(): + elif all(c in "0123456789-" for c in string): return int(string) return string class TestCase(object): - def __init__(self, name, swfdata, testcount): + def __init__(self, name, swfdata): self.name = name self.swfdata = swfdata - self.results = [] - self.testcount = testcount + self.result = None class TestHandler(BaseHTTPRequestHandler): """The HTTP handler class that provides the tests and handles results""" @@ -59,9 +57,10 @@ self.serve_data(mime, data) def do_POST(self): + print self.path if self.path == "/test.result": form = parse_qs(self.rfile.read(int(self.headers['content-length']))) - self.server.testcase.results.append(parse_result(form['result'][0])) + self.server.testcase.result = parse_result(form['result'][0]) def serve_data(self, content_type, data): self.send_response(200) @@ -80,14 +79,14 @@ def get_result(self): testcase = self.httpd.testcase - while len(testcase.results) < testcase.testcount: + while testcase.result is None: self.httpd.handle_request() - return self.httpd.testcase.results + return testcase.result -def browsertest(name, swfdata, testcount): - testcase = TestCase(str(name), swfdata, testcount) +def browsertest(name, swfdata): + testcase = TestCase(str(name), swfdata) driver = BrowserTest() driver.start_server(config.http_port, testcase) webbrowser.open('http://localhost:%d/test.html' % config.http_port) - + return driver.get_result() Modified: pypy/branch/avm/pypy/translator/avm1/test/harness.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/harness.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/harness.py Thu Aug 13 00:29:18 2009 @@ -5,23 +5,22 @@ class TestHarness(object): def __init__(self, name): self.testname = name - self.in_test = False - self.expected = [] self.swf = s.SwfData() self.swf.add_tag(t.SetBackgroundColor(0x333333)) self.swf.add_tag(t.DefineEditText(r.Rect(0, 0, 0, 0), "txt", "Testing %s." % (name,), color=r.RGBA(0xFFFFFF))) - self.swf.add_tag(t.PlaceObject(1, 2)) + self.swf.add_tag(t.PlaceObject2(1, 2)) self.actions = g.AVM1Gen(t.DoAction()) self.swf.add_tag(self.actions.block) self.swf.add_tag(t.ShowFrame()) self.swf.add_tag(t.End()) + self.start_test() def print_text(self, text): self.actions.push_const("txt", "\n" + text) self.actions.push_var("txt") self.actions.swap() - self.actions.concat_string() + self.actions.emit('typed_add') self.actions.set_variable() def print_var(self, prefix, varname): @@ -29,8 +28,8 @@ self.actions.push_var("txt") self.actions.push_const("\n" + prefix) self.actions.push_var(varname) - self.actions.concat_string() - self.actions.concat_string() + self.actions.emit('typed_add') + self.actions.emit('typed_add') self.actions.set_variable() def print_stack(self, prefix): @@ -40,31 +39,29 @@ self.actions.swap() self.actions.push_const("\n" + prefix) self.actions.swap() - self.actions.concat_string() - self.actions.concat_string() + self.actions.emit('typed_add') + self.actions.emit('typed_add') self.actions.set_variable() - def start_test(self, name): - assert not self.in_test - self.in_test = True - self.print_text("Running test %s." % name) + def start_test(self): + self.print_text("Running test %s." % self.testname) self.actions.push_const("result") - def finish_test(self, expected): + def finish_test(self): # result value is on the stack, # followed by the string "result" - assert self.in_test - self.in_test = False - self.expected.append(expected) self.actions.set_variable() self.print_var("Got: ", "result") self.actions.push_const("/test.result", "") # URL, target self.actions.action(a.ActionGetURL2("POST", True, True)) + self.actions.push_const("javascript:window.close()", "") # Close the window. + self.actions.action(a.ActionGetURL2("")) - def do_test(self): - assert not self.in_test - with open("test.swf", "w") as f: + def do_test(self, debug=False): + self.finish_test() + self.actions.scope.block.seal() + if debug: + f = open("test.swf", "w") f.write(self.swf.serialize()) - results = b.browsertest(self.testname, self.swf, len(self.expected)) - for e, r in zip(self.expected, results): - assert e == r + f.close() + return b.browsertest(self.testname, self.swf) Modified: pypy/branch/avm/pypy/translator/avm1/test/runtest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/runtest.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/runtest.py Thu Aug 13 00:29:18 2009 @@ -10,13 +10,14 @@ from pypy.translator.backendopt.checkvirtual import check_virtual_methods from pypy.translator.oosupport.support import patch_os, unpatch_os from pypy.translator.avm.test.harness import TestHarness +from pypy.translator.avm.genavm import GenAVM1 -def translate_space_op(gen, op): - if op.opname == "cast_int_to_char": - gen.push_arg(op.args[0]) - gen.push_const(1) - gen.push_var("String") - gen.call_method("fromCharCode") +# def translate_space_op(gen, op): +# if op.opname == "cast_int_to_char": +# gen.push_arg(op.args[0]) +# gen.push_const(1) +# gen.push_var("String") +# gen.call_method("fromCharCode") def compile_function(func, name, annotation=[], graph=None, backendopt=True, auto_raise_exc=False, exctrans=False, @@ -24,8 +25,11 @@ olddefs = patch_os() gen = _build_gen(func, annotation, name, graph, backendopt, exctrans, annotatorpolicy, nowrap) + harness = TestHarness(name) + gen.ilasm = harness.actions + gen.generate_source() unpatch_os(olddefs) # restore original values - return gen + return gen, harness def _build_gen(func, annotation, name, graph=None, backendopt=True, exctrans=False, annotatorpolicy=None, nowrap=False): @@ -50,62 +54,29 @@ backend_optimizations(t) main_graph = t.graphs[0] - - harness = TestHarness(name) - harness.actions.begin_function(main_graph.name, [v.name for v in main_graph.getargs()]) - for op in main_graph.startblock.operations: - translate_space_op(harness.actions, op) - harness.actions.return_stmt() - harness.actions.exit_scope() + tmpdir = py.path.local('.') - return harness - -class StructTuple(tuple): - def __getattr__(self, name): - if name.startswith('item'): - i = int(name[len('item'):]) - return self[i] - else: - raise AttributeError, name - -class OOList(list): - def ll_length(self): - return len(self) - - def ll_getitem_fast(self, i): - return self[i] - -class InstanceWrapper: - def __init__(self, class_name): - self.class_name = class_name - -class ExceptionWrapper: - def __init__(self, class_name): - self.class_name = class_name - - def __repr__(self): - return 'ExceptionWrapper(%s)' % repr(self.class_name) + return GenAVM1(tmpdir, t, None, exctrans) class AVM1Test(BaseRtypingTest, OORtypeMixin): def __init__(self): self._func = None self._ann = None + self._genoo = None self._harness = None - self._test_count = 1 def _compile(self, fn, args, ann=None, backendopt=True, auto_raise_exc=False, exctrans=False): if ann is None: ann = [lltype_to_annotation(typeOf(x)) for x in args] - if self._func is fn and self._ann == ann: - return self._harness - else: - self._harness = compile_function(fn, self.__class__.__name__, ann, - backendopt=backendopt, - auto_raise_exc=auto_raise_exc, - exctrans=exctrans) - self._func = fn - self._ann = ann - return self._harness + self._genoo, self._harness = compile_function(fn, + "%s.%s" % (self.__class__.__name__, fn.func_name), + ann, + backendopt=backendopt, + auto_raise_exc=auto_raise_exc, + exctrans=exctrans) + self._func = fn + self._ann = ann + return self._harness def _skip_win(self, reason): if platform.system() == 'Windows': @@ -123,16 +94,12 @@ backendopt = getattr(self, 'backendopt', True) # enable it by default return backendopt - def interpret(self, fn, args, expected=None, annotation=None, backendopt=None, exctrans=False): + def interpret(self, fn, args, annotation=None, backendopt=None, exctrans=False): backendopt = self._get_backendopt(backendopt) harness = self._compile(fn, args, annotation, backendopt=backendopt, exctrans=exctrans) - harness.start_test("%d" % self._test_count) - self._test_count += 1 harness.actions.call_function_constargs(fn.func_name, *args) - harness.finish_test(expected) - - def do_test(self): - self._harness.do_test() + result = harness.do_test(True) + return result def interpret_raises(self, exception, fn, args, backendopt=None, exctrans=False): import exceptions # needed by eval Modified: pypy/branch/avm/pypy/translator/avm1/test/test_int.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/test_int.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/test_int.py Thu Aug 13 00:29:18 2009 @@ -2,20 +2,49 @@ import py from pypy.translator.avm.test.runtest import AVM1Test from pypy.rpython.test.test_rint import BaseTestRint +from pypy.rlib.rarithmetic import r_longlong class TestAVM1Int(AVM1Test, BaseTestRint): def test_char_constant(self): def dummyfn(i): return chr(i) - self.interpret(dummyfn, [ord(' ')], ' ') - self.interpret(dummyfn, [ord('a')], 'a') - self.do_test() + _ = self.interpret(dummyfn, [ord(' ')]) + assert _ == ' ' + _ = self.interpret(dummyfn, [ord('a')]) + assert _ == 'a' def test_rarithmetic(self): pass # it doesn't make sense here div_mod_iteration_count = 20 + + def test_div_mod(self): + import random + for inttype in (int, r_longlong): -if __name__ == "__main__": - TestAVM1Int().test_char_constant() + # def d(x, y): + # return x/y + + # for i in range(self.div_mod_iteration_count): + # x = inttype(random.randint(-100000, 100000)) + # y = inttype(random.randint(-100000, 100000)) + # if not y: continue + # res = self.interpret(d, [x, y]) + # print "x:", x, "y:", y, "result in Flash:", res, "result in Python:", d(x, y) + # assert res == d(x, y) + + def m(x, y): + return x%y + + for i in range(self.div_mod_iteration_count): + x = inttype(random.randint(-100000, 100000)) + y = inttype(random.randint(-100000, 100000)) + if not y: continue + res = self.interpret(m, [x, y]) + print "x:", x, "y:", y, "result in Flash:", res, "result in Python:", m(x, y) + assert res == m(x, y) + + +if __name__=="__main__": + TestAVM1Int().test_div_mod() Added: pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,18 @@ +import autopath +import py +from pypy.translator.oosupport.test_template.runtest import BaseTestRunTest +from pypy.translator.avm.test.runtest import AVM1Test + +class TestRunTest(BaseTestRunTest, AVM1Test): + + def test_auto_raise_exc(self): + def fn(): + raise ValueError + f = self._compile(fn, [], auto_raise_exc=True) + py.test.raises(ValueError, f) + + def test_big_arglist(self): + def fn(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9): + return a0 + res = self.interpret(fn, [42]*10) + assert res == 42 Added: pypy/branch/avm/pypy/translator/avm1/types.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/types.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,47 @@ + +from pypy.translator.avm import avm1 +from pypy.objspace.flow import model as flowmodel +from pypy.rlib.rarithmetic import r_longlong +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.lltypesystem import lltype + +_pytype_to_avm1 = { + str: avm1.STRING, + unicode: avm1.STRING, + int: avm1.INTEGER, + long: avm1.INTEGER, + bool: avm1.BOOLEAN, + float: avm1.DOUBLE, + r_longlong: avm1.INTEGER, +} + +class AVM1Number(object): + pass + +class AVM1Primitive(object): + pass + +_lltype_to_avm1 = { + lltype.Number: AVM1Number, + lltype.Primitive: AVM1Primitive +} + +def pytype_to_avm1(value): + return (value, _pytype_to_avm1[type(value)]) + +def lltype_to_avm1(value): + return _lltype_to_avm1[type(value)] + +class AVM1TypeSystem(object): + def __init__(self, db): + self.db = db + + def escape_name(self, name): + return name + + def lltype_to_cts(self, TYPE): + return lltype_to_avm1(TYPE) + + def llvar_to_cts(self, var): + print var.name + return self.lltype_to_cts(var.concretetype), var.name Added: pypy/branch/avm/pypy/translator/avm1/util.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/util.py Thu Aug 13 00:29:18 2009 @@ -0,0 +1,256 @@ + +import struct, os, math + +ALIGN_LEFT = "left" +ALIGN_RIGHT = "right" + +class BitStream(object): + + """ BitStream is a class for taking care of data structures that are bit-packed, like SWF.""" + + def __init__(self, bits=[]): + """ + Constructor. + """ + self.bits = [bool(b) and b != "0" for b in bits] + self.cursor = 0 + self.chunks = set((0,)) + + def read_bit(self): + """Reads a bit from the bit stream and returns it as either True or False. IndexError is thrown if reading past the end of the stream.""" + self.cursor += 1 + return self.bits[self.cursor-1] + + def read_bits(self, length): + """Reads length bits and return them in their own bit stream.""" + self.cursor += length + return BitStream(self.bits[self.cursor-length:self.cursor]) + + def write_bit(self, value): + """Writes the boolean value to the bit stream.""" + if self.cursor < len(self.bits): + self.bits[self.cursor] = bool(value) + else: + self.bits.append(bool(value)) + self.cursor += 1 + + def write_bits(self, bits, offset=0, length=0): + """Writes length bits from bits to this bit stream, starting reading at offset. If length + is 0, the entire stream is used.""" + if length < 1: + length = len(bits) + + if length > self.bits_available(): + for i in range(length - self.bits_available()): + self.bits.append(False) + + self.bits[self.cursor:self.cursor+length] = (bool(x) for x in bits[offset:offset+length]) + self.cursor += length + + def read_int_value(self, length): + """Read length bits and return a number containing those bits with the last bit read being + the least significant bit.""" + n = 0 + for i in reversed(xrange(length)): + n |= self.read_bit() << i + return n + + def write_int_value(self, value, length=-1): + """Writes an int to the specified number of bits in the stream, the most significant bit + first. If length is not specified or negative, the log base 2 of value is taken.""" + + if length < 0: + try: + length = int(math.ceil(math.log(value, 2))) # Get the log base 2, or number of bits value will fit in. + except ValueError: + length = 1 + self.chunk() + for i in reversed(xrange(length)): + self.write_bit(value & (1 << i)) + + + def read_fixed_value(self, eight_bit): + """Reads a fixed point number, either 8.8 or 16.16. If eight_bit is True, an + 8.8 format is used, otherwise 16.16.""" + return self.read_int_value(length) / float(0x100 if eight_bit else 0x10000) + + def write_fixed_value(self, value, eight_bit): + """Writes a fixed point number of length, decimal part first. If eight_bit is True, + an 8.8 format is used instead of a 16.16 format.""" + self.write_bit_value(value * float(0x100 if eight_bit else 0x10000), 8 if eight_bit else 16) + + # Precalculated, see the Wikipedia links below. + _EXPN_BIAS = {16: 16, 32: 127, 64: 1023} + _N_EXPN_BITS = {16: 5, 32: 8, 64: 8} + _N_FRAC_BITS = {16: 10, 32: 23, 64: 52} + _FLOAT_NAME = {16: "float16", 32: "float", 64: "double"} + + def read_float_value(self, length): + """Reads a floating point number of length, which must be 16 (float16), 32 (float), + or 64 (double). See: http://en.wikipedia.org/wiki/IEEE_floating-point_standard""" + + if length not in BitStream._FLOAT_NAME: + raise ValueError, "length is not 16, 32 or 64." + + sign = self.read_bit() + expn = self.read_int_value(BitStream._N_EXPN_BITS[length]) + frac = self.read_int_value(BitStream._N_FRAC_BITS[length]) + + frac_total = float(1 << BitStream._N_FRAC_BITS[length]) + + if expn == 0: + if frac == 0: + return 0 + else: + return ~frac + 1 if sign else frac + elif expn == frac_total - 1: + if frac == 0: + return float("-inf") if sign else float("inf") + else: + return float("nan") + + return (-1 if sign else 1) * 2**(expn - BitStream._EXPN_BIAS[length]) * (1 + frac / frac_total) + + def write_float_value(self, value, length): + """Writes a floating point number of length, which must be 16 (float16), + 32 (float), or 64 (double). See: http://en.wikipedia.org/wiki/IEEE_floating-point_standard""" + + if length not in BitStream._FLOAT_NAME: + raise ValueError, "length is not 16, 32 or 64." + + if value == 0: # value is zero, so we don't care about length + self.write_int_value(0, length) + + if math.isnan(value): + self.one_fill(length) + return + elif value == float("-inf"): # negative infinity + self.one_fill(BitStream._N_EXPN_BITS[length] + 1) # sign merged + self.zero_fill(BitStream._N_FRAC_BITS[length]) + return + elif value == float("inf"): # positive infinity + self.write_bit(False) + self.one_fill(BitStream._N_EXPN_BITS[length]) + self.zero_fill(BitStream._N_FRAC_BITS[length]) + return + + if value < 0: + self.write_bit(True) + value = ~value + 1 + else: + self.write_bit(False) + + exp = BitStream._EXPN_BIAS[length] + if value < 1: + while int(value) != 1: + value *= 2 + exp -= 1 + else: + while int(value) != 1: + value /= 2 + exp += 1 + + if exp < 0 or exp > ( 1 << BitStream._N_EXPN_BITS[length] ): + raise ValueError, "Exponent out of range in %s [%d]." % (BitStream._FLOAT_NAME[length], length) + + frac_total = 1 << BitStream._N_FRAC_BITS[length] + self.write_int_value(exp, BitStream._N_EXPN_BITS[length]) + self.write_int_value(int((value-1)*frac_total) & (frac_total - 1), BitStream._N_FRAC_BITS[length]) + + + def one_fill(self, amount): + """Fills amount bits with one. The equivalent of calling + self.write_boolean(True) amount times, but more efficient.""" + + if amount > self.bits_available(): + for i in range(amount - self.bits_available()): + self.bits.append(True) + + self.bits[self.cursor:self.cursor+amount] = [True] * amount + self.cursor += amount + + def zero_fill(self, amount): + """Fills amount bits with zero. The equivalent of calling + self.write_boolean(False) amount times, but more efficient.""" + + if amount > self.bits_available(): + for i in range(amount - self.bits_available()): + self.bits.append(False) + + self.bits[self.cursor:self.cursor+amount] = [False] * amount + self.cursor += amount + + def seek(self, offset, whence=os.SEEK_SET): + if whence == os.SEEK_SET: + self.cursor = offset + elif whence == os.SEEK_CUR: + self.cursor += offset + elif whence == os.SEEK_END: + self.cursor = len(self.bits) - abs(offset) + + def rewind(self): + self.seek(0, os.SEEK_SET) + + def skip_to_end(self): + self.seek(0, os.SEEK_END) + + def bits_available(self): + return len(self.bits) - self.cursor + + def flush(self): + self.zero_fill(8 - (len(self) % 8)) + + def chunk(self): + self.chunks.add(int(math.ceil(self.cursor / 8.))) + + def __len__(self): + return len(self.bits) + + def __getitem__(self, i): + return self.bits.__getitem__(i) + + def __setitem__(self, i, v): + return self.bits.__setitem__(i, v) + + def __str__(self): + return "".join("1" if b else "0" for b in self.bits) + + def __add__(self, bits): + b = BitStream() + b.write_bits(self) + b.write_bits(bits) + return b + + def __iadd__(self, bits): + self.write_bits(bits) + return self + + def serialize(self, align=ALIGN_LEFT, endianness=None): + """Serialize bit array into a byte string, aligning either + on the right (ALIGN_RIGHT) or left (ALIGN_LEFT). Endianness + can also be "<" for little-endian modes.""" + lst = self.bits[:] + leftover = len(lst) % 8 + if leftover > 0: + if align == ALIGN_RIGHT: + lst[:0] = [False] * (8-leftover) # Insert some False values to pad the list so it is aligned to the right. + else: + lst += [False] * (8-leftover) + + lst = BitStream(lst) + tmp = [lst.read_int_value(8) for i in xrange(int(math.ceil(len(lst)/8.0)))] + + bytes = [None] * len(tmp) + if endianness == "<": + m = sorted(self.chunks) + [len(tmp)] + for start, end in zip(m, m[1::]): + bytes[start:end] = tmp[end-1:None if start == 0 else start-1:-1] + else: + bytes = tmp + return ''.join(chr(b) for b in bytes) + + def parse(self, string, endianness="<"): + """Parse a bit array from a byte string into this BitStream.""" + for char in string: + self.write_int_value(ord(char), 8) + From magcius at codespeak.net Thu Aug 13 00:29:33 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Thu, 13 Aug 2009 00:29:33 +0200 (CEST) Subject: [pypy-svn] r66800 - in pypy/branch/avm/pypy/translator: avm1 avm1/.ropeproject avm1/test avm2 Message-ID: <20090812222933.5132B16801F@codespeak.net> Author: magcius Date: Thu Aug 13 00:29:31 2009 New Revision: 66800 Added: pypy/branch/avm/pypy/translator/avm1/.ropeproject/ pypy/branch/avm/pypy/translator/avm1/.ropeproject/config.py pypy/branch/avm/pypy/translator/avm1/.ropeproject/globalnames pypy/branch/avm/pypy/translator/avm1/.ropeproject/history pypy/branch/avm/pypy/translator/avm1/.ropeproject/objectdb pypy/branch/avm/pypy/translator/avm1/function.py pypy/branch/avm/pypy/translator/avm1/test/mylib.py pypy/branch/avm/pypy/translator/avm1/test/runtest2.py pypy/branch/avm/pypy/translator/avm1/test/simpletest.py pypy/branch/avm/pypy/translator/avm1/test/test_backendopt.py pypy/branch/avm/pypy/translator/avm1/test/test_bool.py pypy/branch/avm/pypy/translator/avm1/test/test_builtin.py pypy/branch/avm/pypy/translator/avm1/test/test_carbonpython.py pypy/branch/avm/pypy/translator/avm1/test/test_cast.py pypy/branch/avm/pypy/translator/avm1/test/test_class.py pypy/branch/avm/pypy/translator/avm1/test/test_constant.py pypy/branch/avm/pypy/translator/avm1/test/test_cts.py pypy/branch/avm/pypy/translator/avm1/test/test_dict.py pypy/branch/avm/pypy/translator/avm1/test/test_dotnet.py pypy/branch/avm/pypy/translator/avm1/test/test_exception.py pypy/branch/avm/pypy/translator/avm1/test/test_float.py pypy/branch/avm/pypy/translator/avm1/test/test_list.py pypy/branch/avm/pypy/translator/avm1/test/test_objectmodel.py pypy/branch/avm/pypy/translator/avm1/test/test_oo.py pypy/branch/avm/pypy/translator/avm1/test/test_op.py pypy/branch/avm/pypy/translator/avm1/test/test_overflow.py pypy/branch/avm/pypy/translator/avm1/test/test_pbc.py pypy/branch/avm/pypy/translator/avm1/test/test_primitive.py pypy/branch/avm/pypy/translator/avm1/test/test_query.py pypy/branch/avm/pypy/translator/avm1/test/test_range.py pypy/branch/avm/pypy/translator/avm1/test/test_snippet.py pypy/branch/avm/pypy/translator/avm1/test/test_streamio.py pypy/branch/avm/pypy/translator/avm1/test/test_string.py pypy/branch/avm/pypy/translator/avm1/test/test_tuple.py pypy/branch/avm/pypy/translator/avm1/test/test_unicode.py pypy/branch/avm/pypy/translator/avm2/ pypy/branch/avm/pypy/translator/avm2/__init__.py pypy/branch/avm/pypy/translator/avm2/constants.py Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py pypy/branch/avm/pypy/translator/avm1/avm1gen.py pypy/branch/avm/pypy/translator/avm1/constant.py pypy/branch/avm/pypy/translator/avm1/database.py pypy/branch/avm/pypy/translator/avm1/metavm.py pypy/branch/avm/pypy/translator/avm1/opcodes.py pypy/branch/avm/pypy/translator/avm1/test/browsertest.py pypy/branch/avm/pypy/translator/avm1/types.py pypy/branch/avm/pypy/translator/avm1/util.py Log: getting ready for first push to svn Added: pypy/branch/avm/pypy/translator/avm1/.ropeproject/config.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/.ropeproject/config.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,85 @@ +# The default ``config.py`` + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + #prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + #prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + #prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! Added: pypy/branch/avm/pypy/translator/avm1/.ropeproject/globalnames ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/.ropeproject/globalnames Thu Aug 13 00:29:31 2009 @@ -0,0 +1,10 @@ +?}qUavm1q]q(UActionStringEqualsqUActionDefineLocalqUActionMultiplyqUActionCallFunctionqUActionShiftLeftqUActionSetVariableq UActionAsciiToCharq +UActionGetPropertyq UActionGetTargetPathq UActionInitObjectq UActionCallNewMethodqU ActionGetURL2qU RegisterErrorqU ActionGreaterqURegisterqUValueqURegisterByIndexqU ActionTypeofqUActionIfqU +ActionStopqU ActionAndqUBranchingActionBaseqU ActionTraceqU ActionExtendsqU +ActionLessqUConstantIndexDescriptorqUActionStringAddqUIndexqU ActionNotq U ActionEndDragq!U ShortActionq"UActionRandomNumberq#U +ActionJumpq$UActionNewObjectq%U Undefinedq&UActionCallMethodq'UActionMBCharToAsciiq(U ActionBitOrq)UActionGotoFrameq*U ActionReturnq+U ActionDivideq,UActionSetPropertyq-UActionTypedAddq.UActionPreviousFrameq/UActionOrq0UActionConvertToNumberq1UActionDelThreadVarsq2U ActionEqualsq3U ActionDelVarq4UActionDecrementq5UActionEnumerateq6U ActionGetTimeq7UActionWaitForFrame2q8UBlockq9UActionInitArrayq:U ActionGetURLq;UActionGetVariableqUActionWaitForFrameq?U ActionPopq at UActionConvertToStringqAUActionSetTargetqBUActionMBStringExtractqCUActionConstantPoolqDURegisterByValueqEUActionMBAsciiToCharqFUActionStringExtractqGUActionNextFrameqHU ActionThrowqIUActionStopSoundsqJUActionStartDragqKUActionImplementsOpqLUActionShiftRightqMUglobal_registersqNUActionGotoFrame2qOU +ActionWithqPU +ActionSwapqQU ActionBitXorqRUActionqSUConstantqTUActionCharToAsciiqUUActionGotoLabelqVUActionCloneSpriteqWUActionDuplicateqXUActionShiftUnsignedqYUActionMBStringLengthqZUActionStoreRegisterq[U ActionBitAndq\UActionDefineLocalValq]UActionGetMemberq^USealedBlockErrorq_UActionIncrementq`U ActionAddqaU ActionTryqbU +ActionPushqcUActionToIntegerqdUActionTypedEqualsqeU +ActionCallqfUActionStringLessqgUActionSetMemberqhU +ActionPlayqiU DataTypesqjUActionStringLengthqkU ActionCastOpqlUActionStrictEqualsqmUNullqnUActionSubtractqoUActionSetTarget2qpUActionDefineFunctionqqU ActionModuloqrUActionStringGreaterqsUActionToggleQualityqtUActionDefineFunction2ques. \ No newline at end of file Added: pypy/branch/avm/pypy/translator/avm1/.ropeproject/history ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/.ropeproject/history Thu Aug 13 00:29:31 2009 @@ -0,0 +1 @@ +?]q(]q]qe. \ No newline at end of file Added: pypy/branch/avm/pypy/translator/avm1/.ropeproject/objectdb ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/.ropeproject/objectdb Thu Aug 13 00:29:31 2009 @@ -0,0 +1,4 @@ +?}qUavm1.pyq}qUBlock.__init__qcrope.base.oi.memorydb +ScopeInfo +q)?q}qUinstanceqUdefinedq hUActionDefineFunction2q +??Uunknown?q ?q Uunknown?q s}q?bss. \ No newline at end of file Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1.py Thu Aug 13 00:29:31 2009 @@ -416,6 +416,8 @@ ACTION_NAME = "ActionPush" ACTION_ID = 0x96 + USE_CONSTANTS = False + def __init__(self, *args): self.values = [] self.add_element(*args) @@ -431,6 +433,7 @@ self.values.append(element) def get_block_props_early(self, block): + if not ActionPush.USE_CONSTANTS: return for index, (value, type) in enumerate(self.values): if type == STRING: constant_index = block.constants.add_constant(value) Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1gen.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py Thu Aug 13 00:29:31 2009 @@ -200,13 +200,14 @@ def set_member(self): self.action(avm1.ActionSetMember()) - self.pop_stack(3) + value, name, obj = self.pop_stack(3) + print "SETMEMBER: %s.%s = %r" % (obj, name, value) def get_member(self): self.action(avm1.ActionGetMember()) name, obj = self.pop_stack(2) print "GETMEMBER:", name, obj - self.push_stack(Variable("%s.%s") % obj, name) + self.push_stack(Variable("%s.%s" % (obj, name))) def push_reg_index(self, index): self.action(avm1.ActionPush((index, avm1.REGISTER))) @@ -222,7 +223,7 @@ k = self.find_register(v) print k if k >= 0: - self.push_stack(v) + self.push_stack(Variable(v)) self.push_reg_index(k) else: if self.in_function() == 2: @@ -267,14 +268,14 @@ self.pop_stack(2) def init_object(self, members={}): - self.push_const(*members.items()) + self.load(members.items()) self.push_const(len(members)) self.action(avm1.ActionInitObject()) self.pop_stack(self.pop_stack()[0]) self.push_stack(ScriptObject("object")) def init_array(self, members=[]): - self.push_const(members) + self.load(members) self.push_const(len(members)) self.action(avm1.ActionInitArray()) self.pop_stack(self.pop_stack()[0]) @@ -296,7 +297,7 @@ # Assumes the args and number of args and ScriptObject are on the stack. def call_method_n(self, func_name): - self.push_const(func_name) + self.load(func_name) self.action(avm1.ActionCallMethod()) name, obj, nargs = self.pop_stack(3) self.pop_stack(nargs) @@ -328,15 +329,15 @@ # If no args are passed then it is assumed that the args and number of args are on the stack. def newobject_constthis(self, obj, *args): if len(args) > 0: - self.push_const(args, len(args), obj) + self.load(args+(len(args), obj)) else: - self.push_const(obj) + self.load(obj) self.newobject() def newobject(self): self.action(avm1.ActionNewObject()) - name, nargs = self.pop_stack() + name, nargs = self.pop_stack(2) args = self.pop_stack(nargs) self.push_stack(ScriptObject(name)) @@ -383,13 +384,12 @@ def dup(self, TYPE): self.action(avm1.ActionDuplicate()) - self.push_stack([self.pop_stack()] * 2) + self.push_stack(*[self.pop_stack()] * 2) def load(self, v): - print v, type(v) if hasattr(v, "__iter__") and not isinstance(v, basestring): for i in v: - self.load(v) + self.load(i) elif isinstance(v, ClassName): if v.namespace: ns = v.namespace.split('.') @@ -480,15 +480,16 @@ call_oounicode = call_oostring - # def new(self, TYPE): - # pass + def new(self, TYPE): + if isinstance(TYPE, ootype.List): + self.oonewarray(None) - def oonewarray(self, TYPE, length): - self.newobject_constthis("Array", 1) + def oonewarray(self, TYPE, length=1): + self.newobject_constthis("Array", length) def push_null(self, TYPE=None): self.action(avm1.ActionPush(avm1.NULL)) - self + self.push_stack(avm1.NULL) def push_undefined(self): self.action(avm1.ActionPush(avm1.UNDEFINED)) @@ -496,6 +497,11 @@ def push_primitive_constant(self, TYPE, value): if TYPE is ootype.Void: - self.push_undefined() + self.push_null() + elif TYPE is ootype.String: + if value._str is None: + self.push_null() + else: + self.push_const(value._str) else: self.push_const(value) Modified: pypy/branch/avm/pypy/translator/avm1/constant.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/constant.py (original) +++ pypy/branch/avm/pypy/translator/avm1/constant.py Thu Aug 13 00:29:31 2009 @@ -1,5 +1,5 @@ -from pypy.translator.oosupport.constant import BaseConstantGenerator +from pypy.translator.oosupport import constant as c CONST_OBJNAME = "PYPY_INTERNAL_CONSTANTS" @@ -13,34 +13,107 @@ # Different generators implementing different techniques for loading # constants (Static fields, singleton fields, etc) -class AVM1ConstGenerator(BaseConstantGenerator): +class AVM1ConstGenerator(c.BaseConstantGenerator): """ AVM1 constant generator. It implements the oosupport constant generator in terms of the AVM1 virtual machine. """ def __init__(self, db): - BaseConstantGenerator.__init__(self, db) + c.BaseConstantGenerator.__init__(self, db) self.cts = db.genoo.TypeSystem(db) - def _begin_gen_constants(self, asmgen, all_constants): - self.asmgen = asmgen - self.asmgen.push_const(CONST_OBJNAME) - self.asmgen.init_object() - self.asmgen.store_register(CONST_OBJNAME) - self.asmgen.set_variable() - return asmgen + def _begin_gen_constants(self, gen, all_constants): + gen.push_const(CONST_OBJNAME) + gen.init_array() + gen.store_register(CONST_OBJNAME) + gen.set_variable() + return gen - def _end_gen_constants(self, a, b): + def _end_gen_constants(self, gen, numsteps): + pass + + def _declare_const(self, gen, const): + pass + + def _close_step(self, gen, stepnum): pass # _________________________________________________________________ # OOSupport interface def push_constant(self, gen, const): - gen.asmgen.push_var(CONST_OBJNAME) - gen.asmgen.push_const(const.name) - gen.asmgen.get_member() + gen.push_var(CONST_OBJNAME) + gen.push_const(const.name) + gen.get_member() + + def _create_pointers(self, gen, all_constants): + pass + + def _initialize_data(self, gen, all_constants): + """ Iterates through each constant, initializing its data. """ + # gen.add_section("Initialize Data Phase") + for const in all_constants: + # gen.add_comment("Constant: %s" % const.name) + const.initialize_data(self, gen) + + +class AVM1ArrayListConst(c.ListConst): + + NAME = 'NOT_IMPL' + + def __init__(self, db, list, count): + c.AbstractConst.__init__(self, db, list, count) + self.name = '%s__%d' % (self.NAME, count) + + def create_pointer(self, gen): + assert False + + def initialize_data(self, constgen, gen): + assert not self.is_null() + + if self._do_not_initialize(): + return + + gen.push_var(CONST_OBJNAME) + gen.push_const(self.name) + gen.init_array(self.value._list) + gen.set_member() + + # for idx, item in enumerate(self.value._list): + # gen.push_const(CONST_OBJNAME, CONST_OBJNAME) + # gen.get_variable() + # gen.get_variable() + # gen.push_const(self.name, self.name) + # gen.get_member() + # gen.push_const(idx) + # gen.load(item) + # gen.set_member() + # gen.set_member() + +class AVM1ArrayConst(AVM1ArrayListConst): + NAME = 'ARRAY' + +class AVM1ListConst(AVM1ArrayListConst): + NAME = 'LIST' + +class AVM1DictConst(c.DictConst): + def initialize_data(self, constgen, gen): + assert not self.is_null() + + gen.push_var(CONST_OBJNAME) + gen.push_const(self.name) + gen.init_object(self.value._dict) + gen.set_member() + + # for key, value in self.value._dict.iteritems(): + # gen.push_const(CONST_OBJNAME, CONST_OBJNAME) + # gen.get_variable() + # gen.get_variable() + # gen.push_const(self.name, self.name) + # gen.get_member() + # gen.load(key) + # gen.load(value) + # gen.set_member() + # gen.set_member() - def _store_constant(self, gen, const): - gen.asmgen.set_static_field(CONST_OBJNAME, const.name) Modified: pypy/branch/avm/pypy/translator/avm1/database.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/database.py (original) +++ pypy/branch/avm/pypy/translator/avm1/database.py Thu Aug 13 00:29:31 2009 @@ -75,8 +75,8 @@ return name def class_name(self, INSTANCE): - if INSTANCE is ootype.ROOT: - return types.object.classname() + #if INSTANCE is ootype.ROOT: + # return types.object.classname() try: NATIVE_INSTANCE = INSTANCE._hints['NATIVE_INSTANCE'] return NATIVE_INSTANCE._name Added: pypy/branch/avm/pypy/translator/avm1/function.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/function.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,198 @@ +from functools import partial + +from pypy.objspace.flow import model as flowmodel +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.lltypesystem.lltype import Void +from pypy.translator.oosupport.function import Function as OOFunction +from pypy.translator.avm.node import Node +from pypy.translator.avm.avm1gen import ClassName + +def load_variable_hook(self, v): + if v.name in self.argset: + selftype, selfname = self.args[0] + if self.is_method and v.name == selfname: + self.generator.push_this() # special case for 'self' + else: + self.generator.push_arg(v) + return True + return False + + +class Function(OOFunction, Node): + + auto_propagate_exceptions = True + + def __init__(self, *args, **kwargs): + OOFunction.__init__(self, *args, **kwargs) + + if hasattr(self.db.genoo, 'exceptiontransformer'): + self.auto_propagate_exceptions = False + + namespace = getattr(self.graph.func, '_namespace_', None) + if namespace: + if '.' in namespace: + self.namespace, self.classname = namespace.rsplit('.', 1) + else: + self.namespace = None + self.classname = namespace + else: + self.namespace = None + self.classname = None + + def _create_generator(self, ilasm): + ilasm.db = self.db + ilasm.load_variable_hook = partial(load_variable_hook, self) + return ilasm + + def record_ll_meta_exc(self, ll_meta_exc): + # record the type only if it doesn't belong to a native_class + ll_exc = ll_meta_exc._INSTANCE + NATIVE_INSTANCE = ll_exc._hints.get('NATIVE_INSTANCE', None) + if NATIVE_INSTANCE is None: + OOFunction.record_ll_meta_exc(self, ll_meta_exc) + + def begin_render(self): + self._set_args() + self._set_locals() + if self.args: + args = zip(*self.args)[1] + else: + args = () + if self.is_method: + self.generator.begin_method(self.name, ClassName(self.namespace, self.classname), args[1:]) + elif self.classname: + self.generator.begin_static_method(self.name, ClassName(self.namespace, self.classname), args) + else: + self.generator.begin_function(self.name, args) + + def end_render(self): + if self.generator.scope.islabel: + self.generator.exit_scope() + self.generator.exit_scope() + + def render_return_block(self, block): + print "RETURN BLOCK RENDERING" + return_var = block.inputargs[0] + if return_var.concretetype is not Void: + self.generator.load(return_var) + self.generator.return_stmt() + + def set_label(self, label): + return self.generator.set_label(label) + + # def _render_op(self, op): + # #instr_list = self.db.genoo.opcodes.get(op.opname, None) + # #instr_list.render(self.generator, op) + # super(Function, self)._render_op(op) + + def _setup_link(self, link): + target = link.target + linkvars = [] + for to_load, to_store in zip(link.args, target.inputargs): + if isinstance(to_load, flowmodel.Variable) and to_load.name == to_store.name: + continue + if to_load.concretetype is ootype.Void: + continue + linkvars.append((to_load, to_store)) + + # after SSI_to_SSA it can happen to have to_load = [a, b] and + # to_store = [b, c]. If we store each variable sequentially, + # 'b' would be overwritten before being read. To solve, we + # first load all the values on the stack, then store in the + # appropriate places. + + if self._trace_enabled(): + self._trace('link', writeline=True) + for to_load, to_store in linkvars: + self._trace_value('%s <-- %s' % (to_store, to_load), to_load) + self._trace('', writeline=True) + + for to_load, to_store in linkvars: + self.generator.load(to_store) + self.generator.load(to_load) + self.generator.set_variable() + + + # def begin_try(self, cond): + # if cond: + # self.ilasm.begin_try() + + # def end_try(self, target_label, cond): + # if cond: + # self.ilasm.leave(target_label) + # self.ilasm.end_try() + # else: + # self.ilasm.branch(target_label) + + # def begin_catch(self, llexitcase): + # ll_meta_exc = llexitcase + # ll_exc = ll_meta_exc._INSTANCE + # cts_exc = self.cts.lltype_to_cts(ll_exc) + # self.ilasm.begin_catch(cts_exc.classname()) + + # def end_catch(self, target_label): + # self.ilasm.leave(target_label) + # self.ilasm.end_catch() + + # def render_raise_block(self, block): + # exc = block.inputargs[1] + # self.load(exc) + # self.ilasm.opcode('throw') + + # def store_exception_and_link(self, link): + # if self._is_raise_block(link.target): + # # the exception value is on the stack, use it as the 2nd target arg + # assert len(link.args) == 2 + # assert len(link.target.inputargs) == 2 + # self.store(link.target.inputargs[1]) + # else: + # # the exception value is on the stack, store it in the proper place + # if isinstance(link.last_exception, flowmodel.Variable): + # self.ilasm.opcode('dup') + # self.store(link.last_exc_value) + # self.ilasm.call_method( + # 'class [mscorlib]System.Type object::GetType()', + # virtual=True) + # self.store(link.last_exception) + # else: + # self.store(link.last_exc_value) + # self._setup_link(link) + + # 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 + # # 32bit, and perform a cast in that case + # self.render_numeric_switch_naive(block) + # return + + # cases, min_case, max_case, default = self._collect_switch_cases(block) + # is_sparse = self._is_sparse_switch(cases, min_case, max_case) + + # naive = (min_case < 0) or is_sparse + # if naive: + # self.render_numeric_switch_naive(block) + # return + + # targets = [] + # for i in xrange(max_case+1): + # link, lbl = cases.get(i, default) + # targets.append(lbl) + # self.generator.load(block.exitswitch) + # self.ilasm.switch(targets) + # self.render_switch_case(*default) + # for link, lbl in cases.itervalues(): + # self.render_switch_case(link, lbl) + + # def call_oostring(self, ARGTYPE): + # if isinstance(ARGTYPE, ootype.Instance): + # argtype = self.cts.types.object + # else: + # argtype = self.cts.lltype_to_cts(ARGTYPE) + # self.call_signature('string [pypylib]pypy.runtime.Utils::OOString(%s, int32)' % argtype) + + # def call_oounicode(self, ARGTYPE): + # argtype = self.cts.lltype_to_cts(ARGTYPE) + # self.call_signature('string [pypylib]pypy.runtime.Utils::OOUnicode(%s)' % argtype) + + # Those parts of the generator interface that are function + # specific Modified: pypy/branch/avm/pypy/translator/avm1/metavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/metavm.py (original) +++ pypy/branch/avm/pypy/translator/avm1/metavm.py Thu Aug 13 00:29:31 2009 @@ -45,6 +45,35 @@ generator.load(arg) generator.push_const(len(args)) +class _CallMethod(MicroInstruction): + def render(self, generator, op): + args = op.args + method_name = args[0].value + this = args[1] + + if isinstance(this.concretetype, ootype.Array): + for arg in args[1:]: + generator.load(arg) + if method_name == "ll_setitem_fast": + generator.set_member() + generator.push_const(False) # Spoof a method call result + elif method_name == "ll_getitem_fast": + generator.get_member() + elif method_name == "ll_length": + generator.load("length") + generator.get_member() + else: + assert False + else: + if len(args) > 2: + for arg in args[2:]: + generator.load(arg) + generator.push_const(len(args)-2) + else: + generator.push_const(0) + generator.load(this) + generator.call_method_n(method_name) + class CallConstantMethod(MicroInstruction): def __init__(self, obj, func_name): self.obj = obj @@ -66,3 +95,4 @@ StoreResultEnd = _StoreResultEnd() GetField = _GetField() SetField = _SetField() +CallMethod = _CallMethod() Modified: pypy/branch/avm/pypy/translator/avm1/opcodes.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/opcodes.py (original) +++ pypy/branch/avm/pypy/translator/avm1/opcodes.py Thu Aug 13 00:29:31 2009 @@ -9,7 +9,8 @@ 'runtimenew': [om.RuntimeNew], 'oosetfield': [am.SetField], 'oogetfield': [am.GetField], -# 'oosend': am.CallMethod + 'oonewarray': [om.OONewArray], + 'oosend': [am.CallMethod], } unary_ops = { Modified: pypy/branch/avm/pypy/translator/avm1/test/browsertest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/browsertest.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/browsertest.py Thu Aug 13 00:29:31 2009 @@ -1,6 +1,7 @@ from BaseHTTPServer import HTTPServer as BaseHTTPServer, BaseHTTPRequestHandler from cgi import parse_qs +import time import webbrowser class HTTPServer(BaseHTTPServer): @@ -30,8 +31,12 @@ return True elif string == "false": return False - elif all(c in "0123456789-" for c in string): + elif string == "undefined" or string == "null": + return None + elif all(c in "123456789-" for c in string): return int(string) + elif "," in string: + return [parse_result(s) for s in string.split(",")] return string class TestCase(object): @@ -57,10 +62,9 @@ self.serve_data(mime, data) def do_POST(self): - print self.path if self.path == "/test.result": form = parse_qs(self.rfile.read(int(self.headers['content-length']))) - self.server.testcase.result = parse_result(form['result'][0]) + self.server.testcase.result = form['result'][0] def serve_data(self, content_type, data): self.send_response(200) @@ -79,7 +83,10 @@ def get_result(self): testcase = self.httpd.testcase + start_time = time.time() while testcase.result is None: + if time.time() - start_time > 10: + assert False self.httpd.handle_request() return testcase.result @@ -89,4 +96,4 @@ driver.start_server(config.http_port, testcase) webbrowser.open('http://localhost:%d/test.html' % config.http_port) - return driver.get_result() + return parse_result(driver.get_result()) Added: pypy/branch/avm/pypy/translator/avm1/test/mylib.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/mylib.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,5 @@ +from pypy.translator.cli.carbonpython import export + + at export(int, int) +def sum(a, b): + return a+b Added: pypy/branch/avm/pypy/translator/avm1/test/runtest2.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/runtest2.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,213 @@ + +import py, re, subprocess +from pypy.translator.translator import TranslationContext +from pypy.translator.avm.test.browsertest import browsertest +# from pypy.translator.backendopt.all import backend_optimizations +# from pypy.translator.js.js import JS +# from pypy.translator.js.test.browsertest import jstest +# from pypy.translator.js import conftest +#from pypy.translator.js.log import log +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 + +log = log.runtest + +port = 8080 + +class AVMException(LLException): + pass + +#def _CLI_is_on_path(): +# if py.path.local.sysfind('js') is None: #we recommend Spidermonkey +# return False +# return True + +class compile_function(object): + def __init__(self, function, annotations, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True, policy = None): + + self.html = html + self.is_interactive = is_interactive + t = TranslationContext() + + if policy is None: + from pypy.annotation.policy import AnnotatorPolicy + policy = AnnotatorPolicy() + policy.allow_someobjects = False + + ann = t.buildannotator(policy=policy) + ann.build_types(function, annotations) + if view or option.view: + t.view() + t.buildrtyper(type_system="ootype").specialize() + + if view or option.view: + t.view() + #self.js = JS(t, [function, callback_function], stackless) + self.js = JS(t, function, stackless) + self.js.write_source() + if root is None and use_tg: + from pypy.translator.js.demo.jsdemo.controllers import Root + self.root = Root + else: + self.root = root + self.run_browser = run_browser + self.function_calls = [] + + def source(self): + return self.js.tmpfile.open().read() + + def _conv(self, v): + if isinstance(v, str): + return repr(v) + return str(v).lower() + + def __call__(self, *kwds): + return self.call(None, kwds) + + def call(self, entry_function, kwds): + args = ', '.join([self._conv(kw) for kw in kwds]) #lowerstr for (py)False->(js)false, etc. + + if entry_function is None: + entry_function = self.js.translator.graphs[0].name + else: + entry_function = self.js.translator.annotator.bookkeeper.getdesc(entry_function).cached_graph(None) + function_call = "%s(%s)" % (entry_function, args) + self.function_calls.append(function_call) + #if self.js.stackless: + # function_call = "slp_entry_point('%s')" % function_call + + if use_browsertest: + if not use_tg: + log("Used html: %r" % self.html) + output = browsertest(self.js.filename, function_call) + else: + global port + from pypy.translator.js.test.tgtest import run_tgtest + out = run_tgtest(self, tg_root = self.root, port=port, run_browser=self.run_browser).results + assert out[1] == 'undefined' or out[1] == "" + output = out[0] + port += 1 + return self.reinterpret(output) + else: +# cmd = 'echo "load(\'%s\'); print(%s)" | js 2>&1' % (self.js.filename, function_call) +# log(cmd) +# output = os.popen(cmd).read().strip() + js = subprocess.Popen(["js"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + 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] + js.stdin.write(input) + stdout, stderr = js.communicate() + output = (stderr + stdout).strip() + for s in output.split('\n'): + log(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 + if s == 'false': + res = False + elif s == 'true': + res = True + elif s == 'undefined': + res = None + elif s == 'inf': + res = 1e300 * 1e300 + elif s == 'NaN': + res = (1e300 * 1e300) / (1e300 * 1e300) + elif s.startswith('[') or s.startswith('('): + l = s[1:-1].split(',') + res = [cls.reinterpret(i) for i in l] + else: + try: + res = float(s) + if float(int(res)) == res: + return int(res) + except ValueError: + res = str(s) + return res + reinterpret = classmethod(reinterpret) + +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 + res = _fn(%s) + if isinstance(res, type(None)): + return None + else: + return str(res)""" + % (func_name, ",".join(["%s=NonConstant(%r)" % (name, i) for + name, i in zip(argnames, args)]))) + exec source.compile() in locals() + 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) + res = f(*args) + return res + + def interpret_raises(self, exception, fn, args): + #import exceptions # needed by eval + #try: + #import pdb; pdb.set_trace() + try: + res = self.interpret(fn, args) + except JSException, e: + s = e.args[0] + assert s.startswith('uncaught exception:') + assert re.search(exception.__name__, s) + else: + raise AssertionError("Did not raise, returned %s" % res) + #except ExceptionWrapper, ex: + # assert issubclass(eval(ex.class_name), exception) + #else: + # assert False, 'function did raise no exception at all' + + def ll_to_string(self, s): + return str(s) + + def ll_to_list(self, l): + return l + + def ll_unpack_tuple(self, t, length): + assert len(t) == length + return tuple(t) + + def class_name(self, value): + return value[:-8].split('.')[-1] + + def is_of_instance_type(self, val): + m = re.match("^<.* object>$", val) + return bool(m) + + def read_attr(self, obj, name): + py.test.skip('read_attr not supported on genjs tests') + +def check_source_contains(compiled_function, pattern): + import re + + source = compiled_function.js.tmpfile.open().read() + return re.search(pattern, source) Added: pypy/branch/avm/pypy/translator/avm1/test/simpletest.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/simpletest.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,17 @@ + +from pypy.translator.avm.swf import SwfData +from pypy.translator.avm.tags import SetBackgroundColor, DefineShape, End +from pypy.translator.avm.records import ShapeWithStyle, LineStyle, StraightEdgeRecord, StyleChangeRecord + +linestyle = LineStyle(3, 0x000000) + +shape = ShapeWithStyle() +shape.add_line_style(linestyle) +shape.add_shape_record(StyleChangeRecord(20, 20, linestyle)) +shape.add_shape_record(StraightEdgeRecord(100, 100)) + +swf = SwfData(400, 300) +swf.add_tag(SetBackgroundColor(0x333333)) +swf.add_tag(DefineShape(shape)) +swf.add_tag(End()) +print swf.serialize() Added: pypy/branch/avm/pypy/translator/avm1/test/test_backendopt.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_backendopt.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,7 @@ +import py +from pypy.translator.cli.test.runtest import compile_function +from pypy.translator.oosupport.test_template.backendopt import BaseTestOptimizedSwitch + +class TestOptimizedSwitch(BaseTestOptimizedSwitch): + def getcompiled(self, fn, annotation): + return compile_function(fn, annotation, backendopt=True) Added: pypy/branch/avm/pypy/translator/avm1/test/test_bool.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_bool.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,7 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rbool import BaseTestRbool + +class TestCliBool(CliTest, BaseTestRbool): + pass + Added: pypy/branch/avm/pypy/translator/avm1/test/test_builtin.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_builtin.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,29 @@ +import platform +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.builtin import BaseTestBuiltin, BaseTestTime + + +def skip_os(self): + py.test.skip("CLI doesn't support the os module, yet") + +def skip_win(): + if platform.system() == 'Windows': + py.test.skip("Doesn't work on Windows, yet") + +class TestCliBuiltin(CliTest, BaseTestBuiltin): + test_os_path_exists = skip_os + test_os_isdir = skip_os + test_os_dup_oo = skip_os + test_os_access = skip_os + + def test_builtin_math_frexp(self): + self._skip_powerpc("Mono math floating point problem") + BaseTestBuiltin.test_builtin_math_frexp(self) + + def test_debug_llinterpcall(self): + py.test.skip("so far, debug_llinterpcall is only used on lltypesystem") + + +class TestCliTime(CliTest, BaseTestTime): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_carbonpython.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_carbonpython.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,175 @@ +import py +py.test.skip("it passes usually, but fails on buildbot, no clue why") + +import os +import os.path +from pypy.tool import udir +from pypy.translator.cli.rte import Target +from pypy.translator.cli.carbonpython import DllDef, export, collect_entrypoints,\ + collect_class_entrypoints, compile_dll +from pypy.translator.cli.test.runtest import CliFunctionWrapper, CliTest + +TEMPLATE = """ +using System; +using System.Collections; +class CarbonPytonTest { + public static void Main() { + %s + } +} +""" + +class TestCarbonPython(CliTest): + + def _csharp(self, source, references=[], netmodules=[]): + tmpfile = udir.udir.join('tmp.cs') + tmpfile.write(TEMPLATE % source) + flags = ['/r:%s' % ref for ref in references] + flags += ['/addmodule:%s' % mod for mod in netmodules] + + class MyTarget(Target): + SOURCES = [str(tmpfile)] + FLAGS = flags + OUTPUT = 'tmp.exe' + SRC_DIR = str(udir.udir) + + func = CliFunctionWrapper(MyTarget.get()) + return func() + + def test_compilation(self): + res = self._csharp('Console.WriteLine(42);') + assert res == 42 + + def test_func_namespace(self): + def foo(x): + return x+1 + def bar(x): + return foo(x) + foo._namespace_ = 'MyNamespace.MyClass' + bar._namespace_ = 'MyClass' + res = self.interpret(bar, [41], backendopt=False) + assert res == 42 + + def test_simple_functions(self): + def foo(x): + return x+1 + def bar(x): + return x*2 + dll = DllDef('test', 'Test', [(foo, [int]), + (bar, [int])]) + dll.compile() + res = self._csharp('Console.WriteLine("{0}, {1}", Test.foo(42), Test.bar(42));', ['test']) + assert res == (43, 84) + + def test_export(self): + @export(int, float) + def foo(x, y): + pass + @export(int, float, namespace='test') + def bar(x, y): + pass + @export + def baz(): + pass + + assert foo._inputtypes_ == (int, float) + assert not hasattr(foo, '_namespace_') + assert bar._inputtypes_ == (int, float) + assert bar._namespace_ == 'test' + assert baz._inputtypes_ == () + + def test_collect_entrypoints(self): + @export(int, float) + def foo(x, y): + pass + def bar(x, y): + pass + mydict = dict(foo=foo, bar=bar, x=42) + entrypoints = collect_entrypoints(mydict) + assert entrypoints == [(foo, (int, float))] + + def test_collect_class_entrypoints(self): + class NotExported: + def __init__(self): + pass + + class MyClass: + @export + def __init__(self): + pass + @export(int) + def foo(self, x): + return x + + assert collect_class_entrypoints(NotExported) == [] + entrypoints = collect_class_entrypoints(MyClass) + assert len(entrypoints) == 2 + assert entrypoints[0][1] == () # __init__ inputtypes + assert entrypoints[1][1] == (MyClass, int) # foo inputtypes + + def test_compile_class(self): + py.test.skip('This test fails every other day. No clue why :-(') + class MyClass: + @export(int) + def __init__(self, x): + self.x = x + @export(int, int) + def add(self, y, z): + return self.x + y + z + MyClass.__module__ = 'Test' # put the class in the Test namespace + + entrypoints = collect_entrypoints({'MyClass': MyClass}) + dll = DllDef('test', 'Test', entrypoints) + dll.compile() + res = self._csharp(""" + Test.MyClass obj = new Test.MyClass(); + obj.__init__(39); + Console.WriteLine(obj.add(1, 2)); + """, ['test']) + assert res == 42 + + def test_export_cliclass(self): + py.test.skip('it fails every other day on builbot, no clue why') + from pypy.translator.cli.dotnet import CLR + + @export(CLR.System.Collections.ArrayList, int) + def getitem(obj, i): + return obj.get_Item(i) + + entrypoints = collect_entrypoints({'getitem': getitem}) + dll = DllDef('test', 'Test', entrypoints) + dll.compile() + res = self._csharp(""" + ArrayList obj = new ArrayList(); + obj.Add(42); + Console.WriteLine(Test.getitem(obj, 0)); + """, ['test']) + assert res == 42 + + def test_compile_dll(self): + py.test.skip('This test fails every other day. No clue why :-(') + cwd, _ = os.path.split(__file__) + mylib_py = os.path.join(cwd, 'mylib.py') + compile_dll(mylib_py, copy_dll=False) + res = self._csharp(""" + Console.WriteLine(mylib.sum(20, 22)); + """, ['mylib']) + assert res == 42 + + def test_compile_dll_alternative_name(self): + cwd, _ = os.path.split(__file__) + mylib_py = os.path.join(cwd, 'mylib.py') + compile_dll(mylib_py, 'mylibxxx.dll', copy_dll=False) + res = self._csharp(""" + Console.WriteLine(mylibxxx.sum(20, 22)); + """, ['mylibxxx']) + assert res == 42 + + def test_compile_netmodule(self): + def foo(x): + return x+1 + dll = DllDef('mymodule', 'Test', [(foo, [int])], isnetmodule=True) + dll.compile() + res = self._csharp('Console.WriteLine("{0}", Test.foo(41));', + netmodules = ['mymodule']) + Added: pypy/branch/avm/pypy/translator/avm1/test/test_cast.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_cast.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,5 @@ +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.cast import BaseTestCast + +class TestCast(BaseTestCast, CliTest): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_class.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_class.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,11 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.class_ import BaseTestClass, BaseTestSpecialcase + +# ====> ../../oosupport/test_template/class_.py + +class TestCliClass(CliTest, BaseTestClass): + pass + +class TestCliSpecialCase(CliTest, BaseTestSpecialcase): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_constant.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_constant.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,5 @@ +from pypy.translator.oosupport.test_template.constant import BaseTestConstant +from pypy.translator.cli.test.runtest import CliTest + +class TestConstant(BaseTestConstant, CliTest): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_cts.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_cts.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,24 @@ +from pypy.translator.cli import cts + +def test_primitive(): + void = cts.CliPrimitiveType('void') + assert str(void) == void.typename() == 'void' + assert void == cts.CliPrimitiveType('void') + +def test_class(): + Math = cts.CliClassType('mscorlib', 'System.Math') + assert str(Math) == Math.typename() == 'class [mscorlib]System.Math' + assert Math.classname() == '[mscorlib]System.Math' + assert Math == cts.CliClassType('mscorlib', 'System.Math') + +def test_generic(): + Dict = cts.CliGenericType('mscorlib', 'System.Dict', 2) + assert str(Dict) == Dict.typename() == 'class [mscorlib]System.Dict`2' + + int32 = cts.CliPrimitiveType('int32') + Math = cts.CliClassType('mscorlib', 'System.Math') + MyDict = Dict.specialize(int32, Math) + assert isinstance(MyDict, cts.CliSpecializedType) + classname = '[mscorlib]System.Dict`2' + assert str(MyDict) == MyDict.typename() == 'class ' + classname + assert MyDict.classname() == classname Added: pypy/branch/avm/pypy/translator/avm1/test/test_dict.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_dict.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,24 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +import pypy.translator.oosupport.test_template.dict as oodict + +class TestCliDict(CliTest, oodict.BaseTestDict): + def test_dict_of_dict(self): + py.test.skip("CLI doesn't support recursive dicts") + + def test_recursive(self): + py.test.skip("CLI doesn't support recursive dicts") + + def test_dict_of_void_special_case(self): + def fn(n): + d = {} + for i in xrange(n): + d[i] = None + return d[0] + assert self.interpret(fn, [2]) is None + +class TestCliEmptyDict(CliTest, oodict.BaseTestEmptyDict): + pass + +class TestCliConstantDict(CliTest, oodict.BaseTestConstantDict): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_dotnet.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_dotnet.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,711 @@ +import py +from pypy.annotation.annrpython import RPythonAnnotator +from pypy.annotation import model as annmodel +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.ootypesystem.ootype import meth, Meth, Char, Signed, Float, String,\ + ROOT, overload, Instance, new +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\ + NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException,\ + native_exc, new_array, init_array, typeof, eventhandler, clidowncast,\ + fieldinfo_for_const, classof, cast_record_to_object, cast_object_to_record + +System = CLR.System +ArrayList = CLR.System.Collections.ArrayList +OpCodes = System.Reflection.Emit.OpCodes +DynamicMethod = System.Reflection.Emit.DynamicMethod +Utils = CLR.pypy.runtime.Utils +FUNCTYPE = ootype.StaticMethod([ootype.Signed, ootype.Signed], ootype.Signed) + +class TestDotnetAnnotation(object): + + def test_overloaded_meth_string(self): + C = Instance("test", ROOT, {}, + {'foo': overload(meth(Meth([Char], Signed)), + meth(Meth([String], Float)), + resolver=OverloadingResolver), + 'bar': overload(meth(Meth([Signed], Char)), + meth(Meth([Float], String)), + resolver=OverloadingResolver)}) + def fn1(): + return new(C).foo('a') + def fn2(): + return new(C).foo('aa') + def fn3(x): + return new(C).bar(x) + a = RPythonAnnotator() + assert isinstance(a.build_types(fn1, []), annmodel.SomeInteger) + assert isinstance(a.build_types(fn2, []), annmodel.SomeFloat) + assert isinstance(a.build_types(fn3, [int]), annmodel.SomeChar) + assert isinstance(a.build_types(fn3, [float]), annmodel.SomeString) + + def test_class(self): + def fn(): + return System.Math + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, SomeCliClass) + assert s.const is System.Math + + def test_fullname(self): + def fn(): + return CLR.System.Math + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, SomeCliClass) + assert s.const is System.Math + + def test_staticmeth(self): + def fn(): + return System.Math.Abs + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, SomeCliStaticMethod) + assert s.cli_class is System.Math + assert s.meth_name == 'Abs' + + def test_staticmeth_call(self): + def fn1(): + return System.Math.Abs(42) + def fn2(): + return System.Math.Abs(42.5) + a = RPythonAnnotator() + assert type(a.build_types(fn1, [])) is annmodel.SomeInteger + assert type(a.build_types(fn2, [])) is annmodel.SomeFloat + + def test_new_instance(self): + def fn(): + return ArrayList() + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeOOInstance) + assert isinstance(s.ootype, NativeInstance) + assert s.ootype._name == '[mscorlib]System.Collections.ArrayList' + + def test_box(self): + def fn(): + return box(42) + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.ootype._name == '[mscorlib]System.Object' + assert not s.can_be_None + + def test_box_can_be_None(self): + def fn(flag): + if flag: + return box(42) + else: + return box(None) + a = RPythonAnnotator() + s = a.build_types(fn, [bool]) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.ootype._name == '[mscorlib]System.Object' + assert s.can_be_None + + def test_unbox(self): + def fn(): + x = box(42) + return unbox(x, ootype.Signed) + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeInteger) + + def test_unbox_can_be_None(self): + class Foo: + pass + def fn(): + x = box(42) + return unbox(x, Foo) + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeInstance) + assert s.can_be_None + + def test_array(self): + def fn(): + x = ArrayList() + return x.ToArray() + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.ootype._isArray + assert s.ootype._ELEMENT._name == '[mscorlib]System.Object' + + def test_array_getitem(self): + def fn(): + x = ArrayList().ToArray() + return x[0] + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.ootype._name == '[mscorlib]System.Object' + + def test_mix_None_and_instance(self): + def fn(x): + if x: + return None + else: + return box(42) + a = RPythonAnnotator() + s = a.build_types(fn, [bool]) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.can_be_None == True + + def test_box_instance(self): + class Foo: + pass + def fn(): + return box(Foo()) + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeOOInstance) + assert s.ootype._name == '[mscorlib]System.Object' + + def test_unbox_instance(self): + class Foo: + pass + def fn(): + boxed = box(Foo()) + return unbox(boxed, Foo) + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeInstance) + assert s.classdef.name.endswith('Foo') + + def test_can_be_None(self): + def fn(): + ttype = System.Type.GetType('foo') + return ttype.get_Namespace() + a = RPythonAnnotator() + s = a.build_types(fn, []) + assert isinstance(s, annmodel.SomeString) + assert s.can_be_None + + +class TestDotnetRtyping(CliTest): + def _skip_pythonnet(self, msg): + pass + + def test_staticmeth_call(self): + def fn(x): + return System.Math.Abs(x) + assert self.interpret(fn, [-42]) == 42 + + def test_staticmeth_overload(self): + self._skip_pythonnet('Pythonnet bug!') + def fn(x, y): + return System.Math.Abs(x), System.Math.Abs(y) + res = self.interpret(fn, [-42, -42.5]) + item0, item1 = self.ll_to_tuple(res) + assert item0 == 42 + assert item1 == 42.5 + + def test_tostring(self): + StringBuilder = CLR.System.Text.StringBuilder + def fn(): + x = StringBuilder() + x.Append(box("foo")).Append(box("bar")) + return x.ToString() + res = self.ll_to_string(self.interpret(fn, [])) + assert res == 'foobar' + + def test_box(self): + def fn(): + x = ArrayList() + x.Add(box(42)) + x.Add(box('Foo')) + return x.get_Count() + assert self.interpret(fn, []) == 2 + + def test_whitout_box(self): + def fn(): + x = ArrayList() + x.Add(42) # note we have forgot box() + py.test.raises(TypeError, self.interpret, fn, []) + + def test_unbox(self): + def fn(): + x = ArrayList() + x.Add(box(42)) + return unbox(x.get_Item(0), ootype.Signed) + assert self.interpret(fn, []) == 42 + + def test_unbox_string(self): + def fn(): + x = ArrayList() + x.Add(box('foo')) + return unbox(x.get_Item(0), ootype.String) + assert self.interpret(fn, []) == 'foo' + + def test_box_method(self): + def fn(): + x = box(42) + t = x.GetType() + return t.get_Name() + res = self.interpret(fn, []) + assert res == 'Int32' + + def test_box_object(self): + def fn(): + return box(System.Object()).ToString() + res = self.interpret(fn, []) + assert res == 'System.Object' + + def test_array(self): + def fn(): + x = ArrayList() + x.Add(box(42)) + array = x.ToArray() + return unbox(array[0], ootype.Signed) + assert self.interpret(fn, []) == 42 + + def test_new_array(self): + def fn(): + x = new_array(System.Object, 2) + x[0] = box(42) + x[1] = box(43) + return unbox(x[0], ootype.Signed) + unbox(x[1], ootype.Signed) + assert self.interpret(fn, []) == 42+43 + + def test_init_array(self): + def fn(): + x = init_array(System.Object, box(42), box(43)) + return unbox(x[0], ootype.Signed) + unbox(x[1], ootype.Signed) + assert self.interpret(fn, []) == 42+43 + + def test_array_setitem_None(self): + py.test.skip('Mono bug :-(') + def fn(): + x = init_array(System.Object, box(42), box(43)) + x[0] = None + return x[0] + assert self.interpret(fn, []) is None + + def test_array_length(self): + def fn(): + x = init_array(System.Object, box(42), box(43)) + return len(x) + assert self.interpret(fn, []) == 2 + + def test_null(self): + def fn(): + return System.Object.Equals(None, None) + assert self.interpret(fn, []) == True + + def test_null_bound_method(self): + def fn(): + x = ArrayList() + x.Add(None) + return x.get_Item(0) + assert self.interpret(fn, []) is None + + def test_native_exception_precise(self): + ArgumentOutOfRangeException = NativeException(CLR.System.ArgumentOutOfRangeException) + def fn(): + x = ArrayList() + try: + x.get_Item(0) + return False + except ArgumentOutOfRangeException: + return True + assert self.interpret(fn, []) == True + + def test_native_exception_superclass(self): + SystemException = NativeException(CLR.System.Exception) + def fn(): + x = ArrayList() + try: + x.get_Item(0) + return False + except SystemException: + return True + assert self.interpret(fn, []) == True + + def test_native_exception_object(self): + SystemException = NativeException(CLR.System.Exception) + def fn(): + x = ArrayList() + try: + x.get_Item(0) + return "Impossible!" + except SystemException, e: + ex = native_exc(e) + return ex.get_Message() + res = self.ll_to_string(self.interpret(fn, [])) + assert res.startswith("Index is less than 0") + + def test_native_exception_invoke(self): + TargetInvocationException = NativeException(CLR.System.Reflection.TargetInvocationException) + def fn(): + x = ArrayList() + t = x.GetType() + meth = t.GetMethod('get_Item') + args = init_array(System.Object, box(0)) + try: + meth.Invoke(x, args) + return "Impossible!" + except TargetInvocationException, e: + inner = native_exc(e).get_InnerException() + message = str(inner.get_Message()) + return message + res = self.ll_to_string(self.interpret(fn, [])) + assert res.startswith("Index is less than 0") + + def test_typeof(self): + def fn(): + x = box(42) + return x.GetType() == typeof(System.Int32) + res = self.interpret(fn, []) + assert res is True + + def test_typeof_pypylib(self): + DelegateType = CLR.pypy.test.DelegateType_int__int_2 + def fn(): + return typeof(DelegateType) is not None + res = self.interpret(fn, []) + assert res is True + + def test_typeof_functype(self): + # this test is overridden in TestPythonnet + def fn(): + t = typeof(FUNCTYPE) + return t.get_Name() + res = self.interpret(fn, []) + assert res.startswith('StaticMethod__') + + def test_clidowncast(self): + def fn(): + a = ArrayList() + b = ArrayList() + a.Add(b) + c = a.get_Item(0) # type of c is Object + c = clidowncast(c, ArrayList) + c.Add(None) + return c.get_Item(0) + res = self.interpret(fn, []) + assert res is None + + def test_clidowncast_lltype(self): + ARRAY_LIST = ArrayList._INSTANCE + def fn(): + a = ArrayList() + b = ArrayList() + a.Add(b) + c = a.get_Item(0) # type of c is Object + c = clidowncast(c, ARRAY_LIST) + c.Add(None) + return c.get_Item(0) + res = self.interpret(fn, []) + assert res is None + + def test_mix_None_and_instance(self): + def g(x): + return x + def fn(flag): + if flag: + x = None + else: + x = box(42) + return g(x) + res = self.interpret(fn, [1]) + assert res is None + + def test_box_unbox_instance(self): + class Foo: + pass + def fn(): + obj = Foo() + b_obj = box(obj) + obj2 = unbox(b_obj, Foo) + return obj is obj2 + res = self.interpret(fn, []) + assert res is True + + def test_unbox_instance_fail(self): + class Foo: + pass + def fn(): + b_obj = box(42) + return unbox(b_obj, Foo) + res = self.interpret(fn, []) + assert res is None + + def test_box_unbox_ooinstance(self): + A = ootype.Instance('A', ootype.ROOT, {'xx': ootype.Signed}) + def fn(flag): + a = ootype.new(A) + a.xx = 42 + b_obj = box(a) + a2 = unbox(b_obj, A) + return a2.xx + res = self.interpret(fn, [True]) + assert res == 42 + + def test_box_unbox_ooinstance_fail(self): + A = ootype.Instance('A', ootype.ROOT, {'xx': ootype.Signed}) + def fn(flag): + b_obj = System.Object() + a2 = unbox(b_obj, A) + return a2 + res = self.interpret(fn, [True]) + assert res is None + + def test_box_unbox_oorecord(self): + A = ootype.Record({'xx': ootype.Signed}) + def fn(flag): + a = ootype.new(A) + a.xx = 42 + b_obj = box(a) + a2 = unbox(b_obj, A) + return a2.xx + res = self.interpret(fn, [True]) + assert res == 42 + + def test_instance_wrapping(self): + class Foo: + pass + def fn(): + obj = Foo() + x = ArrayList() + x.Add(box(obj)) + obj2 = unbox(x.get_Item(0), Foo) + return obj is obj2 + res = self.interpret(fn, []) + assert res is True + + def test_compare_string_None(self): + from pypy.rlib.nonconst import NonConstant + def null(): + if NonConstant(True): + return None + else: + return "" + + def fn(): + ttype = System.Type.GetType('Consts, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') + namespace = ttype.get_Namespace() + if namespace is not None: + return False + else: + return True + res = self.interpret(fn, [], backendopt=False) + assert res is True + + def test_delegate(self): + class Foo: + def __init__(self): + self.x = 0 + def m(self, sender, args): + self.x = 42 + + def fn(flag): + f = Foo() + if flag: + f.m(None, None) + delegate = eventhandler(f.m) + delegate.Invoke(None, None) + return f.x + res = self.interpret(fn, [False]) + assert res == 42 + + def test_static_fields(self): + DummyClass = CLR.pypy.test.DummyClass + def fn(): + obj = System.Object() + DummyClass.myfield = obj + return DummyClass.myfield is obj + res = self.interpret(fn, []) + assert res + + def test_pypylib(self): + def fn(): + return CLR.pypy.runtime.Utils.OOString(42, -1) + res = self.interpret(fn, []) + assert self.ll_to_string(res) == '42' + + def test_call_delegate(self): + def build_fn(): + tInt = typeof(System.Int32) + args = init_array(System.Type, tInt, tInt) + meth = Utils.CreateDynamicMethod("add", tInt, args) + il = meth.GetILGenerator() + il.Emit(OpCodes.Ldarg_0) + il.Emit(OpCodes.Ldarg_1) + il.Emit(OpCodes.Add) + il.Emit(OpCodes.Ret) + myfunc = meth.CreateDelegate(typeof(FUNCTYPE)) + return myfunc + + def fn(x, y): + myfunc = unbox(build_fn(), FUNCTYPE) + a = myfunc(x, y) + mytuple = (x, y) + b = myfunc(*mytuple) + return a+b + res = self.interpret(fn, [10, 11]) + assert res == 42 + + def test_bound_delegate(self): + def build_fn(): + tObjArray = System.Type.GetType("System.Object[]") + tInt = typeof(System.Int32) + args = init_array(System.Type, tObjArray, tInt, tInt) + meth = Utils.CreateDynamicMethod("add", tInt, args) + il = meth.GetILGenerator() + il.Emit(OpCodes.Ldarg_1) + il.Emit(OpCodes.Ldarg_2) + il.Emit(OpCodes.Add) + il.Emit(OpCodes.Ret) + array = new_array(System.Object, 0) + myfunc = meth.CreateDelegate(typeof(FUNCTYPE), array) + return myfunc + + def fn(): + myfunc = unbox(build_fn(), FUNCTYPE) + return myfunc(30, 12) + res = self.interpret(fn, []) + assert res == 42 + + def test_valuetype_field(self): + class Foo: + def __init__(self, x): + self.x = x + + def fn(): + f = Foo(OpCodes.Add) + return f + self.interpret(fn, []) + + def test_fieldinfo_for_const(self): + A = ootype.Instance('A', ootype.ROOT, {'xx': ootype.Signed}) + const = ootype.new(A) + const.xx = 42 + def fn(): + fieldinfo = fieldinfo_for_const(const) + obj = fieldinfo.GetValue(None) + # get the 'xx' field by using reflection + t = obj.GetType() + x_info = t.GetField('xx') + x_value = x_info.GetValue(obj) + return unbox(x_value, ootype.Signed) + res = self.interpret(fn, []) + assert res == 42 + + def test_fieldinfo_for_const_pbc(self): + A = ootype.Instance('A', ootype.ROOT, {'xx': ootype.Signed}) + const = ootype.new(A) + fieldinfo = fieldinfo_for_const(const) + def fn(): + const.xx = 42 + obj = fieldinfo.GetValue(None) + # get the 'xx' field by using reflection + t = obj.GetType() + x_info = t.GetField('xx') + x_value = x_info.GetValue(obj) + return unbox(x_value, ootype.Signed) + res = self.interpret(fn, []) + assert res == 42 + + def test_classof(self): + int32_class = classof(System.Int32) + def fn(): + int32_obj = box(int32_class) + int32_type = clidowncast(int32_obj, System.Type) + return int32_type.get_Name() + assert self.interpret(fn, []) == 'Int32' + + def test_classof_compare(self): + int32_a = classof(System.Int32) + int32_b = classof(System.Int32) + def fn(): + return int32_a is int32_b + assert self.interpret(fn, []) + + def test_classof_functype(self): + # this test is overridden in TestPythonnet + c = classof(FUNCTYPE) + def fn(): + obj = box(c) + t = clidowncast(obj, System.Type) + return t.get_Name() + res = self.interpret(fn, []) + assert res.startswith('StaticMethod__') + + def test_mix_classof(self): + a = classof(System.Int32) + b = classof(FUNCTYPE) + def fn(flag): + if flag: + x = a + else: + x = b + return clidowncast(box(x), System.Type).get_Name() + res = self.interpret(fn, [True]) + assert res == 'Int32' + + def test_cast_record(self): + T = ootype.Record({'x': ootype.Signed}) + record = ootype.new(T) + def fn(flag): + if flag: + obj = cast_record_to_object(record) + else: + obj = System.Object() + record2 = cast_object_to_record(T, obj) + return record is record2 + res = self.interpret(fn, [True]) + assert res + + def test_cast_record_pbc(self): + T = ootype.Record({'x': ootype.Signed}) + record = ootype.new(T) + record.x = 42 + obj = cast_record_to_object(record) + def fn(): + record2 = cast_object_to_record(T, obj) + return record is record2 + res = self.interpret(fn, []) + assert res + + def test_cast_record_mix_object(self): + T = ootype.Record({'x': ootype.Signed}) + NULL = ootype.null(System.Object._INSTANCE) + record = cast_record_to_object(ootype.new(T)) + assert record != NULL + assert NULL != record + + +class TestPythonnet(TestDotnetRtyping): + # don't interpreter functions but execute them directly through pythonnet + def interpret(self, f, args, backendopt='ignored'): + return f(*args) + + def _skip_pythonnet(self, msg): + py.test.skip(msg) + + def test_whitout_box(self): + pass # it makes sense only during translation + + def test_typeof_functype(self): + def fn(): + t = typeof(FUNCTYPE) + return t.get_Name() + res = self.interpret(fn, []) + assert res == 'DelegateType_int__int_2' + + def test_classof_functype(self): + # this test is overridden in TestPythonnet + c = classof(FUNCTYPE) + def fn(): + obj = box(c) + t = clidowncast(obj, System.Type) + return t.get_Name() + res = self.interpret(fn, []) + assert res == 'DelegateType_int__int_2' + + def test_fieldinfo_for_const(self): + pass # it makes sense only during translation + + def test_fieldinfo_for_const_pbc(self): + pass # it makes sense only during translation Added: pypy/branch/avm/pypy/translator/avm1/test/test_exception.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_exception.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,22 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.exception import BaseTestException + +class TestCliException(CliTest, BaseTestException): + use_exception_transformer = False + backendopt = False + + def interpret(self, *args, **kwds): + kwds['exctrans'] = self.use_exception_transformer + return CliTest.interpret(self, *args, **kwds) + + def test_raise_and_catch_other(self): + pass + + def test_raise_prebuilt_and_catch_other(self): + pass + + +class TestCliExceptionTransformer(TestCliException): + use_exception_transformer = True + backendopt = False Added: pypy/branch/avm/pypy/translator/avm1/test/test_float.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_float.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,26 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rfloat import BaseTestRfloat + +class TestCliFloat(CliTest, BaseTestRfloat): + + inf = 'Infinity' + minus_inf = '-Infinity' + nan = 'NaN' + + def test_parse_float(self): + ex = ['', ' ', '0', '1', '-1.5', '1.5E2', '2.5e-1', ' 0 ', '?'] + def fn(i): + s = ex[i] + try: + return float(s) + except ValueError: + return -999.0 + + for i in range(len(ex)): + expected = fn(i) + res = self.interpret(fn, [i]) + assert res == expected + + def test_r_singlefloat(self): + py.test.skip("not implemented: single-precision floats") Added: pypy/branch/avm/pypy/translator/avm1/test/test_list.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_list.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,27 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rlist import BaseTestRlist +from pypy.rlib.rarithmetic import r_uint + +class TestCliList(CliTest, BaseTestRlist): + def test_recursive(self): + py.test.skip("CLI doesn't support recursive lists") + + def test_getitem_exc(self): + py.test.skip('fixme!') + + def test_list_unsigned(self): + def fn(x): + lst = [r_uint(0), r_uint(1)] + lst[0] = r_uint(x) + return lst[0] + res = self.interpret(fn, [42]) + assert res == 42 + + def test_list_bool(self): + def fn(x): + lst = [True, False] + lst[0] = x + return lst[0] + res = self.interpret(fn, [False]) + assert res == False Added: pypy/branch/avm/pypy/translator/avm1/test/test_objectmodel.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_objectmodel.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,10 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.objectmodel import \ + BaseTestObjectModel + +def skip_r_dict(self): + py.test.skip('r_dict support is still incomplete') + +class TestCliObjectModel(CliTest, BaseTestObjectModel): + test_rtype_r_dict_bm = skip_r_dict Added: pypy/branch/avm/pypy/translator/avm1/test/test_oo.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_oo.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,125 @@ +from pypy.translator.cli.test.runtest import CliTest + +class MyClass: + INCREMENT = 1 + + def __init__(self, x, y): + self.x = x + self.y = y + + def compute(self): + return self.x + self.y + + def compute_and_multiply(self, factor): + return self.compute() * factor + + def static_meth(x, y): + return x*y + static_meth = staticmethod(static_meth) + + def class_attribute(self): + return self.x + self.INCREMENT + +class MyDerivedClass(MyClass): + INCREMENT = 2 + + def __init__(self, x, y): + MyClass.__init__(self, x+12, y+34) + + def compute(self): + return self.x - self.y + + +# helper functions +def call_method(obj): + return obj.compute() + +def init_and_compute(cls, x, y): + return cls(x, y).compute() + +def nonnull_helper(lst): + if lst is None: + return 1 + else: + return 2 + + +class TestOO(CliTest): + def test_indirect_call(self): + def f(): + return 1 + def g(): + return 2 + def fn(flag): + if flag: + x = f + else: + x = g + return x() + assert self.interpret(fn, [True]) == 1 + assert self.interpret(fn, [False]) == 2 + + def test_indirect_call_arguments(self): + def f(x): + return x+1 + def g(x): + return x+2 + def fn(flag, n): + if flag: + x = f + else: + x = g + return x(n) + assert self.interpret(fn, [True, 42]) == 43 + + + def test_compute(self): + def fn(x, y): + obj = MyClass(x, y) + return obj.compute() + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_compute_multiply(self): + def fn(x, y): + obj = MyClass(x, y) + return obj.compute_and_multiply(2) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_inheritance(self): + def fn(x, y): + obj = MyDerivedClass(x, y) + return obj.compute_and_multiply(2) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_liskov(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return call_method(base) + call_method(derived) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_static_method(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return base.static_meth(x,y) + derived.static_meth(x, y)\ + + MyClass.static_meth(x, y) + MyDerivedClass.static_meth(x, y) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_class_attribute(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return base.class_attribute() + derived.class_attribute() + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_runtimenew(self): + def fn(x, y): + return init_and_compute(MyClass, x, y) + init_and_compute(MyDerivedClass, x, y) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_nonnull(self): + def fn(x, y): + return nonnull_helper([]) + nonnull_helper(None) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + Added: pypy/branch/avm/pypy/translator/avm1/test/test_op.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_op.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,19 @@ +import sys +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.operations import BaseTestOperations +from pypy.rlib.rarithmetic import ovfcheck + +# ====> ../../oosupport/test_template/operations.py + +class TestOperations(CliTest, BaseTestOperations): + def test_int_div_overflow(self): + import py + py.test.skip('fixme!') + def fn(x, y): + try: + return x//y + except OverflowError: + return 42 + res = self.interpret(fn, [-sys.maxint-1, -1]) + assert res == 42 + Added: pypy/branch/avm/pypy/translator/avm1/test/test_overflow.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_overflow.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,5 @@ +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.overflow import BaseTestOverflow + +class TestOverflow(BaseTestOverflow, CliTest): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_pbc.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_pbc.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,6 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rpbc import BaseTestRPBC + +class TestCliPBC(CliTest, BaseTestRPBC): + pass Added: pypy/branch/avm/pypy/translator/avm1/test/test_primitive.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_primitive.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,13 @@ +import os +import time + +from pypy.translator.cli.test.runtest import CliTest + +class TestPrimitive(CliTest): + + def test_time_time(self): + def fn(): + return time.time() + t1 = self.interpret(fn, []) + t2 = self.interpret(fn, []) + assert t1 <= t2 Added: pypy/branch/avm/pypy/translator/avm1/test/test_query.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_query.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,39 @@ +import py +from pypy.translator.cli import query +from pypy.translator.cli.dotnet import CLR, CliNamespace + +def setup_module(module): + from pypy.translator.cli.query import load_assembly, mscorlib + load_assembly(mscorlib) + +def test_load_assembly(): + query.load_assembly(query.mscorlib) + assert 'System.Math' in query.Types + assert 'System.Collections.ArrayList' in query.Types + +def test_namespaces(): + assert CLR.System._name == 'System' + assert CLR.System.Collections._name == 'System.Collections' + py.test.raises(AttributeError, getattr, CLR, 'Foo') + py.test.raises(AttributeError, getattr, CLR.System, 'Foo') + +def test_CLR_getattr(): + System = CLR.System + assert isinstance(System, CliNamespace) + assert System._name == 'System' + assert hasattr(CLR, 'System') + +def test_static_fields(): + desc = query.get_class_desc('System.Reflection.Emit.OpCodes') + assert ('Add', 'System.Reflection.Emit.OpCode') in desc.StaticFields + +def test_System_Object(): + Object = CLR.System.Object + assert Object._name == '[mscorlib]System.Object' + assert 'Equals' in Object._static_methods + assert 'ToString' in Object._INSTANCE._methods + +def test_array(): + cls = query.get_cli_class('System.Object[]') + assert cls._INSTANCE._isArray + assert cls._INSTANCE._ELEMENT is CLR.System.Object._INSTANCE Added: pypy/branch/avm/pypy/translator/avm1/test/test_range.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_range.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,7 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rrange import BaseTestRrange + +class TestCliRange(CliTest, BaseTestRrange): + def test_rlist_range(self): + pass # it doesn't make sense here Added: pypy/branch/avm/pypy/translator/avm1/test/test_snippet.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_snippet.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,47 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.oosupport.test_template.snippets import BaseTestSnippets + +class TestSnippets(BaseTestSnippets, CliTest): + def test_llshl(self): + py.test.skip('llshl currently broken on CLI') + + 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] + + def test_mangle(self): + class Foo: + def le(self): + return 42 + + def fn(): + f = Foo() + return f.le() + res = self.interpret(fn, [], backendopt=False) + + def test_link_vars_overlapping(self): + from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift + def fn(maxofs): + lastofs = 0 + ofs = 1 + while ofs < maxofs: + lastofs = ofs + try: + ofs = ovfcheck_lshift(ofs, 1) + except OverflowError: + ofs = maxofs + else: + ofs = ofs + 1 + return lastofs + res = self.interpret(fn, [64]) + expected = fn(64) + assert res == expected + Added: pypy/branch/avm/pypy/translator/avm1/test/test_streamio.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_streamio.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,28 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rlib.test.test_streamio import BaseTestBufferingInputStreamTests,\ + BaseTestBufferingOutputStream, BaseTestLineBufferingOutputStream,\ + BaseTestCRLFFilter, BaseTestBufferingInputOutputStreamTests,\ + BaseTestTextInputFilter, BaseTestTextOutputFilter + +class TestBufferingInputStreamTests(CliTest, BaseTestBufferingInputStreamTests): + pass + +class TestBufferingOutputStream(CliTest, BaseTestBufferingOutputStream): + pass + +class TestLineBufferingOutputStream(CliTest, BaseTestLineBufferingOutputStream): + pass + +class TestCRLFFilter(CliTest, BaseTestCRLFFilter): + pass + +class TestBufferingInputOutputStreamTests(CliTest, BaseTestBufferingInputOutputStreamTests): + pass + +class TestTextInputFilter(CliTest, BaseTestTextInputFilter): + pass + +class TestTextOutputFilter(CliTest, BaseTestTextOutputFilter): + pass + Added: pypy/branch/avm/pypy/translator/avm1/test/test_string.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_string.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,40 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +import pypy.translator.oosupport.test_template.string as oostring + +class TestCliString(CliTest, oostring.BaseTestString): + + EMPTY_STRING_HASH = 0 + + def test_unichar_const(self): + py.test.skip("CLI interpret doesn't support unicode for input arguments") + test_unichar_eq = test_unichar_const + test_unichar_ord = test_unichar_const + test_unichar_hash = test_unichar_const + test_char_unichar_eq = test_unichar_const + test_char_unichar_eq_2 = test_unichar_const + + def test_upper(self): + py.test.skip("CLI doens't support backquotes inside string literals") + test_lower = test_upper + + def test_hlstr(self): + py.test.skip("CLI tests can't have string as input arguments") + + test_inplace_add = test_hlstr + + def test_getitem_exc(self): + py.test.skip('fixme!') + + def test_compare(self): + strings = ['aa', 'ZZ'] + def fn(i, j): + return strings[i] < strings[j] + assert self.interpret(fn, [0, 1], backendopt=False) == fn(0, 1) + + def test_literal_length(self): + strings = ['aa', 'a\x01', 'a\x00'] + def fn(): + for s in strings: + assert len(s) == 2 + self.interpret(fn, [], backendopt=False) Added: pypy/branch/avm/pypy/translator/avm1/test/test_tuple.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_tuple.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,12 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rtuple import BaseTestRtuple + +class TestCliTuple(CliTest, BaseTestRtuple): + def test_builtin_records(self): + def fn(x, y): + return x, y + res = self.interpret(fn, [1.0, 1]) + assert res.item0 == 1.0 and res.item1 == 1 + res = self.interpret(fn, [1.0, 1.0]) + assert res.item0 == 1.0 and res.item1 == 1.0 Added: pypy/branch/avm/pypy/translator/avm1/test/test_unicode.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm1/test/test_unicode.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,23 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_runicode import BaseTestRUnicode + +# ====> ../../../rpython/test/test_runicode.py + +class TestCliUnicode(CliTest, BaseTestRUnicode): + + EMPTY_STRING_HASH = 0 + + def test_unichar_const(self): + py.test.skip("CLI interpret doesn't support unicode for input arguments") + test_unichar_eq = test_unichar_const + test_unichar_ord = test_unichar_const + test_unichar_hash = test_unichar_const + test_char_unichar_eq = test_unichar_const + test_char_unichar_eq_2 = test_unichar_const + + def test_getitem_exc(self): + py.test.skip('fixme!') + + def test_inplace_add(self): + py.test.skip("CLI tests can't have string as input arguments") Modified: pypy/branch/avm/pypy/translator/avm1/types.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/types.py (original) +++ pypy/branch/avm/pypy/translator/avm1/types.py Thu Aug 13 00:29:31 2009 @@ -1,36 +1,26 @@ from pypy.translator.avm import avm1 -from pypy.objspace.flow import model as flowmodel -from pypy.rlib.rarithmetic import r_longlong +from pypy.rlib.rarithmetic import r_longlong, r_ulonglong from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lltype _pytype_to_avm1 = { - str: avm1.STRING, - unicode: avm1.STRING, - int: avm1.INTEGER, - long: avm1.INTEGER, - bool: avm1.BOOLEAN, - float: avm1.DOUBLE, - r_longlong: avm1.INTEGER, -} - -class AVM1Number(object): - pass - -class AVM1Primitive(object): - pass - -_lltype_to_avm1 = { - lltype.Number: AVM1Number, - lltype.Primitive: AVM1Primitive + str: avm1.STRING, + unicode: avm1.STRING, + int: avm1.INTEGER, + long: avm1.INTEGER, + r_longlong: avm1.INTEGER, + r_ulonglong: avm1.INTEGER, + bool: avm1.BOOLEAN, + float: avm1.DOUBLE, } def pytype_to_avm1(value): return (value, _pytype_to_avm1[type(value)]) def lltype_to_avm1(value): - return _lltype_to_avm1[type(value)] + return None + #return _lltype_to_avm1[value] class AVM1TypeSystem(object): def __init__(self, db): @@ -43,5 +33,4 @@ return lltype_to_avm1(TYPE) def llvar_to_cts(self, var): - print var.name return self.lltype_to_cts(var.concretetype), var.name Modified: pypy/branch/avm/pypy/translator/avm1/util.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/util.py (original) +++ pypy/branch/avm/pypy/translator/avm1/util.py Thu Aug 13 00:29:31 2009 @@ -4,6 +4,17 @@ ALIGN_LEFT = "left" ALIGN_RIGHT = "right" +def serialize_u32(value): + s = "" + while True: + bits = value & 0b01111111 # low 7 bits + value >>= 7 + if not value: + s += chr(bits) + break + s += chr(0b10000000 | bits) + return s + class BitStream(object): """ BitStream is a class for taking care of data structures that are bit-packed, like SWF.""" Added: pypy/branch/avm/pypy/translator/avm2/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/__init__.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1 @@ +a Added: pypy/branch/avm/pypy/translator/avm2/constants.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/constants.py Thu Aug 13 00:29:31 2009 @@ -0,0 +1,327 @@ + +import struct +from pypy.translator.avm.util import serialize_u32 as u32 + +# ====================================== +# Constants +# ====================================== + +# String types +TYPE_STRING_Utf8 = 0x01 + +# Number types +TYPE_NUMBER_Int = 0x03 +TYPE_NUMBER_UInt = 0x04 +TYPE_NUMBER_DOUBLE = 0x06 + +# Boolean types +TYPE_BOOLEAN_False = 0x0A +TYPE_BOOLEAN_True = 0x0B + +# Object types +TYPE_OBJECT_Undefined = 0x00 +TYPE_OBJECT_Null = 0x0C + +# Namespace types +TYPE_NAMESPACE_PrivateNamespace = 0x05 +TYPE_NAMESPACE_Namespace = 0x08 +TYPE_NAMESPACE_PackageNamespace = 0x16 +TYPE_NAMESPACE_PackageInternalNs = 0x17 +TYPE_NAMESPACE_ProtectedNamespace = 0x18 +TYPE_NAMESPACE_ExplicitNamespace = 0x19 +TYPE_NAMESPACE_StaticProtectedNs = 0x1A + +# Namespace Set types +TYPE_NAMESPACE_SET_NamespaceSet = 0x15 + +# Multiname types +TYPE_MULTINAME_QName = 0x07 +TYPE_MULTINAME_QNameA = 0x0D +TYPE_MULTINAME_Multiname = 0x09 +TYPE_MULTINAME_MultinameA = 0x0E +TYPE_MULTINAME_RtqName = 0x0F +TYPE_MULTINAME_RtqNameA = 0x10 +TYPE_MULTINAME_RtqNameL = 0x11 +TYPE_MULTINAME_RtqNameLA = 0x12 +TYPE_MULTINAME_NameL = 0x13 +TYPE_MULTINAME_NameLA = 0x14 +TYPE_MULTINAME_MultinameL = 0x1B +TYPE_MULTINAME_MultinameLA = 0x1C + +# ====================================== +# Namespaces +# ====================================== + +class Namespace(object): + + def __init__(self, kind, name): + self.kind = kind + self.name = name + self._name_index = None + + def __hash__(self): + return hash((self.name, self.kind)) + + def __eq__(self, other): + return self.name == other.name and self.kind == other.kind + + def __ne__(self, other): + return not self == other + + def write_to_pool(self, pool): + self._name_index = pool.utf8_index(name) + + def serialize(self): + assert self._name_index is not None, "Please call write_to_pool before serializing" + return chr(self.kind) + u32(self._name_index) + +class NamespaceSet(object): + + def __init__(self, *namespaces): + self.namespaces = namespaces + self._namespace_indices = None + + def __len__(self): + return len(self.namespaces) + + def __hash__(self): + return hash(tuple(self.namespaces)) + + def __eq__(self, other): + return len(self) == len(other) and all(n1 == n2 for n1, n2 in zip(self.namespaces, other.namespaces)) + + def __ne__(self, other): + return not self == other + + def write_to_pool(self, pool): + self._namespace_indices = [pool.namespace_index(ns) for ns in self.namespaces] + + def serialize(self): + assert self._namespace_indices is not None, "Please call write_to_pool before serializing" + return u32(len(self.namespaces)) + ''.join(u32(index) for index in self_namespace_indices) + + +NO_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "") +ANY_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "*") + +NO_NAMESPACE_SET = NamespaceSet() + +# ====================================== +# Multinames +# ====================================== + +class MultinameL(object): + KIND = TYPE_MULTINAME_MultinameL + + def __init__(self, ns_set): + self.ns_set = ns_set + self._ns_set_index = None + + def __eq__(self, other): + return self.kind == other.kind and self.ns_set == other.ns_set + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.kind, self.ns_set)) + + def write_to_pool(self, pool): + self._ns_set_index = pool.nsset_index(self.ns_set) + + def serialize(self): + assert self._ns_set_index is not None, "Please call write_to_pool before serializing" + return chr(self.KIND) + u32(self._ns_set_index) + +class MultinameLA(MultinameL): + KIND = TYPE_MULTINAME_MultinameLA + +class Multiname(MultinameL): + KIND = TYPE_MULTINAME_Multiname + + def __init__(self, name, ns_set): + super(Multiname, self).__init__(ns_set) + self.name = name + self._name_index = None + + def __eq__(self, other): + return self.kind == other.kind and self.name == other.name + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.kind, self.name)) + + def write_to_pool(self, pool): + super(Multiname, self).write_to_pool(pool) + self._name_index = pool.utf8_index(self.name) + + def serialize(self): + assert self._name_index is not None, "Please call write_to_pool before serializing" + assert self._ns_set_index is not None, "Please call write_to_pool before serializing" + return chr(self.kind) + u32(self._name_index) + u32(self._ns_set_index) + +class MultinameA(Multiname): + KIND = TYPE_MULTINAME_MultinameA + + +class QName(object): + KIND = TYPE_MULTINAME_QName + + def __init__(self, name, ns): + self.name = name + self.ns = ns + + self._name_index = None + self._ns_index = None + + def __eq__(self, other): + return self.kind == other.kind and self.name == other.name and self.ns == other.ns + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.kind, self.name, self.ns)) + + def write_to_pool(self, pool): + self._name_index = pool.utf8_index(self.name) + self._ns_index = pool.namespace_index(self.ns) + + def serialize(self): + assert self._name_index is not None, "Please call write_to_pool before serializing" + assert self._ns_index is not None, "Please call write_to_pool before serializing" + return chr(self.kind) + u32(self._ns_index) + u32(self._name_index) + +class QNameA(QName): + KIND = TYPE_MULTINAME_QNameA + +class RtqNameL(object): + KIND = TYPE_MULTINAME_RtqNameL + + def serialize(self): + return chr(self.kind) + + def __eq__(self, other): + return self.kind == other.kind + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.kind)) + +class RtqNameLA(RtqNameL): + KIND = TYPE_MULTINAME_RtqNameLA + +class RtqName(object): + KIND = TYPE_MULTINAME_RtqName + + def __init__(self, name): + self.name = name + self._name_index = None + + def write_to_pool(self, pool): + self._name_index = pool.utf8_index(name) + + def serialize(self): + assert self._name_index is not None, "Please call write_to_pool before serializing" + +# ====================================== +# Constant Pool +# ====================================== + +def constant_index_base(default, pool_name): + def fn(self, value): + if value == default: + return 0 + + pool = getattr(self, pool_name) + + if value in pool: + return pool.index(value) + 1 + else: + pool.append(value) + return len(pool) + + return fn + +class OptimizedPool(object): + + def __init__(self, default): + self.index_map = {} + self.pool = [] + self.default = default + + def index_for(self, value): + if value == self.default: + return 0 + + if value in index_map: + return index_map[value] + + self.pool.append(value) + index = len(self.pool) + self.index_map[value] = index + return index + + def value_at(self, index): + if index == 0: + return default + + if index < len(self.pool): + return self.pool[index] + + return None + +class AbcConstantPool(object): + + def __init__(self): + self.int_pool = OptimizedPool() + self.uint_pool = OptimizedPool() + self.double_pool = OptimizedPool() + self.utf8_pool = OptimizedPool() + self.namespace_pool = OptimizedPool() + self.nsset_pool = OptimizedPool() + self.multiname_pool = OptimizedPool() + + int_index = constant_index_base(0, "int_pool") + uint_index = constant_index_base(0, "uint_pool") + double_index = constant_index_base(float("nan"), "double_pool") + utf8_index = constant_index_base("", "utf8_pool") + namespace_index = constant_index_base(ANY_NAMESPACE, "namespace_pool") + nsset_index = constant_index_base(NO_NAMESPACE_SET, "nsset_pool") + + def has_RTNS(self, index): + return self.multiname_pool[index].kind in (TYPE_MULTINAME_RtqName, TYPE_MULTINAME_RtqNameA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA) + + def has_RTName(self, index): + return self.multiname_pool[index].kind in (TYPE_MULTINAME_MultinameL, TYPE_MULTINAME_MultinameLA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA) + + def serialize(self): + + def double(double): + return struct.pack(" Author: pedronis Date: Thu Aug 13 10:12:00 2009 New Revision: 66802 Modified: pypy/trunk/pypy/conftest.py Log: try fixing massive -A test failure, be less paranoid and simplify away dep to py.test internals Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Thu Aug 13 10:12:00 2009 @@ -371,10 +371,8 @@ def runtest(self): target = self.obj - args = self._args - assert not args if option.runappdirect: - return target(*args) + return target() space = gettestobjspace() func = app2interp_temp(target) print "executing", func @@ -400,10 +398,8 @@ def runtest(self): target = self.obj - args = self._args - assert not args if option.runappdirect: - return target(*args) + return target() space = target.im_self.space func = app2interp_temp(target.im_func) w_instance = self.parent.w_instance From pedronis at codespeak.net Thu Aug 13 12:12:27 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 13 Aug 2009 12:12:27 +0200 (CEST) Subject: [pypy-svn] r66803 - pypy/branch/pyjitpl5/pypy Message-ID: <20090813101227.DF73A168011@codespeak.net> Author: pedronis Date: Thu Aug 13 12:12:25 2009 New Revision: 66803 Modified: pypy/branch/pyjitpl5/pypy/ (props changed) pypy/branch/pyjitpl5/pypy/conftest.py Log: port -A tests fix from 66802 trunk Modified: pypy/branch/pyjitpl5/pypy/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/conftest.py Thu Aug 13 12:12:25 2009 @@ -371,10 +371,8 @@ def runtest(self): target = self.obj - args = self._args - assert not args if option.runappdirect: - return target(*args) + return target() space = gettestobjspace() func = app2interp_temp(target) print "executing", func @@ -400,10 +398,8 @@ def runtest(self): target = self.obj - args = self._args - assert not args if option.runappdirect: - return target(*args) + return target() space = target.im_self.space func = app2interp_temp(target.im_func) w_instance = self.parent.w_instance From arigo at codespeak.net Thu Aug 13 20:27:22 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:27:22 +0200 (CEST) Subject: [pypy-svn] r66804 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090813182722.ECF75168014@codespeak.net> Author: arigo Date: Thu Aug 13 20:27:20 2009 New Revision: 66804 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dict.py Log: Remove commented out skips. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dict.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dict.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dict.py Thu Aug 13 20:27:20 2009 @@ -71,10 +71,6 @@ class TestOOtype(DictTests, OOJitMixin): -## def test_dict_keys_values_items(self): -## py.test.skip("implement me") -## def test_dict_iter(self): -## py.test.skip("implement me") pass class TestLLtype(DictTests, LLJitMixin): From arigo at codespeak.net Thu Aug 13 20:39:42 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:39:42 +0200 (CEST) Subject: [pypy-svn] r66806 - pypy/branch/pyjitpl5-guardovf Message-ID: <20090813183942.14DE1168014@codespeak.net> Author: arigo Date: Thu Aug 13 20:39:41 2009 New Revision: 66806 Added: pypy/branch/pyjitpl5-guardovf/ - copied from r66805, pypy/branch/pyjitpl5/ Log: A branch in which to add the operations GUARD_NO_OVERFLOW and GUARD_OVERFLOW, to follow the INT_xxx_OVF operations instead of GUARD_(NO)_EXCEPTION. From arigo at codespeak.net Thu Aug 13 20:40:48 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:40:48 +0200 (CEST) Subject: [pypy-svn] r66807 - in pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp: . test Message-ID: <20090813184048.5ED73168014@codespeak.net> Author: arigo Date: Thu Aug 13 20:40:47 2009 New Revision: 66807 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py Log: Add the GUARD_(NO)_OVERFLOW operations in the frontend. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py Thu Aug 13 20:40:47 2009 @@ -189,10 +189,11 @@ try: z = ovfcheck(x + y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_sub_ovf(cpu, args, descr=None): @@ -201,10 +202,11 @@ try: z = ovfcheck(x - y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_mul_ovf(cpu, args, descr=None): @@ -213,10 +215,11 @@ try: z = ovfcheck(x * y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py Thu Aug 13 20:40:47 2009 @@ -232,7 +232,8 @@ exec py.code.Source(''' @arguments("box", "box") def opimpl_%s(self, b1, b2): - return self.execute_with_exc(rop.%s, [b1, b2]) + self.execute(rop.%s, [b1, b2]) + return self.metainterp.handle_overflow_error() ''' % (_opimpl, _opimpl.upper())).compile() for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not', @@ -1330,6 +1331,9 @@ self.framestack[-1].dont_follow_jump() elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: self.handle_exception() + elif opnum == rop.GUARD_NO_OVERFLOW: # an overflow now detected + self.cpu.set_overflow_error() + self.raise_this_error() def compile(self, original_boxes, live_arg_boxes, start): num_green_args = self.staticdata.num_green_args @@ -1523,6 +1527,17 @@ frame.generate_guard(frame.pc, rop.GUARD_NO_EXCEPTION, None, []) return False + def handle_overflow_error(self): + frame = self.framestack[-1] + if self.cpu.get_overflow_flag(): + self.cpu.set_overflow_flag(False) + frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) + self.cpu.set_overflow_error() + return self.raise_this_error() + else: + frame.generate_guard(frame.pc, rop.GUARD_NO_OVERFLOW, None, []) + return False + def rebuild_state_after_failure(self, resumedescr, newboxes): if not we_are_translated(): self._debug_history.append(['guard_failure', None, None]) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py Thu Aug 13 20:40:47 2009 @@ -73,6 +73,10 @@ return (self.opnum == rop.GUARD_EXCEPTION or self.opnum == rop.GUARD_NO_EXCEPTION) + def is_guard_overflow(self): + return (self.opnum == rop.GUARD_OVERFLOW or + self.opnum == rop.GUARD_NO_OVERFLOW) + def is_always_pure(self): return rop._ALWAYS_PURE_FIRST <= self.opnum <= rop._ALWAYS_PURE_LAST @@ -108,6 +112,8 @@ '_GUARD_FOLDABLE_LAST', 'GUARD_NO_EXCEPTION', 'GUARD_EXCEPTION', + 'GUARD_NO_OVERFLOW', + 'GUARD_OVERFLOW', '_GUARD_LAST', # ----- end of guard operations ----- '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations ----- @@ -190,13 +196,13 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', 'OOSEND', # ootype operation - # - '_OVF_FIRST', + '_CANRAISE_LAST', # ----- end of can_raise operations ----- + + '_OVF_FIRST', # ----- start of is_ovf operations ----- 'INT_ADD_OVF', 'INT_SUB_OVF', 'INT_MUL_OVF', - '_OVF_LAST', - '_CANRAISE_LAST', # ----- end of can_raise operations ----- + '_OVF_LAST', # ----- end of is_ovf operations ----- '_LAST', # for the backend to add more internal operations ] Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py Thu Aug 13 20:40:47 2009 @@ -385,6 +385,22 @@ res = self.meta_interp(f, [1]) assert res == expected + def test_int_ovf_common(self): + import sys + myjitdriver = JitDriver(greens = [], reds = ['n']) + def f(n): + while 1: + myjitdriver.can_enter_jit(n=n) + myjitdriver.jit_merge_point(n=n) + try: + n = ovfcheck(n + sys.maxint) + except OverflowError: + n -= 1 + else: + return n - 2000 + res = self.meta_interp(f, [10], repeat=7) + assert res == sys.maxint - 2000 + def test_int_mod_ovf_zer(self): def f(x, y): try: From arigo at codespeak.net Thu Aug 13 20:41:32 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:41:32 +0200 (CEST) Subject: [pypy-svn] r66808 - in pypy/branch/pyjitpl5-guardovf/pypy/jit/backend: . llgraph llgraph/test test Message-ID: <20090813184132.DC5D4168014@codespeak.net> Author: arigo Date: Thu Aug 13 20:41:32 2009 New Revision: 66808 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/model.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/test_random.py Log: Adapt the backends, step 1. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py Thu Aug 13 20:41:32 2009 @@ -108,10 +108,11 @@ 'guard_true' : (('bool',), None), 'guard_false' : (('bool',), None), 'guard_value' : (('int', 'int'), None), - 'guard_value_inverse' : (('int', 'int'), None), 'guard_class' : (('ptr', 'ptr'), None), 'guard_no_exception' : ((), None), 'guard_exception' : (('ptr',), 'ptr'), + 'guard_no_overflow' : ((), None), + 'guard_overflow' : ((), None), 'newstr' : (('int',), 'ptr'), 'strlen' : (('ptr',), 'int'), 'strgetitem' : (('ptr', 'int'), 'int'), @@ -534,30 +535,14 @@ if value.typeptr != expected_class: raise GuardFailed - def op_guard_class_inverse(self, _, value, expected_class): - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - expected_class = llmemory.cast_adr_to_ptr( - cast_int_to_adr(self.memocast, expected_class), - rclass.CLASSTYPE) - if value.typeptr == expected_class: - raise GuardFailed - def op_guard_value(self, _, value, expected_value): if value != expected_value: raise GuardFailed - def op_guard_value_inverse(self, _, value, expected_value): - if value == expected_value: - raise GuardFailed - def op_guard_no_exception(self, _): if _last_exception: raise GuardFailed - def op_guard_no_exception_inverse(self, _): - if _last_exception is None: - raise GuardFailed - def _check_exception(self, expected_exception): global _last_exception expected_exception = self._cast_exception(expected_exception) @@ -587,14 +572,19 @@ _last_exception = None return res - def op_guard_exception_inverse(self, _, expected_exception): - global _last_exception - if self._check_exception(expected_exception): + def op_guard_no_overflow(self, _): + global _overflow_flag + if _overflow_flag: + _overflow_flag = False raise GuardFailed - res = _last_exception[1] - _last_exception = None - return res - + + def op_guard_overflow(self, _): + global _overflow_flag + if _overflow_flag: + _overflow_flag = False + else: + raise GuardFailed + # ---------- # delegating to the builtins do_xxx() (done automatically for simple cases) @@ -926,6 +916,15 @@ def set_zero_division_error(): _set_error(ZeroDivisionError) +_overflow_flag = False + +def get_overflow_flag(): + return _overflow_flag + +def set_overflow_flag(flag): + global _overflow_flag + _overflow_flag = flag + class MemoCast(object): def __init__(self): self.addresses = [llmemory.NULL] Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/runner.py Thu Aug 13 20:41:32 2009 @@ -219,6 +219,12 @@ def set_zero_division_error(self): llimpl.set_zero_division_error() + def get_overflow_flag(self): + return llimpl.get_overflow_flag() + + def set_overflow_flag(self, flag): + llimpl.set_overflow_flag(flag) + @staticmethod def sizeof(S): return Descr(symbolic.get_size(S)) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/test/test_llgraph.py Thu Aug 13 20:41:32 2009 @@ -36,9 +36,6 @@ assert getattr(res, key) == value interpret(main, []) - def test_ovf_operations(self): - py.test.skip('no way to run this without a typer') - def test_execute_operations_in_env(self): py.test.skip("Rewrite me") x = BoxInt(123) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/model.py Thu Aug 13 20:41:32 2009 @@ -1,4 +1,5 @@ class AbstractCPU(object): + _overflow_flag = False def set_class_sizes(self, class_sizes): self.class_sizes = class_sizes @@ -60,6 +61,12 @@ def set_zero_division_error(self): raise NotImplementedError + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/runner_test.py Thu Aug 13 20:41:32 2009 @@ -217,24 +217,18 @@ if not reversed: ops = [ ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), + ResOperation(rop.GUARD_NO_OVERFLOW, [], None), ResOperation(rop.FAIL, [v_res], None), ] ops[1].suboperations = [ResOperation(rop.FAIL, [], None)] else: - self.cpu.set_overflow_error() - ovferror = self.cpu.get_exception() - assert self.cpu.get_exc_value() - self.cpu.clear_exception() if self.cpu.is_oo: v_exc = BoxObj() - c_ovferror = ConstObj(ovferror) else: v_exc = BoxPtr() - c_ovferror = ConstInt(ovferror) ops = [ ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_EXCEPTION, [c_ovferror], v_exc), + ResOperation(rop.GUARD_OVERFLOW, [], None), ResOperation(rop.FAIL, [], None), ] ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None)] @@ -246,6 +240,7 @@ for x, y, z in testcases: assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() + assert not self.cpu.get_overflow_flag() self.cpu.set_future_value_int(0, x) self.cpu.set_future_value_int(1, y) op = self.cpu.execute_operations(loop) @@ -255,18 +250,9 @@ assert op is ops[-1] if z != boom: assert self.cpu.get_latest_value_int(0) == z - ovferror = self.cpu.get_exception() - assert bool(ovferror) == bool(self.cpu.get_exc_value()) - if reversed: - # in the 'reversed' case, ovferror should always be - # consumed: either it is not set in the first place, - # or it is set and GUARD_EXCEPTION succeeds. - assert not ovferror - elif ovferror: - assert z == boom - self.cpu.clear_exception() - else: - assert z != boom + assert not self.cpu.get_exception() + assert not self.cpu.get_exc_value() + assert not self.cpu.get_overflow_flag() def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/test/test_random.py Thu Aug 13 20:41:32 2009 @@ -184,7 +184,10 @@ v_result = builder.do(self.opnum, args, descr=descr) if v_result is not None: builder.intvars.append(v_result) - if self.boolres: + boolres = self.boolres + if boolres == 'sometimes': + boolres = v_result.value in [0, 1] + if boolres: builder.boolvars.append(v_result) class UnaryOperation(AbstractOperation): @@ -228,20 +231,16 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - exc = builder.cpu.get_exception() - assert bool(exc) == bool(builder.cpu.get_exc_value()) - if exc: # OverflowError - builder.cpu.clear_exception() - exc_box = ConstInt(exc) - res_box = BoxPtr() - op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], res_box) + if builder.cpu.get_overflow_flag(): # overflow detected + builder.cpu.set_overflow_flag(False) + op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including # the result, and then remove it from builder.intvars. fail_subset = builder.subset_of_intvars(r) builder.intvars[:] = original_intvars else: - op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None) + op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) op.suboperations = [ResOperation(rop.FAIL, fail_subset, None)] builder.loop.operations.append(op) @@ -322,7 +321,7 @@ OPERATIONS.append(UnaryOperation(rop.INT_IS_TRUE, boolres=True)) OPERATIONS.append(BooleanUnaryOperation(rop.BOOL_NOT, boolres=True)) -OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres=True)) +OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres='sometimes')) for _op in [rop.INT_ADD_OVF, rop.INT_SUB_OVF, From arigo at codespeak.net Thu Aug 13 20:41:42 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:41:42 +0200 (CEST) Subject: [pypy-svn] r66809 - in pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal: . test Message-ID: <20090813184142.243D0168014@codespeak.net> Author: arigo Date: Thu Aug 13 20:41:41 2009 New Revision: 66809 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/runner.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/test/test_runner.py Log: Adapt the minimal backend. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/runner.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/runner.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/runner.py Thu Aug 13 20:41:41 2009 @@ -42,6 +42,7 @@ self._future_values = [] self._ovf_error_inst = self.setup_error(OverflowError) self._zer_error_inst = self.setup_error(ZeroDivisionError) + self.clear_exception() def setup_error(self, Class): if self.rtyper is not None: # normal case @@ -184,6 +185,15 @@ raise GuardFailed elif opnum == rop.GUARD_EXCEPTION: return self._execute_guard_exception(argboxes) + elif opnum == rop.GUARD_NO_OVERFLOW: + if self._overflow_flag: + self._overflow_flag = False + raise GuardFailed + elif opnum == rop.GUARD_OVERFLOW: + if self._overflow_flag: + self._overflow_flag = False + else: + raise GuardFailed else: ll_assert(False, "execute_guard: unknown guard op") Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/test/test_runner.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/minimal/test/test_runner.py Thu Aug 13 20:41:41 2009 @@ -23,7 +23,6 @@ test_passing_guard_class = _skip # GUARD_CLASS test_failing_guards = _skip # GUARD_CLASS test_failing_guard_class = _skip # GUARD_CLASS - test_ovf_operations_reversed = _skip # exception #class TestOOtype(OOJitMixin, MinimalTestMixin, OOtypeBackendTest): # pass From arigo at codespeak.net Thu Aug 13 20:41:55 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 20:41:55 +0200 (CEST) Subject: [pypy-svn] r66810 - pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86 Message-ID: <20090813184155.A199916801B@codespeak.net> Author: arigo Date: Thu Aug 13 20:41:54 2009 New Revision: 66810 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/runner.py Log: Adapt the x86 backend. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/assembler.py Thu Aug 13 20:41:54 2009 @@ -279,8 +279,8 @@ genop_discard_list[op.opnum](self, op, arglocs) def regalloc_perform_with_guard(self, op, guard_op, regalloc, - arglocs, resloc, ovf): - addr = self.implement_guard_recovery(guard_op, regalloc, ovf) + arglocs, resloc): + addr = self.implement_guard_recovery(guard_op, regalloc) genop_guard_list[op.opnum](self, op, guard_op, addr, arglocs, resloc) @@ -299,17 +299,6 @@ getattr(self.mc, asmop)(arglocs[0], arglocs[1]) return genop_binary - def _binaryop_ovf(asmop, can_swap=False): - def genop_binary_ovf(self, op, guard_op, addr, arglocs, result_loc): - getattr(self.mc, asmop)(arglocs[0], arglocs[1]) - if guard_op.opnum == rop.GUARD_NO_EXCEPTION: - self.mc.JO(rel32(addr)) - elif guard_op.opnum == rop.GUARD_EXCEPTION: - self.mc.JNO(rel32(addr)) - else: - raise AssertionError - return genop_binary_ovf - def _cmpop(cond, rev_cond): def genop_cmp(self, op, arglocs, result_loc): if isinstance(op.args[0], Const): @@ -362,9 +351,9 @@ genop_int_or = _binaryop("OR", True) genop_int_xor = _binaryop("XOR", True) - genop_guard_int_mul_ovf = _binaryop_ovf("IMUL", True) - genop_guard_int_sub_ovf = _binaryop_ovf("SUB") - genop_guard_int_add_ovf = _binaryop_ovf("ADD", True) + genop_int_mul_ovf = genop_int_mul + genop_int_sub_ovf = genop_int_sub + genop_int_add_ovf = genop_int_add genop_int_lt = _cmpop("L", "G") genop_int_le = _cmpop("LE", "GE") @@ -644,9 +633,7 @@ self.implement_guard(addr, op, self.mc.JZ) def genop_guard_guard_no_exception(self, op, ign_1, addr, locs, ign_2): - loc = locs[0] - self.mc.MOV(loc, heap(self._exception_addr)) - self.mc.TEST(loc, loc) + self.mc.CMP(heap(self._exception_addr), imm(0)) self.implement_guard(addr, op, self.mc.JNZ) def genop_guard_guard_exception(self, op, ign_1, addr, locs, resloc): @@ -660,6 +647,12 @@ self.mc.MOV(heap(self._exception_addr), imm(0)) self.mc.MOV(addr_add(imm(self._exception_addr), imm(WORD)), imm(0)) + def genop_guard_guard_no_overflow(self, op, ign_1, addr, locs, resloc): + self.implement_guard(addr, op, self.mc.JO) + + def genop_guard_guard_overflow(self, op, ign_1, addr, locs, resloc): + self.implement_guard(addr, op, self.mc.JNO) + def genop_guard_guard_false(self, op, ign_1, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) @@ -674,20 +667,13 @@ self.mc.CMP(mem(locs[0], offset), locs[1]) self.implement_guard(addr, op, self.mc.JNE) - def implement_guard_recovery(self, guard_op, regalloc, ovf=False): + def implement_guard_recovery(self, guard_op, regalloc): oldmc = self.mc self.mc = self.mc2 self.mc2 = self.mcstack.next_mc() addr = self.mc.tell() - exc = False - if ovf: - regalloc.position = -1 - if guard_op.opnum == rop.GUARD_NO_EXCEPTION: - self.generate_ovf_set() - exc = True - if (guard_op.opnum == rop.GUARD_EXCEPTION or - guard_op.opnum == rop.GUARD_NO_EXCEPTION): - exc = True + exc = (guard_op.opnum == rop.GUARD_EXCEPTION or + guard_op.opnum == rop.GUARD_NO_EXCEPTION) # XXX this is a heuristics to detect whether we're handling this # exception or not. We should have a bit better interface to deal # with that I fear @@ -734,14 +720,6 @@ self.mc.POP(ebp) self.mc.RET() - def generate_ovf_set(self): - ovf_error_vtable = self.cpu.cast_adr_to_int(self._ovf_error_vtable) - self.mc.MOV(addr_add(imm(self._exception_addr), imm(0)), - imm(ovf_error_vtable)) - ovf_error_instance = self.cpu.cast_adr_to_int(self._ovf_error_inst) - self.mc.MOV(addr_add(imm(self._exception_addr), imm(WORD)), - imm(ovf_error_instance)) - def generate_exception_handling(self, loc): self.mc.MOV(loc, heap(self._exception_addr)) self.mc.MOV(heap(self._exception_bck_addr), loc) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/regalloc.py Thu Aug 13 20:41:54 2009 @@ -17,13 +17,6 @@ REGS = [eax, ecx, edx] WORD = 4 -class ImplementConstantOverflow(Exception): - """ This exception is raised when someone uses the result - of GUARD_EXCEPTION(overflowerror). I think codewriter should - constant fold it as we know what kind of exception it will - be - """ - class TempBox(Box): def __init__(self): pass @@ -226,14 +219,12 @@ self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs)) self.assembler.regalloc_perform(op, arglocs, result_loc) - def perform_with_guard(self, op, guard_op, regalloc, arglocs, result_loc, - overflow=False): + def perform_with_guard(self, op, guard_op, regalloc, arglocs, result_loc): if not we_are_translated(): self.assembler.dump('%s <- %s(%s) [GUARDED]' % (result_loc, op, arglocs)) self.assembler.regalloc_perform_with_guard(op, guard_op, regalloc, - arglocs, result_loc, - overflow) + arglocs, result_loc) self.max_stack_depth = max(self.max_stack_depth, regalloc.max_stack_depth) @@ -299,15 +290,7 @@ else: canfold = False if not canfold: - # detect overflow ops - if op.is_ovf(): - assert operations[i + 1].is_guard_exception() - if (operations[i + 1].opnum == rop.GUARD_EXCEPTION and - operations[i + 1].result in self.longevity): - raise ImplementConstantOverflow() - nothing = oplist[op.opnum](self, op, operations[i + 1]) - i += 1 - elif self.can_optimize_cmp_op(op, i, operations): + if self.can_optimize_cmp_op(op, i, operations): nothing = oplist[op.opnum](self, op, operations[i + 1]) i += 1 else: @@ -710,12 +693,9 @@ self.eventually_free_vars(op.args) def consider_guard_no_exception(self, op, ignored): - box = TempBox() - loc = self.force_allocate_reg(box, []) regalloc = self.regalloc_for_guard(op) - self.perform_guard(op, regalloc, [loc], None) + self.perform_guard(op, regalloc, [], None) self.eventually_free_vars(op.inputargs) - self.eventually_free_var(box) def consider_guard_exception(self, op, ignored): loc = self.make_sure_var_in_reg(op.args[0], []) @@ -732,6 +712,9 @@ self.eventually_free_vars(op.args) self.eventually_free_var(box) + consider_guard_no_overflow = consider_guard_no_exception + consider_guard_overflow = consider_guard_no_exception + #def consider_guard2(self, op, ignored): # loc1, ops1 = self.make_sure_var_in_reg(op.args[0], []) # loc2, ops2 = self.make_sure_var_in_reg(op.args[1], []) @@ -790,19 +773,10 @@ consider_int_and = _consider_binop consider_int_or = _consider_binop consider_int_xor = _consider_binop - - def _consider_binop_ovf(self, op, guard_op): - loc, argloc = self._consider_binop_part(op, None) - self.position += 1 - regalloc = self.regalloc_for_guard(guard_op) - self.perform_with_guard(op, guard_op, regalloc, [loc, argloc], loc, - overflow=True) - self.eventually_free_vars(guard_op.inputargs) - self.eventually_free_var(guard_op.result) - - consider_int_mul_ovf = _consider_binop_ovf - consider_int_sub_ovf = _consider_binop_ovf - consider_int_add_ovf = _consider_binop_ovf + + consider_int_mul_ovf = _consider_binop + consider_int_sub_ovf = _consider_binop + consider_int_add_ovf = _consider_binop def consider_int_neg(self, op, ignored): res = self.force_result_in_reg(op.result, op.args[0], []) Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/x86/runner.py Thu Aug 13 20:41:54 2009 @@ -207,6 +207,14 @@ self.assembler._exception_bck[0] = zer_vtable self.assembler._exception_bck[1] = zer_inst + _overflow_flag = False + + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + def compile_operations(self, tree, bridge=None): old_loop = tree._x86_compiled if old_loop: From arigo at codespeak.net Thu Aug 13 21:12:44 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Aug 2009 21:12:44 +0200 (CEST) Subject: [pypy-svn] r66811 - pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm Message-ID: <20090813191244.D77F4168019@codespeak.net> Author: arigo Date: Thu Aug 13 21:12:43 2009 New Revision: 66811 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/compile.py pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/runner.py Log: Adapt the LLVM backend. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/compile.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/compile.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/compile.py Thu Aug 13 21:12:43 2009 @@ -14,6 +14,7 @@ class LLVMJITCompiler(object): FUNC = lltype.FuncType([], lltype.Signed) + lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) def __init__(self, cpu, loop): self.cpu = cpu @@ -348,22 +349,8 @@ lltype.free(arglist, flavor='raw') self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 0, "") - ovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, "") - self._generate_set_ovf(ovf) - - def _generate_set_ovf(self, ovf_flag): - exc_type = llvm_rffi.LLVMBuildSelect(self.builder, ovf_flag, - self.cpu.const_ovf_error_type, - self.cpu.const_null_charptr, - "") - llvm_rffi.LLVMBuildStore(self.builder, exc_type, - self.cpu.const_exc_type) - exc_value = llvm_rffi.LLVMBuildSelect(self.builder, ovf_flag, - self.cpu.const_ovf_error_value, - self.cpu.const_null_charptr, - "") - llvm_rffi.LLVMBuildStore(self.builder, exc_value, - self.cpu.const_exc_value) + self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, + "") def generate_GUARD_FALSE(self, op): self._generate_guard(op, self.getbitarg(op.args[0]), True) @@ -418,6 +405,12 @@ self.cpu.const_exc_value, "") + def generate_GUARD_NO_OVERFLOW(self, op): + self._generate_guard(op, self.lastovf, True) + + def generate_GUARD_OVERFLOW(self, op): + self._generate_guard(op, self.lastovf, False) + def _generate_guard(self, op, verify_condition, reversed, exc=False): func = self.compiling_func bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "") Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llvm/runner.py Thu Aug 13 21:12:43 2009 @@ -350,6 +350,14 @@ self.backup_exc_type[0] = self._zer_error_type self.backup_exc_value[0] = self._zer_error_value + _overflow_flag = False + + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + @staticmethod def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) From david at codespeak.net Thu Aug 13 22:16:19 2009 From: david at codespeak.net (david at codespeak.net) Date: Thu, 13 Aug 2009 22:16:19 +0200 (CEST) Subject: [pypy-svn] r66812 - pypy/branch/io-lang/pypy/lang/io/io Message-ID: <20090813201619.CCE7E168015@codespeak.net> Author: david Date: Thu Aug 13 22:16:18 2009 New Revision: 66812 Added: pypy/branch/io-lang/pypy/lang/io/io/A0_List.io pypy/branch/io-lang/pypy/lang/io/io/A2_Object.io pypy/branch/io-lang/pypy/lang/io/io/A4_Exception.io Log: Imported io code from main repository for Lists, Objects, Exceptions and Coroutines Added: pypy/branch/io-lang/pypy/lang/io/io/A0_List.io ============================================================================== --- (empty file) +++ pypy/branch/io-lang/pypy/lang/io/io/A0_List.io Thu Aug 13 22:16:18 2009 @@ -0,0 +1,281 @@ +Object do( + /*doc Object inlineMethod + Creates a method which is executed directly in a receiver (no Locals object is created). +
+
+  Io> m := inlineMethod(x := x*2)
+  Io> x := 1
+  ==> 1
+  Io> m
+  ==> 2
+  Io> m
+  ==> 4
+  Io> m
+  ==> 8
+  
+ */ + inlineMethod := method(call message argAt(0) setIsActivatable(true)) +) + +List do( + unique := method( + u := List clone + self foreach(v, u appendIfAbsent(v)) + u + ) + + select := method( + aList := List clone + + a1 := call argAt(0) + if(a1 == nil, + Exception raise("missing argument") + return + ) + a2 := call argAt(1) + a3 := call argAt(2) + + if(a3, + a1 := a1 name + a2 := a2 name + self foreach(i, v, + call sender setSlot(a1, i) + call sender setSlot(a2, getSlot("v")) + ss := stopStatus(c := a3 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), aList append(getSlot("v"))) + ) + return aList + ) + + if(a2, + a1 := a1 name + self foreach(v, + call sender setSlot(a1, getSlot("v")) + ss := stopStatus(c := a2 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), aList append(getSlot("v"))) + ) + return aList + ) + + self foreach(v, + ss := stopStatus(c := a1 doInContext(getSlot("v"), call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), aList append(getSlot("v"))) + ) + aList + ) + + detect := method( + a1 := call argAt(0) + if(a1 == nil, Exception raise("missing argument")) + a2 := call argAt(1) + a3 := call argAt(2) + + if(a3, + a1 := a1 name + a2 := a2 name + self foreach(i, v, + call sender setSlot(a1, i) + call sender setSlot(a2, getSlot("v")) + ss := stopStatus(c := a3 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), return getSlot("v")) + ) + return nil + ) + + if(a2, + a1 := a1 name + self foreach(v, + call sender setSlot(a1, getSlot("v")) + ss := stopStatus(c := a2 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), return getSlot("v")) + ) + return nil + ) + + self foreach(v, + ss := stopStatus(c := a1 doInContext(getSlot("v"), call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + if(getSlot("c"), return getSlot("v")) + ) + nil + ) + + map := method( + aList := List clone + + a1 := call argAt(0) + if(a1 == nil, Exception raise("missing argument")) + a2 := call argAt(1) + a3 := call argAt(2) + + if(a2 == nil, + self foreach(v, + ss := stopStatus(c := a1 doInContext(getSlot("v"), call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + aList append(getSlot("c")) + ) + return aList + ) + + if(a3 == nil, + a1 := a1 name + self foreach(v, + call sender setSlot(a1, getSlot("v")) + ss := stopStatus(c := a2 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + aList append(getSlot("c")) + ) + return aList + ) + + a1 := a1 name + a2 := a2 name + self foreach(i, v, + call sender setSlot(a1, i) + call sender setSlot(a2, getSlot("v")) + ss := stopStatus(c := a3 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + aList append(getSlot("c")) + ) + return aList + ) + + groupBy := method( + aMap := Map clone + + a1 := call argAt(0) + if(a1 == nil, Exception raise("missing argument")) + a2 := call argAt(1) + a3 := call argAt(2) + + if(a2 == nil, + self foreach(v, + ss := stopStatus(c := a1 doInContext(getSlot("v"), call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + + key := getSlot("c") asString + + aMap atIfAbsentPut(key, list()) + aMap at(key) append(v) + ) + return aMap + ) + + if(a3 == nil, + a1 := a1 name + self foreach(v, + call sender setSlot(a1, getSlot("v")) + ss := stopStatus(c := a2 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + + key := getSlot("c") asString + + aMap atIfAbsentPut(key, list()) + aMap at(key) append(v) + ) + return aMap + ) + + a1 := a1 name + a2 := a2 name + self foreach(i, v, + call sender setSlot(a1, i) + call sender setSlot(a2, getSlot("v")) + ss := stopStatus(c := a3 doInContext(call sender, call sender)) + if(ss isReturn, ss return getSlot("c")) + if(ss stopLooping, break) + if(ss isContinue, continue) + + key := getSlot("c") asString + + aMap atIfAbsentPut(key, list()) + aMap at(key) append(v) + ) + return aMap + ) + + //doc List copy(v) Replaces self with v list items. Returns self. + copy := method(v, self empty; self appendSeq(v); self) + + //doc List mapInPlace Same as map, but result replaces self. + mapInPlace := method( + self copy(self getSlot("map") performOn(self, call sender, call message)) + ) + + //doc List selectInPlace Same as select, but result replaces self. + selectInPlace := method( + self copy(self getSlot("select") performOn(self, call sender, call message)) + ) + + empty := method(self removeAll) + + isEmpty := method(size == 0) + isNotEmpty := method(size > 0) + + //doc List reverse Reverses the ordering of all the items of the receiver. Returns copy of receiver. + reverse := method(itemCopy reverseInPlace) + + //doc List itemCopy Returns a new list containing the items from the receiver. + itemCopy := method(List clone copy(self)) + + sort := method(self clone sortInPlace) + sortBy := method(b, self clone sortInPlaceBy(getSlot("b"))) + /* + print := method( + e := try( + s := Sequence clone + s appendSeq("list(") + self foreach(i, v, + if(i != 0, s appendSeq(", ")) + s appendSeq(getSlot("v") asString) + ) + ) + + if(e, + s := Sequence clone + s appendSeq("list(") + self foreach(i, v, + if(i != 0, s appendSeq(", ")) + vs := "[exception]" + try(vs := getSlot("v") asString) + s appendSeq(vs) + ) + + ) + s appendSeq(")") + s print + self + ) + */ + //doc List second Returns second element (same as at(1)) + second := method(at(1)) + //doc List second Returns third element (same as at(2)) + third := method(at(2)) +) Added: pypy/branch/io-lang/pypy/lang/io/io/A2_Object.io ============================================================================== --- (empty file) +++ pypy/branch/io-lang/pypy/lang/io/io/A2_Object.io Thu Aug 13 22:16:18 2009 @@ -0,0 +1,612 @@ +/* +//metadoc nil description nil is a singleton object that is used as a placeholder and to mean false in Io.") + +nil do( + //doc nil clone returns self since nil is a singleton. + clone := nil + + //doc nil and(expression) Returns nil without evaluating expression. + setSlot("and", nil) + + elseif := Object getSlot("if") + + //doc nil then(expression) Returns nil without evaluating expression. + setSlot("then", nil) + + //doc nil else(expression) Returns nil without evaluating expression. + setSlot("else", method(v, v)) + + //doc nil or(anObject) Returns anObject if anObject is not nil. Otherwise returns nil. + setSlot("or", method(v, if(v, v, nil))) + + //doc nil print Prints 'nil'. Returns self. + print := method(write("nil")) + + setSlot("==", method(v, self isIdenticalTo(v))) + setSlot("!=", method(v, self isIdenticalTo(v) not)) + + //doc nil isNil Returns Lobby. + isNil := Lobby + + //doc nil ifNil(expression) Evaluates message. + ifNil := method(v, v) +) +*/ + +// if(a == 1) then(b) elseif(b == c) then(d) else(f) +// (a == 1) ifTrue(b) ifFalse(c) + +true do( + //doc true then Evaluates the argument and returns nil. + then := Object getSlot("evalArgAndReturnNil") + + //doc true elseif Does not eval argument and returns true. + elseif := true + + //doc true else Does not eval argument and returns true. + else := true + + //doc true ifTrue Evaluates the argument and returns self. + ifTrue := Object getSlot("evalArgAndReturnSelf") + + //doc true ifFalse Does not eval argument and returns true. + ifFalse := true + + //doc true and Evaluates the argument and returns the result. + + //doc true or Does not eval argument and returns true. + setSlot("or", true) + + //doc true asString Returns true. + asString := "true" + + //doc true asSimpleString Returns true. + asSimpleString := "true" + + //doc true not Does not eval argument and returns false. + not := false + + //doc true clone Returns true. + clone := true +) + +false do( + //doc false then Returns false. + then := false + //doc false ifTrue Returns false. + ifTrue := false + //doc false ifFalse Evaluates the argument and returns self. + ifFalse := Object getSlot("evalArgAndReturnSelf") + //doc false elseif Same as if. + elseif := Object getSlot("if") + //doc false else Evaluates the argument and returns nil. + else := Object getSlot("evalArgAndReturnNil") + //doc false and Returns false. + setSlot("and", false) + //doc false or Evaluates the argument and returns the result. + or := method(v, v isTrue) + + //doc false type Returns "false". + type := "false" + //doc false asString Returns "false". + asString := "false" + //doc false asSimpleString Returns "false". + asSimpleString := "false" + //doc false not Returns true. + not := true + //doc false clone Returns self. + clone := false + isTrue := false +) + +nil do( + not := true + isNil := true + + ifNonNil := Object getSlot("thisContext") + ifNil := Object getSlot("evalArgAndReturnSelf") + + ifNilEval := Object getSlot("evalArg") + ifNonNilEval := Object getSlot("thisContext") + + type := "nil" + asString := type + asSimpleString := type + + setSlot("and", false) + or := method(v, v isTrue) + then := nil + else := nil + elseif := nil + clone := nil + isTrue := false +) + +// I think non-local returns can eliminate all this stopStatus stuff + +Call do( + /*doc Call relayStopStatus(arg) + Sets sender's stop status (Normal, Return, + Break, Continue etc.) and returns evaluated argument. + */ + relayStopStatus := method( + ss := stopStatus(r := call evalArgAt(0)) + call sender call setStopStatus(ss) + getSlot("r") + ) + + /*doc Call resetStopStatus(arg) + Sets stop status to Normal. + See also Call setStopStatus. + */ + resetStopStatus := method( + setStopStatus(Normal) + ) +) + +Normal do( + stopLooping := false + isReturn := false + isBreak := false + isContinue := false + + return := method(arg, + call setStopStatus(Return) + getSlot("arg") + ) +) + +Eol appendProto(Normal) +Continue appendProto(Normal) do( + isContinue := true +) + +Break appendProto(Normal) do( + stopLooping := true + isBreak := true +) + +Return appendProto(Normal) do( + stopLooping := true + isReturn := true + + return := method(arg, + call setStopStatus(Return) + call sender call setStopStatus(Return) + getSlot("arg") + ) +) + +Object do( + //doc Object not Returns nil. + not := nil + //doc Object isNil Returns false. + isNil := false + //doc Object ifNil(arg) Does nothing, returns self. + ifNil := Object getSlot("thisContext") + //doc Object ifNonNil(arg) Evaluates argument and returns self. + ifNonNil := Object getSlot("evalArgAndReturnSelf") + //doc Object ifNonNilEval(arg) Evaluates argument and returns the result. + ifNonNilEval := Object getSlot("evalArg") + //doc Object ifNilEval(arg) Does nothing, returns self. + ifNilEval := Object getSlot("thisContext") + //doc Object and(arg) Evaluates argument and returns the result. + //doc Object or(arg) Returns true. + setSlot("or", true) + + isTrue := true + and := method(v, v isTrue) +) + +Sequence do( + /*doc Sequence makeFirstCharacterLowercase + Receiver must be mutable (see also asMutable). Returns receiver. +
+
+  Io> "ABC" asMutable makeFirstCharacterLowercase
+  ==> aBC
+  
+ */ + makeFirstCharacterLowercase := method( + if(self size > 0, self atPut(0, self at(0) asLowercase)) + ) + /*doc Sequence makeFirstCharacterUppercase + Receiver must be mutable (see also asMutable). Returns receiver. +
+
+  Io> "abc" asMutable makeFirstCharacterUppercase
+  ==> Abc
+  
+ */ + makeFirstCharacterUppercase := method( + if(self size > 0, self atPut(0, self at(0) asUppercase)) + ) + + /*doc Sequence slicesBetween(startSeq, endSeq) + Returns a list of slices delimited + by startSeq and endSeq. +
+
+  Io> "" slicesBetween("<", ">")
+  ==> list("a", "b", "/b", "/a")
+  
+ */ + slicesBetween := method(startSeq, endSeq, + chunks := List clone + lastIndex := 0 + while (startIndex := self findSeq(startSeq, lastIndex), + endIndex := self findSeq(endSeq, startIndex + startSeq size) + endIndex ifNil(break) + chunks append(self exclusiveSlice(startIndex + startSeq size, endIndex)) + lastIndex := endIndex + endSeq size + ) + chunks + ) +) + +Object do( + /*doc Object hasSlot(name) + Returns true if slot is found somewhere in the inheritance chain + (including receiver itself). + */ + // XXX TODO: replace the vm method with this one + //hasSlot := method(n, + // getSlot("self") hasLocalSlot(n) or(getSlot("self") ancestorWithSlot(n) != nil) + //) + + //doc Object list(...) Returns a List containing the arguments. + list := method(call message argsEvaluatedIn(call sender)) + + //doc Object ..(arg) .. is an alias for: method(arg, self asString append(arg asString)) + setSlot("..", method(arg, getSlot("self") asString .. arg asString)) + + Map addKeysAndValues := method(keys, values, keys foreach(i, k, self atPut(k, values at(i))); self) + + /*doc Object slotDescriptionMap + Returns raw map of slot names and short values' descriptions. + See also Object slotSummary. + */ + slotDescriptionMap := method( + slotNames := getSlot("self") slotNames sort + slotDescs := slotNames map(name, getSlot("self") getSlot(name) asSimpleString) + Map clone addKeysAndValues(slotNames, slotDescs) + ) + //doc Object apropos Prints out Protos Core slot descriptions. + apropos := method(keyword, + Protos Core foreachSlot(name, p, + slotDescriptions := getSlot("p") slotDescriptionMap ?select(k, v, k asMutable lowercase containsSeq(keyword)) + + if(slotDescriptions and slotDescriptions size > 0, + s := Sequence clone + slotDescriptions keys sortInPlace foreach(k, + s appendSeq(" ", k alignLeft(16), " = ", slotDescriptions at(k), "\n") + ) + + writeln(name) + writeln(s) + ) + ) + nil + ) + /*doc Object slotSummary + Returns a formatted slotDescriptionMap. +
+
+  Io> slotSummary
+  ==>  Object_0x30c590:
+    Lobby            = Object_0x30c590
+    Protos           = Object_0x30c880
+    exit             = method(...)
+    forward          = method(...)
+  
+ */ + + slotSummary := method(keyword, + if(getSlot("self") type == "Block", + return getSlot("self") asSimpleString + ) + + s := Sequence clone + s appendSeq(" ", getSlot("self") asSimpleString, ":\n") + slotDescriptions := slotDescriptionMap + + if(keyword, + slotDescriptions = slotDescriptions select(k, v, k asMutable lowercase containsSeq(keyword)) + ) + + slotDescriptions keys sortInPlace foreach(k, + s appendSeq(" ", k alignLeft(16), " = ", slotDescriptions at(k), "\n") + ) + s + ) + + //doc Object asString Same as slotSummary. + asString := getSlot("slotSummary") + + //doc Object asSimpleString Returns _ string. + asSimpleString := method(getSlot("self") type .. "_" .. getSlot("self") uniqueHexId) + + /*doc Object newSlot(slotName, aValue) + Creates a getter and setter for the slot with the name slotName + and sets it's default the value aValue. Returns self. For example, + newSlot("foo", 1) would create slot named foo with the value 1 as well as a setter method setFoo(). + */ +/* + newSlot := method(name, value, doc, + getSlot("self") setSlot(name, getSlot("value")) + getSlot("self") setSlot("set" .. name asCapitalized, + doString("method(" .. name .. " = call evalArgAt(0); self)")) + //if(doc, getSlot("self") docSlot(name, doc)) + getSlot("value") + ) +*/ + //doc Object launchFile(pathString) Eval file at pathString as if from the command line in it's folder. + //doc System launchPath Returns a pathComponent of the launch file. + launchFile := method(path, args, + args ifNil(args = List clone) + System launchPath := path pathComponent + Directory setCurrentWorkingDirectory(System launchPath) + System launchScript = path + self doFile(path) + ) + + //doc Object println Same as print, but also prints a new line. Returns self. + println := method(getSlot("self") print; write("\n"); self) + + /*doc Object ?(aMessage) + description: Sends the message aMessage to the receiver if it can respond to it. Example: +
+	MyObject test // performs test
+	MyObject ?test // performs test if MyObject has a slot named test
+	
+ The search for the slot only follows the receivers proto chain. + */ + + // XXX TODO: replace the vm method with this one + /* + setSlot("?", + method( + m := call argAt(0) + if (self getSlot(m name) != nil, + call relayStopStatus(m doInContext(self, call sender)) + , + nil + ) + ) + )*/ + + //doc Object ancestors Returns a list of all of the receiver's ancestors as found by recursively following the protos links. + + ancestors := method(a, + if(a, if(a detect(x, x isIdenticalTo(self)), return a), a = List clone) + a append(self) + self protos foreach(ancestors(a)) + a + ) + + //doc Object isKindOf(anObject) Returns true if anObject is in the receiver's ancestors. + + isKindOf := method(anObject, getSlot("self") ancestors contains(getSlot("anObject"))) + + /*doc Object super(aMessage) + Sends the message aMessage to the receiver's proto with the context of self. Example: +
+	self test(1, 2)   // performs test(1, 2) on self
+	super(test(1, 2)) // performs test(1, 2) on self proto but with the context of self
+	
+ */ + + setSlot("super", method( + senderSlotContext := call sender call slotContext + m := call argAt(0) + m ifNil(Exception raise("Object super requires an argument")) + senderSlotContext ifNil(Exception raise("Object super called outside of block context")) + slotName := m name + ancestor := senderSlotContext ancestorWithSlot(slotName) + if(ancestor == nil, + slotName = "forward" + ancestor = senderSlotContext ancestorWithSlot(slotName) + ) + if(ancestor isIdenticalTo(senderSlotContext), Exception raise("Object super slot " .. slotName .. " not found")) + b := ancestor getSlot(slotName) + if(getSlot("b") isActivatable == false, + b + , + getSlot("b") performOn(call sender call target, call sender, m, ancestor) + ) + )) + + /*doc Object resend + Send the message used to activate the current method to the Object's proto. + For example: +
+  Dog := Mammal clone do(
+    init := method(
+  	  resend
+    )
+  )
+  
+ Calling Dog init will send an init method to Mammal, but using the Dog's context. + */ + + setSlot("resend", method( + senderSlotContext := call sender call slotContext + senderSlotContext ifNil(Exception raise("Object resend called outside of block context")) + m := call sender call message + slotName := m name + ancestor := senderSlotContext ancestorWithSlot(slotName) + + if(ancestor isIdenticalTo(nil), + slotName = "forward" + ancestor = senderSlotContext ancestorWithSlot(slotName) + ) + + if(ancestor isIdenticalTo(senderSlotContext), + Exception raise("Object resend slot " .. slotName .. " not found") + ) + + b := ancestor getSlot(slotName) + if(getSlot("b") != nil, + getSlot("b") performOn(call sender getSlot("self"), call sender call sender, m, ancestor) + , + getSlot("b") + ) + )) + + + //doc Object list(...) Returns a List containing the arguments. + list := method(call message argsEvaluatedIn(call sender)) + + Object print := method(write(getSlot("self") asString); getSlot("self")) + + //doc Object println Same as print, but also prints a new line. Returns self. + println := method(getSlot("self") print; write("\n"); getSlot("self")) + + //doc Object in(aList) Same as: aList contains(self) + in := method(aList, aList contains(self)) + + /*doc Object uniqueHexId + Returns uniqueId in a hexadecimal form (with a "0x" prefix) +
+  Io> Object uniqueId
+  ==> 3146784
+  Io> Object uniqueHexId
+  ==> 0x300420
+  
+ */ + uniqueHexId := method("0x" .. getSlot("self") uniqueId asString toBase(16)) + + /*doc Object lazySlot(code) + Defines a slot with a lazy initialization code. + Code is run only once: the first time slot is accessed. + Returned value is stored in a regular slot. +
+
+  Io> x := lazySlot("Evaluated!" println; 17)
+  Io> x
+  Evaluated!
+  ==> 17
+  Io> x
+  ==> 17
+  Io> x
+  ==> 17
+  
+
+ Another form is lazySlot(name, code): +
+
+  Io> lazySlot("x", "Evaluated!" println; 17)
+  Io> x
+  Evaluated!
+  ==> 17
+  Io> x
+  ==> 17
+  Io> x
+  ==> 17
+  
+ */ + lazySlot := method( + if(call argCount == 1, + m := method( + self setSlot(call message name, nil) + ) + + args := getSlot("m") message next arguments + args atPut(1, call argAt(0) clone) + getSlot("m") message next setArguments(args) + + getSlot("m") clone + , + name := call evalArgAt(0) + m := ("self setSlot(\"" .. name .. "\", " .. call argAt(1) code .. ")") asMessage + self setSlot(name, method() setMessage(m)) + nil + ) + ) + + /*doc Object foreachSlot(slotName, slotValue, code) + Iterates over all the slots in a receiver. Provides slotValue (non-activated) + along with slotName. Code is executed in context of sender. slotName and slotValue + become visible in the receiver (no Locals created! Maybe, it is not the best decision). +
+
+  Io> thisContext foreachSlot(n, v, n println)
+  Lobby
+  Protos
+  exit
+  forward
+  n
+  v
+  ==> false
+  
+ */ + foreachSlot := method( + self slotNames sort foreach(n, + call sender setSlot(call message argAt(0) name, n) + call sender setSlot(call message argAt(1) name, getSlot("self") getSlot(n)) + r := call relayStopStatus(call evalArgAt(2)) + if(call stopStatus isReturn, return getSlot("r")) + if(call stopStatus stopLooping, + call resetStopStatus + break + ) + ) + ) + + /*doc Object switch(, , , , ...) + Execute an expression depending on the value of the caller. (This is an equivalent to C switch/case) + + hour := Date hour switch( + 12, "midday", + 0, "midnight", + 17, "teatime", + Date hour asString + ) + + */ + + switch := method( + for(couple, 0, call argCount - 2, 2, + if(call evalArgAt(couple) == self, + return call relayStopStatus(call evalArgAt(couple + 1)) + ) + ) + if(call argCount isOdd, + call relayStopStatus(call evalArgAt(call argCount - 1)) + , + nil + ) + ) + + //doc Object isLaunchScript Returns true if the current file was run on the command line. Io's version of Python's __file__ == "__main__" + isLaunchScript := method( + call message label == System launchScript + ) + + /*doc Object doRelativeFile(pathString) + Evaluates the File in the context of the receiver. Returns the result. + pathString is relative to the file calling doRelativeFile. (Duplicate of relativeDoFile) + */ + doRelativeFile := method(path, + self doFile(Path with(call message label pathComponent, path)) + ) + + /*doc Object relativeDoFile(pathString) + Evaluates the File in the context of the receiver. Returns the result. + pathString is relative to the file calling doRelativeFile. (Duplicate of doRelativeFile) + */ + relativeDoFile := getSlot("doRelativeFile") + + /*doc Object deprecatedWarning(optionalNewName) + Prints a warning message that the current method is deprecated. + If optionalNewName is supplied, the warning will suggest using that instead. + Returns self. + */ + Object deprecatedWarning := method(newName, + writeln("Warning in ", call sender call message label, ": '", call sender call message name, "' is deprecated", if(newName, ". Use '" .. newName .. "' instead.", " and will be removed from a later version.")) + self + ) + + //referenceIdForObject := method(obj, getSlot("obj") unqiueId) + //objectForReferenceId := method(id, Collector objectWithUniqueId(id)) +) Added: pypy/branch/io-lang/pypy/lang/io/io/A4_Exception.io ============================================================================== --- (empty file) +++ pypy/branch/io-lang/pypy/lang/io/io/A4_Exception.io Thu Aug 13 22:16:18 2009 @@ -0,0 +1,425 @@ + +Call do( + //doc Call description Returns a description of the receiver as a String. + description := method( + m := self message + s := self target type .. " " .. m name + s alignLeft(36) .. " " .. m label lastPathComponent .. " " .. m lineNumber + ) + + /*doc Call delegateTo(target, altSender) + Sends the call's message to target (and relays it's stop status). + The sender is set to altSender, if it is supplied. + Returns the result of the message. + */ + delegateTo := method(target, altSender, + call relayStopStatus(target doMessage(self message clone setNext, altSender ifNilEval(self sender))) + ) + + /*doc Call delegateToMethod(target, methodName) + Sends the call's message to target via the method specified by methodName. + Returns the result of the message. + */ + delegateToMethod := method(target, methodName, + call relayStopStatus(target doMessage(self message clone setNext setName(methodName), self sender)) + ) + + /*doc Call evalArgs + Returns a list containing the call message arguments evaluated in the context of the sender. + */ + evalArgs := method(self message argsEvaluatedIn(sender)) + + /*doc Call hasArgs + Returns true if the call was passed arguments. + */ + hasArgs := method(argCount > 0) + + /*doc Call argCount + Returns the number of arguments for the call. Same as call message argCount. + */ + argCount := method(self message argCount) +) + +//doc Message description Returns a string containing a short description of the method. +Message description := method( + self name alignLeft(36) .. self label lastPathComponent .. " " .. self lineNumber +) + +Scheduler := Object clone do( + //doc Scheduler yieldingCoros The List of yielding Coroutine objects. + //doc Scheduler setYieldingCoros(aListOfCoros) Sets the list of yielding Coroutine objects. + yieldingCoros ::= List clone + + //doc Scheduler timers The List of active timers. + //doc Scheduler setTimers(aListOfTimers) Sets the list of active timers. + timers ::= List clone + + //doc Scheduler currentCoroutine Returns the currently running coroutine. + currentCoroutine := method(Coroutine currentCoroutine) + + waitForCorosToComplete := method( + while(yieldingCoros size > 0, yield) + ) +) + +Coroutine do( + //doc Coroutine stackSize Stack size allocated for each new coroutine. Coroutines will automatically chain themselves as need if more stack space is required. + //doc Coroutine setStackSize + stackSize ::= 128000*10 // PPC needs 128k for current parser + + //doc Coroutine exception Returns the current exception or nil if there is none. + //doc Coroutine setException + exception ::= nil + + //doc Coroutine parentCoroutine Returns the parent coroutine this one was chained from or nil if it wasn't chained. When a Coroutine ends, it will attempt to resume it's parent. + //doc Coroutine setParentCoroutine + parentCoroutine ::= nil + + //doc Coroutine runTarget The object which the coroutine will send a message to when it starts. + //doc Coroutine setRunTarget + runTarget ::= nil + + //doc Coroutine runLocals The locals object in whose context the coroutine will send it's run message. + //doc Coroutine setRunLocals + runLocals ::= nil + + //doc Coroutine runMessage The message to send to the runTarget when the coroutine starts. + //doc Coroutine setRunMessage + runMessage ::= nil + + //doc Coroutine result The result set when the coroutine ends. + //doc Coroutine setResult + result ::= nil + + //doc Coroutine label A label slot useful for debugging purposes. + //doc Coroutine setLabel + label ::= "" + + //doc Coroutine inException Set to true when processing an exception in the coroutine. + //doc Coroutine setInException + inException ::= false + + //doc Coroutine yieldingCoros Reference to Scheduler yieldingCoros. + //doc Coroutine setYieldingCoros + yieldingCoros ::= Scheduler yieldingCoros + //doc Coroutine debugWriteln (See Object debugWriteln.) + debugWriteln := nil + + label := method(self uniqueId) + setLabel := method(s, self label = s .. "_" .. self uniqueId) + + //doc Coroutine showYielding Prints a list of yielding coroutines to STDOUT. + showYielding := method(s, + writeln(" ", label, " ", s) + yieldingCoros foreach(v, writeln(" ", v uniqueId)) + ) + + //doc Coroutine isYielding Returns true if the receiver is yielding (not paused or running). + isYielding := method(yieldingCoros contains(self)) + + /*doc Coroutine yield + Yields to another coroutine in the yieldingCoros queue. + Does nothing if yieldingCoros is empty. + */ + yield := method( + //showYielding("yield") + //writeln("Coro ", self uniqueId, " yielding - yieldingCoros = ", yieldingCoros size) + if(yieldingCoros isEmpty, return) + yieldingCoros append(self) + next := yieldingCoros removeFirst + if(next == self, return) + //writeln(Scheduler currentCoroutine label, " yield - ", next label, " resume") + if(next, next resume) + ) + + /*doc Coroutine resumeLater + Promotes receiver to the top of the yieldingCoros queue, but not yielding to it. + When current coroutine yields, receiver will resume. + */ + resumeLater := method( + yieldingCoros remove(self) + yieldingCoros atInsert(0, self) + //writeln(self label, " resumeLater") + ) + + /*doc Coroutine pause + Removes current coroutine from the yieldingCoros queue and + yields to another coro. System exit is executed if no coros left. +
+ You can resume a coroutine using either resume or resumeLater message. + */ + pause := method( + yieldingCoros remove(self) + if(isCurrent, + next := yieldingCoros removeFirst + if(next, + next resume, + //Exception raise("Scheduler: nothing left to resume so we are exiting") + writeln("Scheduler: nothing left to resume so we are exiting") + self showStack + System exit + ) + , + yieldingCoros remove(self) + ) + ) + + //FIXME: these two methods are identical!! + //doc Coroutine yieldCurrentAndResumeSelf Yields to a receiver. + yieldCurrentAndResumeSelf := method( + //showYielding("yieldCurrentAndResumeSelf") + yieldingCoros remove(self) + isCurrent ifFalse(resume) + ) + //FIXME: these two methods are identical!! + //doc Coroutine pauseCurrentAndResumeSelf Pauses current coroutine and yields to a receiver. + pauseCurrentAndResumeSelf := method( + //showYielding("pauseCurrentAndResumeSelf") + yieldingCoros remove(self) + isCurrent ifFalse(resume) + ) + + //doc Coroutine typeId Returns _ string. + typeId := method(self type .. "_0x" .. self uniqueId asString toBase(16)) + + //doc Coroutine ignoredCoroutineMethodNames List of methods to ignore when building a callStack. + ignoredCoroutineMethodNames := list("setResult", "main", "pauseCurrentAndResumeSelf", "resumeParentCoroutine", "raiseException") + + //doc Coroutine callStack Returns a list of Call objects. + callStack := method( + stack := ioStack + stack selectInPlace(v, Object argIsCall(getSlot("v"))) reverseInPlace + stack selectInPlace(v, + (v target type == "Coroutine" and ignoredCoroutineMethodNames contains(v message name)) not + ) + stack foreach(i, v, if(v target type == "Importer" and v message name == "import", stack sliceInPlace(i+1); break) ) + stack := stack unique + stack + ) + + //doc Coroutine backTraceString Returns a formatted callStack output along with exception info (if any). In case of CGI script, wraps output with <code> tag. + backTraceString := method( + if(Coroutine inException, + writeln("\n", exception type, ": ", exception error, "\n\n") + writeln("Coroutine Exception loop detected"); + System exit + ) + Coroutine setInException(true) + buf := Sequence clone + + //writeln("backTraceString 1\n") + if(getSlot("CGI") != nil and CGI isInWebScript, buf appendSeq("")) + + if(exception, buf appendSeq("\n ", exception type, ": ", exception error, "\n")) + + //writeln("backTraceString 2\n") + if(callStack size > 0) then( + buf appendSeq(" ---------\n") + + if(exception and exception ?caughtMessage, + buf appendSeq(" ", exception caughtMessage description, "\n") + ) + + frames := callStack + + if(exception and exception originalCall, + index := frames indexOf(exception originalCall) + if(index, + frames sliceInPlace(index) + ) + ) + + frames foreach(v, + buf appendSeq(" ", v description, "\n") + ) + buf appendSeq("\n") + ) else( + buf appendSeq(" ---------\n") + if(exception and exception caughtMessage, + m := exception caughtMessage + buf appendSeq(" message '" .. m name .. "' in '" .. m label .. "' on line " .. m lineNumber .. "\n") + buf appendSeq("\n") + , + buf appendSeq(" nothing on stack\n") + ) + ) + + Coroutine setInException(false) + buf + ) + + //doc Coroutine showStack Writes backTraceString to STDOUT. + showStack := method(write(backTraceString)) + + //doc Coroutine resumeParentCoroutine Pauses current coroutine and resumes parent. + resumeParentCoroutine := method( + if(parentCoroutine, parentCoroutine pauseCurrentAndResumeSelf) + ) + + //doc Coroutine main [Seems to be obsolete!] Executes runMessage, resumes parent coroutine. + main := method( + setResult(self getSlot("runTarget") doMessage(runMessage, self getSlot("runLocals"))) + resumeParentCoroutine + pause + ) + + //doc Coroutine raiseException Sets exception in the receiver and resumes parent coroutine. + raiseException := method(e, + self setException(e) + resumeParentCoroutine + ) +) + +/*doc Object wait(s) +Pauses current coroutine for at least s seconds. +
+Note: current coroutine may wait much longer than designated number of seconds +depending on circumstances. +*/ + +Object wait := method(s, + //writeln("Scheduler yieldingCoros size = ", Scheduler yieldingCoros size) + if(Scheduler yieldingCoros isEmpty, + //writeln("System sleep") + System sleep(s) + , + //writeln("Object wait") + endDate := Date clone now + Duration clone setSeconds(s) + loop(endDate isPast ifTrue(break); yield) + ) +) + +Message do( + /*doc Message codeOfLength(n) + Same as Message code, but returns first n characters only. + */ + codeOfLength := method(length, + c := self code + if (c size < length, c, c exclusiveSlice(0, length) .. "...") asMutable replaceSeq("\n", ";") + ) + + //doc Message asStackEntry Returns a string containing message name, file and line. + asStackEntry := method( + label := label lastPathComponent fileName + label alignLeft(19) .. lineNumber asString alignLeft(7) .. name + ) +) + +Object do( + /*doc Object try(code) + Executes particular code in a new coroutine. + Returns exception or nil if no exception is caught. +
+ See also documentation for Exception catch and pass. + */ + try := method( + coro := Coroutine clone + coro setParentCoroutine(Scheduler currentCoroutine) + coro setRunTarget(call sender) + coro setRunLocals(call sender) + coro setRunMessage(call argAt(0)) + coro run + if(coro exception, coro exception, nil) + ) + + /*doc Object coroFor(code) + Returns a new coro to be run in a context of sender. + */ + coroFor := method( + coro := Coroutine clone + coro setRunTarget(call sender) + coro setRunLocals(call sender) + coro setRunMessage(call argAt(0)) + coro + ) + + /*doc Object coroDo(code) + Creates a new coro to be run in a context of sender and yields to it. + Returns a coro. + */ + coroDo := method( + coro := Coroutine clone + coro setRunTarget(call sender) + coro setRunLocals(call sender) + coro setRunMessage(call argAt(0)) + Coroutine yieldingCoros atInsert(0, Scheduler currentCoroutine) + coro run + coro + ) + + /*doc Object coroDoLater(code) + Returns a new coro to be run in a context of sender. + New coro is moved to the top of the yieldingCoros queue to be executed + when current coro yields. +
+ Note: run target is self (i.e. receiver), not call sender as in coroDo. + */ + coroDoLater := method( + coro := Coroutine clone + coro setRunTarget(self) + coro setRunLocals(call sender) + coro setRunMessage(call argAt(0)) + Coroutine yieldingCoros atInsert(0, coro) + coro + ) + + /*doc Object coroWith(code) + Returns a new coro to be run in a context of receiver. + */ + coroWith := method( + coro := Coroutine clone + coro setRunTarget(self) + coro setRunLocals(call sender) + coro setRunMessage(call argAt(0)) + coro + ) + //doc Object currentCoro Returns the currently running coroutine. + currentCoro := method(Coroutine currentCoroutine) +) + +nil do( + //doc nil catch Does nothing, returns nil. See Exception catch. + //doc nil pass Does nothing, returns nil. See Exception pass. + catch := nil + pass := nil +) +/* +Protos Exception do( + type := "Exception" + newSlot("error") + newSlot("coroutine") + newSlot("caughtMessage") + newSlot("nestedException") + newSlot("originalCall") + + raise := method(error, nestedException, + coro := Scheduler currentCoroutine + coro raiseException(self clone setError(error) setCoroutine(coro) setNestedException(nestedException)) + ) + + raiseFrom := method(originalCall, error, nestedException, + coro := Scheduler currentCoroutine + coro raiseException(self clone setError(error) setCoroutine(coro) setNestedException(nestedException) setOriginalCall(originalCall)) + ) + + catch := method(exceptionProto, + if (self isKindOf(exceptionProto), call evalArgAt(1); nil, self) + ) + + pass := method(Scheduler currentCoroutine raiseException(self)) + + showStack := method( + coroutine showStack + if(nestedException, + writeln("Nested Exception: '", nestedException, "'") + nestedException showStack + ) + ) +) + +System userInterruptHandler := method( + writeln("\nStack trace:\n") + Scheduler currentCoroutine showStack + exit +) +*/ \ No newline at end of file From david at codespeak.net Thu Aug 13 22:20:45 2009 From: david at codespeak.net (david at codespeak.net) Date: Thu, 13 Aug 2009 22:20:45 +0200 (CEST) Subject: [pypy-svn] r66813 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090813202045.4494A168015@codespeak.net> Author: david Date: Thu Aug 13 22:20:44 2009 New Revision: 66813 Added: pypy/branch/io-lang/pypy/lang/io/sequence.py pypy/branch/io-lang/pypy/lang/io/test/test_sequence.py Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py pypy/branch/io-lang/pypy/lang/io/test/test_parse.py Log: Sequence Object, Proto, .. and asCapitalized methods Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/objspace.py (original) +++ pypy/branch/io-lang/pypy/lang/io/objspace.py Thu Aug 13 22:20:44 2009 @@ -11,6 +11,7 @@ import pypy.lang.io.message import pypy.lang.io.map import pypy.lang.io.coroutine +import pypy.lang.io.sequence class ObjSpace(object): """docstring for ObjSpace""" @@ -36,7 +37,7 @@ self.w_eol = W_Object(self, [self.w_object]) # XXX TODO: change this when Sequence is implemented - self.w_sequence = W_Object(self, [self.w_object]) + self.w_sequence = W_ImmutableSequence(self, '',[self.w_object]) self.w_immutable_sequence = W_ImmutableSequence(self, '', [self.w_sequence]) # default stop state self.stop_status = self.w_normal @@ -67,6 +68,8 @@ self.init_w_flow_objects() + self.init_w_sequence() + def init_w_map(self): @@ -138,7 +141,7 @@ self.w_core.slots['Normal'].slots['type'] = W_ImmutableSequence(self, 'Normal') # Flow control: Break - self.w_core.slots['Break'] = self.w_block + self.w_core.slots['Break'] = self.w_break self.w_core.slots['Break'].slots['type'] = W_ImmutableSequence(self, 'Break') # Flow control: Continue @@ -158,6 +161,10 @@ for key, function in cfunction_definitions['Coroutine'].items(): self.w_coroutine.slots[key] = W_CFunction(self, function) + def init_w_sequence(self): + for key, function in cfunction_definitions['Sequence'].items(): + self.w_sequence.slots[key] = W_CFunction(self, function) + def break_status(self, result): self.stop_status = self.w_break self.w_return_value = result Added: pypy/branch/io-lang/pypy/lang/io/sequence.py ============================================================================== --- (empty file) +++ pypy/branch/io-lang/pypy/lang/io/sequence.py Thu Aug 13 22:20:44 2009 @@ -0,0 +1,14 @@ +from pypy.lang.io.register import register_method +from pypy.lang.io.model import W_Message, W_ImmutableSequence + + at register_method('Sequence', '..', unwrap_spec=[object, str]) +def sequence_append(space, w_sequence, w_append_seq): + s = space.w_sequence.clone() + s.value = w_sequence.value + w_append_seq + return s + + at register_method('Sequence', 'asCapitalized') +def sequence_as_capitalized(space, w_target, w_message, w_context): + s = space.w_sequence.clone() + s.value = w_target.value.capitalize() + return s \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_parse.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_parse.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_parse.py Thu Aug 13 22:20:44 2009 @@ -19,6 +19,6 @@ input = "a := b" ast = parse(input, space) a = W_Message(space, '"a"', []) - a.literal_value = W_ImmutableSequence(space, 'a') + a.literal_value = space.w_immutable_sequence.clone_and_init('a') assert ast == W_Message(space, "setSlot", [a, W_Message(space, 'b', [])], ) \ No newline at end of file Added: pypy/branch/io-lang/pypy/lang/io/test/test_sequence.py ============================================================================== --- (empty file) +++ pypy/branch/io-lang/pypy/lang/io/test/test_sequence.py Thu Aug 13 22:20:44 2009 @@ -0,0 +1,18 @@ +from pypy.lang.io.parserhack import parse, interpret +from pypy.lang.io.model import W_Object, W_Message, W_Number, W_ImmutableSequence + +def test_append(): + inp = '"lo" .. "rem"' + res, space = interpret(inp) + assert res.value == 'lorem' + +def test_append_returns_copy(): + inp = """ + a := "lo" + b := a .. "" + """ + res, space = interpret(inp) + assert space.w_lobby.slots['a'] is not space.w_lobby.slots['b'] + +def test_sequence_as_capitalized(): + inp = '"asdf qerttz" asCapitalized' \ No newline at end of file From david at codespeak.net Thu Aug 13 22:21:53 2009 From: david at codespeak.net (david at codespeak.net) Date: Thu, 13 Aug 2009 22:21:53 +0200 (CEST) Subject: [pypy-svn] r66814 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090813202153.51580168015@codespeak.net> Author: david Date: Thu Aug 13 22:21:52 2009 New Revision: 66814 Modified: pypy/branch/io-lang/pypy/lang/io/object.py pypy/branch/io-lang/pypy/lang/io/test/test_io_extensions.py pypy/branch/io-lang/pypy/lang/io/test/test_object.py Log: methods doString newSlot and updateSlot on object Modified: pypy/branch/io-lang/pypy/lang/io/object.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/object.py (original) +++ pypy/branch/io-lang/pypy/lang/io/object.py Thu Aug 13 22:21:52 2009 @@ -166,4 +166,30 @@ w_message.arguments[0].eval(space, w_context, w_context) w = space.stop_status space.normal_status() - return w \ No newline at end of file + return w + + at register_method('Object', 'doString', unwrap_spec=[object, str]) +def object_do_string(space, w_target, code): + # XXX Replace this when the actual parser is done + from parserhack import parse + ast = parse(code, space) + return ast.eval(space, w_target, w_target) + + +# XXX replace with the original one in A2_Object.io when it works + at register_method('Object', 'newSlot', unwrap_spec=[object, str, object]) +def object_new_slot(space, w_target, name, w_value): + from pypy.lang.io.model import W_CFunction + w_target.slots[name] = w_value + def setSlot(space, w_target, w_message, w_context): + w_target.slots[name] = w_message.arguments[0].eval(space, w_context, w_context) + return w_target + w_target.slots['set%s' % (name[0].capitalize() + name[1:])] = W_CFunction(space, setSlot) + + at register_method('Object', 'updateSlot', unwrap_spec=[object, str, object]) +def object_update_slot(space, w_target, slotname, w_value): + assert w_target.lookup(slotname) is not None + + w_target.slots[slotname] = w_value + return w_value + Modified: pypy/branch/io-lang/pypy/lang/io/test/test_io_extensions.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_io_extensions.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_io_extensions.py Thu Aug 13 22:21:52 2009 @@ -1,6 +1,6 @@ from pypy.lang.io.parserhack import interpret import py -from pypy.lang.io.model import W_Object, W_List +from pypy.lang.io.model import W_Object, W_List, W_Block def test_map_asObject(): inp = 'Map clone atPut("1", 12345) atPut("2", 99) atPut("3", 3) atPut("4", 234) asObject' @@ -16,11 +16,31 @@ assert isinstance(res, W_Object) assert res.protos == [space.w_object] -def test_map_as_lsit(): - py.test.skip('Depends on Map map wich itself depends on corroutines') +def test_map_as_lit(): + py.test.skip("Depends on ==") inp = 'Map clone atPut("1", 12345) atPut("2", 99) atPut("3", 3) atPut("4", 234) asList' res, space = interpret(inp) assert isinstance(res, W_List) l = [(ll.items[0].value, ll.items[1].value) for ll in res.items] assert l == [('1', 12345), ('2', 99), ('3', 3), ('4', 234)] +def test_new_slot(): + inp = """timers ::= 1""" + res, space = interpret(inp) + assert space.w_lobby.slots['timers'].value == 1 + # assert isinstance(space.w_lobby.slots['setTimers'], W_Block) + +def test_new_slot_complex(): + inp = """a := Object clone + a do( + timers ::= 1 + ) + a setTimers(99) + a timers""" + + res, space = interpret(inp) + assert res.value == 99 + a = space.w_lobby.slots['a'] + assert 'timers' in a.slots + assert 'setTimers' in a.slots + # assert isinstance(a.slots['setTimers'], W_Block) \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Thu Aug 13 22:21:52 2009 @@ -1,5 +1,5 @@ from pypy.lang.io.parserhack import parse, interpret -from pypy.lang.io.model import W_Object, W_Message, W_Number, W_ImmutableSequence +from pypy.lang.io.model import W_Object, W_Message, W_Number, W_ImmutableSequence, W_Block import py.test @@ -221,4 +221,37 @@ res, space = interpret(inp) assert isinstance(res.slots['type'], W_ImmutableSequence) assert res.slots['type'].value == 'foo' - assert space.w_lobby.slots['foo'] == res \ No newline at end of file + assert space.w_lobby.slots['foo'] == res + +def test_doString(): + inp = """doString("1")""" + res, space = interpret(inp) + assert res.value == 1 + +def test_doString_method(): + inp = """ + doString("method(" .. "foo" .. " = call evalArgAt(0); self)")""" + res, space = interpret(inp) + print res + assert isinstance(res, W_Block) +def test_doString_method2(): + py.test.skip() + inp = """ + foo := 234 + name := "foo" + setSlot("set" .. name asCapitalized, + doString("method(" .. name .. " = call evalArgAt(0); self)")) + setFoo(1)""" + res, space = interpret(inp) + assert res.slots['foo'].value == 1 +def test_object_update_slot(): + inp = """ + a := 3 + a = 5 + """ + res, space = interpret(inp) + assert res.value == 5 + assert space.w_lobby.slots['a'].value == 5 +def test_object_update_slot_raises(): + inp = 'qwer = 23' + py.test.raises(Exception, 'interpret(inp)') \ No newline at end of file From david at codespeak.net Thu Aug 13 22:22:49 2009 From: david at codespeak.net (david at codespeak.net) Date: Thu, 13 Aug 2009 22:22:49 +0200 (CEST) Subject: [pypy-svn] r66815 - pypy/branch/io-lang/pypy/lang/io/test Message-ID: <20090813202249.6A724168019@codespeak.net> Author: david Date: Thu Aug 13 22:22:49 2009 New Revision: 66815 Modified: pypy/branch/io-lang/pypy/lang/io/test/test_method.py Log: test fixes Modified: pypy/branch/io-lang/pypy/lang/io/test/test_method.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_method.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_method.py Thu Aug 13 22:22:49 2009 @@ -45,7 +45,8 @@ inp = 'Block' res,space = interpret(inp) assert isinstance(res, W_Block) - assert res.protos == [space.w_object] + assert len(res.protos) == 1 + assert res.protos[0] is space.w_object def test_call_on_method(): inp = 'a := method(x, x + 1); getSlot("a") call(3)' @@ -103,4 +104,13 @@ res, space = interpret(inp) assert space.w_object.slots['inlineMethod'] is not None assert res.value == 4 - \ No newline at end of file + + +def test_resolution_order(): + inp = """id := method(a, a) + test := method(name, getSlot("self") setSlot(3 + name, 33)) + test(7) + """ + res, space = interpret(inp) + assert res.value == 33 + assert space.w_lobby.slots[10].value == 33 \ No newline at end of file From david at codespeak.net Thu Aug 13 22:23:47 2009 From: david at codespeak.net (david at codespeak.net) Date: Thu, 13 Aug 2009 22:23:47 +0200 (CEST) Subject: [pypy-svn] r66816 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090813202347.7D23F168019@codespeak.net> Author: david Date: Thu Aug 13 22:23:46 2009 New Revision: 66816 Modified: pypy/branch/io-lang/pypy/lang/io/coroutine.py pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Log: run, setResult and setRunMessage on Coroutines Modified: pypy/branch/io-lang/pypy/lang/io/coroutine.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/coroutine.py (original) +++ pypy/branch/io-lang/pypy/lang/io/coroutine.py Thu Aug 13 22:23:46 2009 @@ -2,11 +2,27 @@ from pypy.lang.io.model import W_Object from pypy.lang.io.coroutinemodel import W_Coroutine - @register_method('Coroutine', 'currentCoroutine') def coroutine_get_current(space, w_target, w_message, w_context): return W_Coroutine.w_getcurrent(space) @register_method('Coroutine', 'isCurrent') def coroutine_is_current(space, w_target, w_message, w_context): - return space.newbool(w_target is W_Coroutine.w_getcurrent(space)) \ No newline at end of file + return space.newbool(w_target is W_Coroutine.w_getcurrent(space)) + + at register_method('Coroutine', 'setRunMessage', unwrap_spec=[object, object]) +def coroutine_setRunMessage(space, w_coroutine, w_message): + w_coroutine.slots['runMessage'] = w_message + return w_coroutine + + at register_method('Coroutine', 'run') +def coroutine_run(space, w_target, w_message, w_context): + w_target.run(space, w_target, w_context) + return w_target + +# @register_method('Coroutine', 'setResult', unwrap_spec=[object, object]) +# def coroutine_set_result(space, w_coro, w_result): +# print w_result +# w_coro.slots['result'] = w_result +# return w_coro +# \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py (original) +++ pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py Thu Aug 13 22:23:46 2009 @@ -1,3 +1,8 @@ +# XXX wtf +import greenlet +import py.magic +py.magic.__dict__['greenlet'] = greenlet.greenlet + from pypy.lang.io.model import W_Object from pypy.rlib.rcoroutine import make_coroutine_classes d = make_coroutine_classes(W_Object) @@ -14,7 +19,7 @@ W_Object.__init__(self, space, protos) def clone(self): - return W_Coroutine(self.space, self.state, [self]) + return W_Coroutine(self.space, self.costate, [self]) @staticmethod def w_getcurrent(space): @@ -27,6 +32,11 @@ space._coroutine_state = AppCoState(space) space._coroutine_state.post_install() return space._coroutine_state + + def run(self, space, w_receiver, w_context): + t = IoThunk(space, self.slots['runMessage'], w_receiver, w_context) + self.bind(t) + self.switch() class AppCoState(BaseCoState): def __init__(self, space): @@ -46,4 +56,5 @@ self.w_context = w_context def call(self): - self.w_message.eval(self.space, self.w_receiver, self.w_context) \ No newline at end of file + t = self.w_message.eval(self.space, self.w_receiver, self.w_context) + self.w_receiver.slots['result'] = t \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_coro.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_coro.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Thu Aug 13 22:23:46 2009 @@ -1,5 +1,7 @@ from pypy.lang.io.parserhack import parse, interpret from pypy.lang.io.model import W_Object +from pypy.lang.io.coroutinemodel import W_Coroutine + import py def test_isCurrent(): @@ -7,10 +9,58 @@ result, space = interpret(inp) assert result is space.w_true +def test_setRunMessage(): + inp = """m := message(1023) + c := Coroutine currentCoroutine + c setRunMessage(getSlot("m")) + """ + res, space = interpret(inp) + assert isinstance(res, W_Coroutine) + assert res.slots['runMessage'] is space.w_lobby.slots['m'] + +def test_run(): + inp = """a := 12 + c := Coroutine currentCoroutine + c setRunMessage(message(a := a + 1)) + c run + """ + res, space = interpret(inp) + assert isinstance(res, W_Coroutine) + assert res.slots['result'].value == 13 + assert space.w_lobby.slots['a'].value == 12 + +def test_result_slot_proto(): + inp = """Coroutine result""" + res, space = interpret(inp) + assert res == space.w_nil + +def test_set_result(): + inp = """ + c := Coroutine currentCoroutine clone + c setResult(99)""" + res, space = interpret(inp) + print res.slots + assert isinstance(res, W_Coroutine) + assert res.slots['result'].value == 99 + +def test_parentCoroutine_proto(): + inp = 'Coroutine parentCoroutine' + res, space = interpret(inp) + assert res is space.w_nil + +def test_parentCoroutine(): + inp = """ + Object try(Lobby foo := Coroutine currentCoroutine) + foo parentCoroutine + """ + res, space = interpret(inp) + assert isinstance(res, W_Coroutine) + assert res is space.w_lobby.slots['foo'].slots['parentCoroutine'] + def test_coro_resume(): py.test.skip() inp = """ - b := message(currentCoro setResult(23); currentCoro parentCoroutine resume; "bye" print) + b := message(Coroutine currentCoroutine setResult(23); Coroutine currentCoroutine parentCoroutine resume; "bye" print) a := Coroutine currentCoroutine clone a setRunMessage(b) run a result @@ -18,3 +68,27 @@ res,space = interpret(inp) assert res.value == 23 +def test_coro_stacksize(): + inp = 'Coroutine clone stackSize' + res, space = interpret(inp) + assert res.value == 128000*10 + +def test_coro_clone(): + inp = 'Coroutine clone' + res, space = interpret(inp) + assert isinstance(res, W_Coroutine) + +def test_scheduler_current_coro(): + inp = """list(Scheduler currentCoroutine, Coroutine currentCoroutine)""" + res, space = interpret(inp) + assert res.items[0] is res.items[1] + +def test_coroutine_corofor(): + inp = """ + a := 4 clone + a coroFor(message(99))""" + res, space = interpret(inp) + assert isinstance(res, W_Coroutine) + assert res.slots['runTarget'] is space.w_lobby + assert res.slots['runLocals'] is space.w_lobby + \ No newline at end of file From david at codespeak.net Fri Aug 14 00:33:50 2009 From: david at codespeak.net (david at codespeak.net) Date: Fri, 14 Aug 2009 00:33:50 +0200 (CEST) Subject: [pypy-svn] r66817 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090813223350.6A87C168026@codespeak.net> Author: david Date: Fri Aug 14 00:33:49 2009 New Revision: 66817 Modified: pypy/branch/io-lang/pypy/lang/io/object.py pypy/branch/io-lang/pypy/lang/io/objspace.py pypy/branch/io-lang/pypy/lang/io/test/test_object.py Log: write method on Object Modified: pypy/branch/io-lang/pypy/lang/io/object.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/object.py (original) +++ pypy/branch/io-lang/pypy/lang/io/object.py Fri Aug 14 00:33:49 2009 @@ -193,3 +193,9 @@ w_target.slots[slotname] = w_value return w_value + at register_method('Object', 'write') +def object_write(space, w_target, w_message, w_context): + for x in w_message.arguments: + e = x.eval(space, w_context, w_context) + space.w_print_message.eval(space, e, w_context) + return space.w_nil \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/objspace.py (original) +++ pypy/branch/io-lang/pypy/lang/io/objspace.py Fri Aug 14 00:33:49 2009 @@ -70,6 +70,7 @@ self.init_w_sequence() + self.init_stored_messages() def init_w_map(self): @@ -189,4 +190,7 @@ def newbool(self, value): if value: return self.w_true - return self.w_false \ No newline at end of file + return self.w_false + + def init_stored_messages(self): + self.w_print_message = W_Message(self, 'print', []) \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Fri Aug 14 00:33:49 2009 @@ -254,4 +254,20 @@ assert space.w_lobby.slots['a'].value == 5 def test_object_update_slot_raises(): inp = 'qwer = 23' - py.test.raises(Exception, 'interpret(inp)') \ No newline at end of file + py.test.raises(Exception, 'interpret(inp)') + +def test_object_write(): + inp = """ + p := Object clone do( + print := method( + self printed := true + ) + ) + a := p clone + b := p clone + write(a, b) + """ + res, space = interpret(inp) + assert res is space.w_nil + assert space.w_lobby.slots['a'].slots['printed'] is space.w_true + assert space.w_lobby.slots['b'].slots['printed'] is space.w_true \ No newline at end of file From pedronis at codespeak.net Fri Aug 14 09:35:17 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Aug 2009 09:35:17 +0200 (CEST) Subject: [pypy-svn] r66818 - pypy/trunk/lib-python Message-ID: <20090814073517.1DDED168022@codespeak.net> Author: pedronis Date: Fri Aug 14 09:35:16 2009 New Revision: 66818 Modified: pypy/trunk/lib-python/conftest.py Log: another py.lib 1.0 fix Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Fri Aug 14 09:35:16 2009 @@ -633,9 +633,9 @@ if exit_status: raise self.ExternalFailure(test_stdout, test_stderr) - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if not excinfo.errisinstance(self.ExternalFailure): - return super(ReallyRunFileExternal, self).repr_failure(excinfo, outerr) + return super(ReallyRunFileExternal, self).repr_failure(excinfo) out, err = excinfo.value.args return out + err From pedronis at codespeak.net Fri Aug 14 09:54:33 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Aug 2009 09:54:33 +0200 (CEST) Subject: [pypy-svn] r66819 - pypy/branch/pyjitpl5/lib-python Message-ID: <20090814075433.B677F168028@codespeak.net> Author: pedronis Date: Fri Aug 14 09:54:33 2009 New Revision: 66819 Modified: pypy/branch/pyjitpl5/lib-python/conftest.py Log: merge 66818 from trunk Modified: pypy/branch/pyjitpl5/lib-python/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/lib-python/conftest.py (original) +++ pypy/branch/pyjitpl5/lib-python/conftest.py Fri Aug 14 09:54:33 2009 @@ -636,9 +636,9 @@ if exit_status: raise self.ExternalFailure(test_stdout, test_stderr) - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if not excinfo.errisinstance(self.ExternalFailure): - return super(ReallyRunFileExternal, self).repr_failure(excinfo, outerr) + return super(ReallyRunFileExternal, self).repr_failure(excinfo) out, err = excinfo.value.args return out + err From arigo at codespeak.net Fri Aug 14 12:49:21 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 12:49:21 +0200 (CEST) Subject: [pypy-svn] r66820 - pypy/branch/pyjitpl5-guardovf/lib-python Message-ID: <20090814104921.1350416802A@codespeak.net> Author: arigo Date: Fri Aug 14 12:49:20 2009 New Revision: 66820 Modified: pypy/branch/pyjitpl5-guardovf/lib-python/conftest.py Log: Merge r66818 from trunk. Modified: pypy/branch/pyjitpl5-guardovf/lib-python/conftest.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/lib-python/conftest.py (original) +++ pypy/branch/pyjitpl5-guardovf/lib-python/conftest.py Fri Aug 14 12:49:20 2009 @@ -636,9 +636,9 @@ if exit_status: raise self.ExternalFailure(test_stdout, test_stderr) - def repr_failure(self, excinfo, outerr): + def repr_failure(self, excinfo): if not excinfo.errisinstance(self.ExternalFailure): - return super(ReallyRunFileExternal, self).repr_failure(excinfo, outerr) + return super(ReallyRunFileExternal, self).repr_failure(excinfo) out, err = excinfo.value.args return out + err From fijal at codespeak.net Fri Aug 14 14:33:48 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 14 Aug 2009 14:33:48 +0200 (CEST) Subject: [pypy-svn] r66821 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp Message-ID: <20090814123348.F21C716802D@codespeak.net> Author: fijal Date: Fri Aug 14 14:33:47 2009 New Revision: 66821 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/codewriter.py Log: kill outdated code Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/codewriter.py Fri Aug 14 14:33:47 2009 @@ -240,53 +240,6 @@ typedescr = self.cpu.typedescrof(CLASS) self.class_sizes.append((cls, typedescr)) - - if 0: # disabled - def fixed_list_descr_for_tp(self, TP): - try: - return self.fixed_list_cache[TP.TO] - except KeyError: - OF = TP.TO.OF - rtyper = self.rtyper - setfunc, _ = support.builtin_func_for_spec(rtyper, 'list.setitem', - [TP, lltype.Signed, OF], - lltype.Void) - getfunc, _ = support.builtin_func_for_spec(rtyper, 'list.getitem', - [TP, lltype.Signed], OF) - malloc_func, _ = support.builtin_func_for_spec(rtyper, 'newlist', - [lltype.Signed, OF], - TP) - len_func, _ = support.builtin_func_for_spec(rtyper, 'list.len', - [TP], lltype.Signed) -## if isinstance(TP.TO, lltype.GcStruct): -## append_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.append', -## [TP, OF], lltype.Void) -## pop_func, _ = support.builtin_func_for_spec(rtyper, 'list.pop', -## [TP], OF) -## insert_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.insert', [TP, lltype.Signed, OF], lltype.Void) - tp = getkind(OF) -## if isinstance(TP.TO, lltype.GcStruct): -## ld = ListDescr(history.ConstAddr(getfunc.value, self.cpu), -## history.ConstAddr(setfunc.value, self.cpu), -## history.ConstAddr(malloc_func.value, self.cpu), -## history.ConstAddr(append_func.value, self.cpu), -## history.ConstAddr(pop_func.value, self.cpu), -## history.ConstAddr(insert_func.value, self.cpu), -## history.ConstAddr(len_func.value, self.cpu), -## history.ConstAddr(nonzero_func.value, self.cpu), -## tp) -## else: - ld = FixedListDescr(history.ConstAddr(getfunc.value, self.cpu), - history.ConstAddr(setfunc.value, self.cpu), - history.ConstAddr(malloc_func.value, self.cpu), - history.ConstAddr(len_func.value, self.cpu), - tp) - self.fixed_list_cache[TP.TO] = ld - return ld - - class BytecodeMaker(object): debug = False From fijal at codespeak.net Fri Aug 14 14:34:12 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 14 Aug 2009 14:34:12 +0200 (CEST) Subject: [pypy-svn] r66822 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp Message-ID: <20090814123412.6A596168033@codespeak.net> Author: fijal Date: Fri Aug 14 14:34:11 2009 New Revision: 66822 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/specnode.py Log: Avoid rpython warnings Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py Fri Aug 14 14:34:11 2009 @@ -580,6 +580,7 @@ def optimize_GETFIELD_GC(self, op): value = self.getvalue(op.args[0]) + assert isinstance(value, AbstractVirtualStructValue) if value.is_virtual(): # optimizefindnode should ensure that fieldvalue is found fieldvalue = value.getfield(op.descr, None) @@ -621,6 +622,7 @@ def optimize_ARRAYLEN_GC(self, op): value = self.getvalue(op.args[0]) if value.is_virtual(): + assert isinstance(value, VArrayValue) assert op.result.getint() == value.getlength() self.make_constant(op.result) else: @@ -632,6 +634,7 @@ indexbox = op.args[1] if value.is_virtual() and self.is_constant(indexbox): # optimizefindnode should ensure that itemvalue is found + assert isinstance(value, VArrayValue) itemvalue = value.getitem(indexbox.getint(), None) assert itemvalue is not None self.make_equal_to(op.result, itemvalue) @@ -647,6 +650,7 @@ value = self.getvalue(op.args[0]) indexbox = op.args[1] if value.is_virtual() and self.is_constant(indexbox): + assert isinstance(value, VArrayValue) value.setitem(indexbox.getint(), self.getvalue(op.args[2])) else: value.make_nonnull() Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/specnode.py Fri Aug 14 14:34:11 2009 @@ -1,10 +1,17 @@ from pypy.tool.pairtype import extendabletype +class PurelyAbstractBaseClass(NotImplementedError): + pass class SpecNode(object): __metaclass__ = extendabletype # extended in optimizefindnode.py __slots__ = () + def equals(self, other): + raise PurelyAbstractBaseClass() + + def extract_runtime_data(self, cpu, valuebox, resultlist): + raise PurelyAbstractBaseClass() class NotSpecNode(SpecNode): __slots__ = () From fijal at codespeak.net Fri Aug 14 14:34:46 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 14 Aug 2009 14:34:46 +0200 (CEST) Subject: [pypy-svn] r66823 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test Message-ID: <20090814123446.30C2A168030@codespeak.net> Author: fijal Date: Fri Aug 14 14:34:45 2009 New Revision: 66823 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizeopt.py Log: boxkinds is IMO about types of boxes, not an additional way of storing constants. A fix and a test Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/oparser.py Fri Aug 14 14:34:45 2009 @@ -120,9 +120,9 @@ elif arg.startswith('ConstPtr('): name = arg[len('ConstPtr('):-1] if self.type_system == 'lltype': - return ConstPtr(self.boxkinds[name]) + return ConstPtr(self.consts[name]) else: - return ConstObj(self.boxkinds[name]) + return ConstObj(self.consts[name]) return self.vars[arg] def parse_op(self, line): Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_oparser.py Fri Aug 14 14:34:45 2009 @@ -1,5 +1,5 @@ -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, llmemory from pypy.jit.metainterp.test.oparser import parse from pypy.jit.metainterp.resoperation import rop @@ -112,3 +112,12 @@ assert isinstance(b.f0, BoxFloat) assert isinstance(b.f1, BoxFloat) +def test_getvar_const_ptr(): + x = ''' + [] + call(ConstPtr(func_ptr)) + ''' + TP = lltype.GcArray(lltype.Signed) + NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) + loop = parse(x, None, {'func_ptr' : NULL}) + assert loop.operations[0].args[0].value == NULL Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizefindnode.py Fri Aug 14 14:34:45 2009 @@ -50,6 +50,7 @@ ('other', lltype.Ptr(NODE))) node = lltype.malloc(NODE) nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) + myptr = nodebox.value nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) @@ -87,6 +88,7 @@ node = ootype.new(NODE) nodebox = BoxObj(ootype.cast_to_object(node)) + myptr = nodebox.value nodebox2 = BoxObj(ootype.cast_to_object(node)) valuedescr = cpu.fielddescrof(NODE, 'value') nextdescr = cpu.fielddescrof(NODE, 'next') Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/test/test_optimizeopt.py Fri Aug 14 14:34:45 2009 @@ -346,8 +346,8 @@ fail() jump() """ - self.optimize_loop(ops, '', ops, p1=self.nodebox.value, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, '', ops, p1=self.nodebox.value) + def test_p123_simple(self): ops = """ @@ -760,8 +760,7 @@ [i] jump(5) """ - self.optimize_loop(ops, 'Not', expected, i1=5, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, 'Not', expected, i1=5) def test_getfield_gc_nonpure_2(self): ops = """ @@ -770,8 +769,7 @@ jump(i1) """ expected = ops - self.optimize_loop(ops, 'Not', expected, i1=5, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, 'Not', expected, i1=5) def test_varray_1(self): ops = """ From fijal at codespeak.net Fri Aug 14 14:36:13 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 14 Aug 2009 14:36:13 +0200 (CEST) Subject: [pypy-svn] r66824 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86 Message-ID: <20090814123613.B7CFB168032@codespeak.net> Author: fijal Date: Fri Aug 14 14:36:13 2009 New Revision: 66824 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py Log: The "oops" kind of changes, that broke tests. Fix. Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/regalloc.py Fri Aug 14 14:36:13 2009 @@ -738,7 +738,7 @@ reg = None boxsize = sizeofbox(arg) if (arg not in self.loop_consts and self.longevity[arg][1] > -1 and - boxsize == WORD): # only allocate regs for WORD size + boxsize == 1): # only allocate regs for WORD size reg = self.try_allocate_reg(arg) if reg: locs[i] = reg @@ -1105,13 +1105,13 @@ scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) - self.eventually_free_vars(op.args) if scale > 2: # float number... self.force_float_in_reg(op.args[2]) value_loc = st0 else: value_loc = self.make_sure_var_in_reg(op.args[2], op.args) + self.eventually_free_vars(op.args) if ptr: gc_ll_descr = self.assembler.cpu.gc_ll_descr gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) From fijal at codespeak.net Fri Aug 14 14:36:58 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 14 Aug 2009 14:36:58 +0200 (CEST) Subject: [pypy-svn] r66825 - pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test Message-ID: <20090814123658.26860168032@codespeak.net> Author: fijal Date: Fri Aug 14 14:36:57 2009 New Revision: 66825 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Log: Finish test Modified: pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/backend/x86/test/test_regalloc2.py Fri Aug 14 14:36:57 2009 @@ -4,12 +4,20 @@ from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.runner import CPU from pypy.jit.metainterp.test.oparser import parse +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.annlowlevel import llhelper class TestRegalloc(object): - namespace = { - } - type_system = 'lltype' cpu = CPU(None, None) + def func(f1, f2): + print f1, f2 + return f1 + f2*10.0 + FPTR = lltype.Ptr(lltype.FuncType([lltype.Float] * 2, lltype.Float)) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) + + namespace = locals().copy() + type_system = 'lltype' def parse(self, s, boxkinds=None): return parse(s, self.cpu, self.namespace, @@ -67,13 +75,15 @@ assert self.getint(0) == 0 def test_float_call_st0_sync(self): - py.test.skip("XXX finish") + py.test.skip("in-progress") ops = ''' [f0, f1] f2 = float_add(f0, f1) - call(f2, descr=calldescr) + f3 = call(ConstClass(func_ptr), f2, f0, descr=calldescr) + fail(f3) ''' - xxx + self.interpret(ops, [0.5, 1.5]) + assert self.getfloat(0) == 3.0 def test_bug_rshift(): v1 = BoxInt() From pedronis at codespeak.net Fri Aug 14 15:22:08 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Aug 2009 15:22:08 +0200 (CEST) Subject: [pypy-svn] r66826 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem Message-ID: <20090814132208.4E80B16801B@codespeak.net> Author: pedronis Date: Fri Aug 14 15:22:07 2009 New Revision: 66826 Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Log: comment Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Fri Aug 14 15:22:07 2009 @@ -844,6 +844,7 @@ for libname in libraries: libpath = None for dir in eci.library_dirs: + # xxx untested directly, what about 'lib' prefix if sys.platform == "win32": tryfile = os.path.join(dir, libname + '.dll') elif sys.platform == "darwin": From fijall at gmail.com Fri Aug 14 15:19:27 2009 From: fijall at gmail.com (Maciej Fijalkowski) Date: Fri, 14 Aug 2009 07:19:27 -0600 Subject: [pypy-svn] r66826 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem In-Reply-To: <20090814132208.4E80B16801B@codespeak.net> References: <20090814132208.4E80B16801B@codespeak.net> Message-ID: <693bc9ab0908140619m49a5ae97u507bd5e056562cc7@mail.gmail.com> The better version of this is on trunk (and tested) (*I think*) On Fri, Aug 14, 2009 at 7:22 AM, wrote: > Author: pedronis > Date: Fri Aug 14 15:22:07 2009 > New Revision: 66826 > > Modified: > ? pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py > Log: > comment > > Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py > ============================================================================== > --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py (original) > +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Fri Aug 14 15:22:07 2009 > @@ -844,6 +844,7 @@ > ? ? ? ? for libname in libraries: > ? ? ? ? ? ? libpath = None > ? ? ? ? ? ? for dir in eci.library_dirs: > + ? ? ? ? ? ? ? ?# xxx untested directly, what about 'lib' prefix > ? ? ? ? ? ? ? ? if sys.platform == "win32": > ? ? ? ? ? ? ? ? ? ? tryfile = os.path.join(dir, libname + '.dll') > ? ? ? ? ? ? ? ? elif sys.platform == "darwin": > _______________________________________________ > pypy-svn mailing list > pypy-svn at codespeak.net > http://codespeak.net/mailman/listinfo/pypy-svn > From arigo at codespeak.net Fri Aug 14 17:07:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 17:07:25 +0200 (CEST) Subject: [pypy-svn] r66827 - in pypy/branch/pyjitpl5/pypy: config jit/metainterp translator Message-ID: <20090814150725.6463D168024@codespeak.net> Author: arigo Date: Fri Aug 14 17:07:24 2009 New Revision: 66827 Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/translator/driver.py Log: Add the option --jit-debug to select the DEBUG level and use the PROFILER from translate.py without having to edit the source code. Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Fri Aug 14 17:07:24 2009 @@ -107,6 +107,10 @@ ChoiceOption("jit_backend", "choose the backend for the JIT", ["auto", "minimal", "x86", "llvm"], default="auto", cmdline="--jit-backend"), + ChoiceOption("jit_debug", "the amount of debugging dumps made by the JIT", + ["off", "profile", "steps", "detailed"], + default="steps", # XXX for now + cmdline="--jit-debug"), # misc BoolOption("verbose", "Print extra information", default=False), Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Fri Aug 14 17:07:24 2009 @@ -22,6 +22,12 @@ # debug level: 0 off, 1 normal, 2 detailed DEBUG = 1 +# translate.py overrides DEBUG with the --jit-debug=xxx option +_DEBUG_LEVEL = {"off": 0, + "profile": 0, + "steps": 1, + "detailed": 2} + def log(msg): if not we_are_translated(): history.log.info(msg) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Fri Aug 14 17:07:24 2009 @@ -26,19 +26,19 @@ # ____________________________________________________________ # Bootstrapping -PROFILE = False - -def apply_jit(translator, backend_name="auto", **kwds): +def apply_jit(translator, backend_name="auto", debug_level="steps", **kwds): if 'CPUClass' not in kwds: from pypy.jit.backend.detect_cpu import getcpuclass kwds['CPUClass'] = getcpuclass(backend_name) - if PROFILE: + pyjitpl.DEBUG = pyjitpl._DEBUG_LEVEL[debug_level] + if debug_level != "off": profile = Profiler else: profile = None warmrunnerdesc = WarmRunnerDesc(translator, translate_support_code=True, listops=True, + #inline=True, profile=profile, **kwds) warmrunnerdesc.finish() Modified: pypy/branch/pyjitpl5/pypy/translator/driver.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/driver.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/driver.py Fri Aug 14 17:07:24 2009 @@ -389,6 +389,7 @@ # from pypy.jit.metainterp.warmspot import apply_jit apply_jit(self.translator, policy=self.jitpolicy, + debug_level=self.config.translation.jit_debug, backend_name=self.config.translation.jit_backend) # self.log.info("the JIT compiler was generated") @@ -403,6 +404,7 @@ # from pypy.jit.metainterp.warmspot import apply_jit apply_jit(self.translator, policy=self.jitpolicy, + debug_level=self.config.translation.jit_debug, backend_name='cli') #XXX # self.log.info("the JIT compiler was generated") From benjamin at codespeak.net Fri Aug 14 17:19:02 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 14 Aug 2009 17:19:02 +0200 (CEST) Subject: [pypy-svn] r66828 - in pypy/branch/parser-compiler/pypy: interpreter objspace/std objspace/std/test Message-ID: <20090814151902.6895716802A@codespeak.net> Author: benjamin Date: Fri Aug 14 17:19:00 2009 New Revision: 66828 Added: pypy/branch/parser-compiler/pypy/objspace/std/test/test_viewlist.py pypy/branch/parser-compiler/pypy/objspace/std/viewlist.py Modified: pypy/branch/parser-compiler/pypy/interpreter/baseobjspace.py pypy/branch/parser-compiler/pypy/objspace/std/objspace.py Log: add a viewlist implementation Modified: pypy/branch/parser-compiler/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/baseobjspace.py Fri Aug 14 17:19:00 2009 @@ -1205,6 +1205,7 @@ 'is_w', 'newtuple', 'newlist', + 'newviewlist', 'newdict', 'newslice', 'call_args', Modified: pypy/branch/parser-compiler/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/parser-compiler/pypy/objspace/std/objspace.py (original) +++ pypy/branch/parser-compiler/pypy/objspace/std/objspace.py Fri Aug 14 17:19:00 2009 @@ -589,6 +589,15 @@ from pypy.objspace.std.listobject import W_ListObject return W_ListObject(list_w) + def newviewlist(self, context, getitem, setitem, delitem, append, length): + assert self.config.objspace.std.withmultilist, "view lists require " \ + "multilists" + from pypy.objspace.std.listmultiobject import W_ListMultiObject + from pypy.objspace.std.viewlist import ViewListImplementation + impl = ViewListImplementation(self, context, getitem, setitem, delitem, + append, length) + return W_ListMultiObject(self, impl) + def newdict(self, module=False): if self.config.objspace.std.withmultidict and module: from pypy.objspace.std.dictmultiobject import W_DictMultiObject Added: pypy/branch/parser-compiler/pypy/objspace/std/test/test_viewlist.py ============================================================================== --- (empty file) +++ pypy/branch/parser-compiler/pypy/objspace/std/test/test_viewlist.py Fri Aug 14 17:19:00 2009 @@ -0,0 +1,86 @@ +import py +from pypy.conftest import gettestobjspace +from pypy.interpreter.error import OperationError + + +class TestViewList: + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withmultilist" : True}) + + def get_list(self, ctx): + space = self.space + l_w = [space.wrap(i) for i in (1, 2, 3)] + def get(space, context, i): + assert context is ctx + return l_w[i] + def set(space, context, i, what): + assert context is ctx + def app(space, context, what): + assert context is ctx + l_w.append(what) + def delete(space, context, i): + assert context is ctx + raise OperationError(space.w_OSError, space.wrap("can't do that..")) + def length(space, context): + return len(l_w) + return space.newviewlist(ctx, get, set, delete, app, length) + + def test_simple_operations(self): + space = self.space + ctx = object() + w_list = self.get_list(ctx) + w_0, w_1, w_2, w_3 = [space.wrap(i) for i in range(4)] + assert space.eq_w(space.getitem(w_list, w_0), w_1) + assert space.eq_w(space.getitem(w_list, w_1), w_2) + assert space.eq_w(space.getitem(w_list, w_2), w_3) + assert space.eq_w(space.len(w_list), w_3) + exc = py.test.raises(OperationError, space.getitem, w_list, w_3).value + assert exc.match(space, space.w_IndexError) + exc = py.test.raises(OperationError, space.delitem, w_list, w_1).value + assert exc.match(space, space.w_OSError) + + def test_setitem(self): + space = self.space + ctx = object() + w_list = self.get_list(ctx) + space.setitem(w_list, space.wrap(2), space.wrap(23)) + # Our test viewlist doesn't do anything for setting. + assert space.eq_w(space.getitem(w_list, space.wrap(2)), space.wrap(3)) + w_4 = space.wrap(4) + exc = py.test.raises(OperationError, space.setitem, w_list, w_4, w_4) + exc = exc.value + assert exc.match(space, space.w_IndexError) + + def test_length(self): + space = self.space + w_l = self.get_list(object()) + assert space.int_w(space.len(w_l)) == 3 + + def test_add(self): + space = self.space + ctx = object() + w_l1 = self.get_list(ctx) + w_l2 = self.get_list(ctx) + w_added = space.add(w_l1, w_l2) + unwrapped = [space.int_w(w_v) for w_v in space.viewiterable(w_added)] + assert unwrapped == [1, 2, 3]*2 + + def test_append(self): + space = self.space + w_list = self.get_list(object()) + w_app = space.getattr(w_list, space.wrap("append")) + space.call_function(w_app, space.wrap(4)) + assert space.int_w(space.len(w_list)) == 4 + assert space.eq_w(space.getitem(w_list, space.wrap(3)), space.wrap(4)) + + def test_extend(self): + space = self.space + w_list = self.get_list(object()) + w_a = space.wrap("a") + w_b = space.wrap("b") + w_new = space.newlist([w_a, w_b]) + space.call_method(w_list, "extend", w_new) + assert space.int_w(space.len(w_list)) == 5 + assert space.eq_w(space.getitem(w_list, space.wrap(3)), w_a) + assert space.eq_w(space.getitem(w_list, space.wrap(4)), w_b) Added: pypy/branch/parser-compiler/pypy/objspace/std/viewlist.py ============================================================================== --- (empty file) +++ pypy/branch/parser-compiler/pypy/objspace/std/viewlist.py Fri Aug 14 17:19:00 2009 @@ -0,0 +1,48 @@ +from pypy.objspace.std.listmultiobject import ListImplementation + + +class ViewListImplementation(ListImplementation): + + def __init__(self, space, context, getitem, setitem, delitem, append, + length): + self.space = space + self.context = context + self.getitem_hook = getitem + self.setitem_hook = setitem + self.delitem_hook = delitem + self.append_hook = append + self.length_hook = length + + def getitem(self, i): + return self.getitem_hook(self.space, self.context, i) + + def getitem_slice(self, start, stop): + return [self.getitem(i) for i in range(start, stop)] + + def setitem(self, i, w_something): + self.setitem_hook(self.space, self.context, i, w_something) + return self + + def delitem(self, i): + self.delitem_hook(self.space, self.context, i) + return self + + def delitem_slice(self, start, stop): + for i in range(start, stop): + self.delitem(i) + return self + + def append(self, w_something): + self.append_hook(self.space, self.context, w_something) + return self + + def extend(self, other): + for w_something in other.get_list_w(): + self.append(w_something) + return self + + def length(self): + return self.length_hook(self.space, self.context) + + def get_list_w(self): + return [self.getitem(i) for i in range(self.length())] From arigo at codespeak.net Fri Aug 14 18:26:41 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 18:26:41 +0200 (CEST) Subject: [pypy-svn] r66829 - pypy/branch/pyjitpl5/pypy/module/pypyjit Message-ID: <20090814162641.2B698168031@codespeak.net> Author: arigo Date: Fri Aug 14 18:26:39 2009 New Revision: 66829 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py Log: Kill unused imports. Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/policy.py Fri Aug 14 18:26:39 2009 @@ -1,8 +1,5 @@ -import pypy from pypy.jit.metainterp.policy import ManualJitPolicy -from pypy.translator.backendopt.support import find_calls_from - class PyPyJitPolicy(ManualJitPolicy): def look_inside_function(self, func): From arigo at codespeak.net Fri Aug 14 18:31:49 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 18:31:49 +0200 (CEST) Subject: [pypy-svn] r66830 - pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/cli Message-ID: <20090814163149.C347816802A@codespeak.net> Author: arigo Date: Fri Aug 14 18:31:49 2009 New Revision: 66830 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/cli/method.py Log: Add (unimplemented) the guard_overflow operations here too. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/cli/method.py Fri Aug 14 18:31:49 2009 @@ -455,6 +455,12 @@ self.il.Emit(OpCodes.Ldfld, self.exc_value_field) self.store_result(op) + def emit_op_guard_no_overflow(self, op): + pass # XXX implement me! + + def emit_op_guard_overflow(self, op): + pass # XXX implement me! + def emit_op_jump(self, op): target = op.jump_target assert len(op.args) == len(target.inputargs) From pedronis at codespeak.net Fri Aug 14 18:38:47 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Aug 2009 18:38:47 +0200 (CEST) Subject: [pypy-svn] r66831 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem Message-ID: <20090814163847.8B1C516802D@codespeak.net> Author: pedronis Date: Fri Aug 14 18:38:47 2009 New Revision: 66831 Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Log: tweak to find lib gc on darwin on some setups Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Fri Aug 14 18:38:47 2009 @@ -806,6 +806,33 @@ # ____________________________________________ +# xxx from ctypes.util, this code is a useful fallback on darwin too +if sys.platform == 'darwin': + # Andreas Degert's find function using gcc + import re, tempfile, errno + + def _findLib_gcc_fallback(name): + expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) + fdout, ccout = tempfile.mkstemp() + os.close(fdout) + cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \ + '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name + try: + f = os.popen(cmd) + trace = f.read() + f.close() + finally: + try: + os.unlink(ccout) + except OSError, e: + if e.errno != errno.ENOENT: + raise + res = re.search(expr, trace) + if not res: + return None + return res.group(0) +else: + _findLib_gcc_fallback = lambda name: None def get_ctypes_callable(funcptr, calling_conv): if not ctypes: @@ -856,6 +883,8 @@ break if not libpath: libpath = ctypes.util.find_library(libname) + if not libpath: + libpath = _findLib_gcc_fallback(libname) if not libpath and os.path.isabs(libname): libpath = libname if libpath: From pedronis at codespeak.net Fri Aug 14 18:47:47 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Aug 2009 18:47:47 +0200 (CEST) Subject: [pypy-svn] r66832 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090814164747.2979E16802D@codespeak.net> Author: pedronis Date: Fri Aug 14 18:47:46 2009 New Revision: 66832 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Log: on some platform GC_init must be called before any other GC_* function, ensure it is called for the benefit of tests, in translated code with boehm we have startup code that does that Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Fri Aug 14 18:47:46 2009 @@ -39,6 +39,16 @@ _nowrapper=True) self.funcptr_for_new = malloc_fn_ptr + # on some platform GC_init is required before any other + # GC_* functions, call it here for the benefit of tests + init_fn_ptr = rffi.llexternal("GC_init", + [], lltype.Void, + compilation_info=compilation_info, + sandboxsafe=True, + _nowrapper=True) + + init_fn_ptr() + def sizeof(self, S, translate_support_code): size = symbolic.get_size(S, translate_support_code) return ConstDescr3(size, 0, False) From arigo at codespeak.net Fri Aug 14 18:49:59 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 18:49:59 +0200 (CEST) Subject: [pypy-svn] r66833 - pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph Message-ID: <20090814164959.700A116802D@codespeak.net> Author: arigo Date: Fri Aug 14 18:49:59 2009 New Revision: 66833 Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py Log: Improve the precision: complain if a guard_overflow is not preceeded by a int_xxx_ovf. Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-guardovf/pypy/jit/backend/llgraph/llimpl.py Fri Aug 14 18:49:59 2009 @@ -574,15 +574,18 @@ def op_guard_no_overflow(self, _): global _overflow_flag - if _overflow_flag: - _overflow_flag = False + flag = _overflow_flag + assert flag != 'unset' + _overflow_flag = 'unset' + if flag: raise GuardFailed def op_guard_overflow(self, _): global _overflow_flag - if _overflow_flag: - _overflow_flag = False - else: + flag = _overflow_flag + assert flag != 'unset' + _overflow_flag = 'unset' + if not flag: raise GuardFailed # ---------- @@ -916,9 +919,11 @@ def set_zero_division_error(): _set_error(ZeroDivisionError) -_overflow_flag = False +_overflow_flag = 'unset' def get_overflow_flag(): + if _overflow_flag == 'unset': + return False return _overflow_flag def set_overflow_flag(flag): From arigo at codespeak.net Fri Aug 14 18:51:58 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 18:51:58 +0200 (CEST) Subject: [pypy-svn] r66834 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/cli backend/llgraph backend/llgraph/test backend/llvm backend/minimal backend/minimal/test backend/test backend/x86 metainterp metainterp/test Message-ID: <20090814165158.C2B6216802D@codespeak.net> Author: arigo Date: Fri Aug 14 18:51:57 2009 New Revision: 66834 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py pypy/branch/pyjitpl5/pypy/jit/backend/model.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Log: Merge the branch 'pyjitpl5-guardovf', in which 'int_xxx_ovf' no longer raises an exception but just sets a flag that must be checked immediately by 'guard_overflow' or 'guard_no_overflow'. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Fri Aug 14 18:51:57 2009 @@ -455,6 +455,12 @@ self.il.Emit(OpCodes.Ldfld, self.exc_value_field) self.store_result(op) + def emit_op_guard_no_overflow(self, op): + pass # XXX implement me! + + def emit_op_guard_overflow(self, op): + pass # XXX implement me! + def emit_op_jump(self, op): target = op.jump_target assert len(op.args) == len(target.inputargs) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Fri Aug 14 18:51:57 2009 @@ -108,10 +108,11 @@ 'guard_true' : (('bool',), None), 'guard_false' : (('bool',), None), 'guard_value' : (('int', 'int'), None), - 'guard_value_inverse' : (('int', 'int'), None), 'guard_class' : (('ptr', 'ptr'), None), 'guard_no_exception' : ((), None), 'guard_exception' : (('ptr',), 'ptr'), + 'guard_no_overflow' : ((), None), + 'guard_overflow' : ((), None), 'newstr' : (('int',), 'ptr'), 'strlen' : (('ptr',), 'int'), 'strgetitem' : (('ptr', 'int'), 'int'), @@ -534,30 +535,14 @@ if value.typeptr != expected_class: raise GuardFailed - def op_guard_class_inverse(self, _, value, expected_class): - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - expected_class = llmemory.cast_adr_to_ptr( - cast_int_to_adr(self.memocast, expected_class), - rclass.CLASSTYPE) - if value.typeptr == expected_class: - raise GuardFailed - def op_guard_value(self, _, value, expected_value): if value != expected_value: raise GuardFailed - def op_guard_value_inverse(self, _, value, expected_value): - if value == expected_value: - raise GuardFailed - def op_guard_no_exception(self, _): if _last_exception: raise GuardFailed - def op_guard_no_exception_inverse(self, _): - if _last_exception is None: - raise GuardFailed - def _check_exception(self, expected_exception): global _last_exception expected_exception = self._cast_exception(expected_exception) @@ -587,14 +572,22 @@ _last_exception = None return res - def op_guard_exception_inverse(self, _, expected_exception): - global _last_exception - if self._check_exception(expected_exception): + def op_guard_no_overflow(self, _): + global _overflow_flag + flag = _overflow_flag + assert flag != 'unset' + _overflow_flag = 'unset' + if flag: raise GuardFailed - res = _last_exception[1] - _last_exception = None - return res - + + def op_guard_overflow(self, _): + global _overflow_flag + flag = _overflow_flag + assert flag != 'unset' + _overflow_flag = 'unset' + if not flag: + raise GuardFailed + # ---------- # delegating to the builtins do_xxx() (done automatically for simple cases) @@ -926,6 +919,17 @@ def set_zero_division_error(): _set_error(ZeroDivisionError) +_overflow_flag = 'unset' + +def get_overflow_flag(): + if _overflow_flag == 'unset': + return False + return _overflow_flag + +def set_overflow_flag(flag): + global _overflow_flag + _overflow_flag = flag + class MemoCast(object): def __init__(self): self.addresses = [llmemory.NULL] Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Fri Aug 14 18:51:57 2009 @@ -219,6 +219,12 @@ def set_zero_division_error(self): llimpl.set_zero_division_error() + def get_overflow_flag(self): + return llimpl.get_overflow_flag() + + def set_overflow_flag(self, flag): + llimpl.set_overflow_flag(flag) + @staticmethod def sizeof(S): return Descr(symbolic.get_size(S)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py Fri Aug 14 18:51:57 2009 @@ -36,9 +36,6 @@ assert getattr(res, key) == value interpret(main, []) - def test_ovf_operations(self): - py.test.skip('no way to run this without a typer') - def test_execute_operations_in_env(self): py.test.skip("Rewrite me") x = BoxInt(123) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py Fri Aug 14 18:51:57 2009 @@ -14,6 +14,7 @@ class LLVMJITCompiler(object): FUNC = lltype.FuncType([], lltype.Signed) + lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) def __init__(self, cpu, loop): self.cpu = cpu @@ -348,22 +349,8 @@ lltype.free(arglist, flavor='raw') self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 0, "") - ovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, "") - self._generate_set_ovf(ovf) - - def _generate_set_ovf(self, ovf_flag): - exc_type = llvm_rffi.LLVMBuildSelect(self.builder, ovf_flag, - self.cpu.const_ovf_error_type, - self.cpu.const_null_charptr, - "") - llvm_rffi.LLVMBuildStore(self.builder, exc_type, - self.cpu.const_exc_type) - exc_value = llvm_rffi.LLVMBuildSelect(self.builder, ovf_flag, - self.cpu.const_ovf_error_value, - self.cpu.const_null_charptr, - "") - llvm_rffi.LLVMBuildStore(self.builder, exc_value, - self.cpu.const_exc_value) + self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, + "") def generate_GUARD_FALSE(self, op): self._generate_guard(op, self.getbitarg(op.args[0]), True) @@ -418,6 +405,12 @@ self.cpu.const_exc_value, "") + def generate_GUARD_NO_OVERFLOW(self, op): + self._generate_guard(op, self.lastovf, True) + + def generate_GUARD_OVERFLOW(self, op): + self._generate_guard(op, self.lastovf, False) + def _generate_guard(self, op, verify_condition, reversed, exc=False): func = self.compiling_func bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "") Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Fri Aug 14 18:51:57 2009 @@ -350,6 +350,14 @@ self.backup_exc_type[0] = self._zer_error_type self.backup_exc_value[0] = self._zer_error_value + _overflow_flag = False + + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + @staticmethod def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py Fri Aug 14 18:51:57 2009 @@ -42,6 +42,7 @@ self._future_values = [] self._ovf_error_inst = self.setup_error(OverflowError) self._zer_error_inst = self.setup_error(ZeroDivisionError) + self.clear_exception() def setup_error(self, Class): if self.rtyper is not None: # normal case @@ -184,6 +185,15 @@ raise GuardFailed elif opnum == rop.GUARD_EXCEPTION: return self._execute_guard_exception(argboxes) + elif opnum == rop.GUARD_NO_OVERFLOW: + if self._overflow_flag: + self._overflow_flag = False + raise GuardFailed + elif opnum == rop.GUARD_OVERFLOW: + if self._overflow_flag: + self._overflow_flag = False + else: + raise GuardFailed else: ll_assert(False, "execute_guard: unknown guard op") Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py Fri Aug 14 18:51:57 2009 @@ -23,7 +23,6 @@ test_passing_guard_class = _skip # GUARD_CLASS test_failing_guards = _skip # GUARD_CLASS test_failing_guard_class = _skip # GUARD_CLASS - test_ovf_operations_reversed = _skip # exception #class TestOOtype(OOJitMixin, MinimalTestMixin, OOtypeBackendTest): # pass Modified: pypy/branch/pyjitpl5/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/model.py Fri Aug 14 18:51:57 2009 @@ -1,4 +1,5 @@ class AbstractCPU(object): + _overflow_flag = False def set_class_sizes(self, class_sizes): self.class_sizes = class_sizes @@ -60,6 +61,12 @@ def set_zero_division_error(self): raise NotImplementedError + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Fri Aug 14 18:51:57 2009 @@ -217,24 +217,18 @@ if not reversed: ops = [ ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), + ResOperation(rop.GUARD_NO_OVERFLOW, [], None), ResOperation(rop.FAIL, [v_res], None), ] ops[1].suboperations = [ResOperation(rop.FAIL, [], None)] else: - self.cpu.set_overflow_error() - ovferror = self.cpu.get_exception() - assert self.cpu.get_exc_value() - self.cpu.clear_exception() if self.cpu.is_oo: v_exc = BoxObj() - c_ovferror = ConstObj(ovferror) else: v_exc = BoxPtr() - c_ovferror = ConstInt(ovferror) ops = [ ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_EXCEPTION, [c_ovferror], v_exc), + ResOperation(rop.GUARD_OVERFLOW, [], None), ResOperation(rop.FAIL, [], None), ] ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None)] @@ -246,6 +240,7 @@ for x, y, z in testcases: assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() + assert not self.cpu.get_overflow_flag() self.cpu.set_future_value_int(0, x) self.cpu.set_future_value_int(1, y) op = self.cpu.execute_operations(loop) @@ -255,18 +250,9 @@ assert op is ops[-1] if z != boom: assert self.cpu.get_latest_value_int(0) == z - ovferror = self.cpu.get_exception() - assert bool(ovferror) == bool(self.cpu.get_exc_value()) - if reversed: - # in the 'reversed' case, ovferror should always be - # consumed: either it is not set in the first place, - # or it is set and GUARD_EXCEPTION succeeds. - assert not ovferror - elif ovferror: - assert z == boom - self.cpu.clear_exception() - else: - assert z != boom + assert not self.cpu.get_exception() + assert not self.cpu.get_exc_value() + assert not self.cpu.get_overflow_flag() def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Fri Aug 14 18:51:57 2009 @@ -184,7 +184,10 @@ v_result = builder.do(self.opnum, args, descr=descr) if v_result is not None: builder.intvars.append(v_result) - if self.boolres: + boolres = self.boolres + if boolres == 'sometimes': + boolres = v_result.value in [0, 1] + if boolres: builder.boolvars.append(v_result) class UnaryOperation(AbstractOperation): @@ -228,20 +231,16 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - exc = builder.cpu.get_exception() - assert bool(exc) == bool(builder.cpu.get_exc_value()) - if exc: # OverflowError - builder.cpu.clear_exception() - exc_box = ConstInt(exc) - res_box = BoxPtr() - op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], res_box) + if builder.cpu.get_overflow_flag(): # overflow detected + builder.cpu.set_overflow_flag(False) + op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including # the result, and then remove it from builder.intvars. fail_subset = builder.subset_of_intvars(r) builder.intvars[:] = original_intvars else: - op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None) + op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) op.suboperations = [ResOperation(rop.FAIL, fail_subset, None)] builder.loop.operations.append(op) @@ -322,7 +321,7 @@ OPERATIONS.append(UnaryOperation(rop.INT_IS_TRUE, boolres=True)) OPERATIONS.append(BooleanUnaryOperation(rop.BOOL_NOT, boolres=True)) -OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres=True)) +OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres='sometimes')) for _op in [rop.INT_ADD_OVF, rop.INT_SUB_OVF, Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Fri Aug 14 18:51:57 2009 @@ -279,8 +279,8 @@ genop_discard_list[op.opnum](self, op, arglocs) def regalloc_perform_with_guard(self, op, guard_op, regalloc, - arglocs, resloc, ovf): - addr = self.implement_guard_recovery(guard_op, regalloc, ovf) + arglocs, resloc): + addr = self.implement_guard_recovery(guard_op, regalloc) genop_guard_list[op.opnum](self, op, guard_op, addr, arglocs, resloc) @@ -299,17 +299,6 @@ getattr(self.mc, asmop)(arglocs[0], arglocs[1]) return genop_binary - def _binaryop_ovf(asmop, can_swap=False): - def genop_binary_ovf(self, op, guard_op, addr, arglocs, result_loc): - getattr(self.mc, asmop)(arglocs[0], arglocs[1]) - if guard_op.opnum == rop.GUARD_NO_EXCEPTION: - self.mc.JO(rel32(addr)) - elif guard_op.opnum == rop.GUARD_EXCEPTION: - self.mc.JNO(rel32(addr)) - else: - raise AssertionError - return genop_binary_ovf - def _cmpop(cond, rev_cond): def genop_cmp(self, op, arglocs, result_loc): if isinstance(op.args[0], Const): @@ -362,9 +351,9 @@ genop_int_or = _binaryop("OR", True) genop_int_xor = _binaryop("XOR", True) - genop_guard_int_mul_ovf = _binaryop_ovf("IMUL", True) - genop_guard_int_sub_ovf = _binaryop_ovf("SUB") - genop_guard_int_add_ovf = _binaryop_ovf("ADD", True) + genop_int_mul_ovf = genop_int_mul + genop_int_sub_ovf = genop_int_sub + genop_int_add_ovf = genop_int_add genop_int_lt = _cmpop("L", "G") genop_int_le = _cmpop("LE", "GE") @@ -644,9 +633,7 @@ self.implement_guard(addr, op, self.mc.JZ) def genop_guard_guard_no_exception(self, op, ign_1, addr, locs, ign_2): - loc = locs[0] - self.mc.MOV(loc, heap(self._exception_addr)) - self.mc.TEST(loc, loc) + self.mc.CMP(heap(self._exception_addr), imm(0)) self.implement_guard(addr, op, self.mc.JNZ) def genop_guard_guard_exception(self, op, ign_1, addr, locs, resloc): @@ -660,6 +647,12 @@ self.mc.MOV(heap(self._exception_addr), imm(0)) self.mc.MOV(addr_add(imm(self._exception_addr), imm(WORD)), imm(0)) + def genop_guard_guard_no_overflow(self, op, ign_1, addr, locs, resloc): + self.implement_guard(addr, op, self.mc.JO) + + def genop_guard_guard_overflow(self, op, ign_1, addr, locs, resloc): + self.implement_guard(addr, op, self.mc.JNO) + def genop_guard_guard_false(self, op, ign_1, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) @@ -674,20 +667,13 @@ self.mc.CMP(mem(locs[0], offset), locs[1]) self.implement_guard(addr, op, self.mc.JNE) - def implement_guard_recovery(self, guard_op, regalloc, ovf=False): + def implement_guard_recovery(self, guard_op, regalloc): oldmc = self.mc self.mc = self.mc2 self.mc2 = self.mcstack.next_mc() addr = self.mc.tell() - exc = False - if ovf: - regalloc.position = -1 - if guard_op.opnum == rop.GUARD_NO_EXCEPTION: - self.generate_ovf_set() - exc = True - if (guard_op.opnum == rop.GUARD_EXCEPTION or - guard_op.opnum == rop.GUARD_NO_EXCEPTION): - exc = True + exc = (guard_op.opnum == rop.GUARD_EXCEPTION or + guard_op.opnum == rop.GUARD_NO_EXCEPTION) # XXX this is a heuristics to detect whether we're handling this # exception or not. We should have a bit better interface to deal # with that I fear @@ -734,14 +720,6 @@ self.mc.POP(ebp) self.mc.RET() - def generate_ovf_set(self): - ovf_error_vtable = self.cpu.cast_adr_to_int(self._ovf_error_vtable) - self.mc.MOV(addr_add(imm(self._exception_addr), imm(0)), - imm(ovf_error_vtable)) - ovf_error_instance = self.cpu.cast_adr_to_int(self._ovf_error_inst) - self.mc.MOV(addr_add(imm(self._exception_addr), imm(WORD)), - imm(ovf_error_instance)) - def generate_exception_handling(self, loc): self.mc.MOV(loc, heap(self._exception_addr)) self.mc.MOV(heap(self._exception_bck_addr), loc) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Fri Aug 14 18:51:57 2009 @@ -17,13 +17,6 @@ REGS = [eax, ecx, edx] WORD = 4 -class ImplementConstantOverflow(Exception): - """ This exception is raised when someone uses the result - of GUARD_EXCEPTION(overflowerror). I think codewriter should - constant fold it as we know what kind of exception it will - be - """ - class TempBox(Box): def __init__(self): pass @@ -226,14 +219,12 @@ self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs)) self.assembler.regalloc_perform(op, arglocs, result_loc) - def perform_with_guard(self, op, guard_op, regalloc, arglocs, result_loc, - overflow=False): + def perform_with_guard(self, op, guard_op, regalloc, arglocs, result_loc): if not we_are_translated(): self.assembler.dump('%s <- %s(%s) [GUARDED]' % (result_loc, op, arglocs)) self.assembler.regalloc_perform_with_guard(op, guard_op, regalloc, - arglocs, result_loc, - overflow) + arglocs, result_loc) self.max_stack_depth = max(self.max_stack_depth, regalloc.max_stack_depth) @@ -299,15 +290,7 @@ else: canfold = False if not canfold: - # detect overflow ops - if op.is_ovf(): - assert operations[i + 1].is_guard_exception() - if (operations[i + 1].opnum == rop.GUARD_EXCEPTION and - operations[i + 1].result in self.longevity): - raise ImplementConstantOverflow() - nothing = oplist[op.opnum](self, op, operations[i + 1]) - i += 1 - elif self.can_optimize_cmp_op(op, i, operations): + if self.can_optimize_cmp_op(op, i, operations): nothing = oplist[op.opnum](self, op, operations[i + 1]) i += 1 else: @@ -710,12 +693,9 @@ self.eventually_free_vars(op.args) def consider_guard_no_exception(self, op, ignored): - box = TempBox() - loc = self.force_allocate_reg(box, []) regalloc = self.regalloc_for_guard(op) - self.perform_guard(op, regalloc, [loc], None) + self.perform_guard(op, regalloc, [], None) self.eventually_free_vars(op.inputargs) - self.eventually_free_var(box) def consider_guard_exception(self, op, ignored): loc = self.make_sure_var_in_reg(op.args[0], []) @@ -732,6 +712,9 @@ self.eventually_free_vars(op.args) self.eventually_free_var(box) + consider_guard_no_overflow = consider_guard_no_exception + consider_guard_overflow = consider_guard_no_exception + #def consider_guard2(self, op, ignored): # loc1, ops1 = self.make_sure_var_in_reg(op.args[0], []) # loc2, ops2 = self.make_sure_var_in_reg(op.args[1], []) @@ -790,19 +773,10 @@ consider_int_and = _consider_binop consider_int_or = _consider_binop consider_int_xor = _consider_binop - - def _consider_binop_ovf(self, op, guard_op): - loc, argloc = self._consider_binop_part(op, None) - self.position += 1 - regalloc = self.regalloc_for_guard(guard_op) - self.perform_with_guard(op, guard_op, regalloc, [loc, argloc], loc, - overflow=True) - self.eventually_free_vars(guard_op.inputargs) - self.eventually_free_var(guard_op.result) - - consider_int_mul_ovf = _consider_binop_ovf - consider_int_sub_ovf = _consider_binop_ovf - consider_int_add_ovf = _consider_binop_ovf + + consider_int_mul_ovf = _consider_binop + consider_int_sub_ovf = _consider_binop + consider_int_add_ovf = _consider_binop def consider_int_neg(self, op, ignored): res = self.force_result_in_reg(op.result, op.args[0], []) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Fri Aug 14 18:51:57 2009 @@ -207,6 +207,14 @@ self.assembler._exception_bck[0] = zer_vtable self.assembler._exception_bck[1] = zer_inst + _overflow_flag = False + + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, flag): + self._overflow_flag = flag + def compile_operations(self, tree, bridge=None): old_loop = tree._x86_compiled if old_loop: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Fri Aug 14 18:51:57 2009 @@ -189,10 +189,11 @@ try: z = ovfcheck(x + y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_sub_ovf(cpu, args, descr=None): @@ -201,10 +202,11 @@ try: z = ovfcheck(x - y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_mul_ovf(cpu, args, descr=None): @@ -213,10 +215,11 @@ try: z = ovfcheck(x * y) except OverflowError: - cpu.set_overflow_error() + ovf = True z = 0 else: - cpu.clear_exception() + ovf = False + cpu.set_overflow_flag(ovf) return BoxInt(z) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Fri Aug 14 18:51:57 2009 @@ -238,7 +238,8 @@ exec py.code.Source(''' @arguments("box", "box") def opimpl_%s(self, b1, b2): - return self.execute_with_exc(rop.%s, [b1, b2]) + self.execute(rop.%s, [b1, b2]) + return self.metainterp.handle_overflow_error() ''' % (_opimpl, _opimpl.upper())).compile() for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not', @@ -1336,6 +1337,9 @@ self.framestack[-1].dont_follow_jump() elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: self.handle_exception() + elif opnum == rop.GUARD_NO_OVERFLOW: # an overflow now detected + self.cpu.set_overflow_error() + self.raise_this_error() def compile(self, original_boxes, live_arg_boxes, start): num_green_args = self.staticdata.num_green_args @@ -1529,6 +1533,17 @@ frame.generate_guard(frame.pc, rop.GUARD_NO_EXCEPTION, None, []) return False + def handle_overflow_error(self): + frame = self.framestack[-1] + if self.cpu.get_overflow_flag(): + self.cpu.set_overflow_flag(False) + frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) + self.cpu.set_overflow_error() + return self.raise_this_error() + else: + frame.generate_guard(frame.pc, rop.GUARD_NO_OVERFLOW, None, []) + return False + def rebuild_state_after_failure(self, resumedescr, newboxes): if not we_are_translated(): self._debug_history.append(['guard_failure', None, None]) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Fri Aug 14 18:51:57 2009 @@ -73,6 +73,10 @@ return (self.opnum == rop.GUARD_EXCEPTION or self.opnum == rop.GUARD_NO_EXCEPTION) + def is_guard_overflow(self): + return (self.opnum == rop.GUARD_OVERFLOW or + self.opnum == rop.GUARD_NO_OVERFLOW) + def is_always_pure(self): return rop._ALWAYS_PURE_FIRST <= self.opnum <= rop._ALWAYS_PURE_LAST @@ -108,6 +112,8 @@ '_GUARD_FOLDABLE_LAST', 'GUARD_NO_EXCEPTION', 'GUARD_EXCEPTION', + 'GUARD_NO_OVERFLOW', + 'GUARD_OVERFLOW', '_GUARD_LAST', # ----- end of guard operations ----- '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations ----- @@ -190,13 +196,13 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', 'OOSEND', # ootype operation - # - '_OVF_FIRST', + '_CANRAISE_LAST', # ----- end of can_raise operations ----- + + '_OVF_FIRST', # ----- start of is_ovf operations ----- 'INT_ADD_OVF', 'INT_SUB_OVF', 'INT_MUL_OVF', - '_OVF_LAST', - '_CANRAISE_LAST', # ----- end of can_raise operations ----- + '_OVF_LAST', # ----- end of is_ovf operations ----- '_LAST', # for the backend to add more internal operations ] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Fri Aug 14 18:51:57 2009 @@ -385,6 +385,22 @@ res = self.meta_interp(f, [1]) assert res == expected + def test_int_ovf_common(self): + import sys + myjitdriver = JitDriver(greens = [], reds = ['n']) + def f(n): + while 1: + myjitdriver.can_enter_jit(n=n) + myjitdriver.jit_merge_point(n=n) + try: + n = ovfcheck(n + sys.maxint) + except OverflowError: + n -= 1 + else: + return n - 2000 + res = self.meta_interp(f, [10], repeat=7) + assert res == sys.maxint - 2000 + def test_int_mod_ovf_zer(self): def f(x, y): try: From arigo at codespeak.net Fri Aug 14 18:52:18 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Aug 2009 18:52:18 +0200 (CEST) Subject: [pypy-svn] r66835 - pypy/branch/pyjitpl5-guardovf Message-ID: <20090814165218.625BD16802D@codespeak.net> Author: arigo Date: Fri Aug 14 18:52:18 2009 New Revision: 66835 Removed: pypy/branch/pyjitpl5-guardovf/ Log: Remove merged branch. From benjamin at codespeak.net Fri Aug 14 19:05:04 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 14 Aug 2009 19:05:04 +0200 (CEST) Subject: [pypy-svn] r66836 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler/test Message-ID: <20090814170504.C0490168031@codespeak.net> Author: benjamin Date: Fri Aug 14 19:05:00 2009 New Revision: 66836 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/test/test_symtable.py Log: fix syntax Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/test/test_symtable.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/test/test_symtable.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/test/test_symtable.py Fri Aug 14 19:05:00 2009 @@ -1,6 +1,6 @@ import string import py -from pypy.interpreter.astcompiler import ast astbuilder, symtable, consts +from pypy.interpreter.astcompiler import ast, astbuilder, symtable, consts from pypy.interpreter.pyparser import pyparse from pypy.interpreter.pyparser.error import SyntaxError From benjamin at codespeak.net Fri Aug 14 19:08:17 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 14 Aug 2009 19:08:17 +0200 (CEST) Subject: [pypy-svn] r66837 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler Message-ID: <20090814170817.4F06116802A@codespeak.net> Author: benjamin Date: Fri Aug 14 19:08:16 2009 New Revision: 66837 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/astbuilder.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/asthelpers.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Log: make set_context() a method of ast.expr Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/astbuilder.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/astbuilder.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/astbuilder.py Fri Aug 14 19:08:16 2009 @@ -1,4 +1,5 @@ from pypy.interpreter.astcompiler import ast, misc +from pypy.interpreter.astcompiler import asthelpers # Side effects from pypy.interpreter import error from pypy.interpreter.pyparser.pygram import syms, tokens from pypy.interpreter.pyparser.error import SyntaxError @@ -107,72 +108,24 @@ raise SyntaxError(msg, n.lineno, n.column, filename=self.compile_info.filename) + def error_ast(self, msg, ast_node): + raise SyntaxError(msg, ast_node.lineno, ast_node.col_offset, + filename=self.compile_info.filename) + def check_forbidden_name(self, name, node): - """Raise an error if the name cannot be assigned to.""" - if name == "None": - self.error("assignment to None", node) - if name == "__debug__": - self.error("assignment to __debug__", node) - # XXX Warn about using True and False + try: + misc.check_forbidden_name(name) + except misc.ForbiddenNameAssignment, e: + self.error("assignment to %s" % (e.name,), node) - def set_context(self, expr, ctx, node): + def set_context(self, expr, ctx): """Set the context of an expression to Store or Del if possible.""" - error = None - sequence = None - if isinstance(expr, ast.Attribute): - if ctx == ast.Store: - self.check_forbidden_name(expr.attr, node) - expr.ctx = ctx - elif isinstance(expr, ast.Subscript): - expr.ctx = ctx - elif isinstance(expr, ast.Name): - if ctx == ast.Store: - self.check_forbidden_name(expr.id, node) - expr.ctx = ctx - elif isinstance(expr, ast.List): - expr.ctx = ctx - sequence = expr.elts - elif isinstance(expr, ast.Tuple): - if expr.elts: - expr.ctx = ctx - sequence = expr.elts - else: - error = "()" - elif isinstance(expr, ast.Lambda): - error = "lambda" - elif isinstance(expr, ast.Call): - error = "function call" - elif isinstance(expr, ast.BoolOp) or \ - isinstance(expr, ast.BinOp) or \ - isinstance(expr, ast.UnaryOp): - error = "operator" - elif isinstance(expr, ast.GeneratorExp): - error = "generator expression" - elif isinstance(expr, ast.Yield): - error = "yield expression" - elif isinstance(expr, ast.ListComp): - error = "list comprehension" - elif isinstance(expr, ast.Dict) or \ - isinstance(expr, ast.Num) or \ - isinstance(expr, ast.Str): - error = "literal" - elif isinstance(expr, ast.Compare): - error = "comparison" - elif isinstance(expr, ast.IfExp): - error = "conditional expression" - elif isinstance(expr, ast.Repr): - error = "repr" - else: - raise AssertionError("unknown expression in set_context()") - if error is not None: - if ctx == ast.Store: - action = "assign to" - else: - action = "delete" - self.error("can't %s %s" % (action, error), node) - if sequence: - for item in sequence: - self.set_context(item, ctx, node) + try: + expr.set_context(ctx) + except ast.UnacceptableExpressionContext, e: + self.error_ast(e.msg, e.node) + except misc.ForbiddenNameAssignment, e: + self.error_ast("assignment to %s" % (e.name,), e.node) def handle_print_stmt(self, print_node): dest = None @@ -452,7 +405,7 @@ if child_count == 4: target_child = exc.children[3] target = self.handle_expr(target_child) - self.set_context(target, ast.Store, target_child) + self.set_context(target, ast.Store) return ast.excepthandler(test, target, suite, exc.lineno, exc.column) def handle_try_stmt(self, try_node): @@ -494,7 +447,7 @@ if len(with_node.children) == 5: target_node = with_node.children[2] target = self.handle_with_var(target_node) - self.set_context(target, ast.Store, target_node) + self.set_context(target, ast.Store) else: target = None return ast.With(test, target, body, with_node.lineno, with_node.column) @@ -644,7 +597,7 @@ args.append(self.handle_arg_unpacking(child)) break tup = ast.Tuple(args, ast.Store, fplist_node.lineno, fplist_node.column) - self.set_context(tup, ast.Store, fplist_node) + self.set_context(tup, ast.Store) return tup def handle_stmt(self, stmt): @@ -708,7 +661,7 @@ # Augmented assignment. target_child = stmt.children[0] target_expr = self.handle_testlist(target_child) - self.set_context(target_expr, ast.Store, target_child) + self.set_context(target_expr, ast.Store) value_child = stmt.children[2] if value_child.type == syms.testlist: value_expr = self.handle_testlist(value_child) @@ -726,7 +679,7 @@ if target_node.type == syms.yield_expr: self.error("can't assign to yield expression", target_node) target_expr = self.handle_testlist(target_node) - self.set_context(target_expr, ast.Store, target_node) + self.set_context(target_expr, ast.Store) targets.append(target_expr) value_child = stmt.children[-1] if value_child.type == syms.testlist: @@ -1249,6 +1202,6 @@ for i in range(0, len(exprlist.children), 2): child = exprlist.children[i] expr = self.handle_expr(child) - self.set_context(expr, context, child) + self.set_context(expr, context) exprs.append(expr) return exprs Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/asthelpers.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/asthelpers.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/asthelpers.py Fri Aug 14 19:08:16 2009 @@ -1,7 +1,15 @@ -from pypy.interpreter.astcompiler import ast +from pypy.interpreter.astcompiler import ast, misc from pypy.interpreter.error import OperationError +class UnacceptableExpressionContext(Exception): + + def __init__(self, node, msg): + self.node = node + self.msg = msg +setattr(ast, "UnacceptableExpressionContext", UnacceptableExpressionContext) + + class __extend__(ast.expr): constant = False @@ -9,18 +17,112 @@ def as_node_list(self, space): return None + def set_context(self, ctx): + if ctx == ast.Del: + msg = "can't delete %s" % (self._description,) + else: + msg = "can't assign to %s" % (self._description,) + raise UnacceptableExpressionContext(self, msg) + class __extend__(ast.List): def as_node_list(self, space): return self.elts + def set_context(self, ctx): + for elt in self.elts: + elt.set_context(ctx) + self.ctx = ctx + + +class __extend__(ast.Attribute): + + def set_context(self, ctx): + if ctx == ast.Store: + misc.check_forbidden_name(self.attr, self) + self.ctx = ctx + + +class __extend__(ast.Subscript): + + def set_context(self, ctx): + self.ctx = ctx + + +class __extend__(ast.Name): + + def set_context(self, ctx): + if ctx == ast.Store: + misc.check_forbidden_name(self.id, self) + self.ctx = ctx + class __extend__(ast.Tuple): + _description = "()" + def as_node_list(self, space): return self.elts + def set_context(self, ctx): + if self.elts: + for elt in self.elts: + elt.set_context(ctx) + self.ctx = ctx + else: + # Assignment to () raises an error. + ast.expr.set_context(self, ctx) + +class __extend__(ast.Lambda): + + _description = "lambda" + + +class __extend__(ast.Call): + + _description = "function call" + + +class __extend__(ast.BoolOp, ast.BinOp, ast.UnaryOp): + + _description = "operator" + + +class __extend__(ast.GeneratorExp): + + _description = "generator expression" + + +class __extend__(ast.Yield): + + _description = "yield expression" + + +class __extend__(ast.ListComp): + + _description = "list comprehension" + + +class __extend__(ast.Dict, ast.Str, ast.Num, ast.Const): + + _description = "literal" + + +class __extend__(ast.Compare): + + _description = "comparison" + + +class __extend__(ast.IfExp): + + _description = "conditional expression" + + +class __extend__(ast.Repr): + + _description = "repr" + class __extend__(ast.Const): Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py Fri Aug 14 19:08:16 2009 @@ -8,7 +8,7 @@ # please. from pypy.interpreter.astcompiler import ast, assemble, symtable, consts, misc -from pypy.interpreter.astcompiler import optimize, asthelpers # For side effects +from pypy.interpreter.astcompiler import optimize # For side effects from pypy.interpreter.pyparser.error import SyntaxError from pypy.tool import stdlib_opcode as ops from pypy.interpreter.pyparser import future Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Fri Aug 14 19:08:16 2009 @@ -27,6 +27,20 @@ _emit_syntax_warning(space, w_msg, w_filename, w_lineno, w_offset) +class ForbiddenNameAssignment(Exception): + + def __init__(self, name, node): + self.name = name + self.node = node + + +def check_forbidden_name(name, node=None): + """Raise an error if the name cannot be assigned to.""" + if name in ("None", "__debug__"): + raise ForbiddenNameAssignment(name, node) + # XXX Warn about using True and False + + def dict_to_switch(d): """Convert of dictionary with integer keys to a switch statement.""" def lookup(query): From benjamin at codespeak.net Fri Aug 14 21:11:03 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 14 Aug 2009 21:11:03 +0200 (CEST) Subject: [pypy-svn] r66838 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090814191103.2E43216802A@codespeak.net> Author: benjamin Date: Fri Aug 14 21:11:00 2009 New Revision: 66838 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: make nodes call their parent constructors for sum attributes Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Fri Aug 14 21:11:00 2009 @@ -85,6 +85,10 @@ __slots__ = ('lineno', 'col_offset') + def __init__(self, lineno, col_offset): + self.lineno = lineno + self.col_offset = col_offset + class FunctionDef(stmt): __slots__ = ('name', 'args', 'body', 'decorators') @@ -94,8 +98,7 @@ self.args = args self.body = body self.decorators = decorators - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_FunctionDef(self) @@ -115,8 +118,7 @@ self.name = name self.bases = bases self.body = body - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_ClassDef(self) @@ -134,8 +136,7 @@ def __init__(self, value, lineno, col_offset): self.value = value - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Return(self) @@ -151,8 +152,7 @@ def __init__(self, targets, lineno, col_offset): self.targets = targets - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Delete(self) @@ -169,8 +169,7 @@ def __init__(self, targets, value, lineno, col_offset): self.targets = targets self.value = value - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Assign(self) @@ -189,8 +188,7 @@ self.target = target self.op = op self.value = value - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_AugAssign(self) @@ -208,8 +206,7 @@ self.dest = dest self.values = values self.nl = nl - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Print(self) @@ -230,8 +227,7 @@ self.iter = iter self.body = body self.orelse = orelse - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_For(self) @@ -253,8 +249,7 @@ self.test = test self.body = body self.orelse = orelse - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_While(self) @@ -275,8 +270,7 @@ self.test = test self.body = body self.orelse = orelse - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_If(self) @@ -297,8 +291,7 @@ self.context_expr = context_expr self.optional_vars = optional_vars self.body = body - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_With(self) @@ -319,8 +312,7 @@ self.type = type self.inst = inst self.tback = tback - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Raise(self) @@ -342,8 +334,7 @@ self.body = body self.handlers = handlers self.orelse = orelse - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_TryExcept(self) @@ -362,8 +353,7 @@ def __init__(self, body, finalbody, lineno, col_offset): self.body = body self.finalbody = finalbody - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_TryFinally(self) @@ -382,8 +372,7 @@ def __init__(self, test, msg, lineno, col_offset): self.test = test self.msg = msg - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Assert(self) @@ -400,8 +389,7 @@ def __init__(self, names, lineno, col_offset): self.names = names - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Import(self) @@ -417,8 +405,7 @@ self.module = module self.names = names self.level = level - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_ImportFrom(self) @@ -434,8 +421,7 @@ self.body = body self.globals = globals self.locals = locals - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Exec(self) @@ -454,8 +440,7 @@ def __init__(self, names, lineno, col_offset): self.names = names - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Global(self) @@ -469,8 +454,7 @@ def __init__(self, value, lineno, col_offset): self.value = value - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Expr(self) @@ -484,8 +468,7 @@ __slots__ = () def __init__(self, lineno, col_offset): - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Pass(self) @@ -498,8 +481,7 @@ __slots__ = () def __init__(self, lineno, col_offset): - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Break(self) @@ -512,8 +494,7 @@ __slots__ = () def __init__(self, lineno, col_offset): - self.lineno = lineno - self.col_offset = col_offset + stmt.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Continue(self) @@ -525,6 +506,10 @@ __slots__ = ('lineno', 'col_offset') + def __init__(self, lineno, col_offset): + self.lineno = lineno + self.col_offset = col_offset + class BoolOp(expr): __slots__ = ('op', 'values') @@ -532,8 +517,7 @@ def __init__(self, op, values, lineno, col_offset): self.op = op self.values = values - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_BoolOp(self) @@ -551,8 +535,7 @@ self.left = left self.op = op self.right = right - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_BinOp(self) @@ -569,8 +552,7 @@ def __init__(self, op, operand, lineno, col_offset): self.op = op self.operand = operand - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_UnaryOp(self) @@ -586,8 +568,7 @@ def __init__(self, args, body, lineno, col_offset): self.args = args self.body = body - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Lambda(self) @@ -604,8 +585,7 @@ self.test = test self.body = body self.orelse = orelse - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_IfExp(self) @@ -623,8 +603,7 @@ def __init__(self, keys, values, lineno, col_offset): self.keys = keys self.values = values - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Dict(self) @@ -643,8 +622,7 @@ def __init__(self, elt, generators, lineno, col_offset): self.elt = elt self.generators = generators - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_ListComp(self) @@ -660,8 +638,7 @@ def __init__(self, elt, generators, lineno, col_offset): self.elt = elt self.generators = generators - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_GeneratorExp(self) @@ -676,8 +653,7 @@ def __init__(self, value, lineno, col_offset): self.value = value - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Yield(self) @@ -695,8 +671,7 @@ self.left = left self.ops = ops self.comparators = comparators - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Compare(self) @@ -717,8 +692,7 @@ self.keywords = keywords self.starargs = starargs self.kwargs = kwargs - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Call(self) @@ -739,8 +713,7 @@ def __init__(self, value, lineno, col_offset): self.value = value - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Repr(self) @@ -755,8 +728,7 @@ def __init__(self, n, lineno, col_offset): self.n = n - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Num(self) @@ -770,8 +742,7 @@ def __init__(self, s, lineno, col_offset): self.s = s - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Str(self) @@ -787,8 +758,7 @@ self.value = value self.attr = attr self.ctx = ctx - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Attribute(self) @@ -805,8 +775,7 @@ self.value = value self.slice = slice self.ctx = ctx - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Subscript(self) @@ -823,8 +792,7 @@ def __init__(self, id, ctx, lineno, col_offset): self.id = id self.ctx = ctx - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Name(self) @@ -839,8 +807,7 @@ def __init__(self, elts, ctx, lineno, col_offset): self.elts = elts self.ctx = ctx - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_List(self) @@ -857,8 +824,7 @@ def __init__(self, elts, ctx, lineno, col_offset): self.elts = elts self.ctx = ctx - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Tuple(self) @@ -874,8 +840,7 @@ def __init__(self, value, lineno, col_offset): self.value = value - self.lineno = lineno - self.col_offset = col_offset + expr.__init__(self, lineno, col_offset) def walkabout(self, visitor): visitor.visit_Const(self) Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Fri Aug 14 21:11:00 2009 @@ -71,6 +71,12 @@ slots = ", ".join(repr(attr.name.value) for attr in sum.attributes) self.emit("__slots__ = (%s)" % (slots,), 1) self.emit("") + if sum.attributes: + args = ", ".join(attr.name.value for attr in sum.attributes) + self.emit("def __init__(self, %s):" % (args,), 1) + for attr in sum.attributes: + self.visit(attr) + self.emit("") for cons in sum.types: self.visit(cons, base, sum.attributes, simple) self.emit("") @@ -87,12 +93,16 @@ self.emit("visitor.visit_%s(self)" % (name,), 2) self.emit("") - def make_constructor(self, fields): - if fields: - args = ", ".join(str(field.name) for field in fields) + def make_constructor(self, fields, extras=None, base=None): + if fields or extras: + arg_fields = fields + extras if extras else fields + args = ", ".join(str(field.name) for field in arg_fields) self.emit("def __init__(self, %s):" % args, 1) for field in fields: self.visit(field) + if extras: + base_args = ", ".join(str(field.name) for field in extras) + self.emit("%s.__init__(self, %s)" % (base, base_args), 2) else: self.emit("def __init__(self):", 1) self.emit("pass", 2) @@ -100,11 +110,10 @@ def visitConstructor(self, cons, base, extra_attributes, simple): self.emit("class %s(%s):" % (cons.name, base)) self.emit("") - all_fields = cons.fields + extra_attributes slots = ", ".join(repr(field.name.value) for field in cons.fields) self.emit("__slots__ = (%s)" % (slots,), 1) self.emit("") - self.make_constructor(all_fields) + self.make_constructor(cons.fields, extra_attributes, base) self.emit("") self.emit("def walkabout(self, visitor):", 1) self.emit("visitor.visit_%s(self)" % (cons.name,), 2) From arigo at codespeak.net Sat Aug 15 15:59:50 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 15:59:50 +0200 (CEST) Subject: [pypy-svn] r66841 - pypy/branch/pyjitpl5/pypy/doc/config Message-ID: <20090815135950.66CC4168025@codespeak.net> Author: arigo Date: Sat Aug 15 15:59:48 2009 New Revision: 66841 Added: pypy/branch/pyjitpl5/pypy/doc/config/translation.jit_debug.txt (contents, props changed) Log: Document option. Added: pypy/branch/pyjitpl5/pypy/doc/config/translation.jit_debug.txt ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/doc/config/translation.jit_debug.txt Sat Aug 15 15:59:48 2009 @@ -0,0 +1,2 @@ +Choose the level of debugging output in the JIT. +'off' means none, other values give increasingly more. From arigo at codespeak.net Sat Aug 15 16:06:35 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 16:06:35 +0200 (CEST) Subject: [pypy-svn] r66842 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090815140635.D150E168025@codespeak.net> Author: arigo Date: Sat Aug 15 16:06:35 2009 New Revision: 66842 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/jitprof.py Log: Send this to stderr, not to stdout. Fixes at least test_zrpy_gc.py in backend/x86/test/. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/jitprof.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/jitprof.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/jitprof.py Sat Aug 15 16:06:35 2009 @@ -92,11 +92,13 @@ def print_stats(self): cnt = self.counters tim = self.times - print "Tracing: \t%d\t%f" % (cnt[TRACING], tim[TRACING]) - print "Backend: \t%d\t%f" % (cnt[BACKEND], tim[BACKEND]) - print "Running asm:\t%d\t%f" % (cnt[RUNNING], tim[RUNNING]) - print "Blackhole: \t%d\t%f" % (cnt[BLACKHOLE], tim[BLACKHOLE]) - print "TOTAL: \t\t%f" % (self.tk - self.starttime) + lines = ("Tracing: \t%d\t%f\n" % (cnt[TRACING], tim[TRACING]) + + "Backend: \t%d\t%f\n" % (cnt[BACKEND], tim[BACKEND]) + + "Running asm:\t%d\t%f\n" % (cnt[RUNNING], tim[RUNNING]) + + "Blackhole: \t%d\t%f\n" % (cnt[BLACKHOLE], tim[BLACKHOLE]) + + "TOTAL: \t\t%f\n" % (self.tk - self.starttime)) + import os + os.write(2, lines) class BrokenProfilerData(Exception): From arigo at codespeak.net Sat Aug 15 17:05:13 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 17:05:13 +0200 (CEST) Subject: [pypy-svn] r66843 - in pypy/branch/pyjitpl5/pypy: jit/metainterp jit/metainterp/test rlib Message-ID: <20090815150513.DE793168025@codespeak.net> Author: arigo Date: Sat Aug 15 17:05:12 2009 New Revision: 66843 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/rlib/jit.py Log: Support jitdriver.set_param(), encoded as jit_markers by pypy/rlib/jit.py. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Sat Aug 15 17:05:12 2009 @@ -747,6 +747,28 @@ optimizer=simple_optimize) assert res == 42 + def test_set_param(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'x']) + def g(n): + x = 0 + while n > 0: + myjitdriver.can_enter_jit(n=n, x=x) + myjitdriver.jit_merge_point(n=n, x=x) + n -= 1 + x += n + return x + def f(n, threshold): + myjitdriver.set_param('threshold', threshold) + return g(n) + + res = self.meta_interp(f, [10, 3]) + assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 + self.check_tree_loop_count(1) + + res = self.meta_interp(f, [10, 13]) + assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 + self.check_tree_loop_count(0) + class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Sat Aug 15 17:05:12 2009 @@ -79,33 +79,33 @@ return ll_meta_interp(function, args, backendopt=backendopt, translate_support_code=True, **kwds) -def find_can_enter_jit(graphs): +def _find_jit_marker(graphs, marker_name): results = [] for graph in graphs: for block in graph.iterblocks(): for i in range(len(block.operations)): op = block.operations[i] if (op.opname == 'jit_marker' and - op.args[0].value == 'can_enter_jit'): + op.args[0].value == marker_name): results.append((graph, block, i)) + return results + +def find_can_enter_jit(graphs): + results = _find_jit_marker(graphs, 'can_enter_jit') if not results: raise Exception("no can_enter_jit found!") return results def find_jit_merge_point(graphs): - results = [] - for graph in graphs: - for block in graph.iterblocks(): - for i in range(len(block.operations)): - op = block.operations[i] - if (op.opname == 'jit_marker' and - op.args[0].value == 'jit_merge_point'): - results.append((graph, block, i)) + results = _find_jit_marker(graphs, 'jit_merge_point') if len(results) != 1: raise Exception("found %d jit_merge_points, need exactly one!" % (len(results),)) return results[0] +def find_set_param(graphs): + return _find_jit_marker(graphs, 'set_param') + def get_stats(): return pyjitpl._warmrunnerdesc.stats @@ -138,11 +138,10 @@ self.metainterp_sd.generate_bytecode(policy, self.ts) self.make_enter_function() self.rewrite_can_enter_jit() + self.rewrite_set_param() self.add_profiler_finish() self.metainterp_sd.finish_setup() - # hook back for set_param self.make_can_inline_graph() - self.jitdriver.state = self.state def finish(self): vinfo = self.metainterp_sd.virtualizable_info @@ -496,6 +495,27 @@ call_final_function(self.translator, finish_profiler, annhelper = self.annhelper) + def rewrite_set_param(self): + closures = {} + graphs = self.translator.graphs + _, PTR_SET_PARAM_FUNCTYPE = self.ts.get_FuncType([lltype.Signed], + lltype.Void) + def make_closure(fullfuncname): + state = self.state + def closure(i): + getattr(state, fullfuncname)(i) + funcptr = self.helper_func(PTR_SET_PARAM_FUNCTYPE, closure) + return Constant(funcptr, PTR_SET_PARAM_FUNCTYPE) + # + for graph, block, i in find_set_param(graphs): + op = block.operations[i] + assert op.args[1].value == self.jitdriver + funcname = op.args[2].value + if funcname not in closures: + closures[funcname] = make_closure('set_param_' + funcname) + op.opname = 'direct_call' + op.args[:3] = [closures[funcname]] + def decode_hp_hint_args(op): # Returns (list-of-green-vars, list-of-red-vars) without Voids. Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Sat Aug 15 17:05:12 2009 @@ -124,7 +124,6 @@ # special-cased by ExtRegistryEntry # (internal, must receive a constant 'name') assert name in PARAMETERS - #getattr(self.state, 'set_param_' + name)(value) -- ignored def set_param(self, name, value): """Set one of the tunable JIT parameter.""" From arigo at codespeak.net Sat Aug 15 17:07:57 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 17:07:57 +0200 (CEST) Subject: [pypy-svn] r66844 - in pypy/branch/pyjitpl5/pypy: module/pypyjit translator/goal Message-ID: <20090815150757.B4A29168025@codespeak.net> Author: arigo Date: Sat Aug 15 17:07:57 2009 New Revision: 66844 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py pypy/branch/pyjitpl5/pypy/translator/goal/app_main.py Log: Add the --jit option to pypy-c-jit. The syntax is for example: pypy-c-jit --jit threshold=N Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py Sat Aug 15 17:07:57 2009 @@ -11,3 +11,8 @@ def setup_after_space_initialization(self): # force the __extend__ hacks to occur early import pypy.module.pypyjit.interp_jit + # add the 'defaults' attribute + from pypy.rlib.jit import PARAMETERS + w_obj = space.wrap(PARAMETERS) + space = self.space + space.setattr(space.wrap(self), space.wrap('defaults'), w_obj) Modified: pypy/branch/pyjitpl5/pypy/translator/goal/app_main.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/goal/app_main.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/goal/app_main.py Sat Aug 15 17:07:57 2009 @@ -122,7 +122,18 @@ def print_help(): print 'usage: %s [options]' % (sys.executable,) - print __doc__ + print __doc__.rstrip() + if 'pypyjit' in sys.builtin_module_names: + print_jit_help() + print + +def print_jit_help(): + import pypyjit + items = pypyjit.defaults.items() + items.sort() + for key, value in items: + print ' --jit %s=N %slow-level JIT parameter (default %s)' % ( + key, ' '*(18-len(key)), value) class CommandLineError(Exception): pass @@ -161,8 +172,9 @@ def get_argument(option, argv, i): arg = argv[i] - if len(arg) > 2: - return arg[2:], i + n = len(option) + if len(arg) > n: + return arg[n:], i else: i += 1 if i >= len(argv): @@ -269,6 +281,14 @@ break elif arg.startswith('-W'): warnoptions, i = get_argument('-W', argv, i) + elif arg.startswith('--jit'): + jitparam, i = get_argument('--jit', argv, i) + if 'pypyjit' not in sys.builtin_module_names: + print >> sys.stderr, ("Warning: No jit support in %s" % + (sys.executable,)) + else: + import pypyjit + pypyjit.set_param(jitparam) elif arg == '--': i += 1 break # terminates option list From arigo at codespeak.net Sat Aug 15 17:14:02 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 17:14:02 +0200 (CEST) Subject: [pypy-svn] r66845 - pypy/branch/pyjitpl5/pypy/module/pypyjit Message-ID: <20090815151402.E91F9168028@codespeak.net> Author: arigo Date: Sat Aug 15 17:14:01 2009 New Revision: 66845 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py Log: Oups, checked in from the wrong machine. Fix. Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/__init__.py Sat Aug 15 17:14:01 2009 @@ -13,6 +13,6 @@ import pypy.module.pypyjit.interp_jit # add the 'defaults' attribute from pypy.rlib.jit import PARAMETERS - w_obj = space.wrap(PARAMETERS) space = self.space + w_obj = space.wrap(PARAMETERS) space.setattr(space.wrap(self), space.wrap('defaults'), w_obj) From arigo at codespeak.net Sat Aug 15 18:33:37 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 18:33:37 +0200 (CEST) Subject: [pypy-svn] r66846 - pypy/branch/pyjitpl5/pypy/jit/backend/llgraph Message-ID: <20090815163337.7066C168025@codespeak.net> Author: arigo Date: Sat Aug 15 18:33:35 2009 New Revision: 66846 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Log: Update to py.test's change. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 15 18:33:35 2009 @@ -857,7 +857,7 @@ except Exception, e: log.ERROR('%s in CPU frame: %s' % (e.__class__.__name__, e)) # Only invoke pdb when io capturing is not on otherwise py.io complains. - if py.test.config.option.nocapture: + if py.test.config.option.capture == 'no': import sys, pdb pdb.post_mortem(sys.exc_info()[2]) raise From arigo at codespeak.net Sat Aug 15 19:20:37 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 19:20:37 +0200 (CEST) Subject: [pypy-svn] r66847 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli backend/llgraph backend/llvm backend/llvm/test backend/x86 metainterp metainterp/test Message-ID: <20090815172037.B8046168029@codespeak.net> Author: arigo Date: Sat Aug 15 19:20:34 2009 New Revision: 66847 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_1st.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: (pedronis, arigo) Introduced the DEBUG_MERGE_POINT operation, added for debugging purposes only between the bytecodes of the interpreted program. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Sat Aug 15 19:20:34 2009 @@ -631,6 +631,9 @@ self.il.Emit(OpCodes.Callvirt, _ll_resize) self.store_result(op) + def emit_op_debug_merge_point(self, op): + pass + def lltype_only(self, op): print 'Operation %s is lltype specific, should not get here!' % op.getopname() raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 15 19:20:34 2009 @@ -123,6 +123,7 @@ 'unicodesetitem' : (('ptr', 'int', 'int'), 'int'), 'cast_ptr_to_int' : (('ptr',), 'int'), 'cast_int_to_ptr' : (('int',), 'ptr'), + 'debug_merge_point': (('ptr',), None), #'getitem' : (('void', 'ptr', 'int'), 'int'), #'setitem' : (('void', 'ptr', 'int', 'int'), None), #'newlist' : (('void', 'varargs'), 'ptr'), @@ -513,8 +514,9 @@ else: boxedargs.append(BoxPtr(x)) # xxx this passes the 'llimpl' module as the CPU argument + llimpl.is_oo = issubclass(cls, OOFrame) resbox = impl(llimpl, boxedargs) - return resbox.value + return getattr(resbox, 'value', None) op = _op_default_implementation # cls.OPHANDLERS[opnum] = op Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py Sat Aug 15 19:20:34 2009 @@ -714,6 +714,9 @@ self.cpu.const_unicode_index_array, self.cpu.const_unicode_index_length) + def generate_DEBUG_MERGE_POINT(self, op): + pass + # ____________________________________________________________ class MissingOperation(Exception): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_1st.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_1st.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_1st.py Sat Aug 15 19:20:34 2009 @@ -108,3 +108,15 @@ cpu.fielddescrof(rclass.OBJECT, 'typeptr') cpu.arraydescrof(lltype.GcArray(lltype.Signed)) cpu.calldescrof(lltype.FuncType([], lltype.Signed), (), lltype.Signed) + +def test_debug_merge_point(): + loop = TreeLoop('test') + loop.inputargs = [] + loop.operations = [ + ResOperation(rop.DEBUG_MERGE_POINT, [], None), + ResOperation(rop.FAIL, [], None), + ] + cpu = LLVMCPU(None) + cpu.setup_once() + cpu.compile_operations(loop) + cpu.execute_operations(loop) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sat Aug 15 19:20:34 2009 @@ -1150,6 +1150,9 @@ self.assembler.regalloc_pop(later_pops[i]) self.PerformDiscard(op, []) + def consider_debug_merge_point(self, op, ignored): + pass + def not_implemented_op(self, op, ignored): print "[regalloc] Not implemented operation: %s" % op.getopname() raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Sat Aug 15 19:20:34 2009 @@ -2,9 +2,10 @@ """ import py -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lloperation import llop +from pypy.rpython.annlowlevel import hlstr from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr from pypy.jit.metainterp.history import INT, PTR, OBJ @@ -224,6 +225,17 @@ # ____________________________________________________________ +def do_debug_merge_point(cpu, args, descr=None): + from pypy.jit.metainterp.warmspot import get_stats + if cpu.is_oo: + ll_str = ootype.cast_from_object(ootype.String, args[0].value) + else: + ll_str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), args[0].value) + loc = hlstr(ll_str) + get_stats().locations.append(loc) + +# ____________________________________________________________ + def make_execute_list(cpuclass): from pypy.jit.backend.model import AbstractCPU Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Sat Aug 15 19:20:34 2009 @@ -656,6 +656,7 @@ def __init__(self): self.loops = [] + self.locations = [] def get_all_loops(self): return self.loops @@ -666,6 +667,7 @@ opname = op.getopname() insns[opname] = insns.get(opname, 0) + 1 if expected is not None: + insns.pop('debug_merge_point', None) assert insns == expected for insn, expected_count in check.items(): getattr(rop, insn.upper()) # fails if 'rop.INSN' does not exist @@ -681,6 +683,7 @@ continue insns = loop.summary(adding_insns=insns) if expected is not None: + insns.pop('debug_merge_point', None) assert insns == expected for insn, expected_count in check.items(): getattr(rop, insn.upper()) # fails if 'rop.INSN' does not exist Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Sat Aug 15 19:20:34 2009 @@ -785,10 +785,23 @@ @arguments("orgpc") def opimpl_jit_merge_point(self, pc): self.generate_merge_point(pc, self.env) + if DEBUG > 0: + self.debug_merge_point() if self.metainterp.seen_can_enter_jit: self.metainterp.seen_can_enter_jit = False self.metainterp.reached_can_enter_jit(self.env) + def debug_merge_point(self): + # debugging: produce a DEBUG_MERGE_POINT operation + num_green_args = self.metainterp.staticdata.num_green_args + greenkey = self.env[:num_green_args] + sd = self.metainterp.staticdata + greenargs = sd.globaldata.unpack_greenkey(greenkey) + loc = sd.state.get_location_llstr(*greenargs) + constloc = sd.ts.conststr(loc) + self.metainterp.history.record(rop.DEBUG_MERGE_POINT, + [constloc], None) + @arguments("jumptarget") def opimpl_setup_exception_block(self, exception_target): self.exception_target = exception_target Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Sat Aug 15 19:20:34 2009 @@ -192,6 +192,7 @@ 'UNICODESETITEM', 'NEWUNICODE', 'RUNTIMENEW', # ootype operation + 'DEBUG_MERGE_POINT', # debugging only '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py Sat Aug 15 19:20:34 2009 @@ -1,4 +1,5 @@ from pypy.jit.metainterp.warmspot import ll_meta_interp, cast_whatever_to_int +from pypy.jit.metainterp.warmspot import get_stats from pypy.rlib.jit import JitDriver from pypy.jit.backend.llgraph import runner @@ -88,6 +89,29 @@ res = self.meta_interp(f, [110], hash_bits=1) assert res == f(110) + def test_location(self): + # + class MyJitDriver(JitDriver): + greens = ['n'] + reds = ['m'] + + def get_printable_location(n): + return 'GREEN IS %d.' % n + get_printable_location = staticmethod(get_printable_location) + + myjitdriver = MyJitDriver() + + def f(n, m): + while m > 0: + myjitdriver.can_enter_jit(n=n, m=m) + myjitdriver.jit_merge_point(n=n, m=m) + m -= 1 + + self.meta_interp(f, [123, 10]) + assert len(get_stats().locations) >= 4 + for loc in get_stats().locations: + assert loc == 'GREEN IS 123.' + class TestLLWarmspot(WarmspotTests): CPUClass = runner.LLtypeCPU Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py Sat Aug 15 19:20:34 2009 @@ -3,7 +3,7 @@ #from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype -from pypy.rpython.annlowlevel import cast_base_ptr_to_instance +from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, llstr, oostr from pypy.jit.metainterp import history def deref(T): @@ -91,6 +91,10 @@ def setarrayitem(self, array, i, newvalue): array[i] = newvalue + def conststr(self, str): + ll = llstr(str) + return history.ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ll)) + class OOTypeHelper(TypeSystemHelper): @@ -145,6 +149,10 @@ def setarrayitem(self, array, i, newvalue): array.ll_setitem_fast(i, newvalue) + def conststr(self, str): + oo = oostr(str) + return history.ConstObj(ootype.cast_to_object(oo)) + llhelper = LLTypeHelper() oohelper = OOTypeHelper() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Sat Aug 15 19:20:34 2009 @@ -619,6 +619,12 @@ getarrayitem = warmrunnerdesc.ts.getarrayitem setarrayitem = warmrunnerdesc.ts.setarrayitem # + try: + get_printable_location = jitdriver.get_printable_location + except AttributeError: + def get_printable_location(*greenargs): + return '(no jitdriver.get_printable_location!)' + # class MachineCodeEntryPoint(object): next = None # linked list def __init__(self, bridge, *greenargs): @@ -825,4 +831,7 @@ self.mcentrypoints[argshash] = newcell self.mccounters[argshash] = -THRESHOLD_LIMIT-1 + def get_location_llstr(self, *greenargs): + return get_printable_location(*greenargs) + return WarmEnterState From arigo at codespeak.net Sat Aug 15 19:40:14 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 19:40:14 +0200 (CEST) Subject: [pypy-svn] r66848 - in pypy/branch/pyjitpl5/pypy: jit/metainterp jit/metainterp/test rlib Message-ID: <20090815174014.AAC96168028@codespeak.net> Author: arigo Date: Sat Aug 15 19:40:13 2009 New Revision: 66848 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/rlib/jit.py Log: Attach get_printable_location to the jitdriver in the same style as can_inline. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py Sat Aug 15 19:40:13 2009 @@ -90,17 +90,10 @@ assert res == f(110) def test_location(self): - # - class MyJitDriver(JitDriver): - greens = ['n'] - reds = ['m'] - - def get_printable_location(n): - return 'GREEN IS %d.' % n - get_printable_location = staticmethod(get_printable_location) - - myjitdriver = MyJitDriver() - + def get_printable_location(n): + return 'GREEN IS %d.' % n + myjitdriver = JitDriver(greens=['n'], reds=['m'], + get_printable_location=get_printable_location) def f(n, m): while m > 0: myjitdriver.can_enter_jit(n=n, m=m) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Sat Aug 15 19:40:13 2009 @@ -619,11 +619,7 @@ getarrayitem = warmrunnerdesc.ts.getarrayitem setarrayitem = warmrunnerdesc.ts.setarrayitem # - try: - get_printable_location = jitdriver.get_printable_location - except AttributeError: - def get_printable_location(*greenargs): - return '(no jitdriver.get_printable_location!)' + get_printable_location = jitdriver.get_printable_location # class MachineCodeEntryPoint(object): next = None # linked list Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Sat Aug 15 19:40:13 2009 @@ -84,6 +84,11 @@ } unroll_parameters = unrolling_iterable(PARAMETERS.keys()) +def _no_printable_location(*greenargs): + return '(no jitdriver.get_printable_location!)' + +# ____________________________________________________________ + class JitDriver: """Base class to declare fine-grained user control on the JIT. So far, there must be a singleton instance of JitDriver. This style @@ -94,6 +99,7 @@ virtualizables = [] def __init__(self, greens=None, reds=None, virtualizables=None, + get_printable_location=_no_printable_location, can_inline=None): if greens is not None: self.greens = greens @@ -107,6 +113,7 @@ assert v in self.reds self._alllivevars = dict.fromkeys(self.greens + self.reds) self._make_extregistryentries() + self.get_printable_location = get_printable_location self.can_inline = can_inline def _freeze_(self): From arigo at codespeak.net Sat Aug 15 20:01:40 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Aug 2009 20:01:40 +0200 (CEST) Subject: [pypy-svn] r66849 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/llgraph metainterp Message-ID: <20090815180140.50A00168028@codespeak.net> Author: arigo Date: Sat Aug 15 20:01:39 2009 New Revision: 66849 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/support.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Log: Tweak the handling of debug_merge_point in order to have it really printed in the log.ops file. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 15 20:01:39 2009 @@ -514,7 +514,6 @@ else: boxedargs.append(BoxPtr(x)) # xxx this passes the 'llimpl' module as the CPU argument - llimpl.is_oo = issubclass(cls, OOFrame) resbox = impl(llimpl, boxedargs) return getattr(resbox, 'value', None) op = _op_default_implementation Modified: pypy/branch/pyjitpl5/pypy/jit/backend/support.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/support.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/support.py Sat Aug 15 20:01:39 2009 @@ -67,6 +67,10 @@ os.write(self._log_fd, pre + "LOOP %s\n" % args) for i in range(len(operations)): op = operations[i] + if op.opnum == rop.DEBUG_MERGE_POINT: + loc = op.args[0]._get_str() + os.write(self._log_fd, pre + "%s\n" % (loc,)) + continue args = ",".join([self.repr_of_arg(memo, arg) for arg in op.args]) if op.descr is not None: descr = self.repr_of_descr(op.descr) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Sat Aug 15 20:01:39 2009 @@ -2,10 +2,9 @@ """ import py -from pypy.rpython.lltypesystem import lltype, rstr +from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.annlowlevel import hlstr from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr from pypy.jit.metainterp.history import INT, PTR, OBJ @@ -227,11 +226,7 @@ def do_debug_merge_point(cpu, args, descr=None): from pypy.jit.metainterp.warmspot import get_stats - if cpu.is_oo: - ll_str = ootype.cast_from_object(ootype.String, args[0].value) - else: - ll_str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), args[0].value) - loc = hlstr(ll_str) + loc = args[0]._get_str() get_stats().locations.append(loc) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Sat Aug 15 20:01:39 2009 @@ -317,6 +317,11 @@ def repr_rpython(self): return repr_rpython(self, 'cp') + def _get_str(self): # for debugging only + from pypy.rpython.annlowlevel import hlstr + from pypy.rpython.lltypesystem import rstr + return hlstr(lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), self.value)) + class ConstObj(Const): type = OBJ value = ootype.NULL @@ -360,6 +365,10 @@ def repr_rpython(self): return repr_rpython(self, 'co') + def _get_str(self): # for debugging only + from pypy.rpython.annlowlevel import hlstr + return hlstr(ootype.cast_from_object(ootype.String, self.value)) + class Box(AbstractValue): __slots__ = () _extended_display = True @@ -403,6 +412,9 @@ Box._counter += 1 return self._str + def _get_str(self): # for debugging only + return self.constbox()._get_str() + class BoxInt(Box): type = INT _attrs_ = ('value',) From pedronis at codespeak.net Sat Aug 15 20:33:10 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 15 Aug 2009 20:33:10 +0200 (CEST) Subject: [pypy-svn] r66850 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090815183310.4158B168025@codespeak.net> Author: pedronis Date: Sat Aug 15 20:33:08 2009 New Revision: 66850 Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_platform.py (contents, props changed) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: - make sure that stack aligment on calls respects the ABI on Mac OS X - don't check some asserts that make linux based assumptions about address ranges on other platforms Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sat Aug 15 20:33:08 2009 @@ -19,6 +19,15 @@ # and the rest stays on the stack MAX_FAIL_BOXES = 1000 +if sys.platform == 'darwin': + # darwin requires the stack to be 16 bytes aligned on calls + CALL_ALIGN = 4 +else: + CALL_ALIGN = 1 + + +def align_stack_words(words): + return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) class x86Logger(AbstractLogger): @@ -191,7 +200,11 @@ self.sanitize_tree(tree.operations) self.mc.done() self.mc2.done() - tree._x86_stack_depth = regalloc.max_stack_depth + stack_words = regalloc.max_stack_depth + # possibly align, e.g. for Mac OS X + RET_BP = 2 # ret ip + bp = 2 words + stack_words = align_stack_words(stack_words+RET_BP) + tree._x86_stack_depth = stack_words-RET_BP for place in self.places_to_patch_framesize: mc = codebuf.InMemoryCodeBuilder(place, place + 128) mc.ADD(esp, imm32(tree._x86_stack_depth * WORD)) @@ -331,15 +344,23 @@ self.implement_guard(addr, guard_op, getattr(self.mc, name)) return genop_cmp_guard + def align_stack_for_call(self, nargs): + # xxx do something when we don't use push anymore for calls + extra_on_stack = align_stack_words(nargs) + for i in range(extra_on_stack-nargs): + self.mc.PUSH(imm(0)) + return extra_on_stack def call(self, addr, args, res): - for i in range(len(args)-1, -1, -1): + nargs = len(args) + extra_on_stack = self.align_stack_for_call(nargs) + for i in range(nargs-1, -1, -1): arg = args[i] assert not isinstance(arg, MODRM) self.mc.PUSH(arg) self.mc.CALL(rel32(addr)) self.mark_gc_roots() - self.mc.ADD(esp, imm(len(args) * WORD)) + self.mc.ADD(esp, imm(extra_on_stack * WORD)) assert res is eax genop_int_neg = _unaryop("NEG") @@ -739,12 +760,12 @@ assert isinstance(sizeloc, IMM32) size = sizeloc.value arglocs = arglocs[1:] - extra_on_stack = 0 - for i in range(len(op.args) - 1, 0, -1): + nargs = len(op.args)-1 + extra_on_stack = self.align_stack_for_call(nargs) + for i in range(nargs, 0, -1): v = op.args[i] loc = arglocs[i] self.mc.PUSH(loc) - extra_on_stack += 1 if isinstance(op.args[0], Const): x = rel32(op.args[0].getint()) else: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Sat Aug 15 20:33:08 2009 @@ -53,6 +53,13 @@ def __repr__(self): return '' % (self.v0, self.v1, self.flag2) + +def _check_addr_range(x): + if sys.platform == 'linux2': + # this makes assumption about address ranges that are valid + # only on linux (?) + assert x == 0 or x > (1<<20) or x < (-1<<20) + class CPU386(object): debug = True is_oo = False @@ -684,7 +691,8 @@ @staticmethod def cast_int_to_adr(x): - assert x == 0 or x > (1<<20) or x < (-1<<20) + if not we_are_translated(): + _check_addr_range(x) if we_are_translated(): return rffi.cast(llmemory.Address, x) else: @@ -696,12 +704,12 @@ def cast_int_to_gcref(self, x): if not we_are_translated(): - assert x == 0 or x > (1<<20) or x < (-1<<20) + _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) def cast_adr_to_gcref(self, x): if not we_are_translated(): - assert x == 0 or x > (1<<20) or x < (-1<<20) + _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) def uhex(x): Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_platform.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_platform.py Sat Aug 15 20:33:08 2009 @@ -0,0 +1,94 @@ +import sys +import py +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rlib import jit +from pypy.jit.backend.x86.test.test_zrpy_gc import compile_and_run + +from pypy.jit.metainterp import pyjitpl + +#pyjitpl.DEBUG = 4 + + +def test_stack_alignment(): + if sys.platform != 'darwin': + py.test.skip("tests darwin only stack alignment requirements") + + externs = [""" +extern void check0(); +extern void check1(int); +extern void check2(int, int); +extern void check3(int, int, int); +"""] + c_source = r""" +#include + +void check0() { + void *ip = __builtin_return_address(0); + void *fp = __builtin_frame_address(0); + printf("0 %p %p %u\n", ip, fp, (unsigned)fp % 16); +} + +void check1(int a) { + void *ip = __builtin_return_address(0); + void *fp = __builtin_frame_address(0); + printf("1 %p %p %u\n", ip, fp, (unsigned)fp % 16); +} + +void check2(int a, int b) { + void *ip = __builtin_return_address(0); + void *fp = __builtin_frame_address(0); + printf("2 %p %p %u\n", ip, fp, (unsigned)fp % 16); +} + +void check3(int a, int b, int c) { + void *ip = __builtin_return_address(0); + void *fp = __builtin_frame_address(0); + printf("3 %p %p %u\n", ip, fp, (unsigned)fp % 16); +} +""" + + eci = rffi.ExternalCompilationInfo(separate_module_sources=[c_source], + post_include_bits = externs, + # not ideal, would like to apply this only to the checkX + # functions + compile_extra=["-fno-omit-frame-pointer"]) + + check0 = rffi.llexternal('check0', [], lltype.Void, + compilation_info=eci, + _nowrapper=True) + check1 = rffi.llexternal('check1', [lltype.Signed], lltype.Void, + compilation_info=eci, + _nowrapper=True) + check2 = rffi.llexternal('check2', [lltype.Signed, lltype.Signed], + lltype.Void, + compilation_info=eci, + _nowrapper=True) + + check3 = rffi.llexternal('check3', [lltype.Signed, lltype.Signed, + lltype.Signed], + lltype.Void, + compilation_info=eci, + _nowrapper=True) + + myjitdriver = jit.JitDriver(greens = [], reds = ['n']) + + def entrypoint(argv): + myjitdriver.set_param('threshold', 2) + myjitdriver.set_param('trace_eagerness', 0) + n = 16 + while n > 0: + myjitdriver.can_enter_jit(n=n) + myjitdriver.jit_merge_point(n=n) + n -= 1 + check0() + check1(0) + check2(0, 1) + check3(0, 1, 2) + return 0 + + output = compile_and_run(entrypoint, 'boehm', jit=True) + for line in output.splitlines(): + print line + # ret ip + bp == 8 + assert int(line.split()[-1]) == 8 + From benjamin at codespeak.net Sat Aug 15 21:27:54 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sat, 15 Aug 2009 21:27:54 +0200 (CEST) Subject: [pypy-svn] r66851 - pypy/trunk/pypy/rlib Message-ID: <20090815192754.F0BE5168025@codespeak.net> Author: benjamin Date: Sat Aug 15 21:27:53 2009 New Revision: 66851 Modified: pypy/trunk/pypy/rlib/rarithmetic.py Log: typo Modified: pypy/trunk/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/trunk/pypy/rlib/rarithmetic.py (original) +++ pypy/trunk/pypy/rlib/rarithmetic.py Sat Aug 15 21:27:53 2009 @@ -5,7 +5,7 @@ such that before and after translation semantics are consistent -r_uint an unsigned integer which has not overflow +r_uint an unsigned integer which has no overflow checking. It is always positive and always truncated to the internal machine word size. intmask mask a possibly long value when running on CPython From benjamin at codespeak.net Sat Aug 15 21:45:39 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sat, 15 Aug 2009 21:45:39 +0200 (CEST) Subject: [pypy-svn] r66852 - pypy/trunk/pypy/interpreter/test Message-ID: <20090815194539.315F2168025@codespeak.net> Author: benjamin Date: Sat Aug 15 21:45:38 2009 New Revision: 66852 Modified: pypy/trunk/pypy/interpreter/test/test_objspace.py Log: fix these tests on 64bit platforms Modified: pypy/trunk/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_objspace.py (original) +++ pypy/trunk/pypy/interpreter/test/test_objspace.py Sat Aug 15 21:45:38 2009 @@ -8,6 +8,10 @@ # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* + +INT32_MAX = 2147483648 + + class TestObjSpace: def test_newlist(self): w = self.space.wrap @@ -154,9 +158,9 @@ res = space.r_longlong_w(w_value) assert res == 12 assert type(res) is r_longlong - w_value = space.wrap(r_longlong(-sys.maxint * 42)) + w_value = space.wrap(r_longlong(-INT32_MAX * 42)) res = space.r_longlong_w(w_value) - assert res == -sys.maxint * 42 + assert res == -INT32_MAX * 42 assert type(res) is r_longlong w_obj = space.wrap("hello world") space.raises_w(space.w_TypeError, space.r_longlong_w, w_obj) @@ -169,9 +173,9 @@ res = space.r_ulonglong_w(w_value) assert res == 12 assert type(res) is r_ulonglong - w_value = space.wrap(r_ulonglong(sys.maxint * 42)) + w_value = space.wrap(r_ulonglong(INT32_MAX * 42)) res = space.r_ulonglong_w(w_value) - assert res == sys.maxint * 42 + assert res == INT32_MAX * 42 assert type(res) is r_ulonglong w_obj = space.wrap("hello world") space.raises_w(space.w_TypeError, space.r_ulonglong_w, w_obj) From benjamin at codespeak.net Sun Aug 16 04:21:56 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 16 Aug 2009 04:21:56 +0200 (CEST) Subject: [pypy-svn] r66853 - in pypy/branch/parser-compiler/pypy/tool/pytest: . test Message-ID: <20090816022156.21ADB168029@codespeak.net> Author: benjamin Date: Sun Aug 16 04:21:53 2009 New Revision: 66853 Added: pypy/branch/parser-compiler/pypy/tool/pytest/test/test_appsupport.py Modified: pypy/branch/parser-compiler/pypy/tool/pytest/appsupport.py Log: fix exc_info() for exception that aren't caught in except blocks Modified: pypy/branch/parser-compiler/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/parser-compiler/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/parser-compiler/pypy/tool/pytest/appsupport.py Sun Aug 16 04:21:53 2009 @@ -182,6 +182,18 @@ space.newtuple([w_BuiltinAssertionError]), w_dict) +def _exc_info(space, err): + """Hack the fact that exc_info() isn't set until a app except + block catches it.""" + err.normalize_exception(space) + frame = space.getexecutioncontext().framestack.top() + old = frame.last_exception + frame.last_exception = err + try: + return space.sys.call("exc_info") + finally: + frame.last_exception = old + def pypyraises(space, w_ExpectedException, w_expr, __args__): """A built-in function providing the equivalent of py.test.raises().""" args_w, kwds_w = __args__.unpack() @@ -201,14 +213,14 @@ space.exec_(source.compile(), frame.w_globals, w_locals) except OperationError, e: if e.match(space, w_ExpectedException): - return space.sys.call('exc_info') + return _exc_info(space, e) raise else: try: space.call_args(w_expr, __args__) except OperationError, e: if e.match(space, w_ExpectedException): - return space.sys.call('exc_info') + return _exc_info(space, e) raise raise OperationError(space.w_AssertionError, space.wrap("DID NOT RAISE")) Added: pypy/branch/parser-compiler/pypy/tool/pytest/test/test_appsupport.py ============================================================================== --- (empty file) +++ pypy/branch/parser-compiler/pypy/tool/pytest/test/test_appsupport.py Sun Aug 16 04:21:53 2009 @@ -0,0 +1,6 @@ + + +def app_test_raises(): + info = raises(TypeError, id) + assert info[0] is TypeError + assert isinstance(info[1], TypeError) From pedronis at codespeak.net Sun Aug 16 13:15:21 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 13:15:21 +0200 (CEST) Subject: [pypy-svn] r66854 - in pypy/branch/pyjitpl5/pypy/translator/c/gcc: . test Message-ID: <20090816111521.88E8C168029@codespeak.net> Author: pedronis Date: Sun Aug 16 13:15:19 2009 New Revision: 66854 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: (arigo, pedronis) start working on darwin support in trackgcroot Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py Sun Aug 16 13:15:19 2009 @@ -46,7 +46,7 @@ assert len(bytes) == 1+1+2+3+4+4+5+5+1 assert decompress_callshape(bytes) == list(shape) -def test_find_functions(): +def test_find_functions_elf(): source = """\ \t.p2align 4,,15 .globl pypy_g_make_tree @@ -70,7 +70,36 @@ assert parts[3] == (True, lines[8:11]) assert parts[4] == (False, lines[11:]) - +def test_find_functions_darwin(): + source = """\ +\t.text +\t.align 4,0x90 +.globl _pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin +_pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin: +\tFOO +\t.align 4,0x90 +.globl _pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr +_pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr: +\tBAR +\t.cstring +\t.ascii "foo" +\t.text +\t.align 4,0x90 +.globl _pypy_g_RPyRaiseException +_pypy_g_RPyRaiseException: +\tBAZ +\t.section stuff +""" + lines = source.splitlines(True) + parts = list(GcRootTracker(darwin=True).find_functions(iter(lines))) + assert len(parts) == 6 + assert parts[0] == (False, lines[:2]) + assert parts[1] == (True, lines[2:6]) + assert parts[2] == (True, lines[6:9]) + assert parts[3] == (False, lines[9:13]) + assert parts[4] == (True, lines[13:16]) + assert parts[5] == (False, lines[16:]) + def test_computegcmaptable(): tests = [] for path in this_dir.listdir("track*.s"): Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Sun Aug 16 13:15:19 2009 @@ -2,8 +2,15 @@ import re, sys, os, random -r_functionstart = re.compile(r"\t.type\s+(\w+),\s*[@]function\s*$") -r_functionend = re.compile(r"\t.size\s+(\w+),\s*[.]-(\w+)\s*$") +r_functionstart_elf = re.compile(r"\t.type\s+(\w+),\s*[@]function\s*$") +r_functionend_elf = re.compile(r"\t.size\s+(\w+),\s*[.]-(\w+)\s*$") + +# darwin +r_textstart = re.compile(r"\t.text\s*$") +r_sectionstart = re.compile(r"\t.(section|cstring|data).*$") +r_functionstart_darwin = re.compile(r".globl\s+(\w+)\s*$") + +# inside functions r_label = re.compile(r"([.]?\w+)[:]\s*$") r_globl = re.compile(r"\t[.]globl\t(\w+)\s*$") r_insn = re.compile(r"\t([a-z]\w*)\s") @@ -26,9 +33,10 @@ class GcRootTracker(object): - def __init__(self, verbose=0, shuffle=False): + def __init__(self, verbose=0, shuffle=False, darwin=False): self.verbose = verbose self.shuffle = shuffle # to debug the sorting logic in asmgcroot.py + self.darwin = darwin self.clear() def clear(self): @@ -104,17 +112,25 @@ output.writelines(shapelines) def find_functions(self, iterlines): + if self.darwin: + _find_functions = self._find_functions_darwin + else: + _find_functions = self._find_functions_elf + + return _find_functions(iterlines) + + def _find_functions_elf(self, iterlines): functionlines = [] in_function = False for line in iterlines: - if r_functionstart.match(line): + if r_functionstart_elf.match(line): assert not in_function, ( "missed the end of the previous function") yield False, functionlines in_function = True functionlines = [] functionlines.append(line) - if r_functionend.match(line): + if r_functionend_elf.match(line): assert in_function, ( "missed the start of the current function") yield True, functionlines @@ -124,6 +140,29 @@ "missed the end of the previous function") yield False, functionlines + def _find_functions_darwin(self, iterlines): + functionlines = [] + in_text = False + in_function = False + for line in iterlines: + if r_textstart.match(line): + assert not in_text, "unexpected repeated .text start" + in_text = True + elif r_sectionstart.match(line): + if in_function: + yield in_function, functionlines + functionlines = [] + in_text = False + in_function = False + elif in_text and r_functionstart_darwin.match(line): + yield in_function, functionlines + functionlines = [] + in_function = True + functionlines.append(line) + + if functionlines: + yield in_function, functionlines + def process(self, iterlines, newfile, entrypoint='main', filename='?'): for in_function, lines in self.find_functions(iterlines): if in_function: @@ -156,9 +195,9 @@ class FunctionGcRootTracker(object): def __init__(self, lines, filetag=0): - match = r_functionstart.match(lines[0]) + match = r_functionstart_elf.match(lines[0]) self.funcname = match.group(1) - match = r_functionend.match(lines[-1]) + match = r_functionend_elf.match(lines[-1]) assert self.funcname == match.group(1) assert self.funcname == match.group(2) self.lines = lines From pedronis at codespeak.net Sun Aug 16 14:37:55 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 14:37:55 +0200 (CEST) Subject: [pypy-svn] r66855 - in pypy/branch/pyjitpl5/pypy/translator/c/gcc: . test test/darwin test/elf Message-ID: <20090816123755.1ED31168029@codespeak.net> Author: pedronis Date: Sun Aug 16 14:37:53 2009 New Revision: 66855 Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s (contents, props changed) pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s (contents, props changed) pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track0.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track0.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track1.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track1.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track2.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track2.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track3.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track3.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track4.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track4.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track5.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track5.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track6.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track6.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track7.s - copied unchanged from r66849, pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track7.s Removed: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track0.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track1.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track2.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track3.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track4.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track5.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track6.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/track7.s Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: (arigo, pedronis) start passing darwin variants of the test_gcmaptable make directories for elf vs darwin *.s test files Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s Sun Aug 16 14:37:53 2009 @@ -0,0 +1,85 @@ +.globl _pypy_g_clear_large_memory_chunk +_pypy_g_clear_large_memory_chunk: +L80: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + call L103 +"L00000000006$pb": +L103: + popl %ebx + subl $28, %esp + movl $420, 8(%esp) + movl $0, 4(%esp) + movl L_pypy_g_array_21$non_lazy_ptr-"L00000000006$pb"(%ebx), %eax + movl %eax, (%esp) + call L_open$stub + ;; expected {44(%esp) | 28(%esp), 32(%esp), 36(%esp), 40(%esp) | } + cmpl $-1, %eax + movl %eax, %ebp + je L100 +L81: + movl 52(%esp), %esi + movl 48(%esp), %edi + testl %esi, %esi + jg L101 +L88: + movl %ebp, (%esp) + call L_close$stub + ;; expected {44(%esp) | 28(%esp), 32(%esp), 36(%esp), 40(%esp) | } + movl %esi, %edx + movl %edi, %eax +L83: + testl %edx, %edx + jle L97 +L85: + movl %edx, 8(%esp) + movl $0, 4(%esp) + movl %eax, (%esp) + call L_memset$stub + ;; expected {44(%esp) | 28(%esp), 32(%esp), 36(%esp), 40(%esp) | } +L97: + addl $28, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp + ret + .align 4,0x90 +L101: + movl 52(%esp), %esi + movl 48(%esp), %edi + jmp L92 + .align 4,0x90 +L102: + movl %eax, %edi + movl %edx, %esi +L92: +L95: + cmpl $536870913, %esi + movl $536870912, %eax + cmovl %esi, %eax + movl %eax, 8(%esp) + movl %edi, 4(%esp) + movl %ebp, (%esp) + call L_read$stub + ;; expected {44(%esp) | 28(%esp), 32(%esp), 36(%esp), 40(%esp) | } + testl %eax, %eax + jle L88 +L96: +L89: + movl %esi, %edx + subl %eax, %edx + testl %edx, %edx + leal (%edi,%eax), %eax + jg L102 + movl %edx, %esi + movl %eax, %edi + jmp L88 + .align 4,0x90 +L100: + movl 52(%esp), %edx + movl 48(%esp), %eax + jmp L83 + .align 4,0x90 Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s Sun Aug 16 14:37:53 2009 @@ -0,0 +1,82 @@ +.globl _pypy_g_clear_large_memory_chunk +_pypy_g_clear_large_memory_chunk: +L137: + pushl %ebp + movl %esp, %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $28, %esp + movl L_pypy_g_array_21$non_lazy_ptr, %eax + movl $420, 8(%esp) + movl $0, 4(%esp) + movl %eax, (%esp) + call L_open$stub + ;; expected {4(%ebp) | -12(%ebp), -8(%ebp), -4(%ebp), (%ebp) | } + cmpl $-1, %eax + movl %eax, %edi + je L157 +L138: + movl 12(%ebp), %ebx + movl 8(%ebp), %esi + testl %ebx, %ebx + jg L158 +L145: + movl %edi, (%esp) + call L_close$stub + ;; expected {4(%ebp) | -12(%ebp), -8(%ebp), -4(%ebp), (%ebp) | } + movl %ebx, %edx + movl %esi, %eax +L140: + testl %edx, %edx + jle L154 +L142: + movl %edx, 8(%esp) + movl $0, 4(%esp) + movl %eax, (%esp) + call L_memset$stub + ;; expected {4(%ebp) | -12(%ebp), -8(%ebp), -4(%ebp), (%ebp) | } +L154: + addl $28, %esp + popl %ebx + popl %esi + popl %edi + leave + ret + .align 4,0x90 +L158: + movl 12(%ebp), %ebx + movl 8(%ebp), %esi + jmp L149 + .align 4,0x90 +L159: + movl %eax, %esi + movl %edx, %ebx +L149: +L152: + cmpl $536870913, %ebx + movl $536870912, %eax + cmovl %ebx, %eax + movl %eax, 8(%esp) + movl %esi, 4(%esp) + movl %edi, (%esp) + call L_read$stub + ;; expected {4(%ebp) | -12(%ebp), -8(%ebp), -4(%ebp), (%ebp) | } + testl %eax, %eax + jle L145 +L153: +L146: + movl %ebx, %edx + subl %eax, %edx + testl %edx, %edx + leal (%esi,%eax), %eax + jg L159 + movl %edx, %ebx + movl %eax, %esi + jmp L145 + .align 4,0x90 +L157: + movl 12(%ebp), %edx + movl 8(%ebp), %eax + jmp L140 + .align 4,0x90 \ No newline at end of file Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py Sun Aug 16 14:37:53 2009 @@ -91,7 +91,7 @@ \t.section stuff """ lines = source.splitlines(True) - parts = list(GcRootTracker(darwin=True).find_functions(iter(lines))) + parts = list(GcRootTracker(format='darwin').find_functions(iter(lines))) assert len(parts) == 6 assert parts[0] == (False, lines[:2]) assert parts[1] == (True, lines[2:6]) @@ -102,26 +102,27 @@ def test_computegcmaptable(): tests = [] - for path in this_dir.listdir("track*.s"): - n = path.purebasename[5:] - try: - n = int(n) - except ValueError: - pass - tests.append((n, path)) + for format in ('elf', 'darwin'): + for path in this_dir.join(format).listdir("track*.s"): + n = path.purebasename[5:] + try: + n = int(n) + except ValueError: + pass + tests.append((format, n, path)) tests.sort() - for _, path in tests: - yield check_computegcmaptable, path + for format, _, path in tests: + yield check_computegcmaptable, format, path r_globallabel = re.compile(r"([\w]+)[:]") r_expected = re.compile(r"\s*;;\s*expected\s+([{].+[}])") -def check_computegcmaptable(path): +def check_computegcmaptable(format, path): print print path.basename lines = path.readlines() expectedlines = lines[:] - tracker = FunctionGcRootTracker(lines) + tracker = FunctionGcRootTracker(lines, format=format) table = tracker.computegcmaptable(verbose=sys.maxint) tabledict = {} seen = {} Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Sun Aug 16 14:37:53 2009 @@ -15,7 +15,7 @@ r_globl = re.compile(r"\t[.]globl\t(\w+)\s*$") r_insn = re.compile(r"\t([a-z]\w*)\s") r_jump = re.compile(r"\tj\w+\s+([.]?\w+)\s*$") -OPERAND = r"(?:[-\w$%+.:@]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])" +OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])' r_unaryinsn = re.compile(r"\t[a-z]\w*\s+("+OPERAND+")\s*$") r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+([*]"+OPERAND+")\s*$") r_jmp_switch = re.compile(r"\tjmp\t[*]([.]?\w+)[(]") @@ -33,10 +33,10 @@ class GcRootTracker(object): - def __init__(self, verbose=0, shuffle=False, darwin=False): + def __init__(self, verbose=0, shuffle=False, format='elf'): self.verbose = verbose self.shuffle = shuffle # to debug the sorting logic in asmgcroot.py - self.darwin = darwin + self.format = format self.clear() def clear(self): @@ -112,11 +112,7 @@ output.writelines(shapelines) def find_functions(self, iterlines): - if self.darwin: - _find_functions = self._find_functions_darwin - else: - _find_functions = self._find_functions_elf - + _find_functions = getattr(self, '_find_functions_' + self.format) return _find_functions(iterlines) def _find_functions_elf(self, iterlines): @@ -172,7 +168,8 @@ sys.stderr.write('\n') def process_function(self, lines, entrypoint, filename): - tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename)) + tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename), + format=self.format) tracker.is_main = tracker.funcname == entrypoint if self.verbose == 1: sys.stderr.write('.') @@ -194,12 +191,20 @@ class FunctionGcRootTracker(object): - def __init__(self, lines, filetag=0): - match = r_functionstart_elf.match(lines[0]) - self.funcname = match.group(1) - match = r_functionend_elf.match(lines[-1]) - assert self.funcname == match.group(1) - assert self.funcname == match.group(2) + def __init__(self, lines, filetag=0, format='elf'): + if format == 'elf': + match = r_functionstart_elf.match(lines[0]) + funcname = match.group(1) + match = r_functionend_elf.match(lines[-1]) + assert funcname == match.group(1) + assert funcname == match.group(2) + elif format == 'darwin': + match = r_functionstart_darwin.match(lines[0]) + funcname = match.group(1) + else: + assert False, "unknown format: %s" % format + + self.funcname = funcname self.lines = lines self.uses_frame_pointer = False self.r_localvar = r_localvarnofp @@ -694,6 +699,11 @@ target = match.group(1) if target in FUNCTIONS_NOT_RETURNING: return InsnStop() + if target in self.labels: + lineoffset = self.labels[target].lineno - self.currentlineno + if lineoffset >= 0: + assert lineoffset in (1,2) + return [InsnStackAdjust(-4)] return [InsnCall(self.currentlineno), InsnSetLocal('%eax')] # the result is there From arigo at codespeak.net Sun Aug 16 16:40:33 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Aug 2009 16:40:33 +0200 (CEST) Subject: [pypy-svn] r66856 - pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf Message-ID: <20090816144033.06F0616802B@codespeak.net> Author: arigo Date: Sun Aug 16 16:40:32 2009 New Revision: 66856 Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/src8.py (contents, props changed) pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track8.s Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/ (props changed) Log: Add a new passing test: the point is that some "expected" lines mention arguments that are in the caller's frame. Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/src8.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/src8.py Sun Aug 16 16:40:32 2009 @@ -0,0 +1,22 @@ +# ../../../../goal/translate.py --gcrootfinder=asmgcc --gc=semispace src8 + +class A: + pass + +def foo(rec, a1, a2, a3, a4, a5, a6): + if rec > 0: + b = A() + foo(rec-1, b, b, b, b, b, b) + foo(rec-1, b, b, b, b, b, b) + foo(rec-1, a6, a5, a4, a3, a2, a1) + +# __________ Entry point __________ + +def entry_point(argv): + foo(5, A(), A(), A(), A(), A(), A()) + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track8.s ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/elf/track8.s Sun Aug 16 16:40:32 2009 @@ -0,0 +1,217 @@ + .type pypy_g_foo, @function +pypy_g_foo: +.L1780: + subl $76, %esp + movl 80(%esp), %ecx + movl %esi, 64(%esp) + movl 104(%esp), %esi + testl %ecx, %ecx + movl %ebp, 72(%esp) + movl 100(%esp), %ebp + movl %ebx, 60(%esp) + movl %edi, 68(%esp) + jle .L1779 +.L1783: +.L1782: +.L1784: + movl _LLstacktoobig_stack_base_pointer, %edx + leal 59(%esp), %eax + xorl %ebx, %ebx + subl %edx, %eax + cmpl _LLstacktoobig_stack_min, %eax + jl .L1786 + cmpl _LLstacktoobig_stack_max, %eax + jg .L1786 +.L1787: + testl %ebx, %ebx + jne .L1830 +.L1795: +.L1797: +.L1799: +.L1791: + movl pypy_g_ExcData, %eax + testl %eax, %eax + je .L1831 +.L1779: + movl 60(%esp), %ebx + movl 64(%esp), %esi + movl 68(%esp), %edi + movl 72(%esp), %ebp + addl $76, %esp + ret + .p2align 4,,7 +.L1786: + call LL_stack_too_big_slowpath + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %esi, %ebp, 84(%esp), 88(%esp), 92(%esp), 96(%esp)} + testl %eax, %eax + je .L1787 + movl $1, %ebx + jmp .L1787 + .p2align 4,,7 +.L1831: +.L1802: + movl pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+12, %edx + movl pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+80, %ecx + subl %edx, %ecx + cmpl $7, %ecx + jle .L1804 +.L1829: +.L1805: +.L1808: + movl $4, (%edx) + movl %edx, %edi + movl $pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC, %ebx + leal 8(%edx), %edx + movl %edx, 12(%ebx) + movl %edi, %ebx +.L1809: + movl %esi, %edi + movl 84(%esp), %eax + movl 88(%esp), %esi +#APP + /* GCROOT %eax */ + /* GCROOT %edi */ +#NO_APP + movl %eax, 48(%esp) + movl 96(%esp), %eax +#APP + /* GCROOT %esi */ + /* GCROOT %eax */ + /* GCROOT %ebp */ +#NO_APP + movl %eax, 44(%esp) + movl 92(%esp), %eax +#APP + /* GCROOT %eax */ +#NO_APP + movl %eax, 40(%esp) + testl %ebx, %ebx + je .L1779 +.L1811: + movl $pypy_g_src8_A_vtable, 4(%ebx) + movl 80(%esp), %eax + movl %ebx, 24(%esp) + movl %ebx, 20(%esp) + decl %eax + movl %eax, 52(%esp) + movl %ebx, 16(%esp) + movl %ebx, 12(%esp) + movl %ebx, 8(%esp) + movl %ebx, 4(%esp) + movl %eax, (%esp) + call pypy_g_foo + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %ebx, %esi, %edi, %ebp, 40(%esp), 44(%esp), 48(%esp)} + movl pypy_g_ExcData, %ecx +#APP + /* GCROOT %esi */ + /* GCROOT %edi */ +#NO_APP + movl %esi, 36(%esp) + movl 48(%esp), %eax + movl 40(%esp), %esi +#APP + /* GCROOT %eax */ + /* GCROOT %ebp */ +#NO_APP + movl %eax, 32(%esp) + movl %ebx, %eax + movl 44(%esp), %ebx +#APP + /* GCROOT %eax */ + /* GCROOT %ebx */ + /* GCROOT %esi */ +#NO_APP + testl %ecx, %ecx + jne .L1779 +.L1814: + movl %eax, 24(%esp) + movl 52(%esp), %edx + movl %eax, 20(%esp) + movl %eax, 16(%esp) + movl %eax, 12(%esp) + movl %eax, 8(%esp) + movl %eax, 4(%esp) + movl %edx, (%esp) + call pypy_g_foo + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %ebx, %esi, %edi, %ebp, 32(%esp), 36(%esp)} + movl %esi, %eax + movl pypy_g_ExcData, %esi +#APP + /* GCROOT %edi */ +#NO_APP + movl %edi, 28(%esp) + movl 32(%esp), %edx +#APP + /* GCROOT %ebp */ +#NO_APP + movl 36(%esp), %edi +#APP + /* GCROOT %edx */ + /* GCROOT %edi */ +#NO_APP + movl %ebx, %ecx +#APP + /* GCROOT %eax */ + /* GCROOT %ecx */ +#NO_APP + testl %esi, %esi + jne .L1779 +.L1816: + movl %edi, 20(%esp) + movl 28(%esp), %edi + movl %ebp, 8(%esp) + movl 52(%esp), %ebp + movl %edx, 24(%esp) + movl %eax, 16(%esp) + movl %ecx, 12(%esp) + movl %edi, 4(%esp) + movl %ebp, (%esp) + call pypy_g_foo + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | } + jmp .L1779 +.L1807: + .p2align 4,,7 +.L1804: +.L1817: + movl $pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC, (%esp) + movl $8, %ebx + movl %ebx, 4(%esp) + call pypy_g_SemiSpaceGC_try_obtain_free_space + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %esi, %ebp, 84(%esp), 88(%esp), 92(%esp), 96(%esp)} + movl pypy_g_ExcData, %ecx + xorl %edx, %edx + testl %ecx, %ecx + je .L1832 +.L1819: + xorl %ebx, %ebx + testl %ecx, %ecx + jne .L1809 + jmp .L1829 +.L1790: +.L1789: +.L1792: +.L1793: +.L1830: +.L1794: + movl $pypy_g_exceptions_RuntimeError_vtable, %edi + movl $pypy_g_exceptions_RuntimeError, %ebx + movl %edi, pypy_g_ExcData + movl %ebx, pypy_g_ExcData+4 + jmp .L1791 +.L1832: +.L1820: + testb %al, %al + je .L1833 +.L1822: + movl pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+12, %edx + jmp .L1819 +.L1833: +.L1823: +.L1824: +.L1825: + movl $pypy_g_exceptions_MemoryError_vtable, %ecx + movl $pypy_g_exceptions_MemoryError_1, %eax + movl %ecx, pypy_g_ExcData + movl %eax, pypy_g_ExcData+4 + jmp .L1819 + .size pypy_g_foo, .-pypy_g_foo From pedronis at codespeak.net Sun Aug 16 16:49:43 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 16:49:43 +0200 (CEST) Subject: [pypy-svn] r66857 - pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin Message-ID: <20090816144943.113B416802B@codespeak.net> Author: pedronis Date: Sun Aug 16 16:49:43 2009 New Revision: 66857 Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s (contents, props changed) pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s (contents, props changed) Log: some more test cases for darwin too Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s Sun Aug 16 16:49:43 2009 @@ -0,0 +1,191 @@ +.globl _pypy_g_populate +_pypy_g_populate: +L2135: + subl $76, %esp + movl %esi, 64(%esp) + movl 80(%esp), %esi + movl %ebx, 60(%esp) + call L2175 +"L00000000060$pb": +L2175: + popl %ebx + movl %edi, 68(%esp) + testl %esi, %esi + movl %ebp, 72(%esp) + jle L2169 +L2137: +L2138: + movl L__LLstacktoobig_stack_base_pointer$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + leal 47(%esp), %edx + subl (%eax), %edx + movl L__LLstacktoobig_stack_min$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + cmpl (%eax), %edx + jl L2139 + movl L__LLstacktoobig_stack_max$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + cmpl (%eax), %edx + jg L2139 +L2171: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + movl (%edi), %ebp + testl %ebp, %ebp + je L2172 +L2169: + movl 60(%esp), %ebx + movl 64(%esp), %esi + movl 68(%esp), %edi + movl 72(%esp), %ebp + addl $76, %esp + ret + .align 4,0x90 +L2139: + call L_LL_stack_too_big_slowpath$stub + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | 84(%esp)} + testl %eax, %eax + je L2171 +L2142: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + movl L_pypy_g_exceptions_RuntimeError_vtable$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %eax, (%edi) + movl (%edi), %ebp + movl L_pypy_g_exceptions_RuntimeError$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + testl %ebp, %ebp + movl %eax, 4(%edi) + jne L2169 +L2143: + .align 4,0x90 +L2172: + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000060$pb"(%ebx), %ebp + decl %esi + movl %esi, 28(%esp) + movl 12(%ebp), %edx + movl 80(%ebp), %eax + subl %edx, %eax + cmpl $15, %eax + jle L2144 +L2146: + leal 16(%edx), %eax + movl %edx, %ecx + movl $31, (%edx) + movl %eax, 12(%ebp) +L2147: + movl L___gcnoreorderhack$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + movl 84(%esp), %esi + /* GCROOT %esi */ + testl %ecx, %ecx + je L2169 +L2148: + movl L_pypy_g_pypy_translator_goal_gcbench_Node_vtable$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000060$pb"(%ebx), %ebp + movl $0, 8(%edx) + movl $0, 12(%edx) + movl %eax, 4(%edx) + movl %edx, 8(%esi) + movl 12(%ebp), %edx + movl 80(%ebp), %eax + subl %edx, %eax + cmpl $15, %eax + jle L2149 +L2151: + leal 16(%edx), %eax + movl $31, (%edx) + movl %eax, 12(%ebp) + movl %edx, %eax +L2152: + /* GCROOT %esi */ + testl %eax, %eax + je L2169 +L2153: + movl L_pypy_g_pypy_translator_goal_gcbench_Node_vtable$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl $0, 8(%edx) + movl $0, 12(%edx) + movl %eax, 4(%edx) + movl 8(%esi), %eax + movl %edx, 12(%esi) + movl %eax, 4(%esp) + movl 28(%esp), %eax + movl %eax, (%esp) + call _pypy_g_populate + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %esi} + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %esi, %edx + /* GCROOT %edx */ + movl (%eax), %esi + testl %esi, %esi + jne L2169 +L2154: + movl 12(%edx), %eax + movl %eax, 4(%esp) + movl 28(%esp), %eax + movl %eax, (%esp) + call _pypy_g_populate + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | } + jmp L2169 +L2144: + movl $16, 4(%esp) + xorl %esi, %esi + movl %ebp, (%esp) + call _pypy_g_SemiSpaceGC_try_obtain_free_space + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | 84(%esp)} + + movl (%edi), %edx + testl %edx, %edx + je L2173 +L2164: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + xorl %ecx, %ecx + xorl %edx, %edx + movl (%eax), %eax + testl %eax, %eax + jne L2147 + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000060$pb"(%ebx), %ebp + movl %esi, %edx + jmp L2146 +L2149: + movl $16, 4(%esp) + movl %ebp, (%esp) + call _pypy_g_SemiSpaceGC_try_obtain_free_space + ;; expected {76(%esp) | 60(%esp), 64(%esp), 68(%esp), 72(%esp) | %esi} + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + xorl %edx, %edx + movl (%edi), %ecx + testl %ecx, %ecx + je L2174 +L2157: + movl (%edi), %ecx + testl %ecx, %ecx + je L2160 + movl L___gcnoreorderhack$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + xorl %eax, %eax + xorl %edx, %edx + jmp L2152 +L2173: +L2162: + testb %al, %al + jne L2165 +L2166: + movl L_pypy_g_exceptions_MemoryError_vtable$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %eax, (%edi) + movl L_pypy_g_exceptions_MemoryError_1$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %eax, 4(%edi) + jmp L2164 +L2160: + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000060$pb"(%ebx), %ebp + movl L___gcnoreorderhack$non_lazy_ptr-"L00000000060$pb"(%ebx), %edi + jmp L2151 +L2174: +L2155: + testb %al, %al + jne L2158 +L2159: + movl L_pypy_g_exceptions_MemoryError_vtable$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %eax, (%edi) + movl L_pypy_g_exceptions_MemoryError_1$non_lazy_ptr-"L00000000060$pb"(%ebx), %eax + movl %eax, 4(%edi) + jmp L2157 +L2165: + movl 12(%ebp), %esi + jmp L2164 +L2158: + movl 12(%ebp), %edx + jmp L2157 + .align 4,0x90 Added: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s Sun Aug 16 16:49:43 2009 @@ -0,0 +1,203 @@ +.globl _pypy_g_foo +_pypy_g_foo: +L1506: + subl $140, %esp + movl %esi, 128(%esp) + movl 144(%esp), %esi + movl %ebx, 124(%esp) + call L1534 +"L00000000044$pb": +L1534: + popl %ebx + movl %edi, 132(%esp) + testl %esi, %esi + movl %ebp, 136(%esp) + jle L1529 +L1508: +L1509: + movl L__LLstacktoobig_stack_base_pointer$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + leal 111(%esp), %edx + subl (%eax), %edx + movl L__LLstacktoobig_stack_min$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + cmpl (%eax), %edx + jl L1510 + movl L__LLstacktoobig_stack_max$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + cmpl (%eax), %edx + jg L1510 +L1531: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000044$pb"(%ebx), %esi + movl (%esi), %ecx + testl %ecx, %ecx + je L1532 +L1529: + movl 124(%esp), %ebx + movl 128(%esp), %esi + movl 132(%esp), %edi + movl 136(%esp), %ebp + addl $140, %esp + ret + .align 4,0x90 +L1510: + call L_LL_stack_too_big_slowpath$stub + ;; expected {140(%esp) | 124(%esp), 128(%esp), 132(%esp), 136(%esp) | 148(%esp), 152(%esp), 156(%esp), 160(%esp), 164(%esp), 168(%esp)} + testl %eax, %eax + je L1531 +L1513: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000044$pb"(%ebx), %esi + movl L_pypy_g_exceptions_RuntimeError_vtable$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + movl %eax, (%esi) + movl (%esi), %ecx + movl L_pypy_g_exceptions_RuntimeError$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + testl %ecx, %ecx + movl %eax, 4(%esi) + jne L1529 +L1514: + .align 4,0x90 +L1532: + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000044$pb"(%ebx), %edi + movl 12(%edi), %edx + movl 80(%edi), %eax + subl %edx, %eax + cmpl $7, %eax + jle L1515 +L1517: + leal 8(%edx), %eax + movl $4, (%edx) + movl %eax, 12(%edi) + movl %edx, %edi +L1518: + movl L___gcnoreorderhack$non_lazy_ptr-"L00000000044$pb"(%ebx), %esi + movl 168(%esp), %eax + movl 164(%esp), %ebp + /* GCROOT %eax */ + /* GCROOT %ebp */ + movl %eax, 48(%esp) + movl 152(%esp), %eax + /* GCROOT %eax */ + movl %eax, 52(%esp) + movl 156(%esp), %eax + /* GCROOT %eax */ + movl %eax, 56(%esp) + movl 160(%esp), %eax + /* GCROOT %eax */ + movl %eax, 60(%esp) + movl 148(%esp), %eax + /* GCROOT %eax */ + testl %edx, %edx + movl %eax, 64(%esp) + je L1529 +L1519: + movl L_pypy_g_src8_A_vtable$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + movl %eax, 4(%edi) + movl 144(%esp), %edx + movl %edi, 24(%esp) + movl %edi, 20(%esp) + movl %edi, 16(%esp) + decl %edx + movl %edx, 44(%esp) + movl %edi, 12(%esp) + movl %edi, 8(%esp) + movl %edi, 4(%esp) + movl %edx, (%esp) + call _pypy_g_foo + ;; expected {140(%esp) | 124(%esp), 128(%esp), 132(%esp), 136(%esp) | %edi, %ebp, 48(%esp), 52(%esp), 56(%esp), 60(%esp), 64(%esp)} + movl 56(%esp), %edx + /* GCROOT %edx */ + movl %edx, 76(%esp) + movl 60(%esp), %edx + /* GCROOT %edx */ + movl %edx, 80(%esp) + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000044$pb"(%ebx), %edx + /* GCROOT %ebp */ + movl 48(%esp), %eax + movl %ebp, 72(%esp) + movl 52(%esp), %ebp + movl (%edx), %edx + /* GCROOT %eax */ + /* GCROOT %ebp */ + movl %eax, 68(%esp) + movl %edi, %eax + movl 64(%esp), %edi + /* GCROOT %eax */ + /* GCROOT %edi */ + testl %edx, %edx + jne L1529 +L1520: + movl %eax, 24(%esp) + movl %eax, 20(%esp) + movl %eax, 16(%esp) + movl %eax, 12(%esp) + movl %eax, 8(%esp) + movl %eax, 4(%esp) + movl 44(%esp), %eax + movl %eax, (%esp) + call _pypy_g_foo + ;; expected {140(%esp) | 124(%esp), 128(%esp), 132(%esp), 136(%esp) | %edi, %ebp, 68(%esp), 72(%esp), 76(%esp), 80(%esp)} + movl 68(%esp), %edx + movl 72(%esp), %eax + /* GCROOT %edx */ + /* GCROOT %eax */ + movl %edx, 84(%esp) + movl 80(%esp), %ecx + movl %eax, 88(%esp) + movl 76(%esp), %edx + movl %edi, %eax + /* GCROOT %edx */ + /* GCROOT %ecx */ + /* GCROOT %eax */ + movl %edx, 92(%esp) + movl %ebp, %edx + /* GCROOT %edx */ + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000044$pb"(%ebx), %esi + movl (%esi), %esi + testl %esi, %esi + jne L1529 +L1521: + movl %eax, 24(%esp) + movl 92(%esp), %eax + movl %edx, 20(%esp) + movl 84(%esp), %esi + movl 88(%esp), %edx + movl %ecx, 12(%esp) + movl %eax, 16(%esp) + movl 44(%esp), %eax + movl %esi, 4(%esp) + movl %edx, 8(%esp) + movl %eax, (%esp) + call _pypy_g_foo + ;; expected {140(%esp) | 124(%esp), 128(%esp), 132(%esp), 136(%esp) | } + jmp L1529 + .align 4,0x90 +L1515: + movl $8, 4(%esp) + movl %edi, (%esp) + call _pypy_g_SemiSpaceGC_try_obtain_free_space + ;; expected {140(%esp) | 124(%esp), 128(%esp), 132(%esp), 136(%esp) | 148(%esp), 152(%esp), 156(%esp), 160(%esp), 164(%esp), 168(%esp)} + movl (%esi), %edx + xorl %ecx, %ecx + testl %edx, %edx + je L1533 +L1524: + movl L_pypy_g_ExcData$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + xorl %edx, %edx + xorl %edi, %edi + movl (%eax), %eax + testl %eax, %eax + jne L1518 + movl L_pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC$non_lazy_ptr-"L00000000044$pb"(%ebx), %edi + movl %ecx, %edx + jmp L1517 +L1533: +L1522: + testb %al, %al + jne L1525 +L1526: + movl L_pypy_g_exceptions_MemoryError_vtable$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + movl %eax, (%esi) + movl L_pypy_g_exceptions_MemoryError_1$non_lazy_ptr-"L00000000044$pb"(%ebx), %eax + movl %eax, 4(%esi) + jmp L1524 +L1525: + movl 12(%edi), %ecx + jmp L1524 + .align 4,0x90 \ No newline at end of file From pedronis at codespeak.net Sun Aug 16 17:59:26 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 17:59:26 +0200 (CEST) Subject: [pypy-svn] r66858 - pypy/branch/pyjitpl5/pypy/translator/c/src Message-ID: <20090816155926.3CE6C168029@codespeak.net> Author: pedronis Date: Sun Aug 16 17:59:24 2009 New Revision: 66858 Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h Log: give the fuction a cdecl name Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h Sun Aug 16 17:59:24 2009 @@ -7,7 +7,7 @@ asm volatile("addl %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ - "call op_int_overflowed\n\t" \ + "call _op_int_overflowed\n\t" \ "popa\n\t" \ "0:" \ : "=r"(r) /* outputs */ \ @@ -22,7 +22,7 @@ asm volatile("subl %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ - "call op_int_overflowed\n\t" \ + "call _op_int_overflowed\n\t" \ "popa\n\t" \ "0:" \ : "=r"(r) /* outputs */ \ @@ -34,7 +34,7 @@ asm volatile("imull %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ - "call op_int_overflowed\n\t" \ + "call _op_int_overflowed\n\t" \ "popa\n\t" \ "0:" \ : "=r"(r) /* outputs */ \ @@ -45,7 +45,7 @@ /* prototypes */ extern void op_int_overflowed(void) - asm ("op_int_overflowed") + asm ("_op_int_overflowed") __attribute__((used)); /* implementations */ From arigo at codespeak.net Sun Aug 16 18:05:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Aug 2009 18:05:36 +0200 (CEST) Subject: [pypy-svn] r66859 - pypy/branch/pyjitpl5/pypy/translator/c/src Message-ID: <20090816160536.86E02168029@codespeak.net> Author: arigo Date: Sun Aug 16 18:05:35 2009 New Revision: 66859 Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h Log: Put comments /* ignore_in_trackgcroot */ around the generated assembler that we don't want trackgcroot.py to look into. Used for Intel Macs which don't add #APP and #NO_APP markers automatically. Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/src/asm_gcc_x86.h Sun Aug 16 18:05:35 2009 @@ -4,12 +4,15 @@ #undef OP_INT_ADD_OVF #define OP_INT_ADD_OVF(x,y,r) \ - asm volatile("addl %2,%0\n\t" \ + asm volatile( \ + "/* ignore_in_trackgcroot */\n\t" \ + "addl %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ "call _op_int_overflowed\n\t" \ "popa\n\t" \ - "0:" \ + "0:\n\t" \ + "/* end_ignore_in_trackgcroot */" \ : "=r"(r) /* outputs */ \ : "0"(x), "g"(y) /* inputs */ \ : "cc", "memory") /* clobber */ @@ -19,24 +22,30 @@ #undef OP_INT_SUB_OVF #define OP_INT_SUB_OVF(x,y,r) \ - asm volatile("subl %2,%0\n\t" \ + asm volatile( \ + "/* ignore_in_trackgcroot */\n\t" \ + "subl %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ "call _op_int_overflowed\n\t" \ "popa\n\t" \ - "0:" \ + "0:\n\t" \ + "/* end_ignore_in_trackgcroot */" \ : "=r"(r) /* outputs */ \ : "0"(x), "g"(y) /* inputs */ \ : "cc", "memory") /* clobber */ #undef OP_INT_MUL_OVF #define OP_INT_MUL_OVF(x,y,r) \ - asm volatile("imull %2,%0\n\t" \ + asm volatile( \ + "/* ignore_in_trackgcroot */\n\t" \ + "imull %2,%0\n\t" \ "jno 0f\n\t" \ "pusha\n\t" \ "call _op_int_overflowed\n\t" \ "popa\n\t" \ - "0:" \ + "0:\n\t" \ + "/* end_ignore_in_trackgcroot */" \ : "=r"(r) /* outputs */ \ : "0"(x), "g"(y) /* inputs */ \ : "cc", "memory") /* clobber */ From pedronis at codespeak.net Sun Aug 16 19:00:00 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 19:00:00 +0200 (CEST) Subject: [pypy-svn] r66860 - in pypy/branch/pyjitpl5/pypy/translator/c/gcc: . test test/darwin Message-ID: <20090816170000.09EE4168029@codespeak.net> Author: pedronis Date: Sun Aug 16 18:59:59 2009 New Revision: 66860 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: WIP mainly deal with static functions properly and ignore our own handcrafted assembler Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track0.s Sun Aug 16 18:59:59 2009 @@ -1,4 +1,3 @@ -.globl _pypy_g_clear_large_memory_chunk _pypy_g_clear_large_memory_chunk: L80: pushl %ebp Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track1.s Sun Aug 16 18:59:59 2009 @@ -1,4 +1,3 @@ -.globl _pypy_g_clear_large_memory_chunk _pypy_g_clear_large_memory_chunk: L137: pushl %ebp Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track2.s Sun Aug 16 18:59:59 2009 @@ -1,4 +1,3 @@ -.globl _pypy_g_populate _pypy_g_populate: L2135: subl $76, %esp Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/darwin/track8.s Sun Aug 16 18:59:59 2009 @@ -1,4 +1,3 @@ -.globl _pypy_g_foo _pypy_g_foo: L1506: subl $140, %esp Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/test/test_trackgcroot.py Sun Aug 16 18:59:59 2009 @@ -76,8 +76,12 @@ \t.align 4,0x90 .globl _pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin _pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin: +L0: \tFOO \t.align 4,0x90 +_static: +\tSTATIC +\t.align 4,0x90 .globl _pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr _pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr: \tBAR @@ -92,13 +96,14 @@ """ lines = source.splitlines(True) parts = list(GcRootTracker(format='darwin').find_functions(iter(lines))) - assert len(parts) == 6 - assert parts[0] == (False, lines[:2]) - assert parts[1] == (True, lines[2:6]) - assert parts[2] == (True, lines[6:9]) - assert parts[3] == (False, lines[9:13]) - assert parts[4] == (True, lines[13:16]) - assert parts[5] == (False, lines[16:]) + assert len(parts) == 7 + assert parts[0] == (False, lines[:3]) + assert parts[1] == (True, lines[3:7]) + assert parts[2] == (True, lines[7:11]) + assert parts[3] == (True, lines[11:13]) + assert parts[4] == (False, lines[13:18]) + assert parts[5] == (True, lines[18:20]) + assert parts[6] == (False, lines[20:]) def test_computegcmaptable(): tests = [] Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Sun Aug 16 18:59:59 2009 @@ -7,14 +7,14 @@ # darwin r_textstart = re.compile(r"\t.text\s*$") -r_sectionstart = re.compile(r"\t.(section|cstring|data).*$") -r_functionstart_darwin = re.compile(r".globl\s+(\w+)\s*$") +r_sectionstart = re.compile(r"\t.(section|cstring|const|data).*$") +r_functionstart_darwin = re.compile(r"_(\w+):\s*$") # inside functions r_label = re.compile(r"([.]?\w+)[:]\s*$") r_globl = re.compile(r"\t[.]globl\t(\w+)\s*$") r_insn = re.compile(r"\t([a-z]\w*)\s") -r_jump = re.compile(r"\tj\w+\s+([.]?\w+)\s*$") +r_jump = re.compile(r"\tj\w+\s+([.]?[\w$]+)\s*$") OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])' r_unaryinsn = re.compile(r"\t[a-z]\w*\s+("+OPERAND+")\s*$") r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+([*]"+OPERAND+")\s*$") @@ -140,9 +140,9 @@ functionlines = [] in_text = False in_function = False - for line in iterlines: + for n, line in enumerate(iterlines): if r_textstart.match(line): - assert not in_text, "unexpected repeated .text start" + assert not in_text, "unexpected repeated .text start: %d" % n in_text = True elif r_sectionstart.match(line): if in_function: @@ -160,6 +160,8 @@ yield in_function, functionlines def process(self, iterlines, newfile, entrypoint='main', filename='?'): + if self.format == 'darwin': + entrypoint = '_' + entrypoint for in_function, lines in self.find_functions(iterlines): if in_function: lines = self.process_function(lines, entrypoint, filename) @@ -170,6 +172,7 @@ def process_function(self, lines, entrypoint, filename): tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename), format=self.format) + print >> sys.stderr, entrypoint tracker.is_main = tracker.funcname == entrypoint if self.verbose == 1: sys.stderr.write('.') @@ -200,7 +203,7 @@ assert funcname == match.group(2) elif format == 'darwin': match = r_functionstart_darwin.match(lines[0]) - funcname = match.group(1) + funcname = '_'+match.group(1) else: assert False, "unknown format: %s" % format @@ -280,13 +283,13 @@ def parse_instructions(self): self.insns = [InsnFunctionStart()] - in_APP = False + ignore_insns = False for lineno, line in enumerate(self.lines): self.currentlineno = lineno insn = [] match = r_insn.match(line) if match: - if not in_APP: + if not ignore_insns: opname = match.group(1) try: meth = getattr(self, 'visit_' + opname) @@ -295,10 +298,10 @@ insn = meth(line) elif r_gcroot_marker.match(line): insn = self._visit_gcroot_marker(line) - elif line == '#APP\n': - in_APP = True - elif line == '#NO_APP\n': - in_APP = False + elif line == '\t/* ignore_in_trackgcroot */\n': + ignore_insns = True + elif line == '\t/* end_ignore_in_trackgcroot */\n': + ignore_insns = False else: match = r_label.match(line) if match: @@ -478,7 +481,7 @@ 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'prefetch', # floating-point operations cannot produce GC pointers 'f', - 'cvt', # sse2 + 'cvt', 'ucomi', 'subs', 'subp' , 'xorp', 'movap', # sse2 # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', @@ -1070,7 +1073,11 @@ output_raw_table = True else: break - tracker = GcRootTracker(verbose=verbose, shuffle=shuffle) + if sys.platform == 'darwin': + format = 'darwin' + else: + format = 'elf' + tracker = GcRootTracker(verbose=verbose, shuffle=shuffle, format=format) for fn in sys.argv[1:]: tmpfn = fn + '.TMP' f = open(fn, 'r') From pedronis at codespeak.net Sun Aug 16 20:36:36 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 20:36:36 +0200 (CEST) Subject: [pypy-svn] r66861 - in pypy/branch/pyjitpl5/pypy/translator/c: gcc src Message-ID: <20090816183636.738C416802B@codespeak.net> Author: pedronis Date: Sun Aug 16 20:36:35 2009 New Revision: 66861 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py pypy/branch/pyjitpl5/pypy/translator/c/src/mem.h Log: * the asmgcroot tests now pass on Mac OS X (leopard) * targetgcbench also works with gcrootfinder=asmgcc - make sure gcmaptable.s is produced with valid directives and the defining the right names for linking - ignore some more modern fp instructions - consider all possible section directives for Mac OS X 'as' - make sure pypy_asm_stackwalk respects the ABI stack aligment requirements Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Sun Aug 16 20:36:35 2009 @@ -7,7 +7,19 @@ # darwin r_textstart = re.compile(r"\t.text\s*$") -r_sectionstart = re.compile(r"\t.(section|cstring|const|data).*$") +# see +# http://developer.apple.com/documentation/developertools/Reference/Assembler/040-Assembler_Directives/asm_directives.html +OTHERSECTIONS = ['section', 'zerofill', + 'const', 'static_const', 'cstring', + 'literal4', 'literal8', 'literal16', + 'constructor', 'desctructor', + 'symbol_stub', + 'data', 'static_data', + 'non_lazy_symbol_pointer', 'lazy_symbol_pointer', + 'dyld', 'mod_init_func', 'mod_term_func', + 'const_data' + ] +r_sectionstart = re.compile(r"\t\.("+'|'.join(OTHERSECTIONS)+").*$") r_functionstart_darwin = re.compile(r"_(\w+):\s*$") # inside functions @@ -62,10 +74,26 @@ shapes = {} shapelines = [] shapeofs = 0 - print >> output, """\t.text - .globl pypy_asm_stackwalk - .type pypy_asm_stackwalk, @function - pypy_asm_stackwalk: + def _globalname(name): + if self.format == 'darwin': + return '_' + name + return name + def _globl(name): + print >> output, "\t.globl %s" % _globalname(name) + def _label(name): + print >> output, "%s:" % _globalname(name) + def _variant(elf, darwin): + if self.format == 'darwin': + txt = darwin + else: + txt = elf + print >> output, "\t%s" % txt + + print >> output, "\t.text" + _globl('pypy_asm_stackwalk') + _variant('.type pypy_asm_stackwalk, @function', '') + _label('pypy_asm_stackwalk') + print >> output, """\ /* See description in asmgcroot.py */ movl 4(%esp), %edx /* my argument, which is the callback */ movl %esp, %eax /* my frame top address */ @@ -75,21 +103,22 @@ pushl %esi /* ASM_FRAMEDATA[1] */ pushl %ebx /* ASM_FRAMEDATA[0] */ movl %esp, %eax /* address of ASM_FRAMEDATA */ - pushl %eax + pushl %eax /* respect Mac OS X 16 bytes aligment */ + pushl %eax /* the one argument to the callback */ call *%edx /* invoke the callback */ - popl %eax + addl $8, %esp popl %ebx /* restore from ASM_FRAMEDATA[0] */ popl %esi /* restore from ASM_FRAMEDATA[1] */ popl %edi /* restore from ASM_FRAMEDATA[2] */ popl %ebp /* restore from ASM_FRAMEDATA[3] */ popl %eax ret - .size pypy_asm_stackwalk, .-pypy_asm_stackwalk - """ +""" + _variant('.size pypy_asm_stackwalk, .-pypy_asm_stackwalk', '') print >> output, '\t.data' print >> output, '\t.align\t4' - print >> output, '\t.globl\t__gcmapstart' - print >> output, '__gcmapstart:' + _globl('__gcmapstart') + _label('__gcmapstart') for label, state, is_range in self.gcmaptable: try: n = shapes[state] @@ -104,11 +133,11 @@ n = ~ n print >> output, '\t.long\t%s' % (label,) print >> output, '\t.long\t%d' % (n,) - print >> output, '\t.globl\t__gcmapend' - print >> output, '__gcmapend:' - print >> output, '\t.section\t.rodata' - print >> output, '\t.globl\t__gccallshapes' - print >> output, '__gccallshapes:' + _globl('__gcmapend') + _label('__gcmapend') + _variant('.section\t.rodata', '.const') + _globl('__gccallshapes') + _label('__gccallshapes') output.writelines(shapelines) def find_functions(self, iterlines): @@ -172,7 +201,6 @@ def process_function(self, lines, entrypoint, filename): tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename), format=self.format) - print >> sys.stderr, entrypoint tracker.is_main = tracker.funcname == entrypoint if self.verbose == 1: sys.stderr.write('.') @@ -481,7 +509,7 @@ 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'prefetch', # floating-point operations cannot produce GC pointers 'f', - 'cvt', 'ucomi', 'subs', 'subp' , 'xorp', 'movap', # sse2 + 'cvt', 'ucomi', 'subs', 'subp' , 'adds', 'addp', 'xorp', 'movap', # sse2 # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', Modified: pypy/branch/pyjitpl5/pypy/translator/c/src/mem.h ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/src/mem.h (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/src/mem.h Sun Aug 16 20:36:35 2009 @@ -20,7 +20,7 @@ extern char __gcmapstart; extern char __gcmapend; extern char __gccallshapes; -extern char __gcnoreorderhack; +#define __gcnoreorderhack __gcmapend /* The following pseudo-instruction is used by --gcrootfinder=asmgcc just after a call to tell gcc to put a GCROOT mark on each gc-pointer From pedronis at codespeak.net Sun Aug 16 21:11:53 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 16 Aug 2009 21:11:53 +0200 (CEST) Subject: [pypy-svn] r66862 - pypy/branch/pyjitpl5/pypy/translator/c/gcc Message-ID: <20090816191153.3E59916802D@codespeak.net> Author: pedronis Date: Sun Aug 16 21:11:48 2009 New Revision: 66862 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: - more instruction to ignore - some Mac OS X runtime function refs that don't return this allows to translate prolog with gcrootfinder=asmgcc on Mac OS X Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Sun Aug 16 21:11:48 2009 @@ -283,7 +283,8 @@ loc = localvar.getlocation(insn.framesize, self.uses_frame_pointer) else: - assert localvar in REG2LOC + assert localvar in REG2LOC, "%s: %s" % (self.funcname, + localvar) loc = REG2LOC[localvar] assert isinstance(loc, int) if tag is None: @@ -509,7 +510,8 @@ 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'prefetch', # floating-point operations cannot produce GC pointers 'f', - 'cvt', 'ucomi', 'subs', 'subp' , 'adds', 'addp', 'xorp', 'movap', # sse2 + 'cvt', 'ucomi', 'subs', 'subp' , 'adds', 'addp', 'xorp', 'movap', + 'mins', 'minp', 'maxs', 'maxp', # sse2 # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', @@ -930,6 +932,8 @@ 'abort': None, '_exit': None, '__assert_fail': None, + '___assert_rtn': None, + 'L___assert_rtn$stub': None } CALLEE_SAVE_REGISTERS_NOEBP = ['%ebx', '%esi', '%edi'] From magcius at codespeak.net Sun Aug 16 23:00:57 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Sun, 16 Aug 2009 23:00:57 +0200 (CEST) Subject: [pypy-svn] r66863 - in pypy/branch/avm: .ropeproject pypy/translator/avm1 pypy/translator/avm2 Message-ID: <20090816210057.73166168030@codespeak.net> Author: magcius Date: Sun Aug 16 23:00:55 2009 New Revision: 66863 Added: pypy/branch/avm/.ropeproject/ pypy/branch/avm/.ropeproject/config.py Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py pypy/branch/avm/pypy/translator/avm1/function.py pypy/branch/avm/pypy/translator/avm1/genavm.py pypy/branch/avm/pypy/translator/avm1/metavm.py pypy/branch/avm/pypy/translator/avm1/opcodes.py pypy/branch/avm/pypy/translator/avm1/swf.py pypy/branch/avm/pypy/translator/avm1/tags.py pypy/branch/avm/pypy/translator/avm2/__init__.py pypy/branch/avm/pypy/translator/avm2/constants.py Log: Changed import paths Added: pypy/branch/avm/.ropeproject/config.py ============================================================================== --- (empty file) +++ pypy/branch/avm/.ropeproject/config.py Sun Aug 16 23:00:55 2009 @@ -0,0 +1,85 @@ +# The default ``config.py`` + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + #prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + #prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + #prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1.py Sun Aug 16 23:00:55 2009 @@ -2,7 +2,7 @@ # AVM1 = ActionScript Virtual Machine 1 # Used for ActionScript 1 and 2 -from pypy.translator.avm.util import BitStream +from pypy.translator.avm1.util import BitStream from collections import namedtuple import struct Modified: pypy/branch/avm/pypy/translator/avm1/function.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/function.py (original) +++ pypy/branch/avm/pypy/translator/avm1/function.py Sun Aug 16 23:00:55 2009 @@ -4,8 +4,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lltype import Void from pypy.translator.oosupport.function import Function as OOFunction -from pypy.translator.avm.node import Node -from pypy.translator.avm.avm1gen import ClassName +from pypy.translator.avm1.node import Node +from pypy.translator.avm1.avm1gen import ClassName def load_variable_hook(self, v): if v.name in self.argset: Modified: pypy/branch/avm/pypy/translator/avm1/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm1/genavm.py Sun Aug 16 23:00:55 2009 @@ -1,12 +1,12 @@ import py from pypy.translator.oosupport.genoo import GenOO -from pypy.translator.avm.avm1gen import AVM1Gen -from pypy.translator.avm.constant import AVM1ConstGenerator -from pypy.translator.avm.database import LowLevelDatabase -from pypy.translator.avm.function import Function -from pypy.translator.avm.opcodes import opcodes -from pypy.translator.avm.types import AVM1TypeSystem +from pypy.translator.avm1.avm1gen import AVM1Gen +from pypy.translator.avm1.constant import AVM1ConstGenerator +from pypy.translator.avm1.database import LowLevelDatabase +from pypy.translator.avm1.function import Function +from pypy.translator.avm1.opcodes import opcodes +from pypy.translator.avm1.types import AVM1TypeSystem class GenAVM1(GenOO): Modified: pypy/branch/avm/pypy/translator/avm1/metavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/metavm.py (original) +++ pypy/branch/avm/pypy/translator/avm1/metavm.py Sun Aug 16 23:00:55 2009 @@ -1,7 +1,6 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.oosupport.metavm import MicroInstruction -from pypy.translator.avm.avm1gen import StackDummy class _SetField(MicroInstruction): def render(self, generator, op): Modified: pypy/branch/avm/pypy/translator/avm1/opcodes.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/opcodes.py (original) +++ pypy/branch/avm/pypy/translator/avm1/opcodes.py Sun Aug 16 23:00:55 2009 @@ -1,6 +1,6 @@ from pypy.translator.oosupport import metavm as om -from pypy.translator.avm import metavm as am, avm1 as a +from pypy.translator.avm1 import metavm as am, avm1 as a DoNothing = [om.PushAllArgs] Modified: pypy/branch/avm/pypy/translator/avm1/swf.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/swf.py (original) +++ pypy/branch/avm/pypy/translator/avm1/swf.py Sun Aug 16 23:00:55 2009 @@ -1,8 +1,8 @@ import struct -from pypy.translator.avm.util import BitStream -from pypy.translator.avm.records import Rect +from pypy.translator.avm1.util import BitStream +from pypy.translator.avm1.records import Rect class SwfData(object): Modified: pypy/branch/avm/pypy/translator/avm1/tags.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/tags.py (original) +++ pypy/branch/avm/pypy/translator/avm1/tags.py Sun Aug 16 23:00:55 2009 @@ -1,9 +1,9 @@ import struct -from pypy.translator.avm.records import RecordHeader, ShapeWithStyle, Matrix, CXForm -from pypy.translator.avm.avm1 import Block -from pypy.translator.avm.util import BitStream +from pypy.translator.avm1.records import RecordHeader, ShapeWithStyle, Matrix, CXForm +from pypy.translator.avm1.avm1 import Block +from pypy.translator.avm1.util import BitStream next_character_id = 1 Modified: pypy/branch/avm/pypy/translator/avm2/__init__.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/__init__.py (original) +++ pypy/branch/avm/pypy/translator/avm2/__init__.py Sun Aug 16 23:00:55 2009 @@ -1 +1 @@ -a + Modified: pypy/branch/avm/pypy/translator/avm2/constants.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/constants.py (original) +++ pypy/branch/avm/pypy/translator/avm2/constants.py Sun Aug 16 23:00:55 2009 @@ -1,6 +1,6 @@ import struct -from pypy.translator.avm.util import serialize_u32 as u32 +from pypy.translator.avm2.util import serialize_u32 as u32 # ====================================== # Constants @@ -69,7 +69,7 @@ return not self == other def write_to_pool(self, pool): - self._name_index = pool.utf8_index(name) + self._name_index = pool.utf8_pool.index_for(self.name) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" @@ -94,11 +94,11 @@ return not self == other def write_to_pool(self, pool): - self._namespace_indices = [pool.namespace_index(ns) for ns in self.namespaces] + self._namespace_indices = [pool.namespace_pool.index_for(ns) for ns in self.namespaces] def serialize(self): assert self._namespace_indices is not None, "Please call write_to_pool before serializing" - return u32(len(self.namespaces)) + ''.join(u32(index) for index in self_namespace_indices) + return u32(len(self.namespaces)) + ''.join(u32(index) for index in self._namespace_indices) NO_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "") @@ -127,7 +127,7 @@ return hash((self.kind, self.ns_set)) def write_to_pool(self, pool): - self._ns_set_index = pool.nsset_index(self.ns_set) + self._ns_set_index = pool.nsset_pool.index_for(self.ns_set) def serialize(self): assert self._ns_set_index is not None, "Please call write_to_pool before serializing" @@ -155,7 +155,7 @@ def write_to_pool(self, pool): super(Multiname, self).write_to_pool(pool) - self._name_index = pool.utf8_index(self.name) + self._name_index = pool.utf8_pool.index_for(self.name) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" @@ -186,8 +186,8 @@ return hash((self.kind, self.name, self.ns)) def write_to_pool(self, pool): - self._name_index = pool.utf8_index(self.name) - self._ns_index = pool.namespace_index(self.ns) + self._name_index = pool.utf8_pool.index_for(self.name) + self._ns_index = pool.namespace_pool.index_for(self.ns) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" @@ -223,7 +223,7 @@ self._name_index = None def write_to_pool(self, pool): - self._name_index = pool.utf8_index(name) + self._name_index = pool.utf8_pool.index_for(name) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" @@ -232,22 +232,7 @@ # Constant Pool # ====================================== -def constant_index_base(default, pool_name): - def fn(self, value): - if value == default: - return 0 - - pool = getattr(self, pool_name) - - if value in pool: - return pool.index(value) + 1 - else: - pool.append(value) - return len(pool) - - return fn - -class OptimizedPool(object): +class ValuePool(object): def __init__(self, default): self.index_map = {} @@ -258,17 +243,17 @@ if value == self.default: return 0 - if value in index_map: - return index_map[value] + if value in self.index_map: + return self.index_map[value] self.pool.append(value) index = len(self.pool) self.index_map[value] = index return index - + def value_at(self, index): if index == 0: - return default + return self.default if index < len(self.pool): return self.pool[index] @@ -278,26 +263,25 @@ class AbcConstantPool(object): def __init__(self): - self.int_pool = OptimizedPool() - self.uint_pool = OptimizedPool() - self.double_pool = OptimizedPool() - self.utf8_pool = OptimizedPool() - self.namespace_pool = OptimizedPool() - self.nsset_pool = OptimizedPool() - self.multiname_pool = OptimizedPool() - - int_index = constant_index_base(0, "int_pool") - uint_index = constant_index_base(0, "uint_pool") - double_index = constant_index_base(float("nan"), "double_pool") - utf8_index = constant_index_base("", "utf8_pool") - namespace_index = constant_index_base(ANY_NAMESPACE, "namespace_pool") - nsset_index = constant_index_base(NO_NAMESPACE_SET, "nsset_pool") - + self.int_pool = ValuePool(0) + self.uint_pool = ValuePool(0) + self.double_pool = ValuePool(float("nan")) + self.utf8_pool = ValuePool("") + self.namespace_pool = ValuePool(ANY_NAMESPACE) + self.nsset_pool = ValuePool(NO_NAMESPACE_SET) + self.multiname_pool = ValuePool() + def has_RTNS(self, index): - return self.multiname_pool[index].kind in (TYPE_MULTINAME_RtqName, TYPE_MULTINAME_RtqNameA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA) + return self.multiname_pool[index].kind in (TYPE_MULTINAME_RtqName, + TYPE_MULTINAME_RtqNameA, + TYPE_MULTINAME_RtqNameL, + TYPE_MULTINAME_RtqNameLA) def has_RTName(self, index): - return self.multiname_pool[index].kind in (TYPE_MULTINAME_MultinameL, TYPE_MULTINAME_MultinameLA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA) + return self.multiname_pool[index].kind in (TYPE_MULTINAME_MultinameL, + TYPE_MULTINAME_MultinameLA, + TYPE_MULTINAME_RtqNameL, + TYPE_MULTINAME_RtqNameLA) def serialize(self): From benjamin at codespeak.net Sun Aug 16 23:51:14 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 16 Aug 2009 23:51:14 +0200 (CEST) Subject: [pypy-svn] r66864 - in pypy/branch/parser-compiler: lib-python pypy/config pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/astcompiler/tools pypy/interpreter/pyparser pypy/module/__builtin__ pypy/module/_ast pypy/module/_ast/test Message-ID: <20090816215114.C5F63168030@codespeak.net> Author: benjamin Date: Sun Aug 16 23:51:12 2009 New Revision: 66864 Added: pypy/branch/parser-compiler/pypy/module/_ast/ pypy/branch/parser-compiler/pypy/module/_ast/__init__.py pypy/branch/parser-compiler/pypy/module/_ast/test/ pypy/branch/parser-compiler/pypy/module/_ast/test/__init__.py pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Modified: pypy/branch/parser-compiler/lib-python/conftest.py pypy/branch/parser-compiler/pypy/config/pypyoption.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/consts.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py pypy/branch/parser-compiler/pypy/interpreter/pyparser/error.py pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py Log: expose AST to the applevel through the _ast module Modified: pypy/branch/parser-compiler/lib-python/conftest.py ============================================================================== --- pypy/branch/parser-compiler/lib-python/conftest.py (original) +++ pypy/branch/parser-compiler/lib-python/conftest.py Sun Aug 16 23:51:12 2009 @@ -131,7 +131,7 @@ RegrTest('test__locale.py', skip=skip_win32), RegrTest('test_aepack.py', skip=True), RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', skip="unsupported module _ast"), + RegrTest('test_ast.py', core=True), RegrTest('test_anydbm.py'), RegrTest('test_applesingle.py', skip=True), RegrTest('test_array.py', core=True, usemodules='struct'), Modified: pypy/branch/parser-compiler/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/parser-compiler/pypy/config/pypyoption.py (original) +++ pypy/branch/parser-compiler/pypy/config/pypyoption.py Sun Aug 16 23:51:12 2009 @@ -18,7 +18,7 @@ default_modules.update(dict.fromkeys( ["_codecs", "gc", "_weakref", "marshal", "errno", "math", "_sre", "_pickle_support", "operator", - "parser", "symbol", "token", "_random", "__pypy__"])) + "parser", "symbol", "token", "_ast", "_random", "__pypy__"])) # --allworkingmodules Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Sun Aug 16 23:51:12 2009 @@ -1,11 +1,17 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import Wrappable, ObjSpace, W_Root from pypy.interpreter import typedef +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.argument import Arguments +from pypy.interpreter.error import OperationError +from pypy.rlib.unroll import unrolling_iterable from pypy.tool.pairtype import extendabletype +from pypy.tool.sourcetools import func_with_new_name + class AST(Wrappable): - __slots__ = () + __slots__ = ("initialization_state",) __metaclass__ = extendabletype @@ -15,19 +21,66 @@ def mutate_over(self, visitor): raise AssertionError("mutate_over() implementation not provided") + def sync_app_attrs(self, space): + raise NotImplementedError + + class NodeVisitorNotImplemented(Exception): pass + +class _FieldsWrapper(Wrappable): + "Hack around the fact we can't store tuples on a TypeDef." + + def __init__(self, fields): + self.fields = fields + + def __spacebind__(self, space): + return space.newtuple([space.wrap(field) for field in self.fields]) + + +def get_AST_new(node_class): + def generic_AST_new(space, w_type, __args__): + node = space.allocate_instance(node_class, w_type) + node.initialization_state = 0 + return space.wrap(node) + generic_AST_new.unwrap_spec = [ObjSpace, W_Root, Arguments] + return func_with_new_name(generic_AST_new, "new_%s" % node_class.__name__) + + +AST.typedef = typedef.TypeDef("AST", + _fields=_FieldsWrapper([]), + _attributes=_FieldsWrapper([]), +) +AST.typedef.acceptable_as_base_class = False + + +def missing_field(space, state, required, host): + "Find which required field is missing." + for i in range(len(required)): + if not (state >> i) & 1: + missing = required[i] + if missing is not None: + err = "required attribute '%s' missing from %s" + err %= (missing, host) + w_err = space.wrap(err) + raise OperationError(space.w_TypeError, w_err) + raise AssertionError("should not reach here") + + class mod(AST): __slots__ = () class Module(mod): - __slots__ = ('body') + __slots__ = ('body', 'w_body') + def __init__(self, body): self.body = body + self.w_body = None + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_Module(self) @@ -37,12 +90,32 @@ visitor._mutate_sequence(self.body) return visitor.visit_Module(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['body'], 'Module') + else: + pass + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + + class Interactive(mod): - __slots__ = ('body') + __slots__ = ('body', 'w_body') + def __init__(self, body): self.body = body + self.w_body = None + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_Interactive(self) @@ -52,12 +125,31 @@ visitor._mutate_sequence(self.body) return visitor.visit_Interactive(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['body'], 'Interactive') + else: + pass + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + + class Expression(mod): __slots__ = ('body') + def __init__(self, body): self.body = body + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_Expression(self) @@ -66,12 +158,23 @@ self.body = self.body.mutate_over(visitor) return visitor.visit_Expression(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['body'], 'Expression') + else: + pass + self.body.sync_app_attrs(space) + + class Suite(mod): - __slots__ = ('body') + __slots__ = ('body', 'w_body') + def __init__(self, body): self.body = body + self.w_body = None + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_Suite(self) @@ -81,6 +184,23 @@ visitor._mutate_sequence(self.body) return visitor.visit_Suite(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['body'], 'Suite') + else: + pass + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + + class stmt(AST): __slots__ = ('lineno', 'col_offset') @@ -91,14 +211,20 @@ class FunctionDef(stmt): - __slots__ = ('name', 'args', 'body', 'decorators') + __slots__ = ('name', 'args', 'body', 'w_body', 'decorators', 'w_decorators') + + _lineno_mask = 16 + _col_offset_mask = 32 def __init__(self, name, args, body, decorators, lineno, col_offset): self.name = name self.args = args self.body = body + self.w_body = None self.decorators = decorators + self.w_decorators = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 63 def walkabout(self, visitor): visitor.visit_FunctionDef(self) @@ -110,15 +236,49 @@ visitor._mutate_sequence(self.decorators) return visitor.visit_FunctionDef(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 63: + missing_field(space, self.initialization_state, ['name', 'args', 'body', 'decorators', 'lineno', 'col_offset'], 'FunctionDef') + else: + pass + self.args.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_decorators + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.decorators = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.decorators = None + if self.decorators is not None: + for node in self.decorators: + node.sync_app_attrs(space) + + class ClassDef(stmt): - __slots__ = ('name', 'bases', 'body') + __slots__ = ('name', 'bases', 'w_bases', 'body', 'w_body') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, name, bases, body, lineno, col_offset): self.name = name self.bases = bases + self.w_bases = None self.body = body + self.w_body = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_ClassDef(self) @@ -130,13 +290,44 @@ visitor._mutate_sequence(self.body) return visitor.visit_ClassDef(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['name', 'bases', 'body', 'lineno', 'col_offset'], 'ClassDef') + else: + pass + w_list = self.w_bases + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.bases = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.bases = None + if self.bases is not None: + for node in self.bases: + node.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + + class Return(stmt): __slots__ = ('value') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, value, lineno, col_offset): self.value = value stmt.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Return(self) @@ -146,13 +337,27 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Return(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~1) ^ 6: + missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Return') + else: + if not self.initialization_state & 1: + self.value = None + self.value.sync_app_attrs(space) + + class Delete(stmt): - __slots__ = ('targets') + __slots__ = ('targets', 'w_targets') + + _lineno_mask = 2 + _col_offset_mask = 4 def __init__(self, targets, lineno, col_offset): self.targets = targets + self.w_targets = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Delete(self) @@ -162,14 +367,36 @@ visitor._mutate_sequence(self.targets) return visitor.visit_Delete(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['targets', 'lineno', 'col_offset'], 'Delete') + else: + pass + w_list = self.w_targets + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.targets = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.targets = None + if self.targets is not None: + for node in self.targets: + node.sync_app_attrs(space) + + class Assign(stmt): - __slots__ = ('targets', 'value') + __slots__ = ('targets', 'w_targets', 'value') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, targets, value, lineno, col_offset): self.targets = targets + self.w_targets = None self.value = value stmt.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Assign(self) @@ -180,15 +407,37 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Assign(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['targets', 'value', 'lineno', 'col_offset'], 'Assign') + else: + pass + w_list = self.w_targets + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.targets = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.targets = None + if self.targets is not None: + for node in self.targets: + node.sync_app_attrs(space) + self.value.sync_app_attrs(space) + + class AugAssign(stmt): __slots__ = ('target', 'op', 'value') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, target, op, value, lineno, col_offset): self.target = target self.op = op self.value = value stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_AugAssign(self) @@ -198,15 +447,29 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_AugAssign(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['target', 'op', 'value', 'lineno', 'col_offset'], 'AugAssign') + else: + pass + self.target.sync_app_attrs(space) + self.value.sync_app_attrs(space) + + class Print(stmt): - __slots__ = ('dest', 'values', 'nl') + __slots__ = ('dest', 'values', 'w_values', 'nl') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, dest, values, nl, lineno, col_offset): self.dest = dest self.values = values + self.w_values = None self.nl = nl stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Print(self) @@ -218,16 +481,41 @@ visitor._mutate_sequence(self.values) return visitor.visit_Print(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~1) ^ 30: + missing_field(space, self.initialization_state, [None, 'values', 'nl', 'lineno', 'col_offset'], 'Print') + else: + if not self.initialization_state & 1: + self.dest = None + self.dest.sync_app_attrs(space) + w_list = self.w_values + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.values = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.values = None + if self.values is not None: + for node in self.values: + node.sync_app_attrs(space) + + class For(stmt): - __slots__ = ('target', 'iter', 'body', 'orelse') + __slots__ = ('target', 'iter', 'body', 'w_body', 'orelse', 'w_orelse') + + _lineno_mask = 16 + _col_offset_mask = 32 def __init__(self, target, iter, body, orelse, lineno, col_offset): self.target = target self.iter = iter self.body = body + self.w_body = None self.orelse = orelse + self.w_orelse = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 63 def walkabout(self, visitor): visitor.visit_For(self) @@ -241,15 +529,50 @@ visitor._mutate_sequence(self.orelse) return visitor.visit_For(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 63: + missing_field(space, self.initialization_state, ['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset'], 'For') + else: + pass + self.target.sync_app_attrs(space) + self.iter.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_orelse + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.orelse = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.orelse = None + if self.orelse is not None: + for node in self.orelse: + node.sync_app_attrs(space) + + class While(stmt): - __slots__ = ('test', 'body', 'orelse') + __slots__ = ('test', 'body', 'w_body', 'orelse', 'w_orelse') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, test, body, orelse, lineno, col_offset): self.test = test self.body = body + self.w_body = None self.orelse = orelse + self.w_orelse = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_While(self) @@ -262,15 +585,49 @@ visitor._mutate_sequence(self.orelse) return visitor.visit_While(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'While') + else: + pass + self.test.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_orelse + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.orelse = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.orelse = None + if self.orelse is not None: + for node in self.orelse: + node.sync_app_attrs(space) + + class If(stmt): - __slots__ = ('test', 'body', 'orelse') + __slots__ = ('test', 'body', 'w_body', 'orelse', 'w_orelse') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, test, body, orelse, lineno, col_offset): self.test = test self.body = body + self.w_body = None self.orelse = orelse + self.w_orelse = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_If(self) @@ -283,15 +640,48 @@ visitor._mutate_sequence(self.orelse) return visitor.visit_If(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'If') + else: + pass + self.test.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_orelse + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.orelse = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.orelse = None + if self.orelse is not None: + for node in self.orelse: + node.sync_app_attrs(space) + + class With(stmt): - __slots__ = ('context_expr', 'optional_vars', 'body') + __slots__ = ('context_expr', 'optional_vars', 'body', 'w_body') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, context_expr, optional_vars, body, lineno, col_offset): self.context_expr = context_expr self.optional_vars = optional_vars self.body = body + self.w_body = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_With(self) @@ -304,15 +694,39 @@ visitor._mutate_sequence(self.body) return visitor.visit_With(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~2) ^ 29: + missing_field(space, self.initialization_state, ['context_expr', None, 'body', 'lineno', 'col_offset'], 'With') + else: + if not self.initialization_state & 2: + self.optional_vars = None + self.context_expr.sync_app_attrs(space) + self.optional_vars.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + + class Raise(stmt): __slots__ = ('type', 'inst', 'tback') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, type, inst, tback, lineno, col_offset): self.type = type self.inst = inst self.tback = tback stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Raise(self) @@ -326,15 +740,37 @@ self.tback = self.tback.mutate_over(visitor) return visitor.visit_Raise(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~7) ^ 24: + missing_field(space, self.initialization_state, [None, None, None, 'lineno', 'col_offset'], 'Raise') + else: + if not self.initialization_state & 1: + self.type = None + if not self.initialization_state & 2: + self.inst = None + if not self.initialization_state & 4: + self.tback = None + self.type.sync_app_attrs(space) + self.inst.sync_app_attrs(space) + self.tback.sync_app_attrs(space) + + class TryExcept(stmt): - __slots__ = ('body', 'handlers', 'orelse') + __slots__ = ('body', 'w_body', 'handlers', 'w_handlers', 'orelse', 'w_orelse') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, body, handlers, orelse, lineno, col_offset): self.body = body + self.w_body = None self.handlers = handlers + self.w_handlers = None self.orelse = orelse + self.w_orelse = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_TryExcept(self) @@ -346,14 +782,57 @@ visitor._mutate_sequence(self.orelse) return visitor.visit_TryExcept(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['body', 'handlers', 'orelse', 'lineno', 'col_offset'], 'TryExcept') + else: + pass + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_handlers + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.handlers = [space.interp_w(excepthandler, w_obj) for w_obj in list_w] + else: + self.handlers = None + if self.handlers is not None: + for node in self.handlers: + node.sync_app_attrs(space) + w_list = self.w_orelse + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.orelse = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.orelse = None + if self.orelse is not None: + for node in self.orelse: + node.sync_app_attrs(space) + + class TryFinally(stmt): - __slots__ = ('body', 'finalbody') + __slots__ = ('body', 'w_body', 'finalbody', 'w_finalbody') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, body, finalbody, lineno, col_offset): self.body = body + self.w_body = None self.finalbody = finalbody + self.w_finalbody = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_TryFinally(self) @@ -365,14 +844,45 @@ visitor._mutate_sequence(self.finalbody) return visitor.visit_TryFinally(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['body', 'finalbody', 'lineno', 'col_offset'], 'TryFinally') + else: + pass + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + w_list = self.w_finalbody + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.finalbody = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.finalbody = None + if self.finalbody is not None: + for node in self.finalbody: + node.sync_app_attrs(space) + + class Assert(stmt): __slots__ = ('test', 'msg') + _lineno_mask = 4 + _col_offset_mask = 8 + def __init__(self, test, msg, lineno, col_offset): self.test = test self.msg = msg stmt.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Assert(self) @@ -383,13 +893,28 @@ self.msg = self.msg.mutate_over(visitor) return visitor.visit_Assert(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~2) ^ 13: + missing_field(space, self.initialization_state, ['test', None, 'lineno', 'col_offset'], 'Assert') + else: + if not self.initialization_state & 2: + self.msg = None + self.test.sync_app_attrs(space) + self.msg.sync_app_attrs(space) + + class Import(stmt): - __slots__ = ('names') + __slots__ = ('names', 'w_names') + + _lineno_mask = 2 + _col_offset_mask = 4 def __init__(self, names, lineno, col_offset): self.names = names + self.w_names = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Import(self) @@ -397,15 +922,37 @@ def mutate_over(self, visitor): return visitor.visit_Import(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Import') + else: + pass + w_list = self.w_names + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.names = [space.interp_w(alias, w_obj) for w_obj in list_w] + else: + self.names = None + if self.names is not None: + for node in self.names: + node.sync_app_attrs(space) + + class ImportFrom(stmt): - __slots__ = ('module', 'names', 'level') + __slots__ = ('module', 'names', 'w_names', 'level') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, module, names, level, lineno, col_offset): self.module = module self.names = names + self.w_names = None self.level = level stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_ImportFrom(self) @@ -413,15 +960,39 @@ def mutate_over(self, visitor): return visitor.visit_ImportFrom(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~5) ^ 26: + missing_field(space, self.initialization_state, [None, 'names', None, 'lineno', 'col_offset'], 'ImportFrom') + else: + if not self.initialization_state & 1: + self.module = None + if not self.initialization_state & 4: + self.level = 0 + w_list = self.w_names + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.names = [space.interp_w(alias, w_obj) for w_obj in list_w] + else: + self.names = None + if self.names is not None: + for node in self.names: + node.sync_app_attrs(space) + + class Exec(stmt): __slots__ = ('body', 'globals', 'locals') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, body, globals, locals, lineno, col_offset): self.body = body self.globals = globals self.locals = locals stmt.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Exec(self) @@ -434,13 +1005,31 @@ self.locals = self.locals.mutate_over(visitor) return visitor.visit_Exec(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~6) ^ 25: + missing_field(space, self.initialization_state, ['body', None, None, 'lineno', 'col_offset'], 'Exec') + else: + if not self.initialization_state & 2: + self.globals = None + if not self.initialization_state & 4: + self.locals = None + self.body.sync_app_attrs(space) + self.globals.sync_app_attrs(space) + self.locals.sync_app_attrs(space) + + class Global(stmt): - __slots__ = ('names') + __slots__ = ('names', 'w_names') + + _lineno_mask = 2 + _col_offset_mask = 4 def __init__(self, names, lineno, col_offset): self.names = names + self.w_names = None stmt.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Global(self) @@ -448,13 +1037,31 @@ def mutate_over(self, visitor): return visitor.visit_Global(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Global') + else: + pass + w_list = self.w_names + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.names = [space.str_w(w_obj) for w_obj in list_w] + else: + self.names = None + + class Expr(stmt): __slots__ = ('value') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, value, lineno, col_offset): self.value = value stmt.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Expr(self) @@ -463,12 +1070,24 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Expr(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Expr') + else: + pass + self.value.sync_app_attrs(space) + + class Pass(stmt): __slots__ = () + _lineno_mask = 1 + _col_offset_mask = 2 + def __init__(self, lineno, col_offset): stmt.__init__(self, lineno, col_offset) + self.initialization_state = 3 def walkabout(self, visitor): visitor.visit_Pass(self) @@ -476,12 +1095,23 @@ def mutate_over(self, visitor): return visitor.visit_Pass(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 3: + missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Pass') + else: + pass + + class Break(stmt): __slots__ = () + _lineno_mask = 1 + _col_offset_mask = 2 + def __init__(self, lineno, col_offset): stmt.__init__(self, lineno, col_offset) + self.initialization_state = 3 def walkabout(self, visitor): visitor.visit_Break(self) @@ -489,12 +1119,23 @@ def mutate_over(self, visitor): return visitor.visit_Break(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 3: + missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Break') + else: + pass + + class Continue(stmt): __slots__ = () + _lineno_mask = 1 + _col_offset_mask = 2 + def __init__(self, lineno, col_offset): stmt.__init__(self, lineno, col_offset) + self.initialization_state = 3 def walkabout(self, visitor): visitor.visit_Continue(self) @@ -502,6 +1143,13 @@ def mutate_over(self, visitor): return visitor.visit_Continue(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 3: + missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Continue') + else: + pass + + class expr(AST): __slots__ = ('lineno', 'col_offset') @@ -512,12 +1160,17 @@ class BoolOp(expr): - __slots__ = ('op', 'values') + __slots__ = ('op', 'values', 'w_values') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, op, values, lineno, col_offset): self.op = op self.values = values + self.w_values = None expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_BoolOp(self) @@ -527,15 +1180,36 @@ visitor._mutate_sequence(self.values) return visitor.visit_BoolOp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['op', 'values', 'lineno', 'col_offset'], 'BoolOp') + else: + pass + w_list = self.w_values + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.values = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.values = None + if self.values is not None: + for node in self.values: + node.sync_app_attrs(space) + + class BinOp(expr): __slots__ = ('left', 'op', 'right') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, left, op, right, lineno, col_offset): self.left = left self.op = op self.right = right expr.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_BinOp(self) @@ -545,14 +1219,27 @@ self.right = self.right.mutate_over(visitor) return visitor.visit_BinOp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['left', 'op', 'right', 'lineno', 'col_offset'], 'BinOp') + else: + pass + self.left.sync_app_attrs(space) + self.right.sync_app_attrs(space) + + class UnaryOp(expr): __slots__ = ('op', 'operand') + _lineno_mask = 4 + _col_offset_mask = 8 + def __init__(self, op, operand, lineno, col_offset): self.op = op self.operand = operand expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_UnaryOp(self) @@ -561,14 +1248,26 @@ self.operand = self.operand.mutate_over(visitor) return visitor.visit_UnaryOp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['op', 'operand', 'lineno', 'col_offset'], 'UnaryOp') + else: + pass + self.operand.sync_app_attrs(space) + + class Lambda(expr): __slots__ = ('args', 'body') + _lineno_mask = 4 + _col_offset_mask = 8 + def __init__(self, args, body, lineno, col_offset): self.args = args self.body = body expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Lambda(self) @@ -577,15 +1276,28 @@ self.body = self.body.mutate_over(visitor) return visitor.visit_Lambda(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['args', 'body', 'lineno', 'col_offset'], 'Lambda') + else: + pass + self.args.sync_app_attrs(space) + self.body.sync_app_attrs(space) + + class IfExp(expr): __slots__ = ('test', 'body', 'orelse') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, test, body, orelse, lineno, col_offset): self.test = test self.body = body self.orelse = orelse expr.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_IfExp(self) @@ -596,14 +1308,30 @@ self.orelse = self.orelse.mutate_over(visitor) return visitor.visit_IfExp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'IfExp') + else: + pass + self.test.sync_app_attrs(space) + self.body.sync_app_attrs(space) + self.orelse.sync_app_attrs(space) + + class Dict(expr): - __slots__ = ('keys', 'values') + __slots__ = ('keys', 'w_keys', 'values', 'w_values') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, keys, values, lineno, col_offset): self.keys = keys + self.w_keys = None self.values = values + self.w_values = None expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Dict(self) @@ -615,14 +1343,46 @@ visitor._mutate_sequence(self.values) return visitor.visit_Dict(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['keys', 'values', 'lineno', 'col_offset'], 'Dict') + else: + pass + w_list = self.w_keys + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.keys = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.keys = None + if self.keys is not None: + for node in self.keys: + node.sync_app_attrs(space) + w_list = self.w_values + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.values = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.values = None + if self.values is not None: + for node in self.values: + node.sync_app_attrs(space) + + class ListComp(expr): - __slots__ = ('elt', 'generators') + __slots__ = ('elt', 'generators', 'w_generators') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, elt, generators, lineno, col_offset): self.elt = elt self.generators = generators + self.w_generators = None expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_ListComp(self) @@ -631,14 +1391,37 @@ self.elt = self.elt.mutate_over(visitor) return visitor.visit_ListComp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'ListComp') + else: + pass + self.elt.sync_app_attrs(space) + w_list = self.w_generators + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.generators = [space.interp_w(comprehension, w_obj) for w_obj in list_w] + else: + self.generators = None + if self.generators is not None: + for node in self.generators: + node.sync_app_attrs(space) + + class GeneratorExp(expr): - __slots__ = ('elt', 'generators') + __slots__ = ('elt', 'generators', 'w_generators') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, elt, generators, lineno, col_offset): self.elt = elt self.generators = generators + self.w_generators = None expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_GeneratorExp(self) @@ -647,13 +1430,35 @@ self.elt = self.elt.mutate_over(visitor) return visitor.visit_GeneratorExp(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'GeneratorExp') + else: + pass + self.elt.sync_app_attrs(space) + w_list = self.w_generators + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.generators = [space.interp_w(comprehension, w_obj) for w_obj in list_w] + else: + self.generators = None + if self.generators is not None: + for node in self.generators: + node.sync_app_attrs(space) + + class Yield(expr): __slots__ = ('value') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, value, lineno, col_offset): self.value = value expr.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Yield(self) @@ -663,15 +1468,30 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Yield(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~1) ^ 6: + missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Yield') + else: + if not self.initialization_state & 1: + self.value = None + self.value.sync_app_attrs(space) + + class Compare(expr): - __slots__ = ('left', 'ops', 'comparators') + __slots__ = ('left', 'ops', 'w_ops', 'comparators', 'w_comparators') + + _lineno_mask = 8 + _col_offset_mask = 16 def __init__(self, left, ops, comparators, lineno, col_offset): self.left = left self.ops = ops + self.w_ops = None self.comparators = comparators + self.w_comparators = None expr.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Compare(self) @@ -682,17 +1502,48 @@ visitor._mutate_sequence(self.comparators) return visitor.visit_Compare(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['left', 'ops', 'comparators', 'lineno', 'col_offset'], 'Compare') + else: + pass + self.left.sync_app_attrs(space) + w_list = self.w_ops + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.ops = [w_obj.to_simple_int() for w_obj in list_w] + else: + self.ops = None + w_list = self.w_comparators + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.comparators = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.comparators = None + if self.comparators is not None: + for node in self.comparators: + node.sync_app_attrs(space) + + class Call(expr): - __slots__ = ('func', 'args', 'keywords', 'starargs', 'kwargs') + __slots__ = ('func', 'args', 'w_args', 'keywords', 'w_keywords', 'starargs', 'kwargs') + + _lineno_mask = 32 + _col_offset_mask = 64 def __init__(self, func, args, keywords, starargs, kwargs, lineno, col_offset): self.func = func self.args = args + self.w_args = None self.keywords = keywords + self.w_keywords = None self.starargs = starargs self.kwargs = kwargs expr.__init__(self, lineno, col_offset) + self.initialization_state = 127 def walkabout(self, visitor): visitor.visit_Call(self) @@ -707,13 +1558,50 @@ self.kwargs = self.kwargs.mutate_over(visitor) return visitor.visit_Call(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~24) ^ 103: + missing_field(space, self.initialization_state, ['func', 'args', 'keywords', None, None, 'lineno', 'col_offset'], 'Call') + else: + if not self.initialization_state & 8: + self.starargs = None + if not self.initialization_state & 16: + self.kwargs = None + self.func.sync_app_attrs(space) + w_list = self.w_args + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.args = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.args = None + if self.args is not None: + for node in self.args: + node.sync_app_attrs(space) + w_list = self.w_keywords + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.keywords = [space.interp_w(keyword, w_obj) for w_obj in list_w] + else: + self.keywords = None + if self.keywords is not None: + for node in self.keywords: + node.sync_app_attrs(space) + self.starargs.sync_app_attrs(space) + self.kwargs.sync_app_attrs(space) + + class Repr(expr): __slots__ = ('value') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, value, lineno, col_offset): self.value = value expr.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Repr(self) @@ -722,13 +1610,25 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Repr(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Repr') + else: + pass + self.value.sync_app_attrs(space) + + class Num(expr): __slots__ = ('n') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, n, lineno, col_offset): self.n = n expr.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Num(self) @@ -736,13 +1636,24 @@ def mutate_over(self, visitor): return visitor.visit_Num(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['n', 'lineno', 'col_offset'], 'Num') + else: + pass + + class Str(expr): __slots__ = ('s') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, s, lineno, col_offset): self.s = s expr.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Str(self) @@ -750,15 +1661,26 @@ def mutate_over(self, visitor): return visitor.visit_Str(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['s', 'lineno', 'col_offset'], 'Str') + else: + pass + + class Attribute(expr): __slots__ = ('value', 'attr', 'ctx') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, value, attr, ctx, lineno, col_offset): self.value = value self.attr = attr self.ctx = ctx expr.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Attribute(self) @@ -767,15 +1689,27 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Attribute(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['value', 'attr', 'ctx', 'lineno', 'col_offset'], 'Attribute') + else: + pass + self.value.sync_app_attrs(space) + + class Subscript(expr): __slots__ = ('value', 'slice', 'ctx') + _lineno_mask = 8 + _col_offset_mask = 16 + def __init__(self, value, slice, ctx, lineno, col_offset): self.value = value self.slice = slice self.ctx = ctx expr.__init__(self, lineno, col_offset) + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_Subscript(self) @@ -785,14 +1719,27 @@ self.slice = self.slice.mutate_over(visitor) return visitor.visit_Subscript(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 31: + missing_field(space, self.initialization_state, ['value', 'slice', 'ctx', 'lineno', 'col_offset'], 'Subscript') + else: + pass + self.value.sync_app_attrs(space) + self.slice.sync_app_attrs(space) + + class Name(expr): __slots__ = ('id', 'ctx') + _lineno_mask = 4 + _col_offset_mask = 8 + def __init__(self, id, ctx, lineno, col_offset): self.id = id self.ctx = ctx expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Name(self) @@ -800,14 +1747,26 @@ def mutate_over(self, visitor): return visitor.visit_Name(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['id', 'ctx', 'lineno', 'col_offset'], 'Name') + else: + pass + + class List(expr): - __slots__ = ('elts', 'ctx') + __slots__ = ('elts', 'w_elts', 'ctx') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, elts, ctx, lineno, col_offset): self.elts = elts + self.w_elts = None self.ctx = ctx expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_List(self) @@ -817,14 +1776,36 @@ visitor._mutate_sequence(self.elts) return visitor.visit_List(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'List') + else: + pass + w_list = self.w_elts + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.elts = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.elts = None + if self.elts is not None: + for node in self.elts: + node.sync_app_attrs(space) + + class Tuple(expr): - __slots__ = ('elts', 'ctx') + __slots__ = ('elts', 'w_elts', 'ctx') + + _lineno_mask = 4 + _col_offset_mask = 8 def __init__(self, elts, ctx, lineno, col_offset): self.elts = elts + self.w_elts = None self.ctx = ctx expr.__init__(self, lineno, col_offset) + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_Tuple(self) @@ -834,13 +1815,34 @@ visitor._mutate_sequence(self.elts) return visitor.visit_Tuple(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 15: + missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'Tuple') + else: + pass + w_list = self.w_elts + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.elts = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.elts = None + if self.elts is not None: + for node in self.elts: + node.sync_app_attrs(space) + + class Const(expr): __slots__ = ('value') + _lineno_mask = 2 + _col_offset_mask = 4 + def __init__(self, value, lineno, col_offset): self.value = value expr.__init__(self, lineno, col_offset) + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Const(self) @@ -848,6 +1850,49 @@ def mutate_over(self, visitor): return visitor.visit_Const(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Const') + else: + pass + + +class expr_context(AST): + + def to_simple_int(self, space): + w_msg = space.wrap("not a valid expr_context") + raise OperationError(space.w_TypeError, w_msg) + +class _Load(expr_context): + + def to_simple_int(self): + return 1 + +class _Store(expr_context): + + def to_simple_int(self): + return 2 + +class _Del(expr_context): + + def to_simple_int(self): + return 3 + +class _AugLoad(expr_context): + + def to_simple_int(self): + return 4 + +class _AugStore(expr_context): + + def to_simple_int(self): + return 5 + +class _Param(expr_context): + + def to_simple_int(self): + return 6 + Load = 1 Store = 2 Del = 3 @@ -855,6 +1900,15 @@ AugStore = 5 Param = 6 +expr_context_to_class = [ + _Load, + _Store, + _Del, + _AugLoad, + _AugStore, + _Param, +] + class slice(AST): __slots__ = () @@ -863,8 +1917,9 @@ __slots__ = () + def __init__(self): - pass + self.initialization_state = 0 def walkabout(self, visitor): visitor.visit_Ellipsis(self) @@ -872,14 +1927,23 @@ def mutate_over(self, visitor): return visitor.visit_Ellipsis(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 0: + missing_field(space, self.initialization_state, [], 'Ellipsis') + else: + pass + + class Slice(slice): __slots__ = ('lower', 'upper', 'step') + def __init__(self, lower, upper, step): self.lower = lower self.upper = upper self.step = step + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_Slice(self) @@ -893,12 +1957,30 @@ self.step = self.step.mutate_over(visitor) return visitor.visit_Slice(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~7) ^ 0: + missing_field(space, self.initialization_state, [None, None, None], 'Slice') + else: + if not self.initialization_state & 1: + self.lower = None + if not self.initialization_state & 2: + self.upper = None + if not self.initialization_state & 4: + self.step = None + self.lower.sync_app_attrs(space) + self.upper.sync_app_attrs(space) + self.step.sync_app_attrs(space) + + class ExtSlice(slice): - __slots__ = ('dims') + __slots__ = ('dims', 'w_dims') + def __init__(self, dims): self.dims = dims + self.w_dims = None + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_ExtSlice(self) @@ -908,12 +1990,31 @@ visitor._mutate_sequence(self.dims) return visitor.visit_ExtSlice(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['dims'], 'ExtSlice') + else: + pass + w_list = self.w_dims + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.dims = [space.interp_w(slice, w_obj) for w_obj in list_w] + else: + self.dims = None + if self.dims is not None: + for node in self.dims: + node.sync_app_attrs(space) + + class Index(slice): __slots__ = ('value') + def __init__(self, value): self.value = value + self.initialization_state = 1 def walkabout(self, visitor): visitor.visit_Index(self) @@ -922,9 +2023,104 @@ self.value = self.value.mutate_over(visitor) return visitor.visit_Index(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 1: + missing_field(space, self.initialization_state, ['value'], 'Index') + else: + pass + self.value.sync_app_attrs(space) + + +class boolop(AST): + + def to_simple_int(self, space): + w_msg = space.wrap("not a valid boolop") + raise OperationError(space.w_TypeError, w_msg) + +class _And(boolop): + + def to_simple_int(self): + return 1 + +class _Or(boolop): + + def to_simple_int(self): + return 2 + And = 1 Or = 2 +boolop_to_class = [ + _And, + _Or, +] + +class operator(AST): + + def to_simple_int(self, space): + w_msg = space.wrap("not a valid operator") + raise OperationError(space.w_TypeError, w_msg) + +class _Add(operator): + + def to_simple_int(self): + return 1 + +class _Sub(operator): + + def to_simple_int(self): + return 2 + +class _Mult(operator): + + def to_simple_int(self): + return 3 + +class _Div(operator): + + def to_simple_int(self): + return 4 + +class _Mod(operator): + + def to_simple_int(self): + return 5 + +class _Pow(operator): + + def to_simple_int(self): + return 6 + +class _LShift(operator): + + def to_simple_int(self): + return 7 + +class _RShift(operator): + + def to_simple_int(self): + return 8 + +class _BitOr(operator): + + def to_simple_int(self): + return 9 + +class _BitXor(operator): + + def to_simple_int(self): + return 10 + +class _BitAnd(operator): + + def to_simple_int(self): + return 11 + +class _FloorDiv(operator): + + def to_simple_int(self): + return 12 + Add = 1 Sub = 2 Mult = 3 @@ -938,11 +2134,115 @@ BitAnd = 11 FloorDiv = 12 +operator_to_class = [ + _Add, + _Sub, + _Mult, + _Div, + _Mod, + _Pow, + _LShift, + _RShift, + _BitOr, + _BitXor, + _BitAnd, + _FloorDiv, +] + +class unaryop(AST): + + def to_simple_int(self, space): + w_msg = space.wrap("not a valid unaryop") + raise OperationError(space.w_TypeError, w_msg) + +class _Invert(unaryop): + + def to_simple_int(self): + return 1 + +class _Not(unaryop): + + def to_simple_int(self): + return 2 + +class _UAdd(unaryop): + + def to_simple_int(self): + return 3 + +class _USub(unaryop): + + def to_simple_int(self): + return 4 + Invert = 1 Not = 2 UAdd = 3 USub = 4 +unaryop_to_class = [ + _Invert, + _Not, + _UAdd, + _USub, +] + +class cmpop(AST): + + def to_simple_int(self, space): + w_msg = space.wrap("not a valid cmpop") + raise OperationError(space.w_TypeError, w_msg) + +class _Eq(cmpop): + + def to_simple_int(self): + return 1 + +class _NotEq(cmpop): + + def to_simple_int(self): + return 2 + +class _Lt(cmpop): + + def to_simple_int(self): + return 3 + +class _LtE(cmpop): + + def to_simple_int(self): + return 4 + +class _Gt(cmpop): + + def to_simple_int(self): + return 5 + +class _GtE(cmpop): + + def to_simple_int(self): + return 6 + +class _Is(cmpop): + + def to_simple_int(self): + return 7 + +class _IsNot(cmpop): + + def to_simple_int(self): + return 8 + +class _In(cmpop): + + def to_simple_int(self): + return 9 + +class _NotIn(cmpop): + + def to_simple_int(self): + return 10 + Eq = 1 NotEq = 2 Lt = 3 @@ -954,45 +2254,133 @@ In = 9 NotIn = 10 +cmpop_to_class = [ + _Eq, + _NotEq, + _Lt, + _LtE, + _Gt, + _GtE, + _Is, + _IsNot, + _In, + _NotIn, +] + class comprehension(AST): - __slots__ = ('target', 'iter', 'ifs') + __slots__ = ('target', 'iter', 'ifs', 'w_ifs') def __init__(self, target, iter, ifs): self.target = target self.iter = iter self.ifs = ifs + self.w_ifs = None + self.initialization_state = 7 def walkabout(self, visitor): visitor.visit_comprehension(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 7: + missing_field(space, self.initialization_state, ['target', 'iter', 'ifs'], 'comprehension') + else: + pass + self.target.sync_app_attrs(space) + self.iter.sync_app_attrs(space) + w_list = self.w_ifs + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.ifs = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.ifs = None + if self.ifs is not None: + for node in self.ifs: + node.sync_app_attrs(space) + class excepthandler(AST): - __slots__ = ('type', 'name', 'body', 'lineno', 'col_offset') + __slots__ = ('type', 'name', 'body', 'w_body', 'lineno', 'col_offset') def __init__(self, type, name, body, lineno, col_offset): self.type = type self.name = name self.body = body + self.w_body = None self.lineno = lineno self.col_offset = col_offset + self.initialization_state = 31 def walkabout(self, visitor): visitor.visit_excepthandler(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~3) ^ 28: + missing_field(space, self.initialization_state, [None, None, 'body', 'lineno', 'col_offset'], 'excepthandler') + else: + if not self.initialization_state & 1: + self.type = None + if not self.initialization_state & 2: + self.name = None + self.type.sync_app_attrs(space) + self.name.sync_app_attrs(space) + w_list = self.w_body + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.body = [space.interp_w(stmt, w_obj) for w_obj in list_w] + else: + self.body = None + if self.body is not None: + for node in self.body: + node.sync_app_attrs(space) + class arguments(AST): - __slots__ = ('args', 'vararg', 'kwarg', 'defaults') + __slots__ = ('args', 'w_args', 'vararg', 'kwarg', 'defaults', 'w_defaults') def __init__(self, args, vararg, kwarg, defaults): self.args = args + self.w_args = None self.vararg = vararg self.kwarg = kwarg self.defaults = defaults + self.w_defaults = None + self.initialization_state = 15 def walkabout(self, visitor): visitor.visit_arguments(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~6) ^ 9: + missing_field(space, self.initialization_state, ['args', None, None, 'defaults'], 'arguments') + else: + if not self.initialization_state & 2: + self.vararg = None + if not self.initialization_state & 4: + self.kwarg = None + w_list = self.w_args + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.args = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.args = None + if self.args is not None: + for node in self.args: + node.sync_app_attrs(space) + w_list = self.w_defaults + if w_list is not None: + list_w = space.viewiterable(w_list) + if list_w: + self.defaults = [space.interp_w(expr, w_obj) for w_obj in list_w] + else: + self.defaults = None + if self.defaults is not None: + for node in self.defaults: + node.sync_app_attrs(space) + class keyword(AST): __slots__ = ('arg', 'value') @@ -1000,10 +2388,18 @@ def __init__(self, arg, value): self.arg = arg self.value = value + self.initialization_state = 3 def walkabout(self, visitor): visitor.visit_keyword(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~0) ^ 3: + missing_field(space, self.initialization_state, ['arg', 'value'], 'keyword') + else: + pass + self.value.sync_app_attrs(space) + class alias(AST): __slots__ = ('name', 'asname') @@ -1011,10 +2407,18 @@ def __init__(self, name, asname): self.name = name self.asname = asname + self.initialization_state = 3 def walkabout(self, visitor): visitor.visit_alias(self) + def sync_app_attrs(self, space): + if (self.initialization_state & ~2) ^ 1: + missing_field(space, self.initialization_state, ['name', None], 'alias') + else: + if not self.initialization_state & 2: + self.asname = None + class ASTVisitor(object): def visit_sequence(self, seq): @@ -1411,3 +2815,3154 @@ pass +mod.typedef = typedef.TypeDef("mod", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +mod.typedef.acceptable_as_base_class = False + +def Module_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def Module_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 1 + +def Module_init(space, w_self, args): + w_self = space.descr_self_interp_w(Module, w_self) + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("Module constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Module_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Module.typedef = typedef.TypeDef("Module", + mod.typedef, + _fields=_FieldsWrapper(['body']), + body=typedef.GetSetProperty(Module_get_body, Module_set_body, cls=Module), + __new__=interp2app(get_AST_new(Module)), + __init__=interp2app(Module_init), +) +Module.typedef.acceptable_as_base_class = False + +def Interactive_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def Interactive_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 1 + +def Interactive_init(space, w_self, args): + w_self = space.descr_self_interp_w(Interactive, w_self) + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("Interactive constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Interactive_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Interactive.typedef = typedef.TypeDef("Interactive", + mod.typedef, + _fields=_FieldsWrapper(['body']), + body=typedef.GetSetProperty(Interactive_get_body, Interactive_set_body, cls=Interactive), + __new__=interp2app(get_AST_new(Interactive)), + __init__=interp2app(Interactive_init), +) +Interactive.typedef.acceptable_as_base_class = False + +def Expression_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.body) + +def Expression_set_body(space, w_self, w_new_value): + w_self.body = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Expression_init(space, w_self, args): + w_self = space.descr_self_interp_w(Expression, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("Expression constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Expression_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Expression.typedef = typedef.TypeDef("Expression", + mod.typedef, + _fields=_FieldsWrapper(['body']), + body=typedef.GetSetProperty(Expression_get_body, Expression_set_body, cls=Expression), + __new__=interp2app(get_AST_new(Expression)), + __init__=interp2app(Expression_init), +) +Expression.typedef.acceptable_as_base_class = False + +def Suite_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def Suite_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 1 + +def Suite_init(space, w_self, args): + w_self = space.descr_self_interp_w(Suite, w_self) + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("Suite constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Suite_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Suite.typedef = typedef.TypeDef("Suite", + mod.typedef, + _fields=_FieldsWrapper(['body']), + body=typedef.GetSetProperty(Suite_get_body, Suite_set_body, cls=Suite), + __new__=interp2app(get_AST_new(Suite)), + __init__=interp2app(Suite_init), +) +Suite.typedef.acceptable_as_base_class = False + +def stmt_get_lineno(space, w_self): + if not w_self.initialization_state & w_self._lineno_mask: + w_err = space.wrap("attribute 'lineno' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.lineno) + +def stmt_set_lineno(space, w_self, w_new_value): + w_self.lineno = space.int_w(w_new_value) + w_self.initialization_state |= w_self._lineno_mask + +def stmt_get_col_offset(space, w_self): + if not w_self.initialization_state & w_self._col_offset_mask: + w_err = space.wrap("attribute 'col_offset' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.col_offset) + +def stmt_set_col_offset(space, w_self, w_new_value): + w_self.col_offset = space.int_w(w_new_value) + w_self.initialization_state |= w_self._col_offset_mask + +stmt.typedef = typedef.TypeDef("stmt", + AST.typedef, + _attributes=_FieldsWrapper(['lineno', 'col_offset']), + lineno=typedef.GetSetProperty(stmt_get_lineno, stmt_set_lineno, cls=stmt), + col_offset=typedef.GetSetProperty(stmt_get_col_offset, stmt_set_col_offset, cls=stmt), +) +stmt.typedef.acceptable_as_base_class = False + +def FunctionDef_get_name(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'name' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.name) + +def FunctionDef_set_name(space, w_self, w_new_value): + w_self.name = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def FunctionDef_get_args(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'args' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.args) + +def FunctionDef_set_args(space, w_self, w_new_value): + w_self.args = space.interp_w(arguments, w_new_value, False) + w_self.initialization_state |= 2 + +def FunctionDef_get_body(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def FunctionDef_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 4 + +def FunctionDef_get_decorators(space, w_self): + if not w_self.initialization_state & 8: + w_err = space.wrap("attribute 'decorators' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_decorators is None: + if w_self.decorators is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.decorators] + w_list = space.newlist(list_w) + w_self.w_decorators = w_list + return w_self.w_decorators + +def FunctionDef_set_decorators(space, w_self, w_new_value): + w_self.w_decorators = w_new_value + w_self.initialization_state |= 8 + +def FunctionDef_init(space, w_self, args): + w_self = space.descr_self_interp_w(FunctionDef, w_self) + w_self.w_body = None + w_self.w_decorators = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 6: + w_err = space.wrap("FunctionDef constructor takes 0 or 6 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['name', 'args', 'body', 'decorators', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +FunctionDef_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +FunctionDef.typedef = typedef.TypeDef("FunctionDef", + stmt.typedef, + _fields=_FieldsWrapper(['name', 'args', 'body', 'decorators']), + name=typedef.GetSetProperty(FunctionDef_get_name, FunctionDef_set_name, cls=FunctionDef), + args=typedef.GetSetProperty(FunctionDef_get_args, FunctionDef_set_args, cls=FunctionDef), + body=typedef.GetSetProperty(FunctionDef_get_body, FunctionDef_set_body, cls=FunctionDef), + decorators=typedef.GetSetProperty(FunctionDef_get_decorators, FunctionDef_set_decorators, cls=FunctionDef), + __new__=interp2app(get_AST_new(FunctionDef)), + __init__=interp2app(FunctionDef_init), +) +FunctionDef.typedef.acceptable_as_base_class = False + +def ClassDef_get_name(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'name' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.name) + +def ClassDef_set_name(space, w_self, w_new_value): + w_self.name = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def ClassDef_get_bases(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'bases' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_bases is None: + if w_self.bases is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.bases] + w_list = space.newlist(list_w) + w_self.w_bases = w_list + return w_self.w_bases + +def ClassDef_set_bases(space, w_self, w_new_value): + w_self.w_bases = w_new_value + w_self.initialization_state |= 2 + +def ClassDef_get_body(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def ClassDef_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 4 + +def ClassDef_init(space, w_self, args): + w_self = space.descr_self_interp_w(ClassDef, w_self) + w_self.w_bases = None + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("ClassDef constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['name', 'bases', 'body', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +ClassDef_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +ClassDef.typedef = typedef.TypeDef("ClassDef", + stmt.typedef, + _fields=_FieldsWrapper(['name', 'bases', 'body']), + name=typedef.GetSetProperty(ClassDef_get_name, ClassDef_set_name, cls=ClassDef), + bases=typedef.GetSetProperty(ClassDef_get_bases, ClassDef_set_bases, cls=ClassDef), + body=typedef.GetSetProperty(ClassDef_get_body, ClassDef_set_body, cls=ClassDef), + __new__=interp2app(get_AST_new(ClassDef)), + __init__=interp2app(ClassDef_init), +) +ClassDef.typedef.acceptable_as_base_class = False + +def Return_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Return_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def Return_init(space, w_self, args): + w_self = space.descr_self_interp_w(Return, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Return constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Return_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Return.typedef = typedef.TypeDef("Return", + stmt.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Return_get_value, Return_set_value, cls=Return), + __new__=interp2app(get_AST_new(Return)), + __init__=interp2app(Return_init), +) +Return.typedef.acceptable_as_base_class = False + +def Delete_get_targets(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'targets' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_targets is None: + if w_self.targets is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.targets] + w_list = space.newlist(list_w) + w_self.w_targets = w_list + return w_self.w_targets + +def Delete_set_targets(space, w_self, w_new_value): + w_self.w_targets = w_new_value + w_self.initialization_state |= 1 + +def Delete_init(space, w_self, args): + w_self = space.descr_self_interp_w(Delete, w_self) + w_self.w_targets = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Delete constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['targets', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Delete_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Delete.typedef = typedef.TypeDef("Delete", + stmt.typedef, + _fields=_FieldsWrapper(['targets']), + targets=typedef.GetSetProperty(Delete_get_targets, Delete_set_targets, cls=Delete), + __new__=interp2app(get_AST_new(Delete)), + __init__=interp2app(Delete_init), +) +Delete.typedef.acceptable_as_base_class = False + +def Assign_get_targets(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'targets' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_targets is None: + if w_self.targets is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.targets] + w_list = space.newlist(list_w) + w_self.w_targets = w_list + return w_self.w_targets + +def Assign_set_targets(space, w_self, w_new_value): + w_self.w_targets = w_new_value + w_self.initialization_state |= 1 + +def Assign_get_value(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Assign_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def Assign_init(space, w_self, args): + w_self = space.descr_self_interp_w(Assign, w_self) + w_self.w_targets = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Assign constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['targets', 'value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Assign_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Assign.typedef = typedef.TypeDef("Assign", + stmt.typedef, + _fields=_FieldsWrapper(['targets', 'value']), + targets=typedef.GetSetProperty(Assign_get_targets, Assign_set_targets, cls=Assign), + value=typedef.GetSetProperty(Assign_get_value, Assign_set_value, cls=Assign), + __new__=interp2app(get_AST_new(Assign)), + __init__=interp2app(Assign_init), +) +Assign.typedef.acceptable_as_base_class = False + +def AugAssign_get_target(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'target' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.target) + +def AugAssign_set_target(space, w_self, w_new_value): + w_self.target = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def AugAssign_get_op(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'op' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return operator_to_class[w_self.op - 1]() + +def AugAssign_set_op(space, w_self, w_new_value): + obj = space.interp_w(operator, w_new_value) + w_self.op = obj.to_simple_int() + w_self.initialization_state |= 2 + +def AugAssign_get_value(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def AugAssign_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 4 + +def AugAssign_init(space, w_self, args): + w_self = space.descr_self_interp_w(AugAssign, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("AugAssign constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['target', 'op', 'value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +AugAssign_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +AugAssign.typedef = typedef.TypeDef("AugAssign", + stmt.typedef, + _fields=_FieldsWrapper(['target', 'op', 'value']), + target=typedef.GetSetProperty(AugAssign_get_target, AugAssign_set_target, cls=AugAssign), + op=typedef.GetSetProperty(AugAssign_get_op, AugAssign_set_op, cls=AugAssign), + value=typedef.GetSetProperty(AugAssign_get_value, AugAssign_set_value, cls=AugAssign), + __new__=interp2app(get_AST_new(AugAssign)), + __init__=interp2app(AugAssign_init), +) +AugAssign.typedef.acceptable_as_base_class = False + +def Print_get_dest(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'dest' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.dest) + +def Print_set_dest(space, w_self, w_new_value): + w_self.dest = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def Print_get_values(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'values' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_values is None: + if w_self.values is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.values] + w_list = space.newlist(list_w) + w_self.w_values = w_list + return w_self.w_values + +def Print_set_values(space, w_self, w_new_value): + w_self.w_values = w_new_value + w_self.initialization_state |= 2 + +def Print_get_nl(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'nl' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.nl) + +def Print_set_nl(space, w_self, w_new_value): + w_self.nl = space.bool_w(w_new_value) + w_self.initialization_state |= 4 + +def Print_init(space, w_self, args): + w_self = space.descr_self_interp_w(Print, w_self) + w_self.w_values = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Print constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['dest', 'values', 'nl', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Print_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Print.typedef = typedef.TypeDef("Print", + stmt.typedef, + _fields=_FieldsWrapper(['dest', 'values', 'nl']), + dest=typedef.GetSetProperty(Print_get_dest, Print_set_dest, cls=Print), + values=typedef.GetSetProperty(Print_get_values, Print_set_values, cls=Print), + nl=typedef.GetSetProperty(Print_get_nl, Print_set_nl, cls=Print), + __new__=interp2app(get_AST_new(Print)), + __init__=interp2app(Print_init), +) +Print.typedef.acceptable_as_base_class = False + +def For_get_target(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'target' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.target) + +def For_set_target(space, w_self, w_new_value): + w_self.target = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def For_get_iter(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'iter' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.iter) + +def For_set_iter(space, w_self, w_new_value): + w_self.iter = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def For_get_body(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def For_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 4 + +def For_get_orelse(space, w_self): + if not w_self.initialization_state & 8: + w_err = space.wrap("attribute 'orelse' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_orelse is None: + if w_self.orelse is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.orelse] + w_list = space.newlist(list_w) + w_self.w_orelse = w_list + return w_self.w_orelse + +def For_set_orelse(space, w_self, w_new_value): + w_self.w_orelse = w_new_value + w_self.initialization_state |= 8 + +def For_init(space, w_self, args): + w_self = space.descr_self_interp_w(For, w_self) + w_self.w_body = None + w_self.w_orelse = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 6: + w_err = space.wrap("For constructor takes 0 or 6 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +For_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +For.typedef = typedef.TypeDef("For", + stmt.typedef, + _fields=_FieldsWrapper(['target', 'iter', 'body', 'orelse']), + target=typedef.GetSetProperty(For_get_target, For_set_target, cls=For), + iter=typedef.GetSetProperty(For_get_iter, For_set_iter, cls=For), + body=typedef.GetSetProperty(For_get_body, For_set_body, cls=For), + orelse=typedef.GetSetProperty(For_get_orelse, For_set_orelse, cls=For), + __new__=interp2app(get_AST_new(For)), + __init__=interp2app(For_init), +) +For.typedef.acceptable_as_base_class = False + +def While_get_test(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'test' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.test) + +def While_set_test(space, w_self, w_new_value): + w_self.test = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def While_get_body(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def While_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 2 + +def While_get_orelse(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'orelse' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_orelse is None: + if w_self.orelse is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.orelse] + w_list = space.newlist(list_w) + w_self.w_orelse = w_list + return w_self.w_orelse + +def While_set_orelse(space, w_self, w_new_value): + w_self.w_orelse = w_new_value + w_self.initialization_state |= 4 + +def While_init(space, w_self, args): + w_self = space.descr_self_interp_w(While, w_self) + w_self.w_body = None + w_self.w_orelse = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("While constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +While_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +While.typedef = typedef.TypeDef("While", + stmt.typedef, + _fields=_FieldsWrapper(['test', 'body', 'orelse']), + test=typedef.GetSetProperty(While_get_test, While_set_test, cls=While), + body=typedef.GetSetProperty(While_get_body, While_set_body, cls=While), + orelse=typedef.GetSetProperty(While_get_orelse, While_set_orelse, cls=While), + __new__=interp2app(get_AST_new(While)), + __init__=interp2app(While_init), +) +While.typedef.acceptable_as_base_class = False + +def If_get_test(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'test' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.test) + +def If_set_test(space, w_self, w_new_value): + w_self.test = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def If_get_body(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def If_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 2 + +def If_get_orelse(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'orelse' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_orelse is None: + if w_self.orelse is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.orelse] + w_list = space.newlist(list_w) + w_self.w_orelse = w_list + return w_self.w_orelse + +def If_set_orelse(space, w_self, w_new_value): + w_self.w_orelse = w_new_value + w_self.initialization_state |= 4 + +def If_init(space, w_self, args): + w_self = space.descr_self_interp_w(If, w_self) + w_self.w_body = None + w_self.w_orelse = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("If constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +If_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +If.typedef = typedef.TypeDef("If", + stmt.typedef, + _fields=_FieldsWrapper(['test', 'body', 'orelse']), + test=typedef.GetSetProperty(If_get_test, If_set_test, cls=If), + body=typedef.GetSetProperty(If_get_body, If_set_body, cls=If), + orelse=typedef.GetSetProperty(If_get_orelse, If_set_orelse, cls=If), + __new__=interp2app(get_AST_new(If)), + __init__=interp2app(If_init), +) +If.typedef.acceptable_as_base_class = False + +def With_get_context_expr(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'context_expr' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.context_expr) + +def With_set_context_expr(space, w_self, w_new_value): + w_self.context_expr = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def With_get_optional_vars(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'optional_vars' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.optional_vars) + +def With_set_optional_vars(space, w_self, w_new_value): + w_self.optional_vars = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def With_get_body(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def With_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 4 + +def With_init(space, w_self, args): + w_self = space.descr_self_interp_w(With, w_self) + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("With constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['context_expr', 'optional_vars', 'body', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +With_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +With.typedef = typedef.TypeDef("With", + stmt.typedef, + _fields=_FieldsWrapper(['context_expr', 'optional_vars', 'body']), + context_expr=typedef.GetSetProperty(With_get_context_expr, With_set_context_expr, cls=With), + optional_vars=typedef.GetSetProperty(With_get_optional_vars, With_set_optional_vars, cls=With), + body=typedef.GetSetProperty(With_get_body, With_set_body, cls=With), + __new__=interp2app(get_AST_new(With)), + __init__=interp2app(With_init), +) +With.typedef.acceptable_as_base_class = False + +def Raise_get_type(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'type' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.type) + +def Raise_set_type(space, w_self, w_new_value): + w_self.type = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def Raise_get_inst(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'inst' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.inst) + +def Raise_set_inst(space, w_self, w_new_value): + w_self.inst = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def Raise_get_tback(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'tback' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.tback) + +def Raise_set_tback(space, w_self, w_new_value): + w_self.tback = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 4 + +def Raise_init(space, w_self, args): + w_self = space.descr_self_interp_w(Raise, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Raise constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['type', 'inst', 'tback', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Raise_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Raise.typedef = typedef.TypeDef("Raise", + stmt.typedef, + _fields=_FieldsWrapper(['type', 'inst', 'tback']), + type=typedef.GetSetProperty(Raise_get_type, Raise_set_type, cls=Raise), + inst=typedef.GetSetProperty(Raise_get_inst, Raise_set_inst, cls=Raise), + tback=typedef.GetSetProperty(Raise_get_tback, Raise_set_tback, cls=Raise), + __new__=interp2app(get_AST_new(Raise)), + __init__=interp2app(Raise_init), +) +Raise.typedef.acceptable_as_base_class = False + +def TryExcept_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def TryExcept_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 1 + +def TryExcept_get_handlers(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'handlers' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_handlers is None: + if w_self.handlers is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.handlers] + w_list = space.newlist(list_w) + w_self.w_handlers = w_list + return w_self.w_handlers + +def TryExcept_set_handlers(space, w_self, w_new_value): + w_self.w_handlers = w_new_value + w_self.initialization_state |= 2 + +def TryExcept_get_orelse(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'orelse' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_orelse is None: + if w_self.orelse is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.orelse] + w_list = space.newlist(list_w) + w_self.w_orelse = w_list + return w_self.w_orelse + +def TryExcept_set_orelse(space, w_self, w_new_value): + w_self.w_orelse = w_new_value + w_self.initialization_state |= 4 + +def TryExcept_init(space, w_self, args): + w_self = space.descr_self_interp_w(TryExcept, w_self) + w_self.w_body = None + w_self.w_handlers = None + w_self.w_orelse = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("TryExcept constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body', 'handlers', 'orelse', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +TryExcept_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +TryExcept.typedef = typedef.TypeDef("TryExcept", + stmt.typedef, + _fields=_FieldsWrapper(['body', 'handlers', 'orelse']), + body=typedef.GetSetProperty(TryExcept_get_body, TryExcept_set_body, cls=TryExcept), + handlers=typedef.GetSetProperty(TryExcept_get_handlers, TryExcept_set_handlers, cls=TryExcept), + orelse=typedef.GetSetProperty(TryExcept_get_orelse, TryExcept_set_orelse, cls=TryExcept), + __new__=interp2app(get_AST_new(TryExcept)), + __init__=interp2app(TryExcept_init), +) +TryExcept.typedef.acceptable_as_base_class = False + +def TryFinally_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def TryFinally_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 1 + +def TryFinally_get_finalbody(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'finalbody' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_finalbody is None: + if w_self.finalbody is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.finalbody] + w_list = space.newlist(list_w) + w_self.w_finalbody = w_list + return w_self.w_finalbody + +def TryFinally_set_finalbody(space, w_self, w_new_value): + w_self.w_finalbody = w_new_value + w_self.initialization_state |= 2 + +def TryFinally_init(space, w_self, args): + w_self = space.descr_self_interp_w(TryFinally, w_self) + w_self.w_body = None + w_self.w_finalbody = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("TryFinally constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body', 'finalbody', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +TryFinally_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +TryFinally.typedef = typedef.TypeDef("TryFinally", + stmt.typedef, + _fields=_FieldsWrapper(['body', 'finalbody']), + body=typedef.GetSetProperty(TryFinally_get_body, TryFinally_set_body, cls=TryFinally), + finalbody=typedef.GetSetProperty(TryFinally_get_finalbody, TryFinally_set_finalbody, cls=TryFinally), + __new__=interp2app(get_AST_new(TryFinally)), + __init__=interp2app(TryFinally_init), +) +TryFinally.typedef.acceptable_as_base_class = False + +def Assert_get_test(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'test' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.test) + +def Assert_set_test(space, w_self, w_new_value): + w_self.test = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Assert_get_msg(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'msg' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.msg) + +def Assert_set_msg(space, w_self, w_new_value): + w_self.msg = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def Assert_init(space, w_self, args): + w_self = space.descr_self_interp_w(Assert, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Assert constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['test', 'msg', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Assert_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Assert.typedef = typedef.TypeDef("Assert", + stmt.typedef, + _fields=_FieldsWrapper(['test', 'msg']), + test=typedef.GetSetProperty(Assert_get_test, Assert_set_test, cls=Assert), + msg=typedef.GetSetProperty(Assert_get_msg, Assert_set_msg, cls=Assert), + __new__=interp2app(get_AST_new(Assert)), + __init__=interp2app(Assert_init), +) +Assert.typedef.acceptable_as_base_class = False + +def Import_get_names(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'names' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_names is None: + if w_self.names is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.names] + w_list = space.newlist(list_w) + w_self.w_names = w_list + return w_self.w_names + +def Import_set_names(space, w_self, w_new_value): + w_self.w_names = w_new_value + w_self.initialization_state |= 1 + +def Import_init(space, w_self, args): + w_self = space.descr_self_interp_w(Import, w_self) + w_self.w_names = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Import constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['names', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Import_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Import.typedef = typedef.TypeDef("Import", + stmt.typedef, + _fields=_FieldsWrapper(['names']), + names=typedef.GetSetProperty(Import_get_names, Import_set_names, cls=Import), + __new__=interp2app(get_AST_new(Import)), + __init__=interp2app(Import_init), +) +Import.typedef.acceptable_as_base_class = False + +def ImportFrom_get_module(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'module' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.module) + +def ImportFrom_set_module(space, w_self, w_new_value): + if space.is_w(w_new_value, space.w_None): + w_self.module = None + else: + w_self.module = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def ImportFrom_get_names(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'names' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_names is None: + if w_self.names is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.names] + w_list = space.newlist(list_w) + w_self.w_names = w_list + return w_self.w_names + +def ImportFrom_set_names(space, w_self, w_new_value): + w_self.w_names = w_new_value + w_self.initialization_state |= 2 + +def ImportFrom_get_level(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'level' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.level) + +def ImportFrom_set_level(space, w_self, w_new_value): + if space.is_w(w_new_value, space.w_None): + w_self.level = None + else: + w_self.level = space.int_w(w_new_value) + w_self.initialization_state |= 4 + +def ImportFrom_init(space, w_self, args): + w_self = space.descr_self_interp_w(ImportFrom, w_self) + w_self.w_names = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("ImportFrom constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['module', 'names', 'level', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +ImportFrom_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +ImportFrom.typedef = typedef.TypeDef("ImportFrom", + stmt.typedef, + _fields=_FieldsWrapper(['module', 'names', 'level']), + module=typedef.GetSetProperty(ImportFrom_get_module, ImportFrom_set_module, cls=ImportFrom), + names=typedef.GetSetProperty(ImportFrom_get_names, ImportFrom_set_names, cls=ImportFrom), + level=typedef.GetSetProperty(ImportFrom_get_level, ImportFrom_set_level, cls=ImportFrom), + __new__=interp2app(get_AST_new(ImportFrom)), + __init__=interp2app(ImportFrom_init), +) +ImportFrom.typedef.acceptable_as_base_class = False + +def Exec_get_body(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.body) + +def Exec_set_body(space, w_self, w_new_value): + w_self.body = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Exec_get_globals(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'globals' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.globals) + +def Exec_set_globals(space, w_self, w_new_value): + w_self.globals = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def Exec_get_locals(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'locals' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.locals) + +def Exec_set_locals(space, w_self, w_new_value): + w_self.locals = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 4 + +def Exec_init(space, w_self, args): + w_self = space.descr_self_interp_w(Exec, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Exec constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['body', 'globals', 'locals', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Exec_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Exec.typedef = typedef.TypeDef("Exec", + stmt.typedef, + _fields=_FieldsWrapper(['body', 'globals', 'locals']), + body=typedef.GetSetProperty(Exec_get_body, Exec_set_body, cls=Exec), + globals=typedef.GetSetProperty(Exec_get_globals, Exec_set_globals, cls=Exec), + locals=typedef.GetSetProperty(Exec_get_locals, Exec_set_locals, cls=Exec), + __new__=interp2app(get_AST_new(Exec)), + __init__=interp2app(Exec_init), +) +Exec.typedef.acceptable_as_base_class = False + +def Global_get_names(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'names' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_names is None: + if w_self.names is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.names] + w_list = space.newlist(list_w) + w_self.w_names = w_list + return w_self.w_names + +def Global_set_names(space, w_self, w_new_value): + w_self.w_names = w_new_value + w_self.initialization_state |= 1 + +def Global_init(space, w_self, args): + w_self = space.descr_self_interp_w(Global, w_self) + w_self.w_names = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Global constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['names', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Global_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Global.typedef = typedef.TypeDef("Global", + stmt.typedef, + _fields=_FieldsWrapper(['names']), + names=typedef.GetSetProperty(Global_get_names, Global_set_names, cls=Global), + __new__=interp2app(get_AST_new(Global)), + __init__=interp2app(Global_init), +) +Global.typedef.acceptable_as_base_class = False + +def Expr_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Expr_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Expr_init(space, w_self, args): + w_self = space.descr_self_interp_w(Expr, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Expr constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Expr_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Expr.typedef = typedef.TypeDef("Expr", + stmt.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Expr_get_value, Expr_set_value, cls=Expr), + __new__=interp2app(get_AST_new(Expr)), + __init__=interp2app(Expr_init), +) +Expr.typedef.acceptable_as_base_class = False + +def Pass_init(space, w_self, args): + w_self = space.descr_self_interp_w(Pass, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 2: + w_err = space.wrap("Pass constructor takes 0 or 2 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Pass_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Pass.typedef = typedef.TypeDef("Pass", + stmt.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(Pass)), + __init__=interp2app(Pass_init), +) +Pass.typedef.acceptable_as_base_class = False + +def Break_init(space, w_self, args): + w_self = space.descr_self_interp_w(Break, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 2: + w_err = space.wrap("Break constructor takes 0 or 2 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Break_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Break.typedef = typedef.TypeDef("Break", + stmt.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(Break)), + __init__=interp2app(Break_init), +) +Break.typedef.acceptable_as_base_class = False + +def Continue_init(space, w_self, args): + w_self = space.descr_self_interp_w(Continue, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 2: + w_err = space.wrap("Continue constructor takes 0 or 2 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Continue_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Continue.typedef = typedef.TypeDef("Continue", + stmt.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(Continue)), + __init__=interp2app(Continue_init), +) +Continue.typedef.acceptable_as_base_class = False + +def expr_get_lineno(space, w_self): + if not w_self.initialization_state & w_self._lineno_mask: + w_err = space.wrap("attribute 'lineno' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.lineno) + +def expr_set_lineno(space, w_self, w_new_value): + w_self.lineno = space.int_w(w_new_value) + w_self.initialization_state |= w_self._lineno_mask + +def expr_get_col_offset(space, w_self): + if not w_self.initialization_state & w_self._col_offset_mask: + w_err = space.wrap("attribute 'col_offset' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.col_offset) + +def expr_set_col_offset(space, w_self, w_new_value): + w_self.col_offset = space.int_w(w_new_value) + w_self.initialization_state |= w_self._col_offset_mask + +expr.typedef = typedef.TypeDef("expr", + AST.typedef, + _attributes=_FieldsWrapper(['lineno', 'col_offset']), + lineno=typedef.GetSetProperty(expr_get_lineno, expr_set_lineno, cls=expr), + col_offset=typedef.GetSetProperty(expr_get_col_offset, expr_set_col_offset, cls=expr), +) +expr.typedef.acceptable_as_base_class = False + +def BoolOp_get_op(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'op' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return boolop_to_class[w_self.op - 1]() + +def BoolOp_set_op(space, w_self, w_new_value): + obj = space.interp_w(boolop, w_new_value) + w_self.op = obj.to_simple_int() + w_self.initialization_state |= 1 + +def BoolOp_get_values(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'values' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_values is None: + if w_self.values is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.values] + w_list = space.newlist(list_w) + w_self.w_values = w_list + return w_self.w_values + +def BoolOp_set_values(space, w_self, w_new_value): + w_self.w_values = w_new_value + w_self.initialization_state |= 2 + +def BoolOp_init(space, w_self, args): + w_self = space.descr_self_interp_w(BoolOp, w_self) + w_self.w_values = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("BoolOp constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['op', 'values', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +BoolOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +BoolOp.typedef = typedef.TypeDef("BoolOp", + expr.typedef, + _fields=_FieldsWrapper(['op', 'values']), + op=typedef.GetSetProperty(BoolOp_get_op, BoolOp_set_op, cls=BoolOp), + values=typedef.GetSetProperty(BoolOp_get_values, BoolOp_set_values, cls=BoolOp), + __new__=interp2app(get_AST_new(BoolOp)), + __init__=interp2app(BoolOp_init), +) +BoolOp.typedef.acceptable_as_base_class = False + +def BinOp_get_left(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'left' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.left) + +def BinOp_set_left(space, w_self, w_new_value): + w_self.left = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def BinOp_get_op(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'op' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return operator_to_class[w_self.op - 1]() + +def BinOp_set_op(space, w_self, w_new_value): + obj = space.interp_w(operator, w_new_value) + w_self.op = obj.to_simple_int() + w_self.initialization_state |= 2 + +def BinOp_get_right(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'right' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.right) + +def BinOp_set_right(space, w_self, w_new_value): + w_self.right = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 4 + +def BinOp_init(space, w_self, args): + w_self = space.descr_self_interp_w(BinOp, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("BinOp constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['left', 'op', 'right', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +BinOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +BinOp.typedef = typedef.TypeDef("BinOp", + expr.typedef, + _fields=_FieldsWrapper(['left', 'op', 'right']), + left=typedef.GetSetProperty(BinOp_get_left, BinOp_set_left, cls=BinOp), + op=typedef.GetSetProperty(BinOp_get_op, BinOp_set_op, cls=BinOp), + right=typedef.GetSetProperty(BinOp_get_right, BinOp_set_right, cls=BinOp), + __new__=interp2app(get_AST_new(BinOp)), + __init__=interp2app(BinOp_init), +) +BinOp.typedef.acceptable_as_base_class = False + +def UnaryOp_get_op(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'op' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return unaryop_to_class[w_self.op - 1]() + +def UnaryOp_set_op(space, w_self, w_new_value): + obj = space.interp_w(unaryop, w_new_value) + w_self.op = obj.to_simple_int() + w_self.initialization_state |= 1 + +def UnaryOp_get_operand(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'operand' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.operand) + +def UnaryOp_set_operand(space, w_self, w_new_value): + w_self.operand = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def UnaryOp_init(space, w_self, args): + w_self = space.descr_self_interp_w(UnaryOp, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("UnaryOp constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['op', 'operand', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +UnaryOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +UnaryOp.typedef = typedef.TypeDef("UnaryOp", + expr.typedef, + _fields=_FieldsWrapper(['op', 'operand']), + op=typedef.GetSetProperty(UnaryOp_get_op, UnaryOp_set_op, cls=UnaryOp), + operand=typedef.GetSetProperty(UnaryOp_get_operand, UnaryOp_set_operand, cls=UnaryOp), + __new__=interp2app(get_AST_new(UnaryOp)), + __init__=interp2app(UnaryOp_init), +) +UnaryOp.typedef.acceptable_as_base_class = False + +def Lambda_get_args(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'args' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.args) + +def Lambda_set_args(space, w_self, w_new_value): + w_self.args = space.interp_w(arguments, w_new_value, False) + w_self.initialization_state |= 1 + +def Lambda_get_body(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.body) + +def Lambda_set_body(space, w_self, w_new_value): + w_self.body = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def Lambda_init(space, w_self, args): + w_self = space.descr_self_interp_w(Lambda, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Lambda constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['args', 'body', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Lambda_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Lambda.typedef = typedef.TypeDef("Lambda", + expr.typedef, + _fields=_FieldsWrapper(['args', 'body']), + args=typedef.GetSetProperty(Lambda_get_args, Lambda_set_args, cls=Lambda), + body=typedef.GetSetProperty(Lambda_get_body, Lambda_set_body, cls=Lambda), + __new__=interp2app(get_AST_new(Lambda)), + __init__=interp2app(Lambda_init), +) +Lambda.typedef.acceptable_as_base_class = False + +def IfExp_get_test(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'test' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.test) + +def IfExp_set_test(space, w_self, w_new_value): + w_self.test = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def IfExp_get_body(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.body) + +def IfExp_set_body(space, w_self, w_new_value): + w_self.body = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def IfExp_get_orelse(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'orelse' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.orelse) + +def IfExp_set_orelse(space, w_self, w_new_value): + w_self.orelse = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 4 + +def IfExp_init(space, w_self, args): + w_self = space.descr_self_interp_w(IfExp, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("IfExp constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +IfExp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +IfExp.typedef = typedef.TypeDef("IfExp", + expr.typedef, + _fields=_FieldsWrapper(['test', 'body', 'orelse']), + test=typedef.GetSetProperty(IfExp_get_test, IfExp_set_test, cls=IfExp), + body=typedef.GetSetProperty(IfExp_get_body, IfExp_set_body, cls=IfExp), + orelse=typedef.GetSetProperty(IfExp_get_orelse, IfExp_set_orelse, cls=IfExp), + __new__=interp2app(get_AST_new(IfExp)), + __init__=interp2app(IfExp_init), +) +IfExp.typedef.acceptable_as_base_class = False + +def Dict_get_keys(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'keys' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_keys is None: + if w_self.keys is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.keys] + w_list = space.newlist(list_w) + w_self.w_keys = w_list + return w_self.w_keys + +def Dict_set_keys(space, w_self, w_new_value): + w_self.w_keys = w_new_value + w_self.initialization_state |= 1 + +def Dict_get_values(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'values' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_values is None: + if w_self.values is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.values] + w_list = space.newlist(list_w) + w_self.w_values = w_list + return w_self.w_values + +def Dict_set_values(space, w_self, w_new_value): + w_self.w_values = w_new_value + w_self.initialization_state |= 2 + +def Dict_init(space, w_self, args): + w_self = space.descr_self_interp_w(Dict, w_self) + w_self.w_keys = None + w_self.w_values = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Dict constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['keys', 'values', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Dict_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Dict.typedef = typedef.TypeDef("Dict", + expr.typedef, + _fields=_FieldsWrapper(['keys', 'values']), + keys=typedef.GetSetProperty(Dict_get_keys, Dict_set_keys, cls=Dict), + values=typedef.GetSetProperty(Dict_get_values, Dict_set_values, cls=Dict), + __new__=interp2app(get_AST_new(Dict)), + __init__=interp2app(Dict_init), +) +Dict.typedef.acceptable_as_base_class = False + +def ListComp_get_elt(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'elt' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.elt) + +def ListComp_set_elt(space, w_self, w_new_value): + w_self.elt = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def ListComp_get_generators(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'generators' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_generators is None: + if w_self.generators is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.generators] + w_list = space.newlist(list_w) + w_self.w_generators = w_list + return w_self.w_generators + +def ListComp_set_generators(space, w_self, w_new_value): + w_self.w_generators = w_new_value + w_self.initialization_state |= 2 + +def ListComp_init(space, w_self, args): + w_self = space.descr_self_interp_w(ListComp, w_self) + w_self.w_generators = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("ListComp constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['elt', 'generators', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +ListComp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +ListComp.typedef = typedef.TypeDef("ListComp", + expr.typedef, + _fields=_FieldsWrapper(['elt', 'generators']), + elt=typedef.GetSetProperty(ListComp_get_elt, ListComp_set_elt, cls=ListComp), + generators=typedef.GetSetProperty(ListComp_get_generators, ListComp_set_generators, cls=ListComp), + __new__=interp2app(get_AST_new(ListComp)), + __init__=interp2app(ListComp_init), +) +ListComp.typedef.acceptable_as_base_class = False + +def GeneratorExp_get_elt(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'elt' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.elt) + +def GeneratorExp_set_elt(space, w_self, w_new_value): + w_self.elt = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def GeneratorExp_get_generators(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'generators' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_generators is None: + if w_self.generators is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.generators] + w_list = space.newlist(list_w) + w_self.w_generators = w_list + return w_self.w_generators + +def GeneratorExp_set_generators(space, w_self, w_new_value): + w_self.w_generators = w_new_value + w_self.initialization_state |= 2 + +def GeneratorExp_init(space, w_self, args): + w_self = space.descr_self_interp_w(GeneratorExp, w_self) + w_self.w_generators = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("GeneratorExp constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['elt', 'generators', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +GeneratorExp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +GeneratorExp.typedef = typedef.TypeDef("GeneratorExp", + expr.typedef, + _fields=_FieldsWrapper(['elt', 'generators']), + elt=typedef.GetSetProperty(GeneratorExp_get_elt, GeneratorExp_set_elt, cls=GeneratorExp), + generators=typedef.GetSetProperty(GeneratorExp_get_generators, GeneratorExp_set_generators, cls=GeneratorExp), + __new__=interp2app(get_AST_new(GeneratorExp)), + __init__=interp2app(GeneratorExp_init), +) +GeneratorExp.typedef.acceptable_as_base_class = False + +def Yield_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Yield_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def Yield_init(space, w_self, args): + w_self = space.descr_self_interp_w(Yield, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Yield constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Yield_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Yield.typedef = typedef.TypeDef("Yield", + expr.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Yield_get_value, Yield_set_value, cls=Yield), + __new__=interp2app(get_AST_new(Yield)), + __init__=interp2app(Yield_init), +) +Yield.typedef.acceptable_as_base_class = False + +def Compare_get_left(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'left' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.left) + +def Compare_set_left(space, w_self, w_new_value): + w_self.left = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Compare_get_ops(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'ops' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_ops is None: + if w_self.ops is None: + w_list = space.newlist([]) + else: + list_w = [cmpop_to_class[node - 1]() for node in w_self.ops] + w_list = space.newlist(list_w) + w_self.w_ops = w_list + return w_self.w_ops + +def Compare_set_ops(space, w_self, w_new_value): + w_self.w_ops = w_new_value + w_self.initialization_state |= 2 + +def Compare_get_comparators(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'comparators' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_comparators is None: + if w_self.comparators is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.comparators] + w_list = space.newlist(list_w) + w_self.w_comparators = w_list + return w_self.w_comparators + +def Compare_set_comparators(space, w_self, w_new_value): + w_self.w_comparators = w_new_value + w_self.initialization_state |= 4 + +def Compare_init(space, w_self, args): + w_self = space.descr_self_interp_w(Compare, w_self) + w_self.w_ops = None + w_self.w_comparators = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Compare constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['left', 'ops', 'comparators', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Compare_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Compare.typedef = typedef.TypeDef("Compare", + expr.typedef, + _fields=_FieldsWrapper(['left', 'ops', 'comparators']), + left=typedef.GetSetProperty(Compare_get_left, Compare_set_left, cls=Compare), + ops=typedef.GetSetProperty(Compare_get_ops, Compare_set_ops, cls=Compare), + comparators=typedef.GetSetProperty(Compare_get_comparators, Compare_set_comparators, cls=Compare), + __new__=interp2app(get_AST_new(Compare)), + __init__=interp2app(Compare_init), +) +Compare.typedef.acceptable_as_base_class = False + +def Call_get_func(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'func' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.func) + +def Call_set_func(space, w_self, w_new_value): + w_self.func = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Call_get_args(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'args' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_args is None: + if w_self.args is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.args] + w_list = space.newlist(list_w) + w_self.w_args = w_list + return w_self.w_args + +def Call_set_args(space, w_self, w_new_value): + w_self.w_args = w_new_value + w_self.initialization_state |= 2 + +def Call_get_keywords(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'keywords' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_keywords is None: + if w_self.keywords is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.keywords] + w_list = space.newlist(list_w) + w_self.w_keywords = w_list + return w_self.w_keywords + +def Call_set_keywords(space, w_self, w_new_value): + w_self.w_keywords = w_new_value + w_self.initialization_state |= 4 + +def Call_get_starargs(space, w_self): + if not w_self.initialization_state & 8: + w_err = space.wrap("attribute 'starargs' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.starargs) + +def Call_set_starargs(space, w_self, w_new_value): + w_self.starargs = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 8 + +def Call_get_kwargs(space, w_self): + if not w_self.initialization_state & 16: + w_err = space.wrap("attribute 'kwargs' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.kwargs) + +def Call_set_kwargs(space, w_self, w_new_value): + w_self.kwargs = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 16 + +def Call_init(space, w_self, args): + w_self = space.descr_self_interp_w(Call, w_self) + w_self.w_args = None + w_self.w_keywords = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 7: + w_err = space.wrap("Call constructor takes 0 or 7 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['func', 'args', 'keywords', 'starargs', 'kwargs', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Call_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Call.typedef = typedef.TypeDef("Call", + expr.typedef, + _fields=_FieldsWrapper(['func', 'args', 'keywords', 'starargs', 'kwargs']), + func=typedef.GetSetProperty(Call_get_func, Call_set_func, cls=Call), + args=typedef.GetSetProperty(Call_get_args, Call_set_args, cls=Call), + keywords=typedef.GetSetProperty(Call_get_keywords, Call_set_keywords, cls=Call), + starargs=typedef.GetSetProperty(Call_get_starargs, Call_set_starargs, cls=Call), + kwargs=typedef.GetSetProperty(Call_get_kwargs, Call_set_kwargs, cls=Call), + __new__=interp2app(get_AST_new(Call)), + __init__=interp2app(Call_init), +) +Call.typedef.acceptable_as_base_class = False + +def Repr_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Repr_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Repr_init(space, w_self, args): + w_self = space.descr_self_interp_w(Repr, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Repr constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Repr_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Repr.typedef = typedef.TypeDef("Repr", + expr.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Repr_get_value, Repr_set_value, cls=Repr), + __new__=interp2app(get_AST_new(Repr)), + __init__=interp2app(Repr_init), +) +Repr.typedef.acceptable_as_base_class = False + +def Num_get_n(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'n' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return w_self.n + +def Num_set_n(space, w_self, w_new_value): + w_self.n = w_new_value + w_self.initialization_state |= 1 + +def Num_init(space, w_self, args): + w_self = space.descr_self_interp_w(Num, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Num constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['n', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Num_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Num.typedef = typedef.TypeDef("Num", + expr.typedef, + _fields=_FieldsWrapper(['n']), + n=typedef.GetSetProperty(Num_get_n, Num_set_n, cls=Num), + __new__=interp2app(get_AST_new(Num)), + __init__=interp2app(Num_init), +) +Num.typedef.acceptable_as_base_class = False + +def Str_get_s(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 's' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return w_self.s + +def Str_set_s(space, w_self, w_new_value): + if not space.is_true(space.isinstance(w_new_value, space.w_basestring)): + w_err = space.wrap("some kind of string required") + raise OperationError(space.w_TypeError, w_err) + w_self.s = w_new_value + w_self.initialization_state |= 1 + +def Str_init(space, w_self, args): + w_self = space.descr_self_interp_w(Str, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Str constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['s', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Str_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Str.typedef = typedef.TypeDef("Str", + expr.typedef, + _fields=_FieldsWrapper(['s']), + s=typedef.GetSetProperty(Str_get_s, Str_set_s, cls=Str), + __new__=interp2app(get_AST_new(Str)), + __init__=interp2app(Str_init), +) +Str.typedef.acceptable_as_base_class = False + +def Attribute_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Attribute_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Attribute_get_attr(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'attr' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.attr) + +def Attribute_set_attr(space, w_self, w_new_value): + w_self.attr = space.str_w(w_new_value) + w_self.initialization_state |= 2 + +def Attribute_get_ctx(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'ctx' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return expr_context_to_class[w_self.ctx - 1]() + +def Attribute_set_ctx(space, w_self, w_new_value): + obj = space.interp_w(expr_context, w_new_value) + w_self.ctx = obj.to_simple_int() + w_self.initialization_state |= 4 + +def Attribute_init(space, w_self, args): + w_self = space.descr_self_interp_w(Attribute, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Attribute constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'attr', 'ctx', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Attribute_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Attribute.typedef = typedef.TypeDef("Attribute", + expr.typedef, + _fields=_FieldsWrapper(['value', 'attr', 'ctx']), + value=typedef.GetSetProperty(Attribute_get_value, Attribute_set_value, cls=Attribute), + attr=typedef.GetSetProperty(Attribute_get_attr, Attribute_set_attr, cls=Attribute), + ctx=typedef.GetSetProperty(Attribute_get_ctx, Attribute_set_ctx, cls=Attribute), + __new__=interp2app(get_AST_new(Attribute)), + __init__=interp2app(Attribute_init), +) +Attribute.typedef.acceptable_as_base_class = False + +def Subscript_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Subscript_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Subscript_get_slice(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'slice' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.slice) + +def Subscript_set_slice(space, w_self, w_new_value): + w_self.slice = space.interp_w(slice, w_new_value, False) + w_self.initialization_state |= 2 + +def Subscript_get_ctx(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'ctx' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return expr_context_to_class[w_self.ctx - 1]() + +def Subscript_set_ctx(space, w_self, w_new_value): + obj = space.interp_w(expr_context, w_new_value) + w_self.ctx = obj.to_simple_int() + w_self.initialization_state |= 4 + +def Subscript_init(space, w_self, args): + w_self = space.descr_self_interp_w(Subscript, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("Subscript constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'slice', 'ctx', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Subscript_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Subscript.typedef = typedef.TypeDef("Subscript", + expr.typedef, + _fields=_FieldsWrapper(['value', 'slice', 'ctx']), + value=typedef.GetSetProperty(Subscript_get_value, Subscript_set_value, cls=Subscript), + slice=typedef.GetSetProperty(Subscript_get_slice, Subscript_set_slice, cls=Subscript), + ctx=typedef.GetSetProperty(Subscript_get_ctx, Subscript_set_ctx, cls=Subscript), + __new__=interp2app(get_AST_new(Subscript)), + __init__=interp2app(Subscript_init), +) +Subscript.typedef.acceptable_as_base_class = False + +def Name_get_id(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'id' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.id) + +def Name_set_id(space, w_self, w_new_value): + w_self.id = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def Name_get_ctx(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'ctx' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return expr_context_to_class[w_self.ctx - 1]() + +def Name_set_ctx(space, w_self, w_new_value): + obj = space.interp_w(expr_context, w_new_value) + w_self.ctx = obj.to_simple_int() + w_self.initialization_state |= 2 + +def Name_init(space, w_self, args): + w_self = space.descr_self_interp_w(Name, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Name constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['id', 'ctx', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Name_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Name.typedef = typedef.TypeDef("Name", + expr.typedef, + _fields=_FieldsWrapper(['id', 'ctx']), + id=typedef.GetSetProperty(Name_get_id, Name_set_id, cls=Name), + ctx=typedef.GetSetProperty(Name_get_ctx, Name_set_ctx, cls=Name), + __new__=interp2app(get_AST_new(Name)), + __init__=interp2app(Name_init), +) +Name.typedef.acceptable_as_base_class = False + +def List_get_elts(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'elts' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_elts is None: + if w_self.elts is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.elts] + w_list = space.newlist(list_w) + w_self.w_elts = w_list + return w_self.w_elts + +def List_set_elts(space, w_self, w_new_value): + w_self.w_elts = w_new_value + w_self.initialization_state |= 1 + +def List_get_ctx(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'ctx' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return expr_context_to_class[w_self.ctx - 1]() + +def List_set_ctx(space, w_self, w_new_value): + obj = space.interp_w(expr_context, w_new_value) + w_self.ctx = obj.to_simple_int() + w_self.initialization_state |= 2 + +def List_init(space, w_self, args): + w_self = space.descr_self_interp_w(List, w_self) + w_self.w_elts = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("List constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['elts', 'ctx', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +List_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +List.typedef = typedef.TypeDef("List", + expr.typedef, + _fields=_FieldsWrapper(['elts', 'ctx']), + elts=typedef.GetSetProperty(List_get_elts, List_set_elts, cls=List), + ctx=typedef.GetSetProperty(List_get_ctx, List_set_ctx, cls=List), + __new__=interp2app(get_AST_new(List)), + __init__=interp2app(List_init), +) +List.typedef.acceptable_as_base_class = False + +def Tuple_get_elts(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'elts' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_elts is None: + if w_self.elts is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.elts] + w_list = space.newlist(list_w) + w_self.w_elts = w_list + return w_self.w_elts + +def Tuple_set_elts(space, w_self, w_new_value): + w_self.w_elts = w_new_value + w_self.initialization_state |= 1 + +def Tuple_get_ctx(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'ctx' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return expr_context_to_class[w_self.ctx - 1]() + +def Tuple_set_ctx(space, w_self, w_new_value): + obj = space.interp_w(expr_context, w_new_value) + w_self.ctx = obj.to_simple_int() + w_self.initialization_state |= 2 + +def Tuple_init(space, w_self, args): + w_self = space.descr_self_interp_w(Tuple, w_self) + w_self.w_elts = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("Tuple constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['elts', 'ctx', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Tuple_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Tuple.typedef = typedef.TypeDef("Tuple", + expr.typedef, + _fields=_FieldsWrapper(['elts', 'ctx']), + elts=typedef.GetSetProperty(Tuple_get_elts, Tuple_set_elts, cls=Tuple), + ctx=typedef.GetSetProperty(Tuple_get_ctx, Tuple_set_ctx, cls=Tuple), + __new__=interp2app(get_AST_new(Tuple)), + __init__=interp2app(Tuple_init), +) +Tuple.typedef.acceptable_as_base_class = False + +def Const_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return w_self.value + +def Const_set_value(space, w_self, w_new_value): + w_self.value = w_new_value + w_self.initialization_state |= 1 + +def Const_init(space, w_self, args): + w_self = space.descr_self_interp_w(Const, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Const constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Const_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Const.typedef = typedef.TypeDef("Const", + expr.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Const_get_value, Const_set_value, cls=Const), + __new__=interp2app(get_AST_new(Const)), + __init__=interp2app(Const_init), +) +Const.typedef.acceptable_as_base_class = False + +expr_context.typedef = typedef.TypeDef("expr_context", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +expr_context.typedef.acceptable_as_base_class = False + +_Load.typedef = typedef.TypeDef("Load", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Load)), +) +_Load.typedef.acceptable_as_base_class = False + +_Store.typedef = typedef.TypeDef("Store", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Store)), +) +_Store.typedef.acceptable_as_base_class = False + +_Del.typedef = typedef.TypeDef("Del", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Del)), +) +_Del.typedef.acceptable_as_base_class = False + +_AugLoad.typedef = typedef.TypeDef("AugLoad", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_AugLoad)), +) +_AugLoad.typedef.acceptable_as_base_class = False + +_AugStore.typedef = typedef.TypeDef("AugStore", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_AugStore)), +) +_AugStore.typedef.acceptable_as_base_class = False + +_Param.typedef = typedef.TypeDef("Param", + expr_context.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Param)), +) +_Param.typedef.acceptable_as_base_class = False + +slice.typedef = typedef.TypeDef("slice", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +slice.typedef.acceptable_as_base_class = False + +def Ellipsis_init(space, w_self, args): + w_self = space.descr_self_interp_w(Ellipsis, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + w_err = space.wrap("Ellipsis constructor takes no arguments") + raise OperationError(space.w_TypeError, w_err) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Ellipsis_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Ellipsis.typedef = typedef.TypeDef("Ellipsis", + slice.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(Ellipsis)), + __init__=interp2app(Ellipsis_init), +) +Ellipsis.typedef.acceptable_as_base_class = False + +def Slice_get_lower(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'lower' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.lower) + +def Slice_set_lower(space, w_self, w_new_value): + w_self.lower = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def Slice_get_upper(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'upper' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.upper) + +def Slice_set_upper(space, w_self, w_new_value): + w_self.upper = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def Slice_get_step(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'step' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.step) + +def Slice_set_step(space, w_self, w_new_value): + w_self.step = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 4 + +def Slice_init(space, w_self, args): + w_self = space.descr_self_interp_w(Slice, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("Slice constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['lower', 'upper', 'step'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Slice_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Slice.typedef = typedef.TypeDef("Slice", + slice.typedef, + _fields=_FieldsWrapper(['lower', 'upper', 'step']), + lower=typedef.GetSetProperty(Slice_get_lower, Slice_set_lower, cls=Slice), + upper=typedef.GetSetProperty(Slice_get_upper, Slice_set_upper, cls=Slice), + step=typedef.GetSetProperty(Slice_get_step, Slice_set_step, cls=Slice), + __new__=interp2app(get_AST_new(Slice)), + __init__=interp2app(Slice_init), +) +Slice.typedef.acceptable_as_base_class = False + +def ExtSlice_get_dims(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'dims' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_dims is None: + if w_self.dims is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.dims] + w_list = space.newlist(list_w) + w_self.w_dims = w_list + return w_self.w_dims + +def ExtSlice_set_dims(space, w_self, w_new_value): + w_self.w_dims = w_new_value + w_self.initialization_state |= 1 + +def ExtSlice_init(space, w_self, args): + w_self = space.descr_self_interp_w(ExtSlice, w_self) + w_self.w_dims = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("ExtSlice constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['dims'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +ExtSlice_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +ExtSlice.typedef = typedef.TypeDef("ExtSlice", + slice.typedef, + _fields=_FieldsWrapper(['dims']), + dims=typedef.GetSetProperty(ExtSlice_get_dims, ExtSlice_set_dims, cls=ExtSlice), + __new__=interp2app(get_AST_new(ExtSlice)), + __init__=interp2app(ExtSlice_init), +) +ExtSlice.typedef.acceptable_as_base_class = False + +def Index_get_value(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def Index_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def Index_init(space, w_self, args): + w_self = space.descr_self_interp_w(Index, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 1: + w_err = space.wrap("Index constructor takes 0 or 1 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['value'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +Index_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +Index.typedef = typedef.TypeDef("Index", + slice.typedef, + _fields=_FieldsWrapper(['value']), + value=typedef.GetSetProperty(Index_get_value, Index_set_value, cls=Index), + __new__=interp2app(get_AST_new(Index)), + __init__=interp2app(Index_init), +) +Index.typedef.acceptable_as_base_class = False + +boolop.typedef = typedef.TypeDef("boolop", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +boolop.typedef.acceptable_as_base_class = False + +_And.typedef = typedef.TypeDef("And", + boolop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_And)), +) +_And.typedef.acceptable_as_base_class = False + +_Or.typedef = typedef.TypeDef("Or", + boolop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Or)), +) +_Or.typedef.acceptable_as_base_class = False + +operator.typedef = typedef.TypeDef("operator", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +operator.typedef.acceptable_as_base_class = False + +_Add.typedef = typedef.TypeDef("Add", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Add)), +) +_Add.typedef.acceptable_as_base_class = False + +_Sub.typedef = typedef.TypeDef("Sub", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Sub)), +) +_Sub.typedef.acceptable_as_base_class = False + +_Mult.typedef = typedef.TypeDef("Mult", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Mult)), +) +_Mult.typedef.acceptable_as_base_class = False + +_Div.typedef = typedef.TypeDef("Div", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Div)), +) +_Div.typedef.acceptable_as_base_class = False + +_Mod.typedef = typedef.TypeDef("Mod", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Mod)), +) +_Mod.typedef.acceptable_as_base_class = False + +_Pow.typedef = typedef.TypeDef("Pow", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Pow)), +) +_Pow.typedef.acceptable_as_base_class = False + +_LShift.typedef = typedef.TypeDef("LShift", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_LShift)), +) +_LShift.typedef.acceptable_as_base_class = False + +_RShift.typedef = typedef.TypeDef("RShift", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_RShift)), +) +_RShift.typedef.acceptable_as_base_class = False + +_BitOr.typedef = typedef.TypeDef("BitOr", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_BitOr)), +) +_BitOr.typedef.acceptable_as_base_class = False + +_BitXor.typedef = typedef.TypeDef("BitXor", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_BitXor)), +) +_BitXor.typedef.acceptable_as_base_class = False + +_BitAnd.typedef = typedef.TypeDef("BitAnd", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_BitAnd)), +) +_BitAnd.typedef.acceptable_as_base_class = False + +_FloorDiv.typedef = typedef.TypeDef("FloorDiv", + operator.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_FloorDiv)), +) +_FloorDiv.typedef.acceptable_as_base_class = False + +unaryop.typedef = typedef.TypeDef("unaryop", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +unaryop.typedef.acceptable_as_base_class = False + +_Invert.typedef = typedef.TypeDef("Invert", + unaryop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Invert)), +) +_Invert.typedef.acceptable_as_base_class = False + +_Not.typedef = typedef.TypeDef("Not", + unaryop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Not)), +) +_Not.typedef.acceptable_as_base_class = False + +_UAdd.typedef = typedef.TypeDef("UAdd", + unaryop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_UAdd)), +) +_UAdd.typedef.acceptable_as_base_class = False + +_USub.typedef = typedef.TypeDef("USub", + unaryop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_USub)), +) +_USub.typedef.acceptable_as_base_class = False + +cmpop.typedef = typedef.TypeDef("cmpop", + AST.typedef, + _attributes=_FieldsWrapper([]), +) +cmpop.typedef.acceptable_as_base_class = False + +_Eq.typedef = typedef.TypeDef("Eq", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Eq)), +) +_Eq.typedef.acceptable_as_base_class = False + +_NotEq.typedef = typedef.TypeDef("NotEq", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_NotEq)), +) +_NotEq.typedef.acceptable_as_base_class = False + +_Lt.typedef = typedef.TypeDef("Lt", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Lt)), +) +_Lt.typedef.acceptable_as_base_class = False + +_LtE.typedef = typedef.TypeDef("LtE", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_LtE)), +) +_LtE.typedef.acceptable_as_base_class = False + +_Gt.typedef = typedef.TypeDef("Gt", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Gt)), +) +_Gt.typedef.acceptable_as_base_class = False + +_GtE.typedef = typedef.TypeDef("GtE", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_GtE)), +) +_GtE.typedef.acceptable_as_base_class = False + +_Is.typedef = typedef.TypeDef("Is", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_Is)), +) +_Is.typedef.acceptable_as_base_class = False + +_IsNot.typedef = typedef.TypeDef("IsNot", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_IsNot)), +) +_IsNot.typedef.acceptable_as_base_class = False + +_In.typedef = typedef.TypeDef("In", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_In)), +) +_In.typedef.acceptable_as_base_class = False + +_NotIn.typedef = typedef.TypeDef("NotIn", + cmpop.typedef, + _fields=_FieldsWrapper([]), + __new__=interp2app(get_AST_new(_NotIn)), +) +_NotIn.typedef.acceptable_as_base_class = False + +def comprehension_get_target(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'target' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.target) + +def comprehension_set_target(space, w_self, w_new_value): + w_self.target = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 1 + +def comprehension_get_iter(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'iter' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.iter) + +def comprehension_set_iter(space, w_self, w_new_value): + w_self.iter = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def comprehension_get_ifs(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'ifs' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_ifs is None: + if w_self.ifs is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.ifs] + w_list = space.newlist(list_w) + w_self.w_ifs = w_list + return w_self.w_ifs + +def comprehension_set_ifs(space, w_self, w_new_value): + w_self.w_ifs = w_new_value + w_self.initialization_state |= 4 + +def comprehension_init(space, w_self, args): + w_self = space.descr_self_interp_w(comprehension, w_self) + w_self.w_ifs = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 3: + w_err = space.wrap("comprehension constructor takes 0 or 3 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['target', 'iter', 'ifs'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +comprehension_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +comprehension.typedef = typedef.TypeDef("comprehension", + AST.typedef, + _fields=_FieldsWrapper(['target', 'iter', 'ifs']), + target=typedef.GetSetProperty(comprehension_get_target, comprehension_set_target, cls=comprehension), + iter=typedef.GetSetProperty(comprehension_get_iter, comprehension_set_iter, cls=comprehension), + ifs=typedef.GetSetProperty(comprehension_get_ifs, comprehension_set_ifs, cls=comprehension), + __new__=interp2app(get_AST_new(comprehension)), + __init__=interp2app(comprehension_init), +) +comprehension.typedef.acceptable_as_base_class = False + +def excepthandler_get_type(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'type' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.type) + +def excepthandler_set_type(space, w_self, w_new_value): + w_self.type = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 1 + +def excepthandler_get_name(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'name' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.name) + +def excepthandler_set_name(space, w_self, w_new_value): + w_self.name = space.interp_w(expr, w_new_value, True) + w_self.initialization_state |= 2 + +def excepthandler_get_body(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'body' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_body is None: + if w_self.body is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.body] + w_list = space.newlist(list_w) + w_self.w_body = w_list + return w_self.w_body + +def excepthandler_set_body(space, w_self, w_new_value): + w_self.w_body = w_new_value + w_self.initialization_state |= 4 + +def excepthandler_get_lineno(space, w_self): + if not w_self.initialization_state & 8: + w_err = space.wrap("attribute 'lineno' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.lineno) + +def excepthandler_set_lineno(space, w_self, w_new_value): + w_self.lineno = space.int_w(w_new_value) + w_self.initialization_state |= 8 + +def excepthandler_get_col_offset(space, w_self): + if not w_self.initialization_state & 16: + w_err = space.wrap("attribute 'col_offset' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.col_offset) + +def excepthandler_set_col_offset(space, w_self, w_new_value): + w_self.col_offset = space.int_w(w_new_value) + w_self.initialization_state |= 16 + +def excepthandler_init(space, w_self, args): + w_self = space.descr_self_interp_w(excepthandler, w_self) + w_self.w_body = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 5: + w_err = space.wrap("excepthandler constructor takes 0 or 5 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['type', 'name', 'body', 'lineno', 'col_offset'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +excepthandler_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +excepthandler.typedef = typedef.TypeDef("excepthandler", + AST.typedef, + _fields=_FieldsWrapper(['type', 'name', 'body', 'lineno', 'col_offset']), + type=typedef.GetSetProperty(excepthandler_get_type, excepthandler_set_type, cls=excepthandler), + name=typedef.GetSetProperty(excepthandler_get_name, excepthandler_set_name, cls=excepthandler), + body=typedef.GetSetProperty(excepthandler_get_body, excepthandler_set_body, cls=excepthandler), + lineno=typedef.GetSetProperty(excepthandler_get_lineno, excepthandler_set_lineno, cls=excepthandler), + col_offset=typedef.GetSetProperty(excepthandler_get_col_offset, excepthandler_set_col_offset, cls=excepthandler), + __new__=interp2app(get_AST_new(excepthandler)), + __init__=interp2app(excepthandler_init), +) +excepthandler.typedef.acceptable_as_base_class = False + +def arguments_get_args(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'args' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_args is None: + if w_self.args is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.args] + w_list = space.newlist(list_w) + w_self.w_args = w_list + return w_self.w_args + +def arguments_set_args(space, w_self, w_new_value): + w_self.w_args = w_new_value + w_self.initialization_state |= 1 + +def arguments_get_vararg(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'vararg' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.vararg) + +def arguments_set_vararg(space, w_self, w_new_value): + if space.is_w(w_new_value, space.w_None): + w_self.vararg = None + else: + w_self.vararg = space.str_w(w_new_value) + w_self.initialization_state |= 2 + +def arguments_get_kwarg(space, w_self): + if not w_self.initialization_state & 4: + w_err = space.wrap("attribute 'kwarg' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.kwarg) + +def arguments_set_kwarg(space, w_self, w_new_value): + if space.is_w(w_new_value, space.w_None): + w_self.kwarg = None + else: + w_self.kwarg = space.str_w(w_new_value) + w_self.initialization_state |= 4 + +def arguments_get_defaults(space, w_self): + if not w_self.initialization_state & 8: + w_err = space.wrap("attribute 'defaults' has not been set") + raise OperationError(space.w_AttributeError, w_err) + if w_self.w_defaults is None: + if w_self.defaults is None: + w_list = space.newlist([]) + else: + list_w = [space.wrap(node) for node in w_self.defaults] + w_list = space.newlist(list_w) + w_self.w_defaults = w_list + return w_self.w_defaults + +def arguments_set_defaults(space, w_self, w_new_value): + w_self.w_defaults = w_new_value + w_self.initialization_state |= 8 + +def arguments_init(space, w_self, args): + w_self = space.descr_self_interp_w(arguments, w_self) + w_self.w_args = None + w_self.w_defaults = None + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 4: + w_err = space.wrap("arguments constructor takes 0 or 4 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['args', 'vararg', 'kwarg', 'defaults'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +arguments_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +arguments.typedef = typedef.TypeDef("arguments", + AST.typedef, + _fields=_FieldsWrapper(['args', 'vararg', 'kwarg', 'defaults']), + args=typedef.GetSetProperty(arguments_get_args, arguments_set_args, cls=arguments), + vararg=typedef.GetSetProperty(arguments_get_vararg, arguments_set_vararg, cls=arguments), + kwarg=typedef.GetSetProperty(arguments_get_kwarg, arguments_set_kwarg, cls=arguments), + defaults=typedef.GetSetProperty(arguments_get_defaults, arguments_set_defaults, cls=arguments), + __new__=interp2app(get_AST_new(arguments)), + __init__=interp2app(arguments_init), +) +arguments.typedef.acceptable_as_base_class = False + +def keyword_get_arg(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'arg' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.arg) + +def keyword_set_arg(space, w_self, w_new_value): + w_self.arg = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def keyword_get_value(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'value' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.value) + +def keyword_set_value(space, w_self, w_new_value): + w_self.value = space.interp_w(expr, w_new_value, False) + w_self.initialization_state |= 2 + +def keyword_init(space, w_self, args): + w_self = space.descr_self_interp_w(keyword, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 2: + w_err = space.wrap("keyword constructor takes 0 or 2 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['arg', 'value'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +keyword_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +keyword.typedef = typedef.TypeDef("keyword", + AST.typedef, + _fields=_FieldsWrapper(['arg', 'value']), + arg=typedef.GetSetProperty(keyword_get_arg, keyword_set_arg, cls=keyword), + value=typedef.GetSetProperty(keyword_get_value, keyword_set_value, cls=keyword), + __new__=interp2app(get_AST_new(keyword)), + __init__=interp2app(keyword_init), +) +keyword.typedef.acceptable_as_base_class = False + +def alias_get_name(space, w_self): + if not w_self.initialization_state & 1: + w_err = space.wrap("attribute 'name' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.name) + +def alias_set_name(space, w_self, w_new_value): + w_self.name = space.str_w(w_new_value) + w_self.initialization_state |= 1 + +def alias_get_asname(space, w_self): + if not w_self.initialization_state & 2: + w_err = space.wrap("attribute 'asname' has not been set") + raise OperationError(space.w_AttributeError, w_err) + return space.wrap(w_self.asname) + +def alias_set_asname(space, w_self, w_new_value): + if space.is_w(w_new_value, space.w_None): + w_self.asname = None + else: + w_self.asname = space.str_w(w_new_value) + w_self.initialization_state |= 2 + +def alias_init(space, w_self, args): + w_self = space.descr_self_interp_w(alias, w_self) + args_w, kwargs_w = args.unpack() + if args_w: + if len(args_w) != 2: + w_err = space.wrap("alias constructor takes 0 or 2 positional arguments") + raise OperationError(space.w_TypeError, w_err) + for i, field in unrolling_iterable(enumerate(['name', 'asname'])): + space.setattr(w_self, space.wrap(field), args_w[i]) + for field, w_value in kwargs_w.iteritems(): + space.setattr(w_self, space.wrap(field), w_value) +alias_init.unwrap_spec = [ObjSpace, W_Root, Arguments] + +alias.typedef = typedef.TypeDef("alias", + AST.typedef, + _fields=_FieldsWrapper(['name', 'asname']), + name=typedef.GetSetProperty(alias_get_name, alias_set_name, cls=alias), + asname=typedef.GetSetProperty(alias_get_asname, alias_set_asname, cls=alias), + __new__=interp2app(get_AST_new(alias)), + __init__=interp2app(alias_init), +) +alias.typedef.acceptable_as_base_class = False + Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/consts.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/consts.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/consts.py Sun Aug 16 23:51:12 2009 @@ -25,3 +25,4 @@ PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 +PyCF_AST_ONLY = 0x0400 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Sun Aug 16 23:51:12 2009 @@ -9,9 +9,10 @@ class ASDLVisitor(asdl.VisitorBase): - def __init__(self, stream): + def __init__(self, stream, data): super(ASDLVisitor, self).__init__() self.stream = stream + self.data = data def visitModule(self, mod, *args): for df in mod.dfns: @@ -39,32 +40,42 @@ indent = " "*level self.stream.write(indent + line + "\n") - def is_simple_sum(self, sum): - assert isinstance(sum, asdl.Sum) - for constructor in sum.types: - if constructor.fields: - return False - return True +def is_simple_sum(sum): + assert isinstance(sum, asdl.Sum) + for constructor in sum.types: + if constructor.fields: + return False + return True -class ASTNodeVisitor(ASDLVisitor): - def visitModule(self, mod): - dont_touch = set() - for type in mod.dfns: - if isinstance(type.value, asdl.Product) or \ - self.is_simple_sum(type.value): - dont_touch.add(type.name.value) - super(ASTNodeVisitor, self).visitModule(mod, dont_touch) +class ASTNodeVisitor(ASDLVisitor): - def visitType(self, tp, simple): - self.visit(tp.value, tp.name, simple) + def visitType(self, tp): + self.visit(tp.value, tp.name) - def visitSum(self, sum, base, simple): - if self.is_simple_sum(sum): + def visitSum(self, sum, base): + if is_simple_sum(sum): + self.emit("class %s(AST):" % (base,)) + self.emit("") + self.emit("def to_simple_int(self, space):", 1) + self.emit("w_msg = space.wrap(\"not a valid %s\")" % (base,), 2) + self.emit("raise OperationError(space.w_TypeError, w_msg)", 2) + self.emit("") + for i, cons in enumerate(sum.types): + self.emit("class _%s(%s):" % (cons.name, base)) + self.emit("") + self.emit("def to_simple_int(self):", 1) + self.emit("return %i" % (i + 1,), 2) + self.emit("") for i, cons in enumerate(sum.types): self.emit("%s = %i" % (cons.name, i + 1)) self.emit("") + self.emit("%s_to_class = [" % (base,)) + for cons in sum.types: + self.emit("_%s," % (cons.name,), 1) + self.emit("]") + self.emit("") else: self.emit("class %s(AST):" % (base,)) self.emit("") @@ -78,22 +89,82 @@ self.visit(attr) self.emit("") for cons in sum.types: - self.visit(cons, base, sum.attributes, simple) + self.visit(cons, base, sum.attributes) self.emit("") - def visitProduct(self, product, name, simple): + def visitProduct(self, product, name): self.emit("class %s(AST):" % (name,)) self.emit("") - slots = ", ".join(repr(field.name.value) for field in product.fields) + slots = self.make_slots(product.fields) self.emit("__slots__ = (%s)" % (slots,), 1) self.emit("") - self.make_constructor(product.fields) + self.make_constructor(product.fields, product) self.emit("") self.emit("def walkabout(self, visitor):", 1) self.emit("visitor.visit_%s(self)" % (name,), 2) self.emit("") + self.make_var_syncer(product.fields, product, name) + + def make_slots(self, fields): + slots = [] + for field in fields: + name = repr(field.name.value) + slots.append(name) + if field.seq: + slots.append("'w_%s'" % (field.name,)) + return ", ".join(slots) - def make_constructor(self, fields, extras=None, base=None): + def make_var_syncer(self, fields, node, name): + self.emit("def sync_app_attrs(self, space):", 1) + config = (self.data.optional_masks[node], + self.data.required_masks[node]) + self.emit("if (self.initialization_state & ~%i) ^ %i:" % config, 2) + names = [] + for field in fields: + if field.opt: + names.append("None") + else: + names.append(repr(field.name.value)) + sub = (", ".join(names), name.value) + self.emit("missing_field(space, self.initialization_state, [%s], %r)" + % sub, 3) + self.emit("else:", 2) + # Fill in all the default fields. + doing_something = False + for field in fields: + if field.opt: + doing_something = True + flag = self.data.field_masks[field] + self.emit("if not self.initialization_state & %i:" % (flag,), 3) + default = "0" if field.type.value == "int" else "None" + self.emit("self.%s = %s" % (field.name, default), 4) + if not doing_something: + self.emit("pass", 3) + for attr in fields: + if attr.seq: + self.emit("w_list = self.w_%s" % (attr.name,), 2) + self.emit("if w_list is not None:", 2) + self.emit("list_w = space.viewiterable(w_list)", 3) + self.emit("if list_w:", 3) + unwrapper = get_unwrapper(attr.type.value, "w_obj", + self.data.simple_types) + config = (attr.name, unwrapper) + self.emit("self.%s = [%s for w_obj in list_w]" % config, + 4), + self.emit("else:", 3) + self.emit("self.%s = None" % (attr.name,), 4) + if attr.type.value not in asdl.builtin_types and \ + attr.type.value not in self.data.simple_types: + self.emit("if self.%s is not None:" % (attr.name,), 2) + self.emit("for node in self.%s:" % (attr.name,), 3) + self.emit("node.sync_app_attrs(space)", 4) + elif attr.type.value not in asdl.builtin_types and \ + attr.type.value not in self.data.simple_types: + doing_something = True + self.emit("self.%s.sync_app_attrs(space)" % (attr.name,), 2) + self.emit("") + + def make_constructor(self, fields, node, extras=None, base=None): if fields or extras: arg_fields = fields + extras if extras else fields args = ", ".join(str(field.name) for field in arg_fields) @@ -105,15 +176,21 @@ self.emit("%s.__init__(self, %s)" % (base, base_args), 2) else: self.emit("def __init__(self):", 1) - self.emit("pass", 2) + have_everything = self.data.required_masks[node] | \ + self.data.optional_masks[node] + self.emit("self.initialization_state = %i" % (have_everything,), 2) - def visitConstructor(self, cons, base, extra_attributes, simple): + def visitConstructor(self, cons, base, extra_attributes): self.emit("class %s(%s):" % (cons.name, base)) self.emit("") - slots = ", ".join(repr(field.name.value) for field in cons.fields) + slots = self.make_slots(cons.fields) self.emit("__slots__ = (%s)" % (slots,), 1) self.emit("") - self.make_constructor(cons.fields, extra_attributes, base) + for field in self.data.cons_attributes[cons]: + subst = (field.name, self.data.field_masks[field]) + self.emit("_%s_mask = %i" % subst, 1) + self.emit("") + self.make_constructor(cons.fields, cons, extra_attributes, base) self.emit("") self.emit("def walkabout(self, visitor):", 1) self.emit("visitor.visit_%s(self)" % (cons.name,), 2) @@ -121,7 +198,7 @@ self.emit("def mutate_over(self, visitor):", 1) for field in cons.fields: if field.type.value not in asdl.builtin_types and \ - field.type.value not in simple: + field.type.value not in self.data.prod_simple: if field.opt or field.seq: level = 3 self.emit("if self.%s:" % (field.name,), 2) @@ -135,9 +212,14 @@ self.emit("self.%s = self.%s.mutate_over(visitor)" % sub, level) self.emit("return visitor.visit_%s(self)" % (cons.name,), 2) + self.emit("") + self.make_var_syncer(cons.fields + self.data.cons_attributes[cons], + cons, cons.name) def visitField(self, field): self.emit("self.%s = %s" % (field.name, field.name), 2) + if field.seq: + self.emit("self.w_%s = None" % (field.name,), 2) class ASTVisitorVisitor(ASDLVisitor): @@ -162,7 +244,7 @@ def visitType(self, tp): if not (isinstance(tp.value, asdl.Sum) and - self.is_simple_sum(tp.value)): + is_simple_sum(tp.value)): super(ASTVisitorVisitor, self).visitType(tp, tp.name) def visitProduct(self, prod, name): @@ -179,37 +261,33 @@ def visitModule(self, mod): self.emit("class GenericASTVisitor(ASTVisitor):") self.emit("") - simple = set() - for tp in mod.dfns: - if isinstance(tp.value, asdl.Sum) and self.is_simple_sum(tp.value): - simple.add(tp.name.value) - super(GenericASTVisitorVisitor, self).visitModule(mod, simple) + super(GenericASTVisitorVisitor, self).visitModule(mod) self.emit("") - def visitType(self, tp, simple): + def visitType(self, tp): if not (isinstance(tp.value, asdl.Sum) and - self.is_simple_sum(tp.value)): - super(GenericASTVisitorVisitor, self).visitType(tp, tp.name, simple) + is_simple_sum(tp.value)): + super(GenericASTVisitorVisitor, self).visitType(tp, tp.name) - def visitProduct(self, prod, name, simple): - self.make_visitor(name, prod.fields, simple) + def visitProduct(self, prod, name): + self.make_visitor(name, prod.fields) - def visitConstructor(self, cons, _, simple): - self.make_visitor(cons.name, cons.fields, simple) + def visitConstructor(self, cons, _): + self.make_visitor(cons.name, cons.fields) - def make_visitor(self, name, fields, simple): + def make_visitor(self, name, fields): self.emit("def visit_%s(self, node):" % (name,), 1) have_body = False for field in fields: - if self.visitField(field, simple): + if self.visitField(field): have_body = True if not have_body: self.emit("pass", 2) self.emit("") - def visitField(self, field, simple): + def visitField(self, field): if field.type.value not in asdl.builtin_types and \ - field.type.value not in simple: + field.type.value not in self.data.simple_types: if field.seq or field.opt: self.emit("if node.%s:" % (field.name,), 2) level = 3 @@ -224,14 +302,240 @@ return False +asdl_type_map = { + "int" : "int_w", + "identifier" : "str_w", + "bool" : "bool_w" +} + +def get_unwrapper(tp, name, simple_types): + if tp in asdl.builtin_types: + return "space.%s(%s)" % (asdl_type_map[tp], name) + elif tp in simple_types: + return "%s.to_simple_int()" % (name,) + return "space.interp_w(%s, %s)" % (tp, name) + + +class AppExposeVisitor(ASDLVisitor): + + def visitType(self, tp): + super(AppExposeVisitor, self).visitType(tp, tp.name) + + def visitSum(self, sum, name): + for field in sum.attributes: + self.make_property(field, name, True) + self.make_typedef(name, "AST", sum.attributes, + fields_name="_attributes") + if not is_simple_sum(sum): + super(AppExposeVisitor, self).visitSum(sum, name) + else: + for cons in sum.types: + self.make_typedef("_" + cons.name.value, name, (), cons.name, + concrete=True) + + def make_typedef(self, name, base, fields, display_name=None, + fields_name="_fields", concrete=False, needs_init=False): + if display_name is None: + display_name = name + self.emit("%s.typedef = typedef.TypeDef(\"%s\"," % (name, display_name)) + self.emit("%s.typedef," % (base,), 1) + comma_fields = ", ".join(repr(field.name.value) for field in fields) + self.emit("%s=_FieldsWrapper([%s])," % (fields_name, comma_fields), 1) + for field in fields: + getter = "%s_get_%s" % (name, field.name) + setter = "%s_set_%s" % (name, field.name) + config = (field.name, getter, setter, name) + self.emit("%s=typedef.GetSetProperty(%s, %s, cls=%s)," % config, 1) + # CPython lets you create instances of "abstract" AST nodes + # like ast.expr or even ast.AST. This doesn't seem to useful + # and would be a pain to implement safely, so we don't allow + # it. + if concrete: + self.emit("__new__=interp2app(get_AST_new(%s))," % (name,), 1) + if needs_init: + self.emit("__init__=interp2app(%s_init)," % (name,), 1) + self.emit(")") + self.emit("%s.typedef.acceptable_as_base_class = False" % (name,)) + self.emit("") + + def make_init(self, name, fields): + self.emit("def %s_init(space, w_self, args):" % (name,)) + self.emit("w_self = space.descr_self_interp_w(%s, w_self)" % (name,), 1) + for field in fields: + if field.seq: + self.emit("w_self.w_%s = None" % (field.name,), 1) + self.emit("args_w, kwargs_w = args.unpack()", 1) + self.emit("if args_w:", 1) + arity = len(fields) + comma_fields = ", ".join(repr(field.name.value) for field in fields) + if arity: + self.emit("if len(args_w) != %i:" % (arity,), 2) + self.emit("w_err = space.wrap(\"%s constructor takes 0 or %i " \ + "positional arguments\")" % (name, arity), 3) + self.emit("raise OperationError(space.w_TypeError, w_err)", 3) + self.emit("for i, field in unrolling_iterable(enumerate([%s])):" % + (comma_fields,), 2) + self.emit("space.setattr(w_self, space.wrap(field), args_w[i])", 3) + else: + self.emit("w_err = space.wrap(\"%s constructor takes no " \ + " arguments\")" % (name,), 2) + self.emit("raise OperationError(space.w_TypeError, w_err)", 2) + self.emit("for field, w_value in kwargs_w.iteritems():", 1) + self.emit("space.setattr(w_self, space.wrap(field), w_value)", 2) + self.emit("%s_init.unwrap_spec = [ObjSpace, W_Root, Arguments]" + % (name,)) + self.emit("") + + def visitConstructor(self, cons, base): + super(AppExposeVisitor, self).visitConstructor(cons, cons.name) + self.make_init(cons.name, cons.fields + self.data.cons_attributes[cons]) + self.make_typedef(cons.name, base, cons.fields, concrete=True, + needs_init=True) + + def visitProduct(self, product, name): + super(AppExposeVisitor, self).visitProduct(product, name) + self.make_init(name, product.fields) + self.make_typedef(name, "AST", product.fields, concrete=True, + needs_init=True) + + def visitField(self, field, name): + self.make_property(field, name) + + def make_property(self, field, name, different_masks=False): + func = "def %s_get_%s(space, w_self):" % (name, field.name) + self.emit(func) + if different_masks: + flag = "w_self._%s_mask" % (field.name,) + else: + flag = self.data.field_masks[field] + self.emit("if not w_self.initialization_state & %s:" % (flag,), 1) + self.emit("w_err = space.wrap(\"attribute '%s' has not been set\")" % + (field.name,), 2) + self.emit("raise OperationError(space.w_AttributeError, w_err)", 2) + if field.seq: + self.emit("if w_self.w_%s is None:" % (field.name,), 1) + self.emit("if w_self.%s is None:" % (field.name,), 2) + self.emit("w_list = space.newlist([])", 3) + self.emit("else:", 2) + if field.type.value in self.data.simple_types: + wrapper = "%s_to_class[node - 1]()" % (field.type,) + else: + wrapper = "space.wrap(node)" + self.emit("list_w = [%s for node in w_self.%s]" % + (wrapper, field.name), 3) + self.emit("w_list = space.newlist(list_w)", 3) + self.emit("w_self.w_%s = w_list" % (field.name,), 2) + self.emit("return w_self.w_%s" % (field.name,), 1) + elif field.type.value in self.data.simple_types: + config = (field.type, field.name) + self.emit("return %s_to_class[w_self.%s - 1]()" % config, 1) + elif field.type.value in ("object", "string"): + self.emit("return w_self.%s" % (field.name,), 1) + else: + self.emit("return space.wrap(w_self.%s)" % (field.name,), 1) + self.emit("") + + func = "def %s_set_%s(space, w_self, w_new_value):" % (name, field.name) + self.emit(func) + if field.seq: + self.emit("w_self.w_%s = w_new_value" % (field.name,), 1) + elif field.type.value not in asdl.builtin_types: + # These are always other AST nodes. + if field.type.value in self.data.simple_types: + self.emit("obj = space.interp_w(%s, w_new_value)" % \ + (field.type,), 1) + self.emit("w_self.%s = obj.to_simple_int()" % (field.name,), 1) + else: + config = (field.name, field.type, repr(field.opt)) + self.emit("w_self.%s = space.interp_w(%s, w_new_value, %s)" % + config, 1) + else: + level = 1 + if field.opt: + self.emit("if space.is_w(w_new_value, space.w_None):", 1) + self.emit("w_self.%s = None" % (field.name,), 2) + level += 1 + self.emit("else:", 1) + if field.type.value == "object": + self.emit("w_self.%s = w_new_value" % (field.name,), level) + elif field.type.value == "string": + self.emit("if not space.is_true(space.isinstance(" \ + "w_new_value, space.w_basestring)):", level) + line = "w_err = space.wrap(\"some kind of string required\")" + self.emit(line, level + 1) + self.emit("raise OperationError(space.w_TypeError, w_err)", + level + 1) + self.emit("w_self.%s = w_new_value" % (field.name,), level) + else: + space_method = asdl_type_map[field.type.value] + config = (field.name, space_method) + self.emit("w_self.%s = space.%s(w_new_value)" % config, level) + self.emit("w_self.initialization_state |= %s" % (flag,), 1) + self.emit("") + + +def copy_field(field): + return asdl.Field(field.type, field.name, field.seq, field.opt) + + +class ASDLData(object): + + def __init__(self, tree): + simple_types = set() + prod_simple = set() + field_masks = {} + required_masks = {} + optional_masks = {} + cons_attributes = {} + def add_masks(fields, node): + required_mask = 0 + optional_mask = 0 + for i, field in enumerate(fields): + flag = 1 << i + field_masks[field] = flag + if field.opt: + optional_mask |= flag + else: + required_mask |= flag + required_masks[node] = required_mask + optional_masks[node] = optional_mask + for tp in tree.dfns: + if isinstance(tp.value, asdl.Sum): + sum = tp.value + if is_simple_sum(sum): + simple_types.add(tp.name.value) + else: + for cons in sum.types: + attrs = [copy_field(field) for field in sum.attributes] + add_masks(cons.fields + attrs, cons) + cons_attributes[cons] = attrs + else: + prod = tp.value + prod_simple.add(tp.name.value) + add_masks(prod.fields, prod) + prod_simple.update(simple_types) + self.cons_attributes = cons_attributes + self.simple_types = simple_types + self.prod_simple = prod_simple + self.field_masks = field_masks + self.required_masks = required_masks + self.optional_masks = optional_masks + + HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import Wrappable, ObjSpace, W_Root from pypy.interpreter import typedef +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.argument import Arguments +from pypy.interpreter.error import OperationError +from pypy.rlib.unroll import unrolling_iterable from pypy.tool.pairtype import extendabletype +from pypy.tool.sourcetools import func_with_new_name + class AST(Wrappable): - __slots__ = () + __slots__ = ("initialization_state",) __metaclass__ = extendabletype @@ -241,12 +545,57 @@ def mutate_over(self, visitor): raise AssertionError("mutate_over() implementation not provided") + def sync_app_attrs(self, space): + raise NotImplementedError + + class NodeVisitorNotImplemented(Exception): pass + +class _FieldsWrapper(Wrappable): + "Hack around the fact we can't store tuples on a TypeDef." + + def __init__(self, fields): + self.fields = fields + + def __spacebind__(self, space): + return space.newtuple([space.wrap(field) for field in self.fields]) + + +def get_AST_new(node_class): + def generic_AST_new(space, w_type, __args__): + node = space.allocate_instance(node_class, w_type) + node.initialization_state = 0 + return space.wrap(node) + generic_AST_new.unwrap_spec = [ObjSpace, W_Root, Arguments] + return func_with_new_name(generic_AST_new, "new_%s" % node_class.__name__) + + +AST.typedef = typedef.TypeDef("AST", + _fields=_FieldsWrapper([]), + _attributes=_FieldsWrapper([]), +) +AST.typedef.acceptable_as_base_class = False + + +def missing_field(space, state, required, host): + "Find which required field is missing." + for i in range(len(required)): + if not (state >> i) & 1: + missing = required[i] + if missing is not None: + err = "required attribute '%s' missing from %s" + err %= (missing, host) + w_err = space.wrap(err) + raise OperationError(space.w_TypeError, w_err) + raise AssertionError("should not reach here") + + """ -visitors = [ASTNodeVisitor, ASTVisitorVisitor, GenericASTVisitorVisitor] +visitors = [ASTNodeVisitor, ASTVisitorVisitor, GenericASTVisitorVisitor, + AppExposeVisitor] def main(argv): @@ -261,11 +610,12 @@ print >> sys.stderr, "invalid arguments" return 2 mod = asdl.parse(def_file) + data = ASDLData(mod) fp = open(out_file, "w") try: fp.write(HEAD) for visitor in visitors: - visitor(fp).visit(mod) + visitor(fp, data).visit(mod) finally: fp.close() Modified: pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py Sun Aug 16 23:51:12 2009 @@ -223,42 +223,55 @@ self.futureFlags = future.futureFlags_2_5 self.compiler_flags = self.futureFlags.allowed_flags - def compile(self, source, filename, mode, flags): - from pypy.interpreter.pyparser.error import (SyntaxError, - IndentationError, - TokenIndentationError) - from pypy.interpreter.pycode import PyCode + def compile_ast(self, node, filename, mode, flags): from pypy.interpreter.pyparser.pyparse import CompileInfo - from pypy.interpreter.pyparser.future import getFutures - from pypy.interpreter.astcompiler.astbuilder import ast_from_node - from pypy.interpreter.astcompiler.codegen import compile_ast - from pypy.interpreter.astcompiler import consts, optimize + info = CompileInfo(filename, mode, flags) + return self._compile_ast(node, info) + def _compile_ast(self, node, info): + from pypy.interpreter.astcompiler import optimize + from pypy.interpreter.astcompiler.codegen import compile_ast + from pypy.interpreter.pyparser.error import SyntaxError space = self.space + try: + mod = optimize.optimize_ast(space, node, info) + code = compile_ast(space, mod, info) + except SyntaxError, e: + raise OperationError(space.w_SyntaxError, + e.wrap_info(space)) + return code - if flags & ~(consts.PyCF_SOURCE_IS_UTF8 | consts.PyCF_DONT_IMPLY_DEDENT - | self.futureFlags.allowed_flags): - raise OperationError(space.w_ValueError, - space.wrap("invalid compile flags")) + def compile_to_ast(self, source, filename, mode, flags): + from pypy.interpreter.pyparser.pyparse import CompileInfo + info = CompileInfo(filename, mode, flags) + return self._compile_to_ast(source, info) - space.timer.start("PythonAST compile") + def _compile_to_ast(self, source, info): + from pypy.interpreter.pyparser.future import getFutures + from pypy.interpreter.pyparser.error import (SyntaxError, + IndentationError, + TokenIndentationError) + from pypy.interpreter.astcompiler.astbuilder import ast_from_node + space = self.space try: - f_flags, future_lineno = getFutures(self.futureFlags, source) - flags |= f_flags - info = CompileInfo(filename, mode, flags, future_lineno) + f_flags, future_info = getFutures(self.futureFlags, source) + info.last_future_import = future_info + info.flags |= f_flags parse_tree = self.parser.parse_source(source, info) - module = ast_from_node(space, parse_tree, info) - module = optimize.optimize_ast(space, module, info) - code = compile_ast(space, module, info) + mod = ast_from_node(space, parse_tree, info) except IndentationError, e: raise OperationError(space.w_IndentationError, - e.wrap_info(space, filename)) + e.wrap_info(space)) except TokenIndentationError, e: raise OperationError(space.w_IndentationError, - e.wrap_info(space, filename)) + e.wrap_info(space)) except SyntaxError, e: raise OperationError(space.w_SyntaxError, - e.wrap_info(space, filename)) - assert isinstance(code, PyCode) - space.timer.stop("PythonAST compile") - return code + e.wrap_info(space)) + return mod + + def compile(self, source, filename, mode, flags): + from pypy.interpreter.pyparser.pyparse import CompileInfo + info = CompileInfo(filename, mode, flags) + mod = self._compile_to_ast(source, info) + return self._compile_ast(mod, info) Modified: pypy/branch/parser-compiler/pypy/interpreter/pyparser/error.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/pyparser/error.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/pyparser/error.py Sun Aug 16 23:51:12 2009 @@ -10,9 +10,9 @@ self.filename = filename self.print_file_and_line = False - def wrap_info(self, space, filename): + def wrap_info(self, space): return space.newtuple([space.wrap(self.msg), - space.newtuple([space.wrap(filename), + space.newtuple([space.wrap(self.filename), space.wrap(self.lineno), space.wrap(self.offset), space.wrap(self.text)])]) Modified: pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py Sun Aug 16 23:51:12 2009 @@ -298,12 +298,9 @@ self.compiler_features[fname] = flag if version >= feature.getMandatoryRelease(): self.mandatory_flags |= feature.compiler_flag - self.allowed_flags = compiler_flags | PyCF_DONT_IMPLY_DEDENT + self.allowed_flags = compiler_flags def get_flag_names(self, space, flags): - if flags & ~self.allowed_flags: - raise OperationError(space.w_ValueError, - space.wrap("compile(): unrecognized flags")) flag_names = [] for name, value in self.compiler_features.items(): if flags & value: Modified: pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py Sun Aug 16 23:51:12 2009 @@ -150,6 +150,9 @@ for tp, value, lineno, column, line in tokens: if self.add_token(tp, value, lineno, column, line): break + except error.TokenError, e: + e.filename = compile_info.filename + raise except parser.ParseError, e: # Catch parse errors, pretty them up and reraise them as a # SyntaxError. Modified: pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py Sun Aug 16 23:51:12 2009 @@ -5,7 +5,7 @@ from pypy.interpreter.pycode import PyCode from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.error import OperationError -from pypy.interpreter.astcompiler import consts +from pypy.interpreter.astcompiler import consts, ast from pypy.interpreter.gateway import NoneNotWrapped def compile(space, w_source, filename, mode, flags=0, dont_inherit=0): @@ -21,7 +21,13 @@ compile; if absent or zero these statements do influence the compilation, in addition to any features explicitly specified. """ - if space.is_true(space.isinstance(w_source, space.w_unicode)): + + ast_node = None + w_ast_type = space.gettypeobject(ast.AST.typedef) + if space.is_true(space.isinstance(w_source, w_ast_type)): + ast_node = space.interp_w(ast.mod, w_source) + ast_node.sync_app_attrs(space) + elif space.is_true(space.isinstance(w_source, space.w_unicode)): w_utf_8_source = space.call_method(w_source, "encode", space.wrap("utf-8")) str_ = space.str_w(w_utf_8_source) @@ -31,6 +37,10 @@ str_ = space.str_w(w_source) ec = space.getexecutioncontext() + if flags & ~(ec.compiler.compiler_flags | consts.PyCF_AST_ONLY | + consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8): + raise OperationError(space.w_ValueError, + space.wrap("compile() unrecognized flags")) if not dont_inherit: try: caller = ec.framestack.top() @@ -44,7 +54,14 @@ space.wrap("compile() arg 3 must be 'exec' " "or 'eval' or 'single'")) - code = ec.compiler.compile(str_, filename, mode, flags) + if ast_node is None: + if flags & consts.PyCF_AST_ONLY: + mod = ec.compiler.compile_to_ast(str_, filename, mode, flags) + return space.wrap(mod) + else: + code = ec.compiler.compile(str_, filename, mode, flags) + else: + code = ec.compiler.compile_ast(ast_node, filename, mode, flags) return space.wrap(code) # compile.unwrap_spec = [ObjSpace,W_Root,str,str,int,int] Added: pypy/branch/parser-compiler/pypy/module/_ast/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/parser-compiler/pypy/module/_ast/__init__.py Sun Aug 16 23:51:12 2009 @@ -0,0 +1,18 @@ +from pypy.interpreter.mixedmodule import MixedModule +from pypy.interpreter.astcompiler import ast, consts + + +class Module(MixedModule): + + interpleveldefs = { + "PyCF_AST_ONLY" : "space.wrap(%s)" % consts.PyCF_AST_ONLY + } + appleveldefs = {} + + +def _setup(): + defs = Module.interpleveldefs + for name, cls in ast.__dict__.iteritems(): + if isinstance(cls, type) and issubclass(cls, ast.AST): + defs[name.lstrip("_")] = cls.__module__ + "." + name +_setup() Added: pypy/branch/parser-compiler/pypy/module/_ast/test/__init__.py ============================================================================== Added: pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py ============================================================================== --- (empty file) +++ pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Sun Aug 16 23:51:12 2009 @@ -0,0 +1,161 @@ +import py + +from pypy.interpreter import gateway + + +app = gateway.applevel("""def get_ast(source, mode="exec"): + import _ast as ast + mod = compile(source, "", mode, ast.PyCF_AST_ONLY) + assert isinstance(mod, ast.mod) + return mod""") + + +class AppTestAST: + + def setup_class(cls): + cls.w_ast = cls.space.appexec([], """(): + import _ast + return _ast""") + cls.w_get_ast = app.wget(cls.space, "get_ast") + + def test_build_ast(self): + ast = self.ast + mod = self.get_ast("x = 4") + assert isinstance(mod, ast.Module) + assert len(mod.body) == 1 + + def test_simple_sums(self): + ast = self.ast + mod = self.get_ast("x = 4 + 5") + expr = mod.body[0].value + assert isinstance(expr, ast.BinOp) + assert isinstance(expr.op, ast.Add) + expr.op = ast.Sub() + assert isinstance(expr.op, ast.Sub) + co = compile(mod, "", "exec") + ns = {} + exec co in ns + assert ns["x"] == -1 + mod = self.get_ast("4 < 5 < 6", "eval") + assert isinstance(mod.body, ast.Compare) + assert len(mod.body.ops) == 2 + for op in mod.body.ops: + assert isinstance(op, ast.Lt) + mod.body.ops[0] = ast.Gt() + co = compile(mod, "", "exec") + assert not eval(co) + + def test_string(self): + mod = self.get_ast("'hi'", "eval") + s = mod.body + assert s.s == "hi" + s.s = "pypy" + raises(TypeError, setattr, s, "s", 43) + assert eval(compile(mod, "", "eval")) == "pypy" + + def test_empty_initialization(self): + ast = self.ast + def com(node): + return compile(node, "", "exec") + mod = ast.Module() + raises(AttributeError, getattr, mod, "body") + exc = raises(TypeError, com, mod)[1] + assert str(exc) == "required attribute 'body' missing from Module" + expr = ast.Name() + expr.id = "hi" + expr.ctx = ast.Load() + expr.lineno = 4 + exc = raises(TypeError, com, ast.Module([ast.Expr(expr, 0, 0)]))[1] + assert str(exc) == "required attribute 'col_offset' missing from Name" + + def test_int(self): + ast = self.ast + imp = ast.ImportFrom("", ["apples"], -1, 0, 0) + assert imp.level == -1 + imp.level = 3 + assert imp.level == 3 + + def test_identifier(self): + ast = self.ast + name = ast.Name("name_word", ast.Load(), 0, 0) + assert name.id == "name_word" + name.id = "hi" + assert name.id == "hi" + raises(TypeError, setattr, name, "id", 32) + + def test_bool(self): + ast = self.ast + pr = ast.Print(None, [ast.Name("hi", ast.Load(), 0, 0)], False, 0, 0) + assert not pr.nl + assert isinstance(pr.nl, bool) + pr.nl = True + assert pr.nl + + def test_object(self): + ast = self.ast + const = ast.Const(4, 0, 0) + assert const.value == 4 + const.value = 5 + assert const.value == 5 + + def test_list_syncing(self): + ast = self.ast + mod = ast.Module([ast.Lt()]) + raises(TypeError, compile, mod, "", "exec") + mod = self.get_ast("x = y = 3") + assign = mod.body[0] + assert len(assign.targets) == 2 + assign.targets[1] = ast.Name("lemon", ast.Store(), 0, 0) + name = ast.Name("apple", ast.Store(), 0, 0) + mod.body.append(ast.Assign([name], ast.Num(4, 0, 0), 0, 0)) + co = compile(mod, "", "exec") + ns = {} + exec co in ns + assert "y" not in ns + assert ns["x"] == ns["lemon"] == 3 + assert ns["apple"] == 4 + + def test_ast_types(self): + ast = self.ast + expr = ast.Expr() + raises(TypeError, setattr, expr, "value", ast.Lt()) + + def test_abstract_ast_types(self): + ast = self.ast + raises(TypeError, ast.expr) + raises(TypeError, ast.AST) + raises(TypeError, type, "X", (ast.AST,), {}) + raises(TypeError, type, "Y", (ast.expr,), {}) + + def test_constructor(self): + ast = self.ast + body = [] + mod = ast.Module(body) + assert mod.body is body + target = ast.Name("hi", ast.Store(), 0, 0) + expr = ast.Name("apples", ast.Load(), 0, 0) + otherwise = [] + fr = ast.For(target, expr, body, otherwise, 0, 1) + assert fr.target is target + assert fr.iter is expr + assert fr.orelse is otherwise + assert fr.body is body + assert fr.lineno == 0 + assert fr.col_offset == 1 + fr = ast.For(body=body, target=target, iter=expr, col_offset=1, + lineno=0, orelse=otherwise) + assert fr.target is target + assert fr.iter is expr + assert fr.orelse is otherwise + assert fr.body is body + assert fr.lineno == 0 + assert fr.col_offset == 1 + exc = raises(TypeError, ast.Module, 1, 2)[1] + msg = str(exc) + assert msg == "Module constructor takes 0 or 1 positional arguments" + raises(AttributeError, ast.Module, nothing=23) + + def test_future(self): + skip("have to write an AST future parser") + mod = self.get_ast("from __future__ import with_statement") + compile(mod, "", "exec") From arigo at codespeak.net Mon Aug 17 15:46:52 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 17 Aug 2009 15:46:52 +0200 (CEST) Subject: [pypy-svn] r66870 - pypy/branch/asmgcc-exception Message-ID: <20090817134652.EA7FF168016@codespeak.net> Author: arigo Date: Mon Aug 17 15:46:51 2009 New Revision: 66870 Added: pypy/branch/asmgcc-exception/ - copied from r66869, pypy/trunk/ Log: Yet another attempt at using the technique of asmgcc to make exception handling more efficient. From arigo at codespeak.net Mon Aug 17 15:49:01 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 17 Aug 2009 15:49:01 +0200 (CEST) Subject: [pypy-svn] r66871 - in pypy/branch/asmgcc-exception/pypy: config translator translator/c translator/c/gcc translator/c/gcc/test Message-ID: <20090817134901.7B8D7168016@codespeak.net> Author: arigo Date: Mon Aug 17 15:49:00 2009 New Revision: 66871 Added: pypy/branch/asmgcc-exception/pypy/translator/c/gcc/gccexceptiontransform.py (contents, props changed) pypy/branch/asmgcc-exception/pypy/translator/c/gcc/test/test_gccexceptiontransform.py (contents, props changed) Modified: pypy/branch/asmgcc-exception/pypy/config/translationoption.py pypy/branch/asmgcc-exception/pypy/translator/c/database.py pypy/branch/asmgcc-exception/pypy/translator/c/genc.py pypy/branch/asmgcc-exception/pypy/translator/translator.py Log: Preparatory work. The new test fails. Also, it looks like gccexceptiontransform.py will share some code with exceptiontransform.py, but for now I'm just duplicating it. Modified: pypy/branch/asmgcc-exception/pypy/config/translationoption.py ============================================================================== --- pypy/branch/asmgcc-exception/pypy/config/translationoption.py (original) +++ pypy/branch/asmgcc-exception/pypy/config/translationoption.py Mon Aug 17 15:49:00 2009 @@ -90,6 +90,14 @@ "shadowstack": [("translation.gc", "generation")], "asmgcc": [("translation.gc", "generation")], }), + ChoiceOption("exceptions", + "Strategy for raising and catching exceptions", + ["standard", "asmgcc"], + "standard", + cmdline="--exceptions", + requires={ + "asmgcc": [("translation.gcrootfinder", "asmgcc")], + }), # other noticeable options BoolOption("thread", "enable use of threading primitives", Modified: pypy/branch/asmgcc-exception/pypy/translator/c/database.py ============================================================================== --- pypy/branch/asmgcc-exception/pypy/translator/c/database.py (original) +++ pypy/branch/asmgcc-exception/pypy/translator/c/database.py Mon Aug 17 15:49:00 2009 @@ -28,7 +28,8 @@ gcpolicyclass=None, stacklesstransformer=None, thread_enabled=False, - sandbox=False): + sandbox=False, + exceptions="standard"): self.translator = translator self.standalone = standalone self.sandbox = sandbox @@ -57,7 +58,8 @@ if translator is None or translator.rtyper is None: self.exctransformer = None else: - self.exctransformer = translator.getexceptiontransformer() + self.exctransformer = translator.getexceptiontransformer( + exceptions) if translator is not None: self.gctransformer = self.gcpolicy.transformerclass(translator) self.completed = False Added: pypy/branch/asmgcc-exception/pypy/translator/c/gcc/gccexceptiontransform.py ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-exception/pypy/translator/c/gcc/gccexceptiontransform.py Mon Aug 17 15:49:00 2009 @@ -0,0 +1,75 @@ +from pypy.rpython.lltypesystem import lltype +from pypy.objspace.flow.model import Constant +from pypy.annotation import model as annmodel +from pypy.rpython.annlowlevel import MixLevelHelperAnnotator + + +class ExceptionTransformer(object): + + def __init__(self, translator): + self.translator = translator + edata = translator.rtyper.getexceptiondata() + lltype_of_exception_value = edata.lltype_of_exception_value + lltype_of_exception_type = edata.lltype_of_exception_type + self.lltype_of_exception_value = lltype_of_exception_value + self.lltype_of_exception_type = lltype_of_exception_type + self.mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) + + def rpyexc_occured(): + return False + + def rpyexc_fetch_type(): + return lltype.nullptr(lltype_of_exception_type.TO) + + def rpyexc_fetch_value(): + return lltype.nullptr(lltype_of_exception_value.TO) + + def rpyexc_clear(): + pass + + def rpyexc_raise(etype, evalue): + # XXX! + pass + + self.rpyexc_occured_ptr = self.build_func( + "RPyExceptionOccurred", + rpyexc_occured, + [], lltype.Bool) + + self.rpyexc_fetch_type_ptr = self.build_func( + "RPyFetchExceptionType", + rpyexc_fetch_type, + [], self.lltype_of_exception_type) + + self.rpyexc_fetch_value_ptr = self.build_func( + "RPyFetchExceptionValue", + rpyexc_fetch_value, + [], self.lltype_of_exception_value) + + self.rpyexc_clear_ptr = self.build_func( + "RPyClearException", + rpyexc_clear, + [], lltype.Void) + + self.rpyexc_raise_ptr = self.build_func( + "RPyRaiseException", + rpyexc_raise, + [self.lltype_of_exception_type, self.lltype_of_exception_value], + lltype.Void, + jitcallkind='rpyexc_raise') # for the JIT + + self.mixlevelannotator.finish() + + def build_func(self, name, fn, inputtypes, rettype, **kwds): + l2a = annmodel.lltype_to_annotation + graph = self.mixlevelannotator.getgraph(fn, map(l2a, inputtypes), l2a(rettype)) + return self.constant_func(name, inputtypes, rettype, graph, + exception_policy="exc_helper", **kwds) + + def constant_func(self, name, inputtypes, rettype, graph, **kwds): + FUNC_TYPE = lltype.FuncType(inputtypes, rettype) + fn_ptr = lltype.functionptr(FUNC_TYPE, name, graph=graph, **kwds) + return Constant(fn_ptr, lltype.Ptr(FUNC_TYPE)) + + def create_exception_handling(self, graph): + pass Added: pypy/branch/asmgcc-exception/pypy/translator/c/gcc/test/test_gccexceptiontransform.py ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-exception/pypy/translator/c/gcc/test/test_gccexceptiontransform.py Mon Aug 17 15:49:00 2009 @@ -0,0 +1,55 @@ +from pypy.translator.translator import TranslationContext, graphof +from pypy.translator.simplify import join_blocks +from pypy.translator.c.gcc import gccexceptiontransform +from pypy.translator.c.genc import CStandaloneBuilder +from pypy import conftest +from pypy.annotation.listdef import s_list_of_strings + +def get_translator(fn, backendopt=False): + t = TranslationContext() + t.buildannotator().build_types(fn, [s_list_of_strings]) + t.buildrtyper().specialize() + if backendopt: + backend_optimizations(t) + return t + +def transform_func(fn, backendopt=False): + t = get_translator(fn, backendopt) + g = graphof(t, fn) + if conftest.option.view: + g.show() + etrafo = gccexceptiontransform.ExceptionTransformer(t) + etrafo.create_exception_handling(g) + join_blocks(g) + if conftest.option.view: + t.view() + # 't' is not used; instead we usually build a new translator in compile(). + +def compile(fn, backendopt=False): + t = get_translator(fn, backendopt) + t.config.translation.exceptions = "asmgcc" + cbuilder = CStandaloneBuilder(t, fn, t.config) + cbuilder.generate_source() + cbuilder.compile() + res = t.platform.execute(cbuilder.executable_name, '') + out = res.out + if res.returncode != 0: + out += '***' + res.err + return out + + +def test_passthrough(): + def one(x): + if x: + raise ValueError() + def foo(argv): + one(0) + print "before raising" + one(1) + print "after raising" + one(0) + return 0 + + transform_func(foo) + data = compile(foo) + assert data == "before raising\n***Fatal RPython error: ValueError\n" Modified: pypy/branch/asmgcc-exception/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/asmgcc-exception/pypy/translator/c/genc.py (original) +++ pypy/branch/asmgcc-exception/pypy/translator/c/genc.py Mon Aug 17 15:49:00 2009 @@ -148,7 +148,8 @@ gcpolicyclass=gcpolicyclass, stacklesstransformer=stacklesstransformer, thread_enabled=self.config.translation.thread, - sandbox=self.config.translation.sandbox) + sandbox=self.config.translation.sandbox, + exceptions=self.config.translation.exceptions) self.db = db # give the gc a chance to register interest in the start-up functions it Modified: pypy/branch/asmgcc-exception/pypy/translator/translator.py ============================================================================== --- pypy/branch/asmgcc-exception/pypy/translator/translator.py (original) +++ pypy/branch/asmgcc-exception/pypy/translator/translator.py Mon Aug 17 15:49:00 2009 @@ -108,12 +108,18 @@ type_system = type_system) return self.rtyper - def getexceptiontransformer(self): + def getexceptiontransformer(self, kind="standard"): if self.rtyper is None: raise ValueError("no rtyper") if self.exceptiontransformer is not None: return self.exceptiontransformer - from pypy.translator.exceptiontransform import ExceptionTransformer + if kind == "standard": + from pypy.translator.exceptiontransform import ExceptionTransformer + elif kind == "asmgcc": + from pypy.translator.c.gcc.gccexceptiontransform import \ + ExceptionTransformer + else: + raise TypeError("unknown value: kind=%r" % (kind,)) self.exceptiontransformer = ExceptionTransformer(self) return self.exceptiontransformer From fijal at codespeak.net Mon Aug 17 21:01:57 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 17 Aug 2009 21:01:57 +0200 (CEST) Subject: [pypy-svn] r66874 - pypy/branch/pyjitpl5-floats/pypy/jit/metainterp Message-ID: <20090817190157.6D3B9498425@codespeak.net> Author: fijal Date: Mon Aug 17 21:01:54 2009 New Revision: 66874 Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py Log: Move assert to a correct place Modified: pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-floats/pypy/jit/metainterp/optimizeopt.py Mon Aug 17 21:01:54 2009 @@ -580,8 +580,8 @@ def optimize_GETFIELD_GC(self, op): value = self.getvalue(op.args[0]) - assert isinstance(value, AbstractVirtualStructValue) if value.is_virtual(): + assert isinstance(value, AbstractVirtualStructValue) # optimizefindnode should ensure that fieldvalue is found fieldvalue = value.getfield(op.descr, None) assert fieldvalue is not None From magcius at codespeak.net Mon Aug 17 22:48:06 2009 From: magcius at codespeak.net (magcius at codespeak.net) Date: Mon, 17 Aug 2009 22:48:06 +0200 (CEST) Subject: [pypy-svn] r66875 - in pypy/branch/avm/pypy/translator: avm1 avm1/test avm2 Message-ID: <20090817204806.B524E168034@codespeak.net> Author: magcius Date: Mon Aug 17 22:48:04 2009 New Revision: 66875 Added: pypy/branch/avm/pypy/translator/avm2/abc.py pypy/branch/avm/pypy/translator/avm2/assembler.py pypy/branch/avm/pypy/translator/avm2/avm2gen.py pypy/branch/avm/pypy/translator/avm2/database.py pypy/branch/avm/pypy/translator/avm2/instructions.py pypy/branch/avm/pypy/translator/avm2/traits.py pypy/branch/avm/pypy/translator/avm2/util.py Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py pypy/branch/avm/pypy/translator/avm1/test/harness.py pypy/branch/avm/pypy/translator/avm1/test/runtest.py pypy/branch/avm/pypy/translator/avm1/test/test_int.py pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py pypy/branch/avm/pypy/translator/avm1/util.py pypy/branch/avm/pypy/translator/avm2/constants.py Log: More complete AVM2, more path fixes. Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1gen.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py Mon Aug 17 22:48:04 2009 @@ -4,7 +4,7 @@ from pypy.objspace.flow import model as flowmodel from pypy.rpython.ootypesystem import ootype -from pypy.translator.avm import avm1, types +from pypy.translator.avm1 import avm1, types from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.metavm import Generator as OOGenerator, InstructionList from pypy.translator.oosupport.constant import push_constant Modified: pypy/branch/avm/pypy/translator/avm1/test/harness.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/harness.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/harness.py Mon Aug 17 22:48:04 2009 @@ -1,6 +1,6 @@ -from pypy.translator.avm.test import browsertest as b -from pypy.translator.avm import avm1 as a, avm1gen as g, swf as s, tags as t, records as r +from pypy.translator.avm1.test import browsertest as b +from pypy.translator.avm1 import avm1 as a, avm1gen as g, swf as s, tags as t, records as r class TestHarness(object): def __init__(self, name): Modified: pypy/branch/avm/pypy/translator/avm1/test/runtest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/runtest.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/runtest.py Mon Aug 17 22:48:04 2009 @@ -9,8 +9,8 @@ from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.backendopt.checkvirtual import check_virtual_methods from pypy.translator.oosupport.support import patch_os, unpatch_os -from pypy.translator.avm.test.harness import TestHarness -from pypy.translator.avm.genavm import GenAVM1 +from pypy.translator.avm1.test.harness import TestHarness +from pypy.translator.avm1.genavm import GenAVM1 # def translate_space_op(gen, op): # if op.opname == "cast_int_to_char": Modified: pypy/branch/avm/pypy/translator/avm1/test/test_int.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/test_int.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/test_int.py Mon Aug 17 22:48:04 2009 @@ -1,6 +1,6 @@ import autopath import py -from pypy.translator.avm.test.runtest import AVM1Test +from pypy.translator.avm1.test.runtest import AVM1Test from pypy.rpython.test.test_rint import BaseTestRint from pypy.rlib.rarithmetic import r_longlong Modified: pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py Mon Aug 17 22:48:04 2009 @@ -1,7 +1,7 @@ import autopath import py from pypy.translator.oosupport.test_template.runtest import BaseTestRunTest -from pypy.translator.avm.test.runtest import AVM1Test +from pypy.translator.avm1.test.runtest import AVM1Test class TestRunTest(BaseTestRunTest, AVM1Test): Modified: pypy/branch/avm/pypy/translator/avm1/util.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/util.py (original) +++ pypy/branch/avm/pypy/translator/avm1/util.py Mon Aug 17 22:48:04 2009 @@ -4,17 +4,6 @@ ALIGN_LEFT = "left" ALIGN_RIGHT = "right" -def serialize_u32(value): - s = "" - while True: - bits = value & 0b01111111 # low 7 bits - value >>= 7 - if not value: - s += chr(bits) - break - s += chr(0b10000000 | bits) - return s - class BitStream(object): """ BitStream is a class for taking care of data structures that are bit-packed, like SWF.""" Added: pypy/branch/avm/pypy/translator/avm2/abc.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/abc.py Mon Aug 17 22:48:04 2009 @@ -0,0 +1,323 @@ + +import struct + +from pypy.translator.avm2.constants import AbcConstantPool, ValuePool, METHODFLAG_HasOptional, METHODFLAG_HasParamNames, py_to_abc, QName +from pypy.translator.avm2.assembler import Avm2CodeAssembler +from pypy.translator.avm2.util import serialize_u32 as u32 +from pypy.translator.avm1.util import BitStream + +MAJOR_VERSION = 46 +MINOR_VERSION = 16 + +class AbcFile(object): + + def __init__(self, constants=None): + self.constants = constants or AbcConstantPool() + self.methods = ValuePool() + self.metadatas = ValuePool() + self.instances = ValuePool() + self.classes = ValuePool() + self.scripts = ValuePool() + self.bodies = ValuePool() + + def serialize(self): + def write_pool(pool, prefix_count=True): + code = "" + if prefix_count: + code += u32(len(pool)) + + for item in pool: + if hasattr(item, "write_to_file"): + item.write_to_file(self) + + if hasattr(item, "write_to_pool"): + item.write_to_pool(self.constants) + + code += item.serialize() + return code + + code = "" + code += struct.pack("= 0: + self.I(instructions.pushuint(self.constants.uint_pool.index_for(v))) + else: + self.I(instructions.pushint(self.constants.int_pool.index_for(v))) + elif isinstance(v, float): + self.I(instructions.pushdouble(self.constants.double_pool.index_for(v))) + elif isinstance(v, basestring): + self.I(instructions.pushstring(self.constants.utf8_pool.index_for(v))) + elif v is True: + self.I(instructions.pushtrue()) + elif v is False: + self.I(instructions.pushfalse()) + + def push_undefined(self): + self.I(instructions.pushundefined()) + + def push_null(self, TYPE=None): + self.I(instructions.pushnull()) + + def push_primitive_constant(self, TYPE, value): + if TYPE is ootype.Void: + self.push_null() + elif TYPE is ootype.String: + if value._str is None: + self.push_null() + else: + self.push_const(value._str) + else: + self.push_const(value) Modified: pypy/branch/avm/pypy/translator/avm2/constants.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/constants.py (original) +++ pypy/branch/avm/pypy/translator/avm2/constants.py Mon Aug 17 22:48:04 2009 @@ -1,4 +1,4 @@ - +c import struct from pypy.translator.avm2.util import serialize_u32 as u32 @@ -6,6 +6,61 @@ # Constants # ====================================== +# ====================================== +# Method Flags +# ====================================== + +""" +Suggest to the run-time that an arguments object (as specified by +the ActionScript 3.0 Language Reference) be created. Must not be used +together with METHODFLAG_NeedRest +""" +METHODFLAG_Arguments = 0x01 + +""" +Must be set if this method uses the newactivation opcode +""" +METHODFLAG_Activation = 0x02 + +""" +This flag creates an ActionScript 3.0 ...rest arguments array. +Must not by used with METHODFLAG_Arguments +""" +METHODFLAG_NeedRest = 0x04 + +""" +Must be set if this method has optional parameters and the options +field is present in this method_info structure. +""" +METHODFLAG_HasOptional = 0x08 + +""" +Undocumented as of now. +""" +METHODFLAG_IgnoreRest = 0x10 + +""" +Undocumented as fo now. Assuming this flag is to implement the +"native" keyword in AS3. +""" +METHODFLAG_Native = 0x20 + +""" +Must be set if this method uses the dxns or dxnslate opcodes. +""" + +METHODFLAG_SetsDxns = 0x40 + +""" +Must be set when the param_names field is presetn in this method_info +structure. +""" +METHODFLAG_HasParamNames = 0x80 + +# ====================================== +# Types +# ====================================== + # String types TYPE_STRING_Utf8 = 0x01 @@ -48,6 +103,29 @@ TYPE_MULTINAME_MultinameL = 0x1B TYPE_MULTINAME_MultinameLA = 0x1C +def py_to_abc(value, pool): + if value is True: + return TYPE_BOOLEAN_True, None + if value is False: + return TYPE_BOOLEAN_False, None + if value is None: + return TYPE_OBJECT_Null, None + if isinstance(value, basestring): + return TYPE_STRING_Utf8 + if isinstance(value, int): + if value < 0: + return TYPE_NUMBER_Int, pool.int_pool + return TYPE_NUMBER_UInt, pool.uint_pool + if isinstance(value, float): + return TYPE_NUMBER_DOUBLE, pool.double_pool + if isinstance(value, Namespace): + return value.kind, pool.namespace_pool + if isinstance(value, NamespaceSet): + return TYPE_NAMESPACE_SET_NamespaceSet, pool.nsset_pool + if hasattr(value, "KIND"): + return value.KIND, pool.multiname_pool + raise ValueError, "This is not an ABC-compatible type." + # ====================================== # Namespaces # ====================================== @@ -104,6 +182,9 @@ NO_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "") ANY_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "*") +PACKAGE_NAMESPACE = Namespace(TYPE_NAMESPACE_PackageNamespace, "") +PRIVATE_NAMESPACE = Namespace(TYPE_NAMESPACE_PrivateNamespace, "private") + NO_NAMESPACE_SET = NamespaceSet() # ====================================== @@ -155,7 +236,11 @@ def write_to_pool(self, pool): super(Multiname, self).write_to_pool(pool) - self._name_index = pool.utf8_pool.index_for(self.name) + assert self.name != "" + if self.name == "*": + self._name_index = 0 + else: + self._name_index = pool.utf8_pool.index_for(self.name) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" @@ -186,7 +271,11 @@ return hash((self.kind, self.name, self.ns)) def write_to_pool(self, pool): - self._name_index = pool.utf8_pool.index_for(self.name) + assert self.name != "" + if self.name == "*": + self._name_index = 0 + else: + self._name_index = pool.utf8_pool.index_for(self.name) self._ns_index = pool.namespace_pool.index_for(self.ns) def serialize(self): @@ -223,10 +312,17 @@ self._name_index = None def write_to_pool(self, pool): - self._name_index = pool.utf8_pool.index_for(name) + assert self.name != "" + if self.name == "*": + self._name_index = 0 + else: + self._name_index = pool.utf8_pool.index_for(name) def serialize(self): assert self._name_index is not None, "Please call write_to_pool before serializing" + +class RtqNameA(object): + KIND = TYPE_MULTINAME_RtqNameA # ====================================== # Constant Pool @@ -239,6 +335,9 @@ self.pool = [] self.default = default + def __iter__(self): + return iter(self.pool) + def index_for(self, value): if value == self.default: return 0 Added: pypy/branch/avm/pypy/translator/avm2/database.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/database.py Mon Aug 17 22:48:04 2009 @@ -0,0 +1,84 @@ +#from pypy.translator.avm.class_ import Class +from pypy.rpython.ootypesystem import ootype +from pypy.translator.cli.support import Counter +from pypy.translator.oosupport.database import Database as OODatabase + +try: + set +except NameError: + from sets import Set as set + +class LowLevelDatabase(OODatabase): + def __init__(self, genoo): + OODatabase.__init__(self, genoo) + self.classes = {} # INSTANCE --> class_name + self.classnames = set() # (namespace, name) + self.functions = {} # graph --> function_name + self.methods = {} # graph --> method_name + self.consts = {} # value --> AbstractConst + self.delegates = {} # StaticMethod --> type_name + self.const_count = Counter() # store statistics about constants + + def next_count(self): + return self.unique() + + def _default_class_name(self, INSTANCE): + parts = INSTANCE._name.rsplit('.', 1) + if len(parts) == 2: + return parts + else: + return None, parts[0] + + def pending_function(self, graph, functype=None): + if functype is None: + function = self.genoo.Function(self, graph) + else: + function = functype(self, graph) + self.pending_node(function) + return function.get_name() + + # def pending_class(self, INSTANCE): + # try: + # return self.classes[INSTANCE] + # except KeyError: + # pass + + # if isinstance(INSTANCE, dotnet.NativeInstance): + # self.classes[INSTANCE] = INSTANCE._name + # return INSTANCE._name + # else: + # namespace, name = self._default_class_name(INSTANCE) + # name = self.get_unique_class_name(namespace, name) + # if namespace is None: + # full_name = name + # else: + # full_name = '%s.%s' % (namespace, name) + # self.classes[INSTANCE] = full_name + # cls = Class(self, INSTANCE, namespace, name) + # self.pending_node(cls) + # return full_name + + def record_function(self, graph, name): + self.functions[graph] = name + + def graph_name(self, graph): + # XXX: graph name are not guaranteed to be unique + return self.functions.get(graph, None) + + def get_unique_class_name(self, namespace, name): + base_name = name + i = 0 + while (namespace, name) in self.classnames: + name = '%s_%d' % (base_name, i) + i+= 1 + self.classnames.add((namespace, name)) + return name + + def class_name(self, INSTANCE): + #if INSTANCE is ootype.ROOT: + # return types.object.classname() + try: + NATIVE_INSTANCE = INSTANCE._hints['NATIVE_INSTANCE'] + return NATIVE_INSTANCE._name + except KeyError: + return self.classes[INSTANCE] Added: pypy/branch/avm/pypy/translator/avm2/instructions.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/instructions.py Mon Aug 17 22:48:04 2009 @@ -0,0 +1,413 @@ + +from pypy.translator.avm2.util import serialize_u32 as u32, Avm2Label +from pypy.translator.avm2.constants import METHODFLAG_Activation, METHODFLAG_SetsDxns +from decorator import decorator + +INSTRUCTIONS = {} + + at decorator +def needs_specialized(fn, self, *args, **kwargs): + if not self.specialized: + raise ValueError, "Instruction needs to be specialized" + return fn(self, *args, **kwargs) + +class _Avm2ShortInstruction(object): + specialized = False + def __init__(self, opcode, name, stack=0, scope=0, flags=0): + self.opcode = opcode + self.name = name + self.stack = stack + self.scope = scope + self.flags = flags + + INSTRUCTIONS[opcode] = self + + def _repr(self): + return "%s (0x%H)" % (self.name, self.opcode) + + def _set_assembler_props(self, asm): + asm.flags |= self.flags + asm.stack_depth += self.stack + asm.scope_depth += self.scope + + def _serialize(self): + return chr(self.opcode) + + serialize = _serialize + set_assembler_props = _set_assembler_props + __repr__ = _repr + + def specialize(self, **kwargs): + return type("Avm2_%s_Instruction" % self.name, + (self.__class__), dict(kwargs.items(), + specialized=True, + serialize=self._serialize, + set_assembler_props=self._set_assembler_props, + __repr__=self._repr)) + +class _Avm2DebugInstruction(_Avm2ShortInstruction): + @needs_specialized + def _serialize(self): + return chr(self.opcode) + \ + chr(self.debug_type & 0xFF) + \ + u32(self.index) + \ + chr(self.reg & 0xFF) + \ + u32(self.extra) + +class _Avm2U8Instruction(_Avm2ShortInstruction): + @needs_specialized + def _serialize(self): + return chr(self.opcode) + chr(self.argument) + + def __call__(self, argument): + return self.specialize(argument=argument) + +class _Avm2U30Instruction(_Avm2U8Instruction): + @needs_specialized + def _serialize(self): + if hasattr(self.argument, "__iter__"): + return chr(self.opcode) + ''.join(u32(i) for i in self.argument) + else: + return chr(self.opcode) + u32(self.argument) + + def __call__(self, argument, *arguments): + if arguments: + self.argument = [argument] + list(arguments) + else: + self.argument = argument + +class _Avm2KillInstruction(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + super(_Avm2KillInstruction, self)._set_assembler_props(asm) + asm.kill_local(self.argument) + +class _Avm2NamespaceInstruction(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + super(_Avm2NamespaceInstruction, self)._set_assembler_props(asm) + has_rtns = asm.constants.has_RTNS(self.argument) + has_rtname = asm.constants.has_RTName(self.argument) + + asm.stack_depth -= int(has_rtns) + int(has_rtname) + +class _Avm2SetLocalInstruction(_Avm2U30Instruction): + @needs_specialized + def __call__(self, index): + _speed = {0: setlocal_0, 1: setlocal_1, 2: setlocal_2, 3: setlocal_3} + if index in _speed: + return _speed[index] + return self.specialize(index=index) + +class _Avm2GetLocalInstruction(_Avm2ShortInstruction): + def __call__(self, index): + _speed = {0: getlocal_0, 1: getlocal_1, 2: getlocal_2, 3: getlocal_3} + if index in _speed: + return _speed[index] + return self.specialize(index=index) + +class _Avm2OffsetInstruction(_Avm2ShortInstruction): + @needs_specialized + def _repr(self): + return repr(super(_Avm2OffsetInstruction, self))[:-2] + " lbl=%r)>" % self.lbl + + @needs_specialized + def _set_assembler_props(self, asm): + super(_Avm2OffsetInstruction, self)._set_assembler_props + if self.lbl is None: + self.lbl = Avm2Label(asm) + self.asm = asm + + @needs_specialized + def _serialize(self): + code = chr(self.opcode) + code += self.lbl.write_relative_offset(len(self.asm) + 4, len(self.asm) + 1) + return code + + def __call__(self, lbl=None): + return self.specialize(lbl=lbl) + +class _Avm2LookupSwitchInstruction(_Avm2ShortInstruction): + @needs_specialized + def _set_assembler_props(self, asm): + super(_Avm2LookupSwitchInstruction, self)._set_assembler_props(asm) + self.asm = asm + if self.default_label is None: + self.default_label = Avm2Label(asm) + if isinstance(self.case_labels, int): + self.case_labels = [Avm2Label(asm) for i in xrange(self.case_labels)] + + @needs_specialized + def _serialize(self): + code = chr(self.opcode) + base = len(self.asm) + code += self.default_label.write_relative_offset(base, base+1) + code += u32(len(self.case_labels) - 1) + + for lbl in self.case_labels: + location = base + len(code) + code += lbl.write_relative_offset(base, location) + return code + + def __call__(self, default_label=None, case_labels=None): + return self.specialize(default_label=default_label, case_labels=case_labels) + +class _Avm2LabelInstruction(_Avm2ShortInstruction): + @needs_specialized + def _set_assembler_props(self, asm): + super(_Avm2LabelInstruction, self)._set_assembler_props(asm) + if self.lbl == None: + self.define = True + self.lbl = Avm2Label(asm) + else: + assert self.lbl.address == -1 + asm.stack_depth = self.lbl.stack_depth + asm.scope_depth = self.lbl.scope_depth + self.lbl.address = len(asm) + + @needs_specialized + def _serialize(self): + if self.define: + return label_internal.serialize() + return "" + + def __call__(self, lbl=None): + return self.specialize(lbl=lbl, define=False) + +class _Avm2Call(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += 1 - (self.argument + 2) # push function/receiver/args; push result + +class _Avm2Construct(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += 1 - (self.argument + 1) # push object/args; push result + +class _Avm2ConstructSuper(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += self.argument + 1 # pop receiver/args + +class _Avm2CallIDX(_Avm2U30Instruction): + @needs_specialized + def _serialize(self): + return chr(self.opcode) + u32(self.index) + u32(self.argument) + + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += 1 - (self.argument + 1) # push object/args; push result + + def __call__(self, index, num_args): + return self.specialize(index=index, argument=num_args) + +class _Avm2CallMN(_Avm2CallIDX): + @needs_specialized + def _set_assembler_props(self, asm): + has_rtns = asm.constants.has_rtns(self.index) + has_rtname = asm.constants.has_rtname(self.index) + asm.stack_depth += int(self.is_void) - (1 + int(has_rtns) + int(has_rtname) + self.argument) + + def __call__(self, index, num_args, is_void): + return self.specialize(index=index, argument=num_args, is_void=is_void) + +class _Avm2NewArray(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += 1 - self.argument + +class _Avm2NewObject(_Avm2U30Instruction): + @needs_specialized + def _set_assembler_props(self, asm): + asm.stack_depth += 1 - (2 * self.argument) + +#{ Instructions that push one value to the stack and take no arguments. +dup = _Avm2ShortInstruction(0x2A, "dup", 1) +getglobalscope = _Avm2ShortInstruction(0x6A, "getglobalscope", 1) +getlocal_0 = _Avm2ShortInstruction(0xD0, "getlocal_0", 1) +getlocal_1 = _Avm2ShortInstruction(0xD1, 'getlocal_1', 1) +getlocal_2 = _Avm2ShortInstruction(0xD2, 'getlocal_2', 1) +getlocal_3 = _Avm2ShortInstruction(0xD3, 'getlocal_3', 1) +newactivation = _Avm2ShortInstruction(0x57, 'newactivation', 1, flags=METHODFLAG_Activation) +pushfalse = _Avm2ShortInstruction(0x27, 'pushfalse', 1) +pushnan = _Avm2ShortInstruction(0x28, 'pushnan', 1) +pushnull = _Avm2ShortInstruction(0x20, 'pushnull', 1) +pushtrue = _Avm2ShortInstruction(0x26, 'pushtrue', 1) +pushundefined = _Avm2ShortInstruction(0x21, 'pushundefined', 1) +#} + +#{ Instructions that pop one value from the stack and take no arguments. +add = _Avm2ShortInstruction(0xA0, 'add', -1) +add_i = _Avm2ShortInstruction(0xC5, 'add_i', -1) +astypelate = _Avm2ShortInstruction(0x87, 'astypelate', -1) +bitand = _Avm2ShortInstruction(0xA8, 'bitand', -1) +bitor = _Avm2ShortInstruction(0xA9, 'bitor', -1) +bitxor = _Avm2ShortInstruction(0xAA, 'bitxor', -1) +divide = _Avm2ShortInstruction(0xA3, 'divide', -1) +dxnslate = _Avm2ShortInstruction(0x07, 'dxnslate', -1, flags=METHODFLAG_SetsDxns) +equals = _Avm2ShortInstruction(0xAB, 'equals', -1) +greaterequals = _Avm2ShortInstruction(0xB0, 'greaterequals', -1) +greaterthan = _Avm2ShortInstruction(0xAF, 'greaterthan', -1) +hasnext = _Avm2ShortInstruction(0x1F, 'hasnext', -1) +if_ = _Avm2ShortInstruction(0xB4, 'in', -1) +instanceof = _Avm2ShortInstruction(0xB1, 'instanceof', -1) +istypelate = _Avm2ShortInstruction(0xB3, 'istypelate', -1) +lessequals = _Avm2ShortInstruction(0xAE, 'lessequals', -1) +lessthan = _Avm2ShortInstruction(0xAD, 'lessthan', -1) +lshift = _Avm2ShortInstruction(0xA5, 'lshift', -1) +modulo = _Avm2ShortInstruction(0xA4, 'modulo', -1) +multiply = _Avm2ShortInstruction(0xA2, 'multiply', -1) +multiply_i = _Avm2ShortInstruction(0xC7, 'multiply_i', -1) +nextname = _Avm2ShortInstruction(0x1E, 'nextname', -1) +nextvalue = _Avm2ShortInstruction(0x23, 'nextvalue', -1) +pop = _Avm2ShortInstruction(0x29, 'pop', -1) +pushscope = _Avm2ShortInstruction(0x30, 'pushscope', -1, 1) # Changes scope depth. +pushwith = _Avm2ShortInstruction(0x1C, 'pushwith', -1, 1) # Changes scope depth. +returnvalue = _Avm2ShortInstruction(0x48, 'returnvalue', -1) +rshift = _Avm2ShortInstruction(0xA6, 'rshift', -1) +setlocal_0 = _Avm2ShortInstruction(0xD4, 'setlocal_0', -1) +setlocal_1 = _Avm2ShortInstruction(0xD5, 'setlocal_1', -1) +setlocal_2 = _Avm2ShortInstruction(0xD6, 'setlocal_2', -1) +setlocal_3 = _Avm2ShortInstruction(0xD7, 'setlocal_3', -1) +strictequals = _Avm2ShortInstruction(0xAC, 'strictequals', -1) +subtract = _Avm2ShortInstruction(0xA1, 'subtract', -1) +subtract_i = _Avm2ShortInstruction(0xC6, 'subtract_i', -1) +throw = _Avm2ShortInstruction(0x03, 'throw', -1) +urshift = _Avm2ShortInstruction(0xA7, 'urshift', -1) +#} + +#{ Instructions that do not change the stack height and take no arguments. +bitnot = _Avm2ShortInstruction(0x97, 'bitnot') +checkfilter = _Avm2ShortInstruction(0x78, 'checkfilter') +coerce_a = _Avm2ShortInstruction(0x82, 'coerce_a') +coerce_s = _Avm2ShortInstruction(0x85, 'coerce_s') +convert_b = _Avm2ShortInstruction(0x76, 'convert_b') +convert_d = _Avm2ShortInstruction(0x75, 'convert_d') +convert_i = _Avm2ShortInstruction(0x73, 'convert_i') +convert_o = _Avm2ShortInstruction(0x77, 'convert_o') +convert_s = _Avm2ShortInstruction(0x70, 'convert_s') +convert_u = _Avm2ShortInstruction(0x74, 'convert_u') +decrement = _Avm2ShortInstruction(0x93, 'decrement') +decrement_i = _Avm2ShortInstruction(0xC1, 'decrement_i') +esc_xattr = _Avm2ShortInstruction(0x72, 'esc_xattr') +esc_xelem = _Avm2ShortInstruction(0x71, 'esc_xelem') +increment = _Avm2ShortInstruction(0x91, 'increment') +increment_i = _Avm2ShortInstruction(0xC0, 'increment_i') +# kill moved down to Special. +negate = _Avm2ShortInstruction(0x90, 'negate') +negate_i = _Avm2ShortInstruction(0xC4, 'negate_i') +nop = _Avm2ShortInstruction(0x02, 'nop') +not_ = _Avm2ShortInstruction(0x96, 'not') +popscope = _Avm2ShortInstruction(0x1D, 'popscope', 0, -1) # Changes scope depth. +returnvoid = _Avm2ShortInstruction(0x47, 'returnvoid') +swap = _Avm2ShortInstruction(0x2B, 'swap') +typeof = _Avm2ShortInstruction(0x95, 'typeof') +#} + +#{ Call Instructions +call = _Avm2Call(0x41, 'call') +construct = _Avm2Construct(0x42, 'construct') +constructsuper = _Avm2ConstructSuper(0x49, 'constructsuper') + +callmethod = _Avm2CallIDX(0x43, 'callmethod') +callstatic = _Avm2CallIDX(0x43, 'callstatic') + +callsuper = _Avm2CallMN(0x45, 'callsuper') +callproperty = _Avm2CallMN(0x46, 'callproperty') +constructprop = _Avm2CallMN(0x4A, 'constructprop') +callproplex = _Avm2CallMN(0x4C, 'callproplex') +callsupervoid = _Avm2CallMN(0x4E, 'callsupervoid') +callpropvoid = _Avm2CallMN(0x4F, 'callpropvoid') +#} + +#{ Instructions that do not chage the stack height stack and take one U30 argument. +astype = _Avm2U30Instruction(0x86, 'astype') +coerce = _Avm2U30Instruction(0x80, 'coerce') +debugfile = _Avm2U30Instruction(0xF1, 'debugfile') +debugline = _Avm2U30Instruction(0xF0, 'debugline') +declocal = _Avm2U30Instruction(0x94, 'declocal') +declocal_i = _Avm2U30Instruction(0xC3, 'declocal_i') +dxns = _Avm2U30Instruction(0x06, 'dxns', flags=METHODFLAG_SetsDxns) +getslot = _Avm2U30Instruction(0x6C, 'getslot') +inclocal = _Avm2U30Instruction(0x92, 'inclocal') +inclocal_i = _Avm2U30Instruction(0xC2, 'inclocal_i') +istype = _Avm2U30Instruction(0xB2, 'istype') +newclass = _Avm2U30Instruction(0x58, 'newclass') +#} + +#{ Instructions that push to the stack and take one U30 argument. +getglobalslot = _Avm2U30Instruction(0x6E, 'getglobalslot', 1) +getlex = _Avm2U30Instruction(0x60, 'getlex', 1) +getscopeobject = _Avm2U30Instruction(0x65, 'getscopeobject', 1) +getouterscope = _Avm2U30Instruction(0x67, 'getouterscope', 1) +newcatch = _Avm2U30Instruction(0x5A, 'newcatch', 1) +newfunction = _Avm2U30Instruction(0x40, 'newfunction', 1) +pushdouble = _Avm2U30Instruction(0x2F, 'pushdouble', 1) +pushint = _Avm2U30Instruction(0x2D, 'pushint', 1) +pushnamespace = _Avm2U30Instruction(0x31, 'pushnamespace', 1) +pushshort = _Avm2U30Instruction(0x25, 'pushshort', 1) +pushstring = _Avm2U30Instruction(0x2C, 'pushstring', 1) +pushuint = _Avm2U30Instruction(0x2E, 'pushuint', 1) + +getlocal = _Avm2GetLocalInstruction(0x62, 'getlocal') +#} + +#{ Instructions that pop from the stack and take one U30 argument. +setlocal = _Avm2SetLocalInstruction(0x63, 'setlocal') +setslot = _Avm2U30Instruction(0x6D, 'setslot', -1) +#} + +#{ Instructions that push one value to the stack and take two U30 arguments. +hasnext2 = _Avm2U30Instruction(0x32, 'hasnext2', 1) +#} + +#{ Instructions that push/pop values to the stack (depends on arg) and take one U30 argument. +newarray = _Avm2NewArray(0x56, 'newarray') +newobject = _Avm2NewObject(0x55, 'newobject') +#} + +#{ Instructions that take one U8 argument. +pushbyte = _Avm2U8Instruction(0x24, 'pushbyte', 1) +#} + +#{ Offset instructions +ifeq = _Avm2OffsetInstruction(0x13, 'ifeq', -2) +ifge = _Avm2OffsetInstruction(0x18, 'ifge', -2) +ifgt = _Avm2OffsetInstruction(0x17, 'ifgt', -2) +ifle = _Avm2OffsetInstruction(0x16, 'ifle', -2) +iflt = _Avm2OffsetInstruction(0x15, 'iflt', -2) +ifne = _Avm2OffsetInstruction(0x14, 'ifne', -2) +ifnge = _Avm2OffsetInstruction(0x0F, 'ifnge', -2) +ifngt = _Avm2OffsetInstruction(0x0E, 'ifngt', -2) +ifnle = _Avm2OffsetInstruction(0x0D, 'ifnle', -2) +ifnlt = _Avm2OffsetInstruction(0x0C, 'ifnlt', -2) + +ifstricteq = _Avm2OffsetInstruction(0x19, 'ifstricteq', -2) +ifstrictne = _Avm2OffsetInstruction(0x1A, 'ifstrictne', -2) + +iffalse = _Avm2OffsetInstruction(0x12, 'iffalse', -1) +iftrue = _Avm2OffsetInstruction(0x11, 'iftrue', -1) + +ifjump = _Avm2OffsetInstruction(0x10, 'jump') +#} + +#{ Special Instructions +debug = _Avm2DebugInstruction(0xEF, 'debug') + +label_internal = _Avm2ShortInstruction(0x09, 'label') +label = _Avm2LabelInstruction(None, 'label'); + +lookupswitch = _Avm2LookupSwitchInstruction(0x1B, 'lookupswitch') + +deleteproperty = _Avm2NamespaceInstruction(0x6A, 'deleteproperty', 1, 1) +getdescendants = _Avm2NamespaceInstruction(0x59, 'getdescendants', 1, 1) +getproperty = _Avm2NamespaceInstruction(0x66, 'getproperty', 1, 1) +getsuper = _Avm2NamespaceInstruction(0x04, 'getsuper', 1, 1) +findproperty = _Avm2NamespaceInstruction(0x5E, 'findproperty', 0, 1) +findpropstrict = _Avm2NamespaceInstruction(0x5D, 'findpropstrict', 0, 1) +initproperty = _Avm2NamespaceInstruction(0x68, 'initproperty', 2, 0) +setproperty = _Avm2NamespaceInstruction(0x61, 'setproperty', 2, 0) +setsuper = _Avm2NamespaceInstruction(0x05, 'setsuper', 2, 0) + +kill = _Avm2KillInstruction(0x08, 'kill') +#} Added: pypy/branch/avm/pypy/translator/avm2/traits.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/traits.py Mon Aug 17 22:48:04 2009 @@ -0,0 +1,159 @@ + +import struct + +from pypy.translator.avm2.constants import AbcConstantPool, ValuePool, METHODFLAG_HasOptional, METHODFLAG_HasParamNames, py_to_abc, QName +from pypy.translator.avm2.util import serialize_u32 as u32 +from pypy.translator.avm1.util import BitStream + +TRAIT_Slot = 0 +TRAIT_Method = 1 +TRAIT_Getter = 2 +TRAIT_Setter = 3 +TRAIT_Class = 4 +TRAIT_Function = 5 +TRAIT_Const = 6 + +class AbcTrait(object): + KIND = None + def __init__(self, name, final=False, override=False): + self.name = name + self._name_index = None + + self.is_final = final + self.is_override = override + + self.metadata = [] + self._metadata_indices = None + + def write_to_file(self, abc): + self._metadata_indices = [abc.metadatas.index_for(m) for m in self.metadata] + + def write_to_pool(self, pool): + self._name_index = pool.multiname_pool.index_for(self.name) + + @property + def data(self): + return "" + + def serialize(self): + + code = "" + + code += u32(self._name_index) + + flags = BitStream() + flags.write_bit(False) + flags.write_bit(bool(self.metadata)) # ATTR_Metadata + flags.write_bit(self.is_override) # ATTR_Override + flags.write_bit(self.is_final) # ATTR_Final + + flags.write_int_value(self.KIND, 4) # kind + + code += flags.serialize() + + code += self.data + + if self.metadata: + code += u32(len(self.metadata)) + for m in self._metadata_indices: + code += u32(m) + + return code + +class AbcClassTrait(object): + KIND = TRAIT_Class + + def __init__(self, name, cls, slot_id=0, final=False, override=False): + super(AbcClassTrait, self).__init__(name, final, override) + self.slot_id = slot_id + self.cls = cls + self._class_index = None + + def write_to_file(self, abc): + super(AbcClassTrait, self).write_to_file(abc) + self._class_index = abc.classes.index_for(self.cls) + + @property + def data(self): + return u32(self.slot_id) + u32(self._class_index) + +class AbcSlotTrait(object): + KIND = TRAIT_Slot + + def __init__(self, name, type_name, value=None, slot_id=0): + super(AbcSlotTrait, self).__init__(name, False, False) + self.slot_id = slot_id + + self.type_name = type_name + self._type_name_index = None + + self.value = value + self._value_index = None + self._value_kind = None + + def write_to_pool(self, pool): + super(AbcSlotTrait, self).write_to_pool(pool) + if self.value is not None: + self._value_kind, p = py_to_abc(self.value) + if p is not None: + self._value_index = p.index_for(self.value) + else: + self._value_index = self._value_kind + + self._type_name_index = pool.multiname_pool.index_for(self.type_name) + + @property + def data(self): + + code = "" + + code += u32(self.slot_id) + code += u32(self._type_nameIndex) + code += u32(self._value_index) + if self._value_index: + code += u32(self._value_kind) + + return code + +class AbcConstTrait(AbcSlotTrait): + KIND = TRAIT_Const + +class AbcFunctionTrait(AbcTrait): + KIND = TRAIT_Function + def __init__(self, name, function, slot_id=0): + super(AbcFunctionTrait, self).__init__(name, False, False) + self.slot_id = slot_id + + self.function = function + self._function_index = None + + def write_to_file(self, abc): + super(AbcFunctionTrait, self).write_to_file(abc) + self._function_index = abc.methods.index_for(func) + + @property + def data(self): + return u32(self.slot_id) + u32(self._function_index) + +class AbcMethodTrait(AbcTrait): + KIND = TRAIT_Method + def __init__(self, method, disp_id, final=False, override=False): + super(AbcMethodTrait, self).__init__(name, final, override) + self.disp_id = disp_id + + self.method = method + self._method_index = None + + def write_to_file(self, abc): + super(AbcMethodTrait, self).write_to_file(abc) + self._method_index = abc.methods.index_for(self.method) + + @property + def data(self): + return u32(self.disp_id) + u32(self._method_index) + +class AbcGetterTrait(AbcMethodTrait): + KIND = TRAIT_Getter + +class AbcSetterTrait(AbcMethodTrait): + KIND = TRAIT_Setter Added: pypy/branch/avm/pypy/translator/avm2/util.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/util.py Mon Aug 17 22:48:04 2009 @@ -0,0 +1,47 @@ + +import struct + +def serialize_u32(value): + s = "" + i = 0 + while True: + i += 1 + if i == 5: + raise ValueError, "value does not fit in a u32" + bits = value & 0b01111111 # low 7 bits + value >>= 7 + if not value: + s += chr(bits) + break + s += chr(0b10000000 | bits) + return s + +def serialize_s24(value): + m = struct.pack("= 0 and m[3] != "\x00"): + raise ValueError, "value does not fit in a s24" + return m[:3] + +Avm2Backpatch = namedtuple("Avm2Backpatch", "location base lbl") + +class Avm2Label(object): + _next_label = 1000 + + def __init__(self, asm, address=-1): + self.asm = asm + self.name = Avm2Label._next_label + Avm2Label._next_label += 1 + self.address = address + self.stack_depth = asm._stack_depth_max + self.scope_depth = asm._scope_depth_max + + def write_relative_offset(self, base, location): + if self.address == -1: + self.asm.add_backpatch(Avm2Backpatch(location, base, self)) + return "\0\0\0" + else: + return serialize_s24(self.address - base) + + def __repr__(self): + return "" \ + % (self.name, self.address, self.stack_depth, self.scope_depth) From arigo at codespeak.net Tue Aug 18 10:17:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 10:17:09 +0200 (CEST) Subject: [pypy-svn] r66880 - in pypy/branch/pyjitpl5/pypy: interpreter module/pypyjit Message-ID: <20090818081709.A736A168012@codespeak.net> Author: arigo Date: Tue Aug 18 10:17:08 2009 New Revision: 66880 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Log: Add an implementation of get_printable_location() for PyPy. (forgot to check this in earlier) Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pycode.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pycode.py Tue Aug 18 10:17:08 2009 @@ -376,7 +376,10 @@ ] return space.newtuple([new_inst, space.newtuple(tup)]) + def get_repr(self): + return "" % ( + self.co_name, self.co_filename, self.co_firstlineno) + def repr(self, space): - return space.wrap("" % ( - self.co_name, self.co_filename, self.co_firstlineno)) + return space.wrap(self.get_repr()) repr.unwrap_spec = ['self', ObjSpace] Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Tue Aug 18 10:17:08 2009 @@ -44,6 +44,11 @@ return False return True +def get_printable_location(next_instr, bytecode): + if we_are_translated(): + bytecode = cast_base_ptr_to_instance(PyCode, bytecode) + return '%s #%d' % (bytecode.get_repr(), next_instr) + class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] greens = ['next_instr', 'pycode'] @@ -57,7 +62,8 @@ ## blockstack = frame.blockstack ## return (valuestackdepth, blockstack) -pypyjitdriver = PyPyJitDriver(can_inline = can_inline) +pypyjitdriver = PyPyJitDriver(can_inline = can_inline, + get_printable_location = get_printable_location) class __extend__(PyFrame): From cfbolz at codespeak.net Tue Aug 18 11:23:25 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 11:23:25 +0200 (CEST) Subject: [pypy-svn] r66881 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090818092325.105DD168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 11:23:24 2009 New Revision: 66881 Added: pypy/extradoc/sprintinfo/gothenburg-2009/ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (contents, props changed) Log: (all): planning for today, plus various discussions Added: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Tue Aug 18 11:23:24 2009 @@ -0,0 +1,90 @@ + +People present: + - Armin + - Samuele + - Maciek + - Carl Friedrich + - Mikael + +later: + - Benjamin + - Anto + +discussions to be had: + - what goals/benchmarks do we want for the prototype + - things we know are missing + - state of the tests + + - what to do with ootype + - how will Eurostars work, how will work be organized + + +Goals/Benchmarks +----------------- + +Goal: be somehow faster than CPython in real programs + +Benchmarks: + - Richards + - Pystone + - mako, gadfly, templess + - port some of the JS benchmarks? + - look at unladden-swallow benchmarks + - Sympy + - Simpy? + - Pyrolog + +later: + - translate.py + +- there should be a unified way to run these benchmark +- benchmarks should be run nightly +- we might need a benchmarking server + + +State of Tests +--------------- + +- coverage holes in metainterp/optimizer +- coverage of x86 backend needs many random runs ? check this! +- need more direct tests of the x86 backend +- some funniness in test_ll2ctypes.py +- run random tests for x86 nightly +- we need tests for pypy-jit behaviour that explicitely check whether the loops + make sense + +things we know are missing +--------------------------- + +metainterp/frontend: +- virtualizables are not finished +- there is no restriction on the length of the trace +- proper inlining logic +- loop nesting (across calls) +- we need to do something about constantness +- we need to do somethign about assert isinstance(x, Class) +- more backendopt before jitting, assert removal +- many ooisnull guards in a row + +- speed of tracing and fallbacks? + +backend: +- recompilation after every bridge is bad +- jump backward in x86 backend is inefficient +- memory management for the code +- speed of backend? + +Python interpreter: +- lookups of various kinds +- calls? + + +TASKS for the morning +--------------------- + +look at tests + +team 1: metainterp Armin, Carl Friedrich, Mikael +team 2: x86-backend Maciek, Samuele + + From fijal at codespeak.net Tue Aug 18 11:36:57 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 11:36:57 +0200 (CEST) Subject: [pypy-svn] r66882 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem Message-ID: <20090818093657.79BF2168028@codespeak.net> Author: fijal Date: Tue Aug 18 11:36:56 2009 New Revision: 66882 Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Log: (pedronis, fijal) Port speedup from pyjitpl5-float branch Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Tue Aug 18 11:36:56 2009 @@ -109,6 +109,8 @@ assert max_n >= 0 ITEM = A.OF ctypes_item = get_ctypes_type(ITEM, delayed_builders) + MAX_SIZE = sys.maxint/64 + PtrType = ctypes.POINTER(MAX_SIZE * ctypes_item) class CArray(ctypes.Structure): if not A._hints.get('nolength'): @@ -128,7 +130,7 @@ _malloc = classmethod(_malloc) def _indexable(self, index): - PtrType = ctypes.POINTER((index+1) * ctypes_item) + assert index + 1 < MAX_SIZE p = ctypes.cast(ctypes.pointer(self.items), PtrType) return p.contents From cfbolz at codespeak.net Tue Aug 18 11:49:21 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 11:49:21 +0200 (CEST) Subject: [pypy-svn] r66883 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090818094921.06185168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 11:49:21 2009 New Revision: 66883 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Log: (armin, maciek): fish around some more in the repr of constant strings to show the value Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Tue Aug 18 11:49:21 2009 @@ -41,8 +41,12 @@ raise NotImplementedError("type %s not supported" % TYPE) def repr_pointer(box): + from pypy.rpython.lltypesystem import rstr try: - return '*%s' % (box.value._obj.container._TYPE._name,) + T = box.value._obj.container._TYPE + if T is rstr.STR: + return repr(box._get_str()) + return '*%s' % (T._name,) except AttributeError: return box.value From cfbolz at codespeak.net Tue Aug 18 11:49:41 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 11:49:41 +0200 (CEST) Subject: [pypy-svn] r66884 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818094941.3D920168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 11:49:40 2009 New Revision: 66884 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (armin, mikael, cfbolz): increase test coverage Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 18 11:49:40 2009 @@ -575,6 +575,17 @@ # escapes because getarrayitem_gc uses a non-constant index self.find_nodes(ops, 'Not, Not') + def test_find_nodes_arrayitem_forced(self): + ops = """ + [p1] + p2 = new_array(1, descr=arraydescr) + escape(p2) + p4 = new_with_vtable(ConstClass(node_vtable)) + setarrayitem_gc(p2, 0, p4, descr=arraydescr) + jump(p4) + """ + self.find_nodes(ops, 'Not') + def test_find_nodes_struct_virtual_1(self): ops = """ [i1, p2] From cfbolz at codespeak.net Tue Aug 18 12:11:51 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 12:11:51 +0200 (CEST) Subject: [pypy-svn] r66885 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090818101151.47074168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 12:11:50 2009 New Revision: 66885 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (arigo, mikael, cfbolz): more coverage fixes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Tue Aug 18 12:11:50 2009 @@ -99,6 +99,7 @@ class NodeFinder(object): """Abstract base class.""" node_escaped = InstanceNode() + node_escaped.unique = UNIQUE_NO node_escaped.escaped = True def __init__(self): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 18 12:11:50 2009 @@ -551,6 +551,21 @@ """ self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)') + def test_find_nodes_array_virtual_3(self): + ops = """ + [pvalue1, p2] + pvalue2 = new_with_vtable(ConstClass(node_vtable2)) + ps2 = getarrayitem_gc(p2, 1, descr=arraydescr) + setfield_gc(ps2, pvalue2, descr=nextdescr) + ps3 = getarrayitem_gc(p2, 1, descr=arraydescr) + pvalue3 = getfield_gc(ps3, descr=nextdescr) + ps1 = new_with_vtable(ConstClass(node_vtable)) + p3 = new_array(3, descr=arraydescr) + setarrayitem_gc(p3, 1, ps1, descr=arraydescr) + jump(pvalue3, p3) + """ + self.find_nodes(ops, 'Virtual(node_vtable2), VArray(arraydescr, Not, Virtual(node_vtable), Not)') + def test_find_nodes_array_nonvirtual_1(self): ops = """ [i1, p2] From cfbolz at codespeak.net Tue Aug 18 12:17:11 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 12:17:11 +0200 (CEST) Subject: [pypy-svn] r66886 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090818101711.CF072168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 12:17:09 2009 New Revision: 66886 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (arigo, cfbolz, mikael): more coverage, add an unreachability assert Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Tue Aug 18 12:17:09 2009 @@ -82,7 +82,7 @@ for subnode in self.curfields.itervalues(): subnode.set_unique_nodes() else: - self.unique = UNIQUE_NO + assert 0, "most probably unreachable" def __repr__(self): flags = '' Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 18 12:17:09 2009 @@ -566,6 +566,14 @@ """ self.find_nodes(ops, 'Virtual(node_vtable2), VArray(arraydescr, Not, Virtual(node_vtable), Not)') + def test_find_nodes_array_virtual_empty(self): + ops = """ + [i1, p2] + p3 = new_array(3, descr=arraydescr) + jump(i1, p3) + """ + self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)') + def test_find_nodes_array_nonvirtual_1(self): ops = """ [i1, p2] From cfbolz at codespeak.net Tue Aug 18 12:31:48 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 12:31:48 +0200 (CEST) Subject: [pypy-svn] r66887 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818103148.CC4C516802E@codespeak.net> Author: cfbolz Date: Tue Aug 18 12:31:48 2009 New Revision: 66887 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (arigo, cfbolz, mikael): more coverage Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 18 12:31:48 2009 @@ -679,6 +679,38 @@ valuedescr=Not))''', expected) + def test_virtual_constant_isnull(self): + ops = """ + [i0] + p0 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p0, NULL, descr=nextdescr) + p2 = getfield_gc(p0, descr=nextdescr) + i1 = ooisnull(p2) + jump(i1) + """ + expected = """ + [i0] + jump(1) + """ + self.optimize_loop(ops, 'Not', expected) + + + def test_virtual_constant_isnonnull(self): + ops = """ + [i0] + p0 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p0, ConstPtr(myptr), descr=nextdescr) + p2 = getfield_gc(p0, descr=nextdescr) + i1 = ooisnull(p2) + jump(i1) + """ + expected = """ + [i0] + jump(0) + """ + self.optimize_loop(ops, 'Not', expected, p2=self.nodebox.value, + i1=0, boxkinds={'myptr': self.nodebox.value}) + def test_nonvirtual_1(self): ops = """ [i] From fijal at codespeak.net Tue Aug 18 12:34:42 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 12:34:42 +0200 (CEST) Subject: [pypy-svn] r66888 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090818103442.C51FB168031@codespeak.net> Author: fijal Date: Tue Aug 18 12:34:41 2009 New Revision: 66888 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Log: (pedronis, fijal) Fix for bridges not inheriting correct class caches Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Tue Aug 18 12:34:41 2009 @@ -20,6 +20,13 @@ self.structure_types_and_vtables = [] self.class_sizes_cache = [] + def fork(self, cpu, loop, vars): + fork = test_random.OperationBuilder.fork(self, cpu, loop, vars) + fork.structure_types = self.structure_types + fork.structure_types_and_vtables = self.structure_types_and_vtables + fork.class_sizes_cache = self.class_sizes_cache + return fork + def get_structptr_var(self, r, must_have_vtable=False, type=lltype.Struct): while True: ptrvars = [(v, S) for (v, S) in self.ptrvars Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Tue Aug 18 12:34:41 2009 @@ -15,7 +15,7 @@ def __init__(self, subops): self.operations = subops -class OperationBuilder: +class OperationBuilder(object): def __init__(self, cpu, loop, vars): self.cpu = cpu self.loop = loop @@ -26,6 +26,11 @@ self.should_fail_by = None self.counter = 0 + def fork(self, cpu, loop, vars): + fork = self.__class__(cpu, loop, vars) + fork.prebuilt_ptr_consts = self.prebuilt_ptr_consts + return fork + def do(self, opnum, argboxes, descr=None): v_result = execute(self.cpu, opnum, argboxes, descr) if isinstance(v_result, ConstInt): @@ -378,7 +383,7 @@ class RandomLoop(object): dont_generate_more = False - def __init__(self, cpu, BuilderClass, r, startvars=None): + def __init__(self, cpu, builder_factory, r, startvars=None): self.cpu = cpu if startvars is None: startvars = [BoxInt(r.random_integer()) @@ -387,15 +392,15 @@ self.values = [var.value for var in startvars] self.prebuilt_ptr_consts = [] self.r = r - self.build_random_loop(cpu, BuilderClass, r, startvars) + self.build_random_loop(cpu, builder_factory, r, startvars) - def build_random_loop(self, cpu, BuilderClass, r, startvars): + def build_random_loop(self, cpu, builder_factory, r, startvars): loop = TreeLoop('test_random_function') loop.inputargs = startvars[:] loop.operations = [] - builder = BuilderClass(cpu, loop, startvars[:]) + builder = builder_factory(cpu, loop, startvars[:]) self.generate_ops(builder, r, loop, startvars) self.builder = builder cpu.compile_operations(loop) @@ -493,15 +498,15 @@ subloop = DummyLoop(guard_op.suboperations) if guard_op.is_guard_exception(): guard_op.suboperations.append(exc_handling(guard_op)) - bridge_builder = self.builder.__class__(self.builder.cpu, subloop, - op.args[:]) + bridge_builder = self.builder.fork(self.builder.cpu, subloop, + op.args[:]) self.generate_ops(bridge_builder, r, subloop, op.args[:]) if r.random() < 0.1: subset = bridge_builder.subset_of_intvars(r) if len(subset) == 0: return False args = [x.clonebox() for x in subset] - jump_target = RandomLoop(self.builder.cpu, self.builder.__class__, + jump_target = RandomLoop(self.builder.cpu, self.builder.fork, r, args) self.cpu.compile_operations(jump_target.loop) jump_op = ResOperation(rop.JUMP, subset, None) @@ -540,7 +545,7 @@ r = Random() cpu = get_cpu() if demo_conftest.option.repeat == -1: - while 1: + while 1: check_random_function(cpu, BuilderClass, r) else: for i in range(demo_conftest.option.repeat): From cfbolz at codespeak.net Tue Aug 18 13:56:54 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 13:56:54 +0200 (CEST) Subject: [pypy-svn] r66889 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818115654.D7EF216801F@codespeak.net> Author: cfbolz Date: Tue Aug 18 13:56:53 2009 New Revision: 66889 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (arigo, mikael, cfbolz, others watching): improve coverage Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 18 13:56:53 2009 @@ -875,15 +875,19 @@ i1 = getfield_gc(p2, descr=valuedescr) # i1 = const 3 p1 = new_array(i1, descr=arraydescr) escape(p1) + i2 = arraylen_gc(p1) + escape(i2) jump() """ expected = """ [] p1 = new_array(3, descr=arraydescr) escape(p1) + i2 = arraylen_gc(p1) + escape(i2) jump() """ - self.optimize_loop(ops, '', expected, i1=3) + self.optimize_loop(ops, '', expected, i1=3, i2=3) def test_vstruct_1(self): ops = """ From cfbolz at codespeak.net Tue Aug 18 14:19:09 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 14:19:09 +0200 (CEST) Subject: [pypy-svn] r66890 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818121909.B2A69168030@codespeak.net> Author: cfbolz Date: Tue Aug 18 14:19:08 2009 New Revision: 66890 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (mikael, cfbolz): even more coverage: non-virtualized arrays Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 18 14:19:08 2009 @@ -823,6 +823,23 @@ """ self.optimize_loop(ops, 'Not', expected, i3=3) + def test_array_non_optimized(self): + ops = """ + [i1, p0] + setarrayitem_gc(p0, 0, i1, descr=arraydescr) + i2 = ooisnull(p0) + guard_false(i2) + p1 = new_array(i1, descr=arraydescr) + jump(i1, p1) + """ + expected = """ + [i1, p0] + setarrayitem_gc(p0, 0, i1, descr=arraydescr) + p1 = new_array(i1, descr=arraydescr) + jump(i1, p1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + def test_varray_2(self): ops = """ [i0, p1] From benjamin at codespeak.net Tue Aug 18 14:22:06 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 14:22:06 +0200 (CEST) Subject: [pypy-svn] r66891 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools Message-ID: <20090818122206.6B618168033@codespeak.net> Author: benjamin Date: Tue Aug 18 14:22:05 2009 New Revision: 66891 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: add a comment, so I don't forget how this works Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 14:22:05 2009 @@ -316,6 +316,15 @@ return "space.interp_w(%s, %s)" % (tp, name) +# CPython lets blank AST nodes (no constructor arguments) be created +# and the attributes added later. In CPython, it is implemented by +# implementing applevel and c level AST as different structures and +# copying between them. This is hideous, so we use a slightly less +# ugly hack in PyPy. Each field has a bitmask which is set on the +# initialization_state attribute when the field type is set. When +# sync_app_attrs() is called, it's a simple matter of removing the +# optional field flags from initialization_state, and using XOR to +# test if all the required fields have been set. class AppExposeVisitor(ASDLVisitor): def visitType(self, tp): From fijal at codespeak.net Tue Aug 18 14:25:19 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 14:25:19 +0200 (CEST) Subject: [pypy-svn] r66892 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090818122519.C9F84168030@codespeak.net> Author: fijal Date: Tue Aug 18 14:25:19 2009 New Revision: 66892 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: (pedronis, fijal) Remove dead code Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 14:25:19 2009 @@ -123,66 +123,6 @@ def setup(self): self.assembler = Assembler386(self, self.translate_support_code) - # the generic assembler stub that just performs a return -# if self.translate_support_code: -# mixlevelann = self.mixlevelann -# s_int = annmodel.SomeInteger() - -# #def failure_recovery_callback(guard_index, frame_addr): -# # return self.failure_recovery_callback(guard_index, frame_addr) - -# #fn = mixlevelann.delayedfunction(failure_recovery_callback, -# # [s_int, s_int], s_int) -# #self.cfunc_failure_recovery = fn -# else: -# import ctypes -# # the ctypes callback function that handles guard failures -# fntype = ctypes.CFUNCTYPE(ctypes.c_long, -# ctypes.c_long, ctypes.c_void_p) -# self.cfunc_failure_recovery = fntype(self.failure_recovery_callback) -# self.failure_recovery_func_addr = ctypes.cast( -# self.cfunc_failure_recovery, ctypes.c_void_p).value - -# def get_failure_recovery_func_addr(self): -# if self.translate_support_code: -# fn = self.cfunc_failure_recovery -# return lltype.cast_ptr_to_int(fn) -# else: -# return self.failure_recovery_func_addr - -# def failure_recovery_callback(self, guard_index, frame_addr): -# """This function is called back from the assembler code when -# a not-yet-implemented path is followed. It can either compile -# the extra path and ask the assembler to jump to it, or ask -# the assembler to exit the current function. -# """ -# self.assembler.make_sure_mc_exists() -# try: -# del self.keepalives[self.keepalives_index:] -# guard_op = self._guard_list[guard_index] -# #if self.debug: -# # llop.debug_print(lltype.Void, '.. calling back from', -# # guard_op, 'to the jit') -# gf = GuardFailed(self, frame_addr, guard_op) -# self.assembler.logger.log_failure_recovery(gf, guard_index) -# self.metainterp.handle_guard_failure(gf) -# self.return_value_type = gf.return_value_type -# #if self.debug: -# #if gf.return_addr == self.assembler.generic_return_addr: -# # llop.debug_print(lltype.Void, 'continuing at generic return address') -# #else: -# # llop.debug_print(lltype.Void, 'continuing at', -# # uhex(gf.return_addr)) -# return gf.return_addr -# except Exception, e: -# if not we_are_translated(): -# self.caught_exception = sys.exc_info() -# else: -# self.caught_exception = e -# return self.assembler.generic_return_addr - -# def set_meta_interp(self, metainterp): -# self.metainterp = metainterp def setup_once(self): pass @@ -348,39 +288,6 @@ self._guard_list.append(guard_op) return index -# def convert_box_to_int(self, valuebox): -# if isinstance(valuebox, ConstInt): -# return valuebox.value -# elif isinstance(valuebox, BoxInt): -# return valuebox.value -# elif isinstance(valuebox, BoxPtr): -# x = self.cast_gcref_to_int(valuebox.value) -# self.keepalives.append(valuebox.value) -# return x -# elif isinstance(valuebox, ConstPtr): -# x = self.cast_gcref_to_int(valuebox.value) -# self.keepalives.append(valuebox.value) -# return x -# else: -# raise ValueError(valuebox.type) - -# def getvaluebox(self, frameadr, guard_op, argindex): -# # XXX that's plain stupid, do we care about the return value??? -# box = guard_op.liveboxes[argindex] -# frame = getframe(frameadr) -# pos = guard_op.stacklocs[argindex] -# intvalue = frame[pos] -# if isinstance(box, history.BoxInt): -# return history.BoxInt(intvalue) -# elif isinstance(box, history.BoxPtr): -# return history.BoxPtr(self.cast_int_to_gcref(intvalue)) -# else: -# raise AssertionError('getvalue: box = %s' % (box,)) - -# def setvaluebox(self, frameadr, mp, argindex, valuebox): -# frame = getframe(frameadr) -# frame[mp.stacklocs[argindex]] = self.convert_box_to_int(valuebox) - def sizeof(self, S): try: return self._descr_caches['sizeof', S] @@ -390,17 +297,6 @@ self._descr_caches['sizeof', S] = descr return descr -# numof = sizeof -# addresssuffix = str(symbolic.get_size(llmemory.Address)) - -# def itemoffsetof(self, A): -# basesize, itemsize, ofs_length = symbolic.get_array_token(A) -# return basesize - -# def arraylengthoffset(self, A): -# basesize, itemsize, ofs_length = symbolic.get_array_token(A) -# return ofs_length - # ------------------- backend-specific ops ------------------------ def do_arraylen_gc(self, args, arraydescr): @@ -720,36 +616,6 @@ x += 0x100000000 return hex(x) -# class GuardFailed(object): -# return_value_type = 0 - -# def __init__(self, cpu, frame, guard_op): -# self.cpu = cpu -# self.frame = frame -# self.guard_op = guard_op - -# def make_ready_for_return(self, return_value_box): -# self.cpu.assembler.make_sure_mc_exists() -# if return_value_box is not None: -# frame = getframe(self.frame) -# frame[0] = self.cpu.convert_box_to_int(return_value_box) -# if (isinstance(return_value_box, ConstInt) or -# isinstance(return_value_box, BoxInt)): -# self.return_value_type = INT -# else: -# self.return_value_type = PTR -# else: -# self.return_value_type = VOID -# self.return_addr = self.cpu.assembler.generic_return_addr - -# def make_ready_for_continuing_at(self, merge_point): -# # we need to make sure here that return_addr points to a code -# # that is ready to grab coorect values -# self.return_addr = merge_point.comeback_bootstrap_addr - -def getframe(frameadr): - return rffi.cast(rffi.CArrayPtr(lltype.Signed), frameadr) - CPU = CPU386 import pypy.jit.metainterp.executor From benjamin at codespeak.net Tue Aug 18 14:34:10 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 14:34:10 +0200 (CEST) Subject: [pypy-svn] r66893 - pypy/trunk/pypy/interpreter Message-ID: <20090818123410.09CD2168028@codespeak.net> Author: benjamin Date: Tue Aug 18 14:34:09 2009 New Revision: 66893 Modified: pypy/trunk/pypy/interpreter/generator.py Log: (arigo, benjamin) don't throw GeneratorExit when it's not possibly caught Modified: pypy/trunk/pypy/interpreter/generator.py ============================================================================== --- pypy/trunk/pypy/interpreter/generator.py (original) +++ pypy/trunk/pypy/interpreter/generator.py Tue Aug 18 14:34:09 2009 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import NoneNotWrapped from pypy.rlib.rarithmetic import intmask +from pypy.interpreter.pyopcode import LoopBlock class GeneratorIterator(Wrappable): @@ -126,4 +127,7 @@ def __del__(self): if not self.frame.frame_finished_execution: - self._enqueue_for_destruction(self.space) + for block in self.frame.blockstack: + if not isinstance(block, LoopBlock): + self._enqueue_for_destruction(self.space) + break From cfbolz at codespeak.net Tue Aug 18 14:42:00 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 14:42:00 +0200 (CEST) Subject: [pypy-svn] r66894 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090818124200.7F1C9168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 14:42:00 2009 New Revision: 66894 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (cfbolz, mikael): a few more untested cases Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Tue Aug 18 14:42:00 2009 @@ -35,7 +35,7 @@ origitems = None # optimization; equivalent to an empty dict curitems = None # optimization; equivalent to an empty dict - # fields used to store the sahpe of the potential VirtualStruct + # fields used to store the shape of the potential VirtualStruct structdescr = None # set only on freshly-allocated or fromstart structs #origfields = .. # same as above #curfields = .. # same as above Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 18 14:42:00 2009 @@ -686,6 +686,28 @@ self.find_bridge(ops, 'Not', 'Virtual(node_vtable2, valuedescr=Not)', mismatch=True) # bad class + def test_bridge_simple_virtual_struct(self): + ops = """ + [i0] + p0 = new(descr=ssize) + setfield_gc(p0, i0, descr=adescr) + jump(p0) + """ + self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, 'Not', 'VStruct(ssize, adescr=Not)') + + def test_bridge_simple_virtual_struct_non_unique(self): + ops = """ + [i0] + p0 = new(descr=ssize) + setfield_gc(p0, i0, descr=adescr) + jump(p0, p0) + """ + self.find_bridge(ops, 'Not', 'Not, Not') + self.find_bridge(ops, 'Not', 'VStruct(ssize), VStruct(ssize)', + mismatch=True) + + def test_bridge_simple_virtual_2(self): ops = """ [p0] @@ -804,6 +826,17 @@ self.find_bridge(ops, 'Not', 'Not') self.find_bridge(ops, 'Not', 'VArray(arraydescr, Not, Not, Not)') + def test_bridge_array_virtual_size_mismatch(self): + ops = """ + [i1] + p1 = new_array(5, descr=arraydescr) + setarrayitem_gc(p1, 0, i1, descr=arraydescr) + jump(p1) + """ + self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, 'Not', 'VArray(arraydescr, Not, Not, Not)', + mismatch=True) + def test_bridge_array_virtual_2(self): ops = """ [i1] From fijal at codespeak.net Tue Aug 18 14:42:12 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 14:42:12 +0200 (CEST) Subject: [pypy-svn] r66895 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818124212.A3E0E168030@codespeak.net> Author: fijal Date: Tue Aug 18 14:42:12 2009 New Revision: 66895 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Log: (pedronis, fijal) Change a test to execute all paths in opimpl_check_zerodivisionerror Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Tue Aug 18 14:42:12 2009 @@ -402,16 +402,22 @@ assert res == sys.maxint - 2000 def test_int_mod_ovf_zer(self): + myjitdriver = JitDriver(greens = [], reds = ['i', 'x', 'y']) def f(x, y): - try: - return ovfcheck(x%y) - except ZeroDivisionError: - return 1 - except OverflowError: - return 2 + i = 0 + while i < 10: + myjitdriver.can_enter_jit(x=x, y=y, i=i) + myjitdriver.jit_merge_point(x=x, y=y, i=i) + try: + ovfcheck(i%x) + i += 1 + except ZeroDivisionError: + i += 1 + except OverflowError: + i += 2 - res = self.interp_operations(f, [1, 2]) - assert res == 1 + self.meta_interp(f, [0, 0]) + self.meta_interp(f, [1, 0]) def test_int_lshift_ovf(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'y', 'm']) From fijal at codespeak.net Tue Aug 18 14:46:25 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 14:46:25 +0200 (CEST) Subject: [pypy-svn] r66896 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818124625.6FED1168028@codespeak.net> Author: fijal Date: Tue Aug 18 14:46:24 2009 New Revision: 66896 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Log: (pedronis, fijal) a test for int_div overflow Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Tue Aug 18 14:46:24 2009 @@ -1,4 +1,4 @@ -import py +import py, sys from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.rlib.jit import JitDriver from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask @@ -385,6 +385,17 @@ res = self.meta_interp(f, [1]) assert res == expected + + def test_div_ovf(self): + def f(x, y): + try: + return ovfcheck(x/y) + except OverflowError: + return 42 + + res = self.interp_operations(f, [-sys.maxint-1, -1]) + assert res == 42 + def test_int_ovf_common(self): import sys myjitdriver = JitDriver(greens = [], reds = ['n']) From benjamin at codespeak.net Tue Aug 18 14:48:32 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 14:48:32 +0200 (CEST) Subject: [pypy-svn] r66897 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090818124832.D032516802E@codespeak.net> Author: benjamin Date: Tue Aug 18 14:48:31 2009 New Revision: 66897 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: remove incorrect comment Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 14:48:31 2009 @@ -178,7 +178,6 @@ tree._x86_stack_depth) def get_bootstrap_code(self, loop): - # key is locations of arguments addr = loop._x86_bootstrap_code if not addr: arglocs = loop.arglocs From cfbolz at codespeak.net Tue Aug 18 15:28:39 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 15:28:39 +0200 (CEST) Subject: [pypy-svn] r66898 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818132839.48A96168028@codespeak.net> Author: cfbolz Date: Tue Aug 18 15:28:37 2009 New Revision: 66898 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Log: (mikael, cfbolz): skipped test about removing guards of assert isinstance checks Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Tue Aug 18 15:28:37 2009 @@ -646,6 +646,26 @@ res = self.interp_operations(fn, [1]) assert not res + def test_assert_isinstance(self): + py.test.skip("we would really like this to work") + class A: + pass + class B(A): + pass + def fn(n): + # this should only be called with n != 0 + if n: + obj = B() + obj.a = n + else: + obj = A() + obj.a = 17 + assert isinstance(obj, B) + return obj.a + res = self.interp_operations(fn, [1]) + assert res == 1 + self.check_history_(guard_class=0, instanceof=0) + def test_r_dict(self): from pypy.rlib.objectmodel import r_dict class FooError(Exception): From arigo at codespeak.net Tue Aug 18 15:32:03 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 15:32:03 +0200 (CEST) Subject: [pypy-svn] r66899 - pypy/branch/pyjitpl5/pypy/jit/backend/llgraph Message-ID: <20090818133203.902CD168028@codespeak.net> Author: arigo Date: Tue Aug 18 15:32:02 2009 New Revision: 66899 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Log: Oups. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Tue Aug 18 15:32:02 2009 @@ -1292,3 +1292,5 @@ setannotation(do_call_int, annmodel.SomeInteger()) setannotation(do_call_ptr, annmodel.SomePtr(llmemory.GCREF)) setannotation(do_call_void, annmodel.s_None) +setannotation(get_overflow_flag, annmodel.s_Bool) +setannotation(set_overflow_flag, annmodel.s_None) From fijal at codespeak.net Tue Aug 18 15:38:52 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 15:38:52 +0200 (CEST) Subject: [pypy-svn] r66900 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/llgraph backend/x86 metainterp Message-ID: <20090818133852.81FBB16802B@codespeak.net> Author: fijal Date: Tue Aug 18 15:38:52 2009 New Revision: 66900 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/model.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Log: (pedronis, fijal) Change strange interface to set_overflow_error into get_overflow_error that does not store this on CPU first Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Tue Aug 18 15:38:52 2009 @@ -895,14 +895,13 @@ _pseudo_exceptions = {} -def _set_error(Class): - global _last_exception +def _get_error(Class): if _llinterp.typer is not None: llframe = _llinterp.frame_class(None, None, _llinterp) try: llframe.make_llexception(Class()) except LLException, e: - _last_exception = e + return e else: assert 0, "should have raised" else: @@ -912,13 +911,21 @@ ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) _pseudo_exceptions[Class] = LLException(ll_inst.typeptr, ll_inst) - _last_exception = _pseudo_exceptions[Class] + return _pseudo_exceptions[Class] + +def get_overflow_error(): + return llmemory.cast_ptr_to_adr(_get_error(OverflowError).args[0]) + +def get_overflow_error_value(): + return lltype.cast_opaque_ptr(llmemory.GCREF, + _get_error(OverflowError).args[1]) -def set_overflow_error(): - _set_error(OverflowError) +def get_zero_division_error(): + return llmemory.cast_ptr_to_adr(_get_error(ZeroDivisionError).args[0]) -def set_zero_division_error(): - _set_error(ZeroDivisionError) +def get_zero_division_error_value(): + return lltype.cast_opaque_ptr(llmemory.GCREF, + _get_error(ZeroDivisionError).args[1]) _overflow_flag = 'unset' @@ -1256,8 +1263,10 @@ setannotation(get_exception, annmodel.SomeAddress()) setannotation(get_exc_value, annmodel.SomePtr(llmemory.GCREF)) setannotation(clear_exception, annmodel.s_None) -setannotation(set_overflow_error, annmodel.s_None) -setannotation(set_zero_division_error, annmodel.s_None) +setannotation(get_overflow_error, annmodel.SomeAddress()) +setannotation(get_overflow_error_value, annmodel.SomePtr(llmemory.GCREF)) +setannotation(get_zero_division_error, annmodel.SomeAddress()) +setannotation(get_zero_division_error_value, annmodel.SomePtr(llmemory.GCREF)) setannotation(new_memo_cast, s_MemoCast) setannotation(cast_adr_to_int, annmodel.SomeInteger()) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Tue Aug 18 15:38:52 2009 @@ -213,11 +213,13 @@ def clear_exception(self): llimpl.clear_exception() - def set_overflow_error(self): - llimpl.set_overflow_error() - - def set_zero_division_error(self): - llimpl.set_zero_division_error() + def get_overflow_error(self): + return (self.cast_adr_to_int(llimpl.get_overflow_error()), + llimpl.get_overflow_error_value()) + + def get_zero_division_error(self): + return (self.cast_adr_to_int(llimpl.get_zero_division_error()), + llimpl.get_zero_division_error_value()) def get_overflow_flag(self): return llimpl.get_overflow_flag() @@ -485,6 +487,16 @@ else: return ootype.NULL + def get_overflow_error(self): + ll_err = llimpl._get_error(OverflowError) + return (ootype.cast_to_object(ll_err.args[0]), + ootype.cast_to_object(ll_err.args[1])) + + def get_zero_division_error(self): + ll_err = llimpl._get_error(ZeroDivisionError) + return (ootype.cast_to_object(ll_err.args[0]), + ootype.cast_to_object(ll_err.args[1])) + def do_new_with_vtable(self, args, descr=None): assert descr is None assert len(args) == 1 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/model.py Tue Aug 18 15:38:52 2009 @@ -55,10 +55,10 @@ def clear_exception(self): raise NotImplementedError - def set_overflow_error(self): + def get_overflow_error(self): raise NotImplementedError - def set_zero_division_error(self): + def get_zero_division_error(self): raise NotImplementedError def get_overflow_flag(self): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 15:38:52 2009 @@ -140,19 +140,19 @@ self.assembler._exception_bck[0] = 0 self.assembler._exception_bck[1] = 0 - def set_overflow_error(self): + def get_overflow_error(self): self.assembler.make_sure_mc_exists() ovf_vtable = self.cast_adr_to_int(self.assembler._ovf_error_vtable) - ovf_inst = self.cast_adr_to_int(self.assembler._ovf_error_inst) - self.assembler._exception_bck[0] = ovf_vtable - self.assembler._exception_bck[1] = ovf_inst + ovf_inst = self.cast_int_to_gcref( + self.cast_adr_to_int(self.assembler._ovf_error_inst)) + return ovf_vtable, ovf_inst - def set_zero_division_error(self): + def get_zero_division_error(self): self.assembler.make_sure_mc_exists() zer_vtable = self.cast_adr_to_int(self.assembler._zer_error_vtable) - zer_inst = self.cast_adr_to_int(self.assembler._zer_error_inst) - self.assembler._exception_bck[0] = zer_vtable - self.assembler._exception_bck[1] = zer_inst + zer_inst = self.cast_int_to_gcref( + self.cast_adr_to_int(self.assembler._zer_error_inst)) + return zer_vtable, zer_inst _overflow_flag = False Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Tue Aug 18 15:38:52 2009 @@ -384,8 +384,7 @@ return False else: # division by zero! - self.metainterp.cpu.set_zero_division_error() - return self.metainterp.raise_this_error() + return self.metainterp.raise_zero_division_error() @arguments("orgpc", "box", "box") def opimpl_check_div_overflow(self, pc, box1, box2): @@ -403,13 +402,11 @@ return False else: # division overflow! - self.metainterp.cpu.set_overflow_error() - return self.metainterp.raise_this_error() + return self.metainterp.raise_overflow_error() @arguments() def opimpl_overflow_error(self): - self.metainterp.cpu.set_overflow_error() - return self.metainterp.raise_this_error() + return self.metainterp.raise_overflow_error() @arguments("orgpc", "box") def opimpl_int_abs(self, pc, box): @@ -1123,10 +1120,14 @@ else: raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getptr_base()) - def raise_this_error(self): - etype = self.cpu.get_exception() - evalue = self.cpu.get_exc_value() - self.cpu.clear_exception() + def raise_overflow_error(self): + etype, evalue = self.cpu.get_overflow_error() + return self.finishframe_exception( + self.staticdata.ts.get_exception_box(etype), + self.staticdata.ts.get_exc_value_box(evalue)) + + def raise_zero_division_error(self): + etype, evalue = self.cpu.get_zero_division_error() return self.finishframe_exception( self.staticdata.ts.get_exception_box(etype), self.staticdata.ts.get_exc_value_box(evalue)) @@ -1351,8 +1352,7 @@ elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: self.handle_exception() elif opnum == rop.GUARD_NO_OVERFLOW: # an overflow now detected - self.cpu.set_overflow_error() - self.raise_this_error() + self.raise_overflow_error() def compile(self, original_boxes, live_arg_boxes, start): num_green_args = self.staticdata.num_green_args @@ -1551,8 +1551,7 @@ if self.cpu.get_overflow_flag(): self.cpu.set_overflow_flag(False) frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) - self.cpu.set_overflow_error() - return self.raise_this_error() + return self.raise_overflow_error() else: frame.generate_guard(frame.pc, rop.GUARD_NO_OVERFLOW, None, []) return False From cfbolz at codespeak.net Tue Aug 18 15:51:11 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 15:51:11 +0200 (CEST) Subject: [pypy-svn] r66901 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818135111.8D8C2168030@codespeak.net> Author: cfbolz Date: Tue Aug 18 15:51:10 2009 New Revision: 66901 Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_pyjitpl.py (contents, props changed) Log: (mikael, cfbolz): unit test for the bytecode decoding Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_pyjitpl.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_pyjitpl.py Tue Aug 18 15:51:10 2009 @@ -0,0 +1,26 @@ + +# some unit tests for the bytecode decoding + +from pypy.jit.metainterp import pyjitpl, codewriter + +def make_frame(code): + bytecode = codewriter.JitCode("hello") + bytecode.code = code + bytecode.constants = None + frame = pyjitpl.MIFrame(None, bytecode) + frame.pc = 0 + return frame + + +def test_decode_big_int(): + for code, value in [("\x80\x01", 128), ("\x81\x81\x01", 1 + (1 << 7) + (1 << 14))]: + frame = make_frame(code) + val = frame.load_int() + assert val == value + +def test_decode_bool(): + frame = make_frame("\x00") + assert not frame.load_bool() + + frame = make_frame("\x01") + assert frame.load_bool() From fijal at codespeak.net Tue Aug 18 15:53:01 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 15:53:01 +0200 (CEST) Subject: [pypy-svn] r66902 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/llgraph backend/llvm backend/x86 metainterp Message-ID: <20090818135301.19F47168030@codespeak.net> Author: fijal Date: Tue Aug 18 15:52:59 2009 New Revision: 66902 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/model.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Log: (pedronis, arigo, fijal) Kill overflow flag interface on the CPU Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Tue Aug 18 15:52:59 2009 @@ -20,6 +20,7 @@ from pypy.jit.backend.llgraph import symbolic from pypy.rlib.objectmodel import ComputedIntSymbolic +from pypy.rlib.rarithmetic import ovfcheck import py from pypy.tool.ansi_print import ansi_log @@ -574,21 +575,50 @@ return res def op_guard_no_overflow(self, _): - global _overflow_flag - flag = _overflow_flag - assert flag != 'unset' - _overflow_flag = 'unset' + flag = self.overflow_flag + del self.overflow_flag if flag: raise GuardFailed def op_guard_overflow(self, _): - global _overflow_flag - flag = _overflow_flag - assert flag != 'unset' - _overflow_flag = 'unset' + flag = self.overflow_flag + del self.overflow_flag if not flag: raise GuardFailed + def op_int_add_ovf(self, _, x, y): + try: + z = ovfcheck(x + y) + except OverflowError: + ovf = True + z = 0 + else: + ovf = False + self.overflow_flag = ovf + return z + + def op_int_sub_ovf(self, _, x, y): + try: + z = ovfcheck(x - y) + except OverflowError: + ovf = True + z = 0 + else: + ovf = False + self.overflow_flag = ovf + return z + + def op_int_mul_ovf(self, _, x, y): + try: + z = ovfcheck(x * y) + except OverflowError: + ovf = True + z = 0 + else: + ovf = False + self.overflow_flag = ovf + return z + # ---------- # delegating to the builtins do_xxx() (done automatically for simple cases) @@ -927,17 +957,6 @@ return lltype.cast_opaque_ptr(llmemory.GCREF, _get_error(ZeroDivisionError).args[1]) -_overflow_flag = 'unset' - -def get_overflow_flag(): - if _overflow_flag == 'unset': - return False - return _overflow_flag - -def set_overflow_flag(flag): - global _overflow_flag - _overflow_flag = flag - class MemoCast(object): def __init__(self): self.addresses = [llmemory.NULL] @@ -1301,5 +1320,3 @@ setannotation(do_call_int, annmodel.SomeInteger()) setannotation(do_call_ptr, annmodel.SomePtr(llmemory.GCREF)) setannotation(do_call_void, annmodel.s_None) -setannotation(get_overflow_flag, annmodel.s_Bool) -setannotation(set_overflow_flag, annmodel.s_None) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Tue Aug 18 15:52:59 2009 @@ -221,12 +221,6 @@ return (self.cast_adr_to_int(llimpl.get_zero_division_error()), llimpl.get_zero_division_error_value()) - def get_overflow_flag(self): - return llimpl.get_overflow_flag() - - def set_overflow_flag(self, flag): - llimpl.set_overflow_flag(flag) - @staticmethod def sizeof(S): return Descr(symbolic.get_size(S)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Tue Aug 18 15:52:59 2009 @@ -342,6 +342,8 @@ self.backup_exc_type[0] = 0 self.backup_exc_value[0] = lltype.nullptr(llmemory.GCREF.TO) + # XXX wrong, but untested + def set_overflow_error(self): self.backup_exc_type[0] = self._ovf_error_type self.backup_exc_value[0] = self._ovf_error_value @@ -350,14 +352,6 @@ self.backup_exc_type[0] = self._zer_error_type self.backup_exc_value[0] = self._zer_error_value - _overflow_flag = False - - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, flag): - self._overflow_flag = flag - @staticmethod def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/model.py Tue Aug 18 15:52:59 2009 @@ -1,6 +1,4 @@ class AbstractCPU(object): - _overflow_flag = False - def set_class_sizes(self, class_sizes): self.class_sizes = class_sizes @@ -61,12 +59,6 @@ def get_zero_division_error(self): raise NotImplementedError - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, flag): - self._overflow_flag = flag - @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 15:52:59 2009 @@ -154,14 +154,6 @@ self.cast_adr_to_int(self.assembler._zer_error_inst)) return zer_vtable, zer_inst - _overflow_flag = False - - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, flag): - self._overflow_flag = flag - def compile_operations(self, tree, bridge=None): old_loop = tree._x86_compiled if old_loop: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Tue Aug 18 15:52:59 2009 @@ -193,7 +193,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_sub_ovf(cpu, args, descr=None): @@ -206,7 +206,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_mul_ovf(cpu, args, descr=None): @@ -219,7 +219,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Tue Aug 18 15:52:59 2009 @@ -1548,8 +1548,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu.get_overflow_flag(): - self.cpu.set_overflow_flag(False) + if self.cpu._overflow_flag: + self.cpu._overflow_flag = False frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From fijal at codespeak.net Tue Aug 18 15:55:44 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 15:55:44 +0200 (CEST) Subject: [pypy-svn] r66903 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090818135544.C6E3B168030@codespeak.net> Author: fijal Date: Tue Aug 18 15:55:44 2009 New Revision: 66903 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: (pedronis, fijal, arigo) fix the test Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Tue Aug 18 15:55:44 2009 @@ -240,7 +240,6 @@ for x, y, z in testcases: assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() - assert not self.cpu.get_overflow_flag() self.cpu.set_future_value_int(0, x) self.cpu.set_future_value_int(1, y) op = self.cpu.execute_operations(loop) @@ -252,7 +251,6 @@ assert self.cpu.get_latest_value_int(0) == z assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() - assert not self.cpu.get_overflow_flag() def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) From benjamin at codespeak.net Tue Aug 18 15:59:34 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 15:59:34 +0200 (CEST) Subject: [pypy-svn] r66904 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818135934.2E4DD16802B@codespeak.net> Author: benjamin Date: Tue Aug 18 15:59:33 2009 New Revision: 66904 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: use tuples not lists Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 15:59:33 2009 @@ -2846,7 +2846,7 @@ if len(args_w) != 1: w_err = space.wrap("Module constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body'])): + for i, field in unrolling_iterable(enumerate(('body',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -2886,7 +2886,7 @@ if len(args_w) != 1: w_err = space.wrap("Interactive constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body'])): + for i, field in unrolling_iterable(enumerate(('body',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -2918,7 +2918,7 @@ if len(args_w) != 1: w_err = space.wrap("Expression constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body'])): + for i, field in unrolling_iterable(enumerate(('body',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -2958,7 +2958,7 @@ if len(args_w) != 1: w_err = space.wrap("Suite constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body'])): + for i, field in unrolling_iterable(enumerate(('body',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3064,7 +3064,7 @@ if len(args_w) != 6: w_err = space.wrap("FunctionDef constructor takes 0 or 6 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['name', 'args', 'body', 'decorators', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('name', 'args', 'body', 'decorators', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3135,7 +3135,7 @@ if len(args_w) != 5: w_err = space.wrap("ClassDef constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['name', 'bases', 'body', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('name', 'bases', 'body', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3169,7 +3169,7 @@ if len(args_w) != 3: w_err = space.wrap("Return constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3209,7 +3209,7 @@ if len(args_w) != 3: w_err = space.wrap("Delete constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['targets', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('targets', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3259,7 +3259,7 @@ if len(args_w) != 4: w_err = space.wrap("Assign constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['targets', 'value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('targets', 'value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3313,7 +3313,7 @@ if len(args_w) != 5: w_err = space.wrap("AugAssign constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['target', 'op', 'value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('target', 'op', 'value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3375,7 +3375,7 @@ if len(args_w) != 5: w_err = space.wrap("Print constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['dest', 'values', 'nl', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('dest', 'values', 'nl', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3455,7 +3455,7 @@ if len(args_w) != 6: w_err = space.wrap("For constructor takes 0 or 6 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('target', 'iter', 'body', 'orelse', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3526,7 +3526,7 @@ if len(args_w) != 5: w_err = space.wrap("While constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3596,7 +3596,7 @@ if len(args_w) != 5: w_err = space.wrap("If constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3658,7 +3658,7 @@ if len(args_w) != 5: w_err = space.wrap("With constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['context_expr', 'optional_vars', 'body', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('context_expr', 'optional_vars', 'body', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3712,7 +3712,7 @@ if len(args_w) != 5: w_err = space.wrap("Raise constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['type', 'inst', 'tback', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('type', 'inst', 'tback', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3790,7 +3790,7 @@ if len(args_w) != 5: w_err = space.wrap("TryExcept constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body', 'handlers', 'orelse', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('body', 'handlers', 'orelse', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3850,7 +3850,7 @@ if len(args_w) != 4: w_err = space.wrap("TryFinally constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body', 'finalbody', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('body', 'finalbody', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3893,7 +3893,7 @@ if len(args_w) != 4: w_err = space.wrap("Assert constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['test', 'msg', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('test', 'msg', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -3934,7 +3934,7 @@ if len(args_w) != 3: w_err = space.wrap("Import constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['names', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('names', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4000,7 +4000,7 @@ if len(args_w) != 5: w_err = space.wrap("ImportFrom constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['module', 'names', 'level', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('module', 'names', 'level', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4054,7 +4054,7 @@ if len(args_w) != 5: w_err = space.wrap("Exec constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['body', 'globals', 'locals', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('body', 'globals', 'locals', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4096,7 +4096,7 @@ if len(args_w) != 3: w_err = space.wrap("Global constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['names', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('names', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4128,7 +4128,7 @@ if len(args_w) != 3: w_err = space.wrap("Expr constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4150,7 +4150,7 @@ if len(args_w) != 2: w_err = space.wrap("Pass constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4171,7 +4171,7 @@ if len(args_w) != 2: w_err = space.wrap("Break constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4192,7 +4192,7 @@ if len(args_w) != 2: w_err = space.wrap("Continue constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4270,7 +4270,7 @@ if len(args_w) != 4: w_err = space.wrap("BoolOp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['op', 'values', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('op', 'values', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4324,7 +4324,7 @@ if len(args_w) != 5: w_err = space.wrap("BinOp constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['left', 'op', 'right', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('left', 'op', 'right', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4369,7 +4369,7 @@ if len(args_w) != 4: w_err = space.wrap("UnaryOp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['op', 'operand', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('op', 'operand', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4412,7 +4412,7 @@ if len(args_w) != 4: w_err = space.wrap("Lambda constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['args', 'body', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('args', 'body', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4465,7 +4465,7 @@ if len(args_w) != 5: w_err = space.wrap("IfExp constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['test', 'body', 'orelse', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4525,7 +4525,7 @@ if len(args_w) != 4: w_err = space.wrap("Dict constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['keys', 'values', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('keys', 'values', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4576,7 +4576,7 @@ if len(args_w) != 4: w_err = space.wrap("ListComp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['elt', 'generators', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('elt', 'generators', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4627,7 +4627,7 @@ if len(args_w) != 4: w_err = space.wrap("GeneratorExp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['elt', 'generators', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('elt', 'generators', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4660,7 +4660,7 @@ if len(args_w) != 3: w_err = space.wrap("Yield constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4728,7 +4728,7 @@ if len(args_w) != 5: w_err = space.wrap("Compare constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['left', 'ops', 'comparators', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('left', 'ops', 'comparators', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4818,7 +4818,7 @@ if len(args_w) != 7: w_err = space.wrap("Call constructor takes 0 or 7 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['func', 'args', 'keywords', 'starargs', 'kwargs', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('func', 'args', 'keywords', 'starargs', 'kwargs', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4854,7 +4854,7 @@ if len(args_w) != 3: w_err = space.wrap("Repr constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4886,7 +4886,7 @@ if len(args_w) != 3: w_err = space.wrap("Num constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['n', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('n', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4921,7 +4921,7 @@ if len(args_w) != 3: w_err = space.wrap("Str constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['s', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('s', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -4974,7 +4974,7 @@ if len(args_w) != 5: w_err = space.wrap("Attribute constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'attr', 'ctx', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'attr', 'ctx', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5029,7 +5029,7 @@ if len(args_w) != 5: w_err = space.wrap("Subscript constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'slice', 'ctx', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'slice', 'ctx', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5074,7 +5074,7 @@ if len(args_w) != 4: w_err = space.wrap("Name constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['id', 'ctx', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('id', 'ctx', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5126,7 +5126,7 @@ if len(args_w) != 4: w_err = space.wrap("List constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['elts', 'ctx', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('elts', 'ctx', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5178,7 +5178,7 @@ if len(args_w) != 4: w_err = space.wrap("Tuple constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['elts', 'ctx', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('elts', 'ctx', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5211,7 +5211,7 @@ if len(args_w) != 3: w_err = space.wrap("Const constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5335,7 +5335,7 @@ if len(args_w) != 3: w_err = space.wrap("Slice constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['lower', 'upper', 'step'])): + for i, field in unrolling_iterable(enumerate(('lower', 'upper', 'step',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5377,7 +5377,7 @@ if len(args_w) != 1: w_err = space.wrap("ExtSlice constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['dims'])): + for i, field in unrolling_iterable(enumerate(('dims',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5409,7 +5409,7 @@ if len(args_w) != 1: w_err = space.wrap("Index constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['value'])): + for i, field in unrolling_iterable(enumerate(('value',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5689,7 +5689,7 @@ if len(args_w) != 3: w_err = space.wrap("comprehension constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['target', 'iter', 'ifs'])): + for i, field in unrolling_iterable(enumerate(('target', 'iter', 'ifs',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5771,7 +5771,7 @@ if len(args_w) != 5: w_err = space.wrap("excepthandler constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['type', 'name', 'body', 'lineno', 'col_offset'])): + for i, field in unrolling_iterable(enumerate(('type', 'name', 'body', 'lineno', 'col_offset',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5859,7 +5859,7 @@ if len(args_w) != 4: w_err = space.wrap("arguments constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['args', 'vararg', 'kwarg', 'defaults'])): + for i, field in unrolling_iterable(enumerate(('args', 'vararg', 'kwarg', 'defaults',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5904,7 +5904,7 @@ if len(args_w) != 2: w_err = space.wrap("keyword constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['arg', 'value'])): + for i, field in unrolling_iterable(enumerate(('arg', 'value',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) @@ -5950,7 +5950,7 @@ if len(args_w) != 2: w_err = space.wrap("alias constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(['name', 'asname'])): + for i, field in unrolling_iterable(enumerate(('name', 'asname',))): space.setattr(w_self, space.wrap(field), args_w[i]) for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 15:59:33 2009 @@ -382,7 +382,7 @@ self.emit("w_err = space.wrap(\"%s constructor takes 0 or %i " \ "positional arguments\")" % (name, arity), 3) self.emit("raise OperationError(space.w_TypeError, w_err)", 3) - self.emit("for i, field in unrolling_iterable(enumerate([%s])):" % + self.emit("for i, field in unrolling_iterable(enumerate((%s,))):" % (comma_fields,), 2) self.emit("space.setattr(w_self, space.wrap(field), args_w[i])", 3) else: From fijal at codespeak.net Tue Aug 18 15:59:48 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 15:59:48 +0200 (CEST) Subject: [pypy-svn] r66905 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090818135948.9AC9D16802B@codespeak.net> Author: fijal Date: Tue Aug 18 15:59:48 2009 New Revision: 66905 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Log: (pedronis, arigo, fijal) Fix test_random Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Tue Aug 18 15:59:48 2009 @@ -236,8 +236,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu.get_overflow_flag(): # overflow detected - builder.cpu.set_overflow_flag(False) + if builder.cpu._overflow_flag: # overflow detected + del builder.cpu._overflow_flag op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including From benjamin at codespeak.net Tue Aug 18 16:06:24 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:06:24 +0200 (CEST) Subject: [pypy-svn] r66906 - pypy/branch/parser-compiler/pypy/module/__builtin__ Message-ID: <20090818140624.C9FB9168030@codespeak.net> Author: benjamin Date: Tue Aug 18 16:06:24 2009 New Revision: 66906 Modified: pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py Log: help annotator Modified: pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py Tue Aug 18 16:06:24 2009 @@ -24,6 +24,7 @@ ast_node = None w_ast_type = space.gettypeobject(ast.AST.typedef) + str_ = None if space.is_true(space.isinstance(w_source, w_ast_type)): ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) From benjamin at codespeak.net Tue Aug 18 16:14:47 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:14:47 +0200 (CEST) Subject: [pypy-svn] r66907 - pypy/branch/parser-compiler/pypy/module/parser Message-ID: <20090818141447.2E02E168031@codespeak.net> Author: benjamin Date: Tue Aug 18 16:14:45 2009 New Revision: 66907 Modified: pypy/branch/parser-compiler/pypy/module/parser/pyparser.py Log: fix tests Modified: pypy/branch/parser-compiler/pypy/module/parser/pyparser.py ============================================================================== --- pypy/branch/parser-compiler/pypy/module/parser/pyparser.py (original) +++ pypy/branch/parser-compiler/pypy/module/parser/pyparser.py Tue Aug 18 16:14:45 2009 @@ -74,10 +74,10 @@ tree = parser.parse_source(source, info) except error.IndentationError, e: raise OperationError(space.w_IndentationError, - e.wrap_info(space, "")) + e.wrap_info(space)) except error.SyntaxError, e: raise OperationError(space.w_SyntaxError, - e.wrap_info(space, "")) + e.wrap_info(space)) return space.wrap(STType(tree, mode)) From fijal at codespeak.net Tue Aug 18 16:23:41 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 16:23:41 +0200 (CEST) Subject: [pypy-svn] r66908 - in pypy/branch/pyjitpl5/pypy/jit/backend: test x86 Message-ID: <20090818142341.2CF28168028@codespeak.net> Author: fijal Date: Tue Aug 18 16:23:40 2009 New Revision: 66908 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: (pedronis, fijal) * Add a real test for sort_key * Remove dead code Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Tue Aug 18 16:23:40 2009 @@ -797,6 +797,14 @@ assert isinstance(z, BoxPtr) assert z.value == x.value + def test_sorting_of_fields(self): + S = self.S + value = self.cpu.fielddescrof(S, 'value').sort_key() + chr1 = self.cpu.fielddescrof(S, 'chr1').sort_key() + chr2 = self.cpu.fielddescrof(S, 'chr2').sort_key() + assert (sorted([chr2, chr1, value]) == + [value, chr1, chr2]) + assert len(dict.fromkeys([value, chr1, chr2]).keys()) == 3 class OOtypeBackendTest(BaseBackendTest): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 16:23:40 2009 @@ -27,15 +27,6 @@ self.v1 = v1 self.flag2 = flag2 - def _v(self): - l = [] - for i in (self.v0, self.v1, self.flag2): - if isinstance(i, Symbolic): - l.append(id(i)) - else: - l.append(i) - return tuple(l) - def sort_key(self): return self.v0 # the ofs field for fielddescrs @@ -45,15 +36,9 @@ def is_array_of_pointers(self): return self.flag2 # for arraydescrs - def equals(self, other): - if not isinstance(other, ConstDescr3): - return False - return self.sort_key() == other.sort_key() - def __repr__(self): return '' % (self.v0, self.v1, self.flag2) - def _check_addr_range(x): if sys.platform == 'linux2': # this makes assumption about address ranges that are valid @@ -561,7 +546,9 @@ pass ofs, size = symbolic.get_field_token(S, fieldname, self.translate_support_code) - assert rffi.sizeof(getattr(S, fieldname)) in [1, 2, WORD] + exp_size = rffi.sizeof(getattr(S, fieldname)) + if type(exp_size) is int: + assert exp_size in [1, 2, WORD] if (isinstance(getattr(S, fieldname), lltype.Ptr) and getattr(S, fieldname).TO._gckind == 'gc'): ptr = True From benjamin at codespeak.net Tue Aug 18 16:27:32 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:27:32 +0200 (CEST) Subject: [pypy-svn] r66909 - in pypy/branch/parser-compiler/pypy: interpreter interpreter/astcompiler module/_ast/test Message-ID: <20090818142732.CBCBB16802E@codespeak.net> Author: benjamin Date: Tue Aug 18 16:27:31 2009 New Revision: 66909 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Log: fix __future__ when compiling from AST Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Tue Aug 18 16:27:31 2009 @@ -27,6 +27,27 @@ _emit_syntax_warning(space, w_msg, w_filename, w_lineno, w_offset) +def parse_future(tree): + future_lineno = 0 + future_column = 0 + if isinstance(tree, ast.Module) or isinstance(tree, ast.Interactive): + for stmt in tree.body: + if isinstance(stmt, ast.Str): + if have_docstring: + break + else: + have_docstring = True + elif isinstance(stmt, ast.ImportFrom): + if stmt.module == "__future__": + future_lineno = stmt.lineno + future_column = stmt.col_offset + else: + break + else: + break + return future_lineno, future_column + + class ForbiddenNameAssignment(Exception): def __init__(self, name, node): Modified: pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py Tue Aug 18 16:27:31 2009 @@ -225,7 +225,8 @@ def compile_ast(self, node, filename, mode, flags): from pypy.interpreter.pyparser.pyparse import CompileInfo - info = CompileInfo(filename, mode, flags) + from pypy.interpreter.astcompiler.misc import parse_future + info = CompileInfo(filename, mode, flags, parse_future(node)) return self._compile_ast(node, info) def _compile_ast(self, node, info): Modified: pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py (original) +++ pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Tue Aug 18 16:27:31 2009 @@ -156,6 +156,8 @@ raises(AttributeError, ast.Module, nothing=23) def test_future(self): - skip("have to write an AST future parser") mod = self.get_ast("from __future__ import with_statement") compile(mod, "", "exec") + mod = self.get_ast("from __future__ import with_statement; import y; " \ + "from __future__ import nested_scopes") + raises(SyntaxError, compile, mod, "", "exec") From benjamin at codespeak.net Tue Aug 18 16:33:54 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:33:54 +0200 (CEST) Subject: [pypy-svn] r66910 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818143354.3132D16802E@codespeak.net> Author: benjamin Date: Tue Aug 18 16:33:53 2009 New Revision: 66910 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: make the field unroller static Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 16:33:53 2009 @@ -2838,6 +2838,7 @@ w_self.w_body = w_new_value w_self.initialization_state |= 1 +_Module_field_unroller = unrolling_iterable(['body']) def Module_init(space, w_self, args): w_self = space.descr_self_interp_w(Module, w_self) w_self.w_body = None @@ -2846,8 +2847,10 @@ if len(args_w) != 1: w_err = space.wrap("Module constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body',))): + i = 0 + for field in _Module_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Module_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -2878,6 +2881,7 @@ w_self.w_body = w_new_value w_self.initialization_state |= 1 +_Interactive_field_unroller = unrolling_iterable(['body']) def Interactive_init(space, w_self, args): w_self = space.descr_self_interp_w(Interactive, w_self) w_self.w_body = None @@ -2886,8 +2890,10 @@ if len(args_w) != 1: w_err = space.wrap("Interactive constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body',))): + i = 0 + for field in _Interactive_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Interactive_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -2911,6 +2917,7 @@ w_self.body = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 1 +_Expression_field_unroller = unrolling_iterable(['body']) def Expression_init(space, w_self, args): w_self = space.descr_self_interp_w(Expression, w_self) args_w, kwargs_w = args.unpack() @@ -2918,8 +2925,10 @@ if len(args_w) != 1: w_err = space.wrap("Expression constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body',))): + i = 0 + for field in _Expression_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Expression_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -2950,6 +2959,7 @@ w_self.w_body = w_new_value w_self.initialization_state |= 1 +_Suite_field_unroller = unrolling_iterable(['body']) def Suite_init(space, w_self, args): w_self = space.descr_self_interp_w(Suite, w_self) w_self.w_body = None @@ -2958,8 +2968,10 @@ if len(args_w) != 1: w_err = space.wrap("Suite constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body',))): + i = 0 + for field in _Suite_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Suite_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3055,6 +3067,7 @@ w_self.w_decorators = w_new_value w_self.initialization_state |= 8 +_FunctionDef_field_unroller = unrolling_iterable(['name', 'args', 'body', 'decorators', 'lineno', 'col_offset']) def FunctionDef_init(space, w_self, args): w_self = space.descr_self_interp_w(FunctionDef, w_self) w_self.w_body = None @@ -3064,8 +3077,10 @@ if len(args_w) != 6: w_err = space.wrap("FunctionDef constructor takes 0 or 6 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('name', 'args', 'body', 'decorators', 'lineno', 'col_offset',))): + i = 0 + for field in _FunctionDef_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) FunctionDef_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3126,6 +3141,7 @@ w_self.w_body = w_new_value w_self.initialization_state |= 4 +_ClassDef_field_unroller = unrolling_iterable(['name', 'bases', 'body', 'lineno', 'col_offset']) def ClassDef_init(space, w_self, args): w_self = space.descr_self_interp_w(ClassDef, w_self) w_self.w_bases = None @@ -3135,8 +3151,10 @@ if len(args_w) != 5: w_err = space.wrap("ClassDef constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('name', 'bases', 'body', 'lineno', 'col_offset',))): + i = 0 + for field in _ClassDef_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) ClassDef_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3162,6 +3180,7 @@ w_self.value = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 1 +_Return_field_unroller = unrolling_iterable(['value', 'lineno', 'col_offset']) def Return_init(space, w_self, args): w_self = space.descr_self_interp_w(Return, w_self) args_w, kwargs_w = args.unpack() @@ -3169,8 +3188,10 @@ if len(args_w) != 3: w_err = space.wrap("Return constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): + i = 0 + for field in _Return_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Return_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3201,6 +3222,7 @@ w_self.w_targets = w_new_value w_self.initialization_state |= 1 +_Delete_field_unroller = unrolling_iterable(['targets', 'lineno', 'col_offset']) def Delete_init(space, w_self, args): w_self = space.descr_self_interp_w(Delete, w_self) w_self.w_targets = None @@ -3209,8 +3231,10 @@ if len(args_w) != 3: w_err = space.wrap("Delete constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('targets', 'lineno', 'col_offset',))): + i = 0 + for field in _Delete_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Delete_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3251,6 +3275,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 2 +_Assign_field_unroller = unrolling_iterable(['targets', 'value', 'lineno', 'col_offset']) def Assign_init(space, w_self, args): w_self = space.descr_self_interp_w(Assign, w_self) w_self.w_targets = None @@ -3259,8 +3284,10 @@ if len(args_w) != 4: w_err = space.wrap("Assign constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('targets', 'value', 'lineno', 'col_offset',))): + i = 0 + for field in _Assign_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Assign_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3306,6 +3333,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 4 +_AugAssign_field_unroller = unrolling_iterable(['target', 'op', 'value', 'lineno', 'col_offset']) def AugAssign_init(space, w_self, args): w_self = space.descr_self_interp_w(AugAssign, w_self) args_w, kwargs_w = args.unpack() @@ -3313,8 +3341,10 @@ if len(args_w) != 5: w_err = space.wrap("AugAssign constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('target', 'op', 'value', 'lineno', 'col_offset',))): + i = 0 + for field in _AugAssign_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) AugAssign_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3367,6 +3397,7 @@ w_self.nl = space.bool_w(w_new_value) w_self.initialization_state |= 4 +_Print_field_unroller = unrolling_iterable(['dest', 'values', 'nl', 'lineno', 'col_offset']) def Print_init(space, w_self, args): w_self = space.descr_self_interp_w(Print, w_self) w_self.w_values = None @@ -3375,8 +3406,10 @@ if len(args_w) != 5: w_err = space.wrap("Print constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('dest', 'values', 'nl', 'lineno', 'col_offset',))): + i = 0 + for field in _Print_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Print_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3446,6 +3479,7 @@ w_self.w_orelse = w_new_value w_self.initialization_state |= 8 +_For_field_unroller = unrolling_iterable(['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset']) def For_init(space, w_self, args): w_self = space.descr_self_interp_w(For, w_self) w_self.w_body = None @@ -3455,8 +3489,10 @@ if len(args_w) != 6: w_err = space.wrap("For constructor takes 0 or 6 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('target', 'iter', 'body', 'orelse', 'lineno', 'col_offset',))): + i = 0 + for field in _For_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) For_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3517,6 +3553,7 @@ w_self.w_orelse = w_new_value w_self.initialization_state |= 4 +_While_field_unroller = unrolling_iterable(['test', 'body', 'orelse', 'lineno', 'col_offset']) def While_init(space, w_self, args): w_self = space.descr_self_interp_w(While, w_self) w_self.w_body = None @@ -3526,8 +3563,10 @@ if len(args_w) != 5: w_err = space.wrap("While constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): + i = 0 + for field in _While_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) While_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3587,6 +3626,7 @@ w_self.w_orelse = w_new_value w_self.initialization_state |= 4 +_If_field_unroller = unrolling_iterable(['test', 'body', 'orelse', 'lineno', 'col_offset']) def If_init(space, w_self, args): w_self = space.descr_self_interp_w(If, w_self) w_self.w_body = None @@ -3596,8 +3636,10 @@ if len(args_w) != 5: w_err = space.wrap("If constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): + i = 0 + for field in _If_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) If_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3650,6 +3692,7 @@ w_self.w_body = w_new_value w_self.initialization_state |= 4 +_With_field_unroller = unrolling_iterable(['context_expr', 'optional_vars', 'body', 'lineno', 'col_offset']) def With_init(space, w_self, args): w_self = space.descr_self_interp_w(With, w_self) w_self.w_body = None @@ -3658,8 +3701,10 @@ if len(args_w) != 5: w_err = space.wrap("With constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('context_expr', 'optional_vars', 'body', 'lineno', 'col_offset',))): + i = 0 + for field in _With_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) With_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3705,6 +3750,7 @@ w_self.tback = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 4 +_Raise_field_unroller = unrolling_iterable(['type', 'inst', 'tback', 'lineno', 'col_offset']) def Raise_init(space, w_self, args): w_self = space.descr_self_interp_w(Raise, w_self) args_w, kwargs_w = args.unpack() @@ -3712,8 +3758,10 @@ if len(args_w) != 5: w_err = space.wrap("Raise constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('type', 'inst', 'tback', 'lineno', 'col_offset',))): + i = 0 + for field in _Raise_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Raise_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3780,6 +3828,7 @@ w_self.w_orelse = w_new_value w_self.initialization_state |= 4 +_TryExcept_field_unroller = unrolling_iterable(['body', 'handlers', 'orelse', 'lineno', 'col_offset']) def TryExcept_init(space, w_self, args): w_self = space.descr_self_interp_w(TryExcept, w_self) w_self.w_body = None @@ -3790,8 +3839,10 @@ if len(args_w) != 5: w_err = space.wrap("TryExcept constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body', 'handlers', 'orelse', 'lineno', 'col_offset',))): + i = 0 + for field in _TryExcept_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) TryExcept_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3841,6 +3892,7 @@ w_self.w_finalbody = w_new_value w_self.initialization_state |= 2 +_TryFinally_field_unroller = unrolling_iterable(['body', 'finalbody', 'lineno', 'col_offset']) def TryFinally_init(space, w_self, args): w_self = space.descr_self_interp_w(TryFinally, w_self) w_self.w_body = None @@ -3850,8 +3902,10 @@ if len(args_w) != 4: w_err = space.wrap("TryFinally constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body', 'finalbody', 'lineno', 'col_offset',))): + i = 0 + for field in _TryFinally_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) TryFinally_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3886,6 +3940,7 @@ w_self.msg = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 2 +_Assert_field_unroller = unrolling_iterable(['test', 'msg', 'lineno', 'col_offset']) def Assert_init(space, w_self, args): w_self = space.descr_self_interp_w(Assert, w_self) args_w, kwargs_w = args.unpack() @@ -3893,8 +3948,10 @@ if len(args_w) != 4: w_err = space.wrap("Assert constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('test', 'msg', 'lineno', 'col_offset',))): + i = 0 + for field in _Assert_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Assert_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3926,6 +3983,7 @@ w_self.w_names = w_new_value w_self.initialization_state |= 1 +_Import_field_unroller = unrolling_iterable(['names', 'lineno', 'col_offset']) def Import_init(space, w_self, args): w_self = space.descr_self_interp_w(Import, w_self) w_self.w_names = None @@ -3934,8 +3992,10 @@ if len(args_w) != 3: w_err = space.wrap("Import constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('names', 'lineno', 'col_offset',))): + i = 0 + for field in _Import_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Import_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -3992,6 +4052,7 @@ w_self.level = space.int_w(w_new_value) w_self.initialization_state |= 4 +_ImportFrom_field_unroller = unrolling_iterable(['module', 'names', 'level', 'lineno', 'col_offset']) def ImportFrom_init(space, w_self, args): w_self = space.descr_self_interp_w(ImportFrom, w_self) w_self.w_names = None @@ -4000,8 +4061,10 @@ if len(args_w) != 5: w_err = space.wrap("ImportFrom constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('module', 'names', 'level', 'lineno', 'col_offset',))): + i = 0 + for field in _ImportFrom_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) ImportFrom_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4047,6 +4110,7 @@ w_self.locals = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 4 +_Exec_field_unroller = unrolling_iterable(['body', 'globals', 'locals', 'lineno', 'col_offset']) def Exec_init(space, w_self, args): w_self = space.descr_self_interp_w(Exec, w_self) args_w, kwargs_w = args.unpack() @@ -4054,8 +4118,10 @@ if len(args_w) != 5: w_err = space.wrap("Exec constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('body', 'globals', 'locals', 'lineno', 'col_offset',))): + i = 0 + for field in _Exec_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Exec_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4088,6 +4154,7 @@ w_self.w_names = w_new_value w_self.initialization_state |= 1 +_Global_field_unroller = unrolling_iterable(['names', 'lineno', 'col_offset']) def Global_init(space, w_self, args): w_self = space.descr_self_interp_w(Global, w_self) w_self.w_names = None @@ -4096,8 +4163,10 @@ if len(args_w) != 3: w_err = space.wrap("Global constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('names', 'lineno', 'col_offset',))): + i = 0 + for field in _Global_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Global_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4121,6 +4190,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 1 +_Expr_field_unroller = unrolling_iterable(['value', 'lineno', 'col_offset']) def Expr_init(space, w_self, args): w_self = space.descr_self_interp_w(Expr, w_self) args_w, kwargs_w = args.unpack() @@ -4128,8 +4198,10 @@ if len(args_w) != 3: w_err = space.wrap("Expr constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): + i = 0 + for field in _Expr_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Expr_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4143,6 +4215,7 @@ ) Expr.typedef.acceptable_as_base_class = False +_Pass_field_unroller = unrolling_iterable(['lineno', 'col_offset']) def Pass_init(space, w_self, args): w_self = space.descr_self_interp_w(Pass, w_self) args_w, kwargs_w = args.unpack() @@ -4150,8 +4223,10 @@ if len(args_w) != 2: w_err = space.wrap("Pass constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): + i = 0 + for field in _Pass_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Pass_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4164,6 +4239,7 @@ ) Pass.typedef.acceptable_as_base_class = False +_Break_field_unroller = unrolling_iterable(['lineno', 'col_offset']) def Break_init(space, w_self, args): w_self = space.descr_self_interp_w(Break, w_self) args_w, kwargs_w = args.unpack() @@ -4171,8 +4247,10 @@ if len(args_w) != 2: w_err = space.wrap("Break constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): + i = 0 + for field in _Break_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Break_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4185,6 +4263,7 @@ ) Break.typedef.acceptable_as_base_class = False +_Continue_field_unroller = unrolling_iterable(['lineno', 'col_offset']) def Continue_init(space, w_self, args): w_self = space.descr_self_interp_w(Continue, w_self) args_w, kwargs_w = args.unpack() @@ -4192,8 +4271,10 @@ if len(args_w) != 2: w_err = space.wrap("Continue constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('lineno', 'col_offset',))): + i = 0 + for field in _Continue_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Continue_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4262,6 +4343,7 @@ w_self.w_values = w_new_value w_self.initialization_state |= 2 +_BoolOp_field_unroller = unrolling_iterable(['op', 'values', 'lineno', 'col_offset']) def BoolOp_init(space, w_self, args): w_self = space.descr_self_interp_w(BoolOp, w_self) w_self.w_values = None @@ -4270,8 +4352,10 @@ if len(args_w) != 4: w_err = space.wrap("BoolOp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('op', 'values', 'lineno', 'col_offset',))): + i = 0 + for field in _BoolOp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) BoolOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4317,6 +4401,7 @@ w_self.right = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 4 +_BinOp_field_unroller = unrolling_iterable(['left', 'op', 'right', 'lineno', 'col_offset']) def BinOp_init(space, w_self, args): w_self = space.descr_self_interp_w(BinOp, w_self) args_w, kwargs_w = args.unpack() @@ -4324,8 +4409,10 @@ if len(args_w) != 5: w_err = space.wrap("BinOp constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('left', 'op', 'right', 'lineno', 'col_offset',))): + i = 0 + for field in _BinOp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) BinOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4362,6 +4449,7 @@ w_self.operand = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 2 +_UnaryOp_field_unroller = unrolling_iterable(['op', 'operand', 'lineno', 'col_offset']) def UnaryOp_init(space, w_self, args): w_self = space.descr_self_interp_w(UnaryOp, w_self) args_w, kwargs_w = args.unpack() @@ -4369,8 +4457,10 @@ if len(args_w) != 4: w_err = space.wrap("UnaryOp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('op', 'operand', 'lineno', 'col_offset',))): + i = 0 + for field in _UnaryOp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) UnaryOp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4405,6 +4495,7 @@ w_self.body = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 2 +_Lambda_field_unroller = unrolling_iterable(['args', 'body', 'lineno', 'col_offset']) def Lambda_init(space, w_self, args): w_self = space.descr_self_interp_w(Lambda, w_self) args_w, kwargs_w = args.unpack() @@ -4412,8 +4503,10 @@ if len(args_w) != 4: w_err = space.wrap("Lambda constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('args', 'body', 'lineno', 'col_offset',))): + i = 0 + for field in _Lambda_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Lambda_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4458,6 +4551,7 @@ w_self.orelse = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 4 +_IfExp_field_unroller = unrolling_iterable(['test', 'body', 'orelse', 'lineno', 'col_offset']) def IfExp_init(space, w_self, args): w_self = space.descr_self_interp_w(IfExp, w_self) args_w, kwargs_w = args.unpack() @@ -4465,8 +4559,10 @@ if len(args_w) != 5: w_err = space.wrap("IfExp constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('test', 'body', 'orelse', 'lineno', 'col_offset',))): + i = 0 + for field in _IfExp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) IfExp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4516,6 +4612,7 @@ w_self.w_values = w_new_value w_self.initialization_state |= 2 +_Dict_field_unroller = unrolling_iterable(['keys', 'values', 'lineno', 'col_offset']) def Dict_init(space, w_self, args): w_self = space.descr_self_interp_w(Dict, w_self) w_self.w_keys = None @@ -4525,8 +4622,10 @@ if len(args_w) != 4: w_err = space.wrap("Dict constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('keys', 'values', 'lineno', 'col_offset',))): + i = 0 + for field in _Dict_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Dict_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4568,6 +4667,7 @@ w_self.w_generators = w_new_value w_self.initialization_state |= 2 +_ListComp_field_unroller = unrolling_iterable(['elt', 'generators', 'lineno', 'col_offset']) def ListComp_init(space, w_self, args): w_self = space.descr_self_interp_w(ListComp, w_self) w_self.w_generators = None @@ -4576,8 +4676,10 @@ if len(args_w) != 4: w_err = space.wrap("ListComp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('elt', 'generators', 'lineno', 'col_offset',))): + i = 0 + for field in _ListComp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) ListComp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4619,6 +4721,7 @@ w_self.w_generators = w_new_value w_self.initialization_state |= 2 +_GeneratorExp_field_unroller = unrolling_iterable(['elt', 'generators', 'lineno', 'col_offset']) def GeneratorExp_init(space, w_self, args): w_self = space.descr_self_interp_w(GeneratorExp, w_self) w_self.w_generators = None @@ -4627,8 +4730,10 @@ if len(args_w) != 4: w_err = space.wrap("GeneratorExp constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('elt', 'generators', 'lineno', 'col_offset',))): + i = 0 + for field in _GeneratorExp_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) GeneratorExp_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4653,6 +4758,7 @@ w_self.value = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 1 +_Yield_field_unroller = unrolling_iterable(['value', 'lineno', 'col_offset']) def Yield_init(space, w_self, args): w_self = space.descr_self_interp_w(Yield, w_self) args_w, kwargs_w = args.unpack() @@ -4660,8 +4766,10 @@ if len(args_w) != 3: w_err = space.wrap("Yield constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): + i = 0 + for field in _Yield_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Yield_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4719,6 +4827,7 @@ w_self.w_comparators = w_new_value w_self.initialization_state |= 4 +_Compare_field_unroller = unrolling_iterable(['left', 'ops', 'comparators', 'lineno', 'col_offset']) def Compare_init(space, w_self, args): w_self = space.descr_self_interp_w(Compare, w_self) w_self.w_ops = None @@ -4728,8 +4837,10 @@ if len(args_w) != 5: w_err = space.wrap("Compare constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('left', 'ops', 'comparators', 'lineno', 'col_offset',))): + i = 0 + for field in _Compare_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Compare_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4809,6 +4920,7 @@ w_self.kwargs = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 16 +_Call_field_unroller = unrolling_iterable(['func', 'args', 'keywords', 'starargs', 'kwargs', 'lineno', 'col_offset']) def Call_init(space, w_self, args): w_self = space.descr_self_interp_w(Call, w_self) w_self.w_args = None @@ -4818,8 +4930,10 @@ if len(args_w) != 7: w_err = space.wrap("Call constructor takes 0 or 7 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('func', 'args', 'keywords', 'starargs', 'kwargs', 'lineno', 'col_offset',))): + i = 0 + for field in _Call_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Call_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4847,6 +4961,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 1 +_Repr_field_unroller = unrolling_iterable(['value', 'lineno', 'col_offset']) def Repr_init(space, w_self, args): w_self = space.descr_self_interp_w(Repr, w_self) args_w, kwargs_w = args.unpack() @@ -4854,8 +4969,10 @@ if len(args_w) != 3: w_err = space.wrap("Repr constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): + i = 0 + for field in _Repr_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Repr_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4879,6 +4996,7 @@ w_self.n = w_new_value w_self.initialization_state |= 1 +_Num_field_unroller = unrolling_iterable(['n', 'lineno', 'col_offset']) def Num_init(space, w_self, args): w_self = space.descr_self_interp_w(Num, w_self) args_w, kwargs_w = args.unpack() @@ -4886,8 +5004,10 @@ if len(args_w) != 3: w_err = space.wrap("Num constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('n', 'lineno', 'col_offset',))): + i = 0 + for field in _Num_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Num_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4914,6 +5034,7 @@ w_self.s = w_new_value w_self.initialization_state |= 1 +_Str_field_unroller = unrolling_iterable(['s', 'lineno', 'col_offset']) def Str_init(space, w_self, args): w_self = space.descr_self_interp_w(Str, w_self) args_w, kwargs_w = args.unpack() @@ -4921,8 +5042,10 @@ if len(args_w) != 3: w_err = space.wrap("Str constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('s', 'lineno', 'col_offset',))): + i = 0 + for field in _Str_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Str_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -4967,6 +5090,7 @@ w_self.ctx = obj.to_simple_int() w_self.initialization_state |= 4 +_Attribute_field_unroller = unrolling_iterable(['value', 'attr', 'ctx', 'lineno', 'col_offset']) def Attribute_init(space, w_self, args): w_self = space.descr_self_interp_w(Attribute, w_self) args_w, kwargs_w = args.unpack() @@ -4974,8 +5098,10 @@ if len(args_w) != 5: w_err = space.wrap("Attribute constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'attr', 'ctx', 'lineno', 'col_offset',))): + i = 0 + for field in _Attribute_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Attribute_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5022,6 +5148,7 @@ w_self.ctx = obj.to_simple_int() w_self.initialization_state |= 4 +_Subscript_field_unroller = unrolling_iterable(['value', 'slice', 'ctx', 'lineno', 'col_offset']) def Subscript_init(space, w_self, args): w_self = space.descr_self_interp_w(Subscript, w_self) args_w, kwargs_w = args.unpack() @@ -5029,8 +5156,10 @@ if len(args_w) != 5: w_err = space.wrap("Subscript constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'slice', 'ctx', 'lineno', 'col_offset',))): + i = 0 + for field in _Subscript_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Subscript_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5067,6 +5196,7 @@ w_self.ctx = obj.to_simple_int() w_self.initialization_state |= 2 +_Name_field_unroller = unrolling_iterable(['id', 'ctx', 'lineno', 'col_offset']) def Name_init(space, w_self, args): w_self = space.descr_self_interp_w(Name, w_self) args_w, kwargs_w = args.unpack() @@ -5074,8 +5204,10 @@ if len(args_w) != 4: w_err = space.wrap("Name constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('id', 'ctx', 'lineno', 'col_offset',))): + i = 0 + for field in _Name_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Name_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5118,6 +5250,7 @@ w_self.ctx = obj.to_simple_int() w_self.initialization_state |= 2 +_List_field_unroller = unrolling_iterable(['elts', 'ctx', 'lineno', 'col_offset']) def List_init(space, w_self, args): w_self = space.descr_self_interp_w(List, w_self) w_self.w_elts = None @@ -5126,8 +5259,10 @@ if len(args_w) != 4: w_err = space.wrap("List constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('elts', 'ctx', 'lineno', 'col_offset',))): + i = 0 + for field in _List_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) List_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5170,6 +5305,7 @@ w_self.ctx = obj.to_simple_int() w_self.initialization_state |= 2 +_Tuple_field_unroller = unrolling_iterable(['elts', 'ctx', 'lineno', 'col_offset']) def Tuple_init(space, w_self, args): w_self = space.descr_self_interp_w(Tuple, w_self) w_self.w_elts = None @@ -5178,8 +5314,10 @@ if len(args_w) != 4: w_err = space.wrap("Tuple constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('elts', 'ctx', 'lineno', 'col_offset',))): + i = 0 + for field in _Tuple_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Tuple_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5204,6 +5342,7 @@ w_self.value = w_new_value w_self.initialization_state |= 1 +_Const_field_unroller = unrolling_iterable(['value', 'lineno', 'col_offset']) def Const_init(space, w_self, args): w_self = space.descr_self_interp_w(Const, w_self) args_w, kwargs_w = args.unpack() @@ -5211,8 +5350,10 @@ if len(args_w) != 3: w_err = space.wrap("Const constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value', 'lineno', 'col_offset',))): + i = 0 + for field in _Const_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Const_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5280,6 +5421,7 @@ ) slice.typedef.acceptable_as_base_class = False +_Ellipsis_field_unroller = unrolling_iterable([]) def Ellipsis_init(space, w_self, args): w_self = space.descr_self_interp_w(Ellipsis, w_self) args_w, kwargs_w = args.unpack() @@ -5328,6 +5470,7 @@ w_self.step = space.interp_w(expr, w_new_value, True) w_self.initialization_state |= 4 +_Slice_field_unroller = unrolling_iterable(['lower', 'upper', 'step']) def Slice_init(space, w_self, args): w_self = space.descr_self_interp_w(Slice, w_self) args_w, kwargs_w = args.unpack() @@ -5335,8 +5478,10 @@ if len(args_w) != 3: w_err = space.wrap("Slice constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('lower', 'upper', 'step',))): + i = 0 + for field in _Slice_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Slice_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5369,6 +5514,7 @@ w_self.w_dims = w_new_value w_self.initialization_state |= 1 +_ExtSlice_field_unroller = unrolling_iterable(['dims']) def ExtSlice_init(space, w_self, args): w_self = space.descr_self_interp_w(ExtSlice, w_self) w_self.w_dims = None @@ -5377,8 +5523,10 @@ if len(args_w) != 1: w_err = space.wrap("ExtSlice constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('dims',))): + i = 0 + for field in _ExtSlice_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) ExtSlice_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5402,6 +5550,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 1 +_Index_field_unroller = unrolling_iterable(['value']) def Index_init(space, w_self, args): w_self = space.descr_self_interp_w(Index, w_self) args_w, kwargs_w = args.unpack() @@ -5409,8 +5558,10 @@ if len(args_w) != 1: w_err = space.wrap("Index constructor takes 0 or 1 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('value',))): + i = 0 + for field in _Index_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) Index_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5681,6 +5832,7 @@ w_self.w_ifs = w_new_value w_self.initialization_state |= 4 +_comprehension_field_unroller = unrolling_iterable(['target', 'iter', 'ifs']) def comprehension_init(space, w_self, args): w_self = space.descr_self_interp_w(comprehension, w_self) w_self.w_ifs = None @@ -5689,8 +5841,10 @@ if len(args_w) != 3: w_err = space.wrap("comprehension constructor takes 0 or 3 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('target', 'iter', 'ifs',))): + i = 0 + for field in _comprehension_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) comprehension_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5763,6 +5917,7 @@ w_self.col_offset = space.int_w(w_new_value) w_self.initialization_state |= 16 +_excepthandler_field_unroller = unrolling_iterable(['type', 'name', 'body', 'lineno', 'col_offset']) def excepthandler_init(space, w_self, args): w_self = space.descr_self_interp_w(excepthandler, w_self) w_self.w_body = None @@ -5771,8 +5926,10 @@ if len(args_w) != 5: w_err = space.wrap("excepthandler constructor takes 0 or 5 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('type', 'name', 'body', 'lineno', 'col_offset',))): + i = 0 + for field in _excepthandler_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) excepthandler_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5850,6 +6007,7 @@ w_self.w_defaults = w_new_value w_self.initialization_state |= 8 +_arguments_field_unroller = unrolling_iterable(['args', 'vararg', 'kwarg', 'defaults']) def arguments_init(space, w_self, args): w_self = space.descr_self_interp_w(arguments, w_self) w_self.w_args = None @@ -5859,8 +6017,10 @@ if len(args_w) != 4: w_err = space.wrap("arguments constructor takes 0 or 4 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('args', 'vararg', 'kwarg', 'defaults',))): + i = 0 + for field in _arguments_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) arguments_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5897,6 +6057,7 @@ w_self.value = space.interp_w(expr, w_new_value, False) w_self.initialization_state |= 2 +_keyword_field_unroller = unrolling_iterable(['arg', 'value']) def keyword_init(space, w_self, args): w_self = space.descr_self_interp_w(keyword, w_self) args_w, kwargs_w = args.unpack() @@ -5904,8 +6065,10 @@ if len(args_w) != 2: w_err = space.wrap("keyword constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('arg', 'value',))): + i = 0 + for field in _keyword_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) keyword_init.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -5943,6 +6106,7 @@ w_self.asname = space.str_w(w_new_value) w_self.initialization_state |= 2 +_alias_field_unroller = unrolling_iterable(['name', 'asname']) def alias_init(space, w_self, args): w_self = space.descr_self_interp_w(alias, w_self) args_w, kwargs_w = args.unpack() @@ -5950,8 +6114,10 @@ if len(args_w) != 2: w_err = space.wrap("alias constructor takes 0 or 2 positional arguments") raise OperationError(space.w_TypeError, w_err) - for i, field in unrolling_iterable(enumerate(('name', 'asname',))): + i = 0 + for field in _alias_field_unroller: space.setattr(w_self, space.wrap(field), args_w[i]) + i += 1 for field, w_value in kwargs_w.iteritems(): space.setattr(w_self, space.wrap(field), w_value) alias_init.unwrap_spec = [ObjSpace, W_Root, Arguments] Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 16:33:53 2009 @@ -368,6 +368,9 @@ self.emit("") def make_init(self, name, fields): + comma_fields = ", ".join(repr(field.name.value) for field in fields) + config = (name, comma_fields) + self.emit("_%s_field_unroller = unrolling_iterable([%s])" % config) self.emit("def %s_init(space, w_self, args):" % (name,)) self.emit("w_self = space.descr_self_interp_w(%s, w_self)" % (name,), 1) for field in fields: @@ -376,15 +379,15 @@ self.emit("args_w, kwargs_w = args.unpack()", 1) self.emit("if args_w:", 1) arity = len(fields) - comma_fields = ", ".join(repr(field.name.value) for field in fields) if arity: self.emit("if len(args_w) != %i:" % (arity,), 2) self.emit("w_err = space.wrap(\"%s constructor takes 0 or %i " \ "positional arguments\")" % (name, arity), 3) self.emit("raise OperationError(space.w_TypeError, w_err)", 3) - self.emit("for i, field in unrolling_iterable(enumerate((%s,))):" % - (comma_fields,), 2) + self.emit("i = 0", 2) + self.emit("for field in _%s_field_unroller:" % (name,), 2) self.emit("space.setattr(w_self, space.wrap(field), args_w[i])", 3) + self.emit("i += 1", 3) else: self.emit("w_err = space.wrap(\"%s constructor takes no " \ " arguments\")" % (name,), 2) From fijal at codespeak.net Tue Aug 18 16:34:44 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 16:34:44 +0200 (CEST) Subject: [pypy-svn] r66911 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818143444.AA2E716802E@codespeak.net> Author: fijal Date: Tue Aug 18 16:34:44 2009 New Revision: 66911 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (arigo, pedronis, fijal) Port r66823 from pyjitpl5-floats Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py Tue Aug 18 16:34:44 2009 @@ -115,9 +115,9 @@ elif arg.startswith('ConstPtr('): name = arg[len('ConstPtr('):-1] if self.type_system == 'lltype': - return ConstPtr(self.boxkinds[name]) + return ConstPtr(self.consts[name]) else: - return ConstObj(self.boxkinds[name]) + return ConstObj(self.consts[name]) return self.vars[arg] def parse_op(self, line): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py Tue Aug 18 16:34:44 2009 @@ -1,5 +1,5 @@ -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, llmemory from pypy.jit.metainterp.test.oparser import parse from pypy.jit.metainterp.resoperation import rop @@ -101,3 +101,13 @@ loop = parse(x, None, {}, boxkinds={'sum': BoxInt}) b = loop.getboxes() assert isinstance(b.sum0, BoxInt) + +def test_getvar_const_ptr(): + x = ''' + [] + call(ConstPtr(func_ptr)) + ''' + TP = lltype.GcArray(lltype.Signed) + NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) + loop = parse(x, None, {'func_ptr' : NULL}) + assert loop.operations[0].args[0].value == NULL Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 18 16:34:44 2009 @@ -50,6 +50,7 @@ ('other', lltype.Ptr(NODE))) node = lltype.malloc(NODE) nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) + myptr = nodebox.value nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) @@ -87,6 +88,7 @@ node = ootype.new(NODE) nodebox = BoxObj(ootype.cast_to_object(node)) + myptr = nodebox.value nodebox2 = BoxObj(ootype.cast_to_object(node)) valuedescr = cpu.fielddescrof(NODE, 'value') nextdescr = cpu.fielddescrof(NODE, 'next') Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 18 16:34:44 2009 @@ -97,9 +97,9 @@ expected.operations, remap) - def optimize_loop(self, ops, spectext, optops, - boxkinds=None, checkspecnodes=True, **values): - loop = self.parse(ops, boxkinds=boxkinds) + def optimize_loop(self, ops, spectext, optops, checkspecnodes=True, + **values): + loop = self.parse(ops) loop.setvalues(**values) # if checkspecnodes: @@ -118,7 +118,7 @@ # optimize_loop_1(self.cpu, loop) # - expected = self.parse(optops, boxkinds=boxkinds) + expected = self.parse(optops) self.assert_equal(loop, expected) def test_simple(self): @@ -346,8 +346,8 @@ fail() jump() """ - self.optimize_loop(ops, '', ops, p1=self.nodebox.value, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, '', ops, p1=self.nodebox.value) + def test_p123_simple(self): ops = """ @@ -708,8 +708,7 @@ [i0] jump(0) """ - self.optimize_loop(ops, 'Not', expected, p2=self.nodebox.value, - i1=0, boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, 'Not', expected, p2=self.nodebox.value, i1=0) def test_nonvirtual_1(self): ops = """ @@ -792,8 +791,7 @@ [i] jump(5) """ - self.optimize_loop(ops, 'Not', expected, i1=5, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, 'Not', expected, i1=5) def test_getfield_gc_nonpure_2(self): ops = """ @@ -802,8 +800,7 @@ jump(i1) """ expected = ops - self.optimize_loop(ops, 'Not', expected, i1=5, - boxkinds={'myptr': self.nodebox.value}) + self.optimize_loop(ops, 'Not', expected, i1=5) def test_varray_1(self): ops = """ From benjamin at codespeak.net Tue Aug 18 16:42:30 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:42:30 +0200 (CEST) Subject: [pypy-svn] r66912 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818144230.DD63B16802E@codespeak.net> Author: benjamin Date: Tue Aug 18 16:42:30 2009 New Revision: 66912 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: a int field can't be None Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 16:42:30 2009 @@ -4046,10 +4046,7 @@ return space.wrap(w_self.level) def ImportFrom_set_level(space, w_self, w_new_value): - if space.is_w(w_new_value, space.w_None): - w_self.level = None - else: - w_self.level = space.int_w(w_new_value) + w_self.level = space.int_w(w_new_value) w_self.initialization_state |= 4 _ImportFrom_field_unroller = unrolling_iterable(['module', 'names', 'level', 'lineno', 'col_offset']) Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 16:42:30 2009 @@ -463,7 +463,7 @@ config, 1) else: level = 1 - if field.opt: + if field.opt and field.type.value != "int": self.emit("if space.is_w(w_new_value, space.w_None):", 1) self.emit("w_self.%s = None" % (field.name,), 2) level += 1 From arigo at codespeak.net Tue Aug 18 16:45:41 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 16:45:41 +0200 (CEST) Subject: [pypy-svn] r66913 - pypy/branch/pyjitpl5/pypy/jit/tl Message-ID: <20090818144541.487FE168030@codespeak.net> Author: arigo Date: Tue Aug 18 16:45:40 2009 New Revision: 66913 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: Print a documentation instead of crashing if run directly. Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Tue Aug 18 16:45:40 2009 @@ -19,6 +19,11 @@ from pypy.interpreter.pycode import PyCode from pypy.translator.goal import unixcheckpoint +if not hasattr(py.test.config.option, 'ootype'): + import sys + print >> sys.stderr, __doc__ + sys.exit(2) + if py.test.config.option.ootype: BACKEND = 'cli' else: From benjamin at codespeak.net Tue Aug 18 16:48:59 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:48:59 +0200 (CEST) Subject: [pypy-svn] r66914 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818144859.35D0C16802E@codespeak.net> Author: benjamin Date: Tue Aug 18 16:48:58 2009 New Revision: 66914 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: pass consistent arguments to to_simple_int() Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 16:48:58 2009 @@ -1512,7 +1512,7 @@ if w_list is not None: list_w = space.viewiterable(w_list) if list_w: - self.ops = [w_obj.to_simple_int() for w_obj in list_w] + self.ops = [w_obj.to_simple_int(space) for w_obj in list_w] else: self.ops = None w_list = self.w_comparators @@ -1865,32 +1865,32 @@ class _Load(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 1 class _Store(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 2 class _Del(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 3 class _AugLoad(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 4 class _AugStore(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 5 class _Param(expr_context): - def to_simple_int(self): + def to_simple_int(self, space): return 6 Load = 1 @@ -2039,12 +2039,12 @@ class _And(boolop): - def to_simple_int(self): + def to_simple_int(self, space): return 1 class _Or(boolop): - def to_simple_int(self): + def to_simple_int(self, space): return 2 And = 1 @@ -2063,62 +2063,62 @@ class _Add(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 1 class _Sub(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 2 class _Mult(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 3 class _Div(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 4 class _Mod(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 5 class _Pow(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 6 class _LShift(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 7 class _RShift(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 8 class _BitOr(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 9 class _BitXor(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 10 class _BitAnd(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 11 class _FloorDiv(operator): - def to_simple_int(self): + def to_simple_int(self, space): return 12 Add = 1 @@ -2157,22 +2157,22 @@ class _Invert(unaryop): - def to_simple_int(self): + def to_simple_int(self, space): return 1 class _Not(unaryop): - def to_simple_int(self): + def to_simple_int(self, space): return 2 class _UAdd(unaryop): - def to_simple_int(self): + def to_simple_int(self, space): return 3 class _USub(unaryop): - def to_simple_int(self): + def to_simple_int(self, space): return 4 Invert = 1 @@ -2195,52 +2195,52 @@ class _Eq(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 1 class _NotEq(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 2 class _Lt(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 3 class _LtE(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 4 class _Gt(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 5 class _GtE(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 6 class _Is(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 7 class _IsNot(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 8 class _In(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 9 class _NotIn(cmpop): - def to_simple_int(self): + def to_simple_int(self, space): return 10 Eq = 1 @@ -3320,7 +3320,7 @@ def AugAssign_set_op(space, w_self, w_new_value): obj = space.interp_w(operator, w_new_value) - w_self.op = obj.to_simple_int() + w_self.op = obj.to_simple_int(space) w_self.initialization_state |= 2 def AugAssign_get_value(space, w_self): @@ -4320,7 +4320,7 @@ def BoolOp_set_op(space, w_self, w_new_value): obj = space.interp_w(boolop, w_new_value) - w_self.op = obj.to_simple_int() + w_self.op = obj.to_simple_int(space) w_self.initialization_state |= 1 def BoolOp_get_values(space, w_self): @@ -4385,7 +4385,7 @@ def BinOp_set_op(space, w_self, w_new_value): obj = space.interp_w(operator, w_new_value) - w_self.op = obj.to_simple_int() + w_self.op = obj.to_simple_int(space) w_self.initialization_state |= 2 def BinOp_get_right(space, w_self): @@ -4433,7 +4433,7 @@ def UnaryOp_set_op(space, w_self, w_new_value): obj = space.interp_w(unaryop, w_new_value) - w_self.op = obj.to_simple_int() + w_self.op = obj.to_simple_int(space) w_self.initialization_state |= 1 def UnaryOp_get_operand(space, w_self): @@ -5084,7 +5084,7 @@ def Attribute_set_ctx(space, w_self, w_new_value): obj = space.interp_w(expr_context, w_new_value) - w_self.ctx = obj.to_simple_int() + w_self.ctx = obj.to_simple_int(space) w_self.initialization_state |= 4 _Attribute_field_unroller = unrolling_iterable(['value', 'attr', 'ctx', 'lineno', 'col_offset']) @@ -5142,7 +5142,7 @@ def Subscript_set_ctx(space, w_self, w_new_value): obj = space.interp_w(expr_context, w_new_value) - w_self.ctx = obj.to_simple_int() + w_self.ctx = obj.to_simple_int(space) w_self.initialization_state |= 4 _Subscript_field_unroller = unrolling_iterable(['value', 'slice', 'ctx', 'lineno', 'col_offset']) @@ -5190,7 +5190,7 @@ def Name_set_ctx(space, w_self, w_new_value): obj = space.interp_w(expr_context, w_new_value) - w_self.ctx = obj.to_simple_int() + w_self.ctx = obj.to_simple_int(space) w_self.initialization_state |= 2 _Name_field_unroller = unrolling_iterable(['id', 'ctx', 'lineno', 'col_offset']) @@ -5244,7 +5244,7 @@ def List_set_ctx(space, w_self, w_new_value): obj = space.interp_w(expr_context, w_new_value) - w_self.ctx = obj.to_simple_int() + w_self.ctx = obj.to_simple_int(space) w_self.initialization_state |= 2 _List_field_unroller = unrolling_iterable(['elts', 'ctx', 'lineno', 'col_offset']) @@ -5299,7 +5299,7 @@ def Tuple_set_ctx(space, w_self, w_new_value): obj = space.interp_w(expr_context, w_new_value) - w_self.ctx = obj.to_simple_int() + w_self.ctx = obj.to_simple_int(space) w_self.initialization_state |= 2 _Tuple_field_unroller = unrolling_iterable(['elts', 'ctx', 'lineno', 'col_offset']) Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 16:48:58 2009 @@ -65,7 +65,7 @@ for i, cons in enumerate(sum.types): self.emit("class _%s(%s):" % (cons.name, base)) self.emit("") - self.emit("def to_simple_int(self):", 1) + self.emit("def to_simple_int(self, space):", 1) self.emit("return %i" % (i + 1,), 2) self.emit("") for i, cons in enumerate(sum.types): @@ -312,7 +312,7 @@ if tp in asdl.builtin_types: return "space.%s(%s)" % (asdl_type_map[tp], name) elif tp in simple_types: - return "%s.to_simple_int()" % (name,) + return "%s.to_simple_int(space)" % (name,) return "space.interp_w(%s, %s)" % (tp, name) @@ -456,7 +456,8 @@ if field.type.value in self.data.simple_types: self.emit("obj = space.interp_w(%s, w_new_value)" % \ (field.type,), 1) - self.emit("w_self.%s = obj.to_simple_int()" % (field.name,), 1) + self.emit("w_self.%s = obj.to_simple_int(space)" % + (field.name,), 1) else: config = (field.name, field.type, repr(field.opt)) self.emit("w_self.%s = space.interp_w(%s, w_new_value, %s)" % From fijal at codespeak.net Tue Aug 18 16:49:52 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 16:49:52 +0200 (CEST) Subject: [pypy-svn] r66915 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818144952.200DE168030@codespeak.net> Author: fijal Date: Tue Aug 18 16:49:51 2009 New Revision: 66915 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py Log: (fijal, pedronis) A syntax for jumps Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py Tue Aug 18 16:49:51 2009 @@ -49,13 +49,15 @@ getattr(boxes, name).value = value class OpParser(object): - def __init__(self, descr, cpu, namespace, type_system, boxkinds): + def __init__(self, descr, cpu, namespace, type_system, boxkinds, jump_targets): self.descr = descr self.vars = {} self.cpu = cpu self.consts = namespace self.type_system = type_system self.boxkinds = boxkinds or {} + self.jumps = [] + self.jump_targets = jump_targets def box_for_var(self, elem): try: @@ -170,6 +172,8 @@ def parse_op_no_result(self, line): opnum, args, descr = self.parse_op(line) res = ResOperation(opnum, args, None, descr) + if opnum == rop.JUMP: + self.jumps.append(res) return res def parse_next_op(self, line): @@ -192,6 +196,15 @@ if num < len(newlines): raise ParseError("unexpected dedent at line: %s" % newlines[num]) loop = ExtendedTreeLoop("loop") + if (self.jump_targets is not None and + len(self.jump_targets) != len(self.jumps)): + raise ParseError("Wrong number of jump targets") + if self.jump_targets is None: + for jump in self.jumps: + jump.jump_target = loop + else: + for jump, jump_target in zip(self.jumps, self.jump_targets): + jump.jump_target = jump_target loop.operations = ops loop.inputargs = inpargs return loop @@ -225,10 +238,10 @@ return base_indent, inpargs def parse(descr, cpu=None, namespace=None, type_system='lltype', - boxkinds=None): + boxkinds=None, jump_targets=None): if namespace is None: namespace = _default_namespace[type_system] - return OpParser(descr, cpu, namespace, type_system, boxkinds).parse() + return OpParser(descr, cpu, namespace, type_system, boxkinds, jump_targets).parse() def _box_counter_more_than(s): if s.isdigit(): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py Tue Aug 18 16:49:51 2009 @@ -111,3 +111,21 @@ NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) loop = parse(x, None, {'func_ptr' : NULL}) assert loop.operations[0].args[0].value == NULL + +def test_jump_target(): + x = ''' + [] + jump() + ''' + loop = parse(x) + assert loop.operations[0].jump_target is loop + +def test_jump_target_other(): + x = ''' + [] + jump() + ''' + obj = object() + loop = parse(x, jump_targets=[obj]) + assert loop.operations[0].jump_target is obj + From fijal at codespeak.net Tue Aug 18 16:51:00 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 16:51:00 +0200 (CEST) Subject: [pypy-svn] r66916 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090818145100.0F807168030@codespeak.net> Author: fijal Date: Tue Aug 18 16:50:59 2009 New Revision: 66916 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) Replace test_regalloc with something saner using oparser and an example test Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Tue Aug 18 16:50:59 2009 @@ -2,440 +2,46 @@ """ Tests for register allocation for common constructs """ -import py -py.test.skip("Think about a nice way of doing stuff below") -from pypy.jit.backend.x86.test.test_runner import FakeMetaInterp, FakeStats from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ - BoxPtr, ConstPtr + BoxPtr, ConstPtr, TreeLoop +from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.runner import CPU +from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.lltypesystem import lltype -from pypy.jit.metainterp.resoperation import rop -from pypy.rpython.lltypesystem import lltype, llmemory - -def test_simple_loop(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - i = BoxInt(0) # a loop variable - i_0 = BoxInt(0) # another incarnation of loop variable - flag = BoxInt(1) # True - flag_0 = BoxInt(1) # True - # this should be more or less: - # i = 0 - # while i < 5: - # i += 1 - operations = [ - ResOperation(rop.MERGE_POINT, [i, flag], None), - ResOperation(rop.GUARD_TRUE, [flag], None), - ResOperation(rop.INT_ADD, [i, ConstInt(1)], i_0), - ResOperation(rop.INT_LT, [i_0, ConstInt(5)], flag_0), - ResOperation(rop.JUMP, [i_0, flag_0], None), - ] - startmp = operations[0] - operations[-1].jump_target = startmp - operations[1].liveboxes = [i, flag] - - cpu.compile_operations(operations) - res = cpu.execute_operations_in_new_frame('foo', operations, - [BoxInt(0), BoxInt(1)]) - assert res.value == 5 - assert meta_interp.recordedvalues == [5, False] - # assert stuff - regalloc = cpu.assembler._regalloc - # no leakage, args to merge_point - assert regalloc.current_stack_depth == 2 - longevity = regalloc.longevity - assert longevity == {i: (0, 2), flag: (0, 1), i_0: (2, 4), flag_0: (3, 4)} - -def test_longer_loop(): - """ This test checks whether register allocation can - reclaim back unused registers - """ - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - x = BoxInt(1) - x0 = BoxInt(0) - y = BoxInt(1) - i = BoxInt(0) - i0 = BoxInt(0) - flag = BoxInt(1) # True - flag0 = BoxInt(0) # False - v0 = BoxInt(0) - v1 = BoxInt(0) - v2 = BoxInt(0) - v3 = BoxInt(0) - y0 = BoxInt(0) - # code for: - def f(): - i = 0 - x = 1 - y = 1 - while i < 5: - x = ((y + x) * i) - x - y = i * y - x * y - i += 1 - return [x, y, i, i < 5] - operations = [ - ResOperation(rop.MERGE_POINT, [x, y, i, flag], None), - ResOperation(rop.GUARD_TRUE, [flag], None), - ResOperation(rop.INT_ADD, [y, x], v0), - ResOperation(rop.INT_MUL, [v0, i], v1), - ResOperation(rop.INT_SUB, [v1, x], x0), - ResOperation(rop.INT_MUL, [x0, y], v2), - ResOperation(rop.INT_MUL, [i, y], v3), - ResOperation(rop.INT_SUB, [v3, v2], y0), - ResOperation(rop.INT_ADD, [i, ConstInt(1)], i0), - ResOperation(rop.INT_LT, [i0, ConstInt(5)], flag0), - ResOperation(rop.JUMP, [x0, y0, i0, flag0], None), - ] - startmp = operations[0] - operations[-1].jump_target = startmp - operations[1].liveboxes = [x, y, i, flag] - - cpu.compile_operations(operations) - - res = cpu.execute_operations_in_new_frame('foo', operations, - [BoxInt(1), BoxInt(1), - BoxInt(0), BoxInt(1)]) - assert res.value == 6 - assert meta_interp.recordedvalues == f() - -def test_loop_with_const_and_var_swap(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - x = BoxInt(0) - y = BoxInt(0) - z = BoxInt(0) - i = BoxInt(0) - i0 = BoxInt(0) - v0 = BoxInt(0) - operations = [ - ResOperation(rop.MERGE_POINT, [x, y, z, i], None), - ResOperation(rop.INT_SUB, [i, ConstInt(1)], i0), - ResOperation(rop.INT_GT, [i0, ConstInt(0)], v0), - ResOperation(rop.GUARD_TRUE, [v0], None), - ResOperation(rop.JUMP, [x, z, y, i0], None), - ] - operations[-1].jump_target = operations[0] - operations[3].liveboxes = [x, y, z, i0] - - cpu.compile_operations(operations) - - res = cpu.execute_operations_in_new_frame('foo', operations, - [BoxInt(1), BoxInt(2), - BoxInt(3), BoxInt(10)]) - assert res.value == 1 - assert meta_interp.recordedvalues == [1, 3, 2, 0] - -def test_bool_optimizations(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - arg0 = BoxInt(3) - arg1 = BoxInt(4) - res = BoxInt(0) - ops = [ - ResOperation(rop.MERGE_POINT, [arg0, arg1], None), - ResOperation(rop.INT_GT, [arg0, arg1], res), - ResOperation(rop.GUARD_TRUE, [res], None), - # we should never get here - ] - ops[2].liveboxes = [res] - - cpu.compile_operations(ops) - res = cpu.execute_operations_in_new_frame('foo', ops, - [arg0, arg1]) - - #assert len(cpu.assembler._regalloc.computed_ops) == 2 - assert meta_interp.gf - # er, what to check here, assembler??? - -def test_bool_cannot_optimize(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - arg0 = BoxInt(3) - arg1 = BoxInt(4) - res = BoxInt(0) - r = BoxInt(1) - ops = [ - ResOperation(rop.MERGE_POINT, [arg0, arg1], None), - ResOperation(rop.INT_GT, [arg0, arg1], res), - ResOperation(rop.GUARD_TRUE, [res], None), - # we should never get here - ResOperation(rop.INT_ADD, [res, ConstInt(0)], r), - ResOperation(RETURN, [r], None), - ] - ops[2].liveboxes = [res] - - cpu.compile_operations(ops) - res = cpu.execute_operations_in_new_frame('foo', ops, - [arg0, arg1]) - - #assert len(cpu.assembler._regalloc.computed_ops) == 5 - assert meta_interp.gf - # er, what to check here, assembler??? - -def test_bug_1(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - TP = lltype.GcStruct('x', ('y', lltype.Ptr(lltype.GcStruct('y')))) - cpu.assembler._ovf_error_vtable = llmemory.cast_ptr_to_adr(lltype.nullptr(TP)) - cpu.assembler._ovf_error_inst = cpu.assembler._ovf_error_vtable - - p0 = BoxPtr() - p1 = BoxPtr() - i2 = BoxInt(1000) - i3 = BoxInt(0) - i4 = BoxInt(1) - i5 = BoxInt(3) - p6 = BoxPtr() - p7 = BoxPtr() - i8 = BoxInt(3) - i9 = BoxInt(3) - i10 = BoxInt(1) - i11 = BoxInt(37) - p12 = BoxPtr() - p13 = BoxPtr() - i14 = BoxInt() - i15 = BoxInt() - i16 = BoxInt() - i17 = BoxInt() - i18 = BoxInt() - i19 = BoxInt() - i20 = BoxInt() - i21 = BoxInt() - p22 = BoxPtr() - i23 = BoxInt() - none_ptr = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, - lltype.nullptr(TP))) - const_code = none_ptr - stuff = lltype.malloc(TP) - stuff_2 = lltype.malloc(TP.y.TO) - stuff.y = stuff_2 - const_ptr = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, - stuff)) - p12 = const_code.clonebox() - const_name = none_ptr - ops = [ - ResOperation(rop.MERGE_POINT, [p0, p1, i2, i3, i4, i5, p6, p7, i8, - i9, i10, i11, p12, p13], None), - ResOperation(rop.GUARD_VALUE, [ConstInt(1), i10], None), - ResOperation(rop.OOISNULL, [p1], i14), - ResOperation(rop.GUARD_TRUE, [i14], None), - ResOperation(rop.INT_LT, [i5, ConstInt(0)], i15), - ResOperation(rop.GUARD_FALSE, [i15], None), - ResOperation(rop.INT_GE, [i5, i2], i16), - ResOperation(rop.GUARD_FALSE, [i16], None), - ResOperation(rop.INT_LT, [i5, ConstInt(0)], i17), - ResOperation(rop.GUARD_FALSE, [i17], None), - ResOperation(rop.INT_MUL, [i5, i4], i18), - ResOperation(rop.INT_ADD, [i3, i18], i19), - ResOperation(rop.INT_ADD, [i5, ConstInt(1)], i20), - ResOperation(rop.INT_ADD_OVF, [i8, i19], i21), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.GETFIELD_GC, [const_ptr], p22), - ResOperation(rop.OOISNULL, [p22], i23), - ResOperation(rop.GUARD_FALSE, [i23], None), - ResOperation(rop.GUARD_VALUE, [p12, const_code], None), - ResOperation(rop.JUMP, [p0, p1, i2, i3, i4, i20, none_ptr, none_ptr, - i21, i19, ConstInt(1), ConstInt(37), p12, p22], - None) - ] - ops[-5].descr = cpu.fielddescrof(TP, 'y') - ops[1].liveboxes = [p0, i11, i5, i2, i3, i4, p1, p6, p7, i8, - i9, i10, p12, p13] - ops[3].liveboxes = [p0, i5, i2, i3, i4, p1, p6, p7, i8, i9, p12, p13] - ops[5].liveboxes = [p0, i5, i2, i3, i4, p1, p6, p7, i8, i9, p12, p13] - ops[7].liveboxes = [p0, i5, i2, i3, i4, p1, p6, p7, i8, i9, p12, p13] - ops[9].liveboxes = [p0, i5, i2, i3, i4, p1, p6, p7, i8, i9, p12, p13] - ops[14].liveboxes = [p0, i20, i2, i3, i4, p1, i8, i19, p12, p13, i21] - ops[17].liveboxes = [p0, i20, i2, i3, i4, p1, i21, i19, p12, p13, p22] - ops[-2].liveboxes = [p0, i20, i2, i3, i4, p1, i21, i19, p12, p13, p22] +from pypy.rpython.annlowlevel import llhelper - ops[-1].jump_target = ops[0] - cpu.compile_operations(ops) - args = [p0, p1, i2, i3, i4, i5, p6, p7, i8, i9, i10, i11, p12, p13] - res = cpu.execute_operations_in_new_frame('foo', ops, args) - assert meta_interp.recordedvalues[1:3] == [1000, 1000] +class TestRegalloc(object): + cpu = CPU(None, None) -def test_bug_2(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - TP = lltype.GcStruct('x', ('y', lltype.Ptr(lltype.GcStruct('y')))) - cpu.assembler._ovf_error_vtable = llmemory.cast_ptr_to_adr(lltype.nullptr(TP)) - cpu.assembler._ovf_error_inst = cpu.assembler._ovf_error_vtable - ptr_0 = lltype.malloc(TP) - ptr_0.y = lltype.malloc(TP.y.TO) - ptr_1 = lltype.nullptr(TP) - ptr_2 = lltype.nullptr(TP) - ptr_3 = ptr_0 - ptr_4 = ptr_0 - boxptr_0 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_0)) - boxint_1 = BoxInt(780) - boxint_2 = BoxInt(40) - boxint_3 = BoxInt(37) - boxptr_4 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_1)) - boxint_5 = BoxInt(40) - boxint_6 = BoxInt(1000) - boxint_7 = BoxInt(0) - boxint_8 = BoxInt(1) - boxptr_9 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxptr_10 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxptr_11 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxint_12 = BoxInt(1) - boxptr_13 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_3)) - constint_14 = ConstInt(1) - boxint_15 = BoxInt(1) - constint_16 = ConstInt(0) - boxint_17 = BoxInt(0) - boxint_18 = BoxInt(0) - boxint_19 = BoxInt(0) - boxint_20 = BoxInt(40) - boxint_21 = BoxInt(40) - constint_22 = ConstInt(1) - boxint_23 = BoxInt(41) - boxint_24 = BoxInt(820) - constptr_25 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_4)) - boxptr_26 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_3)) - boxint_27 = BoxInt(0) - constptr_28 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_1)) - constint_29 = ConstInt(37) - constptr_30 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - constint_31 = ConstInt(1) - ops = [ - ResOperation(rop.MERGE_POINT, [boxptr_0, boxint_1, boxint_2, boxint_3, boxptr_4, boxint_5, boxint_6, boxint_7, boxint_8, boxptr_9, boxptr_10, boxptr_11, boxint_12, boxptr_13], None), - ResOperation(rop.GUARD_VALUE, [boxint_12, constint_14], None), - ResOperation(rop.OOISNULL, [boxptr_9], boxint_15), - ResOperation(rop.GUARD_TRUE, [boxint_15], None), - ResOperation(rop.INT_LT, [boxint_5, constint_16], boxint_17), - ResOperation(rop.GUARD_FALSE, [boxint_17], None), - ResOperation(rop.INT_GE, [boxint_5, boxint_6], boxint_18), - ResOperation(rop.GUARD_FALSE, [boxint_18], None), - ResOperation(rop.INT_LT, [boxint_5, constint_16], boxint_19), - ResOperation(rop.GUARD_FALSE, [boxint_19], None), - ResOperation(rop.INT_MUL, [boxint_5, boxint_8], boxint_20), - ResOperation(rop.INT_ADD, [boxint_7, boxint_20], boxint_21), - ResOperation(rop.INT_ADD, [boxint_5, constint_22], boxint_23), - ResOperation(rop.INT_ADD_OVF, [boxint_1, boxint_21], boxint_24), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.GETFIELD_GC, [constptr_25], boxptr_26), - ResOperation(rop.OOISNULL, [boxptr_26], boxint_27), - ResOperation(rop.GUARD_FALSE, [boxint_27], None), - ResOperation(rop.GUARD_VALUE, [boxptr_4, constptr_28], None), - ResOperation(rop.JUMP, [boxptr_0, boxint_24, boxint_21, constint_29, boxptr_4, boxint_23, boxint_6, boxint_7, boxint_8, boxptr_9, constptr_30, constptr_30, constint_31, boxptr_26], None), - ] - ops[-1].jump_target = ops[0] - ops[-1].jump_target = ops[0] - ops[1].liveboxes = [] - ops[3].liveboxes = [] - ops[5].liveboxes = [] - ops[7].liveboxes = [] - ops[9].liveboxes = [] - ops[-2].liveboxes = [] - ops[-3].liveboxes = [] - ops[-6].liveboxes = [] - ops[-5].descr = cpu.fielddescrof(TP, 'y') - args = [boxptr_0, boxint_1, boxint_2, boxint_3, boxptr_4, boxint_5, boxint_6, boxint_7, boxint_8, boxptr_9, boxptr_10, boxptr_11, boxint_12, boxptr_13] - cpu.compile_operations(ops) - res = cpu.execute_operations_in_new_frame('foo', ops, args) + namespace = locals().copy() + type_system = 'lltype' -def test_bug_3(): - meta_interp = FakeMetaInterp() - cpu = CPU(rtyper=None, stats=FakeStats()) - cpu.set_meta_interp(meta_interp) - TP = lltype.GcStruct('x', ('y', lltype.Ptr(lltype.GcStruct('y')))) - cpu.assembler._ovf_error_vtable = llmemory.cast_ptr_to_adr(lltype.nullptr(TP)) - cpu.assembler._ovf_error_inst = cpu.assembler._ovf_error_vtable - ptr_0 = lltype.malloc(TP) - ptr_0.y = lltype.malloc(TP.y.TO) - ptr_1 = lltype.nullptr(TP) - ptr_2 = lltype.nullptr(TP) - ptr_3 = ptr_0 - ptr_4 = ptr_0 - boxptr_0 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_0)) - boxint_1 = BoxInt(60) - boxint_2 = BoxInt(40) - boxint_3 = BoxInt(57) - boxptr_4 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_1)) - boxint_5 = BoxInt(40) - boxint_6 = BoxInt(100000000) - boxint_7 = BoxInt(0) - boxint_8 = BoxInt(1) - boxptr_9 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxptr_10 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxptr_11 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - boxint_12 = BoxInt(1) - boxptr_13 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_3)) - constint_14 = ConstInt(1) - boxint_15 = BoxInt(1) - constint_16 = ConstInt(0) - boxint_17 = BoxInt(0) - boxint_18 = BoxInt(0) - boxint_19 = BoxInt(0) - boxint_20 = BoxInt(40) - boxint_21 = BoxInt(40) - constint_22 = ConstInt(1) - boxint_23 = BoxInt(41) - constptr_24 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_1)) - constint_25 = ConstInt(2) - boxint_26 = BoxInt(0) - boxint_27 = BoxInt(42) - boxint_28 = BoxInt(0) - boxint_29 = BoxInt(0) - boxint_30 = BoxInt(0) - boxint_31 = BoxInt(0) - boxint_32 = BoxInt(0) - boxint_33 = BoxInt(0) - constint_34 = ConstInt(2) - boxint_35 = BoxInt(62) - constptr_36 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_4)) - boxptr_37 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_3)) - boxint_38 = BoxInt(0) - constint_39 = ConstInt(57) - constptr_40 = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ptr_2)) - constint_41 = ConstInt(1) - ops = [ - ResOperation(rop.MERGE_POINT, [boxptr_0, boxint_1, boxint_2, boxint_3, boxptr_4, boxint_5, boxint_6, boxint_7, boxint_8, boxptr_9, boxptr_10, boxptr_11, boxint_12, boxptr_13], None), - ResOperation(rop.GUARD_VALUE, [boxint_12, constint_14], None), - ResOperation(rop.OOISNULL, [boxptr_9], boxint_15), - ResOperation(rop.GUARD_TRUE, [boxint_15], None), - ResOperation(rop.INT_LT, [boxint_5, constint_16], boxint_17), - ResOperation(rop.GUARD_FALSE, [boxint_17], None), - ResOperation(rop.INT_GE, [boxint_5, boxint_6], boxint_18), - ResOperation(rop.GUARD_FALSE, [boxint_18], None), - ResOperation(rop.INT_LT, [boxint_5, constint_16], boxint_19), - ResOperation(rop.GUARD_FALSE, [boxint_19], None), - ResOperation(rop.INT_MUL, [boxint_5, boxint_8], boxint_20), - ResOperation(rop.INT_ADD, [boxint_7, boxint_20], boxint_21), - ResOperation(rop.INT_ADD, [boxint_5, constint_22], boxint_23), - ResOperation(rop.GUARD_VALUE, [boxptr_4, constptr_24], None), - ResOperation(rop.INT_MOD_OVF, [boxint_21, constint_25], boxint_26), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.INT_XOR, [boxint_21, constint_25], boxint_27), - ResOperation(rop.INT_LE, [boxint_27, constint_16], boxint_28), - ResOperation(rop.INT_NE, [boxint_26, constint_16], boxint_29), - ResOperation(rop.INT_AND, [boxint_28, boxint_29], boxint_30), - ResOperation(rop.INT_MUL, [boxint_30, constint_25], boxint_31), - ResOperation(rop.INT_ADD, [boxint_26, boxint_31], boxint_32), - ResOperation(rop.INT_NE, [boxint_32, constint_16], boxint_33), - ResOperation(rop.GUARD_FALSE, [boxint_33], None), - ResOperation(rop.INT_ADD_OVF, [boxint_1, constint_34], boxint_35), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.GETFIELD_GC, [constptr_36], boxptr_37), - ResOperation(rop.OOISNULL, [boxptr_37], boxint_38), - ResOperation(rop.GUARD_FALSE, [boxint_38], None), - ResOperation(rop.JUMP, [boxptr_0, boxint_35, boxint_21, constint_39, boxptr_4, boxint_23, boxint_6, boxint_7, boxint_8, boxptr_9, constptr_40, constptr_40, constint_41, boxptr_37], None), - ] - ops[-1].jump_target = ops[0] - for op in ops: - if op.is_guard(): - op.liveboxes = [] - ops[-4].descr = cpu.fielddescrof(TP, 'y') - cpu.compile_operations(ops) - args = [boxptr_0, boxint_1, boxint_2, boxint_3, boxptr_4, boxint_5, boxint_6, boxint_7, boxint_8, boxptr_9, boxptr_10, boxptr_11, boxint_12, boxptr_13] - res = cpu.execute_operations_in_new_frame('foo', ops, args) + def parse(self, s, boxkinds=None): + return parse(s, self.cpu, self.namespace, + type_system=self.type_system, + boxkinds=boxkinds) + + def interpret(self, ops, args): + loop = self.parse(ops) + self.cpu.compile_operations(loop) + for i, arg in enumerate(args): + if isinstance(arg, int): + self.cpu.set_future_value_int(i, arg) + else: + raise NotImplementedError("Arg: %s" % arg) + self.cpu.execute_operations(loop) + + def getint(self, index): + return self.cpu.get_latest_value_int(index) + + def test_simple_loop(self): + ops = ''' + [i0] + i1 = int_add(i0, 1) + i2 = int_lt(i1, 20) + guard_true(i2) + fail(i1) + jump(i1) + ''' + self.interpret(ops, [0]) + assert self.getint(0) == 20 From benjamin at codespeak.net Tue Aug 18 16:58:24 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 16:58:24 +0200 (CEST) Subject: [pypy-svn] r66917 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818145824.D9DE2168021@codespeak.net> Author: benjamin Date: Tue Aug 18 16:58:23 2009 New Revision: 66917 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: unwrap simple sums correctly Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 16:58:23 2009 @@ -1512,7 +1512,7 @@ if w_list is not None: list_w = space.viewiterable(w_list) if list_w: - self.ops = [w_obj.to_simple_int(space) for w_obj in list_w] + self.ops = [space.interp_w(cmpop, w_obj).to_simple_int() for w_obj in list_w] else: self.ops = None w_list = self.w_comparators Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 16:58:23 2009 @@ -312,8 +312,9 @@ if tp in asdl.builtin_types: return "space.%s(%s)" % (asdl_type_map[tp], name) elif tp in simple_types: - return "%s.to_simple_int(space)" % (name,) - return "space.interp_w(%s, %s)" % (tp, name) + return "space.interp_w(%s, %s).to_simple_int()" % (tp, name) + else: + return "space.interp_w(%s, %s)" % (tp, name) # CPython lets blank AST nodes (no constructor arguments) be created From benjamin at codespeak.net Tue Aug 18 17:05:00 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 17:05:00 +0200 (CEST) Subject: [pypy-svn] r66918 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler Message-ID: <20090818150500.DA8BA168021@codespeak.net> Author: benjamin Date: Tue Aug 18 17:04:59 2009 New Revision: 66918 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Log: annotator hint Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Tue Aug 18 17:04:59 2009 @@ -30,6 +30,7 @@ def parse_future(tree): future_lineno = 0 future_column = 0 + have_docstring = False if isinstance(tree, ast.Module) or isinstance(tree, ast.Interactive): for stmt in tree.body: if isinstance(stmt, ast.Str): From fijal at codespeak.net Tue Aug 18 17:09:31 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 17:09:31 +0200 (CEST) Subject: [pypy-svn] r66919 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090818150931.52A7216802B@codespeak.net> Author: fijal Date: Tue Aug 18 17:09:29 2009 New Revision: 66919 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (arigo, fijal, pedronis) Improve a bit coverage of test_regalloc Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Tue Aug 18 17:09:29 2009 @@ -30,6 +30,7 @@ else: raise NotImplementedError("Arg: %s" % arg) self.cpu.execute_operations(loop) + return loop def getint(self, index): return self.cpu.get_latest_value_int(index) @@ -45,3 +46,35 @@ ''' self.interpret(ops, [0]) assert self.getint(0) == 20 + + def test_compile_and_recompile(self): + ops = ''' + [i0] + i1 = int_add(i0, 1) + i2 = int_lt(i1, 20) + guard_true(i2) + fail(i1) + jump(i1) + ''' + loop = self.interpret(ops, [0]) + assert self.getint(0) == 20 + ops = ''' + [i1] + i3 = int_add(i1, 1) + i4 = int_add(i3, 1) + i5 = int_add(i4, 1) + i6 = int_add(i5, 1) + fail(i3, i4, i5, i6) + ''' + bridge = self.parse(ops) + guard_op = loop.operations[-2] + guard_op.suboperations = bridge.operations + self.cpu.compile_operations(loop, guard_op) + self.cpu.set_future_value_int(0, 0) + op = self.cpu.execute_operations(loop) + assert op is bridge.operations[-1] + assert self.getint(0) == 21 + assert self.getint(1) == 22 + assert self.getint(2) == 23 + assert self.getint(3) == 24 + From benjamin at codespeak.net Tue Aug 18 17:10:43 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 17:10:43 +0200 (CEST) Subject: [pypy-svn] r66920 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818151043.28CF1168021@codespeak.net> Author: benjamin Date: Tue Aug 18 17:10:42 2009 New Revision: 66920 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: pass space Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 17:10:42 2009 @@ -1512,7 +1512,7 @@ if w_list is not None: list_w = space.viewiterable(w_list) if list_w: - self.ops = [space.interp_w(cmpop, w_obj).to_simple_int() for w_obj in list_w] + self.ops = [space.interp_w(cmpop, w_obj).to_simple_int(space) for w_obj in list_w] else: self.ops = None w_list = self.w_comparators Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 17:10:42 2009 @@ -312,7 +312,7 @@ if tp in asdl.builtin_types: return "space.%s(%s)" % (asdl_type_map[tp], name) elif tp in simple_types: - return "space.interp_w(%s, %s).to_simple_int()" % (tp, name) + return "space.interp_w(%s, %s).to_simple_int(space)" % (tp, name) else: return "space.interp_w(%s, %s)" % (tp, name) From benjamin at codespeak.net Tue Aug 18 17:18:32 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 17:18:32 +0200 (CEST) Subject: [pypy-svn] r66921 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler Message-ID: <20090818151832.20C4C168021@codespeak.net> Author: benjamin Date: Tue Aug 18 17:18:26 2009 New Revision: 66921 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Log: please the annotator Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Tue Aug 18 17:18:26 2009 @@ -31,21 +31,26 @@ future_lineno = 0 future_column = 0 have_docstring = False - if isinstance(tree, ast.Module) or isinstance(tree, ast.Interactive): - for stmt in tree.body: - if isinstance(stmt, ast.Str): - if have_docstring: - break - else: - have_docstring = True - elif isinstance(stmt, ast.ImportFrom): - if stmt.module == "__future__": - future_lineno = stmt.lineno - future_column = stmt.col_offset - else: - break + if isinstance(tree, ast.Module): + body = tree.body + elif isinstance(tree, ast.Interactive): + body = tree.body + else: + return 0, 0 + for stmt in tree.body: + if isinstance(stmt, ast.Str): + if have_docstring: + break + else: + have_docstring = True + elif isinstance(stmt, ast.ImportFrom): + if stmt.module == "__future__": + future_lineno = stmt.lineno + future_column = stmt.col_offset else: break + else: + break return future_lineno, future_column From cfbolz at codespeak.net Tue Aug 18 17:20:42 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 17:20:42 +0200 (CEST) Subject: [pypy-svn] r66922 - pypy/branch/pyjitpl5/pypy/translator/backendopt/test Message-ID: <20090818152042.C5417168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 17:20:41 2009 New Revision: 66922 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_merge_if_blocks.py Log: bad armin, no cookie Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_merge_if_blocks.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_merge_if_blocks.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_merge_if_blocks.py Tue Aug 18 17:20:41 2009 @@ -222,6 +222,4 @@ inline.auto_inlining(t, 20) malloc.remove_mallocs(t, t.graphs) from pypy.translator import simplify - t.view() simplify.join_blocks(graph) - t.view() From cfbolz at codespeak.net Tue Aug 18 17:21:39 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 17:21:39 +0200 (CEST) Subject: [pypy-svn] r66923 - pypy/branch/pyjitpl5/pypy/translator Message-ID: <20090818152139.7E4D6168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 17:21:38 2009 New Revision: 66923 Modified: pypy/branch/pyjitpl5/pypy/translator/simplify.py Log: (mikael, cfbolz): replace a use-case of traverse by a nice iterator Modified: pypy/branch/pyjitpl5/pypy/translator/simplify.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/simplify.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/simplify.py Tue Aug 18 17:21:38 2009 @@ -402,12 +402,7 @@ def transform_dead_op_vars(graph, translator=None): """Remove dead operations and variables that are passed over a link but not used in the target block. Input is a graph.""" - blocks = {} - def visit(block): - if isinstance(block, Block): - blocks[block] = True - traverse(visit, graph) - return transform_dead_op_vars_in_blocks(blocks, translator) + return transform_dead_op_vars_in_blocks(list(graph.iterblocks()), translator) # the set of operations that can safely be removed # (they have no side effects, at least in R-Python) From cfbolz at codespeak.net Tue Aug 18 17:22:21 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 17:22:21 +0200 (CEST) Subject: [pypy-svn] r66924 - in pypy/branch/pyjitpl5/pypy/translator/backendopt: . test Message-ID: <20090818152221.82AE1168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 17:22:21 2009 New Revision: 66924 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/removenoops.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_removeassert.py Log: (mikael, cfbolz): write a function that really gets rid of all asserts fully. Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/removenoops.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/removenoops.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/removenoops.py Tue Aug 18 17:22:21 2009 @@ -101,6 +101,12 @@ "removed %s cast_pointers in %s" % (num_removed, graph.name)) return num_removed +def remove_debug_assert(graph): + for block in graph.iterblocks(): + for i, op in list(enumerate(block.operations))[::-1]: + if op.opname == "debug_assert": + del block.operations[i] + def remove_superfluous_keep_alive(graph): for block in graph.iterblocks(): used = {} Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_removeassert.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_removeassert.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_removeassert.py Tue Aug 18 17:22:21 2009 @@ -23,6 +23,7 @@ remove_asserts(t, [graph]) assert contains_raise(graph) == remaining_raise check_graph(graph, args, expected_result, t) + return t, graph def test_simple(): @@ -40,6 +41,12 @@ remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) + from pypy.translator.backendopt.removenoops import remove_debug_assert + remove_debug_assert(graph) + assert summary(graph) == {'int_ge': 1, 'int_sub': 1} + from pypy.translator.simplify import transform_dead_op_vars + transform_dead_op_vars(graph) + assert summary(graph) == {'int_sub': 1} def test_and(): def fn(n): @@ -69,7 +76,14 @@ x = g(n) assert isinstance(x, B) return x.value - check(fn, [5], 321) + t, graph = check(fn, [5], 321) + assert summary(graph)['debug_assert'] == 1 + from pypy.translator.backendopt.removenoops import remove_debug_assert + remove_debug_assert(graph) + assert "debug_assert" not in summary(graph) + from pypy.translator.simplify import transform_dead_op_vars + transform_dead_op_vars(graph, t) + assert summary(graph)["direct_call"] == 1 def test_with_exception(): def g(n): @@ -82,3 +96,5 @@ except ValueError: return 42 check(fn, [-8], 42, remaining_raise=True) + + From benjamin at codespeak.net Tue Aug 18 17:23:57 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 17:23:57 +0200 (CEST) Subject: [pypy-svn] r66925 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler Message-ID: <20090818152357.3DC39168021@codespeak.net> Author: benjamin Date: Tue Aug 18 17:23:56 2009 New Revision: 66925 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Log: use correctly annotated variable Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/misc.py Tue Aug 18 17:23:56 2009 @@ -37,7 +37,7 @@ body = tree.body else: return 0, 0 - for stmt in tree.body: + for stmt in body: if isinstance(stmt, ast.Str): if have_docstring: break From fijal at codespeak.net Tue Aug 18 17:40:23 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 17:40:23 +0200 (CEST) Subject: [pypy-svn] r66926 - in pypy/branch/pyjitpl5/pypy/jit/backend: test x86 Message-ID: <20090818154023.62D2216802E@codespeak.net> Author: fijal Date: Tue Aug 18 17:40:23 2009 New Revision: 66926 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: (pedronis, arigo, fijal) * Add a bit of tests * Fix cases for 16bit access Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Tue Aug 18 17:40:23 2009 @@ -382,6 +382,11 @@ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)], 'int', descr=arraydescr) assert r.value == 7441 + r = self.cpu.do_getarrayitem_gc([a_box, BoxInt(310)], arraydescr) + assert r.value == 7441 + self.cpu.do_setarrayitem_gc([a_box, BoxInt(3), BoxInt(170)], arraydescr) + r = self.cpu.do_getarrayitem_gc([a_box, BoxInt(3)], arraydescr) + assert r.value == 170 # a_box, A = self.alloc_array_of(lltype.Char, 11) arraydescr = self.cpu.arraydescrof(A) @@ -403,6 +408,7 @@ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(3)], 'int', descr=arraydescr) assert r.value == 160 + # if isinstance(A, lltype.GcArray): A = lltype.Ptr(A) @@ -494,6 +500,10 @@ r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(4)], 'int') assert r.value == 31313 + u_box = self.cpu.do_newunicode([ConstInt(3)]) + self.cpu.do_unicodesetitem([u_box, BoxInt(4), BoxInt(123)]) + r = self.cpu.do_unicodegetitem([u_box, BoxInt(4)]) + assert r.value == 123 def test_same_as(self): r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int') @@ -524,6 +534,7 @@ ('value', lltype.Signed), ('chr1', lltype.Char), ('chr2', lltype.Char), + ('short', rffi.SHORT), ('next', lltype.Ptr(S)))) T = lltype.GcStruct('T', ('parent', S), ('next', lltype.Ptr(S))) @@ -622,13 +633,22 @@ assert r1.value != r2.value descr1 = cpu.fielddescrof(self.S, 'chr1') descr2 = cpu.fielddescrof(self.S, 'chr2') + descrshort = cpu.fielddescrof(self.S, 'short') self.execute_operation(rop.SETFIELD_GC, [r1, BoxInt(150)], 'void', descr=descr2) self.execute_operation(rop.SETFIELD_GC, [r1, BoxInt(190)], 'void', descr=descr1) + self.execute_operation(rop.SETFIELD_GC, [r1, BoxInt(1313)], + 'void', descr=descrshort) s = lltype.cast_opaque_ptr(lltype.Ptr(self.T), r1.value) assert s.parent.chr1 == chr(190) assert s.parent.chr2 == chr(150) + r = self.cpu.do_getfield_gc([r1], descrshort) + assert r.value == 1313 + self.cpu.do_setfield_gc([r1, BoxInt(1333)], descrshort) + r = self.execute_operation(rop.GETFIELD_GC, [r1], 'int', + descr=descrshort) + assert r.value == 1333 t = lltype.cast_opaque_ptr(lltype.Ptr(self.T), t_box.value) assert s.parent.parent.typeptr == t.parent.parent.typeptr Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Tue Aug 18 17:40:23 2009 @@ -501,6 +501,8 @@ size = size_loc.value if size == 1: self.mc.MOVZX(resloc, addr8_add(base_loc, ofs_loc)) + elif size == 2: + self.mc.MOVZX(resloc, addr_add(base_loc, ofs_loc)) elif size == WORD: self.mc.MOV(resloc, addr_add(base_loc, ofs_loc)) else: @@ -532,8 +534,7 @@ if size == WORD: self.mc.MOV(addr_add(base_loc, ofs_loc), value_loc) elif size == 2: - raise NotImplementedError("shorts and friends") - self.mc.MOV(addr16_add(base_loc, ofs_loc), lower_2_bytes(value_loc)) + self.mc.MOV16(addr_add(base_loc, ofs_loc), value_loc) elif size == 1: self.mc.MOV(addr8_add(base_loc, ofs_loc), lower_byte(value_loc)) else: @@ -865,19 +866,6 @@ else: return memSIB8(reg_or_imm1, reg_or_imm2, scale, offset) -def addr16_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0): - if isinstance(reg_or_imm1, IMM32): - if isinstance(reg_or_imm2, IMM32): - return heap16(reg_or_imm1.value + (offset << scale) + - reg_or_imm2.value) - else: - return memSIB16(None, reg_or_imm2, scale, reg_or_imm1.value + offset) - else: - if isinstance(reg_or_imm2, IMM32): - return mem16(reg_or_imm1, (offset << scale) + reg_or_imm2.value) - else: - return memSIB16(reg_or_imm1, reg_or_imm2, scale, offset) - def addr_add_const(reg_or_imm1, offset): if isinstance(reg_or_imm1, IMM32): return heap(reg_or_imm1.value + offset) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 18 17:40:23 2009 @@ -586,14 +586,6 @@ _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) -def uhex(x): - if we_are_translated(): - return hex(x) - else: - if x < 0: - x += 0x100000000 - return hex(x) - CPU = CPU386 import pypy.jit.metainterp.executor From fijal at codespeak.net Tue Aug 18 17:42:02 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 17:42:02 +0200 (CEST) Subject: [pypy-svn] r66927 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090818154202.D0FCE16802E@codespeak.net> Author: fijal Date: Tue Aug 18 17:42:01 2009 New Revision: 66927 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Log: remove dead code Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Tue Aug 18 17:42:01 2009 @@ -617,9 +617,6 @@ # locs, stacklocs) def patch_jump(self, old_pos, new_pos, oldlocs, newlocs, olddepth, newdepth): - if len(oldlocs) != len(newlocs): - assert 0 # virtualizable mess - return for i in range(len(oldlocs)): oldloc = oldlocs[i] newloc = newlocs[i] From fijal at codespeak.net Tue Aug 18 17:45:04 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 18 Aug 2009 17:45:04 +0200 (CEST) Subject: [pypy-svn] r66928 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090818154504.E162C168030@codespeak.net> Author: fijal Date: Tue Aug 18 17:45:03 2009 New Revision: 66928 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: remove some dead code Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Tue Aug 18 17:45:03 2009 @@ -489,21 +489,6 @@ self.Store(v_to_spill, loc, newloc) return loc -# def _locs_from_liveboxes(self, guard_op): -# stacklocs = [] -# locs = [] -# for arg in guard_op.inputargs: -# assert isinstance(arg, Box) -# if arg not in self.stack_bindings: -# self.dirty_stack[arg] = True -# stacklocs.append(self.stack_loc(arg).position) -# locs.append(self.loc(arg)) -# if not we_are_translated(): -# assert len(dict.fromkeys(stacklocs)) == len(stacklocs) -# guard_op.stacklocs = stacklocs -# guard_op.locs = locs -# return locs - def stack_loc(self, v): try: res = self.stack_bindings[v] @@ -715,22 +700,6 @@ consider_guard_no_overflow = consider_guard_no_exception consider_guard_overflow = consider_guard_no_exception - #def consider_guard2(self, op, ignored): - # loc1, ops1 = self.make_sure_var_in_reg(op.args[0], []) - # loc2, ops2 = self.make_sure_var_in_reg(op.args[1], []) - # locs = [self.loc(arg) for arg in op.liveboxes] - # self.eventually_free_vars(op.args + op.liveboxes) - # return ops1 + ops2 + [PerformDiscard(op, [loc1, loc2] + locs)] - - #consider_guard_lt = consider_guard2 - #consider_guard_le = consider_guard2 - #consider_guard_eq = consider_guard2 - #consider_guard_ne = consider_guard2 - #consider_guard_gt = consider_guard2 - #consider_guard_ge = consider_guard2 - #consider_guard_is = consider_guard2 - #consider_guard_isnot = consider_guard2 - def consider_guard_value(self, op, ignored): x = self.loc(op.args[0]) if not (isinstance(x, REG) or isinstance(op.args[1], Const)): @@ -1032,18 +1001,6 @@ consider_getfield_raw = consider_getfield_gc consider_getarrayitem_gc_pure = consider_getarrayitem_gc - def _consider_listop(self, op, ignored): - return self._call(op, [self.loc(arg) for arg in op.args]) - - xxx_consider_getitem = _consider_listop - xxx_consider_len = _consider_listop - xxx_consider_append = _consider_listop - xxx_consider_pop = _consider_listop - xxx_consider_setitem = _consider_listop - xxx_consider_newlist = _consider_listop - xxx_consider_insert = _consider_listop - xxx_consider_listnonzero = _consider_listop - def _same_as(self, op, ignored): x = op.args[0] if isinstance(x, Const): From cfbolz at codespeak.net Tue Aug 18 17:53:12 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 17:53:12 +0200 (CEST) Subject: [pypy-svn] r66929 - pypy/branch/io-lang Message-ID: <20090818155312.4325716802E@codespeak.net> Author: cfbolz Date: Tue Aug 18 17:53:11 2009 New Revision: 66929 Modified: pypy/branch/io-lang/ (props changed) Log: fix revision From benjamin at codespeak.net Tue Aug 18 18:26:15 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 18:26:15 +0200 (CEST) Subject: [pypy-svn] r66930 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818162615.0DC5316802E@codespeak.net> Author: benjamin Date: Tue Aug 18 18:26:14 2009 New Revision: 66930 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: replace inplace mod Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 18:26:14 2009 @@ -62,7 +62,7 @@ missing = required[i] if missing is not None: err = "required attribute '%s' missing from %s" - err %= (missing, host) + err = erro % (missing, host) w_err = space.wrap(err) raise OperationError(space.w_TypeError, w_err) raise AssertionError("should not reach here") Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 18:26:14 2009 @@ -600,7 +600,7 @@ missing = required[i] if missing is not None: err = "required attribute '%s' missing from %s" - err %= (missing, host) + err = erro % (missing, host) w_err = space.wrap(err) raise OperationError(space.w_TypeError, w_err) raise AssertionError("should not reach here") From benjamin at codespeak.net Tue Aug 18 18:33:53 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 18:33:53 +0200 (CEST) Subject: [pypy-svn] r66931 - in pypy/branch/parser-compiler/pypy/interpreter/astcompiler: . tools Message-ID: <20090818163353.20220168030@codespeak.net> Author: benjamin Date: Tue Aug 18 18:33:52 2009 New Revision: 66931 Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Log: typo Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ast.py Tue Aug 18 18:33:52 2009 @@ -62,7 +62,7 @@ missing = required[i] if missing is not None: err = "required attribute '%s' missing from %s" - err = erro % (missing, host) + err = err % (missing, host) w_err = space.wrap(err) raise OperationError(space.w_TypeError, w_err) raise AssertionError("should not reach here") Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 18 18:33:52 2009 @@ -600,7 +600,7 @@ missing = required[i] if missing is not None: err = "required attribute '%s' missing from %s" - err = erro % (missing, host) + err = err % (missing, host) w_err = space.wrap(err) raise OperationError(space.w_TypeError, w_err) raise AssertionError("should not reach here") From cfbolz at codespeak.net Tue Aug 18 18:40:58 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 18:40:58 +0200 (CEST) Subject: [pypy-svn] r66932 - in pypy/branch/pyjitpl5/pypy: config translator/backendopt translator/backendopt/test Message-ID: <20090818164058.7C5BF168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 18:40:57 2009 New Revision: 66932 Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py pypy/branch/pyjitpl5/pypy/translator/backendopt/all.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_all.py Log: (mikael, cfbolz, pedronis, arigo): move removing of asserts to the beginning of doing optimizations Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Tue Aug 18 18:40:57 2009 @@ -238,6 +238,10 @@ "Remove operations that look like 'raise AssertionError', " "which lets the C optimizer remove the asserts", default=False), + BoolOption("really_remove_asserts", + "Really remove operations that look like 'raise AssertionError', " + "without relying on the C compiler", + default=False), BoolOption("stack_optimization", "Tranform graphs in SSI form into graphs tailored for " Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/all.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/all.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/all.py Tue Aug 18 18:40:57 2009 @@ -55,6 +55,15 @@ if translator.rtyper.type_system.name == 'ootypesystem': check_virtual_methods() + if config.remove_asserts: + constfold(config, graphs) + remove_asserts(translator, graphs) + + if config.really_remove_asserts: + for graph in graphs: + removenoops.remove_debug_assert(graph) + # the dead operations will be killed by the remove_obvious_noops below + # remove obvious no-ops def remove_obvious_noops(): for graph in graphs: @@ -114,9 +123,6 @@ call_count_pred=call_count_pred) constfold(config, graphs) - if config.remove_asserts: - remove_asserts(translator, graphs) - if config.heap2stack: assert graphs is translator.graphs # XXX for now malloc_to_stack(translator) Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_all.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_all.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_all.py Tue Aug 18 18:40:57 2009 @@ -5,7 +5,7 @@ from pypy.translator.backendopt.test.test_malloc import TestLLTypeMallocRemoval as LLTypeMallocRemovalTest from pypy.translator.backendopt.test.test_malloc import TestOOTypeMallocRemoval as OOTypeMallocRemovalTest from pypy.translator.translator import TranslationContext, graphof -from pypy.objspace.flow.model import Constant +from pypy.objspace.flow.model import Constant, summary from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.rarithmetic import intmask @@ -211,6 +211,27 @@ assert Constant(7) not in link.args assert Constant(11) not in link.args + def test_isinstance(self): + class A: + pass + class B(A): + pass + def g(n): + if n > 10: + return A() + else: + b = B() + b.value = 321 + return b + def fn(n): + x = g(n) + assert isinstance(x, B) + return x.value + t = self.translateopt(fn, [int], really_remove_asserts=True, + remove_asserts=True) + graph = graphof(t, fn) + assert "direct_call" not in summary(graph) + class TestLLType(BaseTester): type_system = 'lltype' check_malloc_removed = LLTypeMallocRemovalTest.check_malloc_removed From arigo at codespeak.net Tue Aug 18 18:41:13 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 18:41:13 +0200 (CEST) Subject: [pypy-svn] r66933 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090818164113.37C01168021@codespeak.net> Author: arigo Date: Tue Aug 18 18:41:12 2009 New Revision: 66933 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: Unify the logic behind get_printable_location() and can_inline(). In particular, make get_printable_location() work in pypyjit.py. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Tue Aug 18 18:41:12 2009 @@ -593,7 +593,7 @@ num_green_args = self.metainterp.staticdata.num_green_args portal_code = self.metainterp.staticdata.portal_code greenkey = varargs[1:num_green_args + 1] - if self.metainterp.staticdata.warmrunnerdesc.can_inline_callable(greenkey): + if self.metainterp.staticdata.state.can_inline_callable(greenkey): self.metainterp.in_recursion += 1 return self.perform_call(portal_code, varargs[1:]) return self.execute_with_exc(rop.CALL, varargs, descr=calldescr) @@ -793,8 +793,7 @@ num_green_args = self.metainterp.staticdata.num_green_args greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata - greenargs = sd.globaldata.unpack_greenkey(greenkey) - loc = sd.state.get_location_llstr(*greenargs) + loc = sd.state.get_location_str(greenkey) constloc = sd.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Tue Aug 18 18:41:12 2009 @@ -2,7 +2,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import llhelper, MixLevelHelperAnnotator,\ - cast_base_ptr_to_instance + cast_base_ptr_to_instance, hlstr from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLException from pypy.rpython.test.test_llinterp import get_interpreter, clear_tcache @@ -132,6 +132,7 @@ self.build_meta_interp(**kwds) self.make_args_specification() self.rewrite_jit_merge_point() + self.make_driverhook_graph() if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) @@ -141,7 +142,6 @@ self.rewrite_set_param() self.add_profiler_finish() self.metainterp_sd.finish_setup() - self.make_can_inline_graph() def finish(self): vinfo = self.metainterp_sd.virtualizable_info @@ -232,18 +232,25 @@ self.maybe_enter_jit_fn = maybe_enter_jit - def make_can_inline_graph(self): - if self.jitdriver.can_inline is None: - self.jitdriver.can_inline_graph = None - return + def make_driverhook_graph(self): + self.can_inline_ptr = self._make_hook_graph( + self.jitdriver.can_inline, bool) + self.get_printable_location_ptr = self._make_hook_graph( + self.jitdriver.get_printable_location, str) + + def _make_hook_graph(self, func, rettype): + from pypy.annotation.signature import annotationoftype + if func is None: + return None annhelper = MixLevelHelperAnnotator(self.translator.rtyper) - func = self.jitdriver.can_inline - FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, lltype.Bool) + s_result = annotationoftype(rettype) + RETTYPE = annhelper.rtyper.getrepr(s_result).lowleveltype + FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, RETTYPE) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] - s_result = annmodel.lltype_to_annotation(FUNC.RESULT) graph = annhelper.getgraph(func, args_s, s_result) - self.can_inline_ptr = annhelper.graph2delayed(graph, FUNC) + funcptr = annhelper.graph2delayed(graph, FUNC) annhelper.finish() + return funcptr def make_args_specification(self): graph, block, index = self.jit_merge_point_pos @@ -450,17 +457,6 @@ else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value - - if self.jitdriver.can_inline is None: - def can_inline_callable(greenkey): - return True - else: - def can_inline_callable(greenkey): - args = self.state.unwrap_greenkey(greenkey) - return support.maybe_on_top_of_llinterp(rtyper, self.can_inline_ptr)(*args) - - self.can_inline_callable = can_inline_callable - ll_portal_runner._recursive_portal_call_ = True portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, @@ -619,7 +615,9 @@ getarrayitem = warmrunnerdesc.ts.getarrayitem setarrayitem = warmrunnerdesc.ts.setarrayitem # - get_printable_location = jitdriver.get_printable_location + rtyper = warmrunnerdesc.translator.rtyper + can_inline_ptr = warmrunnerdesc.can_inline_ptr + get_printable_location_ptr = warmrunnerdesc.get_printable_location_ptr # class MachineCodeEntryPoint(object): next = None # linked list @@ -827,7 +825,26 @@ self.mcentrypoints[argshash] = newcell self.mccounters[argshash] = -THRESHOLD_LIMIT-1 - def get_location_llstr(self, *greenargs): - return get_printable_location(*greenargs) + if can_inline_ptr is None: + def can_inline_callable(self, greenkey): + return True + else: + def can_inline_callable(self, greenkey): + args = self.unwrap_greenkey(greenkey) + fn = support.maybe_on_top_of_llinterp(rtyper, can_inline_ptr) + return fn(*args) + + if get_printable_location_ptr is None: + def get_location_str(self, greenkey): + return '(no jitdriver.get_printable_location!)' + else: + def get_location_str(self, greenkey): + args = self.unwrap_greenkey(greenkey) + fn = support.maybe_on_top_of_llinterp(rtyper, + get_printable_location_ptr) + res = fn(*args) + if we_are_translated() or not isinstance(res, str): + res = hlstr(res) + return res return WarmEnterState From cfbolz at codespeak.net Tue Aug 18 18:57:22 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 18:57:22 +0200 (CEST) Subject: [pypy-svn] r66934 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090818165722.21C83168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 18:57:21 2009 New Revision: 66934 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Log: (mikael, cfbolz): better coverage for switches Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Tue Aug 18 18:57:21 2009 @@ -345,6 +345,8 @@ else: return 42 res = self.interp_operations(f, [7]) assert res == 1212 + res = self.interp_operations(f, [12311]) + assert res == 42 def test_r_uint(self): from pypy.rlib.rarithmetic import r_uint @@ -407,6 +409,8 @@ return -1 res = self.interp_operations(f, [5]) assert res == 17 + res = self.interp_operations(f, [15]) + assert res == -1 def test_mod_ovf(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'y']) From cfbolz at codespeak.net Tue Aug 18 18:57:55 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 18:57:55 +0200 (CEST) Subject: [pypy-svn] r66935 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090818165755.1C75916802E@codespeak.net> Author: cfbolz Date: Tue Aug 18 18:57:54 2009 New Revision: 66935 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Log: (cfbolz, mikael): use really_remove_asserts for the JIT tests. unskip a now-working test. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py Tue Aug 18 18:57:54 2009 @@ -46,7 +46,8 @@ auto_inlining(t, threshold=inline) if backendoptimize: from pypy.translator.backendopt.all import backend_optimizations - backend_optimizations(t, inline_threshold=inline or 0) + backend_optimizations(t, inline_threshold=inline or 0, + remove_asserts=True, really_remove_asserts=True) #if conftest.option.view: # t.view() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Tue Aug 18 18:57:54 2009 @@ -651,7 +651,6 @@ assert not res def test_assert_isinstance(self): - py.test.skip("we would really like this to work") class A: pass class B(A): From benjamin at codespeak.net Tue Aug 18 19:14:26 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 19:14:26 +0200 (CEST) Subject: [pypy-svn] r66936 - pypy/branch/parser-compiler/pypy/module/_ast/test Message-ID: <20090818171426.97A9316801F@codespeak.net> Author: benjamin Date: Tue Aug 18 19:14:25 2009 New Revision: 66936 Modified: pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Log: rewrite get_ast exposing Modified: pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py ============================================================================== --- pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py (original) +++ pypy/branch/parser-compiler/pypy/module/_ast/test/test_ast.py Tue Aug 18 19:14:25 2009 @@ -1,14 +1,5 @@ import py -from pypy.interpreter import gateway - - -app = gateway.applevel("""def get_ast(source, mode="exec"): - import _ast as ast - mod = compile(source, "", mode, ast.PyCF_AST_ONLY) - assert isinstance(mod, ast.mod) - return mod""") - class AppTestAST: @@ -16,7 +7,13 @@ cls.w_ast = cls.space.appexec([], """(): import _ast return _ast""") - cls.w_get_ast = app.wget(cls.space, "get_ast") + cls.w_get_ast = cls.space.appexec([], """(): + def get_ast(source, mode="exec"): + import _ast as ast + mod = compile(source, "", mode, ast.PyCF_AST_ONLY) + assert isinstance(mod, ast.mod) + return mod + return get_ast""") def test_build_ast(self): ast = self.ast From cfbolz at codespeak.net Tue Aug 18 19:18:10 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 19:18:10 +0200 (CEST) Subject: [pypy-svn] r66937 - pypy/branch/pyjitpl5/pypy/translator Message-ID: <20090818171810.05B14168021@codespeak.net> Author: cfbolz Date: Tue Aug 18 19:18:07 2009 New Revision: 66937 Modified: pypy/branch/pyjitpl5/pypy/translator/driver.py Log: (mikael, cfbolz): enable removal of asserts in the pre-jit optimizations Modified: pypy/branch/pyjitpl5/pypy/translator/driver.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/driver.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/driver.py Tue Aug 18 19:18:07 2009 @@ -362,7 +362,8 @@ merge_if_blocks=True, constfold=True, raisingop2direct_call=False, - remove_asserts=False) + remove_asserts=True, + really_remove_asserts=True) # task_prejitbackendopt_lltype = taskdef( task_prejitbackendopt_lltype, @@ -376,7 +377,8 @@ merge_if_blocks=True, constfold=False, # XXX? raisingop2direct_call=False, - remove_asserts=False) + remove_asserts=True, + really_remove_asserts=True) # task_prejitbackendopt_ootype = taskdef( task_prejitbackendopt_ootype, From david at codespeak.net Tue Aug 18 19:23:08 2009 From: david at codespeak.net (david at codespeak.net) Date: Tue, 18 Aug 2009 19:23:08 +0200 (CEST) Subject: [pypy-svn] r66938 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090818172308.DDE7A16801F@codespeak.net> Author: david Date: Tue Aug 18 19:23:08 2009 New Revision: 66938 Modified: pypy/branch/io-lang/pypy/lang/io/coroutine.py pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Log: switching between coroutines Modified: pypy/branch/io-lang/pypy/lang/io/coroutine.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/coroutine.py (original) +++ pypy/branch/io-lang/pypy/lang/io/coroutine.py Tue Aug 18 19:23:08 2009 @@ -25,4 +25,8 @@ # print w_result # w_coro.slots['result'] = w_result # return w_coro -# \ No newline at end of file +# + + at register_method('Coroutine', 'resume') +def coroutine_switch(space, w_target, w_message, w_context): + w_target.switch() \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_coro.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_coro.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Tue Aug 18 19:23:08 2009 @@ -39,7 +39,6 @@ c := Coroutine currentCoroutine clone c setResult(99)""" res, space = interpret(inp) - print res.slots assert isinstance(res, W_Coroutine) assert res.slots['result'].value == 99 @@ -57,6 +56,15 @@ assert isinstance(res, W_Coroutine) assert res is space.w_lobby.slots['foo'].slots['parentCoroutine'] +def test_coro_result_last_value(): + inp = """ + c := Coroutine currentCoroutine clone + c setRunMessage(message(99)) + c run + c""" + res, space = interpret(inp) + assert res.slots['result'].value == 99 + def test_coro_resume(): py.test.skip() inp = """ @@ -68,6 +76,20 @@ res,space = interpret(inp) assert res.value == 23 +def test_coro_resume2(): + inp = """ + a := Coroutine currentCoroutine clone + b := Coroutine currentCoroutine clone + + a setRunMessage(message(b run; b resume; 4)) + b setRunMessage(message(a resume; 5)) + a run + a result + """ + res, space = interpret(inp) + assert res.value == 4 + assert space.w_lobby.slots['b'].slots['result'].value == 5 + def test_coro_stacksize(): inp = 'Coroutine clone stackSize' res, space = interpret(inp) From benjamin at codespeak.net Tue Aug 18 19:49:59 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 18 Aug 2009 19:49:59 +0200 (CEST) Subject: [pypy-svn] r66939 - pypy/branch/parser-compiler/pypy Message-ID: <20090818174959.C48C116801F@codespeak.net> Author: benjamin Date: Tue Aug 18 19:49:59 2009 New Revision: 66939 Modified: pypy/branch/parser-compiler/pypy/conftest.py Log: emulate pypyraises when running with -A Modified: pypy/branch/parser-compiler/pypy/conftest.py ============================================================================== --- pypy/branch/parser-compiler/pypy/conftest.py (original) +++ pypy/branch/parser-compiler/pypy/conftest.py Tue Aug 18 19:49:59 2009 @@ -185,13 +185,21 @@ # Interfacing/Integrating with py.test's collection process # # -def ensure_pytest_builtin_helpers(helpers='skip raises'.split()): + +def _pytest_raises_wrapper(*args, **kwargs): + """Emulate the API of appsupport.pypyraises.""" + __tracebackhide__ = True + return py.test.raises(*args, **kwargs)._excinfo + +def ensure_pytest_builtin_helpers(helpers='skip'.split()): """ hack (py.test.) raises and skip into builtins, needed for applevel tests to run directly on cpython but apparently earlier on "raises" was already added to module's globals. """ import __builtin__ + if not hasattr(__builtin__, "raises"): + __builtin__.raises = _pytest_raises_wrapper for helper in helpers: if not hasattr(__builtin__, helper): setattr(__builtin__, helper, getattr(py.test, helper)) From arigo at codespeak.net Tue Aug 18 19:53:01 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 19:53:01 +0200 (CEST) Subject: [pypy-svn] r66940 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090818175301.A2D7B16801F@codespeak.net> Author: arigo Date: Tue Aug 18 19:53:01 2009 New Revision: 66940 Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_history.py (contents, props changed) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Log: Tweak the repr of ConstPtrs to show exactly the class of the object that they contain. Test it. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Tue Aug 18 19:53:01 2009 @@ -43,7 +43,7 @@ def repr_pointer(box): from pypy.rpython.lltypesystem import rstr try: - T = box.value._obj.container._TYPE + T = box.value._obj.container._normalizedcontainer(check=False)._TYPE if T is rstr.STR: return repr(box._get_str()) return '*%s' % (T._name,) Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_history.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_history.py Tue Aug 18 19:53:01 2009 @@ -0,0 +1,11 @@ +from pypy.jit.metainterp.history import * +from pypy.rpython.lltypesystem import lltype, llmemory + + +def test_repr(): + S = lltype.GcStruct('S') + T = lltype.GcStruct('T', ('header', S)) + t = lltype.malloc(T) + s = lltype.cast_pointer(lltype.Ptr(S), t) + const = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) + assert const._getrepr_() == "*T" From arigo at codespeak.net Tue Aug 18 19:58:03 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Aug 2009 19:58:03 +0200 (CEST) Subject: [pypy-svn] r66941 - in pypy/branch/pyjitpl5/pypy/jit: metainterp tl Message-ID: <20090818175803.B146E16801F@codespeak.net> Author: arigo Date: Tue Aug 18 19:58:02 2009 New Revision: 66941 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: Fix: previously, some operations didn't have "name" and "pc" attributes any more. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Tue Aug 18 19:58:02 2009 @@ -901,6 +901,7 @@ liveboxes = resumebuilder.finish(resumedescr) op = history.ResOperation(rop.FAIL, liveboxes, None, descr=resumedescr) guard_op.suboperations = [op] + metainterp.attach_debug_info(guard_op) self.pc = saved_pc return guard_op @@ -1170,14 +1171,17 @@ # record the operation if not constant-folded away if not canfold: op = self.history.record(opnum, argboxes, resbox, descr) - if (not we_are_translated() and op is not None - and getattr(self, 'framestack', None)): - op.pc = self.framestack[-1].pc - op.name = self.framestack[-1].jitcode.name + self.attach_debug_info(op) if require_attention: self.after_generate_residual_call() return resbox + def attach_debug_info(self, op): + if (not we_are_translated() and op is not None + and getattr(self, 'framestack', None)): + op.pc = self.framestack[-1].pc + op.name = self.framestack[-1].jitcode.name + def _interpret(self): # Execute the frames forward until we raise a DoneWithThisFrame, # a ContinueRunningNormally, or a GenerateMergePoint exception. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py Tue Aug 18 19:58:02 2009 @@ -1,3 +1,5 @@ +from pypy.rlib.objectmodel import we_are_translated + class ResOperation(object): """The central ResOperation class, representing one operation.""" @@ -34,20 +36,23 @@ self.descr = descr def clone(self): - return ResOperation(self.opnum, self.args, self.result, self.descr) + op = ResOperation(self.opnum, self.args, self.result, self.descr) + if not we_are_translated(): + op.name = self.name + op.pc = self.pc + return op def __repr__(self): return self.repr() def repr(self): - from pypy.rlib.objectmodel import we_are_translated # RPython-friendly version if self.result is not None: sres = '%s = ' % (self.result,) else: sres = '' if self.name: - prefix = "%s:%s:" % (self.name, self.pc) + prefix = "%s:%s " % (self.name, self.pc) else: prefix = "" if self.descr is None or we_are_translated(): Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Tue Aug 18 19:58:02 2009 @@ -76,9 +76,10 @@ def read_code(): from pypy.module.marshal.interp_marshal import dumps - source = readfile('pypyjit_demo.py') + filename = 'pypyjit_demo.py' + source = readfile(filename) ec = space.getexecutioncontext() - code = ec.compiler.compile(source, '?', 'exec', 0) + code = ec.compiler.compile(source, filename, 'exec', 0) return llstr(space.str_w(dumps(space, code, space.wrap(2)))) if BACKEND == 'c': From cfbolz at codespeak.net Tue Aug 18 20:31:28 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 20:31:28 +0200 (CEST) Subject: [pypy-svn] r66942 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090818183128.E8B69168016@codespeak.net> Author: cfbolz Date: Tue Aug 18 20:31:27 2009 New Revision: 66942 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: rename InstanceValue to OptValue, as it is not only about instances. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Tue Aug 18 20:31:27 2009 @@ -36,7 +36,7 @@ LEVEL_CONSTANT = 3 -class InstanceValue(object): +class OptValue(object): _attrs_ = ('box', 'level') level = LEVEL_UNKNOWN @@ -92,7 +92,7 @@ return self.box is None -class ConstantValue(InstanceValue): +class ConstantValue(OptValue): level = LEVEL_CONSTANT def __init__(self, box): @@ -103,7 +103,7 @@ CVAL_NULLOBJ = ConstantValue(ConstObj(ConstObj.value)) -class AbstractVirtualValue(InstanceValue): +class AbstractVirtualValue(OptValue): _attrs_ = ('optimizer', 'keybox', 'source_op') box = None level = LEVEL_KNOWNCLASS @@ -130,7 +130,7 @@ return self._fields.get(ofs, default) def setfield(self, ofs, fieldvalue): - assert isinstance(fieldvalue, InstanceValue) + assert isinstance(fieldvalue, OptValue) self._fields[ofs] = fieldvalue def force_box(self): @@ -225,7 +225,7 @@ return res def setitem(self, index, itemvalue): - assert isinstance(itemvalue, InstanceValue) + assert isinstance(itemvalue, OptValue) self._items[index] = itemvalue def force_box(self): @@ -328,7 +328,7 @@ try: value = self.values[box] except KeyError: - value = self.values[box] = InstanceValue(box) + value = self.values[box] = OptValue(box) return value def is_constant(self, box): From cfbolz at codespeak.net Tue Aug 18 20:37:06 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Aug 2009 20:37:06 +0200 (CEST) Subject: [pypy-svn] r66943 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090818183706.82A5216801E@codespeak.net> Author: cfbolz Date: Tue Aug 18 20:37:05 2009 New Revision: 66943 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (pedronis) remember skipped tests Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Tue Aug 18 20:37:05 2009 @@ -52,6 +52,7 @@ - run random tests for x86 nightly - we need tests for pypy-jit behaviour that explicitely check whether the loops make sense +- the tragedy of the skipped tests things we know are missing --------------------------- @@ -62,7 +63,7 @@ - proper inlining logic - loop nesting (across calls) - we need to do something about constantness -- we need to do somethign about assert isinstance(x, Class) +- we need to do something about assert isinstance(x, Class) - more backendopt before jitting, assert removal - many ooisnull guards in a row From afa at codespeak.net Tue Aug 18 21:58:25 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 21:58:25 +0200 (CEST) Subject: [pypy-svn] r66944 - pypy/branch/asmgcc-mingw32 Message-ID: <20090818195825.4C3A316802B@codespeak.net> Author: afa Date: Tue Aug 18 21:58:24 2009 New Revision: 66944 Added: pypy/branch/asmgcc-mingw32/ - copied from r66943, pypy/branch/pyjitpl5/ Log: branch from pyjitpl5, and work on win32 support in trackgcroot (using the mingw32 compiler) From afa at codespeak.net Tue Aug 18 22:25:12 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 22:25:12 +0200 (CEST) Subject: [pypy-svn] r66945 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test Message-ID: <20090818202512.B64C816802B@codespeak.net> Author: afa Date: Tue Aug 18 22:25:11 2009 New Revision: 66945 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py Log: in-progress: enable the tests if the mingw32 compiler is on the PATH Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py Tue Aug 18 22:25:11 2009 @@ -7,7 +7,9 @@ from pypy import conftest if sys.platform == 'win32': - py.test.skip("No asmgcc on Windows") + if not ('mingw' in os.popen('gcc --version').read() and + 'GNU' in os.popen('make --version').read()): + py.test.skip("mingw32 and MSYS are required for asmgcc on Windows") class AbstractTestAsmGCRoot: # the asmgcroot gc transformer doesn't generate gc_reload_possibly_moved @@ -30,6 +32,8 @@ config = get_pypy_config(translating=True) config.translation.gc = self.gcpolicy config.translation.gcrootfinder = "asmgcc" + if sys.platform == 'win32': + config.translation.cc = 'mingw32' t = TranslationContext(config=config) self.t = t a = t.buildannotator() From afa at codespeak.net Tue Aug 18 22:40:01 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 22:40:01 +0200 (CEST) Subject: [pypy-svn] r66946 - pypy/branch/asmgcc-mingw32/pypy/translator/platform Message-ID: <20090818204001.20615168018@codespeak.net> Author: afa Date: Tue Aug 18 22:40:00 2009 New Revision: 66946 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py pypy/branch/asmgcc-mingw32/pypy/translator/platform/windows.py Log: Escape backslashes in makefile macros definitions Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py Tue Aug 18 22:40:00 2009 @@ -121,6 +121,7 @@ def write(self, f): def write_list(prefix, lst): for i, fn in enumerate(lst): + fn = fn.replace('\\', '\\\\') print >> f, prefix, fn, if i < len(lst)-1: print >> f, '\\' @@ -129,7 +130,7 @@ prefix = ' ' * len(prefix) name, value = self.name, self.value if isinstance(value, str): - f.write('%s = %s\n' % (name, value)) + f.write('%s = %s\n' % (name, value.replace('\\', '\\\\'))) else: write_list('%s =' % (name,), value) if value: Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/platform/windows.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/platform/windows.py Tue Aug 18 22:40:00 2009 @@ -280,4 +280,7 @@ def library_dirs_for_libffi(self): return [] - + def _handle_error(self, returncode, stderr, stdout, outname): + # Mingw tools write compilation errors to stdout + super(MingwPlatform, self)._handle_error( + returncode, stderr + stdout, '', outname) From afa at codespeak.net Tue Aug 18 22:54:14 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 22:54:14 +0200 (CEST) Subject: [pypy-svn] r66947 - pypy/branch/asmgcc-mingw32/pypy/translator/c/src Message-ID: <20090818205414.69E5C168018@codespeak.net> Author: afa Date: Tue Aug 18 22:54:13 2009 New Revision: 66947 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h Log: Fix a tiny compilation warning on win32 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h Tue Aug 18 22:54:13 2009 @@ -61,7 +61,7 @@ return GetCurrentThreadId(); } -static int +static void bootstrap(void *call) { callobj *obj = (callobj*)call; @@ -71,7 +71,6 @@ obj->id = RPyThreadGetIdent(); ReleaseSemaphore(obj->done, 1, NULL); func(); - return 0; } long RPyThreadStart(void (*func)(void)) From afa at codespeak.net Tue Aug 18 22:55:19 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 22:55:19 +0200 (CEST) Subject: [pypy-svn] r66948 - pypy/branch/asmgcc-mingw32/pypy/translator/c Message-ID: <20090818205519.567D6168018@codespeak.net> Author: afa Date: Tue Aug 18 22:55:17 2009 New Revision: 66948 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/genc.py Log: work around the lack of executable scripts on Windows Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/genc.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/genc.py Tue Aug 18 22:55:17 2009 @@ -489,8 +489,14 @@ mk.definition('GCMAPFILES', gcmapfiles) mk.definition('OBJECTS', '$(ASMFILES) gcmaptable.s') mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') - mk.rule('%.gcmap', '%.s', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1)') - mk.rule('gcmaptable.s', '$(GCMAPFILES)', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1)') + if sys.platform == 'win32': + python = sys.executable.replace('\\', '/') + ' ' + else: + python = "" + mk.rule('%.gcmap', '%.s', + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1)') + mk.rule('gcmaptable.s', '$(GCMAPFILES)', + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1)') mk.write() #self.translator.platform, From afa at codespeak.net Tue Aug 18 23:03:23 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:03:23 +0200 (CEST) Subject: [pypy-svn] r66949 - pypy/branch/asmgcc-mingw32/pypy/translator/platform Message-ID: <20090818210323.45FE0168018@codespeak.net> Author: afa Date: Tue Aug 18 23:03:22 2009 New Revision: 66949 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py Log: Use forward slashes for target names Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/platform/posix.py Tue Aug 18 23:03:22 2009 @@ -172,7 +172,8 @@ if fpath.dirpath() == self.makefile_dir: return fpath.basename elif fpath.dirpath().dirpath() == self.makefile_dir.dirpath(): - return '../' + fpath.relto(self.makefile_dir.dirpath()) + path = '../' + fpath.relto(self.makefile_dir.dirpath()) + return path.replace('\\', '/') else: return str(fpath) From afa at codespeak.net Tue Aug 18 23:13:12 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:13:12 +0200 (CEST) Subject: [pypy-svn] r66950 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc Message-ID: <20090818211312.3546616803A@codespeak.net> Author: afa Date: Tue Aug 18 23:13:11 2009 New Revision: 66950 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Log: Start parsing the assembler code. mingw32 format is very similar to darwin. Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Tue Aug 18 23:13:11 2009 @@ -188,8 +188,10 @@ if functionlines: yield in_function, functionlines + _find_functions_mingw32 = _find_functions_darwin + def process(self, iterlines, newfile, entrypoint='main', filename='?'): - if self.format == 'darwin': + if self.format in ('darwin', 'mingw32'): entrypoint = '_' + entrypoint for in_function, lines in self.find_functions(iterlines): if in_function: @@ -232,6 +234,9 @@ elif format == 'darwin': match = r_functionstart_darwin.match(lines[0]) funcname = '_'+match.group(1) + elif format == 'mingw32': + match = r_functionstart_darwin.match(lines[0]) + funcname = '_'+match.group(1) else: assert False, "unknown format: %s" % format @@ -1107,6 +1112,8 @@ break if sys.platform == 'darwin': format = 'darwin' + elif sys.platform == 'win32': + format = 'mingw32' else: format = 'elf' tracker = GcRootTracker(verbose=verbose, shuffle=shuffle, format=format) From afa at codespeak.net Tue Aug 18 23:26:25 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:26:25 +0200 (CEST) Subject: [pypy-svn] r66951 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc Message-ID: <20090818212625.668BD16803A@codespeak.net> Author: afa Date: Tue Aug 18 23:26:24 2009 New Revision: 66951 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Log: Handle __stdcall calling convention. More functions pass Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Tue Aug 18 23:26:24 2009 @@ -742,8 +742,15 @@ if lineoffset >= 0: assert lineoffset in (1,2) return [InsnStackAdjust(-4)] - return [InsnCall(self.currentlineno), - InsnSetLocal('%eax')] # the result is there + insns = [InsnCall(self.currentlineno), + InsnSetLocal('%eax')] # the result is there + if sys.platform == 'win32': + # handle __stdcall calling convention: + # Stack cleanup is performed by the called function, + # Function name is decorated with "@N" where N is the stack size + if match and '@' in target: + insns.append(InsnStackAdjust(int(target.split('@')[1]))) + return insns class UnrecognizedOperation(Exception): From afa at codespeak.net Tue Aug 18 23:34:25 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:34:25 +0200 (CEST) Subject: [pypy-svn] r66952 - pypy/branch/asmgcc-mingw32/pypy/translator/c/src Message-ID: <20090818213425.30A8816803A@codespeak.net> Author: afa Date: Tue Aug 18 23:34:24 2009 New Revision: 66952 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h Log: Remove some Win95 compatibility code (just like CPython 2.6), and there is no need to support analysis of __stdcall functions. Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/src/thread_nt.h Tue Aug 18 23:34:24 2009 @@ -129,69 +129,14 @@ /************************************************************/ -typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; - -/* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */ -static PVOID WINAPI interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand) -{ - static LONG spinlock = 0 ; - PVOID result ; - DWORD dwSleep = 0; - - /* Acqire spinlock (yielding control to other threads if cant aquire for the moment) */ - while(InterlockedExchange(&spinlock, 1)) - { - // Using Sleep(0) can cause a priority inversion. - // Sleep(0) only yields the processor if there's - // another thread of the same priority that's - // ready to run. If a high-priority thread is - // trying to acquire the lock, which is held by - // a low-priority thread, then the low-priority - // thread may never get scheduled and hence never - // free the lock. NT attempts to avoid priority - // inversions by temporarily boosting the priority - // of low-priority runnable threads, but the problem - // can still occur if there's a medium-priority - // thread that's always runnable. If Sleep(1) is used, - // then the thread unconditionally yields the CPU. We - // only do this for the second and subsequent even - // iterations, since a millisecond is a long time to wait - // if the thread can be scheduled in again sooner - // (~100,000 instructions). - // Avoid priority inversion: 0, 1, 0, 1,... - Sleep(dwSleep); - dwSleep = !dwSleep; - } - result = *dest ; - if (result == comperand) - *dest = exc ; - /* Release spinlock */ - spinlock = 0 ; - return result ; -} ; - -static interlocked_cmp_xchg_t *ixchg ; BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) { - if (!ixchg) - { - /* Sorely, Win95 has no InterlockedCompareExchange API (Win98 has), so we have to use emulation */ - HANDLE kernel = GetModuleHandle("kernel32.dll") ; - if (!kernel || (ixchg = (interlocked_cmp_xchg_t *)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL) - ixchg = interlocked_cmp_xchg ; - } - mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */ mutex->thread_id = 0 ; mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ; return mutex->hevent != NULL ; /* TRUE if the mutex is created */ } -#ifdef InterlockedCompareExchange -#undef InterlockedCompareExchange -#endif -#define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand))) - VOID DeleteNonRecursiveMutex(PNRMUTEX mutex) { /* No in-use check */ @@ -207,7 +152,7 @@ /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */ if (!wait) { - if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0, (PVOID)-1) != (PVOID)-1) + if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1) return WAIT_TIMEOUT ; ret = WAIT_OBJECT_0 ; } From afa at codespeak.net Tue Aug 18 23:49:18 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:49:18 +0200 (CEST) Subject: [pypy-svn] r66953 - pypy/branch/asmgcc-mingw32/pypy/translator/platform Message-ID: <20090818214918.D69D616803E@codespeak.net> Author: afa Date: Tue Aug 18 23:49:18 2009 New Revision: 66953 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/__init__.py Log: Increase the number of lines displayed when a command fails. We want to avoid the hundreds of errors that gcc generates when one forgets a header file; OTOH Makefiles run several commands and the relevant message was often truncated. Modified: pypy/branch/asmgcc-mingw32/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/platform/__init__.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/platform/__init__.py Tue Aug 18 23:49:18 2009 @@ -103,9 +103,9 @@ errorfile = outname.new(ext='errors') errorfile.write(stderr) stderrlines = stderr.splitlines() - for line in stderrlines[:20]: + for line in stderrlines[:50]: log.ERROR(line) - if len(stderrlines) > 20: + if len(stderrlines) > 50: log.ERROR('...') raise CompilationError(stdout, stderr) From afa at codespeak.net Tue Aug 18 23:52:31 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 18 Aug 2009 23:52:31 +0200 (CEST) Subject: [pypy-svn] r66954 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc Message-ID: <20090818215231.558B916803E@codespeak.net> Author: afa Date: Tue Aug 18 23:52:30 2009 New Revision: 66954 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Log: add mingw32 to the _variant() function. The error messages where something like "unknown directive"; the empty string seems to be the right choice. Now the program compiles and links. Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Tue Aug 18 23:52:30 2009 @@ -75,23 +75,22 @@ shapelines = [] shapeofs = 0 def _globalname(name): - if self.format == 'darwin': + if self.format in ('darwin', 'mingw32'): return '_' + name return name def _globl(name): print >> output, "\t.globl %s" % _globalname(name) def _label(name): print >> output, "%s:" % _globalname(name) - def _variant(elf, darwin): - if self.format == 'darwin': - txt = darwin - else: - txt = elf + def _variant(**kwargs): + txt = kwargs[self.format] print >> output, "\t%s" % txt - + print >> output, "\t.text" _globl('pypy_asm_stackwalk') - _variant('.type pypy_asm_stackwalk, @function', '') + _variant(elf='.type pypy_asm_stackwalk, @function', + darwin='', + mingw32='') _label('pypy_asm_stackwalk') print >> output, """\ /* See description in asmgcroot.py */ @@ -114,7 +113,9 @@ popl %eax ret """ - _variant('.size pypy_asm_stackwalk, .-pypy_asm_stackwalk', '') + _variant(elf='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk', + darwin='', + mingw32='') print >> output, '\t.data' print >> output, '\t.align\t4' _globl('__gcmapstart') @@ -135,7 +136,9 @@ print >> output, '\t.long\t%d' % (n,) _globl('__gcmapend') _label('__gcmapend') - _variant('.section\t.rodata', '.const') + _variant(elf='.section\t.rodata', + darwin='.const', + mingw32='') _globl('__gccallshapes') _label('__gccallshapes') output.writelines(shapelines) From afa at codespeak.net Wed Aug 19 00:13:54 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 19 Aug 2009 00:13:54 +0200 (CEST) Subject: [pypy-svn] r66955 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test Message-ID: <20090818221354.3DF2616803A@codespeak.net> Author: afa Date: Wed Aug 19 00:13:53 2009 New Revision: 66955 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py Log: Use double quotes to execute the program. All tests pass! Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/test/test_asmgcroot.py Wed Aug 19 00:13:53 2009 @@ -52,7 +52,7 @@ def run(): lines = [] print >> sys.stderr, 'RUN: starting', exe_name - g = os.popen("'%s'" % (exe_name,), 'r') + g = os.popen('"%s"' % (exe_name,), 'r') for line in g: print >> sys.stderr, 'RUN:', line.rstrip() lines.append(line) From cfbolz at codespeak.net Wed Aug 19 10:45:16 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 10:45:16 +0200 (CEST) Subject: [pypy-svn] r66957 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090819084516.A908616801D@codespeak.net> Author: cfbolz Date: Wed Aug 19 10:45:15 2009 New Revision: 66957 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Wed Aug 19 10:45:15 2009 @@ -4,16 +4,16 @@ - Samuele - Maciek - Carl Friedrich + - Benjamin - Mikael later: - - Benjamin - Anto discussions to be had: - - what goals/benchmarks do we want for the prototype - - things we know are missing - - state of the tests + - what goals/benchmarks do we want for the prototype DONE + - things we know are missing DONE + - state of the tests DONE - what to do with ootype - how will Eurostars work, how will work be organized @@ -85,7 +85,19 @@ look at tests -team 1: metainterp Armin, Carl Friedrich, Mikael -team 2: x86-backend Maciek, Samuele - - + - more or less full coverage for optimize*.py + - remove asserts before bytecode production DONE + - make pypyjit.py work again DONE + - add tests for x86 backend IN-PROGRESS + - make test_ll_random.py a bit better than before + - set up test_ll_random to run nightly + + - optimize generator closing DONE + - make x86 not recompile everything + - write more tests that cover recompilation (Samuele, Maciek) + - think about code memory management + - optimize chains of ooisnull/oononnull (Mikael, Carl Friedrich) + - discuss constantness improvements (everybody) + - don't trace into action flag stuff (Benjamin, Armin) + - bit of inlining before bytecode production + - inlining on the Python level From benjamin at codespeak.net Wed Aug 19 10:52:06 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 10:52:06 +0200 (CEST) Subject: [pypy-svn] r66958 - in pypy/branch/pyjitpl5/pypy: jit/metainterp/test rlib Message-ID: <20090819085206.87412168016@codespeak.net> Author: benjamin Date: Wed Aug 19 10:52:05 2009 New Revision: 66958 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/rlib/jit.py Log: (arigo, benjamin) add a dont_look_inside decorator Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Wed Aug 19 10:52:05 2009 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, we_are_jitted, hint +from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats from pypy.jit.backend.llgraph import runner from pypy.jit.metainterp import support, codewriter, pyjitpl, history @@ -792,6 +792,16 @@ assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 self.check_tree_loop_count(0) + def test_dont_look_inside(self): + @dont_look_inside + def g(a, b): + return a + b + def f(a, b): + return g(a, b) + res = self.interp_operations(f, [3, 5]) + assert res == 8 + self.check_history_(int_add=0, call=1) + class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Wed Aug 19 10:52:05 2009 @@ -9,6 +9,10 @@ def hint(x, **kwds): return x +def dont_look_inside(func): + func._look_inside_me_ = False + return func + class Entry(ExtRegistryEntry): _about_ = hint From benjamin at codespeak.net Wed Aug 19 10:57:29 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 10:57:29 +0200 (CEST) Subject: [pypy-svn] r66959 - pypy/branch/pyjitpl5/pypy/interpreter Message-ID: <20090819085729.967AC168016@codespeak.net> Author: benjamin Date: Wed Aug 19 10:57:28 2009 New Revision: 66959 Modified: pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py Log: dont look into action_dispatcher for the jit Modified: pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py Wed Aug 19 10:57:28 2009 @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib import jit def new_framestack(): return Stack() @@ -340,6 +341,7 @@ nonperiodic_actions = unrolling_iterable(self._nonperiodic_actions) has_bytecode_counter = self.has_bytecode_counter + @jit.dont_look_inside def action_dispatcher(ec, frame): # periodic actions if has_bytecode_counter: From fijal at codespeak.net Wed Aug 19 11:02:18 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 11:02:18 +0200 (CEST) Subject: [pypy-svn] r66960 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090819090218.E764616800E@codespeak.net> Author: fijal Date: Wed Aug 19 11:02:18 2009 New Revision: 66960 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py Log: (pedronis, fijal) Support for a jump to self Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py Wed Aug 19 11:02:18 2009 @@ -204,6 +204,8 @@ jump.jump_target = loop else: for jump, jump_target in zip(self.jumps, self.jump_targets): + if jump_target == 'self': + jump_target = loop jump.jump_target = jump_target loop.operations = ops loop.inputargs = inpargs Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_oparser.py Wed Aug 19 11:02:18 2009 @@ -129,3 +129,14 @@ loop = parse(x, jump_targets=[obj]) assert loop.operations[0].jump_target is obj +def test_jump_target_self(): + x = ''' + [i2] + guard_true(i2) + jump() + jump() + ''' + obj = object() + loop = parse(x, jump_targets=[obj, 'self']) + assert loop.operations[-1].jump_target is loop + assert loop.operations[0].suboperations[0].jump_target is obj From benjamin at codespeak.net Wed Aug 19 11:25:00 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 11:25:00 +0200 (CEST) Subject: [pypy-svn] r66961 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090819092500.CAECA168011@codespeak.net> Author: benjamin Date: Wed Aug 19 11:24:58 2009 New Revision: 66961 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: avoid an unneeded dict lookup Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Wed Aug 19 11:24:58 2009 @@ -140,8 +140,8 @@ newoperations = self.optimizer.newoperations newoperations.append(self.source_op) self.box = box = self.source_op.result - for ofs in self._fields: - subbox = self._fields[ofs].force_box() + for ofs, value in self._fields.iteritems(): + subbox = value.force_box() op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) newoperations.append(op) From arigo at codespeak.net Wed Aug 19 12:25:03 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 12:25:03 +0200 (CEST) Subject: [pypy-svn] r66962 - pypy/branch/pyjitpl5/pypy/rlib Message-ID: <20090819102503.5145B168012@codespeak.net> Author: arigo Date: Wed Aug 19 12:25:02 2009 New Revision: 66962 Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py Log: Forgot to check this in. Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Wed Aug 19 12:25:02 2009 @@ -88,9 +88,6 @@ } unroll_parameters = unrolling_iterable(PARAMETERS.keys()) -def _no_printable_location(*greenargs): - return '(no jitdriver.get_printable_location!)' - # ____________________________________________________________ class JitDriver: @@ -103,8 +100,7 @@ virtualizables = [] def __init__(self, greens=None, reds=None, virtualizables=None, - get_printable_location=_no_printable_location, - can_inline=None): + can_inline=None, get_printable_location=None): if greens is not None: self.greens = greens if reds is not None: From fijal at codespeak.net Wed Aug 19 12:28:01 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 12:28:01 +0200 (CEST) Subject: [pypy-svn] r66963 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090819102801.33CDC168013@codespeak.net> Author: fijal Date: Wed Aug 19 12:28:00 2009 New Revision: 66963 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) Improve test coverage of assembler.py Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 12:28:00 2009 @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.runner import CPU from pypy.jit.metainterp.test.oparser import parse -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.annlowlevel import llhelper class TestRegalloc(object): @@ -16,25 +16,39 @@ namespace = locals().copy() type_system = 'lltype' - def parse(self, s, boxkinds=None): + def parse(self, s, boxkinds=None, jump_targets=None): return parse(s, self.cpu, self.namespace, type_system=self.type_system, + jump_targets=jump_targets, boxkinds=boxkinds) - def interpret(self, ops, args): - loop = self.parse(ops) + def interpret(self, ops, args, jump_targets=None): + loop = self.parse(ops, jump_targets=jump_targets) self.cpu.compile_operations(loop) for i, arg in enumerate(args): if isinstance(arg, int): self.cpu.set_future_value_int(i, arg) else: - raise NotImplementedError("Arg: %s" % arg) + assert isinstance(lltype.typeOf(arg), lltype.Ptr) + llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) + self.cpu.set_future_value_ptr(i, llgcref) self.cpu.execute_operations(loop) return loop def getint(self, index): return self.cpu.get_latest_value_int(index) + def getptr(self, index, T): + gcref = self.cpu.get_latest_value_ptr(index) + return lltype.cast_opaque_ptr(T, gcref) + + def attach_bridge(self, ops, loop, guard_op): + assert guard_op.is_guard() + bridge = self.parse(ops) + guard_op.suboperations = bridge.operations + self.cpu.compile_operations(loop, guard_op) + return bridge + def test_simple_loop(self): ops = ''' [i0] @@ -66,10 +80,7 @@ i6 = int_add(i5, 1) fail(i3, i4, i5, i6) ''' - bridge = self.parse(ops) - guard_op = loop.operations[-2] - guard_op.suboperations = bridge.operations - self.cpu.compile_operations(loop, guard_op) + bridge = self.attach_bridge(ops, loop, loop.operations[-2]) self.cpu.set_future_value_int(0, 0) op = self.cpu.execute_operations(loop) assert op is bridge.operations[-1] @@ -77,4 +88,45 @@ assert self.getint(1) == 22 assert self.getint(2) == 23 assert self.getint(3) == 24 - + + def test_two_loops_and_a_bridge(self): + ops = ''' + [i0, i1, i2, i3] + i4 = int_add(i0, 1) + i5 = int_lt(i4, 20) + guard_true(i5) + fail(i4, i1, i2, i3) + jump(i4, i1, i2, i3) + ''' + loop = self.interpret(ops, [0]) + ops2 = ''' + [i5] + i1 = int_add(i5, 1) + i3 = int_add(i1, 1) + i4 = int_add(i3, 1) + i2 = int_lt(i4, 30) + guard_true(i2) + jump(i4, i4, i4, i4) + jump(i4) + ''' + loop2 = self.interpret(ops2, [0], jump_targets=[loop, 'self']) + assert self.getint(0) == 31 + assert self.getint(1) == 30 + assert self.getint(2) == 30 + assert self.getint(3) == 30 + + def test_pointer_arg(self): + ops = ''' + [i0, p0] + i1 = int_add(i0, 1) + i2 = int_lt(i1, 10) + guard_true(i2) + fail(p0) + jump(i1, p0) + ''' + S = lltype.GcStruct('S') + ptr = lltype.malloc(S) + self.interpret(ops, [0, ptr]) + assert self.getptr(0, lltype.Ptr(S)) == ptr + assert not self.cpu.assembler.fail_boxes_ptr[0] + assert not self.cpu.assembler.fail_boxes_ptr[1] From arigo at codespeak.net Wed Aug 19 12:34:55 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 12:34:55 +0200 (CEST) Subject: [pypy-svn] r66964 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090819103455.7E65E168013@codespeak.net> Author: arigo Date: Wed Aug 19 12:34:55 2009 New Revision: 66964 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: Add a task. Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Wed Aug 19 12:34:55 2009 @@ -66,6 +66,8 @@ - we need to do something about assert isinstance(x, Class) - more backendopt before jitting, assert removal - many ooisnull guards in a row +- remove the numerous checks for frame.vable_rti in the + interpreter (non-JITting) part - speed of tracing and fallbacks? From micke at codespeak.net Wed Aug 19 12:39:53 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Wed, 19 Aug 2009 12:39:53 +0200 (CEST) Subject: [pypy-svn] r66966 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090819103953.F2A31168013@codespeak.net> Author: micke Date: Wed Aug 19 12:39:53 2009 New Revision: 66966 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (cfbolz, micke): optimize series of ooisnull and oononnull on the same object Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Wed Aug 19 12:39:53 2009 @@ -85,12 +85,27 @@ if self.level < LEVEL_NONNULL: self.level = LEVEL_NONNULL + def make_null_or_nonnull(self): + if self.box.nonnull(): + self.make_nonnull() + else: + self.make_constant() + def is_virtual(self): # Don't check this with 'isinstance(_, VirtualValue)'! # Even if it is a VirtualValue, the 'box' can be non-None, # meaning it has been forced. return self.box is None +class BoolValue(OptValue): + + def __init__(self, box, fromvalue): + OptValue.__init__(self, box) + self.fromvalue = fromvalue + + def make_constant(self): + OptValue.make_constant(self) + self.fromvalue.make_null_or_nonnull() class ConstantValue(OptValue): level = LEVEL_CONSTANT @@ -364,6 +379,11 @@ self.make_equal_to(box, vvalue) return vvalue + def make_bool(self, box, fromvalue): + value = BoolValue(box, fromvalue) + self.make_equal_to(box, value) + return value + def new_ptr_box(self): if not self.cpu.is_oo: return BoxPtr() @@ -536,19 +556,22 @@ self.emit_operation(op) self.exception_might_have_happened = False - def optimize_OONONNULL(self, op): + def _optimize_nullness(self, op, expect_nonnull): if self.known_nonnull(op.args[0]): - assert op.result.getint() == 1 + assert op.result.getint() == expect_nonnull + self.make_constant(op.result) + elif self.is_constant(op.args[0]): # known to be null + assert op.result.getint() == (not expect_nonnull) self.make_constant(op.result) else: - self.optimize_default(op) + self.make_bool(op.result, self.getvalue(op.args[0])) + self.emit_operation(op) + + def optimize_OONONNULL(self, op): + self._optimize_nullness(op, True) def optimize_OOISNULL(self, op): - if self.known_nonnull(op.args[0]): - assert op.result.getint() == 0 - self.make_constant(op.result) - else: - self.optimize_default(op) + self._optimize_nullness(op, False) def optimize_OOISNOT(self, op): value0 = self.getvalue(op.args[0]) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Wed Aug 19 12:39:53 2009 @@ -245,7 +245,6 @@ self.optimize_loop(ops, 'Not', expected, i0=1, i1=0) def test_ooisnull_oononnull_2(self): - py.test.skip("less important") ops = """ [p0] i0 = oononnull(p0) # p0 != NULL @@ -263,7 +262,32 @@ fail() jump(p0) """ - self.optimize_loop(ops, 'Not', expected, i0=1, i1=0) + self.optimize_loop(ops, 'Not', expected, i0=1, i1=0, + p0=self.nodebox.value) + + def test_ooisnull_oononnull_via_virtual(self): + ops = """ + [p0] + pv = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(pv, p0, descr=valuedescr) + i0 = oononnull(p0) # p0 != NULL + guard_true(i0) + fail() + p1 = getfield_gc(pv, descr=valuedescr) + i1 = ooisnull(p1) + guard_false(i1) + fail() + jump(p0) + """ + expected = """ + [p0] + i0 = oononnull(p0) + guard_true(i0) + fail() + jump(p0) + """ + self.optimize_loop(ops, 'Not', expected, i0=1, i1=0, + p0=self.nodebox.value) def test_oois_1(self): ops = """ @@ -556,21 +580,6 @@ i1 = oononnull(p0) guard_true(i1) fail() - i2 = ooisnull(p0) - guard_false(i2) - fail() - i3 = oononnull(p0) - guard_true(i3) - fail() - i4 = ooisnull(p0) - guard_false(i4) - fail() - i5 = oononnull(p0) - guard_true(i5) - fail() - i6 = ooisnull(p0) - guard_false(i6) - fail() i7 = ooisnot(p0, p1) guard_true(i7) fail() From cfbolz at codespeak.net Wed Aug 19 13:03:31 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 13:03:31 +0200 (CEST) Subject: [pypy-svn] r66967 - in pypy/branch/pyjitpl5/pypy/translator/backendopt: . test Message-ID: <20090819110331.C8AB6168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 13:03:30 2009 New Revision: 66967 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Log: make the jit inliner not inline pure functions Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Wed Aug 19 13:03:30 2009 @@ -630,7 +630,8 @@ try: oopspec = graph.func.oopspec except AttributeError: - return inlining_heuristic(graph) + if not getattr(getattr(graph, "func", None), "_pure_function_", False): + return inlining_heuristic(graph) return (sys.maxint, True) def inlinable_static_callers(graphs): Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Wed Aug 19 13:03:30 2009 @@ -629,20 +629,25 @@ assert res == 5 def test_no_oopspec_inliner(self): - def f(): + from pypy.rlib.jit import purefunction + @purefunction + def g(x): + return x + 1 + + def f(x): tot = 0 - for item in [1,2,3]: + for item in [1,2,g(x)]: tot += item return tot eval_func, t = self.check_auto_inlining( - f, [], heuristic=inlining_heuristic_no_oopspec) + f, [int], heuristic=inlining_heuristic_no_oopspec) f_graph = graphof(t, f) called_graphs = collect_called_graphs(f_graph, t, include_oosend=False) print called_graphs - assert len(called_graphs) == 4 # newlist, setitem, getitem, length + assert len(called_graphs) == 5 # g, newlist, setitem, getitem, length - result = eval_func([]) + result = eval_func([2]) assert result == 6 From cfbolz at codespeak.net Wed Aug 19 13:04:41 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 13:04:41 +0200 (CEST) Subject: [pypy-svn] r66968 - in pypy/branch/pyjitpl5/pypy/translator/backendopt: . test Message-ID: <20090819110441.786C1168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 13:04:40 2009 New Revision: 66968 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Log: (micke, cfbolz): rename the heuristic to be called jit, because it does more than just not inline oopspec stuff Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Wed Aug 19 13:04:40 2009 @@ -626,7 +626,7 @@ return (0.9999 * measure_median_execution_cost(graph) + count), True -def inlining_heuristic_no_oopspec(graph): +def inlining_heuristic_jit(graph): try: oopspec = graph.func.oopspec except AttributeError: Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Wed Aug 19 13:04:40 2009 @@ -9,7 +9,7 @@ from pypy.translator.backendopt.inline import collect_called_graphs from pypy.translator.backendopt.inline import measure_median_execution_cost from pypy.translator.backendopt.inline import instrument_inline_candidates -from pypy.translator.backendopt.inline import inlining_heuristic_no_oopspec +from pypy.translator.backendopt.inline import inlining_heuristic_jit from pypy.translator.backendopt.checkvirtual import check_virtual_methods from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.llinterp import LLInterpreter @@ -628,7 +628,7 @@ res = eval_func([]) assert res == 5 - def test_no_oopspec_inliner(self): + def test_jit_inliner(self): from pypy.rlib.jit import purefunction @purefunction def g(x): @@ -641,7 +641,7 @@ return tot eval_func, t = self.check_auto_inlining( - f, [int], heuristic=inlining_heuristic_no_oopspec) + f, [int], heuristic=inlining_heuristic_jit) f_graph = graphof(t, f) called_graphs = collect_called_graphs(f_graph, t, include_oosend=False) print called_graphs From fijal at codespeak.net Wed Aug 19 13:11:48 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 13:11:48 +0200 (CEST) Subject: [pypy-svn] r66969 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090819111148.7391E168013@codespeak.net> Author: fijal Date: Wed Aug 19 13:11:48 2009 New Revision: 66969 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: (pedronis, fijal) Add more tests Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Wed Aug 19 13:11:48 2009 @@ -9,6 +9,9 @@ from pypy.rpython.ootypesystem import ootype from pypy.jit.metainterp.executor import execute from pypy.rlib.rarithmetic import r_uint, intmask +from pypy.jit.metainterp.test.oparser import parse +from pypy.rpython.annlowlevel import llhelper +from pypy.rpython.llinterp import LLException class Runner(object): @@ -70,7 +73,6 @@ class BaseBackendTest(Runner): def test_do_call(self): - from pypy.rpython.annlowlevel import llhelper cpu = self.cpu # def func(c): @@ -85,7 +87,6 @@ assert x.value == ord('B') def test_call(self): - from pypy.rpython.annlowlevel import llhelper cpu = self.cpu # def func(c): @@ -252,6 +253,53 @@ assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() + def test_exceptions(self): + def func(i): + if i: + raise LLException(zdtp, zdptr) + + ops = ''' + [i0] + call(ConstClass(fptr), i0, descr=calldescr) + p0 = guard_exception(ConstClass(zdtp)) + fail(1) + fail(0) + ''' + FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) + fptr = llhelper(FPTR, func) + calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) + zdtp, zdptr = self.cpu.get_zero_division_error() + zd_addr = self.cpu.cast_int_to_adr(zdtp) + zdtp = llmemory.cast_adr_to_ptr(zd_addr, lltype.Ptr(self.MY_VTABLE)) + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 0 + self.cpu.clear_exception() + self.cpu.set_future_value_int(0, 0) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + + ops = ''' + [i0] + call(ConstClass(fptr), i0, descr=calldescr) + guard_no_exception() + fail(1) + fail(0) + ''' + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + self.cpu.set_future_value_int(0, 0) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 0 + self.cpu.clear_exception() + def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) @@ -500,7 +548,7 @@ r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(4)], 'int') assert r.value == 31313 - u_box = self.cpu.do_newunicode([ConstInt(3)]) + u_box = self.cpu.do_newunicode([ConstInt(5)]) self.cpu.do_unicodesetitem([u_box, BoxInt(4), BoxInt(123)]) r = self.cpu.do_unicodegetitem([u_box, BoxInt(4)]) assert r.value == 123 From micke at codespeak.net Wed Aug 19 13:13:23 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Wed, 19 Aug 2009 13:13:23 +0200 (CEST) Subject: [pypy-svn] r66970 - in pypy/branch/pyjitpl5/pypy/translator/backendopt: . test Message-ID: <20090819111323.CA39B168013@codespeak.net> Author: micke Date: Wed Aug 19 13:13:23 2009 New Revision: 66970 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Log: (cbolz, micke): do not inline functions marked _dont_look_inside_ if you use the jit heuristic Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Wed Aug 19 13:13:23 2009 @@ -627,11 +627,15 @@ count), True def inlining_heuristic_jit(graph): + func = getattr(graph, "func", None) try: oopspec = graph.func.oopspec except AttributeError: - if not getattr(getattr(graph, "func", None), "_pure_function_", False): - return inlining_heuristic(graph) + if getattr(func, "_pure_function_", False): + return (sys.maxint, True) + elif not getattr(func, "_look_inside_me_", True): + return (sys.maxint, True) + return inlining_heuristic(graph) return (sys.maxint, True) def inlinable_static_callers(graphs): Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Wed Aug 19 13:13:23 2009 @@ -629,14 +629,17 @@ assert res == 5 def test_jit_inliner(self): - from pypy.rlib.jit import purefunction + from pypy.rlib.jit import purefunction, dont_look_inside @purefunction def g(x): return x + 1 + @dont_look_inside + def h(x): + return x + 2 def f(x): tot = 0 - for item in [1,2,g(x)]: + for item in [1,2,g(x),h(x)]: tot += item return tot @@ -645,10 +648,10 @@ f_graph = graphof(t, f) called_graphs = collect_called_graphs(f_graph, t, include_oosend=False) print called_graphs - assert len(called_graphs) == 5 # g, newlist, setitem, getitem, length + assert len(called_graphs) == 6 # g, h, newlist, setitem, getitem, length result = eval_func([2]) - assert result == 6 + assert result == 10 From fijal at codespeak.net Wed Aug 19 15:11:13 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 15:11:13 +0200 (CEST) Subject: [pypy-svn] r66971 - in pypy/branch/pyjitpl5/pypy/jit/backend: test x86 x86/test Message-ID: <20090819131113.7C12C168014@codespeak.net> Author: fijal Date: Wed Aug 19 15:11:11 2009 New Revision: 66971 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) Cover assembler.py fully by unittests Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Wed Aug 19 15:11:11 2009 @@ -87,18 +87,30 @@ assert x.value == ord('B') def test_call(self): - cpu = self.cpu - # - def func(c): - return chr(ord(c) + 1) - FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char)) - func_ptr = llhelper(FPTR, func) - calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char) - res = self.execute_operation(rop.CALL, - [self.get_funcbox(cpu, func_ptr), - BoxInt(ord('A'))], - 'int', descr=calldescr) - assert res.value == ord('B') + + def func_int(a, b): + return a + b + def func_char(c, c1): + return chr(ord(c) + ord(c1)) + + functions = [ + (func_int, lltype.Signed, 655360), + (func_int, rffi.SHORT, 1213), + (func_char, lltype.Char, 12) + ] + + for func, TP, num in functions: + cpu = self.cpu + # + FPTR = self.Ptr(self.FuncType([TP, TP], TP)) + func_ptr = llhelper(FPTR, func) + FUNC = deref(FPTR) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) + res = self.execute_operation(rop.CALL, + [self.get_funcbox(cpu, func_ptr), + BoxInt(num), BoxInt(num)], + 'int', descr=calldescr) + assert res.value == 2 * num def test_executor(self): cpu = self.cpu @@ -263,7 +275,7 @@ call(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(zdtp)) fail(1) - fail(0) + fail(0, p0) ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -276,6 +288,7 @@ self.cpu.set_future_value_int(0, 1) self.cpu.execute_operations(loop) assert self.cpu.get_latest_value_int(0) == 0 + assert self.cpu.get_latest_value_ptr(1) == zdptr self.cpu.clear_exception() self.cpu.set_future_value_int(0, 0) self.cpu.execute_operations(loop) @@ -316,16 +329,23 @@ # fielddescr1 = self.cpu.fielddescrof(self.S, 'chr1') fielddescr2 = self.cpu.fielddescrof(self.S, 'chr2') + shortdescr = self.cpu.fielddescrof(self.S, 'short') self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(250)], 'void', descr=fielddescr2) self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(133)], 'void', descr=fielddescr1) + self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(1331)], + 'void', descr=shortdescr) res = self.execute_operation(rop.GETFIELD_GC, [t_box], 'int', descr=fielddescr2) assert res.value == 250 res = self.execute_operation(rop.GETFIELD_GC, [t_box], 'int', descr=fielddescr1) assert res.value == 133 + res = self.execute_operation(rop.GETFIELD_GC, [t_box], + 'int', descr=shortdescr) + assert res.value == 1331 + # u_box, U_box = self.alloc_instance(self.U) fielddescr2 = self.cpu.fielddescrof(self.S, 'next') Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Wed Aug 19 15:11:11 2009 @@ -768,8 +768,6 @@ x = rel32(op.args[0].getint()) else: x = arglocs[0] - if isinstance(x, MODRM): - x = stack_pos(x.position) self.mc.CALL(x) self.mark_gc_roots() self.mc.ADD(esp, imm(WORD * extra_on_stack)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 15:11:11 2009 @@ -9,10 +9,23 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.annlowlevel import llhelper +from pypy.rpython.lltypesystem import rclass class TestRegalloc(object): cpu = CPU(None, None) + def raising_func(i): + if i: + raise LLException(zero_division_error, + zero_division_value) + FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) + raising_fptr = llhelper(FPTR, raising_func) + zero_division_tp, zero_division_value = cpu.get_zero_division_error() + zd_addr = cpu.cast_int_to_adr(zero_division_tp) + zero_division_error = llmemory.cast_adr_to_ptr(zd_addr, + lltype.Ptr(rclass.OBJECT_VTABLE)) + raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) + namespace = locals().copy() type_system = 'lltype' @@ -130,3 +143,18 @@ assert self.getptr(0, lltype.Ptr(S)) == ptr assert not self.cpu.assembler.fail_boxes_ptr[0] assert not self.cpu.assembler.fail_boxes_ptr[1] + + def test_exception_bridge_no_exception(self): + + + ops = ''' + [i0] + call(ConstClass(raising_fptr), i0, descr=raising_calldescr) + guard_exception(ConstClass(zero_division_error)) + guard_no_exception() + fail(2) + fail(1) + fail(0) + ''' + self.interpret(ops, [0]) + assert self.getint(0) == 1 From fijal at codespeak.net Wed Aug 19 15:13:12 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 15:13:12 +0200 (CEST) Subject: [pypy-svn] r66972 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090819131312.6E65A168014@codespeak.net> Author: fijal Date: Wed Aug 19 15:13:12 2009 New Revision: 66972 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: typo Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 15:13:12 2009 @@ -12,7 +12,7 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop -# esi edi and ebp can be added to this list, provided they're correctly +# esi edi and ebx can be added to this list, provided they're correctly # saved and restored REGS = [eax, ecx, edx] WORD = 4 From micke at codespeak.net Wed Aug 19 15:18:25 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Wed, 19 Aug 2009 15:18:25 +0200 (CEST) Subject: [pypy-svn] r66973 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090819131825.E662B168014@codespeak.net> Author: micke Date: Wed Aug 19 15:18:22 2009 New Revision: 66973 Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py Log: (cfbolz, micke): add an all_graphs() helper method to the JitPolicy Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py Wed Aug 19 15:18:22 2009 @@ -73,6 +73,10 @@ return 'residual' return 'regular' + def all_graphs(self, translator): + return [graph for graph in translator.graphs + if self.look_inside_graph(graph)] + def contains_unsupported_variable_type(graph): getkind = history.getkind try: Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py Wed Aug 19 15:18:22 2009 @@ -0,0 +1,24 @@ +from pypy.jit.metainterp import policy, support +from pypy.rlib.jit import purefunction, dont_look_inside + +def test_all_graphs(): + def f(x): + return x + 1 + @purefunction + def g(x): + return x + 2 + @dont_look_inside + def h(x): + return x + 3 + def i(x): + return f(x) * g(x) * h(x) + + rtyper = support.annotate(i, [7]) + + jitpolicy = policy.JitPolicy() + res = jitpolicy.all_graphs(rtyper.annotator.translator) + + funcs = [graph.func for graph in res] + assert funcs[:2] == [i, f] + assert g not in funcs + assert h not in funcs From fijal at codespeak.net Wed Aug 19 15:32:02 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 15:32:02 +0200 (CEST) Subject: [pypy-svn] r66974 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090819133202.D0139168013@codespeak.net> Author: fijal Date: Wed Aug 19 15:32:02 2009 New Revision: 66974 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: (pedronis, fijal) Remove some carefulness code, since this case should not occur any more. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 15:32:02 2009 @@ -250,14 +250,11 @@ if (operations[i + 1].opnum != rop.GUARD_TRUE and operations[i + 1].opnum != rop.GUARD_FALSE): return False - if operations[i + 1].args[0] is not op.result: - return False - if self.longevity[op.result][1] > i + 1: - return False - if op.result in operations[i + 1].inputargs: - # XXX implement optimization that replace var with a const - # not right now - return False + if (operations[i + 1].args[0] is not op.result or + self.longevity[op.result][1] > i + 1 or + op.result in operations[i + 1].inputargs): + print "boolean flag not optimized away" + assert False return True def walk_operations(self, tree): From fijal at codespeak.net Wed Aug 19 15:51:35 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 15:51:35 +0200 (CEST) Subject: [pypy-svn] r66975 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090819135135.E9008168012@codespeak.net> Author: fijal Date: Wed Aug 19 15:51:35 2009 New Revision: 66975 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Log: Make inheritance a bit better Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Wed Aug 19 15:51:35 2009 @@ -890,7 +890,7 @@ -class TestLLtype(BasicTests, LLJitMixin): +class BaseLLtypeTests(BasicTests): def test_oops_on_nongc(self): from pypy.rpython.lltypesystem import lltype @@ -918,3 +918,6 @@ x = lltype.malloc(TP) expected = lltype.cast_opaque_ptr(llmemory.GCREF, x) assert self.interp_operations(f, [x]) == expected + +class TestLLtype(BaseLLtypeTests, LLJitMixin): + pass From fijal at codespeak.net Wed Aug 19 16:00:42 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 16:00:42 +0200 (CEST) Subject: [pypy-svn] r66977 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090819140042.1EF2E16800D@codespeak.net> Author: fijal Date: Wed Aug 19 16:00:41 2009 New Revision: 66977 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: (pedronis, fijal) Add const version of those operations Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Wed Aug 19 16:00:41 2009 @@ -660,6 +660,11 @@ [BoxPtr(x)], 'int').value res2 = self.execute_operation(rop.CAST_INT_TO_PTR, [BoxInt(res)], 'ptr').value + x = lltype.cast_opaque_ptr(llmemory.GCREF, x) + res = self.execute_operation(rop.CAST_PTR_TO_INT, + [ConstPtr(x)], 'int').value + res2 = self.execute_operation(rop.CAST_INT_TO_PTR, + [ConstInt(res)], 'ptr').value assert res2 == x def test_ooops_non_gc(self): From fijal at codespeak.net Wed Aug 19 16:02:40 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 16:02:40 +0200 (CEST) Subject: [pypy-svn] r66978 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819140240.9E820168010@codespeak.net> Author: fijal Date: Wed Aug 19 16:02:40 2009 New Revision: 66978 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) * A bit of code sanitization * Inherit correct tests from test_basic Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Wed Aug 19 16:02:40 2009 @@ -461,6 +461,8 @@ def genop_same_as(self, op, arglocs, resloc): self.mc.MOV(resloc, arglocs[0]) + genop_cast_int_to_ptr = genop_same_as + genop_cast_ptr_to_int = genop_same_as def genop_int_mod(self, op, arglocs, resloc): self.mc.CDQ() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 16:02:40 2009 @@ -283,20 +283,16 @@ op = operations[i] self.position = i if op.has_no_side_effect() and op.result not in self.longevity: - canfold = True + print "Operation has no side effect, but was not removed" + assert False + if self.can_optimize_cmp_op(op, i, operations): + nothing = oplist[op.opnum](self, op, operations[i + 1]) + i += 1 else: - canfold = False - if not canfold: - if self.can_optimize_cmp_op(op, i, operations): - nothing = oplist[op.opnum](self, op, operations[i + 1]) - i += 1 - else: - nothing = oplist[op.opnum](self, op, None) - assert nothing is None # temporary, remove me - self.eventually_free_var(op.result) - self._check_invariants() - else: - self.eventually_free_vars(op.args) + nothing = oplist[op.opnum](self, op, None) + assert nothing is None # temporary, remove me + self.eventually_free_var(op.result) + self._check_invariants() i += 1 assert not self.reg_bindings jmp = operations[-1] @@ -429,12 +425,6 @@ self.reg_bindings[v] = loc return loc - def allocate_new_loc(self, v): - reg = self.try_allocate_reg(v) - if reg: - return reg - return self.stack_loc(v) - def return_constant(self, v, forbidden_vars, selected_reg=None, imm_fine=True): assert isinstance(v, Const) @@ -998,25 +988,6 @@ consider_getfield_raw = consider_getfield_gc consider_getarrayitem_gc_pure = consider_getarrayitem_gc - def _same_as(self, op, ignored): - x = op.args[0] - if isinstance(x, Const): - pos = self.allocate_new_loc(op.result) - self.Load(op.result, self.loc(x), pos) - return - if self.longevity[x][1] > self.position or x not in self.reg_bindings: - if x in self.reg_bindings: - res = self.allocate_new_loc(op.result) - self.Load(op.result, self.loc(x), res) - else: - res = self.force_allocate_reg(op.result, op.args) - self.Load(op.result, self.loc(x), res) - else: - self.reallocate_from_to(x, op.result) - - consider_cast_int_to_ptr = _same_as - consider_cast_ptr_to_int = _same_as - def consider_int_is_true(self, op, ignored): argloc = self.make_sure_var_in_reg(op.args[0], []) resloc = self.force_allocate_reg(op.result, op.args) @@ -1047,6 +1018,8 @@ self.eventually_free_var(op.args[0]) resloc = self.force_allocate_reg(op.result, []) self.Perform(op, [argloc], resloc) + consider_cast_int_to_ptr = consider_same_as + consider_cast_ptr_to_int = consider_same_as def consider_strlen(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_basic.py Wed Aug 19 16:02:40 2009 @@ -12,7 +12,7 @@ def check_jumps(self, maxcount): pass -class TestBasic(Jit386Mixin, test_basic.BasicTests): +class TestBasic(Jit386Mixin, test_basic.BaseLLtypeTests): # for the individual tests see # ====> ../../../metainterp/test/test_basic.py def test_bug(self): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 16:02:40 2009 @@ -11,7 +11,7 @@ from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import rclass -class TestRegalloc(object): +class BaseTestRegalloc(object): cpu = CPU(None, None) def raising_func(i): @@ -62,6 +62,8 @@ self.cpu.compile_operations(loop, guard_op) return bridge + +class TestRegallocSimple(BaseTestRegalloc): def test_simple_loop(self): ops = ''' [i0] @@ -158,3 +160,24 @@ ''' self.interpret(ops, [0]) assert self.getint(0) == 1 + + def test_inputarg_unused(self): + ops = ''' + [i0] + fail(1) + ''' + self.interpret(ops, [0]) + # assert did not explode + + def test_nested_guards(self): + ops = ''' + [i0, i1] + guard_true(i0) + guard_true(i0) + fail(i0, i1) + fail(3) + fail(4) + ''' + self.interpret(ops, [0, 10]) + assert self.getint(0) == 0 + assert self.getint(1) == 10 From arigo at codespeak.net Wed Aug 19 16:09:56 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 16:09:56 +0200 (CEST) Subject: [pypy-svn] r66979 - in pypy/branch/pyjitpl5/pypy: annotation annotation/test rpython rpython/test Message-ID: <20090819140956.EB64B168010@codespeak.net> Author: arigo Date: Wed Aug 19 16:09:56 2009 New Revision: 66979 Modified: pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py pypy/branch/pyjitpl5/pypy/annotation/unaryop.py pypy/branch/pyjitpl5/pypy/rpython/rpbc.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py Log: Support hash(None) as part of hash(instance-or-None). Modified: pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py Wed Aug 19 16:09:56 2009 @@ -3106,6 +3106,15 @@ s = a.build_types(f, [int]) assert s.const == 0 + def test_hash(self): + class A(object): + pass + def f(): + return hash(A()) + hash(None) + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert s.knowntype == int + def g(n): return [0,1,2,n] Modified: pypy/branch/pyjitpl5/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/annotation/unaryop.py (original) +++ pypy/branch/pyjitpl5/pypy/annotation/unaryop.py Wed Aug 19 16:09:56 2009 @@ -683,6 +683,13 @@ else: return SomeObject() # len() on a pbc? no chance + def hash(pbc): + if pbc.isNone(): + # only supports hash(None) as part of hash() + return SomeInteger() + else: + return SomeObject.hash(pbc) + class __extend__(SomeGenericCallable): def call(self, args): bookkeeper = getbookkeeper() Modified: pypy/branch/pyjitpl5/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rpbc.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rpbc.py Wed Aug 19 16:09:56 2009 @@ -609,11 +609,17 @@ def ll_str(self, none): return llstr("None") + def get_ll_hash_function(self): + return ll_none_hash + rtype_simple_call = none_call rtype_call_args = none_call none_frozen_pbc_repr = NoneFrozenPBCRepr() +def ll_none_hash(_): + return 0 + class __extend__(pairtype(Repr, NoneFrozenPBCRepr)): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py Wed Aug 19 16:09:56 2009 @@ -673,6 +673,13 @@ res = self.interpret(fn, [0]) assert res == 0 + def test_hash_of_only_none(self): + def fn(): + obj = None + return hash(obj) + res = self.interpret(fn, []) + assert res == 0 + class TestLltype(BaseTestRclass, LLRtypeMixin): From fijal at codespeak.net Wed Aug 19 16:40:02 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 16:40:02 +0200 (CEST) Subject: [pypy-svn] r66980 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819144002.40B4F168010@codespeak.net> Author: fijal Date: Wed Aug 19 16:40:01 2009 New Revision: 66980 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) * Remove dead and redundant code * Improve coverage Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 16:40:01 2009 @@ -101,72 +101,15 @@ jump_or_fail = guard_op.suboperations[-1] self.loop_consts = {} self.tree = regalloc.tree - if jump_or_fail.opnum == rop.FAIL: - self.jump_reg_candidates = {} - else: - if jump_or_fail.jump_target is regalloc.tree: - self.loop_consts = regalloc.loop_consts - self._create_jump_reg_candidates(jump_or_fail) - - def _create_jump_reg_candidates(self, jump): - self.jump_reg_candidates = {} - return - for i in range(len(jump.args)): - arg = jump.args[i] - loc = jump.jump_target.arglocs[i] - if isinstance(loc, REG): - self.jump_reg_candidates[arg] = loc + if (jump_or_fail.opnum == rop.JUMP and + jump_or_fail.jump_target is regalloc.tree): + self.loop_consts = regalloc.loop_consts def copy(self, guard_op): return RegAlloc(self.assembler, None, self.translate_support_code, self, guard_op) -# def _start_from_guard_op(self, guard_op, mp, jump): -# xxx -# rev_stack_binds = {} -# self.jump_reg_candidates = {} -# j = 0 -# sd = len(mp.args) -# if len(jump.args) > sd: -# sd = len(jump.args) -# for i in range(len(mp.args)): -# arg = mp.args[i] -# if not isinstance(arg, Const): -# stackpos = guard_op.stacklocs[j] -# if stackpos >= sd: -# sd = stackpos + 1 -# loc = guard_op.locs[j] -# if isinstance(loc, REG): -# self.free_regs = [reg for reg in self.free_regs if reg is not loc] -# self.reg_bindings[arg] = loc -# self.dirty_stack[arg] = True -# self.stack_bindings[arg] = stack_pos(stackpos) -# rev_stack_binds[stackpos] = arg -# j += 1 -# if jump.opnum != rop.JUMP: -# return {}, sd -# for i in range(len(jump.args)): -# argloc = jump.jump_target.arglocs[i] -# jarg = jump.args[i] -# if not isinstance(jarg, Const): -# if isinstance(argloc, REG): -# self.jump_reg_candidates[jarg] = argloc -# if (i in rev_stack_binds and -# (self.longevity[rev_stack_binds[i]][1] > -# self.longevity[jarg][0])): -# # variables cannot occupy the same place on stack, -# # because they overlap, but we care only in consider_jump -# pass -# else: -# # optimization for passing around values -# if jarg not in self.stack_bindings: -# self.dirty_stack[jarg] = True -# self.stack_bindings[jarg] = stack_pos(i) -# j += 1 -# return {}, sd - def _compute_loop_consts(self, inputargs, jump): - self.jump_reg_candidates = {} if jump.opnum != rop.JUMP or jump.jump_target is not self.tree: loop_consts = {} else: @@ -174,15 +117,6 @@ for i in range(len(inputargs)): if inputargs[i] is jump.args[i]: loop_consts[inputargs[i]] = i - #for i in range(len(inputargs)): - # arg = inputargs[i] - # jarg = jump.args[i] - # if arg is not jarg and not isinstance(jarg, Const): - # if self.longevity[arg][1] <= self.longevity[jarg][0]: - # if (jarg not in self.stack_bindings and - # arg in self.stack_bindings): - # self.stack_bindings[jarg] = stack_pos(i) - # self.dirty_stack[jarg] = True return loop_consts, len(inputargs) def _check_invariants(self): @@ -190,8 +124,8 @@ # make sure no duplicates assert len(dict.fromkeys(self.reg_bindings.values())) == len(self.reg_bindings) # this is not true, due to jump args - #assert (len(dict.fromkeys([str(i) for i in self.stack_bindings.values()] - # )) == len(self.stack_bindings)) + assert (len(dict.fromkeys([str(i) for i in self.stack_bindings.values()] + )) == len(self.stack_bindings)) rev_regs = dict.fromkeys(self.reg_bindings.values()) for reg in self.free_regs: assert reg not in rev_regs @@ -393,8 +327,7 @@ assert isinstance(arg, Box) def try_allocate_reg(self, v, selected_reg=None): - if isinstance(v, Const): - return convert_to_imm(v) + assert not isinstance(v, Const) if selected_reg is not None: res = self.reg_bindings.get(v, None) if res: @@ -413,15 +346,7 @@ return self.reg_bindings[v] except KeyError: if self.free_regs: - reg = self.jump_reg_candidates.get(v, None) - if reg: - if reg in self.free_regs: - self.free_regs = [r for r in self.free_regs if r is not reg] - loc = reg - else: - loc = self.free_regs.pop() - else: - loc = self.free_regs.pop() + loc = self.free_regs.pop() self.reg_bindings[v] = loc return loc @@ -542,13 +467,6 @@ return -1 def pick_variable_to_spill(self, v, forbidden_vars, selected_reg=None): - # XXX could be improved - if v in self.jump_reg_candidates and (selected_reg is None or - self.jump_reg_candidates[v] is selected_reg): - for var, reg in self.reg_bindings.items(): - if (reg is self.jump_reg_candidates[v] and - var not in forbidden_vars): - return var candidates = [] for next in self.reg_bindings: if (next not in forbidden_vars and selected_reg is None or @@ -620,7 +538,6 @@ if jump.opnum != rop.JUMP: jump = None elif jump.jump_target is not tree: - jump = self._create_jump_reg_candidates(jump) jump = None for i in range(len(inputargs)): arg = inputargs[i] @@ -633,9 +550,6 @@ # it's better to say here that we're always in dirty stack # than worry at the jump point self.dirty_stack[arg] = True - #if jump is not None: - # jarg = jump.args[i] - # self.jump_reg_candidates[jarg] = reg else: loc = stack_pos(i) self.stack_bindings[arg] = loc @@ -708,12 +622,6 @@ def _consider_binop_part(self, op, ignored): x = op.args[0] - if isinstance(x, Const): - res = self.force_allocate_reg(op.result, []) - argloc = self.loc(op.args[1]) - self.eventually_free_var(op.args[1]) - self.Load(x, self.loc(x), res) - return res, argloc argloc = self.loc(op.args[1]) loc = self.force_result_in_reg(op.result, x, op.args) self.eventually_free_var(op.args[1]) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 16:40:01 2009 @@ -51,6 +51,10 @@ def getint(self, index): return self.cpu.get_latest_value_int(index) + def getints(self, end): + return [self.cpu.get_latest_value_int(index) for + index in range(0, end)] + def getptr(self, index, T): gcref = self.cpu.get_latest_value_ptr(index) return lltype.cast_opaque_ptr(T, gcref) @@ -181,3 +185,50 @@ self.interpret(ops, [0, 10]) assert self.getint(0) == 0 assert self.getint(1) == 10 + + def test_spill_for_constant(self): + ops = ''' + [i0, i1, i2, i3] + i4 = int_add(3, i1) + i5 = int_lt(i4, 30) + guard_true(i5) + fail(i0, i4, i2, i3) + jump(1, i4, 3, 4) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1, 30, 3, 4] + + def test_spill_for_constant_lshift(self): + ops = ''' + [i0, i2, i1, i3] + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) + fail(i4, i5, i2, i3) + jump(i4, 3, i5, 4) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] + ops = ''' + [i0, i1, i2, i3] + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) + fail(i4, i5, i2, i3) + jump(i4, i5, 3, 4) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] + ops = ''' + [i0, i3, i1, i2] + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) + fail(i4, i5, i2, i3) + jump(i4, 4, i5, 3) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] From benjamin at codespeak.net Wed Aug 19 16:46:55 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 16:46:55 +0200 (CEST) Subject: [pypy-svn] r66981 - in pypy/branch/pyjitpl5/pypy: interpreter jit/metainterp jit/metainterp/test rpython rpython/lltypesystem rpython/ootypesystem rpython/test Message-ID: <20090819144655.68185168010@codespeak.net> Author: benjamin Date: Wed Aug 19 16:46:54 2009 New Revision: 66981 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rclass.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/rclass.py pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (arigo, benjamin) add a _immutable_fields_ hint to describe fields where operations can be folded safely It uses the syntax of _virtualizable2_, so arrays can be indicated. Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pycode.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pycode.py Wed Aug 19 16:46:54 2009 @@ -53,6 +53,8 @@ class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True + _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", + "co_freevars[*]", "co_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Wed Aug 19 16:46:54 2009 @@ -1377,7 +1377,8 @@ self.register_var(op.result) def serialize_op_debug_assert(self, op): - pass # for now + log.WARNING("found debug_assert in %r; should have be removed" % + (self.graph,)) def serialize_op_promote_virtualizable(self, op): vinfo = self.codewriter.metainterp_sd.virtualizable_info Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Wed Aug 19 16:46:54 2009 @@ -6,7 +6,7 @@ from pypy.rlib.rarithmetic import intmask from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR -from pypy.rpython.lltypesystem.rvirtualizable2 import VirtualizableAccessor +from pypy.rpython.rclass import FieldListAccessor from pypy.jit.metainterp.warmspot import get_stats from pypy.jit.metainterp import history, heaptracker from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin @@ -25,7 +25,7 @@ ('vable_rti', VABLERTIPTR), ('inst_x', lltype.Signed), ('inst_node', lltype.Ptr(LLtypeMixin.NODE)), - hints = {'virtualizable2_accessor': VirtualizableAccessor()}) + hints = {'virtualizable2_accessor': FieldListAccessor()}) XY._hints['virtualizable2_accessor'].initialize( XY, ['inst_x', 'inst_node']) @@ -247,7 +247,7 @@ ('inst_x', lltype.Signed), ('inst_l1', lltype.Ptr(lltype.GcArray(lltype.Signed))), ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))), - hints = {'virtualizable2_accessor': VirtualizableAccessor()}) + hints = {'virtualizable2_accessor': FieldListAccessor()}) XY2._hints['virtualizable2_accessor'].initialize( XY2, ['inst_x', 'inst_l1[*]', 'inst_l2[*]']) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Wed Aug 19 16:46:54 2009 @@ -42,7 +42,7 @@ self.VTYPE = VTYPE = deref(VTYPEPTR) # accessor = VTYPE._hints['virtualizable2_accessor'] - all_fields = accessor.redirected_fields + all_fields = accessor.fields static_fields = [] array_fields = [] for name in all_fields: Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rclass.py Wed Aug 19 16:46:54 2009 @@ -8,7 +8,8 @@ AbstractInstanceRepr,\ MissingRTypeAttribute,\ getclassrepr, getinstancerepr,\ - get_type_repr, rtype_new_instance + get_type_repr, rtype_new_instance, \ + FieldListAccessor from pypy.rpython.lltypesystem.lltype import \ Ptr, Struct, GcStruct, malloc, \ cast_pointer, cast_ptr_to_int, castable, nullptr, \ @@ -350,6 +351,11 @@ if '_immutable_' in self.classdef.classdesc.classdict: hints = hints.copy() hints['immutable'] = True + if '_immutable_fields_' in self.classdef.classdesc.classdict: + hints = hints.copy() + self.immutable_field_list = self.classdef.classdesc.classdict['_immutable_fields_'].value + accessor = FieldListAccessor() + hints['immutable_fields'] = accessor if ('_hash_cache_' in fields or '_hash_cache_' in self.rbase.allinstancefields): adtmeths = adtmeths.copy() @@ -368,6 +374,10 @@ attachRuntimeTypeInfo(self.object_type) def _setup_repr_final(self): + hints = self.object_type._hints + if "immutable_fields" in hints: + accessor = hints["immutable_fields"] + self._parse_field_list(self.immutable_field_list, accessor) if self.gcflavor == 'gc': if (self.classdef is not None and self.classdef.classdesc.lookup('__del__') is not None): @@ -394,6 +404,9 @@ def common_repr(self): # -> object or nongcobject reprs return getinstancerepr(self.rtyper, None, self.gcflavor) + def _get_field(self, attr): + return self.fields[attr] + def null_instance(self): return nullptr(self.object_type) Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py Wed Aug 19 16:46:54 2009 @@ -2,18 +2,11 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.rvirtualizable import VABLERTIPTR from pypy.rpython.lltypesystem.rclass import InstanceRepr -from pypy.rpython.rvirtualizable2 import AbstractVirtualizableAccessor from pypy.rpython.rvirtualizable2 import AbstractVirtualizable2InstanceRepr -class VirtualizableAccessor(AbstractVirtualizableAccessor): - pass - - class Virtualizable2InstanceRepr(AbstractVirtualizable2InstanceRepr, InstanceRepr): - VirtualizableAccessor = VirtualizableAccessor - def _setup_repr_llfields(self): llfields = [] if self.top_of_virtualizable_hierarchy: @@ -21,9 +14,6 @@ llfields.append(('vable_rti', VABLERTIPTR)) return llfields - def get_field(self, attr): - return self.fields[attr] - def set_vable(self, llops, vinst, force_cast=False): if self.top_of_virtualizable_hierarchy: if force_cast: Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py Wed Aug 19 16:46:54 2009 @@ -393,6 +393,10 @@ ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults) + def _get_field(self, attr): + mangled = mangle(attr, self.rtyper.getconfig()) + return mangled, self.allfields[mangled] + def attach_abstract_class_attr_accessor(self, mangled, attrtype): M = ootype.Meth([], attrtype) m = ootype.meth(M, _name=mangled, abstract=True) Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py Wed Aug 19 16:46:54 2009 @@ -1,29 +1,18 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle, OBJECT -from pypy.rpython.rvirtualizable2 import AbstractVirtualizableAccessor from pypy.rpython.rvirtualizable2 import AbstractVirtualizable2InstanceRepr VABLERTI = OBJECT -class VirtualizableAccessor(AbstractVirtualizableAccessor): - pass - - class Virtualizable2InstanceRepr(AbstractVirtualizable2InstanceRepr, InstanceRepr): - VirtualizableAccessor = VirtualizableAccessor - def _setup_repr_llfields(self): llfields = [] if self.top_of_virtualizable_hierarchy: llfields.append(('vable_rti', VABLERTI)) return llfields - def get_field(self, attr): - mangled = mangle(attr, self.rtyper.getconfig()) - return mangled, self.allfields[mangled] - def set_vable(self, llops, vinst, force_cast=False): pass # TODO Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rclass.py Wed Aug 19 16:46:54 2009 @@ -5,6 +5,20 @@ from pypy.rpython.error import TyperError from pypy.rpython.rmodel import Repr, getgcflavor + +class FieldListAccessor(object): + + def initialize(self, TYPE, fields): + self.TYPE = TYPE + self.fields = fields + + def __repr__(self): + return '' % getattr(self, 'TYPE', '?') + + def _freeze_(self): + return True + + def getclassrepr(rtyper, classdef): try: result = rtyper.class_reprs[classdef] @@ -161,6 +175,21 @@ def _setup_repr_final(self): pass + def _parse_field_list(self, fields, accessor): + mangled_fields = {} + with_suffix = [] + for name in fields: + if name.endswith('[*]'): + name = name[:-3] + suffix = '[*]' + else: + suffix = '' + mangled_name, r = self._get_field(name) + with_suffix.append(mangled_name + suffix) + mangled_fields[mangled_name] = True + accessor.initialize(self.object_type, with_suffix) + return mangled_fields + def new_instance(self, llops, classcallhop=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py Wed Aug 19 16:46:54 2009 @@ -2,26 +2,11 @@ from pypy.rpython.rmodel import inputconst, log from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype -from pypy.rpython.rclass import AbstractInstanceRepr - - -class AbstractVirtualizableAccessor(object): - - def initialize(self, TYPE, redirected_fields): - self.TYPE = TYPE - self.redirected_fields = redirected_fields - - def __repr__(self): - return '' % getattr(self, 'TYPE', '?') - - def _freeze_(self): - return True +from pypy.rpython.rclass import AbstractInstanceRepr, FieldListAccessor class AbstractVirtualizable2InstanceRepr(AbstractInstanceRepr): - VirtualizableAccessor = AbstractVirtualizableAccessor - def _super(self): return super(AbstractVirtualizable2InstanceRepr, self) @@ -32,7 +17,7 @@ basedesc = classdesc.basedesc assert basedesc is None or basedesc.lookup('_virtualizable2_') is None self.top_of_virtualizable_hierarchy = True - self.accessor = self.VirtualizableAccessor() + self.accessor = FieldListAccessor() else: self.top_of_virtualizable_hierarchy = False @@ -42,9 +27,6 @@ def set_vable(self, llops, vinst, force_cast=False): raise NotImplementedError - def get_field(self, attr): - raise NotImplementedError - def _setup_repr(self): if self.top_of_virtualizable_hierarchy: hints = {'virtualizable2_accessor': self.accessor} @@ -53,19 +35,9 @@ self._super()._setup_repr(llfields, hints = hints) else: self._super()._setup_repr(hints = hints) - my_redirected_fields = [] - self.my_redirected_fields = {} c_vfields = self.classdef.classdesc.classdict['_virtualizable2_'] - for name in c_vfields.value: - if name.endswith('[*]'): - name = name[:-3] - suffix = '[*]' - else: - suffix = '' - mangled_name, r = self.get_field(name) - my_redirected_fields.append(mangled_name + suffix) - self.my_redirected_fields[mangled_name] = True - self.accessor.initialize(self.object_type, my_redirected_fields) + self.my_redirected_fields = self._parse_field_list(c_vfields.value, + self.accessor) else: self.my_redirected_fields = {} self._super()._setup_repr() Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py Wed Aug 19 16:46:54 2009 @@ -761,6 +761,21 @@ t, typer, graph = self.gengraph(f, [], backendopt=True) assert summary(graph) == {} + def test_immutable_fields(self): + class A(object): + _immutable_fields_ = ["x", "y[*]"] + + def __init__(self, x, y): + self.x = x + self.y = y + + def f(): + return A(3, []) + t, typer, graph = self.gengraph(f, []) + A_TYPE = graph.getreturnvar().concretetype + accessor = A_TYPE.TO._hints["immutable_fields"] + assert accessor.fields == ["inst_x", "inst_y[*]"] + def test_immutable_inheritance(self): class I(object): def __init__(self, v): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Wed Aug 19 16:46:54 2009 @@ -76,8 +76,8 @@ TYPE = self.gettype(v_inst) accessor = TYPE._hints['virtualizable2_accessor'] assert accessor.TYPE == TYPE - assert accessor.redirected_fields == [self.prefix + 'v1', - self.prefix + 'v2[*]'] + assert accessor.fields == [self.prefix + 'v1', + self.prefix + 'v2[*]'] # def fn2(n): Base().base1 = 42 From fijal at codespeak.net Wed Aug 19 16:50:58 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 16:50:58 +0200 (CEST) Subject: [pypy-svn] r66982 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090819145058.A69C2168011@codespeak.net> Author: fijal Date: Wed Aug 19 16:50:58 2009 New Revision: 66982 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: (pedronis, fijal) Refactor the code, remove the code duplication Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 16:50:58 2009 @@ -362,16 +362,7 @@ loc = self.free_regs.pop() self.Load(v, convert_to_imm(v), loc) return loc - v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg) - loc = self.loc(v_to_spill) - if v_to_spill not in self.stack_bindings or v_to_spill in self.dirty_stack: - newloc = self.stack_loc(v_to_spill) - try: - del self.dirty_stack[v_to_spill] - except KeyError: - pass - self.Store(v_to_spill, loc, newloc) - del self.reg_bindings[v_to_spill] + loc = self._spill_var(v, forbidden_vars, selected_reg) self.free_regs.append(loc) self.Load(v, convert_to_imm(v), loc) return loc @@ -385,13 +376,14 @@ loc = self.try_allocate_reg(v, selected_reg) if loc: return loc - return self._spill_var(v, forbidden_vars, selected_reg) + loc = self._spill_var(v, forbidden_vars, selected_reg) + self.reg_bindings[v] = loc + return loc def _spill_var(self, v, forbidden_vars, selected_reg): v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg) loc = self.reg_bindings[v_to_spill] del self.reg_bindings[v_to_spill] - self.reg_bindings[v] = loc if v_to_spill not in self.stack_bindings or v_to_spill in self.dirty_stack: newloc = self.stack_loc(v_to_spill) try: From arigo at codespeak.net Wed Aug 19 16:58:37 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 16:58:37 +0200 (CEST) Subject: [pypy-svn] r66983 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090819145837.A0313168011@codespeak.net> Author: arigo Date: Wed Aug 19 16:58:37 2009 New Revision: 66983 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Log: Force simple_optimize for interp_operations tests. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Wed Aug 19 16:58:37 2009 @@ -11,7 +11,7 @@ from pypy.rpython.ootypesystem import ootype def get_metainterp(func, values, CPUClass, type_system, policy, - listops=False): + listops=False, optimizer=None): from pypy.annotation.policy import AnnotatorPolicy from pypy.annotation.model import lltype_to_annotation from pypy.rpython.test.test_llinterp import gengraph @@ -22,7 +22,8 @@ cpu = CPUClass(rtyper, stats, False) graph = rtyper.annotator.translator.graphs[0] opt = history.Options(specialize=False, listops=listops) - metainterp_sd = pyjitpl.MetaInterpStaticData(graph, [], cpu, stats, opt) + metainterp_sd = pyjitpl.MetaInterpStaticData(graph, [], cpu, stats, opt, + optimizer=optimizer) metainterp_sd.finish_setup() metainterp = pyjitpl.MetaInterp(metainterp_sd) return metainterp, rtyper @@ -55,6 +56,8 @@ return ll_meta_interp(*args, **kwds) def interp_operations(self, f, args, policy=None, **kwds): + from pypy.jit.metainterp import simple_optimize + class DoneWithThisFrame(Exception): pass @@ -66,6 +69,7 @@ policy = JitPolicy() metainterp, rtyper = get_metainterp(f, args, self.CPUClass, self.type_system, policy=policy, + optimizer=simple_optimize, **kwds) cw = codewriter.CodeWriter(metainterp.staticdata, policy, self.ts) graph = rtyper.annotator.translator.graphs[0] From fijal at codespeak.net Wed Aug 19 17:12:07 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 17:12:07 +0200 (CEST) Subject: [pypy-svn] r66984 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819151207.7D338168011@codespeak.net> Author: fijal Date: Wed Aug 19 17:12:06 2009 New Revision: 66984 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) * Kill more dead code * Increase coverage Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 17:12:06 2009 @@ -369,8 +369,6 @@ return convert_to_imm(v) def force_allocate_reg(self, v, forbidden_vars, selected_reg=None): - if isinstance(v, Const): - return self.return_constant(v, forbidden_vars, selected_reg) if isinstance(v, TempBox): self.longevity[v] = (self.position, self.position) loc = self.try_allocate_reg(v, selected_reg) @@ -415,17 +413,6 @@ self.Load(v, prev_loc, loc) return loc - def make_sure_var_on_stack(self, v): - loc = self.stack_loc(v) - if v not in self.reg_bindings: - return loc - self.Store(v, self.reg_bindings[v], loc) - try: - del self.dirty_stack[v] - except KeyError: - pass - return loc - def reallocate_from_to(self, from_v, to_v): reg = self.reg_bindings[from_v] del self.reg_bindings[from_v] @@ -487,25 +474,21 @@ pass self.Store(v, prev_loc, loc) - def force_result_in_reg(self, result_v, v, forbidden_vars, - selected_reg=None): + def force_result_in_reg(self, result_v, v, forbidden_vars): """ Make sure that result is in the same register as v and v is copied away if it's further used """ if isinstance(v, Const): loc = self.make_sure_var_in_reg(v, forbidden_vars, - selected_reg, imm_fine=False) assert not isinstance(loc, IMM8) self.reg_bindings[result_v] = loc self.free_regs = [reg for reg in self.free_regs if reg is not loc] return loc - if v in self.reg_bindings and selected_reg: - self.make_sure_var_in_reg(v, forbidden_vars, selected_reg) - elif v not in self.reg_bindings: + if v not in self.reg_bindings: assert v not in self.dirty_stack prev_loc = self.stack_bindings[v] - loc = self.force_allocate_reg(v, forbidden_vars, selected_reg) + loc = self.force_allocate_reg(v, forbidden_vars) self.Load(v, prev_loc, loc) assert v in self.reg_bindings if self.longevity[v][1] > self.position: @@ -526,11 +509,6 @@ # more optimal inputargs = tree.inputargs locs = [None] * len(inputargs) - jump = tree.operations[-1] - if jump.opnum != rop.JUMP: - jump = None - elif jump.jump_target is not tree: - jump = None for i in range(len(inputargs)): arg = inputargs[i] assert not isinstance(arg, Const) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 17:12:06 2009 @@ -232,3 +232,16 @@ ''' self.interpret(ops, [0, 0, 0, 0]) assert self.getints(4) == [1<<29, 30, 3, 4] + + def test_result_selected_reg_via_neg(self): + ops = ''' + [i0, i1, i2, i3] + i6 = int_neg(i2) + i7 = int_add(1, i1) + i4 = int_lt(i7, 10) + guard_true(i4) + fail(i0, i6, i7) + jump(1, i7, i2, i6) + ''' + self.interpret(ops, [0, 0, 3, 0]) + assert self.getints(3) == [1, -3, 10] From benjamin at codespeak.net Wed Aug 19 17:30:21 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 17:30:21 +0200 (CEST) Subject: [pypy-svn] r66985 - in pypy/branch/pyjitpl5/pypy/rpython: . test Message-ID: <20090819153021.476E6168013@codespeak.net> Author: benjamin Date: Wed Aug 19 17:30:20 2009 New Revision: 66985 Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (arigo, benjamin) simplify _immutable_hints_ accessor Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rclass.py Wed Aug 19 17:30:20 2009 @@ -176,8 +176,7 @@ pass def _parse_field_list(self, fields, accessor): - mangled_fields = {} - with_suffix = [] + with_suffix = {} for name in fields: if name.endswith('[*]'): name = name[:-3] @@ -185,10 +184,9 @@ else: suffix = '' mangled_name, r = self._get_field(name) - with_suffix.append(mangled_name + suffix) - mangled_fields[mangled_name] = True + with_suffix[mangled_name] = suffix accessor.initialize(self.object_type, with_suffix) - return mangled_fields + return with_suffix def new_instance(self, llops, classcallhop=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rclass.py Wed Aug 19 17:30:20 2009 @@ -774,7 +774,7 @@ t, typer, graph = self.gengraph(f, []) A_TYPE = graph.getreturnvar().concretetype accessor = A_TYPE.TO._hints["immutable_fields"] - assert accessor.fields == ["inst_x", "inst_y[*]"] + assert accessor.fields == {"inst_x" : "", "inst_y" : "[*]"} def test_immutable_inheritance(self): class I(object): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Wed Aug 19 17:30:20 2009 @@ -76,8 +76,8 @@ TYPE = self.gettype(v_inst) accessor = TYPE._hints['virtualizable2_accessor'] assert accessor.TYPE == TYPE - assert accessor.fields == [self.prefix + 'v1', - self.prefix + 'v2[*]'] + assert accessor.fields == {self.prefix + 'v1' : "", + self.prefix + 'v2': "[*]"} # def fn2(n): Base().base1 = 42 From cfbolz at codespeak.net Wed Aug 19 17:37:20 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 17:37:20 +0200 (CEST) Subject: [pypy-svn] r66986 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090819153720.4C563168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 17:37:19 2009 New Revision: 66986 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py Log: (mikke, cfbolz): signals don't work on .NET anyway Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_del.py Wed Aug 19 17:37:19 2009 @@ -27,6 +27,8 @@ 'guard_true': 1, 'jump': 1}) + +class TestLLtype(DelTests, LLJitMixin): def test_signal_action(self): from pypy.module.signal.interp_signal import SignalActionFlag action = SignalActionFlag() @@ -49,11 +51,7 @@ self.meta_interp(f, [20]) self.check_loops(getfield_raw=1, call=0, call_pure=0) - -class TestLLtype(DelTests, LLJitMixin): - pass - class TestOOtype(DelTests, OOJitMixin): - def setup_class(cls): + def test_del_keep_obj(self): py.test.skip("XXX dels are not implemented in the" " static CLI or JVM backend") From fijal at codespeak.net Wed Aug 19 17:52:26 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 17:52:26 +0200 (CEST) Subject: [pypy-svn] r66987 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819155226.AD4BF168013@codespeak.net> Author: fijal Date: Wed Aug 19 17:52:26 2009 New Revision: 66987 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) Increase coverage and general cleanup Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 17:52:26 2009 @@ -91,9 +91,9 @@ assert arg in regalloc.reg_bindings if arg in regalloc.dirty_stack: self.dirty_stack[arg] = regalloc.dirty_stack[arg] - if (arg in regalloc.stack_bindings and - arg in regalloc.reg_bindings): - self.dirty_stack[arg] = True + else: + assert not (arg in regalloc.stack_bindings and + arg in regalloc.reg_bindings) allocated_regs = self.reg_bindings.values() self.free_regs = [v for v in REGS if v not in allocated_regs] self.current_stack_depth = regalloc.current_stack_depth @@ -407,6 +407,7 @@ if isinstance(v, Const): return self.return_constant(v, forbidden_vars, selected_reg, imm_fine) + prev_loc = self.loc(v) loc = self.force_allocate_reg(v, forbidden_vars, selected_reg) if prev_loc is not loc: @@ -572,9 +573,7 @@ consider_guard_overflow = consider_guard_no_exception def consider_guard_value(self, op, ignored): - x = self.loc(op.args[0]) - if not (isinstance(x, REG) or isinstance(op.args[1], Const)): - x = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False) + x = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False) y = self.loc(op.args[1]) regalloc = self.regalloc_for_guard(op) self.perform_guard(op, regalloc, [x, y], None) @@ -694,10 +693,6 @@ pass # otherwise it's clean - def sync_var_if_survives(self, v): - if self.longevity[v][1] > self.position: - self.sync_var(v) - def _call(self, op, arglocs, force_store=[]): # we need to store all variables which are now in registers for v, reg in self.reg_bindings.items(): @@ -808,22 +803,24 @@ ofs, size, ptr = CPU386.unpack_fielddescr(fielddescr) return imm(ofs), imm(size), ptr - def consider_setfield_gc(self, op, ignored): + def _common_consider_setfield(self, op, ignored, raw): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) value_loc = self.make_sure_var_in_reg(op.args[1], op.args) ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) if ptr: + if raw: + print "Setfield of raw structure with gc pointer" + assert False gc_ll_descr = self.assembler.cpu.gc_ll_descr gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) self.eventually_free_vars(op.args) self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc]) + def consider_setfield_gc(self, op, ignored): + self._common_consider_setfield(op, ignored, raw=False) + def consider_setfield_raw(self, op, ignored): - base_loc = self.make_sure_var_in_reg(op.args[0], op.args) - value_loc = self.make_sure_var_in_reg(op.args[1], op.args) - ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) - self.eventually_free_vars(op.args) - self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc]) + self._common_consider_setfield(op, ignored, raw=True) def consider_strsetitem(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 17:52:26 2009 @@ -4,13 +4,38 @@ from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ BoxPtr, ConstPtr, TreeLoop -from pypy.jit.metainterp.resoperation import rop +from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86.runner import CPU +from pypy.jit.backend.x86.regalloc import RegAlloc, REGS from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import rclass +class DummyTree(object): + operations = [ResOperation(rop.FAIL, [], None)] + inputargs = [] + +class MockAssembler(object): + gcrefs = None + +class TestRegallocDirect(object): + def fill_regs(self, regalloc): + allboxes = [] + for reg in REGS: + box = BoxInt() + allboxes.append(box) + regalloc.reg_bindings[box] = reg + return allboxes + + def test_make_sure_var_in_reg(self): + regalloc = RegAlloc(MockAssembler(), DummyTree()) + boxes = self.fill_regs(regalloc) + box = boxes[-1] + oldloc = regalloc.loc(box) + newloc = regalloc.make_sure_var_in_reg(box, []) + assert oldloc is newloc + class BaseTestRegalloc(object): cpu = CPU(None, None) @@ -245,3 +270,16 @@ ''' self.interpret(ops, [0, 0, 3, 0]) assert self.getints(3) == [1, -3, 10] + + def test_compare_memory_result_survives(self): + ops = ''' + [i0, i1, i2, i3] + i4 = int_lt(i0, i1) + i5 = int_add(i3, 1) + i6 = int_lt(i5, 30) + guard_true(i6) + fail(i4) + jump(i0, i1, i4, i5) + ''' + self.interpret(ops, [0, 10, 0, 0]) + assert self.getint(0) == 1 From cfbolz at codespeak.net Wed Aug 19 17:58:31 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 17:58:31 +0200 (CEST) Subject: [pypy-svn] r66988 - in pypy/branch/pyjitpl5/pypy: jit/metainterp jit/metainterp/test translator translator/goal translator/test Message-ID: <20090819155831.80D52168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 17:58:30 2009 New Revision: 66988 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/translator/driver.py pypy/branch/pyjitpl5/pypy/translator/goal/translate.py pypy/branch/pyjitpl5/pypy/translator/test/test_driver.py Log: (mikke, cfbolz): remove the prejitbackendopt driver phase and give warmspot the responsibility of doing backendopts before code writing. This makes it possible to sanely enable inlining before code writing because the inlining is restricted to those graphs that the policy would look into. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/policy.py Wed Aug 19 17:58:30 2009 @@ -73,10 +73,6 @@ return 'residual' return 'regular' - def all_graphs(self, translator): - return [graph for graph in translator.graphs - if self.look_inside_graph(graph)] - def contains_unsupported_variable_type(graph): getkind = history.getkind try: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Wed Aug 19 17:58:30 2009 @@ -53,6 +53,8 @@ def meta_interp(self, *args, **kwds): kwds['CPUClass'] = self.CPUClass kwds['type_system'] = self.type_system + if "backendopt" not in kwds: + kwds["backendopt"] = False return ll_meta_interp(*args, **kwds) def interp_operations(self, f, args, policy=None, **kwds): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_policy.py Wed Aug 19 17:58:30 2009 @@ -1,8 +1,10 @@ -from pypy.jit.metainterp import policy, support +from pypy.jit.metainterp import policy, support, warmspot from pypy.rlib.jit import purefunction, dont_look_inside -def test_all_graphs(): +def test_find_all_graphs(): def f(x): + if x < 0: + return f(-x) return x + 1 @purefunction def g(x): @@ -16,9 +18,21 @@ rtyper = support.annotate(i, [7]) jitpolicy = policy.JitPolicy() - res = jitpolicy.all_graphs(rtyper.annotator.translator) + translator = rtyper.annotator.translator + res = warmspot.find_all_graphs(translator.graphs[0], jitpolicy, translator) funcs = [graph.func for graph in res] - assert funcs[:2] == [i, f] - assert g not in funcs - assert h not in funcs + assert funcs == [i, f] + +def test_find_all_graphs_str_join(): + def i(x, y): + return "hello".join([str(x), str(y), "bye"]) + + rtyper = support.annotate(i, [7, 100]) + + jitpolicy = policy.JitPolicy() + translator = rtyper.annotator.translator + res = warmspot.find_all_graphs(translator.graphs[0], jitpolicy, translator) + + funcs = [graph.func for graph in res] + assert funcs[:1] == [i] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Wed Aug 19 17:58:30 2009 @@ -51,12 +51,13 @@ type_system=type_system, inline_threshold=0) clear_tcache() - return jittify_and_run(interp, graph, args, **kwds) + return jittify_and_run(interp, graph, args, backendopt=backendopt, **kwds) -def jittify_and_run(interp, graph, args, repeat=1, hash_bits=None, **kwds): +def jittify_and_run(interp, graph, args, repeat=1, hash_bits=None, backendopt=False, + **kwds): translator = interp.typer.annotator.translator translator.config.translation.gc = "boehm" - warmrunnerdesc = WarmRunnerDesc(translator, **kwds) + warmrunnerdesc = WarmRunnerDesc(translator, backendopt=backendopt, **kwds) warmrunnerdesc.state.set_param_threshold(3) # for tests warmrunnerdesc.state.set_param_trace_eagerness(2) # for tests warmrunnerdesc.state.create_tables_now() # for tests @@ -124,11 +125,15 @@ class WarmRunnerDesc: - def __init__(self, translator, policy=None, **kwds): + def __init__(self, translator, policy=None, backendopt=True, **kwds): pyjitpl._warmrunnerdesc = self # this is a global for debugging only! if policy is None: policy = JitPolicy() self.set_translator(translator) + self.find_portal() + if backendopt: + self.prejit_optimizations(policy) + self.build_meta_interp(**kwds) self.make_args_specification() self.rewrite_jit_merge_point() @@ -162,20 +167,7 @@ self.ts = OOTypeHelper() self.gcdescr = gc.get_description(translator.config) - def build_meta_interp(self, CPUClass=None, view="auto", - translate_support_code=False, optimizer=None, - profile=None, **kwds): - assert CPUClass is not None - opt = history.Options(**kwds) - self.stats = history.Stats() - if translate_support_code: - self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper) - annhelper = self.annhelper - else: - annhelper = None - cpu = CPUClass(self.translator.rtyper, self.stats, - translate_support_code, annhelper, self.gcdescr) - self.cpu = cpu + def find_portal(self): graphs = self.translator.graphs self.jit_merge_point_pos = find_jit_merge_point(graphs) graph, block, pos = self.jit_merge_point_pos @@ -193,7 +185,33 @@ self.translator.graphs.append(graph) self.portal_graph = graph self.jitdriver = block.operations[pos].args[1].value - self.metainterp_sd = MetaInterpStaticData(graph, graphs, cpu, + + def prejit_optimizations(self, policy): + from pypy.translator.backendopt.all import backend_optimizations + graphs = find_all_graphs(self.portal_graph, policy, self.translator) + backend_optimizations(self.translator, + graphs=graphs, + merge_if_blocks=True, + constfold=True, + raisingop2direct_call=False, + remove_asserts=True, + really_remove_asserts=True) + + def build_meta_interp(self, CPUClass=None, translate_support_code=False, + view="auto", optimizer=None, profile=None, **kwds): + assert CPUClass is not None + opt = history.Options(**kwds) + self.stats = history.Stats() + if translate_support_code: + self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper) + annhelper = self.annhelper + else: + annhelper = None + cpu = CPUClass(self.translator.rtyper, self.stats, + translate_support_code, annhelper, self.gcdescr) + self.cpu = cpu + self.metainterp_sd = MetaInterpStaticData(self.portal_graph, + self.translator.graphs, cpu, self.stats, opt, optimizer=optimizer, profile=profile, @@ -513,6 +531,30 @@ op.args[:3] = [closures[funcname]] +def find_all_graphs(portal, policy, translator): + from pypy.translator.simplify import get_graph + all_graphs = [portal] + seen = set([portal]) + todo = [portal] + while todo: + top_graph = todo.pop() + for _, op in top_graph.iterblockops(): + if op.opname not in ("direct_call", "indirect_call", "oosend"): + continue + kind = policy.guess_call_kind(op) + if kind != "regular": + continue + for graph in policy.graphs_from(op): + if graph in seen: + continue + if policy.look_inside_graph(graph): + todo.append(graph) + all_graphs.append(graph) + seen.add(graph) + return all_graphs + + + def decode_hp_hint_args(op): # Returns (list-of-green-vars, list-of-red-vars) without Voids. assert op.opname == 'jit_marker' Modified: pypy/branch/pyjitpl5/pypy/translator/driver.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/driver.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/driver.py Wed Aug 19 17:58:30 2009 @@ -120,7 +120,7 @@ else: task, postfix = parts if task in ('rtype', 'backendopt', 'llinterpret', - 'prejitbackendopt', 'pyjitpl'): + 'pyjitpl'): if ts: if ts == postfix: expose_task(task, explicit_task) @@ -355,36 +355,6 @@ task_rtype_ootype = taskdef(task_rtype_ootype, ['annotate'], "ootyping") OOTYPE = 'rtype_ootype' - def task_prejitbackendopt_lltype(self): - from pypy.translator.backendopt.all import backend_optimizations - backend_optimizations(self.translator, - inline_threshold=0, - merge_if_blocks=True, - constfold=True, - raisingop2direct_call=False, - remove_asserts=True, - really_remove_asserts=True) - # - task_prejitbackendopt_lltype = taskdef( - task_prejitbackendopt_lltype, - [RTYPE], - "Backendopt before jitting") - - def task_prejitbackendopt_ootype(self): - from pypy.translator.backendopt.all import backend_optimizations - backend_optimizations(self.translator, - inline_threshold=0, - merge_if_blocks=True, - constfold=False, # XXX? - raisingop2direct_call=False, - remove_asserts=True, - really_remove_asserts=True) - # - task_prejitbackendopt_ootype = taskdef( - task_prejitbackendopt_ootype, - [OOTYPE], - "Backendopt before jitting") - def task_pyjitpl_lltype(self): get_policy = self.extra['jitpolicy'] self.jitpolicy = get_policy(self) @@ -397,7 +367,7 @@ self.log.info("the JIT compiler was generated") # task_pyjitpl_lltype = taskdef(task_pyjitpl_lltype, - [RTYPE, '?prejitbackendopt_lltype'], + [RTYPE], "JIT compiler generation") def task_pyjitpl_ootype(self): @@ -412,7 +382,7 @@ self.log.info("the JIT compiler was generated") # task_pyjitpl_ootype = taskdef(task_pyjitpl_ootype, - [OOTYPE, '?prejitbackendopt_ootype'], + [OOTYPE], "JIT compiler generation") def task_backendopt_lltype(self): Modified: pypy/branch/pyjitpl5/pypy/translator/goal/translate.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/goal/translate.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/goal/translate.py Wed Aug 19 17:58:30 2009 @@ -20,8 +20,6 @@ GOALS= [ ("annotate", "do type inference", "-a --annotate", ""), ("rtype", "do rtyping", "-t --rtype", ""), - ("prejitbackendopt", "backend optimize before jitting", - "--prejitbackendopt", ""), ("pyjitpl", "JIT generation step", "--pyjitpl", ""), ("backendopt", "do backend optimizations", "--backendopt", ""), ("source", "create source", "-s --source", ""), Modified: pypy/branch/pyjitpl5/pypy/translator/test/test_driver.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/test/test_driver.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/test/test_driver.py Wed Aug 19 17:58:30 2009 @@ -6,7 +6,7 @@ def test_ctr(): td = TranslationDriver() expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source', - 'compile', 'run', 'prejitbackendopt', 'pyjitpl'] + 'compile', 'run', 'pyjitpl'] assert set(td.exposed) == set(expected) assert td.backend_select_goals(['compile_c']) == ['compile_c'] @@ -35,8 +35,8 @@ 'compile_cli', 'compile_c', 'run_c', 'run_cli', 'compile_jvm', 'source_jvm', 'run_jvm', - 'prejitbackendopt_lltype', 'pyjitpl_lltype', - 'prejitbackendopt_ootype', 'pyjitpl_ootype'] + 'pyjitpl_lltype', + 'pyjitpl_ootype'] assert set(td.exposed) == set(expected) td = TranslationDriver({'backend': None, 'type_system': 'lltype'}) @@ -50,6 +50,6 @@ 'backendopt_lltype'] expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', - 'compile_c', 'run_c', 'prejitbackendopt', 'pyjitpl'] + 'compile_c', 'run_c', 'pyjitpl'] assert set(td.exposed) == set(expected) From cfbolz at codespeak.net Wed Aug 19 18:09:52 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 18:09:52 +0200 (CEST) Subject: [pypy-svn] r66989 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090819160952.6724E168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 18:09:51 2009 New Revision: 66989 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: some things that are done Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Wed Aug 19 18:09:51 2009 @@ -98,8 +98,8 @@ - make x86 not recompile everything - write more tests that cover recompilation (Samuele, Maciek) - think about code memory management - - optimize chains of ooisnull/oononnull (Mikael, Carl Friedrich) - - discuss constantness improvements (everybody) + - optimize chains of ooisnull/oononnull DONE + - discuss constantness improvements DONE - don't trace into action flag stuff (Benjamin, Armin) - - bit of inlining before bytecode production + - bit of inlining before bytecode production (Carl Friedrich, Mikael) - inlining on the Python level From cfbolz at codespeak.net Wed Aug 19 18:10:37 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 18:10:37 +0200 (CEST) Subject: [pypy-svn] r66990 - in pypy/branch/pyjitpl5/pypy/translator/backendopt: . test Message-ID: <20090819161037.6E708168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 18:10:37 2009 New Revision: 66990 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Log: (mikke, cfbolz): kill jit inlining heuristic, as it was replaced by a new approach Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Wed Aug 19 18:10:37 2009 @@ -626,18 +626,6 @@ return (0.9999 * measure_median_execution_cost(graph) + count), True -def inlining_heuristic_jit(graph): - func = getattr(graph, "func", None) - try: - oopspec = graph.func.oopspec - except AttributeError: - if getattr(func, "_pure_function_", False): - return (sys.maxint, True) - elif not getattr(func, "_look_inside_me_", True): - return (sys.maxint, True) - return inlining_heuristic(graph) - return (sys.maxint, True) - def inlinable_static_callers(graphs): ok_to_call = dict.fromkeys(graphs) result = [] Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/test/test_inline.py Wed Aug 19 18:10:37 2009 @@ -9,7 +9,6 @@ from pypy.translator.backendopt.inline import collect_called_graphs from pypy.translator.backendopt.inline import measure_median_execution_cost from pypy.translator.backendopt.inline import instrument_inline_candidates -from pypy.translator.backendopt.inline import inlining_heuristic_jit from pypy.translator.backendopt.checkvirtual import check_virtual_methods from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.llinterp import LLInterpreter @@ -628,32 +627,6 @@ res = eval_func([]) assert res == 5 - def test_jit_inliner(self): - from pypy.rlib.jit import purefunction, dont_look_inside - @purefunction - def g(x): - return x + 1 - @dont_look_inside - def h(x): - return x + 2 - - def f(x): - tot = 0 - for item in [1,2,g(x),h(x)]: - tot += item - return tot - - eval_func, t = self.check_auto_inlining( - f, [int], heuristic=inlining_heuristic_jit) - f_graph = graphof(t, f) - called_graphs = collect_called_graphs(f_graph, t, include_oosend=False) - print called_graphs - assert len(called_graphs) == 6 # g, h, newlist, setitem, getitem, length - - result = eval_func([2]) - assert result == 10 - - class TestInlineOOType(OORtypeMixin, BaseTestInline): From cfbolz at codespeak.net Wed Aug 19 18:13:16 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 18:13:16 +0200 (CEST) Subject: [pypy-svn] r66991 - pypy/branch/pyjitpl5/pypy/objspace/std Message-ID: <20090819161316.61197168013@codespeak.net> Author: cfbolz Date: Wed Aug 19 18:13:15 2009 New Revision: 66991 Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Log: (mikke, cfbolz): kill deepfreeze hint Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Wed Aug 19 18:13:15 2009 @@ -271,7 +271,6 @@ raise UnwrapError(w_self) def is_heaptype(w_self): - w_self = hint(w_self, deepfreeze=True) return w_self.__flags__&_HEAPTYPE def get_module(w_self): From fijal at codespeak.net Wed Aug 19 18:17:13 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 18:17:13 +0200 (CEST) Subject: [pypy-svn] r66992 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090819161713.00E66168012@codespeak.net> Author: fijal Date: Wed Aug 19 18:17:12 2009 New Revision: 66992 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) Increase coverage for regalloc.py Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 18:17:12 2009 @@ -283,3 +283,14 @@ ''' self.interpret(ops, [0, 10, 0, 0]) assert self.getint(0) == 1 + + def test_jump_different_args(self): + ops = ''' + [i0, i15, i16, i18, i1, i2, i3] + i4 = int_add(i3, 1) + i5 = int_lt(i4, 20) + guard_true(i5) + fail(i2, i1) + jump(i0, i18, i15, i16, i2, i1, i4) + ''' + self.interpret(ops, [0, 1, 2, 3]) From benjamin at codespeak.net Wed Aug 19 18:32:12 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 18:32:12 +0200 (CEST) Subject: [pypy-svn] r66993 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090819163212.B0AB7168012@codespeak.net> Author: benjamin Date: Wed Aug 19 18:32:11 2009 New Revision: 66993 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Log: (arigo, benjamin) account for changes in the FieldListAccessor API Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Wed Aug 19 18:32:11 2009 @@ -27,7 +27,7 @@ ('inst_node', lltype.Ptr(LLtypeMixin.NODE)), hints = {'virtualizable2_accessor': FieldListAccessor()}) XY._hints['virtualizable2_accessor'].initialize( - XY, ['inst_x', 'inst_node']) + XY, {'inst_x' : "", 'inst_node' : ""}) xy_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) heaptracker.set_testing_vtable_for_gcstruct(XY, xy_vtable, 'XY') @@ -249,7 +249,7 @@ ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))), hints = {'virtualizable2_accessor': FieldListAccessor()}) XY2._hints['virtualizable2_accessor'].initialize( - XY2, ['inst_x', 'inst_l1[*]', 'inst_l2[*]']) + XY2, {'inst_x' : "", 'inst_l1' : "[*]", 'inst_l2' : "[*]"}) xy2_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) heaptracker.set_testing_vtable_for_gcstruct(XY2, xy2_vtable, 'XY2') Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Wed Aug 19 18:32:11 2009 @@ -45,9 +45,9 @@ all_fields = accessor.fields static_fields = [] array_fields = [] - for name in all_fields: - if name.endswith('[*]'): - array_fields.append(name[:-3]) + for name, suffix in all_fields.iteritems(): + if suffix == '[*]': + array_fields.append(name) else: static_fields.append(name) self.static_fields = static_fields From fijal at codespeak.net Wed Aug 19 18:34:52 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 18:34:52 +0200 (CEST) Subject: [pypy-svn] r66994 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819163452.9F130168013@codespeak.net> Author: fijal Date: Wed Aug 19 18:34:52 2009 New Revision: 66994 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) A test and a fix Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 18:34:52 2009 @@ -184,8 +184,9 @@ if (operations[i + 1].opnum != rop.GUARD_TRUE and operations[i + 1].opnum != rop.GUARD_FALSE): return False - if (operations[i + 1].args[0] is not op.result or - self.longevity[op.result][1] > i + 1 or + if operations[i + 1].args[0] is not op.result: + return False + if (self.longevity[op.result][1] > i + 1 or op.result in operations[i + 1].inputargs): print "boolean flag not optimized away" assert False Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 18:34:52 2009 @@ -294,3 +294,16 @@ jump(i0, i18, i15, i16, i2, i1, i4) ''' self.interpret(ops, [0, 1, 2, 3]) + +class TestRegallocCompOps(BaseTestRegalloc): + + def test_cmp_op_0(self): + ops = ''' + [i0, i3] + i2 = int_lt(i0, 100) + guard_true(i3) + fail(1, i2) + fail(0, i2) + ''' + self.interpret(ops, [0, 1]) + assert self.getint(0) == 0 From benjamin at codespeak.net Wed Aug 19 18:48:36 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 18:48:36 +0200 (CEST) Subject: [pypy-svn] r66996 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090819164836.16801168014@codespeak.net> Author: benjamin Date: Wed Aug 19 18:48:35 2009 New Revision: 66996 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Log: use pure operations for fields marked immutable Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Wed Aug 19 18:48:35 2009 @@ -398,6 +398,7 @@ self.free_vars = 0 self.var_positions = {} self.vable_array_vars = {} + self.immutable_arrays = {} for arg in self.force_block_args_order(block): self.register_var(arg, verbose=False) self.emit(label(block)) @@ -866,8 +867,13 @@ self.vable_array_vars[op.result] = (op.args[0], arrayindex) return # check for deepfrozen structures that force constant-folding - if deref(v_inst.concretetype)._hints.get('immutable'): + hints = deref(v_inst.concretetype)._hints + accessor = hints.get("immutable_fields") + if hints.get('immutable') or \ + accessor and c_fieldname.value in accessor.fields: pure = '_pure' + if accessor and accessor.fields[c_fieldname.value] == "[*]": + self.immutable_arrays[op.result] = True else: pure = '' argname = getattr(deref(v_inst.concretetype), '_gckind', 'gc') @@ -1298,6 +1304,8 @@ self.var_position(args[1])) self.register_var(op.result) return True + elif args[0] in self.immutable_arrays: + opname = "getarrayitem_gc_pure" index = self.prepare_list_getset(op, arraydescr, args) if index is None: return False From benjamin at codespeak.net Wed Aug 19 18:49:32 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 18:49:32 +0200 (CEST) Subject: [pypy-svn] r66997 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090819164932.D4DB3168014@codespeak.net> Author: benjamin Date: Wed Aug 19 18:49:32 2009 New Revision: 66997 Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py Log: add tests for previous checkin Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py Wed Aug 19 18:49:32 2009 @@ -0,0 +1,43 @@ +import py +from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin + + +class ImmutableFieldsTests: + + def test_fields(self): + class X(object): + _immutable_fields_ = ["x"] + + def __init__(self, x): + self.x = x + + def f(x): + y = X(x) + return y.x + 5 + res = self.interp_operations(f, [23]) + assert res == 28 + self.check_history_(getfield_gc=0, getfield_gc_pure=1, int_add=1) + + def test_array(self): + class X(object): + _immutable_fields_ = ["y[*]"] + + def __init__(self, x): + self.y = x + def f(index): + l = [1, 2, 3, 4] + l[2] = 30 + a = X(l) + return a.y[index] + res = self.interp_operations(f, [2], listops=True) + assert res == 30 + self.check_history_(getfield_gc=0, getfield_gc_pure=1, + getarrayitem_gc=0, getarrayitem_gc_pure=1) + + +class TestLLtypeImmutableFieldsTests(ImmutableFieldsTests, LLJitMixin): + pass + +# XXX implement +# class TestOOtypeImmutableFieldsTests(ImmutableFieldsTests, OOJitMixin): +# pass From benjamin at codespeak.net Wed Aug 19 19:07:37 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 19 Aug 2009 19:07:37 +0200 (CEST) Subject: [pypy-svn] r66998 - pypy/branch/pyjitpl5/pypy/objspace/std Message-ID: <20090819170737.894F6168012@codespeak.net> Author: benjamin Date: Wed Aug 19 19:07:37 2009 New Revision: 66998 Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Log: mark __flags__ as immutable on W_TypeObject Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Wed Aug 19 19:07:37 2009 @@ -50,6 +50,8 @@ lazyloaders = {} # can be overridden by specific instances version_tag = None + _immutable_fields_ = ["__flags__"] + uses_object_getattribute = False # ^^^ for config.objspace.std.getattributeshortcut # (False is a conservative default, fixed during real usage) From fijal at codespeak.net Wed Aug 19 19:36:47 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 19:36:47 +0200 (CEST) Subject: [pypy-svn] r66999 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090819173647.7CC8A16801D@codespeak.net> Author: fijal Date: Wed Aug 19 19:36:46 2009 New Revision: 66999 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (pedronis, fijal) - reinstate support for some corner cases - remove dirty_stack Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Wed Aug 19 19:36:46 2009 @@ -65,15 +65,14 @@ # compute longevity of variables self._compute_vars_longevity(tree.inputargs, tree.operations) self.free_regs = REGS[:] - self.dirty_stack = {} jump = tree.operations[-1] #self.startmp = mp #if guard_op: # loop_consts, sd = self._start_from_guard_op(guard_op, mp, jump) #else: - loop_consts, sd = self._compute_loop_consts(tree.inputargs, jump) + loop_consts = self._compute_loop_consts(tree.inputargs, jump) self.loop_consts = loop_consts - self.current_stack_depth = sd + self.current_stack_depth = 0 else: self._rewrite_const_ptrs(guard_op.suboperations) guard_op.inputargs = None @@ -81,7 +80,6 @@ inp = guard_op.inputargs self.reg_bindings = {} self.stack_bindings = {} - self.dirty_stack = {} for arg in inp: if arg in regalloc.reg_bindings: self.reg_bindings[arg] = regalloc.reg_bindings[arg] @@ -89,11 +87,6 @@ self.stack_bindings[arg] = regalloc.stack_bindings[arg] else: assert arg in regalloc.reg_bindings - if arg in regalloc.dirty_stack: - self.dirty_stack[arg] = regalloc.dirty_stack[arg] - else: - assert not (arg in regalloc.stack_bindings and - arg in regalloc.reg_bindings) allocated_regs = self.reg_bindings.values() self.free_regs = [v for v in REGS if v not in allocated_regs] self.current_stack_depth = regalloc.current_stack_depth @@ -117,7 +110,7 @@ for i in range(len(inputargs)): if inputargs[i] is jump.args[i]: loop_consts[inputargs[i]] = i - return loop_consts, len(inputargs) + return loop_consts def _check_invariants(self): if not we_are_translated(): @@ -130,11 +123,6 @@ for reg in self.free_regs: assert reg not in rev_regs assert len(rev_regs) + len(self.free_regs) == len(REGS) - for v, val in self.stack_bindings.items(): - if (isinstance(v, Box) and (v not in self.reg_bindings) and - self.longevity[v][1] > self.position and - self.longevity[v][0] <= self.position): - assert not v in self.dirty_stack else: assert len(self.reg_bindings) + len(self.free_regs) == len(REGS) @@ -188,8 +176,8 @@ return False if (self.longevity[op.result][1] > i + 1 or op.result in operations[i + 1].inputargs): - print "boolean flag not optimized away" - assert False + print "!!!! boolean flag not optimized away !!!!" + return False return True def walk_operations(self, tree): @@ -202,10 +190,6 @@ def walk_guard_ops(self, inputargs, operations, exc): self.exc = exc - for arg in inputargs: - if arg not in self.reg_bindings: - assert arg in self.stack_bindings - assert arg not in self.dirty_stack old_regalloc = self.assembler._regalloc self.assembler._regalloc = self self._walk_operations(operations) @@ -218,8 +202,9 @@ op = operations[i] self.position = i if op.has_no_side_effect() and op.result not in self.longevity: - print "Operation has no side effect, but was not removed" - assert False + i += 1 + self.eventually_free_vars(op.args) + continue if self.can_optimize_cmp_op(op, i, operations): nothing = oplist[op.opnum](self, op, operations[i + 1]) i += 1 @@ -383,12 +368,8 @@ v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg) loc = self.reg_bindings[v_to_spill] del self.reg_bindings[v_to_spill] - if v_to_spill not in self.stack_bindings or v_to_spill in self.dirty_stack: + if v_to_spill not in self.stack_bindings: newloc = self.stack_loc(v_to_spill) - try: - del self.dirty_stack[v_to_spill] - except KeyError: - pass self.Store(v_to_spill, loc, newloc) return loc @@ -470,10 +451,6 @@ def move_variable_away(self, v, prev_loc): reg = None loc = self.stack_loc(v) - try: - del self.dirty_stack[v] - except KeyError: - pass self.Store(v, prev_loc, loc) def force_result_in_reg(self, result_v, v, forbidden_vars): @@ -488,7 +465,6 @@ self.free_regs = [reg for reg in self.free_regs if reg is not loc] return loc if v not in self.reg_bindings: - assert v not in self.dirty_stack prev_loc = self.stack_bindings[v] loc = self.force_allocate_reg(v, forbidden_vars) self.Load(v, prev_loc, loc) @@ -498,7 +474,7 @@ # store result in the same place loc = self.reg_bindings[v] del self.reg_bindings[v] - if v not in self.stack_bindings or v in self.dirty_stack: + if v not in self.stack_bindings: self.move_variable_away(v, loc) self.reg_bindings[result_v] = loc else: @@ -519,12 +495,8 @@ reg = self.try_allocate_reg(arg) if reg: locs[i] = reg - # it's better to say here that we're always in dirty stack - # than worry at the jump point - self.dirty_stack[arg] = True else: - loc = stack_pos(i) - self.stack_bindings[arg] = loc + loc = self.stack_loc(arg) locs[i] = loc # otherwise we have it saved on stack, so no worry tree.arglocs = locs @@ -685,13 +657,9 @@ consider_ooisnot = _consider_compop def sync_var(self, v): - if v in self.dirty_stack or v not in self.stack_bindings: + if v not in self.stack_bindings: reg = self.reg_bindings[v] self.Store(v, reg, self.stack_loc(v)) - try: - del self.dirty_stack[v] - except KeyError: - pass # otherwise it's clean def _call(self, op, arglocs, force_store=[]): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Wed Aug 19 19:36:46 2009 @@ -295,6 +295,14 @@ ''' self.interpret(ops, [0, 1, 2, 3]) + def test_op_result_unused(self): + ops = ''' + [i0, i1] + i2 = int_add(i0, i1) + fail(0) + ''' + self.interpret(ops, [0, 0]) + class TestRegallocCompOps(BaseTestRegalloc): def test_cmp_op_0(self): From arigo at codespeak.net Wed Aug 19 19:53:30 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 19:53:30 +0200 (CEST) Subject: [pypy-svn] r67001 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090819175330.7E14316801D@codespeak.net> Author: arigo Date: Wed Aug 19 19:53:28 2009 New Revision: 67001 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: Fix tests depending on a precise order here (failures occur very rarely, for some reason). Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Wed Aug 19 19:53:28 2009 @@ -155,7 +155,12 @@ newoperations = self.optimizer.newoperations newoperations.append(self.source_op) self.box = box = self.source_op.result - for ofs, value in self._fields.iteritems(): + # + iteritems = self._fields.iteritems() + if not we_are_translated(): #random order is fine, except for tests + iteritems = list(iteritems) + iteritems.sort(key = lambda (x,y): x.sort_key()) + for ofs, value in iteritems: subbox = value.force_box() op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) From arigo at codespeak.net Wed Aug 19 20:50:47 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Aug 2009 20:50:47 +0200 (CEST) Subject: [pypy-svn] r67003 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090819185047.8105E168022@codespeak.net> Author: arigo Date: Wed Aug 19 20:50:45 2009 New Revision: 67003 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py Log: Fix (oups). Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Wed Aug 19 20:50:45 2009 @@ -869,11 +869,12 @@ # check for deepfrozen structures that force constant-folding hints = deref(v_inst.concretetype)._hints accessor = hints.get("immutable_fields") - if hints.get('immutable') or \ - accessor and c_fieldname.value in accessor.fields: + if accessor and c_fieldname.value in accessor.fields: pure = '_pure' - if accessor and accessor.fields[c_fieldname.value] == "[*]": + if accessor.fields[c_fieldname.value] == "[*]": self.immutable_arrays[op.result] = True + elif hints.get('immutable'): + pure = '_pure' else: pure = '' argname = getattr(deref(v_inst.concretetype), '_gckind', 'gc') Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_codewriter.py Wed Aug 19 20:50:45 2009 @@ -35,6 +35,25 @@ getarrayitem_gc=0, getarrayitem_gc_pure=1) + def test_array_in_immutable(self): + class X(object): + _immutable_ = True + _immutable_fields_ = ["lst[*]"] + + def __init__(self, lst, y): + self.lst = lst + self.y = y + + def f(x, index): + y = X([x], x+1) + return y.lst[index] + y.y + 5 + res = self.interp_operations(f, [23, 0], listops=True) + assert res == 23 + 24 + 5 + self.check_history_(getfield_gc=0, getfield_gc_pure=2, + getarrayitem_gc=0, getarrayitem_gc_pure=1, + int_add=3) + + class TestLLtypeImmutableFieldsTests(ImmutableFieldsTests, LLJitMixin): pass From fijal at codespeak.net Wed Aug 19 21:50:57 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 19 Aug 2009 21:50:57 +0200 (CEST) Subject: [pypy-svn] r67004 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090819195057.7835D168015@codespeak.net> Author: fijal Date: Wed Aug 19 21:50:55 2009 New Revision: 67004 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: add a task Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Wed Aug 19 21:50:55 2009 @@ -82,8 +82,8 @@ - calls? -TASKS for the morning ---------------------- +TASKS +----- look at tests @@ -103,3 +103,4 @@ - don't trace into action flag stuff (Benjamin, Armin) - bit of inlining before bytecode production (Carl Friedrich, Mikael) - inlining on the Python level + - storage sinking (removing consecutive getfields/setfields) From cfbolz at codespeak.net Wed Aug 19 21:52:06 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Aug 2009 21:52:06 +0200 (CEST) Subject: [pypy-svn] r67005 - pypy/branch/pyjitpl5/pypy/interpreter Message-ID: <20090819195206.E4AF716801D@codespeak.net> Author: cfbolz Date: Wed Aug 19 21:52:05 2009 New Revision: 67005 Modified: pypy/branch/pyjitpl5/pypy/interpreter/gateway.py pypy/branch/pyjitpl5/pypy/interpreter/typedef.py Log: (pedronis, cfbolz): sprinkle sprinkle little star Modified: pypy/branch/pyjitpl5/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/gateway.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/gateway.py Wed Aug 19 21:52:05 2009 @@ -533,6 +533,7 @@ # (verbose) performance hack below class BuiltinCodePassThroughArguments0(BuiltinCode): + _immutable_ = True def funcrun(self, func, args): space = func.space @@ -557,6 +558,7 @@ return w_result class BuiltinCodePassThroughArguments1(BuiltinCode): + _immutable_ = True fast_natural_arity = -1 def funcrun_obj(self, func, w_obj, args): @@ -582,10 +584,10 @@ return w_result class BuiltinCode0(BuiltinCode): + _immutable_ = True fast_natural_arity = 0 def fastcall_0(self, space, w_func): - #self = hint(self, deepfreeze=True) try: w_result = self.fastfunc_0(space) except KeyboardInterrupt: @@ -602,10 +604,10 @@ return w_result class BuiltinCode1(BuiltinCode): + _immutable_ = True fast_natural_arity = 1 def fastcall_1(self, space, w_func, w1): - #self = hint(self, deepfreeze=True) try: w_result = self.fastfunc_1(space, w1) except KeyboardInterrupt: @@ -627,10 +629,10 @@ return w_result class BuiltinCode2(BuiltinCode): + _immutable_ = True fast_natural_arity = 2 def fastcall_2(self, space, w_func, w1, w2): - #self = hint(self, deepfreeze=True) try: w_result = self.fastfunc_2(space, w1, w2) except KeyboardInterrupt: @@ -652,10 +654,10 @@ return w_result class BuiltinCode3(BuiltinCode): + _immutable_ = True fast_natural_arity = 3 def fastcall_3(self, space, func, w1, w2, w3): - #self = hint(self, deepfreeze=True) try: w_result = self.fastfunc_3(space, w1, w2, w3) except KeyboardInterrupt: @@ -677,10 +679,10 @@ return w_result class BuiltinCode4(BuiltinCode): + _immutable_ = True fast_natural_arity = 4 def fastcall_4(self, space, func, w1, w2, w3, w4): - #self = hint(self, deepfreeze=True) try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) except KeyboardInterrupt: Modified: pypy/branch/pyjitpl5/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/typedef.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/typedef.py Wed Aug 19 21:52:05 2009 @@ -11,6 +11,7 @@ from pypy.tool.sourcetools import compile2, func_with_new_name from pypy.rlib.objectmodel import instantiate from pypy.rlib.rarithmetic import intmask +from pypy.rlib.jit import hint class TypeDef: def __init__(self, __name, __base=None, **rawdict): @@ -225,7 +226,7 @@ if "user" in features: # generic feature needed by all subcls class Proto(object): def getclass(self, space): - return self.w__class__ + return hint(self.w__class__, promote=True) def setclass(self, space, w_subtype): # only used by descr_set___class__ From cfbolz at codespeak.net Thu Aug 20 10:18:06 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Aug 2009 10:18:06 +0200 (CEST) Subject: [pypy-svn] r67009 - pypy/branch/pyjitpl5/pypy/doc/config Message-ID: <20090820081806.62CF9168038@codespeak.net> Author: cfbolz Date: Thu Aug 20 10:18:03 2009 New Revision: 67009 Added: pypy/branch/pyjitpl5/pypy/doc/config/translation.backendopt.really_remove_asserts.txt (contents, props changed) Log: missing doc Added: pypy/branch/pyjitpl5/pypy/doc/config/translation.backendopt.really_remove_asserts.txt ============================================================================== From cfbolz at codespeak.net Thu Aug 20 10:40:39 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Aug 2009 10:40:39 +0200 (CEST) Subject: [pypy-svn] r67011 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090820084039.9FDCE168020@codespeak.net> Author: cfbolz Date: Thu Aug 20 10:40:38 2009 New Revision: 67011 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Thu Aug 20 10:40:38 2009 @@ -1,6 +1,5 @@ People present: - - Armin - Samuele - Maciek - Carl Friedrich @@ -9,6 +8,9 @@ later: - Anto + - Armin + - Iko + - Bea discussions to be had: - what goals/benchmarks do we want for the prototype DONE @@ -88,19 +90,25 @@ look at tests - more or less full coverage for optimize*.py - - remove asserts before bytecode production DONE - - make pypyjit.py work again DONE - - add tests for x86 backend IN-PROGRESS + - add tests for x86 backend DONE - make test_ll_random.py a bit better than before - - set up test_ll_random to run nightly + - set up test_ll_random to run nightly with x86 backend + - fix test_ll_random with llgraph backend + - fix x86 nightly failure (Maciek, Benjamin) + - fix the generator test on trunk (Maciek, Benjamin) + - look at the codewriter problems (Mikael, Carl Friedrich) - - optimize generator closing DONE - make x86 not recompile everything - - write more tests that cover recompilation (Samuele, Maciek) - think about code memory management - - optimize chains of ooisnull/oononnull DONE - - discuss constantness improvements DONE - - don't trace into action flag stuff (Benjamin, Armin) - - bit of inlining before bytecode production (Carl Friedrich, Mikael) + - don't trace into action flag stuff DONE + - bit of inlining before bytecode production DONE - inlining on the Python level - storage sinking (removing consecutive getfields/setfields) + - build a pypy-c-jit from before the sprint for comparison + + - green virtualizable fields + - remove the numerous checks for frame.vable_rti in the + interpreter (non-JITting) part + - test the loops that pypy-c-jit produces + + - what to do with the minimal backend? From fijal at codespeak.net Thu Aug 20 10:48:44 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 10:48:44 +0200 (CEST) Subject: [pypy-svn] r67012 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090820084844.B3FB1168020@codespeak.net> Author: fijal Date: Thu Aug 20 10:48:44 2009 New Revision: 67012 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Log: (benjamin, fijal) Fix the zrpy test which is not prepared to deal with functions returning None Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py Thu Aug 20 10:48:44 2009 @@ -426,6 +426,7 @@ i += 1 except OverflowError: i += 2 + return 0 self.meta_interp(f, [0, 0]) self.meta_interp(f, [1, 0]) From cfbolz at codespeak.net Thu Aug 20 10:52:52 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Aug 2009 10:52:52 +0200 (CEST) Subject: [pypy-svn] r67013 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090820085252.C0B88168020@codespeak.net> Author: cfbolz Date: Thu Aug 20 10:52:52 2009 New Revision: 67013 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: (mikke, cfbolz): don't inline the portal anywhere Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 20 10:52:52 2009 @@ -184,6 +184,8 @@ assert len(dict.fromkeys(graph.getargs())) == len(graph.getargs()) self.translator.graphs.append(graph) self.portal_graph = graph + if hasattr(graph, "func"): + graph.func._dont_inline_ = True self.jitdriver = block.operations[pos].args[1].value def prejit_optimizations(self, policy): From benjamin at codespeak.net Thu Aug 20 11:15:29 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 11:15:29 +0200 (CEST) Subject: [pypy-svn] r67014 - in pypy/trunk/pypy: interpreter module/_weakref/test Message-ID: <20090820091529.21FE9168026@codespeak.net> Author: benjamin Date: Thu Aug 20 11:15:28 2009 New Revision: 67014 Modified: pypy/trunk/pypy/interpreter/generator.py pypy/trunk/pypy/module/_weakref/test/test_weakref.py Log: the applevel __del__ must always be called for weakrefs to be cleared Modified: pypy/trunk/pypy/interpreter/generator.py ============================================================================== --- pypy/trunk/pypy/interpreter/generator.py (original) +++ pypy/trunk/pypy/interpreter/generator.py Thu Aug 20 11:15:28 2009 @@ -123,11 +123,12 @@ applevel __del__, which is called at a safe point after the interp-level __del__ enqueued the object for destruction """ - self.descr_close() - - def __del__(self): + # Only bother raising an exception if the frame is still not + # finished and finally or except blocks are present. if not self.frame.frame_finished_execution: for block in self.frame.blockstack: if not isinstance(block, LoopBlock): - self._enqueue_for_destruction(self.space) - break + self.descr_close() + + def __del__(self): + self._enqueue_for_destruction(self.space) Modified: pypy/trunk/pypy/module/_weakref/test/test_weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/test/test_weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/test/test_weakref.py Thu Aug 20 11:15:28 2009 @@ -231,6 +231,12 @@ del g gc.collect() assert w() is None + g = f(10) + w = _weakref.ref(g) + assert list(g) == range(10) + del g + gc.collect() + assert w() is None def test_weakref_subclass_with_del(self): import _weakref, gc From fijal at codespeak.net Thu Aug 20 11:38:25 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 11:38:25 +0200 (CEST) Subject: [pypy-svn] r67015 - pypy/branch/pyjitpl5/pypy/translator/c/gcc Message-ID: <20090820093825.F35A2168026@codespeak.net> Author: fijal Date: Thu Aug 20 11:38:24 2009 New Revision: 67015 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: (benjamin, fijal) Skip bswap operation Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Thu Aug 20 11:38:24 2009 @@ -515,6 +515,7 @@ # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', + 'bswap', # zero-extending moves should not produce GC pointers 'movz', ]) From pedronis at codespeak.net Thu Aug 20 12:11:05 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 12:11:05 +0200 (CEST) Subject: [pypy-svn] r67016 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090820101105.8550D168026@codespeak.net> Author: pedronis Date: Thu Aug 20 12:11:04 2009 New Revision: 67016 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Log: (iko, pedronis) - fix test_ll_random but what should be the semantics of guard_exception?? Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Thu Aug 20 12:11:04 2009 @@ -532,7 +532,7 @@ builder.cpu.clear_exception() while True: _, vtableptr = builder.get_random_structure_type_and_vtable(r) - if vtableptr != exc: + if not rclass.ll_issubclass(vtableptr, exc): break other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr()) From fijal at codespeak.net Thu Aug 20 12:55:00 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 12:55:00 +0200 (CEST) Subject: [pypy-svn] r67017 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090820105500.9A91F16802F@codespeak.net> Author: fijal Date: Thu Aug 20 12:54:58 2009 New Revision: 67017 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Log: make output a bit nicer Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Thu Aug 20 12:54:58 2009 @@ -529,7 +529,7 @@ self.builder.cpu.compile_operations(self.loop) return True -def check_random_function(cpu, BuilderClass, r): +def check_random_function(cpu, BuilderClass, r, num=None, max=None): loop = RandomLoop(cpu, BuilderClass, r) while True: loop.run_loop() @@ -538,7 +538,10 @@ break else: break - print ' # passed.' + if num is not None: + print ' # passed (%d/%d).' % (num + 1, max) + else: + print ' # passed.' print def test_random_function(BuilderClass=OperationBuilder): @@ -549,4 +552,5 @@ check_random_function(cpu, BuilderClass, r) else: for i in range(demo_conftest.option.repeat): - check_random_function(cpu, BuilderClass, r) + check_random_function(cpu, BuilderClass, r, i, + demo_conftest.option.repeat) From fijal at codespeak.net Thu Aug 20 12:56:05 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 12:56:05 +0200 (CEST) Subject: [pypy-svn] r67018 - in pypy/branch/pyjitpl5/pypy/jit/backend: . cli x86 Message-ID: <20090820105605.6E19416802F@codespeak.net> Author: fijal Date: Thu Aug 20 12:56:03 2009 New Revision: 67018 Added: pypy/branch/pyjitpl5/pypy/jit/backend/logger.py - copied, changed from r66997, pypy/branch/pyjitpl5/pypy/jit/backend/support.py Removed: pypy/branch/pyjitpl5/pypy/jit/backend/support.py Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Log: (benjamin, fijal) * IN-PROGRESS start working on parsing logger output * Rename support.py to logger.py as that's what it's there * Make output slightly nicer Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu Aug 20 12:56:03 2009 @@ -10,7 +10,7 @@ from pypy.jit.metainterp.history import (AbstractValue, Const, ConstInt, ConstObj) from pypy.jit.metainterp.resoperation import rop, opname -from pypy.jit.backend.support import AbstractLogger +from pypy.jit.backend.logger import AbstractLogger from pypy.jit.backend.cli import runner from pypy.jit.backend.cli.methodfactory import get_method_wrapper Copied: pypy/branch/pyjitpl5/pypy/jit/backend/logger.py (from r66997, pypy/branch/pyjitpl5/pypy/jit/backend/support.py) ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/support.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/logger.py Thu Aug 20 12:56:03 2009 @@ -69,7 +69,7 @@ op = operations[i] if op.opnum == rop.DEBUG_MERGE_POINT: loc = op.args[0]._get_str() - os.write(self._log_fd, pre + "%s\n" % (loc,)) + os.write(self._log_fd, pre + "#%s\n" % (loc,)) continue args = ",".join([self.repr_of_arg(memo, arg) for arg in op.args]) if op.descr is not None: @@ -85,13 +85,13 @@ if op.is_guard(): self.eventually_log_operations(None, op.suboperations, memo, indent=indent+2) - if operations[-1].opnum == rop.JUMP: - if operations[-1].jump_target is not None: - jump_target = compute_unique_id(operations[-1].jump_target) - else: - # XXX hack for the annotator - jump_target = 13 - os.write(self._log_fd, pre + 'JUMPTO:%s\n' % jump_target) +# if operations[-1].opnum == rop.JUMP: +# if operations[-1].jump_target is not None: + +# else: +# # XXX hack for the annotator +# jump_target = 13 +# os.write(self._log_fd, pre + 'JUMPTO:%s\n' % jump_target) if inputargs is None: os.write(self._log_fd, pre + "END\n") else: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 12:56:03 2009 @@ -5,6 +5,117 @@ import sys, py, re +def count_indent(s): + indent = 0 + for char in s: + if char != " ": + break + indent += 1 + return indent + +class EndOfBlock(Exception): + pass + +class Block(object): + def __init__(self): + self.operations = [] + + def add(self, element): + self.operations.append(element) + +class Comment(object): + def __init__(self, text): + self.text = text + +class Operation(object): + def __init__(self, opname, args, result=None): + self.opname = opname + self.args = args + self.result = result + + def __repr__(self): + if self.result is None: + return "%s(%s)" % (self.opname, self.args) + return "%s = %s(%s)" % (self.result, self.opname, self.args) + +class GuardOperation(Operation): + pass + +class Parser(object): + current_indentation = 0 + + def parse(self, fname): + self.current_block = Block() + self.blockstack = [] + data = py.path.local(fname).read() + lines = data.splitlines() + i = 0 + res = self._parse(lines, i) + assert res == len(lines) + assert not self.blockstack + return self.current_block + + def parse_args(self, args): + return args + + def parse_result(self, result): + return result + + def parse_inputargs(self, inputargs): + return inputargs + + def parse_block(self, lines, start, guard_op): + self.blockstack.append(self.current_block) + block = Block() + guard_op.suboperations = block + self.current_block = block + res = self._parse(lines, start) + self.current_block = self.blockstack.pop() + self.current_indentation -= 2 + return res + + def parse_next_instruction(self, lines, i): + line = lines[i].strip() + if line.startswith('LOOP END'): + raise EndOfBlock() + if line.startswith('LOOP'): + _, inputargs = line.split(" ") + self.current_block.inputargs = self.parse_inputargs(inputargs) + return i + 1 + if line.startswith('END'): + raise EndOfBlock() + if line.startswith('#'): + self.current_block.add(Comment(line[1:])) + return i + 1 + opname, args = line.split(" ") + _, opname = opname.split(":") + args = self.parse_args(args) + if lines[i + 1].startswith(" " * (self.current_indentation + 2)): + if lines[i + 1].strip().startswith('BEGIN'): + self.current_indentation += 2 + guard_op = GuardOperation(opname, args) + self.current_block.add(guard_op) + return self.parse_block(lines, i + 2, guard_op) + marker, result = lines[i + 1].strip().split(" ") + assert marker == '=>' + result = self.parse_result(result) + self.current_block.add(Operation(opname, args, result)) + return i + 2 + else: + self.current_block.add(Operation(opname, args)) + return i + 1 + + def _parse(self, lines, i): + while True: + try: + indentation = count_indent(lines[i]) + if indentation == self.current_indentation: + i = self.parse_next_instruction(lines, i) + else: + xxx + except EndOfBlock: + return i + 1 + def pairs(lst): res = [] for i in range(0, len(lst), 2): @@ -27,7 +138,7 @@ self.jmp_from = jmp_from self.args = args -class Parser(object): +class OldParser(object): def __init__(self): self.boxes = {} self.box_creations = [] @@ -185,11 +296,3 @@ parser.parse(sys.argv[1]) parser.output() -def test_loopparser(): - parser = Parser() - parser.parse(py.magic.autopath().join('..', 'inp')) - assert len(parser.blocks[0].operations) == 10 - assert parser.blocks[0].operations[1] == ('int_add', - ['boxint_2', 'boxint_0'], 'boxint_3', None) - assert len(parser.box_creations) == 13 - Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Thu Aug 20 12:56:03 2009 @@ -13,7 +13,7 @@ from pypy.jit.backend.x86 import codebuf from pypy.jit.backend.x86.ri386 import * from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.support import AbstractLogger +from pypy.jit.backend.logger import AbstractLogger # our calling convention - we pass three first args as edx, ecx and eax # and the rest stays on the stack From fijal at codespeak.net Thu Aug 20 12:56:36 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 12:56:36 +0200 (CEST) Subject: [pypy-svn] r67019 - in pypy/branch/pyjitpl5/pypy/jit/backend/test: . loopdata Message-ID: <20090820105636.33F2D16802F@codespeak.net> Author: fijal Date: Thu Aug 20 12:56:35 2009 New Revision: 67019 Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (contents, props changed) Log: Tests for the previous checkin Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Thu Aug 20 12:56:35 2009 @@ -0,0 +1,15 @@ +LOOP bi(0,6),bi(1,4),bi(2,18) +#(no jitdriver.get_printable_location!) +1:int_add bi(2,18),bi(0,6) + => bi(3,24) +2:int_sub bi(1,4),ci(4,1) + => bi(5,3) +3:int_gt bi(5,3),ci(6,0) + => bi(7,1) +4:guard_true bi(7,1) + BEGIN(0) + 0:fail bi(0,6),bi(5,3),bi(3,24)[] + END +#(no jitdriver.get_printable_location!) +6:jump bi(0,6),bi(5,3),bi(3,24) +LOOP END Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Thu Aug 20 12:56:35 2009 @@ -0,0 +1,21 @@ + +import py +from pypy.jit.backend.loopparser import * + +class TestParser(object): + def parse(self, name): + parser = Parser() + return parser.parse(py.magic.autopath().join('..', 'loopdata', name)) + + def test_simple_loop(self): + topblock = self.parse('simple.ops') + assert len(topblock.operations) == 7 + assert isinstance(topblock.operations[0], Comment) + assert isinstance(topblock.operations[-2], Comment) + assert isinstance(topblock.operations[4], GuardOperation) + assert ([op.opname for op in topblock.operations + if not isinstance(op, Comment)] == + ['int_add', 'int_sub', 'int_gt', 'guard_true', 'jump']) + subops = topblock.operations[4].suboperations.operations + assert len(subops) == 1 + assert subops[0].opname == 'fail' From arigo at codespeak.net Thu Aug 20 13:07:51 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 13:07:51 +0200 (CEST) Subject: [pypy-svn] r67020 - pypy/branch/pyjitpl5/pypy/interpreter Message-ID: <20090820110751.9B60A16800F@codespeak.net> Author: arigo Date: Thu Aug 20 13:07:51 2009 New Revision: 67020 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Log: (cfbolz, arigo) Shut off the warning: "general usage of virtualizable array" by skipping the functions explicitly. Some of those will need to be revisited at some point. Modified: pypy/branch/pyjitpl5/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pycode.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pycode.py Thu Aug 20 13:07:51 2009 @@ -12,6 +12,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.rlib.rarithmetic import intmask from pypy.rlib.debug import make_sure_not_resized, make_sure_not_modified +from pypy.rlib import jit # helper @@ -183,6 +184,7 @@ self.fast_natural_arity = PyCode.FLATPYCALL | self.co_argcount + @jit.dont_look_inside def funcrun(self, func, args): frame = self.space.createframe(self, func.w_func_globals, func.closure) @@ -194,6 +196,7 @@ frame.init_cells() return frame.run() + @jit.dont_look_inside def funcrun_obj(self, func, w_obj, args): frame = self.space.createframe(self, func.w_func_globals, func.closure) Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Thu Aug 20 13:07:51 2009 @@ -10,6 +10,7 @@ from pypy.rlib.objectmodel import we_are_translated, instantiate from pypy.rlib.jit import we_are_jitted, hint from pypy.rlib.debug import make_sure_not_resized +from pypy.rlib import jit # Define some opcodes used g = globals() @@ -245,7 +246,8 @@ return Arguments(self.space, self.peekvalues(nargs)) else: return ArgumentsFromValuestack(self.space, self, nargs) - + + @jit.dont_look_inside def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule from pypy.module._pickle_support import maker # helper fns @@ -304,6 +306,7 @@ return nt([new_inst, nt([]), nt(tup_state)]) + @jit.dont_look_inside def descr__setstate__(self, space, w_args): from pypy.module._pickle_support import maker # helper fns from pypy.interpreter.pycode import PyCode @@ -368,6 +371,7 @@ def getcode(self): return hint(self.pycode, promote=True) + @jit.dont_look_inside def getfastscope(self): "Get the fast locals as a list." return self.fastlocals_w @@ -378,7 +382,10 @@ scope_len = len(scope_w) if scope_len > len(self.fastlocals_w): raise ValueError, "new fastscope is longer than the allocated area" - self.fastlocals_w[:scope_len] = scope_w + # don't assign directly to 'fastlocals_w[:scope_len]' to be + # virtualizable-friendly + for i in range(scope_len): + self.fastlocals_w[i] = scope_w[i] self.init_cells() def init_cells(self): From arigo at codespeak.net Thu Aug 20 13:13:52 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 13:13:52 +0200 (CEST) Subject: [pypy-svn] r67021 - in pypy/branch/pyjitpl5/pypy/jit: metainterp metainterp/test tl Message-ID: <20090820111352.5AE2F168026@codespeak.net> Author: arigo Date: Thu Aug 20 13:13:50 2009 New Revision: 67021 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/jit/tl/tl.py Log: (cfbolz, arigo) Kill the "XXX temporary" hack from codewriter.py. Now you get the VirtualizableArrayField exception explicitly, and you have to disable the graph manually with jit.dont_look_inside (or meditate on the structure of your code). Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Thu Aug 20 13:13:50 2009 @@ -302,7 +302,6 @@ assert not portal, "portal has been hidden!" graph = make_calling_stub(codewriter.rtyper, graph) self.graph = graph - self._tmphack = False def assemble(self): """Assemble the opcodes for self.bytecode.""" @@ -313,24 +312,10 @@ self.seen_blocks = {} self.dont_minimize_variables = 0 self.pending_exception_handlers = [] - try: - self.make_bytecode_block(self.graph.startblock) - while self.pending_exception_handlers: - exc_handler = self.pending_exception_handlers.pop() - self.make_exception_handler(exc_handler) - except VirtualizableArrayField: - # using a virtualizable's array in an unsupported way -- give up - # (XXX temporary hack, improve...) - if self.portal: - raise - history.log.WARNING('general usage of a virtualizable array, ' - 'ignoring graph') - history.log.WARNING(' %s' % (self.graph,)) - assert self._tmphack is False - self._tmphack = True - self.graph = make_calling_stub(self.codewriter.rtyper, self.graph) - self.assemble() - return + self.make_bytecode_block(self.graph.startblock) + while self.pending_exception_handlers: + exc_handler = self.pending_exception_handlers.pop() + self.make_exception_handler(exc_handler) labelpos = {} code = assemble(labelpos, self.codewriter.metainterp_sd, @@ -932,7 +917,7 @@ if op.args[1].value in vinfo.static_field_to_extra_box: return True if op.args[1].value in vinfo.array_fields: - raise VirtualizableArrayField + raise VirtualizableArrayField(self.graph) return False def handle_getfield_typeptr(self, op): @@ -1075,8 +1060,6 @@ def serialize_op_direct_call(self, op): kind = self.codewriter.policy.guess_call_kind(op) - if self._tmphack: - kind = 'residual' return getattr(self, 'handle_%s_call' % kind)(op) def serialize_op_indirect_call(self, op): @@ -1424,7 +1407,7 @@ return self.var_positions[v] except KeyError: if v in self.vable_array_vars: - raise VirtualizableArrayField + raise VirtualizableArrayField(self.graph) raise def emit(self, *stuff): @@ -1534,4 +1517,6 @@ return newgraph class VirtualizableArrayField(Exception): - pass + def __str__(self): + return "using virtualizable array in illegal way in %r" % ( + self.args[0],) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Thu Aug 20 13:13:50 2009 @@ -110,7 +110,7 @@ 'int_is_true':1, 'guard_false':1, 'jump':1, 'guard_value':1}) - def test_tl_call(self, listops=True): + def test_tl_call(self, listops=True, policy=None): from pypy.jit.tl.tl import interp from pypy.jit.tl.tlopcode import compile from pypy.jit.metainterp import simple_optimize @@ -146,14 +146,21 @@ return interp(codes[num], inputarg=arg) res = self.meta_interp(main, [0, 20], optimizer=simple_optimize, - listops=listops, backendopt=True) + listops=listops, backendopt=True, policy=policy) assert res == 0 def test_tl_call_full_of_residuals(self): # This forces most methods of Stack to be ignored and treated as # residual calls. It tests that the right thing occurs in this # case too. - self.test_tl_call(listops=False) + from pypy.jit.tl.tl import Stack + methods = [Stack.put, + Stack.pick, + Stack.roll, + Stack.append, + Stack.pop] + methods = [m.im_func for m in methods] + self.test_tl_call(listops=False, policy=StopAtXPolicy(*methods)) class TestOOtype(ToyLanguageTests, OOJitMixin): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Thu Aug 20 13:13:50 2009 @@ -2,7 +2,7 @@ from pypy.rpython.lltypesystem import lltype, lloperation, rclass, llmemory from pypy.rpython.annlowlevel import llhelper from pypy.jit.metainterp.policy import StopAtXPolicy -from pypy.rlib.jit import JitDriver, hint +from pypy.rlib.jit import JitDriver, hint, dont_look_inside from pypy.rlib.rarithmetic import intmask from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR @@ -343,11 +343,14 @@ myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'], virtualizables = ['xy2']) ARRAY = lltype.GcArray(lltype.Signed) + # + @dont_look_inside def h(xy2): - # so far, this function is marked for residual calls because + # this function is marked for residual calls because # it does something with a virtualizable's array that is not # just accessing an item return xy2.inst_l2 + # def g(xy2, n): while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 20 13:13:50 2009 @@ -47,9 +47,8 @@ def ll_meta_interp(function, args, backendopt=False, type_system='lltype', **kwds): interp, graph = get_interpreter(function, args, - backendopt=backendopt, - type_system=type_system, - inline_threshold=0) + backendopt=False, # will be done below + type_system=type_system) clear_tcache() return jittify_and_run(interp, graph, args, backendopt=backendopt, **kwds) Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tl.py Thu Aug 20 13:13:50 2009 @@ -2,7 +2,7 @@ import py from pypy.jit.tl.tlopcode import * -from pypy.rlib.jit import JitDriver, hint +from pypy.rlib.jit import JitDriver, hint, dont_look_inside def char2int(c): t = ord(c) @@ -12,7 +12,8 @@ class Stack(object): _virtualizable2_ = ['stackpos', 'stack[*]'] - + + @dont_look_inside def __init__(self, size): self.stack = [0] * size self.stackpos = 0 From arigo at codespeak.net Thu Aug 20 13:30:23 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 13:30:23 +0200 (CEST) Subject: [pypy-svn] r67022 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090820113023.720BB16803C@codespeak.net> Author: arigo Date: Thu Aug 20 13:30:21 2009 New Revision: 67022 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Log: Check early that we really have the hybrid GC. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Thu Aug 20 13:30:21 2009 @@ -280,6 +280,11 @@ self.cpu = cpu self.translator = cpu.mixlevelann.rtyper.annotator.translator + # we need the hybrid GC for GcRefList.alloc_gcref_list() to work + if gcdescr.config.translation.gc != 'hybrid': + raise NotImplementedError("--gc=%s not implemented with the JIT" % + (gcdescr.config.translation.gc,)) + # to find roots in the assembler, make a GcRootMap name = gcdescr.config.translation.gcrootfinder try: From arigo at codespeak.net Thu Aug 20 13:31:26 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 13:31:26 +0200 (CEST) Subject: [pypy-svn] r67023 - pypy/branch/pyjitpl5/pypy/config Message-ID: <20090820113126.E3E7116803E@codespeak.net> Author: arigo Date: Thu Aug 20 13:31:26 2009 New Revision: 67023 Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py Log: Kill the now-obscure 'suggests' for --gcrootfinder=asmgcc. Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Thu Aug 20 13:31:26 2009 @@ -82,11 +82,7 @@ "asmgcc": [("translation.gctransformer", "framework"), ("translation.backend", "c"), ("translation.thread", False)], - }, - suggests={ - "shadowstack": [("translation.gc", "generation")], - "asmgcc": [("translation.gc", "generation")], - }), + }), # other noticeable options BoolOption("thread", "enable use of threading primitives", From pedronis at codespeak.net Thu Aug 20 14:35:29 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 14:35:29 +0200 (CEST) Subject: [pypy-svn] r67024 - in pypy/branch/pyjitpl5/pypy/jit/backend: llgraph test Message-ID: <20090820123529.213E016803E@codespeak.net> Author: pedronis Date: Thu Aug 20 14:35:28 2009 New Revision: 67024 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Log: (iko, pedronis) fix guard_excecption to use an exact match Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Thu Aug 20 14:35:28 2009 @@ -552,7 +552,8 @@ exc = _last_exception if exc: got = exc.args[0] - if not self._issubclass(got, expected_exception): + # exact match! + if got != expected_exception: return False return True else: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Thu Aug 20 14:35:28 2009 @@ -266,35 +266,65 @@ assert not self.cpu.get_exc_value() def test_exceptions(self): + exc_tp = None + exc_ptr = None def func(i): if i: - raise LLException(zdtp, zdptr) + raise LLException(exc_tp, exc_ptr) ops = ''' [i0] call(ConstClass(fptr), i0, descr=calldescr) - p0 = guard_exception(ConstClass(zdtp)) + p0 = guard_exception(ConstClass(xtp)) fail(1) fail(0, p0) ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) - zdtp, zdptr = self.cpu.get_zero_division_error() - zd_addr = self.cpu.cast_int_to_adr(zdtp) - zdtp = llmemory.cast_adr_to_ptr(zd_addr, lltype.Ptr(self.MY_VTABLE)) + + xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + xtp.subclassrange_min = 1 + xtp.subclassrange_max = 3 + X = lltype.GcStruct('X', ('parent', rclass.OBJECT), + hints={'vtable': xtp._obj}) + xptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(X)) + + + exc_tp = xtp + exc_ptr = xptr loop = parse(ops, self.cpu, namespace=locals()) self.cpu.compile_operations(loop) self.cpu.set_future_value_int(0, 1) self.cpu.execute_operations(loop) assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_ptr(1) == zdptr + assert self.cpu.get_latest_value_ptr(1) == xptr self.cpu.clear_exception() self.cpu.set_future_value_int(0, 0) self.cpu.execute_operations(loop) assert self.cpu.get_latest_value_int(0) == 1 self.cpu.clear_exception() + ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + ytp.subclassrange_min = 2 + ytp.subclassrange_max = 2 + assert rclass.ll_issubclass(ytp, xtp) + Y = lltype.GcStruct('Y', ('parent', rclass.OBJECT), + hints={'vtable': ytp._obj}) + yptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(Y)) + + # guard_exception uses an exact match + exc_tp = ytp + exc_ptr = yptr + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + + exc_tp = xtp + exc_ptr = xptr ops = ''' [i0] call(ConstClass(fptr), i0, descr=calldescr) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Thu Aug 20 14:35:28 2009 @@ -532,7 +532,7 @@ builder.cpu.clear_exception() while True: _, vtableptr = builder.get_random_structure_type_and_vtable(r) - if not rclass.ll_issubclass(vtableptr, exc): + if vtableptr != exc: break other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr()) From pedronis at codespeak.net Thu Aug 20 14:37:16 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 14:37:16 +0200 (CEST) Subject: [pypy-svn] r67025 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090820123716.B2F2E16803E@codespeak.net> Author: pedronis Date: Thu Aug 20 14:37:15 2009 New Revision: 67025 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: in its current form this test is a LL only test Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Thu Aug 20 14:37:15 2009 @@ -265,84 +265,6 @@ assert not self.cpu.get_exception() assert not self.cpu.get_exc_value() - def test_exceptions(self): - exc_tp = None - exc_ptr = None - def func(i): - if i: - raise LLException(exc_tp, exc_ptr) - - ops = ''' - [i0] - call(ConstClass(fptr), i0, descr=calldescr) - p0 = guard_exception(ConstClass(xtp)) - fail(1) - fail(0, p0) - ''' - FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) - fptr = llhelper(FPTR, func) - calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) - - xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) - xtp.subclassrange_min = 1 - xtp.subclassrange_max = 3 - X = lltype.GcStruct('X', ('parent', rclass.OBJECT), - hints={'vtable': xtp._obj}) - xptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(X)) - - - exc_tp = xtp - exc_ptr = xptr - loop = parse(ops, self.cpu, namespace=locals()) - self.cpu.compile_operations(loop) - self.cpu.set_future_value_int(0, 1) - self.cpu.execute_operations(loop) - assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_ptr(1) == xptr - self.cpu.clear_exception() - self.cpu.set_future_value_int(0, 0) - self.cpu.execute_operations(loop) - assert self.cpu.get_latest_value_int(0) == 1 - self.cpu.clear_exception() - - ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) - ytp.subclassrange_min = 2 - ytp.subclassrange_max = 2 - assert rclass.ll_issubclass(ytp, xtp) - Y = lltype.GcStruct('Y', ('parent', rclass.OBJECT), - hints={'vtable': ytp._obj}) - yptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(Y)) - - # guard_exception uses an exact match - exc_tp = ytp - exc_ptr = yptr - loop = parse(ops, self.cpu, namespace=locals()) - self.cpu.compile_operations(loop) - self.cpu.set_future_value_int(0, 1) - self.cpu.execute_operations(loop) - assert self.cpu.get_latest_value_int(0) == 1 - self.cpu.clear_exception() - - exc_tp = xtp - exc_ptr = xptr - ops = ''' - [i0] - call(ConstClass(fptr), i0, descr=calldescr) - guard_no_exception() - fail(1) - fail(0) - ''' - loop = parse(ops, self.cpu, namespace=locals()) - self.cpu.compile_operations(loop) - self.cpu.set_future_value_int(0, 1) - self.cpu.execute_operations(loop) - assert self.cpu.get_latest_value_int(0) == 1 - self.cpu.clear_exception() - self.cpu.set_future_value_int(0, 0) - self.cpu.execute_operations(loop) - assert self.cpu.get_latest_value_int(0) == 0 - self.cpu.clear_exception() - def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) @@ -929,6 +851,84 @@ [value, chr1, chr2]) assert len(dict.fromkeys([value, chr1, chr2]).keys()) == 3 + def test_exceptions(self): + exc_tp = None + exc_ptr = None + def func(i): + if i: + raise LLException(exc_tp, exc_ptr) + + ops = ''' + [i0] + call(ConstClass(fptr), i0, descr=calldescr) + p0 = guard_exception(ConstClass(xtp)) + fail(1) + fail(0, p0) + ''' + FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) + fptr = llhelper(FPTR, func) + calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT) + + xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + xtp.subclassrange_min = 1 + xtp.subclassrange_max = 3 + X = lltype.GcStruct('X', ('parent', rclass.OBJECT), + hints={'vtable': xtp._obj}) + xptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(X)) + + + exc_tp = xtp + exc_ptr = xptr + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 0 + assert self.cpu.get_latest_value_ptr(1) == xptr + self.cpu.clear_exception() + self.cpu.set_future_value_int(0, 0) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + + ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + ytp.subclassrange_min = 2 + ytp.subclassrange_max = 2 + assert rclass.ll_issubclass(ytp, xtp) + Y = lltype.GcStruct('Y', ('parent', rclass.OBJECT), + hints={'vtable': ytp._obj}) + yptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(Y)) + + # guard_exception uses an exact match + exc_tp = ytp + exc_ptr = yptr + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + + exc_tp = xtp + exc_ptr = xptr + ops = ''' + [i0] + call(ConstClass(fptr), i0, descr=calldescr) + guard_no_exception() + fail(1) + fail(0) + ''' + loop = parse(ops, self.cpu, namespace=locals()) + self.cpu.compile_operations(loop) + self.cpu.set_future_value_int(0, 1) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 1 + self.cpu.clear_exception() + self.cpu.set_future_value_int(0, 0) + self.cpu.execute_operations(loop) + assert self.cpu.get_latest_value_int(0) == 0 + self.cpu.clear_exception() + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' From cfbolz at codespeak.net Thu Aug 20 14:41:58 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Aug 2009 14:41:58 +0200 (CEST) Subject: [pypy-svn] r67026 - pypy/branch/pyjitpl5/pypy/interpreter Message-ID: <20090820124158.A3305168041@codespeak.net> Author: cfbolz Date: Thu Aug 20 14:41:58 2009 New Revision: 67026 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Log: also cannot look into PyFrame.__init__ Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Thu Aug 20 14:41:58 2009 @@ -47,6 +47,7 @@ instr_prev = -1 is_being_profiled = False + @jit.dont_look_inside def __init__(self, space, code, w_globals, closure): #self = hint(self, access_directly=True) assert isinstance(code, pycode.PyCode) From afa at codespeak.net Thu Aug 20 14:50:52 2009 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 20 Aug 2009 14:50:52 +0200 (CEST) Subject: [pypy-svn] r67027 - pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc Message-ID: <20090820125052.71F86168038@codespeak.net> Author: afa Date: Thu Aug 20 14:50:52 2009 New Revision: 67027 Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Log: On Windows, decorated function names can contain @, so are the label names. Modified: pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-mingw32/pypy/translator/c/gcc/trackgcroot.py Thu Aug 20 14:50:52 2009 @@ -23,15 +23,16 @@ r_functionstart_darwin = re.compile(r"_(\w+):\s*$") # inside functions -r_label = re.compile(r"([.]?\w+)[:]\s*$") +LABEL = r'([.]?[\w$@]+)' +r_label = re.compile(LABEL+"[:]\s*$") r_globl = re.compile(r"\t[.]globl\t(\w+)\s*$") r_insn = re.compile(r"\t([a-z]\w*)\s") -r_jump = re.compile(r"\tj\w+\s+([.]?[\w$]+)\s*$") +r_jump = re.compile(r"\tj\w+\s+"+LABEL+"\s*$") OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])' r_unaryinsn = re.compile(r"\t[a-z]\w*\s+("+OPERAND+")\s*$") r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+([*]"+OPERAND+")\s*$") -r_jmp_switch = re.compile(r"\tjmp\t[*]([.]?\w+)[(]") -r_jmptable_item = re.compile(r"\t.long\t([.]?\w+)\s*$") +r_jmp_switch = re.compile(r"\tjmp\t[*]"+LABEL+"[(]") +r_jmptable_item = re.compile(r"\t.long\t"+LABEL+"\s*$") r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text") r_binaryinsn = re.compile(r"\t[a-z]\w*\s+("+OPERAND+"),\s*("+OPERAND+")\s*$") LOCALVAR = r"%eax|%edx|%ecx|%ebx|%esi|%edi|%ebp|\d*[(]%esp[)]" From arigo at codespeak.net Thu Aug 20 15:06:35 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 15:06:35 +0200 (CEST) Subject: [pypy-svn] r67028 - in pypy/branch/pyjitpl5/pypy/config: . test Message-ID: <20090820130635.92AAA168041@codespeak.net> Author: arigo Date: Thu Aug 20 15:06:35 2009 New Revision: 67028 Modified: pypy/branch/pyjitpl5/pypy/config/config.py pypy/branch/pyjitpl5/pypy/config/test/test_config.py Log: Synchronize the handling of BoolOption and ChoiceOption. Modified: pypy/branch/pyjitpl5/pypy/config/config.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/config.py (original) +++ pypy/branch/pyjitpl5/pypy/config/config.py Thu Aug 20 15:06:35 2009 @@ -259,7 +259,11 @@ for path, reqvalue in self._requires.get(value, []): toplevel = config._cfgimpl_get_toplevel() homeconfig, name = toplevel._cfgimpl_get_home_by_path(path) - homeconfig.setoption(name, reqvalue, who) + if who == 'default': + who2 = 'default' + else: + who2 = 'required' + homeconfig.setoption(name, reqvalue, who2) for path, reqvalue in self._suggests.get(value, []): toplevel = config._cfgimpl_get_toplevel() homeconfig, name = toplevel._cfgimpl_get_home_by_path(path) @@ -303,7 +307,11 @@ for path, reqvalue in self._requires: toplevel = config._cfgimpl_get_toplevel() homeconfig, name = toplevel._cfgimpl_get_home_by_path(path) - homeconfig.setoption(name, reqvalue, "required") + if who == 'default': + who2 = 'default' + else: + who2 = 'required' + homeconfig.setoption(name, reqvalue, who2) if value and self._suggests is not None: for path, reqvalue in self._suggests: toplevel = config._cfgimpl_get_toplevel() Modified: pypy/branch/pyjitpl5/pypy/config/test/test_config.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/test/test_config.py (original) +++ pypy/branch/pyjitpl5/pypy/config/test/test_config.py Thu Aug 20 15:06:35 2009 @@ -342,7 +342,19 @@ config.set(backend='cli') assert config.backend == 'cli' assert config.type_system == 'oo' - + +def test_overrides_require_as_default_boolopt(): + descr = OptionDescription("test", "", [ + BoolOption("backend", "", default=False, + requires=[('type_system', True)]), + BoolOption("type_system", "", default=False) + ]) + config = Config(descr, backend=True) + config.set(backend=False) + config.set(type_system=False) + assert config.backend == False + assert config.type_system == False + def test_overrides_dont_change_user_options(): descr = OptionDescription("test", "", [ BoolOption("b", "", default=False)]) @@ -502,6 +514,41 @@ assert not c.t3 assert not c.t2 +def test_suggests_can_fail_choiceopt(): + # this is what occurs in "./translate.py --gcrootfinder=asmgcc --jit" + # with --jit suggesting the boehm gc, but --gcrootfinder requiring the + # framework gctransformer. + descr = OptionDescription("test", '', [ + ChoiceOption("t1", "", ["a", "b"], default="a"), + ChoiceOption("t2", "", ["c", "d"], default="c", + requires={"d": [("t3", "f")]}), + ChoiceOption("t3", "", ["e", "f"], default="e"), + ChoiceOption("opt", "", ["g", "h"], default="g", + suggests={"h": [("t1", "b"), ("t2", "d")]}) + ]) + c = Config(descr) + assert c.t1 == 'a' + assert c.t2 == 'c' + assert c.t3 == 'e' + assert c.opt == 'g' + c.opt = "h" + assert c.opt == 'h' + assert c.t1 == 'b' + assert c.t2 == 'd' + assert c.t3 == 'f' + # does not crash + c.t2 = 'c' + assert c.t2 == 'c' + + c = Config(descr) + c.t3 = 'e' + assert c.t3 == 'e' + # does not crash + c.opt = 'h' + assert c.opt == 'h' + assert c.t3 == 'e' + assert c.t2 == 'c' + def test_choice_suggests(): descr = OptionDescription("test", '', [ From cfbolz at codespeak.net Thu Aug 20 15:14:50 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Aug 2009 15:14:50 +0200 (CEST) Subject: [pypy-svn] r67029 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090820131450.58724168047@codespeak.net> Author: cfbolz Date: Thu Aug 20 15:14:49 2009 New Revision: 67029 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for the next half hour Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Thu Aug 20 15:14:49 2009 @@ -90,13 +90,13 @@ look at tests - more or less full coverage for optimize*.py - - add tests for x86 backend DONE - - make test_ll_random.py a bit better than before + - add GC tests for x86 backend (Armin and Maciek around) + - make test_ll_random.py a bit better than before SORT-OF-DONE - set up test_ll_random to run nightly with x86 backend - - fix test_ll_random with llgraph backend - - fix x86 nightly failure (Maciek, Benjamin) - - fix the generator test on trunk (Maciek, Benjamin) - - look at the codewriter problems (Mikael, Carl Friedrich) + - fix test_ll_random with llgraph backend DONE + - fix x86 nightly failure DONE + - fix the generator test on trunk DONE + - look at the codewriter problems DONE - make x86 not recompile everything - think about code memory management @@ -104,11 +104,12 @@ - bit of inlining before bytecode production DONE - inlining on the Python level - storage sinking (removing consecutive getfields/setfields) - - build a pypy-c-jit from before the sprint for comparison + - build a pypy-c-jit from before the sprint for comparison IN-PROGRESS - - green virtualizable fields + - green virtualizable fields (Armin, Iko) - remove the numerous checks for frame.vable_rti in the - interpreter (non-JITting) part - - test the loops that pypy-c-jit produces + interpreter (non-JITting) part (Samuele, Carl Friedrich, Armin around) + - test the loops that pypy-c-jit produces IN-PROGRESS (Benjamin, Mikke, + Macie(k/j) around) - - what to do with the minimal backend? + - kill the minimal backend (Armin, Iko) From arigo at codespeak.net Thu Aug 20 15:18:43 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 15:18:43 +0200 (CEST) Subject: [pypy-svn] r67030 - in pypy/branch/pyjitpl5/pypy: config jit/backend jit/backend/minimal jit/backend/test Message-ID: <20090820131843.5341F168047@codespeak.net> Author: arigo Date: Thu Aug 20 15:18:41 2009 New Revision: 67030 Removed: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/ Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py pypy/branch/pyjitpl5/pypy/jit/backend/detect_cpu.py pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Log: (iko, arigo) Delete the minimal backend, which turned out to be useless. Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Thu Aug 20 15:18:41 2009 @@ -101,7 +101,7 @@ suggests=[("translation.gc", "boehm"), # for now ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "minimal", "x86", "llvm"], + ["auto", "x86", "llvm"], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_debug", "the amount of debugging dumps made by the JIT", ["off", "profile", "steps", "detailed"], Modified: pypy/branch/pyjitpl5/pypy/jit/backend/detect_cpu.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/detect_cpu.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/detect_cpu.py Thu Aug 20 15:18:41 2009 @@ -45,8 +45,6 @@ backend_name = autodetect() if backend_name in ('i386', 'x86'): from pypy.jit.backend.x86.runner import CPU - elif backend_name == 'minimal': - from pypy.jit.backend.minimal.runner import LLtypeCPU as CPU elif backend_name == 'cli': from pypy.jit.backend.cli.runner import CliCPU as CPU elif backend_name == 'llvm': Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/conftest.py Thu Aug 20 15:18:41 2009 @@ -10,7 +10,7 @@ help="choose a fixed random seed") group.addoption('--backend', action="store", default='llgraph', - choices=['llgraph', 'minimal', 'x86'], + choices=['llgraph', 'x86'], dest="backend", help="select the backend to run the functions with") group.addoption('--block-length', action="store", type="int", Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Thu Aug 20 15:18:41 2009 @@ -369,9 +369,6 @@ if demo_conftest.option.backend == 'llgraph': from pypy.jit.backend.llgraph.runner import LLtypeCPU return LLtypeCPU(None) - elif demo_conftest.option.backend == 'minimal': - from pypy.jit.backend.minimal.runner import LLtypeCPU - return LLtypeCPU(None, None) elif demo_conftest.option.backend == 'x86': from pypy.jit.backend.x86.runner import CPU386 return CPU386(None, None) From benjamin at codespeak.net Thu Aug 20 16:23:15 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 16:23:15 +0200 (CEST) Subject: [pypy-svn] r67031 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test Message-ID: <20090820142315.554C2168044@codespeak.net> Author: benjamin Date: Thu Aug 20 16:23:13 2009 New Revision: 67031 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Log: (micke, benjamin) write tests for and fix up the loop parser Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 16:23:13 2009 @@ -28,10 +28,11 @@ self.text = text class Operation(object): - def __init__(self, opname, args, result=None): + def __init__(self, opname, args, result=None, descr=None): self.opname = opname self.args = args self.result = result + self.descr = descr def __repr__(self): if self.result is None: @@ -39,24 +40,94 @@ return "%s = %s(%s)" % (self.result, self.opname, self.args) class GuardOperation(Operation): + + @property + def suboperations(self): + return self.subblock.operations + +class AbstractValue(object): + + def __init__(self, value): + self.value = int(value) + +class Box(AbstractValue): + pass + +class BoxInt(Box): + pass + +class BoxAddr(Box): pass +class BoxPtr(Box): + pass + +class Const(AbstractValue): + pass + +class ConstInt(Const): + pass + +class ConstAddr(Const): + pass + +class ConstPtr(Const): + pass + +box_map = { + 'b' : { + 'i' : BoxInt, + 'a' : BoxAddr, + 'p' : BoxPtr + }, + 'c' : { + 'i' : ConstInt, + 'a' : ConstAddr, + 'p' : ConstPtr + }, +} + + +_arg_finder = re.compile(r"(..)\((\d+),(\d+)\)") + class Parser(object): + current_indentation = 0 - + def parse(self, fname): self.current_block = Block() self.blockstack = [] + self.boxes = {} data = py.path.local(fname).read() lines = data.splitlines() i = 0 - res = self._parse(lines, i) - assert res == len(lines) + length = len(lines) + loops = [] + while i < length: + i = self._parse(lines, i) + loops.append(self.current_block) + self.boxes = {} + self.current_block = Block() assert not self.blockstack - return self.current_block + return loops - def parse_args(self, args): - return args + def _parse_boxes(self, box_string): + boxes = [] + for info, iden, value in _arg_finder.findall(box_string): + box = self.get_box(iden, info, value) + boxes.append(self.get_box(int(iden), info, value)) + return boxes + + def get_box(self, key, tp_info, value): + try: + node = self.boxes[key] + except KeyError: + box_type, tp = tp_info + klass = box_map[box_type][tp] + node = klass(value) + self.boxes[key] = node + assert node.__class__ is box_map[tp_info[0]][tp_info[1]] + return node def parse_result(self, result): return result @@ -67,7 +138,7 @@ def parse_block(self, lines, start, guard_op): self.blockstack.append(self.current_block) block = Block() - guard_op.suboperations = block + guard_op.subblock = block self.current_block = block res = self._parse(lines, start) self.current_block = self.blockstack.pop() @@ -87,9 +158,19 @@ if line.startswith('#'): self.current_block.add(Comment(line[1:])) return i + 1 - opname, args = line.split(" ") + descr = None + if " " in line: + # has arguments + opname, args_string = line.split(" ") + args = self._parse_boxes(args_string) + bracket = args_string.find("[") + if bracket != -1: + assert args_string[-1] == "]" + descr = eval(args_string[bracket:]) + else: + opname = line + args = [] _, opname = opname.split(":") - args = self.parse_args(args) if lines[i + 1].startswith(" " * (self.current_indentation + 2)): if lines[i + 1].strip().startswith('BEGIN'): self.current_indentation += 2 @@ -98,11 +179,11 @@ return self.parse_block(lines, i + 2, guard_op) marker, result = lines[i + 1].strip().split(" ") assert marker == '=>' - result = self.parse_result(result) - self.current_block.add(Operation(opname, args, result)) + result, = self._parse_boxes(result) + self.current_block.add(Operation(opname, args, result, descr)) return i + 2 else: - self.current_block.add(Operation(opname, args)) + self.current_block.add(Operation(opname, args, descr=descr)) return i + 1 def _parse(self, lines, i): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Thu Aug 20 16:23:13 2009 @@ -8,14 +8,61 @@ return parser.parse(py.magic.autopath().join('..', 'loopdata', name)) def test_simple_loop(self): - topblock = self.parse('simple.ops') + topblock, = self.parse('simple.ops') assert len(topblock.operations) == 7 assert isinstance(topblock.operations[0], Comment) + assert topblock.operations[0].text == \ + "(no jitdriver.get_printable_location!)" assert isinstance(topblock.operations[-2], Comment) assert isinstance(topblock.operations[4], GuardOperation) assert ([op.opname for op in topblock.operations if not isinstance(op, Comment)] == ['int_add', 'int_sub', 'int_gt', 'guard_true', 'jump']) - subops = topblock.operations[4].suboperations.operations + subops = topblock.operations[4].suboperations assert len(subops) == 1 assert subops[0].opname == 'fail' + fail = subops[0] + assert len(fail.args) == 3 + assert fail.descr == [] + add = topblock.operations[1] + assert len(add.args) == 2 + assert isinstance(add.args[0], BoxInt) + assert add.args[0].value == 18 + assert isinstance(add.args[1], BoxInt) + assert add.args[1].value == 6 + assert isinstance(add.result, BoxInt) + assert isinstance(topblock.operations[2].args[1], ConstInt) + assert topblock.operations[2].args[1].value == 1 + assert topblock.operations[2].result is topblock.operations[3].args[0] + + def test_two_paths(self): + loops = self.parse("two_paths.ops") + assert len(loops) == 4 + one = loops[0] + guard = one.operations[1] + assert not guard.args + call = loops[1].operations[3] + assert call.opname == "call" + assert len(call.args) == 4 + assert isinstance(call.args[0], ConstAddr) + assert call.args[0].value == 166630900 + for arg in call.args[1:]: + assert isinstance(arg, BoxInt) + assert call.descr == [3, 0, False] + last = loops[-1] + nested_guard = last.operations[2].suboperations[5] + assert isinstance(nested_guard, GuardOperation) + assert nested_guard.opname == "guard_true" + assert len(nested_guard.args) == 1 + assert isinstance(nested_guard.args[0], BoxInt) + + def test_string_loop(self): + loops = self.parse("string.ops") + assert len(loops) == 3 + newstr = loops[1].operations[1] + assert newstr.opname == "newstr" + assert isinstance(newstr.result, BoxPtr) + assert len(newstr.args) == 1 + assert isinstance(newstr.args[0], ConstInt) + assert newstr.result.value == 177102832 + assert newstr.result is loops[1].operations[2].args[0] From fijal at codespeak.net Thu Aug 20 16:24:04 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 16:24:04 +0200 (CEST) Subject: [pypy-svn] r67032 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090820142404.ED42A168044@codespeak.net> Author: fijal Date: Thu Aug 20 16:24:04 2009 New Revision: 67032 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Log: Add some possibility for guard_value(box, box) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py Thu Aug 20 16:24:04 2009 @@ -272,14 +272,18 @@ class GuardValueOperation(GuardOperation): def gen_guard(self, builder, r): v = r.choice(builder.intvars) - if r.random() < 0.75: - value = v.value - elif r.random() < 0.5: - value = v.value ^ 1 + if r.random() > 0.8: + other = r.choice(builder.intvars) else: - value = r.random_integer() - op = ResOperation(self.opnum, [v, ConstInt(value)], None) - return op, (v.value == value) + if r.random() < 0.75: + value = v.value + elif r.random() < 0.5: + value = v.value ^ 1 + else: + value = r.random_integer() + other = ConstInt(value) + op = ResOperation(self.opnum, [v, other], None) + return op, (v.value == other.value) # ____________________________________________________________ From fijal at codespeak.net Thu Aug 20 16:24:43 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 16:24:43 +0200 (CEST) Subject: [pypy-svn] r67033 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090820142443.2B8D8168044@codespeak.net> Author: fijal Date: Thu Aug 20 16:24:43 2009 New Revision: 67033 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: Cleanup a bit the code and increase coverage. Start writing direct tests for the gc integration Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Thu Aug 20 16:24:43 2009 @@ -66,18 +66,12 @@ self._compute_vars_longevity(tree.inputargs, tree.operations) self.free_regs = REGS[:] jump = tree.operations[-1] - #self.startmp = mp - #if guard_op: - # loop_consts, sd = self._start_from_guard_op(guard_op, mp, jump) - #else: loop_consts = self._compute_loop_consts(tree.inputargs, jump) self.loop_consts = loop_consts self.current_stack_depth = 0 else: - self._rewrite_const_ptrs(guard_op.suboperations) - guard_op.inputargs = None - self._compute_inpargs(guard_op) inp = guard_op.inputargs + assert inp is not None self.reg_bindings = {} self.stack_bindings = {} for arg in inp: @@ -94,11 +88,8 @@ jump_or_fail = guard_op.suboperations[-1] self.loop_consts = {} self.tree = regalloc.tree - if (jump_or_fail.opnum == rop.JUMP and - jump_or_fail.jump_target is regalloc.tree): - self.loop_consts = regalloc.loop_consts - def copy(self, guard_op): + def regalloc_for_guard(self, guard_op): return RegAlloc(self.assembler, None, self.translate_support_code, self, guard_op) @@ -206,11 +197,10 @@ self.eventually_free_vars(op.args) continue if self.can_optimize_cmp_op(op, i, operations): - nothing = oplist[op.opnum](self, op, operations[i + 1]) + oplist[op.opnum](self, op, operations[i + 1]) i += 1 else: - nothing = oplist[op.opnum](self, op, None) - assert nothing is None # temporary, remove me + oplist[op.opnum](self, op, None) self.eventually_free_var(op.result) self._check_invariants() i += 1 @@ -246,6 +236,8 @@ [ConstInt(addr)], box, single_gcref_descr)) op.args[i] = box + if op.is_guard(): + self._rewrite_const_ptrs(op.suboperations) newops.append(op) del operations[:] operations.extend(newops) @@ -503,9 +495,6 @@ self.assembler.make_merge_point(tree, locs) self.eventually_free_vars(inputargs) - def regalloc_for_guard(self, guard_op): - return self.copy(guard_op) - def _consider_guard(self, op, ignored): loc = self.make_sure_var_in_reg(op.args[0], []) regalloc = self.regalloc_for_guard(op) @@ -546,7 +535,7 @@ consider_guard_overflow = consider_guard_no_exception def consider_guard_value(self, op, ignored): - x = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False) + x = self.make_sure_var_in_reg(op.args[0], []) y = self.loc(op.args[1]) regalloc = self.regalloc_for_guard(op) self.perform_guard(op, regalloc, [x, y], None) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Thu Aug 20 16:24:43 2009 @@ -6,9 +6,9 @@ BoxPtr, ConstPtr, TreeLoop from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86.runner import CPU -from pypy.jit.backend.x86.regalloc import RegAlloc, REGS +from pypy.jit.backend.x86.regalloc import RegAlloc, REGS, WORD from pypy.jit.metainterp.test.oparser import parse -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import rclass @@ -303,6 +303,16 @@ ''' self.interpret(ops, [0, 0]) + def test_guard_value_two_boxes(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7] + guard_value(i6, i1) + fail(i0, i2, i3, i4, i5, i6) + fail(i0, i2, i3, i4, i5, i6) + ''' + self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0]) + assert self.getint(0) == 0 + class TestRegallocCompOps(BaseTestRegalloc): def test_cmp_op_0(self): @@ -315,3 +325,80 @@ ''' self.interpret(ops, [0, 1]) assert self.getint(0) == 0 + +class GcRootMap(object): + def initialize(self): + pass + +class MockGcDescr(object): + def get_funcptr_for_new(self): + return 123 + get_funcptr_for_newarray = get_funcptr_for_new + get_funcptr_for_newstr = get_funcptr_for_new + get_funcptr_for_newunicode = get_funcptr_for_new + + moving_gc = True + class GcRefList(object): + MAXLEN = 1000 + + def __init__(self): + TP = rffi.CArray(llmemory.GCREF) + self.l = lltype.malloc(TP, self.MAXLEN, flavor='raw') + self.size = 0 + + def get_address_of_gcref(self, addr): + baseaddr = rffi.cast(lltype.Signed, self.l) + for i in range(self.size): + if self.l[i] == addr: + return baseaddr + i * WORD + self.l[self.size] = addr + self.size += 1 + return baseaddr + (self.size - 1) * WORD + + gcrootmap = GcRootMap() + +class TestRegallocGc(BaseTestRegalloc): + cpu = CPU(None, None) + cpu.gc_ll_descr = MockGcDescr() + cpu.gcrefs = cpu.gc_ll_descr.GcRefList() + + S = lltype.GcForwardReference() + S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)))) + + fielddescr = cpu.fielddescrof(S, 'field') + + struct_ptr = lltype.malloc(S) + struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr) + child_ptr = lltype.nullptr(S) + struct_ptr.field = child_ptr + + namespace = locals().copy() + + def test_basic(self): + ops = ''' + [p0] + p1 = getfield_gc(p0, descr=fielddescr) + fail(p1) + ''' + self.interpret(ops, [self.struct_ptr]) + assert not self.getptr(0, lltype.Ptr(self.S)) + + def test_rewrite_constptr(self): + ops = ''' + [] + p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr) + fail(p1) + ''' + self.interpret(ops, []) + assert not self.getptr(0, lltype.Ptr(self.S)) + + def test_rewrite_constptr_in_brdige(self): + ops = ''' + [i0] + guard_true(i0) + p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr) + fail(p1) + fail(0) + ''' + self.interpret(ops, [0]) + assert not self.getptr(0, lltype.Ptr(self.S)) From benjamin at codespeak.net Thu Aug 20 16:25:19 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 16:25:19 +0200 (CEST) Subject: [pypy-svn] r67034 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820142519.F4036168045@codespeak.net> Author: benjamin Date: Thu Aug 20 16:25:19 2009 New Revision: 67034 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: remove old and broken parser Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 16:25:19 2009 @@ -197,183 +197,3 @@ except EndOfBlock: return i + 1 -def pairs(lst): - res = [] - for i in range(0, len(lst), 2): - res.append(lst[i] + ',' + lst[i + 1]) - return res - -class Loop(object): - def __init__(self, operations, guard_op): - self.operations = operations - self.guard_op = guard_op - -class Call(object): - def __init__(self, name, args): - self.name = name - self.args = args - -class GuardFailure(object): - def __init__(self, index, jmp_from, args): - self.index = index - self.jmp_from = jmp_from - self.args = args - -class OldParser(object): - def __init__(self): - self.boxes = {} - self.box_creations = [] - self.blocks = [] - self.unique_ptrs = {} - - def parse_name(self, name): - if name == 'bp': - return 'BoxPtr' - elif name == 'bi': - return 'BoxInt' - elif name == 'ci': - return 'ConstInt' - elif name == 'cp': - return 'ConstPtr' - elif name == 'ca': - return 'ConstAddr' - raise NotImplementedError - - def _get_unique_ptr(self, val): - try: - return self.unique_ptrs[val] - except KeyError: - self.unique_ptrs[val] = len(self.unique_ptrs) - return len(self.unique_ptrs) - 1 - - def get_ptr_val(self, val): - return 'lltype.cast_opaque_ptr(llmemory.GCREF, ptr_%d)' % self._get_unique_ptr(val) - - def get_adr_val(self, val): - return 'llmemory.cast_ptr_to_adr(ptr_%d)' % self._get_unique_ptr(val) - - def register_box(self, id, name, val): - try: - return self.boxes[id] - except KeyError: - result = name.lower() + '_' + str(id) - self.boxes[id] = result - if name.endswith('Ptr'): - val = self.get_ptr_val(val) - elif name == 'ConstAddr': - val = self.get_adr_val(val) - self.box_creations.append('%s = %s(%s)' % (result, name, val)) - return result - - def parse_args(self, args): - res = [] - for arg in args: - m = re.match('(\w\w)\((\d+),(\d+)\)', arg) - name = self.parse_name(m.group(1)) - id = int(m.group(2)) - val = int(m.group(3)) - unique_box = self.register_box(id, name, val) - res.append(unique_box) - return res - - def parse_loop(self, lines): - i = 0 - operations = [] - if lines[0].startswith('GO'): - guard_op = int(re.search('\((-?\d+)\)', lines[0]).group(1)) - i = 1 - else: - guard_op = None - while i < len(lines): - line = lines[i] - if line: - opname, args = line.split(' ') - if args: - parsed_args = self.parse_args(pairs(args.split(","))) - else: - parsed_args = [] - if i + 1 < len(lines) and lines[i + 1].startswith(' =>'): - i += 1 - box = lines[i][5:] - [res] = self.parse_args([box]) - else: - res = None - if i + 1 < len(lines) and lines[i + 1].startswith(' ..'): - i += 1 - liveboxes = lines[i][5:] - liveboxes = self.parse_args(pairs(liveboxes.split(","))) - else: - liveboxes = None - operations.append((opname, parsed_args, res, liveboxes)) - i += 1 - return Loop(operations, guard_op) - - def parse_call(self, line): - name, args = line.split(" ") - return Call(name, self.parse_args(pairs(args.split(",")))) - - def parse_guard_failure(self, line): - index, jmp_from, args = line.split(" ") - return GuardFailure(index, jmp_from, self.parse_args(pairs(args.split(",")))) - - def parse(self, fname): - data = py.path.local(fname).read() - lines = data.split("\n") - i = 0 - while i < len(lines): - if lines[i] == '<<<<<<<<<<': - # a loop - j = i - while lines[j] != '>>>>>>>>>>': - j += 1 - self.blocks.append(self.parse_loop(lines[i+1:j])) - i = j + 1 - elif lines[i] == 'CALL': - self.blocks.append(self.parse_call(lines[i+1])) - i += 2 - elif lines[i] == 'xxxxxxxxxx': - assert lines[i + 2] == 'xxxxxxxxxx' - self.blocks.append(self.parse_guard_failure(lines[i + 1])) - i += 3 - elif not lines[i]: - i += 1 - else: - xxxx - - def output(self): - for val, num in self.unique_ptrs.items(): - print " " * 4 + "ptr_%d = xxx(%d)" % (num, val) - for box in self.box_creations: - print " " * 4 + box - for block in self.blocks: - if isinstance(block, Loop): - if block.operations[-1][0] == '<119>': - continue - print " " * 4 + "ops = [" - d = {} - for i, (name, args, res, liveboxes) in enumerate(block.operations): - print " " * 8 + "ResOperation(rop.%s, [%s], %s)," % (name.upper(), ", ".join(args), res) - if liveboxes is not None: - d[i] = liveboxes - for k, v in d.items(): - print " " * 4 + "ops[%d].liveboxes = [%s]" % (k, ", ".join(v)) - print " " * 4 + "]" - print " " * 4 + "ops[-1].jump_target = ops[0]" - print " " * 4 + "cpu.compile_operations(ops)" - if isinstance(block, Call): - if block.name == 'call': - continue # ignore calls to single function - print " " * 4 + "cpu.execute_operations_in_new_frame('%s', [%s])" % (block.name, ", ".join(block.args)) - if isinstance(block, GuardFailure): - expected = "[" + ", ".join(["%s.value" % arg for arg in block.args]) + "]" - print " " * 4 + "expected = " + expected - print " " * 4 + "assert meta_interp.recordedvalues = expected" - -if __name__ == '__main__': - if len(sys.argv) != 2: - print __doc__ - sys.exit(1) - parser = Parser() - parser.parse(sys.argv[1]) - parser.output() - From benjamin at codespeak.net Thu Aug 20 16:29:32 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 16:29:32 +0200 (CEST) Subject: [pypy-svn] r67035 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820142932.0AC7D168045@codespeak.net> Author: benjamin Date: Thu Aug 20 16:29:32 2009 New Revision: 67035 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: (micke, benjamin) rewrite parse loop to cleaner Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 16:29:32 2009 @@ -187,13 +187,12 @@ return i + 1 def _parse(self, lines, i): - while True: - try: - indentation = count_indent(lines[i]) - if indentation == self.current_indentation: - i = self.parse_next_instruction(lines, i) - else: - xxx - except EndOfBlock: - return i + 1 + try: + while True: + i = self.parse_next_instruction(lines, i) + except EndOfBlock: + assert i < len(lines) + return i + 1 + else: + raise AssertionError("shouldn't happen (python bug????)") From arigo at codespeak.net Thu Aug 20 17:02:47 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 17:02:47 +0200 (CEST) Subject: [pypy-svn] r67036 - pypy/branch/pyjitpl5/pypy/module/pypyjit Message-ID: <20090820150247.1959B168042@codespeak.net> Author: arigo Date: Thu Aug 20 17:02:46 2009 New Revision: 67036 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Log: This removes all guards about PyCode except the first one, which is fine for now. Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Thu Aug 20 17:02:46 2009 @@ -20,7 +20,7 @@ from opcode import opmap from pypy.rlib.objectmodel import we_are_translated -PyFrame._virtualizable2_ = ['last_instr', +PyFrame._virtualizable2_ = ['last_instr', 'pycode', 'valuestackdepth', 'valuestack_w[*]', 'fastlocals_w[*]', ] From benjamin at codespeak.net Thu Aug 20 17:05:22 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 17:05:22 +0200 (CEST) Subject: [pypy-svn] r67037 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820150522.8757D168044@codespeak.net> Author: benjamin Date: Thu Aug 20 17:05:21 2009 New Revision: 67037 Added: pypy/branch/pyjitpl5/pypy/jit/backend/autopath.py - copied unchanged from r67031, pypy/branch/pyjitpl5/pypy/tool/autopath.py Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: (micke, benjamin) support displaying the parsed loop with graphpage Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 17:05:21 2009 @@ -3,6 +3,7 @@ new tests from crashes """ +import autopath import sys, py, re def count_indent(s): @@ -16,18 +17,45 @@ class EndOfBlock(Exception): pass -class Block(object): +class OpContainer(object): def __init__(self): self.operations = [] def add(self, element): self.operations.append(element) -class Comment(object): + def get_operations(self): + return self.operations + + def get_display_text(self): + return repr(self) + + +class Loop(OpContainer): + + def __repr__(self): + return "Loop" + +class Block(OpContainer): + + def __repr__(self): + return "Block" + +class BaseOperation(object): + + def is_guard(self): + return False + +class Comment(BaseOperation): def __init__(self, text): self.text = text + self.args = [] + self.result = None -class Operation(object): + def __repr__(self): + return "Comment: %r" % (self.text,) + +class Operation(BaseOperation): def __init__(self, opname, args, result=None, descr=None): self.opname = opname self.args = args @@ -45,13 +73,21 @@ def suboperations(self): return self.subblock.operations + def is_guard(self): + return True + class AbstractValue(object): - def __init__(self, value): + def __init__(self, iden, value): self.value = int(value) + self.iden = iden + + def __repr__(self): + klass = self.__class__.__name__ + return "%s(%s, %s)" % (klass, self.iden, self.value) class Box(AbstractValue): - pass + is_box = True class BoxInt(Box): pass @@ -95,7 +131,7 @@ current_indentation = 0 def parse(self, fname): - self.current_block = Block() + self.current_block = Loop() self.blockstack = [] self.boxes = {} data = py.path.local(fname).read() @@ -107,7 +143,7 @@ i = self._parse(lines, i) loops.append(self.current_block) self.boxes = {} - self.current_block = Block() + self.current_block = Loop() assert not self.blockstack return loops @@ -124,7 +160,7 @@ except KeyError: box_type, tp = tp_info klass = box_map[box_type][tp] - node = klass(value) + node = klass(key, value) self.boxes[key] = node assert node.__class__ is box_map[tp_info[0]][tp_info[1]] return node @@ -196,3 +232,10 @@ else: raise AssertionError("shouldn't happen (python bug????)") +if __name__ == "__main__": + from pypy.jit.metainterp.graphpage import display_loops + fn = sys.argv[1] + parser = Parser() + loops = parser.parse(fn) + display_loops(loops) + From benjamin at codespeak.net Thu Aug 20 17:13:24 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 17:13:24 +0200 (CEST) Subject: [pypy-svn] r67038 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820151324.25AE8168044@codespeak.net> Author: benjamin Date: Thu Aug 20 17:13:22 2009 New Revision: 67038 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: remove unused hack Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 17:13:22 2009 @@ -87,7 +87,7 @@ return "%s(%s, %s)" % (klass, self.iden, self.value) class Box(AbstractValue): - is_box = True + pass class BoxInt(Box): pass From pedronis at codespeak.net Thu Aug 20 17:14:21 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 17:14:21 +0200 (CEST) Subject: [pypy-svn] r67039 - in pypy/branch/pyjitpl5/pypy: annotation/test rlib rpython/test Message-ID: <20090820151421.0E99C168044@codespeak.net> Author: pedronis Date: Thu Aug 20 17:14:20 2009 New Revision: 67039 Modified: pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py pypy/branch/pyjitpl5/pypy/rlib/jit.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, pedronis) - reinstated the behavior of the access_directly hint - ported rtyping tests for it from the past Modified: pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/pyjitpl5/pypy/annotation/test/test_annrpython.py Thu Aug 20 17:14:20 2009 @@ -2746,11 +2746,10 @@ assert isinstance(s, annmodel.SomeInteger) def test_instance_with_flags(self): - py.test.skip("not supported any more") from pypy.rlib.jit import hint class A: - _virtualizable_ = True + _virtualizable2_ = [] class B(A): def meth(self): return self Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Thu Aug 20 17:14:20 2009 @@ -19,6 +19,18 @@ def compute_result_annotation(self, s_x, **kwds_s): from pypy.annotation import model as annmodel s_x = annmodel.not_const(s_x) + if 's_access_directly' in kwds_s: + if isinstance(s_x, annmodel.SomeInstance): + from pypy.objspace.flow.model import Constant + classdesc = s_x.classdef.classdesc + virtualizable = classdesc.read_attribute('_virtualizable2_', + Constant(None)).value + if virtualizable is not None: + flags = s_x.flags.copy() + flags['access_directly'] = True + s_x = annmodel.SomeInstance(s_x.classdef, + s_x.can_be_None, + flags) return s_x def specialize_call(self, hop, **kwds_i): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Thu Aug 20 17:14:20 2009 @@ -2,6 +2,8 @@ from pypy.rpython.lltypesystem import lltype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.rvirtualizable2 import replace_promote_virtualizable_with_call +from pypy.rlib.jit import hint +from pypy.objspace.flow.model import summary class V(object): @@ -16,6 +18,13 @@ def __init__(self, lst): self.lst = lst +class B(object): + _virtualizable2_ = ['v0'] + + x = "XX" + + def __init__(self, v0): + self.v0 = v0 class BaseTest(BaseRtypingTest): def test_generate_promote_virtualizable(self): @@ -121,9 +130,105 @@ assert op_promote.args[0].value == funcptr assert op_promote.args[1] == op_getfield.args[0] + def test_access_directly(self): + def g(b): + return b.v0 + + def f(n): + b = B(n) + b = hint(b, access_directly=True) + return g(b) + + t, typer, graph = self.gengraph(f, [int]) + g_graph = t._graphof(g) + assert summary(g_graph) == {self.GETFIELD: 1} + + res = self.interpret(f, [23]) + assert res == 23 + + def test_access_directly_specialized(self): + def g(b): + return b.v0 + + def f(n): + b = B(n) + x = g(b) + y = g(hint(b, access_directly=True)) + return x + y + + t, typer, graph = self.gengraph(f, [int]) + desc = typer.annotator.bookkeeper.getdesc(g) + g_graphs = desc._cache.items() + assert len(g_graphs) == 2 + g_graphs.sort() + assert g_graphs[0][0] is None + assert summary(g_graphs[0][1]) == {'promote_virtualizable': 1, self.GETFIELD: 1} + assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} + + res = self.interpret(f, [23]) + assert res == 46 + + def test_access_directly_escape(self): + class Global: + pass + glob = Global() + + def g(b): + glob.b = b + + def h(b): + return b.v0 + + def f(n): + b = B(n) + g(b) + g(hint(b, access_directly=True)) + return h(glob.b) + + t, typer, graph = self.gengraph(f, [int]) + desc = typer.annotator.bookkeeper.getdesc(g) + g_graphs = desc._cache.items() + assert len(g_graphs) == 2 + g_graphs.sort() + assert g_graphs[0][0] is None + assert summary(g_graphs[0][1]) == {self.SETFIELD: 1} + assert summary(g_graphs[1][1]) == {self.SETFIELD: 1} + + h_graph = t._graphof(h) + assert summary(h_graph) == {'promote_virtualizable': 1, self.GETFIELD: 1} + + res = self.interpret(f, [23]) + assert res == 23 + + def test_access_directly_method(self): + class A: + _virtualizable2_ = ['v0'] + + def __init__(self, v): + self.v0 = v + + def meth1(self, x): + return self.g(x+1) + + def g(self, y): + return self.v0 * y + + def f(n): + a = A(n) + a = hint(a, access_directly=True) + return a.meth1(100) + + t, typer, graph = self.gengraph(f, [int]) + g_graph = t._graphof(A.g.im_func) + assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} + + res = self.interpret(f, [23]) + assert res == 2323 class TestLLtype(LLRtypeMixin, BaseTest): prefix = 'inst_' + GETFIELD = 'getfield' + SETFIELD = 'setfield' def gettype(self, v): return v.concretetype.TO @@ -141,7 +246,16 @@ class TestOOtype(OORtypeMixin, BaseTest): prefix = 'o' - + GETFIELD = 'oogetfield' + SETFIELD = 'oosetfield' + def gettype(self, v): return v.concretetype + def test_access_directly(self): + py.test.skip("ootype doesn't pass around flags") + + test_access_directly_specialized = test_access_directly + + test_access_directly_method = test_access_directly + From benjamin at codespeak.net Thu Aug 20 17:18:58 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 17:18:58 +0200 (CEST) Subject: [pypy-svn] r67040 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test Message-ID: <20090820151858.B7BF016803D@codespeak.net> Author: benjamin Date: Thu Aug 20 17:18:56 2009 New Revision: 67040 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Log: support proper handle of loop inputargs Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 17:18:56 2009 @@ -168,9 +168,6 @@ def parse_result(self, result): return result - def parse_inputargs(self, inputargs): - return inputargs - def parse_block(self, lines, start, guard_op): self.blockstack.append(self.current_block) block = Block() @@ -187,7 +184,7 @@ raise EndOfBlock() if line.startswith('LOOP'): _, inputargs = line.split(" ") - self.current_block.inputargs = self.parse_inputargs(inputargs) + self.current_block.inputargs = self._parse_boxes(inputargs) return i + 1 if line.startswith('END'): raise EndOfBlock() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Thu Aug 20 17:18:56 2009 @@ -9,6 +9,9 @@ def test_simple_loop(self): topblock, = self.parse('simple.ops') + assert len(topblock.inputargs) == 3 + for arg in topblock.inputargs: + assert isinstance(arg, BoxInt) assert len(topblock.operations) == 7 assert isinstance(topblock.operations[0], Comment) assert topblock.operations[0].text == \ From pedronis at codespeak.net Thu Aug 20 17:24:16 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 17:24:16 +0200 (CEST) Subject: [pypy-svn] r67041 - in pypy/branch/pyjitpl5/pypy/rpython: . lltypesystem lltypesystem/test test Message-ID: <20090820152416.42298168043@codespeak.net> Author: pedronis Date: Thu Aug 20 17:24:15 2009 New Revision: 67041 Removed: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_rvirtualizable.py Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, pedronis) remove unused virtualizable mk 1 Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rclass.py Thu Aug 20 17:24:15 2009 @@ -55,17 +55,9 @@ unboxed = [subdef for subdef in classdef.getallsubdefs() if subdef.classdesc.pyobj is not None and issubclass(subdef.classdesc.pyobj, UnboxedValue)] - virtualizable = classdef.classdesc.read_attribute('_virtualizable_', - Constant(False)).value virtualizable2 = classdef.classdesc.read_attribute('_virtualizable2_', Constant(False)).value - if virtualizable: - assert rtyper.type_system.name == 'lltypesystem' - assert len(unboxed) == 0 - assert gcflavor == 'gc' - from pypy.rpython.lltypesystem import rvirtualizable - return rvirtualizable.VirtualizableInstanceRepr(rtyper, classdef) - elif virtualizable2: + if virtualizable2: assert len(unboxed) == 0 assert gcflavor == 'gc' return rtyper.type_system.rvirtualizable2.Virtualizable2InstanceRepr(rtyper, classdef) Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Thu Aug 20 17:24:15 2009 @@ -241,7 +241,6 @@ assert res.item1 == 42 res = lltype.normalizeptr(res.item0) assert res.inst_v == 42 - py.test.skip("later") assert not res.vable_rti class TestOOtype(OORtypeMixin, BaseTest): From benjamin at codespeak.net Thu Aug 20 18:02:08 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:02:08 +0200 (CEST) Subject: [pypy-svn] r67042 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820160208.B5FF2168048@codespeak.net> Author: benjamin Date: Thu Aug 20 18:02:07 2009 New Revision: 67042 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: support converting to oparse syntax Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:02:07 2009 @@ -86,6 +86,10 @@ klass = self.__class__.__name__ return "%s(%s, %s)" % (klass, self.iden, self.value) + @property + def pretty(self): + return "i%s" % (self.iden,) + class Box(AbstractValue): pass @@ -229,10 +233,40 @@ else: raise AssertionError("shouldn't happen (python bug????)") + +def _write_operations(ops, level): + def write(stuff): + print " " * level + stuff + for op in (op for op in ops if not isinstance(op, Comment)): + args = [arg.pretty for arg in op.args] + if op.descr: + args.append("descr=%r" % (op.descr,)) + args_string = ", ".join(args) + op_string = "%s(%s)" % (op.opname, args_string) + if op.is_guard(): + write(op_string) + _write_operations(op.suboperations, level + 4) + else: + if op.result is None: + write(op_string) + else: + write("%s = %s" % (op.result.pretty, op_string)) + + +def convert_to_oparse(loops): + if len(loops) > 1: + print >> sys.stderr, "there's more than one loop in that file!" + sys.exit(1) + loop, = loops + print "[%s]" % (", ".join(arg.pretty for arg in loop.inputargs),) + _write_operations(loop.operations, 0) + sys.exit(0) + + if __name__ == "__main__": from pypy.jit.metainterp.graphpage import display_loops fn = sys.argv[1] parser = Parser() loops = parser.parse(fn) - display_loops(loops) + convert_to_oparse(loops) From benjamin at codespeak.net Thu Aug 20 18:08:01 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:08:01 +0200 (CEST) Subject: [pypy-svn] r67043 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test test/loopdata Message-ID: <20090820160801.C010D16804D@codespeak.net> Author: benjamin Date: Thu Aug 20 18:08:01 2009 New Revision: 67043 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Log: support negative values correctly Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:08:01 2009 @@ -128,7 +128,7 @@ } -_arg_finder = re.compile(r"(..)\((\d+),(\d+)\)") +_arg_finder = re.compile(r"(..)\((\d+),(-?\d+)\)") class Parser(object): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Thu Aug 20 18:08:01 2009 @@ -4,7 +4,7 @@ => bi(3,24) 2:int_sub bi(1,4),ci(4,1) => bi(5,3) -3:int_gt bi(5,3),ci(6,0) +3:int_gt bi(5,3),ci(6,-42) => bi(7,1) 4:guard_true bi(7,1) BEGIN(0) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Thu Aug 20 18:08:01 2009 @@ -37,6 +37,7 @@ assert isinstance(topblock.operations[2].args[1], ConstInt) assert topblock.operations[2].args[1].value == 1 assert topblock.operations[2].result is topblock.operations[3].args[0] + assert topblock.operations[3].args[1].value == -42 def test_two_paths(self): loops = self.parse("two_paths.ops") From arigo at codespeak.net Thu Aug 20 18:11:50 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Aug 2009 18:11:50 +0200 (CEST) Subject: [pypy-svn] r67044 - pypy/branch/pyjitpl5/pypy/jit/tl Message-ID: <20090820161150.B277C168053@codespeak.net> Author: arigo Date: Thu Aug 20 18:11:50 2009 New Revision: 67044 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: (fijal, arigo) Fix options. Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Thu Aug 20 18:11:50 2009 @@ -38,12 +38,12 @@ config.objspace.usemodules.pypyjit = True config.objspace.usemodules._weakref = False config.objspace.usemodules._sre = False -config.translation.rweakref = False # XXX set_pypy_opt_level(config, level='0') config.objspace.std.builtinshortcut = True config.objspace.opcodes.CALL_LIKELY_BUILTIN = True config.objspace.std.withrangelist = True config.objspace.std.withsharingdict = True +config.objspace.std.withmethodcache = True if BACKEND == 'c': config.objspace.std.multimethods = 'mrd' From benjamin at codespeak.net Thu Aug 20 18:13:19 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:13:19 +0200 (CEST) Subject: [pypy-svn] r67045 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820161319.4D615168057@codespeak.net> Author: benjamin Date: Thu Aug 20 18:13:18 2009 New Revision: 67045 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: output constants correctly Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:13:18 2009 @@ -103,10 +103,16 @@ pass class Const(AbstractValue): - pass + + @property + def pretty(self): + return "%s(REPLACE!!!)" % (self.__class__.__name__,) class ConstInt(Const): - pass + + @property + def pretty(self): + return str(self.value) class ConstAddr(Const): pass From benjamin at codespeak.net Thu Aug 20 18:20:04 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:20:04 +0200 (CEST) Subject: [pypy-svn] r67046 - pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata Message-ID: <20090820162004.71EF916805C@codespeak.net> Author: benjamin Date: Thu Aug 20 18:20:01 2009 New Revision: 67046 Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/two_paths.ops Log: add missing test support files Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops Thu Aug 20 18:20:01 2009 @@ -0,0 +1,54 @@ +LOOP bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3) +0:call bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3)[5,0,False] + => bi(6,0) +1:guard_no_exception + BEGIN(0) + 0:fail + END +2:fail bi(6,0) +LOOP END +LOOP bp(0,177266788),bi(1,97) +#(no jitdriver.get_printable_location!) +1:newstr ci(2,1) + => bp(3,177102832) +2:strsetitem bp(3,177102832),ci(4,0),bi(1,97) +3:strlen bp(0,177266788) + => bi(5,3) +4:strlen bp(3,177102832) + => bi(6,1) +5:int_add bi(5,3),bi(6,1) + => bi(7,4) +6:int_ge bi(7,4),ci(4,0) + => bi(8,1) +7:newstr bi(7,4) + => bp(9,177102816) +8:call ca(10,175948220),bp(0,177266788),bp(9,177102816),ci(4,0),ci(4,0),bi(5,3)[5,0,False] +9:guard_no_exception + BEGIN(0) + 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + END +10:call ca(10,175948220),bp(3,177102832),bp(9,177102816),ci(4,0),bi(5,3),bi(6,1)[5,0,False] +11:guard_no_exception + BEGIN(0) + 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + END +12:int_sub bi(1,97),ci(2,1) + => bi(11,96) +13:int_gt bi(11,96),ci(12,13) + => bi(13,1) +14:guard_true bi(13,1) + BEGIN(0) + 0:fail bi(11,96),bp(9,177102816)[] + END +#(no jitdriver.get_printable_location!) +16:jump bp(9,177102816),bi(11,96) +LOOP END +LOOP bi(0,-1207988312),bp(1,177134016) +0:call bi(0,-1207988312),bp(1,177134016)[1,4,False] + => bi(2,0) +1:guard_no_exception + BEGIN(0) + 0:fail + END +2:fail bi(2,0) +LOOP END Added: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/two_paths.ops ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/two_paths.ops Thu Aug 20 18:20:01 2009 @@ -0,0 +1,91 @@ +LOOP bi(0,-1208475688),bi(1,30),bi(2,6),bi(3,18) +0:call bi(0,-1208475688),bi(1,30),bi(2,6),bi(3,18)[3,0,False] + => bi(4,0) +1:guard_no_exception + BEGIN(0) + 0:fail + END +2:fail bi(4,0) +LOOP END +LOOP bi(0,6),bi(1,30),bi(2,18) +#(no jitdriver.get_printable_location!) +1:int_le bi(1,30),ci(3,12) + => bi(4,0) +2:guard_false bi(4,0) + BEGIN(0) + 0:fail bi(0,6),bi(1,30),bi(2,18)[] + END +3:call ca(5,166630900),bi(1,30),bi(0,6),bi(2,18)[3,0,False] +4:int_add bi(2,18),bi(0,6) + => bi(6,24) +5:int_sub bi(1,30),ci(7,1) + => bi(8,29) +6:int_gt bi(8,29),ci(9,0) + => bi(10,1) +7:guard_true bi(10,1) + BEGIN(0) + 0:fail bi(0,6),bi(8,29),bi(6,24)[] + END +#(no jitdriver.get_printable_location!) +9:jump bi(0,6),bi(8,29),bi(6,24) +LOOP END +LOOP bi(0,6),bi(1,10),bi(2,134) +#(no jitdriver.get_printable_location!) +1:int_le bi(1,10),ci(3,12) + => bi(4,1) +2:guard_true bi(4,1) + BEGIN(0) + 0:fail bi(0,6),bi(1,10),bi(2,134)[] + END +3:int_sub bi(0,6),ci(5,2) + => bi(6,4) +4:call ca(7,166630900),bi(1,10),bi(0,6),bi(2,134)[3,0,False] +5:int_add bi(2,134),bi(6,4) + => bi(8,138) +6:int_sub bi(1,10),ci(9,1) + => bi(10,9) +7:int_gt bi(10,9),ci(11,0) + => bi(12,1) +8:guard_true bi(12,1) + BEGIN(0) + 0:fail bi(0,6),bi(10,9),bi(8,138)[] + END +#(no jitdriver.get_printable_location!) +10:jump bi(0,6),bi(10,9),bi(8,138) +LOOP END +LOOP bi(0,6),bi(1,9),bi(2,138) +#(no jitdriver.get_printable_location!) +1:int_le bi(1,9),ci(3,12) + => bi(4,0) +2:guard_false bi(4,0) + BEGIN(0) + 0:int_sub bi(0,6),ci(5,2) + => bi(6,4) + 1:call ca(7,166630900),bi(1,9),bi(0,6),bi(2,138)[3,0,False] + 2:int_add bi(2,138),bi(6,4) + => bi(8,142) + 3:int_sub bi(1,9),ci(9,1) + => bi(10,8) + 4:int_gt bi(10,8),ci(11,0) + => bi(12,1) + 5:guard_true bi(12,1) + BEGIN(0) + 0:fail bi(0,6),bi(10,8),bi(8,142)[] + END + #(no jitdriver.get_printable_location!) + 7:jump bi(0,6),bi(10,8),bi(8,142) + END +3:call ca(7,166630900),bi(1,9),bi(0,6),bi(2,138)[3,0,False] +4:int_add bi(2,138),bi(0,6) + => bi(13,24) +5:int_sub bi(1,9),ci(9,1) + => bi(14,29) +6:int_gt bi(14,29),ci(11,0) + => bi(15,1) +7:guard_true bi(15,1) + BEGIN(0) + 0:fail bi(0,6),bi(14,29),bi(13,24)[] + END +#(no jitdriver.get_printable_location!) +9:jump bi(0,6),bi(14,29),bi(13,24) +LOOP END From pedronis at codespeak.net Thu Aug 20 18:25:10 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 20 Aug 2009 18:25:10 +0200 (CEST) Subject: [pypy-svn] r67047 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090820162510.019B816805D@codespeak.net> Author: pedronis Date: Thu Aug 20 18:25:10 2009 New Revision: 67047 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: (cfbolz, pedronis) add test about access_direct for virtualizables in the jit Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Thu Aug 20 18:25:10 2009 @@ -7,7 +7,7 @@ from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR from pypy.rpython.rclass import FieldListAccessor -from pypy.jit.metainterp.warmspot import get_stats +from pypy.jit.metainterp.warmspot import get_stats, get_translator from pypy.jit.metainterp import history, heaptracker from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin @@ -704,6 +704,60 @@ self.check_loops(int_add=0, int_sub=1) # for 'n -= 1' only + def test_simple_access_directly(self): + myjitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + + def __init__(self, x, y): + self = hint(self, access_directly=True) + self.x = x + self.y = y + + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def f(n): + frame = Frame(n, 0) + somewhere_else.top_frame = frame # escapes + frame = hint(frame, access_directly=True) + while frame.x > 0: + myjitdriver.can_enter_jit(frame=frame) + myjitdriver.jit_merge_point(frame=frame) + frame.y += frame.x + frame.x -= 1 + return somewhere_else.top_frame.y + + res = self.meta_interp(f, [10]) + assert res == 55 + self.check_loops(getfield_gc=0, setfield_gc=0) + + t = get_translator() + f_graph = t.graphs[0] + assert f_graph.func is f + portal_graph = t.graphs[-1] + assert portal_graph.func is f + init_graph = t._graphof(Frame.__init__.im_func) + + deref = t.rtyper.type_system_deref + + def direct_calls(graph): + return [deref(op.args[0].value)._callable.func_name + for block, op in graph.iterblockops() + if op.opname == 'direct_call'] + + if isinstance(self, OOJitMixin): + py.test.skip("oo virtualizable support incomplete") + + assert direct_calls(f_graph) == ['__init__', 'force_if_necessary', 'll_portal_runner'] + assert direct_calls(portal_graph) == ['force_if_necessary', 'maybe_enter_jit'] + + assert direct_calls(init_graph) == [] + + class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 20 18:25:10 2009 @@ -109,6 +109,9 @@ def get_stats(): return pyjitpl._warmrunnerdesc.stats +def get_translator(): + return pyjitpl._warmrunnerdesc.translator + def debug_checks(): stats = get_stats() stats.maybe_view() From benjamin at codespeak.net Thu Aug 20 18:26:15 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:26:15 +0200 (CEST) Subject: [pypy-svn] r67048 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820162615.A4CB3168060@codespeak.net> Author: benjamin Date: Thu Aug 20 18:26:14 2009 New Revision: 67048 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: support showing and converting loops on the cmdline Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:26:14 2009 @@ -266,13 +266,23 @@ loop, = loops print "[%s]" % (", ".join(arg.pretty for arg in loop.inputargs),) _write_operations(loop.operations, 0) - sys.exit(0) if __name__ == "__main__": from pypy.jit.metainterp.graphpage import display_loops - fn = sys.argv[1] + if len(sys.argv) != 3: + print >> sys.stderr, "usage: (convert | show) file" + sys.exit(2) + operation = sys.argv[1] + fn = sys.argv[2] parser = Parser() loops = parser.parse(fn) - convert_to_oparse(loops) + if operation == "convert": + convert_to_oparse(loops) + elif operation == "show": + display_loops(loops) + else: + print >> sys.stderr, "invalid operation" + sys.exit(2) + sys.exit(0) From benjamin at codespeak.net Thu Aug 20 18:50:12 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 20 Aug 2009 18:50:12 +0200 (CEST) Subject: [pypy-svn] r67049 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090820165012.B78AF168057@codespeak.net> Author: benjamin Date: Thu Aug 20 18:50:11 2009 New Revision: 67049 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: use 'p' prefix for pointer vars Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:50:11 2009 @@ -88,19 +88,19 @@ @property def pretty(self): - return "i%s" % (self.iden,) + return "%s%s" % (self._var_prefix, self.iden) class Box(AbstractValue): pass class BoxInt(Box): - pass + _var_prefix = "i" class BoxAddr(Box): pass class BoxPtr(Box): - pass + _var_prefix = "p" class Const(AbstractValue): From micke at codespeak.net Thu Aug 20 18:54:39 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Thu, 20 Aug 2009 18:54:39 +0200 (CEST) Subject: [pypy-svn] r67050 - in pypy/branch/pyjitpl5/pypy/jit: backend metainterp Message-ID: <20090820165439.5C5E6168057@codespeak.net> Author: micke Date: Thu Aug 20 18:54:38 2009 New Revision: 67050 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Log: Enable links in the graphviz view that the loopparser can spawn. The text representation of the values had to slightly chang as the current graphparser refuses to make links of any text that is not solely alphanumeric. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Thu Aug 20 18:54:38 2009 @@ -28,7 +28,7 @@ return self.operations def get_display_text(self): - return repr(self) + return str(self) class Loop(OpContainer): @@ -63,9 +63,10 @@ self.descr = descr def __repr__(self): + str_args = [str(arg) for arg in self.args] if self.result is None: - return "%s(%s)" % (self.opname, self.args) - return "%s = %s(%s)" % (self.result, self.opname, self.args) + return "%s(%s)" % (self.opname, str_args) + return "%s = %s(%s)" % (self.result, self.opname, str_args) class GuardOperation(Operation): @@ -78,13 +79,19 @@ class AbstractValue(object): + is_box = True + def __init__(self, iden, value): self.value = int(value) self.iden = iden def __repr__(self): klass = self.__class__.__name__ - return "%s(%s, %s)" % (klass, self.iden, self.value) + return "%s%s(%s)" % (klass, self.iden, self.value) + + def __str__(self): + klass = self.__class__.__name__ + return '%s%s' % (klass, self.iden) @property def pretty(self): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py Thu Aug 20 18:54:38 2009 @@ -169,7 +169,7 @@ boxes = {} for op in self.all_operations: for box in op.args + [op.result]: - if isinstance(box, Box): + if getattr(box, 'is_box', False): boxes[box] = True links = {} for box in boxes: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Thu Aug 20 18:54:38 2009 @@ -377,6 +377,7 @@ __slots__ = () _extended_display = True _counter = 0 + is_box = True # hint that we want to make links in graphviz from this @staticmethod def _new(x, cpu): From fijal at codespeak.net Thu Aug 20 19:20:37 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 20 Aug 2009 19:20:37 +0200 (CEST) Subject: [pypy-svn] r67051 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090820172037.88065168059@codespeak.net> Author: fijal Date: Thu Aug 20 19:20:35 2009 New Revision: 67051 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: Add a passing test and make assumptions a bit harder Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Thu Aug 20 19:20:35 2009 @@ -107,7 +107,6 @@ if not we_are_translated(): # make sure no duplicates assert len(dict.fromkeys(self.reg_bindings.values())) == len(self.reg_bindings) - # this is not true, due to jump args assert (len(dict.fromkeys([str(i) for i in self.stack_bindings.values()] )) == len(self.stack_bindings)) rev_regs = dict.fromkeys(self.reg_bindings.values()) @@ -116,6 +115,8 @@ assert len(rev_regs) + len(self.free_regs) == len(REGS) else: assert len(self.reg_bindings) + len(self.free_regs) == len(REGS) + for v in self.reg_bindings: + assert self.longevity[v][1] > self.position def Load(self, v, from_loc, to_loc): if not we_are_translated(): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Thu Aug 20 19:20:35 2009 @@ -60,7 +60,7 @@ jump_targets=jump_targets, boxkinds=boxkinds) - def interpret(self, ops, args, jump_targets=None): + def interpret(self, ops, args, jump_targets=None, run=True): loop = self.parse(ops, jump_targets=jump_targets) self.cpu.compile_operations(loop) for i, arg in enumerate(args): @@ -70,7 +70,8 @@ assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) self.cpu.set_future_value_ptr(i, llgcref) - self.cpu.execute_operations(loop) + if run: + self.cpu.execute_operations(loop) return loop def getint(self, index): @@ -363,7 +364,8 @@ cpu.gcrefs = cpu.gc_ll_descr.GcRefList() S = lltype.GcForwardReference() - S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)))) + S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), + ('int', lltype.Signed))) fielddescr = cpu.fielddescrof(S, 'field') @@ -372,6 +374,10 @@ child_ptr = lltype.nullptr(S) struct_ptr.field = child_ptr + + descr0 = cpu.fielddescrof(S, 'int') + ptr0 = struct_ref + namespace = locals().copy() def test_basic(self): @@ -402,3 +408,48 @@ ''' self.interpret(ops, [0]) assert not self.getptr(0, lltype.Ptr(self.S)) + + def test_bug_0(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7, i8] + guard_value(i2, 1) + fail(i2, i3, i4, i5, i6, i7, i0, i1, i8) + guard_class(i4, 138998336) + fail(i4, i5, i6, i7, i0, i1, i8) + i11 = getfield_gc(i4, descr=descr0) + i12 = ooisnull(i11) + guard_false(i12) + fail(i4, i5, i6, i7, i0, i1, i11, i8) + i13 = getfield_gc(i11, descr=descr0) + i14 = ooisnull(i13) + guard_true(i14) + fail(i4, i5, i6, i7, i0, i1, i11, i8) + i15 = getfield_gc(i4, descr=descr0) + i17 = int_lt(i15, 0) + guard_false(i17) + fail(i4, i5, i6, i7, i0, i1, i11, i15, i8) + i18 = getfield_gc(i11, descr=descr0) + i19 = int_ge(i15, i18) + guard_false(i19) + fail(i4, i5, i6, i7, i0, i1, i11, i15, i8) + i20 = int_lt(i15, 0) + guard_false(i20) + fail(i4, i5, i6, i7, i0, i1, i11, i15, i8) + i21 = getfield_gc(i11, descr=descr0) + i22 = getfield_gc(i11, descr=descr0) + i23 = int_mul(i15, i22) + i24 = int_add(i21, i23) + i25 = getfield_gc(i4, descr=descr0) + i27 = int_add(i25, 1) + setfield_gc(i4, i27, descr=descr0) + i29 = getfield_raw(144839744, descr=descr0) + i31 = int_and(i29, -2141192192) + i32 = int_is_true(i31) + guard_false(i32) + fail(i4, i6, i7, i0, i1, i24) + i33 = getfield_gc(i0, descr=descr0) + guard_value(i33, ConstPtr(ptr0)) + fail(i4, i6, i7, i0, i1, i33, i24) + jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24) + ''' + self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False) From cfbolz at codespeak.net Fri Aug 21 12:06:53 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 21 Aug 2009 12:06:53 +0200 (CEST) Subject: [pypy-svn] r67052 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090821100653.BF182168048@codespeak.net> Author: cfbolz Date: Fri Aug 21 12:06:52 2009 New Revision: 67052 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all) planning for today Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Fri Aug 21 12:06:52 2009 @@ -5,20 +5,20 @@ - Carl Friedrich - Benjamin - Mikael - -later: - Anto - Armin - Iko - Bea +later: + discussions to be had: - - what goals/benchmarks do we want for the prototype DONE + - what benchmarks do we want for the prototype DONE - things we know are missing DONE - state of the tests DONE - - what to do with ootype - - how will Eurostars work, how will work be organized + - how will Eurostars work, how will work be organized (today at 16.00) + - what to do with ootype (Anto, Maciek, Armin, Samuele; on Sunday) Goals/Benchmarks @@ -90,26 +90,26 @@ look at tests - more or less full coverage for optimize*.py - - add GC tests for x86 backend (Armin and Maciek around) + - add GC tests for x86 backend DONE + - find bug in x86 backend related to GC (Maciek, Armin around) - make test_ll_random.py a bit better than before SORT-OF-DONE - set up test_ll_random to run nightly with x86 backend - - fix test_ll_random with llgraph backend DONE - - fix x86 nightly failure DONE - - fix the generator test on trunk DONE - - look at the codewriter problems DONE - make x86 not recompile everything - think about code memory management - - don't trace into action flag stuff DONE - - bit of inlining before bytecode production DONE - inlining on the Python level - - storage sinking (removing consecutive getfields/setfields) + - store sinking (removing consecutive getfields/setfields) STARTED (Armin, Iko) - build a pypy-c-jit from before the sprint for comparison IN-PROGRESS - - green virtualizable fields (Armin, Iko) + - green virtualizable fields ABANDONED - remove the numerous checks for frame.vable_rti in the - interpreter (non-JITting) part (Samuele, Carl Friedrich, Armin around) - - test the loops that pypy-c-jit produces IN-PROGRESS (Benjamin, Mikke, - Macie(k/j) around) - - - kill the minimal backend (Armin, Iko) + interpreter (non-JITting) part IN-PROGRESS (Carl Friedrich, Samuele) + - parser for the ops files that pypy-c-jit produces DONE + - test the loops that pypy-c-jit produces (Mikke, Benjamin) + + - kill the minimal backend DONE + - getting confused IN-PROGRESS + - fix the CLI backend (Anto) + - fix config tests (Armin, Carl Friedrich around) + - merge the compiler branch + - general wizardry (Maciek, Bea) From arigo at codespeak.net Fri Aug 21 12:16:20 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 12:16:20 +0200 (CEST) Subject: [pypy-svn] r67053 - pypy/branch/pyjitpl5/pypy/translator Message-ID: <20090821101620.332DC16804A@codespeak.net> Author: arigo Date: Fri Aug 21 12:16:19 2009 New Revision: 67053 Modified: pypy/branch/pyjitpl5/pypy/translator/interactive.py Log: Workaround, e.g. for pypy.translator.sandbox.test.test_sandbox: set the gc before setting any other options. Obscure. Modified: pypy/branch/pyjitpl5/pypy/translator/interactive.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/interactive.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/interactive.py Fri Aug 21 12:16:19 2009 @@ -73,6 +73,8 @@ kwds.get('standalone')) kwds.pop('policy', None) kwds.pop('standalone', None) + gc = kwds.pop('gc', None) + if gc: self.config.translation.gc = gc self.config.translation.set(**kwds) def ensure_opt(self, name, value=None, fallback=None): From pedronis at codespeak.net Fri Aug 21 12:25:08 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 21 Aug 2009 12:25:08 +0200 (CEST) Subject: [pypy-svn] r67054 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem Message-ID: <20090821102508.33BD416804A@codespeak.net> Author: pedronis Date: Fri Aug 21 12:25:07 2009 New Revision: 67054 Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py Log: (cfbolz, pedronis) fix imports Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/rvirtualizable2.py Fri Aug 21 12:25:07 2009 @@ -1,9 +1,9 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rpython.lltypesystem.rvirtualizable import VABLERTIPTR -from pypy.rpython.lltypesystem.rclass import InstanceRepr +from pypy.rpython.lltypesystem.rclass import InstanceRepr, OBJECTPTR from pypy.rpython.rvirtualizable2 import AbstractVirtualizable2InstanceRepr +VABLERTIPTR = OBJECTPTR class Virtualizable2InstanceRepr(AbstractVirtualizable2InstanceRepr, InstanceRepr): From arigo at codespeak.net Fri Aug 21 12:45:54 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 12:45:54 +0200 (CEST) Subject: [pypy-svn] r67055 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090821104554.34D7A16804A@codespeak.net> Author: arigo Date: Fri Aug 21 12:45:53 2009 New Revision: 67055 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, arigo) Optimize duplicate GETFIELD_GCs, first step. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Fri Aug 21 12:45:53 2009 @@ -39,6 +39,7 @@ class OptValue(object): _attrs_ = ('box', 'level') level = LEVEL_UNKNOWN + _fields = None def __init__(self, box): self.box = box @@ -165,6 +166,7 @@ op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) newoperations.append(op) + self._fields = None return self.box def prepare_force_box(self): @@ -342,6 +344,8 @@ self.cpu = cpu self.loop = loop self.values = {} + self.values_to_clean = [] # OptValues to clean when we see an + # operation with side-effects self.reached_the_end = False def getvalue(self, box): @@ -510,6 +514,10 @@ # all constant arguments: constant-fold away self.make_constant(op.result) return + elif not op.has_no_side_effect(): + for value in self.values_to_clean: + value._fields = None + del self.values_to_clean[:] # otherwise, the operation remains self.emit_operation(op) @@ -614,8 +622,18 @@ assert fieldvalue is not None self.make_equal_to(op.result, fieldvalue) else: + # check if the field was read from another getfield_gc just before + if value._fields is None: + value._fields = av_newdict2() + elif op.descr in value._fields: + self.make_equal_to(op.result, value._fields[op.descr]) + return + # default case: produce the operation value.make_nonnull() self.optimize_default(op) + # then remember the result of reading the field + value._fields[op.descr] = self.getvalue(op.result) + self.values_to_clean.append(value) # note: the following line does not mean that the two operations are # completely equivalent, because GETFIELD_GC_PURE is_always_pure(). Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Fri Aug 21 12:45:53 2009 @@ -949,6 +949,86 @@ self.optimize_loop(ops, 'Not, VStruct(ssize, adescr=Not), Not', expected) + def test_duplicate_getfield_1(self): + ops = """ + [p1] + i1 = getfield_gc(p1, descr=valuedescr) + i2 = getfield_gc(p1, descr=valuedescr) + escape(i1) + escape(i2) + jump(p1) + """ + expected = """ + [p1] + i1 = getfield_gc(p1, descr=valuedescr) + escape(i1) + escape(i1) + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + + def test_duplicate_getfield_2(self): + py.test.skip("in-progress") + ops = """ + [p1, i1] + setfield_gc(p1, i1, descr=valuedescr) + i2 = getfield_gc(p1, descr=valuedescr) + escape(i2) + jump(p1, i1) + """ + expected = """ + [p1] + setfield_gc(p1, i1, descr=valuedescr) + escape(i1) + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + + def test_duplicate_getfield_3(self): + py.test.skip("in-progress") + ops = """ + [p1] + i1 = getfield_gc(p1, descr=valuedescr) + debug_merge_point(15) + i2 = getfield_gc(p1, descr=valuedescr) + escape(i1) + escape(i2) + jump(p1) + """ + expected = """ + [p1] + i1 = getfield_gc(p1, descr=valuedescr) + debug_merge_point(15) + escape(i1) + escape(i1) + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + + def test_duplicate_getfield_sideeffects_1(self): + ops = """ + [p1] + i1 = getfield_gc(p1, descr=valuedescr) + escape() + i2 = getfield_gc(p1, descr=valuedescr) + escape(i1) + escape(i2) + jump(p1) + """ + self.optimize_loop(ops, 'Not', ops) + + def test_duplicate_getfield_sideeffects_2(self): + py.test.skip("in-progress") + ops = """ + [p1, i1] + setfield_gc(p1, i1, descr=valuedescr) + escape() + i2 = getfield_gc(p1, descr=valuedescr) + escape(i2) + jump(p1, i1) + """ + self.optimize_loop(ops, 'Not', ops) + # ---------- def make_fail_descr(self): From arigo at codespeak.net Fri Aug 21 12:50:22 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 12:50:22 +0200 (CEST) Subject: [pypy-svn] r67056 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090821105022.705F716804A@codespeak.net> Author: arigo Date: Fri Aug 21 12:50:21 2009 New Revision: 67056 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, arigo) Optimize SETFIELD_GC/GETFIELD_GC pairs. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Fri Aug 21 12:50:21 2009 @@ -646,6 +646,11 @@ else: value.make_nonnull() self.optimize_default(op) + # remember the result of future reads of the field + if value._fields is None: + value._fields = av_newdict2() + value._fields[op.descr] = self.getvalue(op.args[1]) + self.values_to_clean.append(value) def optimize_NEW_WITH_VTABLE(self, op): self.make_virtual(op.args[0], op.result, op) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Fri Aug 21 12:50:21 2009 @@ -968,7 +968,6 @@ self.optimize_loop(ops, 'Not', expected) def test_duplicate_getfield_2(self): - py.test.skip("in-progress") ops = """ [p1, i1] setfield_gc(p1, i1, descr=valuedescr) @@ -977,12 +976,12 @@ jump(p1, i1) """ expected = """ - [p1] + [p1, i1] setfield_gc(p1, i1, descr=valuedescr) escape(i1) - jump(p1) + jump(p1, i1) """ - self.optimize_loop(ops, 'Not', expected) + self.optimize_loop(ops, 'Not, Not', expected) def test_duplicate_getfield_3(self): py.test.skip("in-progress") @@ -1018,7 +1017,6 @@ self.optimize_loop(ops, 'Not', ops) def test_duplicate_getfield_sideeffects_2(self): - py.test.skip("in-progress") ops = """ [p1, i1] setfield_gc(p1, i1, descr=valuedescr) @@ -1027,7 +1025,7 @@ escape(i2) jump(p1, i1) """ - self.optimize_loop(ops, 'Not', ops) + self.optimize_loop(ops, 'Not, Not', ops) # ---------- From arigo at codespeak.net Fri Aug 21 12:53:53 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 12:53:53 +0200 (CEST) Subject: [pypy-svn] r67057 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090821105353.8622716804A@codespeak.net> Author: arigo Date: Fri Aug 21 12:53:52 2009 New Revision: 67057 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, arigo) Handle DEBUG_MERGE_POINT specially in optimizeopt. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Fri Aug 21 12:53:52 2009 @@ -710,6 +710,11 @@ return self.emit_operation(op) + def optimize_DEBUG_MERGE_POINT(self, op): + # special-case this operation to prevent e.g. the handling of + # 'values_to_clean' (the op cannot be marked as side-effect-free) + self.newoperations.append(op) + optimize_ops = _findall(Optimizer, 'optimize_') class Storage: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Fri Aug 21 12:53:52 2009 @@ -984,7 +984,6 @@ self.optimize_loop(ops, 'Not, Not', expected) def test_duplicate_getfield_3(self): - py.test.skip("in-progress") ops = """ [p1] i1 = getfield_gc(p1, descr=valuedescr) From arigo at codespeak.net Fri Aug 21 13:02:05 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 13:02:05 +0200 (CEST) Subject: [pypy-svn] r67058 - pypy/branch/pyjitpl5/pypy/objspace/std Message-ID: <20090821110205.7CB7D168054@codespeak.net> Author: arigo Date: Fri Aug 21 13:02:04 2009 New Revision: 67058 Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Log: (iko, arigo) Kill one guard... Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Fri Aug 21 13:02:04 2009 @@ -188,12 +188,12 @@ space = w_self.space assert space.config.objspace.std.withmethodcache version_tag = w_self.version_tag + version_tag = hint(version_tag, promote=True) if version_tag is None: tup = w_self._lookup_where(name) return tup w_self = hint(w_self, promote=True) name = hint(name, promote=True) - version_tag = hint(version_tag, promote=True) return w_self._pure_lookup_where_with_method_cache(name, version_tag) @purefunction From benjamin at codespeak.net Fri Aug 21 13:06:15 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 13:06:15 +0200 (CEST) Subject: [pypy-svn] r67059 - pypy/branch/pyjitpl5/pypy/jit/tl/spli Message-ID: <20090821110615.0B398168054@codespeak.net> Author: benjamin Date: Fri Aug 21 13:06:14 2009 New Revision: 67059 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py Log: fix spli tests Modified: pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py Fri Aug 21 13:06:14 2009 @@ -4,7 +4,7 @@ from pypy.tool.stdlib_opcode import unrolling_opcode_descs from pypy.tool.stdlib_opcode import opcode_method_names from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.jit import JitDriver, hint +from pypy.rlib.jit import JitDriver, hint, dont_look_inside from pypy.rlib.objectmodel import we_are_translated @@ -44,6 +44,7 @@ _virtualizable2_ = ['value_stack[*]', 'locals[*]', 'stack_depth'] + @dont_look_inside def __init__(self, code, locs=None, globs=None): self.code = code self.value_stack = [None] * code.co_stacksize From benjamin at codespeak.net Fri Aug 21 13:09:52 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 13:09:52 +0200 (CEST) Subject: [pypy-svn] r67060 - pypy/trunk/pypy/config/test Message-ID: <20090821110952.18BF1168054@codespeak.net> Author: benjamin Date: Fri Aug 21 13:09:50 2009 New Revision: 67060 Modified: pypy/trunk/pypy/config/test/test_makerestdoc.py Log: don't fail if docutils is not installed Modified: pypy/trunk/pypy/config/test/test_makerestdoc.py ============================================================================== --- pypy/trunk/pypy/config/test/test_makerestdoc.py (original) +++ pypy/trunk/pypy/config/test/test_makerestdoc.py Fri Aug 21 13:09:50 2009 @@ -5,6 +5,11 @@ tempdir = py.test.ensuretemp('config') +try: + import docutils +except ImportError: + py.test.skip("don't have docutils") + def checkrest(rest, filename): tempfile = tempdir.join(filename) tempfile.write(rest) From benjamin at codespeak.net Fri Aug 21 14:19:45 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 14:19:45 +0200 (CEST) Subject: [pypy-svn] r67061 - pypy/trunk/pypy/lib Message-ID: <20090821121945.8E758168054@codespeak.net> Author: benjamin Date: Fri Aug 21 14:19:41 2009 New Revision: 67061 Modified: pypy/trunk/pypy/lib/_marshal.py Log: remove compatibility for versions we don't care about Modified: pypy/trunk/pypy/lib/_marshal.py ============================================================================== --- pypy/trunk/pypy/lib/_marshal.py (original) +++ pypy/trunk/pypy/lib/_marshal.py Fri Aug 21 14:19:41 2009 @@ -6,11 +6,6 @@ import types from _codecs import utf_8_decode, utf_8_encode -try: - import new -except ImportError: - new = None - TYPE_NULL = '0' TYPE_NONE = 'N' TYPE_FALSE = 'F' @@ -409,11 +404,9 @@ name = self.load() firstlineno = self.r_long() lnotab = self.load() - if not new: - raise RuntimeError, "can't unmarshal code objects; no 'new' module" - return new.code(argcount, nlocals, stacksize, flags, code, consts, - names, varnames, filename, name, firstlineno, lnotab, - freevars, cellvars) + return types.CodeType(argcount, nlocals, stacksize, flags, code, consts, + names, varnames, filename, name, firstlineno, + lnotab, freevars, cellvars) dispatch[TYPE_CODE] = load_code def load_set(self): @@ -627,11 +620,9 @@ name = self.load() firstlineno = _r_long(self) lnotab = self.load() - if not new: - raise RuntimeError, "can't unmarshal code objects; no 'new' module" - return new.code(argcount, nlocals, stacksize, flags, code, consts, - names, varnames, filename, name, firstlineno, lnotab, - freevars, cellvars) + return types.CodeType(argcount, nlocals, stacksize, flags, code, consts, + names, varnames, filename, name, firstlineno, + lnotab, freevars, cellvars) dispatch[TYPE_CODE] = load_code def load_set(self): @@ -650,17 +641,6 @@ # _________________________________________________________________ # -# compatibility - -try: - set -except NameError: - def set(x): - raise ValueError("cannot unmarshal set objects on Python < 2.4") - frozenset = set - -# _________________________________________________________________ -# # user interface version = 1 From arigo at codespeak.net Fri Aug 21 14:28:00 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 14:28:00 +0200 (CEST) Subject: [pypy-svn] r67062 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090821122800.2F388168059@codespeak.net> Author: arigo Date: Fri Aug 21 14:27:59 2009 New Revision: 67062 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: Oups. Restore translatability. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Fri Aug 21 14:27:59 2009 @@ -37,7 +37,7 @@ class OptValue(object): - _attrs_ = ('box', 'level') + _attrs_ = ('box', 'level', '_fields') level = LEVEL_UNKNOWN _fields = None From pedronis at codespeak.net Fri Aug 21 14:29:45 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 21 Aug 2009 14:29:45 +0200 (CEST) Subject: [pypy-svn] r67063 - in pypy/branch/pyjitpl5/pypy: annotation jit/metainterp jit/metainterp/test jit/tl rpython/test Message-ID: <20090821122945.4EC9B16805C@codespeak.net> Author: pedronis Date: Fri Aug 21 14:29:44 2009 New Revision: 67063 Modified: pypy/branch/pyjitpl5/pypy/annotation/specialize.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/jit/tl/tl.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, pedronis, armin around) - don't propagate access_directly into dont_look_inside functions - add access directly hints to tl, adjust the residual calls test - add a sanity check that graphs not seen by the jit are not accessing directly virtualizables Modified: pypy/branch/pyjitpl5/pypy/annotation/specialize.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/annotation/specialize.py (original) +++ pypy/branch/pyjitpl5/pypy/annotation/specialize.py Fri Aug 21 14:29:44 2009 @@ -59,18 +59,33 @@ # first flatten the *args args_s, key, name_suffix, builder = flatten_star_args(funcdesc, args_s) # two versions: a regular one and one for instances with 'access_directly' - for s_obj in args_s: + jit_look_inside = getattr(funcdesc.pyobj, '_look_inside_me_', True) + # change args_s in place, "official" interface + access_directly = False + for i, s_obj in enumerate(args_s): if (isinstance(s_obj, annmodel.SomeInstance) and 'access_directly' in s_obj.flags): - key = (AccessDirect, key) - name_suffix += '_AccessDirect' - break + if jit_look_inside: + access_directly = True + key = (AccessDirect, key) + name_suffix += '_AccessDirect' + break + else: + new_flags = s_obj.flags.copy() + del new_flags['access_directly'] + new_s_obj = annmodel.SomeInstance(s_obj.classdef, s_obj.can_be_None, + flags = new_flags) + args_s[i] = new_s_obj + # done if name_suffix: alt_name = '%s%s' % (funcdesc.name, name_suffix) else: alt_name = None - return funcdesc.cachedgraph(key, alt_name=alt_name, builder=builder) + graph = funcdesc.cachedgraph(key, alt_name=alt_name, builder=builder) + if access_directly: + graph.access_directly = True + return graph class AccessDirect(object): """marker for specialization: set when any arguments is a SomeInstance Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Fri Aug 21 14:29:44 2009 @@ -159,9 +159,16 @@ Stack.roll, Stack.append, Stack.pop] - methods = [m.im_func for m in methods] - self.test_tl_call(listops=False, policy=StopAtXPolicy(*methods)) - + for meth in methods: + meth_func = meth.im_func + assert not hasattr(meth_func, '_look_inside_me_') + meth_func._look_inside_me_ = False + try: + self.test_tl_call(listops=False) + finally: + for meth in methods: + meth_func = meth.im_func + del meth_func._look_inside_me_ class TestOOtype(ToyLanguageTests, OOJitMixin): def test_tl_call_full_of_residuals(self): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Fri Aug 21 14:29:44 2009 @@ -756,8 +756,6 @@ assert direct_calls(portal_graph) == ['force_if_necessary', 'maybe_enter_jit'] assert direct_calls(init_graph) == [] - - class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Fri Aug 21 14:29:44 2009 @@ -133,8 +133,10 @@ policy = JitPolicy() self.set_translator(translator) self.find_portal() + graphs = find_all_graphs(self.portal_graph, policy, self.translator) + self.check_access_directly_sanity(graphs) if backendopt: - self.prejit_optimizations(policy) + self.prejit_optimizations(policy, graphs) self.build_meta_interp(**kwds) self.make_args_specification() @@ -190,9 +192,15 @@ graph.func._dont_inline_ = True self.jitdriver = block.operations[pos].args[1].value - def prejit_optimizations(self, policy): + def check_access_directly_sanity(self, graphs): + jit_graphs = set(graphs) + for graph in self.translator.graphs: + if graph in jit_graphs: + continue + assert not getattr(graph, 'access_directly', False) + + def prejit_optimizations(self, policy, graphs): from pypy.translator.backendopt.all import backend_optimizations - graphs = find_all_graphs(self.portal_graph, policy, self.translator) backend_optimizations(self.translator, graphs=graphs, merge_if_blocks=True, Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tl.py Fri Aug 21 14:29:44 2009 @@ -15,6 +15,7 @@ @dont_look_inside def __init__(self, size): + self = hint(self, access_directly=True) self.stack = [0] * size self.stackpos = 0 @@ -64,6 +65,8 @@ stack = Stack(len(code)) + stack = hint(stack, access_directly=True) + while pc < len(code): myjitdriver.jit_merge_point(pc=pc, code=code, stack=stack, inputarg=inputarg) Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Fri Aug 21 14:29:44 2009 @@ -225,6 +225,52 @@ res = self.interpret(f, [23]) assert res == 2323 + def test_access_directly_stop_at_dont_look_inside(self): + from pypy.rlib.jit import hint, dont_look_inside + + class A: + _virtualizable2_ = ['x'] + + def h(a): + g(a) + h = dont_look_inside(h) + + def g(a): + a.x = 2 + h(a) + + def f(): + a = A() + a = hint(a, access_directly=True) + a.x = 1 + g(a) + + t, typer, graph = self.gengraph(f, []) + deref = typer.type_system_deref + + desc = typer.annotator.bookkeeper.getdesc(g) + g_graphs = desc._cache.items() + assert len(g_graphs) == 2 + g_graphs.sort() + + assert g_graphs[0][0] is None # default + g_graph = g_graphs[0][1] + g_graph_directly = g_graphs[1][1] + + f_graph = t._graphof(f) + h_graph = t._graphof(h) # 1 graph! + + def get_direct_call_graph(graph): + for block, op in graph.iterblockops(): + if op.opname == 'direct_call': + return deref(op.args[0].value).graph + return None + + assert get_direct_call_graph(f_graph) is g_graph_directly + assert get_direct_call_graph(g_graph) is h_graph + assert get_direct_call_graph(g_graph_directly) is h_graph + assert get_direct_call_graph(h_graph) is g_graph + class TestLLtype(LLRtypeMixin, BaseTest): prefix = 'inst_' GETFIELD = 'getfield' From fijal at codespeak.net Fri Aug 21 14:45:26 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 21 Aug 2009 14:45:26 +0200 (CEST) Subject: [pypy-svn] r67064 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090821124526.3231E168054@codespeak.net> Author: fijal Date: Fri Aug 21 14:45:24 2009 New Revision: 67064 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: Fix the bug that debug_merge_point does not free its arg (but but but in case of a moving gc its a box and not a const) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Fri Aug 21 14:45:24 2009 @@ -226,6 +226,8 @@ single_gcref_descr = self.assembler.single_gcref_descr newops = [] for op in operations: + if op.opnum == rop.DEBUG_MERGE_POINT: + continue for i in range(len(op.args)): v = op.args[i] if (isinstance(v, ConstPtr) and v.value Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Fri Aug 21 14:45:24 2009 @@ -409,6 +409,15 @@ self.interpret(ops, [0]) assert not self.getptr(0, lltype.Ptr(self.S)) + def test_get_rid_of_debug_merge_point(self): + ops = ''' + [] + debug_merge_point() + fail() + ''' + loop = self.interpret(ops, [], run=False) + assert len(loop.operations) == 1 + def test_bug_0(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8] From benjamin at codespeak.net Fri Aug 21 14:51:11 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 14:51:11 +0200 (CEST) Subject: [pypy-svn] r67065 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test test/loopdata Message-ID: <20090821125111.014F4168054@codespeak.net> Author: benjamin Date: Fri Aug 21 14:51:11 2009 New Revision: 67065 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Log: (micke, benjamin) support parsing information about the code object Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Fri Aug 21 14:51:11 2009 @@ -205,8 +205,11 @@ return i + 1 if line.startswith('END'): raise EndOfBlock() - if line.startswith('#'): - self.current_block.add(Comment(line[1:])) + has_hash = line.startswith('#') + if has_hash or line.startswith('<'): + if has_hash: + line = line.lstrip("#") + self.current_block.add(Comment(line)) return i + 1 descr = None if " " in line: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Fri Aug 21 14:51:11 2009 @@ -12,4 +12,5 @@ END #(no jitdriver.get_printable_location!) 6:jump bi(0,6),bi(5,3),bi(3,24) + #19 LOOP END Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Fri Aug 21 14:51:11 2009 @@ -12,11 +12,11 @@ assert len(topblock.inputargs) == 3 for arg in topblock.inputargs: assert isinstance(arg, BoxInt) - assert len(topblock.operations) == 7 + assert len(topblock.operations) == 8 assert isinstance(topblock.operations[0], Comment) assert topblock.operations[0].text == \ "(no jitdriver.get_printable_location!)" - assert isinstance(topblock.operations[-2], Comment) + assert isinstance(topblock.operations[5], Comment) assert isinstance(topblock.operations[4], GuardOperation) assert ([op.opname for op in topblock.operations if not isinstance(op, Comment)] == @@ -38,6 +38,9 @@ assert topblock.operations[2].args[1].value == 1 assert topblock.operations[2].result is topblock.operations[3].args[0] assert topblock.operations[3].args[1].value == -42 + code_comment = topblock.operations[7] + assert isinstance(code_comment, Comment) + assert code_comment.text == " #19" def test_two_paths(self): loops = self.parse("two_paths.ops") From antocuni at codespeak.net Fri Aug 21 14:53:52 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 21 Aug 2009 14:53:52 +0200 (CEST) Subject: [pypy-svn] r67066 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test Message-ID: <20090821125352.8A350168059@codespeak.net> Author: antocuni Date: Fri Aug 21 14:53:51 2009 New Revision: 67066 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py Log: no chance to make these tests working with pythonnet Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py Fri Aug 21 14:53:51 2009 @@ -41,6 +41,8 @@ test_residual_call_pure = skip test_div_overflow = skip test_subclassof = skip + test_assert_isinstance = skip + test_dont_look_inside = skip def test_fielddescr_ootype(): From micke at codespeak.net Fri Aug 21 15:41:47 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Fri, 21 Aug 2009 15:41:47 +0200 (CEST) Subject: [pypy-svn] r67067 - in pypy/branch/pyjitpl5/pypy/module/pypyjit/test: . loops Message-ID: <20090821134147.CED71168054@codespeak.net> Author: micke Date: Fri Aug 21 15:41:46 2009 New Revision: 67067 Added: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/dict_lookup.py pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/simple_add.py Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Log: (benjamin, micke): Mechanism for running code in pypy w/ jit and cpython and compare the results, as well as analyzing the operations log from the jit. Also a simple test for looking at the operations produced for a simple loop doing integer addition. Added: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/dict_lookup.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/dict_lookup.py Fri Aug 21 15:41:46 2009 @@ -0,0 +1,6 @@ +def f(): + d = {'x': 1} + for i in range(10000): + d['x'] = i + print d['x'] +f() Added: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/simple_add.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/loops/simple_add.py Fri Aug 21 15:41:46 2009 @@ -0,0 +1,7 @@ +def f(): + i = 0 + for _ in range(10000): + i += 1 + print i + +f() Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Fri Aug 21 15:41:46 2009 @@ -1,8 +1,20 @@ from pypy.conftest import gettestobjspace, option from pypy.tool.udir import udir +from pypy.jit.backend import loopparser import py import sys, os +def run_source(sourcefile, pypy_executable, tmpdir): + logfilepath = tmpdir.join(sourcefile.basename[:-3] + '.log') + if sys.platform.startswith('win'): + py.test.skip("XXX this is not Windows-friendly") + + result = py.process.cmdexec('PYPYJITLOG="%s" "%s" "%s"' % ( + logfilepath, pypy_executable, sourcefile)) + assert result + assert logfilepath.check() + return result, logfilepath + '.ops' + class PyPyCJITTests(object): def run_source(self, source, testcases): source = py.code.Source(source) @@ -134,5 +146,24 @@ cls.counter = 0 cls.pypy_c = option.pypy_c - - + def run_and_compare(self, sourcefile): + fname = py.magic.autopath().dirpath().join('loops', sourcefile) + pypy_out, log = run_source(fname, self.pypy_c, self.tmpdir) + cpy_out = py.process.cmdexec('"%s" "%s"' % ( + sys.executable, fname)) + assert pypy_out == cpy_out + parser = loopparser.Parser() + return parser.parse(log) + + def assert_no_op(self, loop, opname): + for operation in loop.iter_operations(): + assert operation.opname != opname + + def test_trivial_add(self): + loops = self.run_and_compare('simple_add.py') + self.assert_no_op(loops[0], 'call') + + def test_dict_lookup(self): + py.test.skip('should remove dict lookups') + loops = self.run_and_compare('dict_lookup.py') + self.assert_no_op(loops[1], 'getfield_gc') From arigo at codespeak.net Fri Aug 21 15:43:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 15:43:36 +0200 (CEST) Subject: [pypy-svn] r67068 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090821134336.2DB82168054@codespeak.net> Author: arigo Date: Fri Aug 21 15:43:35 2009 New Revision: 67068 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: Obscure optimization. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Fri Aug 21 15:43:35 2009 @@ -516,7 +516,7 @@ return elif not op.has_no_side_effect(): for value in self.values_to_clean: - value._fields = None + value._fields.clear() del self.values_to_clean[:] # otherwise, the operation remains self.emit_operation(op) From micke at codespeak.net Fri Aug 21 15:43:37 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Fri, 21 Aug 2009 15:43:37 +0200 (CEST) Subject: [pypy-svn] r67069 - pypy/branch/pyjitpl5/pypy/jit/backend Message-ID: <20090821134337.25A1C168054@codespeak.net> Author: micke Date: Fri Aug 21 15:43:35 2009 New Revision: 67069 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Log: (benjamin, micke) oops! convenience function for retrieving all interesting (i.e. non comment) operations from the parsed opts log. This should have come with commit 67067. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Fri Aug 21 15:43:35 2009 @@ -30,6 +30,10 @@ def get_display_text(self): return str(self) + def iter_operations(self): + for op in self.operations: + if isinstance(op, Operation): + yield op class Loop(OpContainer): From arigo at codespeak.net Fri Aug 21 15:46:51 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 15:46:51 +0200 (CEST) Subject: [pypy-svn] r67070 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090821134651.9B5BA168054@codespeak.net> Author: arigo Date: Fri Aug 21 15:46:51 2009 New Revision: 67070 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Log: (iko, arigo) Removed the __hash__ on Consts. This has the effect that equal Consts as keys in a dict are not shared any more (they already weren't after translation). The (hopefully) only place that cared is codewriter.py, which can be fixed with an r_dict. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Fri Aug 21 15:46:51 2009 @@ -6,7 +6,7 @@ from pypy.rlib import objectmodel from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.jit import _we_are_jitted -from pypy.jit.metainterp.history import Const, getkind +from pypy.jit.metainterp.history import Const, getkind, dict_equal_consts from pypy.jit.metainterp import heaptracker, support, history from pypy.tool.udir import udir from pypy.translator.simplify import get_funcobj, get_functype @@ -81,7 +81,7 @@ portal_graph = None def __init__(self, metainterp_sd, policy, ts): - self.all_prebuilt_values = {} + self.all_prebuilt_values = dict_equal_consts() self.all_graphs = {} self.all_indirectcallsets = {} self.all_methdescrs = {} Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Fri Aug 21 15:46:51 2009 @@ -173,29 +173,27 @@ return 'Const(%s)' % self._getrepr_() def __eq__(self, other): + "NOT_RPYTHON" + # Remember that you should not compare Consts with '==' in RPython. + # Consts have no special __hash__, in order to force different Consts + # from being considered as different keys when stored in dicts + # (as they always are after translation). Use a dict_equal_consts() + # to get the other behavior (i.e. using this __eq__). if self.__class__ is not other.__class__: return False if isinstance(self.value, Symbolic): - v = id(self.value) + v1 = "symbolic", id(self.value) else: - v = self.value + v1 = self.value if isinstance(other.value, Symbolic): - v2 = id(other.value) + v2 = "symbolic", id(other.value) else: v2 = other.value - return v == v2 + return v1 == v2 def __ne__(self, other): return not (self == other) - def __hash__(self): - if isinstance(self.value, Symbolic): - return id(self.value) - try: - return self.get_() - except lltype.DelayedPointer: - return -2 # xxx risk of changing hash... - class ConstInt(Const): type = INT @@ -541,6 +539,27 @@ # ____________________________________________________________ +def dict_equal_consts(): + "NOT_RPYTHON" + # Returns a dict in which Consts that compare as equal + # are identified when used as keys. + return r_dict(dc_eq, dc_hash) + +def dc_eq(c1, c2): + return c1 == c2 + +def dc_hash(c): + if not isinstance(c, Const): + return hash(c) + if isinstance(c.value, Symbolic): + return id(c.value) + try: + return c.get_() + except lltype.DelayedPointer: + return -2 # xxx risk of changing hash... + +# ____________________________________________________________ + # The TreeLoop class contains a loop or a generalized loop, i.e. a tree # of operations. Each branch ends in a jump which can go either to # the top of the same loop, or to another TreeLoop; or it ends in a FAIL. From arigo at codespeak.net Fri Aug 21 15:47:12 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 15:47:12 +0200 (CEST) Subject: [pypy-svn] r67071 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090821134712.78887168047@codespeak.net> Author: arigo Date: Fri Aug 21 15:47:11 2009 New Revision: 67071 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, arigo) Add a test. Skipped for now. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Fri Aug 21 15:47:11 2009 @@ -1003,6 +1003,25 @@ """ self.optimize_loop(ops, 'Not', expected) + def test_duplicate_getfield_constant(self): + py.test.skip("maybe implement later") + ops = """ + [] + i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) + i2 = getfield_gc(ConstPtr(myptr), descr=valuedescr) + escape(i1) + escape(i2) + jump() + """ + expected = """ + [] + i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) + escape(i1) + escape(i1) + jump() + """ + self.optimize_loop(ops, '', expected) + def test_duplicate_getfield_sideeffects_1(self): ops = """ [p1] From arigo at codespeak.net Fri Aug 21 15:52:03 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 15:52:03 +0200 (CEST) Subject: [pypy-svn] r67072 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090821135203.B540116804A@codespeak.net> Author: arigo Date: Fri Aug 21 15:52:02 2009 New Revision: 67072 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (iko, arigo) Fix test. If run with optimizations turned on, we get only one GETFIELD_GC instead of three. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Fri Aug 21 15:52:02 2009 @@ -8,7 +8,7 @@ from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR from pypy.rpython.rclass import FieldListAccessor from pypy.jit.metainterp.warmspot import get_stats, get_translator -from pypy.jit.metainterp import history, heaptracker +from pypy.jit.metainterp import history, heaptracker, simple_optimize from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin promote_virtualizable = lloperation.llop.promote_virtualizable @@ -403,7 +403,7 @@ n -= 1 return xy2.inst_l2[0] expected = f(20) - res = self.meta_interp(f, [20]) + res = self.meta_interp(f, [20], optimizer=simple_optimize) assert res == expected self.check_loops(getfield_gc=3, setfield_gc=0, arraylen_gc=1, getarrayitem_gc=1, setarrayitem_gc=1) From cfbolz at codespeak.net Fri Aug 21 16:52:46 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 21 Aug 2009 16:52:46 +0200 (CEST) Subject: [pypy-svn] r67073 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090821145246.BEAE216804A@codespeak.net> Author: cfbolz Date: Fri Aug 21 16:52:45 2009 New Revision: 67073 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (bea, cfbolz): some tasks Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Fri Aug 21 16:52:45 2009 @@ -113,3 +113,13 @@ - fix config tests (Armin, Carl Friedrich around) - merge the compiler branch - general wizardry (Maciek, Bea) + + +Ater the Sprint +---------------- + +- merge the jit branch to trunk +- upgrade python on wyvern +- improve test running, compile only once +- can we have a buildbot download button for pypy-cs? +- sort out a benchmark server (Open End?) From benjamin at codespeak.net Fri Aug 21 16:56:01 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 16:56:01 +0200 (CEST) Subject: [pypy-svn] r67074 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090821145601.8BA0E16804A@codespeak.net> Author: benjamin Date: Fri Aug 21 16:56:01 2009 New Revision: 67074 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: example Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Fri Aug 21 16:56:01 2009 @@ -54,7 +54,7 @@ - run random tests for x86 nightly - we need tests for pypy-jit behaviour that explicitely check whether the loops make sense -- the tragedy of the skipped tests +- the tragedy of the skipped tests (like test_pypy_c.py) things we know are missing --------------------------- From pedronis at codespeak.net Fri Aug 21 17:05:24 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 21 Aug 2009 17:05:24 +0200 (CEST) Subject: [pypy-svn] r67075 - in pypy/branch/pyjitpl5/pypy: jit/tl module/pypyjit rlib rlib/test rpython rpython/lltypesystem translator/c/test translator/cli translator/jvm translator/oosupport/test_template Message-ID: <20090821150524.E5B8C168054@codespeak.net> Author: pedronis Date: Fri Aug 21 17:05:23 2009 New Revision: 67075 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tiny2.py pypy/branch/pyjitpl5/pypy/jit/tl/tiny2_hotpath.py pypy/branch/pyjitpl5/pypy/jit/tl/tiny3_hotpath.py pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py pypy/branch/pyjitpl5/pypy/rlib/jit.py pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py pypy/branch/pyjitpl5/pypy/rpython/llinterp.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lloperation.py pypy/branch/pyjitpl5/pypy/translator/c/test/test_symbolic.py pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py pypy/branch/pyjitpl5/pypy/translator/jvm/opcodes.py pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/operations.py Log: remove _is_early_constant() Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tiny2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tiny2.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tiny2.py Fri Aug 21 17:05:23 2009 @@ -27,7 +27,7 @@ { #1 #1 1 SUB ->#1 #1 } => when called with 5, gives '5 4 3 2 1' """ -from pypy.rlib.jit import hint, _is_early_constant +from pypy.rlib.jit import hint # # See pypy/doc/jit.txt for a higher-level overview of the JIT techniques @@ -189,16 +189,9 @@ start += 1 return res def myint(s, start=0): - if _is_early_constant(s): - s = hint(s, promote=True) - start = hint(start, promote=True) - n = myint_internal(s, start) - if n < 0: - raise ValueError - else: - n = myint_internal(s, start) - if n < 0: - raise ValueError + n = myint_internal(s, start) + if n < 0: + raise ValueError return n # ------------------------------ Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tiny2_hotpath.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tiny2_hotpath.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tiny2_hotpath.py Fri Aug 21 17:05:23 2009 @@ -27,7 +27,7 @@ { #1 #1 1 SUB ->#1 #1 } => when called with 5, gives '5 4 3 2 1' """ -from pypy.rlib.jit import hint, _is_early_constant, JitDriver +from pypy.rlib.jit import hint, JitDriver # # See pypy/doc/jit.txt for a higher-level overview of the JIT techniques @@ -225,16 +225,9 @@ start += 1 return res def myint(s, start=0): - if _is_early_constant(s): - s = hint(s, promote=True) - start = hint(start, promote=True) - n = myint_internal(s, start) - if n < 0: - raise ValueError - else: - n = myint_internal(s, start) - if n < 0: - raise ValueError + n = myint_internal(s, start) + if n < 0: + raise ValueError return n # ------------------------------ Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tiny3_hotpath.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tiny3_hotpath.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tiny3_hotpath.py Fri Aug 21 17:05:23 2009 @@ -28,7 +28,7 @@ { #1 #1 1 SUB ->#1 #1 } => when called with 5, gives '5 4 3 2 1' """ -from pypy.rlib.jit import hint, _is_early_constant, JitDriver +from pypy.rlib.jit import hint, JitDriver from pypy.rlib.objectmodel import specialize # @@ -237,16 +237,9 @@ start += 1 return res def myint(s, start=0): - if _is_early_constant(s): - s = hint(s, promote=True) - start = hint(start, promote=True) - n = myint_internal(s, start) - if n < 0: - raise ValueError - else: - n = myint_internal(s, start) - if n < 0: - raise ValueError + n = myint_internal(s, start) + if n < 0: + raise ValueError return n @specialize.argtype(0) Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Fri Aug 21 17:05:23 2009 @@ -88,21 +88,6 @@ pycode=f.getcode()) return jumpto -##class __extend__(Function): -## __metaclass__ = extendabletype - -## def getcode(self): -## # if the self is a compile time constant and if its code -## # is a BuiltinCode => grab and return its code as a constant -## if _is_early_constant(self): -## from pypy.interpreter.gateway import BuiltinCode -## code = hint(self, deepfreeze=True).code -## if not isinstance(code, BuiltinCode): code = self.code -## else: -## code = self.code -## return code - - # ____________________________________________________________ # # Public interface Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Fri Aug 21 17:05:23 2009 @@ -67,27 +67,6 @@ from pypy.rpython.lltypesystem import lltype return hop.inputconst(lltype.Signed, _we_are_jitted) -def _is_early_constant(x): - return False - -class Entry(ExtRegistryEntry): - _about_ = _is_early_constant - - def compute_result_annotation(self, s_value): - from pypy.annotation import model as annmodel - s = annmodel.SomeBool() - if s_value.is_constant(): - s.const = True - return s - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - if hop.s_result.is_constant(): - assert hop.s_result.const - return hop.inputconst(lltype.Bool, True) - v, = hop.inputargs(hop.args_r[0]) - return hop.genop('is_early_constant', [v], resulttype=lltype.Bool) - # ____________________________________________________________ # User interface for the hotpath JIT policy Modified: pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py Fri Aug 21 17:05:23 2009 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import hint, _is_early_constant +from pypy.rlib.jit import hint from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin @@ -10,22 +10,3 @@ return x res = self.interpret(f, []) assert res == 5 - - def test_is_early_constant(self): - def f(x): - if _is_early_constant(x): - return 42 - return 0 - - assert f(3) == 0 - res = self.interpret(f, [5]) - assert res == 0 - - def g(): - return f(88) - - res = self.interpret(g, []) - assert res == 42 - - - Modified: pypy/branch/pyjitpl5/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/llinterp.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/llinterp.py Fri Aug 21 17:05:23 2009 @@ -578,9 +578,6 @@ def op_hint(self, x, hints): return x - def op_is_early_constant(self, x): - return False - def op_resume_point(self, *args): pass Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lloperation.py Fri Aug 21 17:05:23 2009 @@ -457,7 +457,6 @@ 'keepalive': LLOp(), 'same_as': LLOp(canfold=True), 'hint': LLOp(), - 'is_early_constant': LLOp(sideeffects=False), 'check_no_more_arg': LLOp(canraise=(Exception,)), 'check_self_nonzero': LLOp(canraise=(Exception,)), 'decode_arg': LLOp(canraise=(Exception,)), Modified: pypy/branch/pyjitpl5/pypy/translator/c/test/test_symbolic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/test/test_symbolic.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/test/test_symbolic.py Fri Aug 21 17:05:23 2009 @@ -109,16 +109,3 @@ fn = t.compile_c() res = fn() assert res == 42 - -def test_is_early_constant(): - from pypy.rlib import jit - def f(x): - if jit._is_early_constant(x): - return 42 - return 0 - - - fn, t = getcompiled(f, [int]) - res = fn(5) - assert res == 0 - Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Fri Aug 21 17:05:23 2009 @@ -78,7 +78,6 @@ 'debug_print': [DebugPrint], 'debug_fatalerror': [PushAllArgs, 'call void [pypylib]pypy.runtime.Utils::debug_fatalerror(string)'], 'keepalive': Ignore, - 'is_early_constant': [PushPrimitive(ootype.Bool, False)], 'jit_marker': Ignore, 'promote_virtualizable': Ignore, } Modified: pypy/branch/pyjitpl5/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/jvm/opcodes.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/jvm/opcodes.py Fri Aug 21 17:05:23 2009 @@ -221,6 +221,4 @@ 'truncate_longlong_to_int': jvm.L2I, 'cast_longlong_to_float': jvm.L2D, 'cast_primitive': [PushAllArgs, CastPrimitive, StoreResult], - 'is_early_constant': [PushPrimitive(ootype.Bool, False), StoreResult] - }) Modified: pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/operations.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/operations.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/operations.py Fri Aug 21 17:05:23 2009 @@ -210,14 +210,6 @@ return bool(x) self._check_all(fn) - def test_is_early_constant(self): - from pypy.rlib import jit - def f(x): - if jit._is_early_constant(x): - return 42 - return 0 - assert self.interpret(f, [5]) == 0 - def test_ullong_rshift(self): def f(x): return x >> 1 From benjamin at codespeak.net Fri Aug 21 17:06:25 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 17:06:25 +0200 (CEST) Subject: [pypy-svn] r67076 - pypy/branch/pyjitpl5/pypy/module/pypyjit/test Message-ID: <20090821150625.A7944168054@codespeak.net> Author: benjamin Date: Fri Aug 21 17:06:24 2009 New Revision: 67076 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Log: fix use of outdated JIT API Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Fri Aug 21 17:06:24 2009 @@ -26,8 +26,7 @@ # some support code... print >> f, py.code.Source(""" import sys, pypyjit - pypyjit.enable() - pypyjit.setthreshold(3) + pypyjit.set_param(threshold=3) def check(args, expected): for i in range(3): From benjamin at codespeak.net Fri Aug 21 17:07:59 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 17:07:59 +0200 (CEST) Subject: [pypy-svn] r67077 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090821150759.3829B168054@codespeak.net> Author: benjamin Date: Fri Aug 21 17:07:58 2009 New Revision: 67077 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: fixed this one Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Fri Aug 21 17:07:58 2009 @@ -54,7 +54,7 @@ - run random tests for x86 nightly - we need tests for pypy-jit behaviour that explicitely check whether the loops make sense -- the tragedy of the skipped tests (like test_pypy_c.py) +- the tragedy of the skipped tests things we know are missing --------------------------- From benjamin at codespeak.net Fri Aug 21 17:15:02 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 17:15:02 +0200 (CEST) Subject: [pypy-svn] r67078 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090821151502.097E7168054@codespeak.net> Author: benjamin Date: Fri Aug 21 17:15:00 2009 New Revision: 67078 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: add a task Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Fri Aug 21 17:15:00 2009 @@ -94,6 +94,7 @@ - find bug in x86 backend related to GC (Maciek, Armin around) - make test_ll_random.py a bit better than before SORT-OF-DONE - set up test_ll_random to run nightly with x86 backend + - update things in metainterp/doc - make x86 not recompile everything - think about code memory management From cfbolz at codespeak.net Fri Aug 21 17:34:03 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 21 Aug 2009 17:34:03 +0200 (CEST) Subject: [pypy-svn] r67079 - pypy/branch/pyjitpl5/pypy/jit/tl Message-ID: <20090821153403.4CBF4168050@codespeak.net> Author: cfbolz Date: Fri Aug 21 17:34:02 2009 New Revision: 67079 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: use sharing dict with pypyjit Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Fri Aug 21 17:34:02 2009 @@ -44,6 +44,7 @@ config.objspace.std.withrangelist = True config.objspace.std.withsharingdict = True config.objspace.std.withmethodcache = True +config.objspace.std.withsharingdict = True if BACKEND == 'c': config.objspace.std.multimethods = 'mrd' From micke at codespeak.net Fri Aug 21 17:36:10 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Fri, 21 Aug 2009 17:36:10 +0200 (CEST) Subject: [pypy-svn] r67080 - pypy/branch/pyjitpl5/pypy/module/pypyjit/test Message-ID: <20090821153610.7E09D168053@codespeak.net> Author: micke Date: Fri Aug 21 17:36:09 2009 New Revision: 67080 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Log: Add option to view the graphs generated when jit is running test loops Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Fri Aug 21 17:36:09 2009 @@ -152,7 +152,11 @@ sys.executable, fname)) assert pypy_out == cpy_out parser = loopparser.Parser() - return parser.parse(log) + loops = parser.parse(log) + if option.view: + from pypy.jit.metainterp.graphpage import display_loops + display_loops(loops) + return loops def assert_no_op(self, loop, opname): for operation in loop.iter_operations(): From fijal at codespeak.net Fri Aug 21 17:41:25 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 21 Aug 2009 17:41:25 +0200 (CEST) Subject: [pypy-svn] r67081 - pypy/branch/pyjitpl5/pypy/jit/tl Message-ID: <20090821154125.2A5EE168053@codespeak.net> Author: fijal Date: Fri Aug 21 17:41:23 2009 New Revision: 67081 Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: Revert 67079 as we have this option on already Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Fri Aug 21 17:41:23 2009 @@ -44,7 +44,6 @@ config.objspace.std.withrangelist = True config.objspace.std.withsharingdict = True config.objspace.std.withmethodcache = True -config.objspace.std.withsharingdict = True if BACKEND == 'c': config.objspace.std.multimethods = 'mrd' From benjamin at codespeak.net Fri Aug 21 17:42:12 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 21 Aug 2009 17:42:12 +0200 (CEST) Subject: [pypy-svn] r67082 - pypy/branch/pyjitpl5/pypy/jit/metainterp/doc Message-ID: <20090821154212.92C6716805C@codespeak.net> Author: benjamin Date: Fri Aug 21 17:42:12 2009 New Revision: 67082 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt Log: update, mostly by deleting things I know aren't true anymore Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt Fri Aug 21 17:42:12 2009 @@ -12,20 +12,20 @@ Tracing: executing code and recording what we did, for one loop. This starts at the app-level JUMP_ABSOLUTE (or equivalent) bytecode that -closes an app-level loop. Implemented by interpreting the rainbow +closes an app-level loop. Implemented by interpreting a custom bytecode that describes the interpreter itself. (Could later be optimized by removing the rainbow bytecode.) We pass around BoxInt and BoxPtr objects that have this minimal content:: - +- BoxPtr ---------+ + +- BoxInt ---------+ | real value | +------------------+ -In other words, BoxInt and BoxPtr just record the real value. Each -operation generates a new BoxInt or BoxPtr (even if it contains the same -real value as another box). +In other words, BoxInt and BoxPtr just record the real value. Like +PyPy's flowgraph, each operation generates a new BoxInt or BoxPtr +(even if it contains the same real value as another box). Tracing goes on for exactly one iteration of the app-level loop. As it handles real values, it makes the real program progress one iteration. @@ -95,9 +95,11 @@ ============= When a guard fails, we normally fall back to regular interpretation. -Because the guard failure occurs in the middle of executing an app-level -bytecode, this requires interpreting the rainbow bytecode with a -fall-back interpreter until the start of the next app-level bytecode. +Because the guard failure occurs in the middle of executing an +app-level bytecode, this requires interpreting the bytecode describing +the interpreter with a fall-back interpreter (which is actually +implemented with the same code as the tracer) until the start of the +next app-level bytecode. When we decide instead to compile more code for this guard failure, we take the set of live values and put them back into boxes, and proceed Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt Fri Aug 21 17:42:12 2009 @@ -25,33 +25,9 @@ so that it points to the next bytecode to execute */ } -Initially, for a given frame position, there is no machine code produced -by the JIT so far. To simplify things, we use the following trick: -conceptually there is *always* machine code available, but this machine -code just contains an always-failing guard. So -lookup_machine_code_for() returns a pointer to machine code that looks -like this:: - - setup the frame... - /* here starts the code for an always- failing guard */ - PUSH info_about_this_guard - JMP generic_guard_recovery_code - -The generic guard recovery code contains the following logic:: - - REG1 = info_about_this_guard - REG2 = current_stack_base_pointer - REG3 = CALL jit_compile(REG1, REG2) - copy REG3->inputargs[0] to EAX - copy REG3->inputargs[1] to EBX - etc. - JMP REG3->targetaddr - -The jit_compile() function comes from RPython sources written in the JIT -support code. It does tracing and generally ends up compiling an extra -loop to machine code. It can also patch the failing guard in the -machine code (above) so that later invocations will jump directly to the -correct code. +The jit_compile() function comes from RPython sources written in the +JIT support code (warmspot.py). It does tracing and generally ends up +compiling an extra loop to machine code. Then jit_compile() itself needs to transfer execution to the newly compiled loop. Instead of calling the loop, jit_compile() returns a Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt Fri Aug 21 17:42:12 2009 @@ -57,48 +57,3 @@ We can achieve that by unpacking W_IntObject read from locals before the loop and carefully rebuilding this for each guard failure, by a small bit of assembler code. - -Problem one: what if we access this from a call or somewhere else? -------------------------------------------------------------------- - -This is the general problem with virtualizables, what if one has a reference -to that object and will choose to use it in place where we have things on -stack or not allocated at all? - -1. We store a small piece of assembler code as a function pointer inside - a virtualizable. This is, I think, simpler than having complex rebuild - info kept together along the chain. If someone accesses the frame, - this code will run and rebuild what is necessary. If this happens, there - are two possiblities: - -2. We check after the call (guard_nonvirtualized, but we need to put it - a bit differently) that frame was not accessed and if it was, exit the - jit. - -Problem two: what if we grow more elements during bridges? ----------------------------------------------------------- - -The problem is for such code: - - while i < 10000: - if i % 2: - i += a - else: - i += b - -Now the first loop is compiled and when the second part (a bridge) is compiled, -we end up with non-matching virtualizables. To avoid that, we need to pass -more arguments to the loop that usually anticipated. Note that this is not -a big deal if we're careful enough (for x86) since we can put more stuff on -the stack if we update esp register. We'll use ebp as a base for stack -operations, so we're free to change value of esp any time we want. -So we will end up with things like this: - -(%ebp-4), (%ebp-8), (%ebp-c) - original args -(%ebp-10), %(ebp-14) - temporary values -(%ebp-18) - additional value - -and we'll update esp by +4 - -This also solves the problem of moving around vars when we need to update -esp because of jump. good. From arigo at codespeak.net Fri Aug 21 18:53:08 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Aug 2009 18:53:08 +0200 (CEST) Subject: [pypy-svn] r67083 - in pypy/branch/pyjitpl5/pypy: config jit/tl Message-ID: <20090821165308.39C77168061@codespeak.net> Author: arigo Date: Fri Aug 21 18:53:06 2009 New Revision: 67083 Modified: pypy/branch/pyjitpl5/pypy/config/pypyoption.py pypy/branch/pyjitpl5/pypy/config/translationoption.py pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Log: (iko, arigo) Replace the option --jit with using the optimization level -Ojit. Much more flexible. Modified: pypy/branch/pyjitpl5/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/pypyoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/pypyoption.py Fri Aug 21 18:53:06 2009 @@ -356,7 +356,7 @@ backend = config.translation.backend # all the good optimizations for PyPy should be listed here - if level in ['2', '3']: + if level in ['2', '3', 'jit']: config.objspace.opcodes.suggest(CALL_LIKELY_BUILTIN=True) config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withmultidict=True) @@ -392,6 +392,10 @@ if type_system == 'ootype': config.objspace.std.suggest(multimethods="doubledispatch") + # extra optimizations with the JIT + if level == 'jit': + config.objspace.std.suggest(withsharingdict=True) + def enable_allworkingmodules(config): if config.translation.type_system == 'ootype': Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Fri Aug 21 18:53:06 2009 @@ -94,9 +94,9 @@ BoolOption("rweakref", "The backend supports RPython-level weakrefs", default=True), - # JIT generation + # JIT generation: use -Ojit to enable it BoolOption("jit", "generate a JIT", - default=False, cmdline="--jit", + default=False, requires=[("translation.thread", False)], suggests=[("translation.gc", "boehm"), # for now ("translation.list_comprehension_operations", True)]), @@ -298,7 +298,7 @@ # ____________________________________________________________ -OPT_LEVELS = ['0', '1', 'size', 'mem', '2', '3'] +OPT_LEVELS = ['0', '1', 'size', 'mem', '2', '3', 'jit'] DEFAULT_OPT_LEVEL = '2' OPT_TABLE_DOC = { @@ -308,6 +308,7 @@ 'mem': 'Optimize for run-time memory usage and use a memory-saving GC.', '2': 'Enable most optimizations and use a high-performance GC.', '3': 'Enable all optimizations and use a high-performance GC.', + 'jit': 'Enable the JIT.', } OPT_TABLE = { @@ -318,6 +319,7 @@ 'mem': 'markcompact lowinline remove_asserts', '2': 'hybrid extraopts', '3': 'hybrid extraopts remove_asserts', + 'jit': 'boehm extraopts', # XXX boehm for now, fix me } def set_opt_level(config, level): Modified: pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit.py Fri Aug 21 18:53:06 2009 @@ -31,19 +31,15 @@ config = get_pypy_config(translating=True) config.translation.backendopt.inline_threshold = 0 -set_opt_level(config, level='1') -config.objspace.compiler = 'ast' config.objspace.nofaking = True +config.objspace.compiler = "ast" +config.translating = True +set_opt_level(config, level='jit') config.objspace.allworkingmodules = False config.objspace.usemodules.pypyjit = True config.objspace.usemodules._weakref = False config.objspace.usemodules._sre = False -set_pypy_opt_level(config, level='0') -config.objspace.std.builtinshortcut = True -config.objspace.opcodes.CALL_LIKELY_BUILTIN = True -config.objspace.std.withrangelist = True -config.objspace.std.withsharingdict = True -config.objspace.std.withmethodcache = True +set_pypy_opt_level(config, level='jit') if BACKEND == 'c': config.objspace.std.multimethods = 'mrd' From cfbolz at codespeak.net Fri Aug 21 18:53:15 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 21 Aug 2009 18:53:15 +0200 (CEST) Subject: [pypy-svn] r67084 - in pypy/branch/pyjitpl5/pypy: interpreter jit/metainterp module/pypyjit Message-ID: <20090821165315.8DCC8168064@codespeak.net> Author: cfbolz Date: Fri Aug 21 18:53:14 2009 New Revision: 67084 Modified: pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Log: (pedronis, cfbolz): - make assertion consider only reachable graphs - enable direct accessing in python interpreter - don't look into some functions to preven the assert from being triggered Modified: pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py Fri Aug 21 18:53:14 2009 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted +from pypy.rlib.jit import we_are_jitted, dont_look_inside import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -765,6 +765,7 @@ if isinstance(args, ArgumentsFromValuestack): args.frame = None + @dont_look_inside def call_args_and_c_profile(self, frame, w_func, args): ec = self.getexecutioncontext() ec.c_call_trace(frame, w_func) Modified: pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py Fri Aug 21 18:53:14 2009 @@ -105,6 +105,7 @@ space.setitem(w_globals, w_key, w_value) return w_globals + @jit.dont_look_inside def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: @@ -112,6 +113,7 @@ else: self._trace(frame, 'c_call', w_func) + @jit.dont_look_inside def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: @@ -119,6 +121,7 @@ else: self._trace(frame, 'c_return', w_retval) + @jit.dont_look_inside def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: @@ -136,6 +139,7 @@ frame = fr[0] self.profilefunc(space, self.w_profilefuncarg, frame, event, w_arg) + @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: @@ -143,6 +147,7 @@ if self.profilefunc: frame.is_being_profiled = True + @jit.dont_look_inside def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: @@ -161,6 +166,7 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True + @jit.dont_look_inside def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Fri Aug 21 18:53:14 2009 @@ -193,8 +193,10 @@ self.jitdriver = block.operations[pos].args[1].value def check_access_directly_sanity(self, graphs): + from pypy.translator.backendopt.inline import collect_called_graphs jit_graphs = set(graphs) - for graph in self.translator.graphs: + for graph in collect_called_graphs(self.translator.graphs[0], + self.translator): if graph in jit_graphs: continue assert not getattr(graph, 'access_directly', False) @@ -566,7 +568,6 @@ return all_graphs - def decode_hp_hint_args(op): # Returns (list-of-green-vars, list-of-red-vars) without Voids. assert op.opname == 'jit_marker' Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Fri Aug 21 18:53:14 2009 @@ -68,6 +68,7 @@ class __extend__(PyFrame): def dispatch(self, pycode, next_instr, ec): + self = hint(self, access_directly=True) next_instr = r_uint(next_instr) try: while True: From micke at codespeak.net Fri Aug 21 19:07:57 2009 From: micke at codespeak.net (micke at codespeak.net) Date: Fri, 21 Aug 2009 19:07:57 +0200 (CEST) Subject: [pypy-svn] r67085 - in pypy/branch/pyjitpl5/pypy: jit/backend jit/backend/test module/pypyjit/test Message-ID: <20090821170757.9B35E16804D@codespeak.net> Author: micke Date: Fri Aug 21 19:07:56 2009 New Revision: 67085 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Log: - Distinguish reference to byte code instructions from comments in the opts log parser - Use this to find the relevant loop to inspect in the jit log parser based tests as the logs are relatively spammy Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Fri Aug 21 19:07:56 2009 @@ -59,6 +59,11 @@ def __repr__(self): return "Comment: %r" % (self.text,) +class ByteCodeRef(Comment): + def __init__(self, text): + Comment.__init__(self, text) + self.address = int(text.rsplit('#')[1]) + class Operation(BaseOperation): def __init__(self, opname, args, result=None, descr=None): self.opname = opname @@ -213,7 +218,10 @@ if has_hash or line.startswith('<'): if has_hash: line = line.lstrip("#") - self.current_block.add(Comment(line)) + if line.startswith(' #19" + assert code_comment.address == 19 def test_two_paths(self): loops = self.parse("two_paths.ops") Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/test/test_pypy_c.py Fri Aug 21 19:07:56 2009 @@ -164,7 +164,13 @@ def test_trivial_add(self): loops = self.run_and_compare('simple_add.py') - self.assert_no_op(loops[0], 'call') + for loop in loops: + # naive way if finding the relevant loop to inspect + if isinstance(loop.operations[0], loopparser.ByteCodeRef): + self.assert_no_op(loop, 'call') + break + else: + assert False def test_dict_lookup(self): py.test.skip('should remove dict lookups') From antocuni at codespeak.net Fri Aug 21 19:36:16 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 21 Aug 2009 19:36:16 +0200 (CEST) Subject: [pypy-svn] r67086 - pypy/branch/pyjitpl5/pypy/jit/backend/cli Message-ID: <20090821173616.7764B168058@codespeak.net> Author: antocuni Date: Fri Aug 21 19:36:15 2009 New Revision: 67086 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Log: implement guard_overflow and guard_no_overflow for the cli jit backend Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Fri Aug 21 19:36:15 2009 @@ -8,7 +8,7 @@ from pypy.translator.cli import opcodes from pypy.jit.metainterp import history from pypy.jit.metainterp.history import (AbstractValue, Const, ConstInt, - ConstObj) + ConstObj, BoxInt) from pypy.jit.metainterp.resoperation import rop, opname from pypy.jit.backend.logger import AbstractLogger from pypy.jit.backend.cli import runner @@ -152,6 +152,7 @@ self.av_consts = MethodArgument(0, System.Type.GetType("System.Object[]")) t_InputArgs = dotnet.typeof(InputArgs) self.av_inputargs = MethodArgument(1,t_InputArgs ) + self.av_ovf_flag = BoxInt() self.exc_value_field = t_InputArgs.GetField('exc_value') if cpu.rtyper: self.av_OverflowError = ConstObj(ootype.cast_to_object(cpu.ll_ovf_exc)) @@ -360,6 +361,9 @@ self.av_inputargs.load(self) self.il.Emit(OpCodes.Ldnull) self.il.Emit(OpCodes.Stfld, self.exc_value_field) + # clear the overflow flag + self.il.Emit(OpCodes.Ldc_I4_0) + self.av_ovf_flag.store(self) def emit_raising_op(self, op, emit_op, exctypes): self.emit_clear_exception() @@ -370,13 +374,13 @@ v = self.il.DeclareLocal(exctype) self.il.BeginCatchBlock(exctype) if exctype == dotnet.typeof(System.OverflowException) and self.av_OverflowError: - # translate OverflowException into excpetions.OverflowError - self.il.Emit(OpCodes.Pop) - self.av_OverflowError.load(self) - self.il.Emit(OpCodes.Stloc, v) - self.av_inputargs.load(self) - self.il.Emit(OpCodes.Ldloc, v) - self.il.Emit(OpCodes.Stfld, self.exc_value_field) + self.il.Emit(OpCodes.Ldc_I4_1) + self.av_ovf_flag.store(self) + else: + self.il.Emit(OpCodes.Stloc, v) + self.av_inputargs.load(self) + self.il.Emit(OpCodes.Ldloc, v) + self.il.Emit(OpCodes.Stfld, self.exc_value_field) self.il.EndExceptionBlock() def mark(self, msg): @@ -455,11 +459,18 @@ self.il.Emit(OpCodes.Ldfld, self.exc_value_field) self.store_result(op) + def emit_guard_overflow_impl(self, op, opcode): + assert op.suboperations + assert len(op.args) == 0 + il_label = self.newbranch(op) + self.av_ovf_flag.load(self) + self.il.Emit(opcode, il_label) + def emit_op_guard_no_overflow(self, op): - pass # XXX implement me! + self.emit_guard_overflow_impl(op, OpCodes.Brtrue) def emit_op_guard_overflow(self, op): - pass # XXX implement me! + self.emit_guard_overflow_impl(op, OpCodes.Brfalse) def emit_op_jump(self, op): target = op.jump_target Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Fri Aug 21 19:36:15 2009 @@ -132,6 +132,16 @@ def clear_exception(self): self.get_inputargs().set_exc_value(None) + def get_overflow_error(self): + exc_type = ootype.cast_to_object(ootype.classof(self.ll_ovf_exc)) + exc_value = ootype.cast_to_object(self.ll_ovf_exc) + return exc_type, exc_value + + def get_zero_division_error(self): + exc_type = ootype.cast_to_object(ootype.classof(self.ll_zero_exc)) + exc_value = ootype.cast_to_object(self.ll_zero_exc) + return exc_type, exc_value + def set_overflow_error(self): exc_obj = ootype.cast_to_object(self.ll_ovf_exc) exc_value = dotnet.cast_to_native_object(exc_obj) From fijal at codespeak.net Fri Aug 21 23:10:37 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 21 Aug 2009 23:10:37 +0200 (CEST) Subject: [pypy-svn] r67087 - pypy/branch/pyjitpl5/pypy/config Message-ID: <20090821211037.16E7F168072@codespeak.net> Author: fijal Date: Fri Aug 21 23:10:35 2009 New Revision: 67087 Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py Log: Actually enable jit with -Ojit Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original) +++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Fri Aug 21 23:10:35 2009 @@ -319,7 +319,7 @@ 'mem': 'markcompact lowinline remove_asserts', '2': 'hybrid extraopts', '3': 'hybrid extraopts remove_asserts', - 'jit': 'boehm extraopts', # XXX boehm for now, fix me + 'jit': 'boehm extraopts jit', # XXX boehm for now, fix me } def set_opt_level(config, level): @@ -354,6 +354,8 @@ config.translation.backendopt.suggest(remove_asserts=True) elif word == 'extraopts': config.translation.suggest(withsmallfuncsets=5) + elif word == 'jit': + config.translation.suggest(jit=True) else: raise ValueError(word) From fijal at codespeak.net Sat Aug 22 13:25:57 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 22 Aug 2009 13:25:57 +0200 (CEST) Subject: [pypy-svn] r67088 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090822112557.9722F16807B@codespeak.net> Author: fijal Date: Sat Aug 22 13:25:55 2009 New Revision: 67088 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: (arigo, pedronis, fijal) Use more registers than just 3. Win is a bit questionable though Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sat Aug 22 13:25:55 2009 @@ -232,6 +232,9 @@ #if self.gcrootmap: self.mc.PUSH(ebp) self.mc.MOV(ebp, esp) + self.mc.PUSH(ebx) + self.mc.PUSH(esi) + self.mc.PUSH(edi) self.mc.SUB(esp, imm(framesize * WORD)) for i in range(len(arglocs)): loc = arglocs[i] @@ -302,6 +305,9 @@ genop_guard_list[op.opnum](self, op, None, addr, arglocs, resloc) + def load_effective_addr(self, sizereg, baseofs, scale, result): + self.mc.LEA(result, addr_add(imm(0), sizereg, baseofs, scale)) + def _unaryop(asmop): def genop_unary(self, op, arglocs, resloc): getattr(self.mc, asmop)(arglocs[0]) @@ -738,6 +744,9 @@ guard_index = self.cpu.make_guard_index(op) self.mc.MOV(eax, imm(guard_index)) #if self.gcrootmap: + self.mc.POP(edi) + self.mc.POP(esi) + self.mc.POP(ebx) self.mc.POP(ebp) self.mc.RET() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sat Aug 22 13:25:55 2009 @@ -14,7 +14,7 @@ # esi edi and ebx can be added to this list, provided they're correctly # saved and restored -REGS = [eax, ecx, edx] +REGS = [eax, ecx, edx, ebx, esi, edi] WORD = 4 class TempBox(Box): @@ -115,8 +115,9 @@ assert len(rev_regs) + len(self.free_regs) == len(REGS) else: assert len(self.reg_bindings) + len(self.free_regs) == len(REGS) - for v in self.reg_bindings: - assert self.longevity[v][1] > self.position + if self.longevity: + for v in self.reg_bindings: + assert self.longevity[v][1] > self.position def Load(self, v, from_loc, to_loc): if not we_are_translated(): @@ -307,7 +308,7 @@ for arg in guard.inputargs: assert isinstance(arg, Box) - def try_allocate_reg(self, v, selected_reg=None): + def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False): assert not isinstance(v, Const) if selected_reg is not None: res = self.reg_bindings.get(v, None) @@ -323,6 +324,20 @@ self.reg_bindings[v] = selected_reg return selected_reg return None + if need_lower_byte: + loc = self.reg_bindings.get(v, None) + if loc is not None and loc is not edi and loc is not esi: + return loc + for i in range(len(self.free_regs)): + reg = self.free_regs[i] + if reg is not edi and reg is not esi: + if loc is not None: + self.free_regs[i] = loc + else: + del self.free_regs[i] + self.reg_bindings[v] = reg + return reg + return None try: return self.reg_bindings[v] except KeyError: @@ -349,18 +364,26 @@ return loc return convert_to_imm(v) - def force_allocate_reg(self, v, forbidden_vars, selected_reg=None): + def force_allocate_reg(self, v, forbidden_vars, selected_reg=None, + need_lower_byte=False): if isinstance(v, TempBox): self.longevity[v] = (self.position, self.position) - loc = self.try_allocate_reg(v, selected_reg) + loc = self.try_allocate_reg(v, selected_reg, + need_lower_byte=need_lower_byte) if loc: return loc - loc = self._spill_var(v, forbidden_vars, selected_reg) + loc = self._spill_var(v, forbidden_vars, selected_reg, + need_lower_byte=need_lower_byte) + prev_loc = self.reg_bindings.get(v, None) + if prev_loc is not None: + self.free_regs.append(prev_loc) self.reg_bindings[v] = loc return loc - def _spill_var(self, v, forbidden_vars, selected_reg): - v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg) + def _spill_var(self, v, forbidden_vars, selected_reg, + need_lower_byte=False): + v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, + selected_reg, need_lower_byte=need_lower_byte) loc = self.reg_bindings[v_to_spill] del self.reg_bindings[v_to_spill] if v_to_spill not in self.stack_bindings: @@ -380,13 +403,14 @@ return res def make_sure_var_in_reg(self, v, forbidden_vars, selected_reg=None, - imm_fine=True): + imm_fine=True, need_lower_byte=False): if isinstance(v, Const): return self.return_constant(v, forbidden_vars, selected_reg, imm_fine) prev_loc = self.loc(v) - loc = self.force_allocate_reg(v, forbidden_vars, selected_reg) + loc = self.force_allocate_reg(v, forbidden_vars, selected_reg, + need_lower_byte=need_lower_byte) if prev_loc is not loc: self.Load(v, prev_loc, loc) return loc @@ -423,12 +447,18 @@ return -1 return -1 - def pick_variable_to_spill(self, v, forbidden_vars, selected_reg=None): + def pick_variable_to_spill(self, v, forbidden_vars, selected_reg=None, + need_lower_byte=False): candidates = [] for next in self.reg_bindings: - if (next not in forbidden_vars and selected_reg is None or - self.reg_bindings[next] is selected_reg): - candidates.append(next) + reg = self.reg_bindings[next] + if next in forbidden_vars: + continue + if selected_reg is not None and reg is selected_reg: + return next + if need_lower_byte and (reg is esi or reg is edi): + continue + candidates.append(next) assert candidates if len(candidates) == 1: return candidates[0] @@ -626,7 +656,8 @@ self.eventually_free_var(vx) self.eventually_free_var(vy) if guard_op is None: - loc = self.force_allocate_reg(op.result, op.args) + loc = self.force_allocate_reg(op.result, op.args, + need_lower_byte=True) self.Perform(op, arglocs, loc) else: regalloc = self.regalloc_for_guard(guard_op) @@ -655,16 +686,23 @@ # otherwise it's clean def _call(self, op, arglocs, force_store=[]): - # we need to store all variables which are now in registers + # we need to store all variables which are now + # in registers eax, ecx and edx for v, reg in self.reg_bindings.items(): - if self.longevity[v][1] > self.position or v in force_store: - self.sync_var(v) - self.reg_bindings = newcheckdict() + if v not in force_store and self.longevity[v][1] <= self.position: + # variable dies + del self.reg_bindings[v] + self.free_regs.append(reg) + continue + if reg is ebx or reg is esi or reg is edi: + # we don't need to + continue + self.sync_var(v) + del self.reg_bindings[v] + self.free_regs.append(reg) if op.result is not None: self.reg_bindings[op.result] = eax - self.free_regs = [reg for reg in REGS if reg is not eax] - else: - self.free_regs = REGS[:] + self.free_regs = [reg for reg in self.free_regs if reg is not eax] self.Perform(op, arglocs, eax) def consider_call(self, op, ignored): @@ -723,18 +761,12 @@ # XXX kill this function at some point if isinstance(v, Box): loc = self.make_sure_var_in_reg(v, [v]) - self.sync_var(v) - if size != 0: - # XXX lshift? no, better yet, use 'LEA' somehow (it can be - # combined with the following INT_ADD) - self.Perform(ResOperation(rop.INT_MUL, [], None), - [loc, imm(1 << size)], loc) - self.Perform(ResOperation(rop.INT_ADD, [], None), - [loc, imm(ofs_items)], loc) + other_loc = self.force_allocate_reg(TempBox(), [v]) + self.assembler.load_effective_addr(loc, ofs_items, size, other_loc) else: - loc = imm(ofs_items + (v.getint() << size)) + other_loc = imm(ofs_items + (v.getint() << size)) self._call(ResOperation(rop.NEW, [v], res_v), - [loc], [v]) + [other_loc], [v]) loc = self.make_sure_var_in_reg(v, [res_v]) assert self.loc(res_v) == eax # now we have to reload length to some reasonable place @@ -765,9 +797,15 @@ return imm(ofs), imm(size), ptr def _common_consider_setfield(self, op, ignored, raw): - base_loc = self.make_sure_var_in_reg(op.args[0], op.args) - value_loc = self.make_sure_var_in_reg(op.args[1], op.args) ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) + assert isinstance(size_loc, IMM32) + if size_loc.value == 1: + need_lower_byte = True + else: + need_lower_byte = False + base_loc = self.make_sure_var_in_reg(op.args[0], op.args) + value_loc = self.make_sure_var_in_reg(op.args[1], op.args, + need_lower_byte=need_lower_byte) if ptr: if raw: print "Setfield of raw structure with gc pointer" @@ -786,7 +824,8 @@ def consider_strsetitem(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) - value_loc = self.make_sure_var_in_reg(op.args[2], op.args) + value_loc = self.make_sure_var_in_reg(op.args[2], op.args, + need_lower_byte=True) self.eventually_free_vars([op.args[0], op.args[1], op.args[2]]) self.PerformDiscard(op, [base_loc, ofs_loc, value_loc]) @@ -795,7 +834,12 @@ def consider_setarrayitem_gc(self, op, ignored): scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) - value_loc = self.make_sure_var_in_reg(op.args[2], op.args) + if scale == 0: + need_lower_byte = True + else: + need_lower_byte = False + value_loc = self.make_sure_var_in_reg(op.args[2], op.args, + need_lower_byte=need_lower_byte) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) if ptr: gc_ll_descr = self.assembler.cpu.gc_ll_descr @@ -826,7 +870,8 @@ def consider_int_is_true(self, op, ignored): argloc = self.make_sure_var_in_reg(op.args[0], []) - resloc = self.force_allocate_reg(op.result, op.args) + resloc = self.force_allocate_reg(op.result, op.args, + need_lower_byte=True) self.eventually_free_var(op.args[0]) self.Perform(op, [argloc], resloc) @@ -843,7 +888,8 @@ else: argloc = self.loc(op.args[0]) self.eventually_free_var(op.args[0]) - resloc = self.force_allocate_reg(op.result, []) + resloc = self.force_allocate_reg(op.result, [], + need_lower_byte=True) self.Perform(op, [argloc], resloc) consider_ooisnull = _consider_nullity @@ -934,7 +980,7 @@ return res def lower_byte(reg): - # argh + # argh, kill, use lowest8bits instead if isinstance(reg, MODRM): return reg if isinstance(reg, IMM32): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Sat Aug 22 13:25:55 2009 @@ -10,7 +10,8 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.annlowlevel import llhelper -from pypy.rpython.lltypesystem import rclass +from pypy.rpython.lltypesystem import rclass, rstr +from pypy.jit.backend.x86.ri386 import * class DummyTree(object): operations = [ResOperation(rop.FAIL, [], None)] @@ -19,6 +20,35 @@ class MockAssembler(object): gcrefs = None + def __init__(self): + self.loads = [] + self.stores = [] + self.performs = [] + self.lea = [] + + def dump(self, *args): + pass + + def regalloc_load(self, from_loc, to_loc): + self.loads.append((from_loc, to_loc)) + + def regalloc_store(self, from_loc, to_loc): + self.stores.append((from_loc, to_loc)) + + def regalloc_perform(self, op, arglocs, resloc): + self.performs.append((op, arglocs, resloc)) + + def regalloc_perform_discard(self, op, arglocs): + self.performs.append((op, arglocs)) + + def load_effective_addr(self, *args): + self.lea.append(args) + +class RegAllocForTests(RegAlloc): + position = 0 + def _compute_next_usage(self, v, _): + return -1 + class TestRegallocDirect(object): def fill_regs(self, regalloc): allboxes = [] @@ -26,6 +56,7 @@ box = BoxInt() allboxes.append(box) regalloc.reg_bindings[box] = reg + regalloc.free_regs = [] return allboxes def test_make_sure_var_in_reg(self): @@ -35,6 +66,69 @@ oldloc = regalloc.loc(box) newloc = regalloc.make_sure_var_in_reg(box, []) assert oldloc is newloc + regalloc._check_invariants() + + def test_make_sure_var_in_reg_need_lower_byte(self): + regalloc = RegAlloc(MockAssembler(), DummyTree()) + box = BoxInt() + regalloc.reg_bindings[box] = edi + regalloc.free_regs.remove(edi) + loc = regalloc.make_sure_var_in_reg(box, [], need_lower_byte=True) + assert loc is not edi and loc is not esi + assert len(regalloc.assembler.loads) == 1 + regalloc._check_invariants() + + def test_make_sure_var_in_reg_need_lower_byte_no_free_reg(self): + regalloc = RegAllocForTests(MockAssembler(), DummyTree()) + box = BoxInt() + regalloc.reg_bindings = {BoxInt(): eax, BoxInt(): ebx, BoxInt(): ecx, + BoxInt(): edx, box:edi} + regalloc.free_regs = [esi] + regalloc._check_invariants() + loc = regalloc.make_sure_var_in_reg(box, [], need_lower_byte=True) + assert loc is not edi and loc is not esi + assert len(regalloc.assembler.loads) == 1 + regalloc._check_invariants() + + def test_make_sure_var_in_reg_mem(self): + regalloc = RegAlloc(MockAssembler(), DummyTree()) + box = BoxInt() + regalloc.stack_loc(box) + loc = regalloc.make_sure_var_in_reg(box, [], need_lower_byte=True) + assert loc is not edi and loc is not esi + assert len(regalloc.assembler.loads) == 1 + regalloc._check_invariants() + + def test_registers_around_call(self): + cpu = CPU(None, None) + regalloc = RegAlloc(MockAssembler(), DummyTree()) + boxes = self.fill_regs(regalloc) + TP = lltype.FuncType([], lltype.Void) + calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT) + regalloc._check_invariants() + box = boxes[0] + for box in boxes: + regalloc.longevity[box] = (0, 1) + regalloc.position = 0 + regalloc.consider_call(ResOperation(rop.CALL, [box], None, calldescr), + None) + assert len(regalloc.assembler.stores) == 3 + regalloc._check_invariants() + + def test_registers_around_newstr(self): + cpu = CPU(None, None) + regalloc = RegAllocForTests(MockAssembler(), DummyTree()) + regalloc.assembler.cpu = cpu + boxes = self.fill_regs(regalloc) + regalloc._check_invariants() + for box in boxes: + regalloc.longevity[box] = (0, 1) + regalloc.position = 0 + resbox = BoxInt() + regalloc.longevity[resbox] = (1, 1) + regalloc.consider_newstr(ResOperation(rop.NEWSTR, [box], resbox, + None), None) + regalloc._check_invariants() class BaseTestRegalloc(object): cpu = CPU(None, None) @@ -327,6 +421,93 @@ self.interpret(ops, [0, 1]) assert self.getint(0) == 0 +class TestRegallocMoreRegisters(BaseTestRegalloc): + + cpu = BaseTestRegalloc.cpu + + S = lltype.GcStruct('S', ('field', lltype.Char)) + fielddescr = cpu.fielddescrof(S, 'field') + + A = lltype.GcArray(lltype.Char) + arraydescr = cpu.arraydescrof(A) + + namespace = locals().copy() + + def test_int_is_true(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7] + i10 = int_is_true(i0) + i11 = int_is_true(i1) + i12 = int_is_true(i2) + i13 = int_is_true(i3) + i14 = int_is_true(i4) + i15 = int_is_true(i5) + i16 = int_is_true(i6) + i17 = int_is_true(i7) + fail(i10, i11, i12, i13, i14, i15, i16, i17) + ''' + self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333]) + assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1] + + def test_comparison_ops(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6] + i10 = int_lt(i0, i1) + i11 = int_le(i2, i3) + i12 = int_ge(i4, i5) + i13 = int_eq(i5, i6) + i14 = int_gt(i6, i2) + i15 = int_ne(i2, i6) + fail(i10, i11, i12, i13, i14, i15) + ''' + self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) + assert self.getints(6) == [1, 1, 0, 0, 1, 1] + + def test_nullity(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6] + i10 = oononnull(i0) + i11 = ooisnull(i1) + i12 = oononnull(i2) + i13 = oononnull(i3) + i14 = ooisnull(i6) + i15 = ooisnull(i5) + fail(i10, i11, i12, i13, i14, i15) + ''' + self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) + assert self.getints(6) == [0, 0, 1, 1, 0, 0] + + def test_strsetitem(self): + ops = ''' + [p0, i] + strsetitem(p0, 1, i) + fail() + ''' + llstr = rstr.mallocstr(10) + self.interpret(ops, [llstr, ord('a')]) + assert llstr.chars[1] == 'a' + + def test_setfield_char(self): + ops = ''' + [p0, i] + setfield_gc(p0, i, descr=fielddescr) + fail() + ''' + s = lltype.malloc(self.S) + self.interpret(ops, [s, ord('a')]) + assert s.field == 'a' + + def test_setarrayitem_gc(self): + ops = ''' + [p0, i] + setarrayitem_gc(p0, 1, i, descr=arraydescr) + fail() + ''' + s = lltype.malloc(self.A, 3) + self.interpret(ops, [s, ord('a')]) + assert s[1] == 'a' + + class GcRootMap(object): def initialize(self): pass From pedronis at codespeak.net Sat Aug 22 15:45:10 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 22 Aug 2009 15:45:10 +0200 (CEST) Subject: [pypy-svn] r67094 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090822134510.4368C168064@codespeak.net> Author: pedronis Date: Sat Aug 22 15:45:09 2009 New Revision: 67094 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: task before I forget Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Sat Aug 22 15:45:09 2009 @@ -96,6 +96,7 @@ - set up test_ll_random to run nightly with x86 backend - update things in metainterp/doc + - compare backend vs gcc quality - make x86 not recompile everything - think about code memory management - inlining on the Python level From arigo at codespeak.net Sun Aug 23 10:29:08 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 10:29:08 +0200 (CEST) Subject: [pypy-svn] r67098 - pypy/build/bot2/pypybuildbot Message-ID: <20090823082908.CD59C1683C6@codespeak.net> Author: arigo Date: Sun Aug 23 10:29:08 2009 New Revision: 67098 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Oups, forgot to update this. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sun Aug 23 10:29:08 2009 @@ -200,7 +200,7 @@ setup_steps(platform, self) - self.addStep(Translate(['--jit', '--gc=boehm'], + self.addStep(Translate(['-Ojit', '--gc=boehm'], ['--withoutmod-thread'])) self.addStep(ShellCmd( From cfbolz at codespeak.net Sun Aug 23 10:47:59 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 23 Aug 2009 10:47:59 +0200 (CEST) Subject: [pypy-svn] r67099 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090823084759.9CD911683E2@codespeak.net> Author: cfbolz Date: Sun Aug 23 10:47:58 2009 New Revision: 67099 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Sun Aug 23 10:47:58 2009 @@ -91,8 +91,7 @@ - more or less full coverage for optimize*.py - add GC tests for x86 backend DONE - - find bug in x86 backend related to GC (Maciek, Armin around) - - make test_ll_random.py a bit better than before SORT-OF-DONE + - find bug in x86 backend related to GC DONE - set up test_ll_random to run nightly with x86 backend - update things in metainterp/doc @@ -100,21 +99,28 @@ - make x86 not recompile everything - think about code memory management - inlining on the Python level - - store sinking (removing consecutive getfields/setfields) STARTED (Armin, Iko) + - store sinking (removing consecutive getfields/setfields) (Iko, Anto) - build a pypy-c-jit from before the sprint for comparison IN-PROGRESS - green virtualizable fields ABANDONED - remove the numerous checks for frame.vable_rti in the - interpreter (non-JITting) part IN-PROGRESS (Carl Friedrich, Samuele) + interpreter (non-JITting) part DONE - parser for the ops files that pypy-c-jit produces DONE - - test the loops that pypy-c-jit produces (Mikke, Benjamin) + - add infrastructure to test the loops that pypy-c-jit produces DONE - kill the minimal backend DONE - getting confused IN-PROGRESS - - fix the CLI backend (Anto) - - fix config tests (Armin, Carl Friedrich around) + - fix the CLI backend DONE + - fix config tests DONE - merge the compiler branch - - general wizardry (Maciek, Bea) + - general wizardry + - change x86 backend to utilize more registers DONE + - look at calls performance? (Samuele, Carl Friedrich) + - fix virtualizable tests (Samuele, Carl Friedrich) + - fix the backend tests (Maciek, Armin, Wyvern around) + - write sprint blog post (Maciek, Carl Friedrich) + - get rid of pups and poshes at the end of the loop in x86 backend (Benjamin, Armin) + Ater the Sprint From benjamin at codespeak.net Sun Aug 23 10:56:27 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 23 Aug 2009 10:56:27 +0200 (CEST) Subject: [pypy-svn] r67100 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823085627.5DA0B1683C6@codespeak.net> Author: benjamin Date: Sun Aug 23 10:56:26 2009 New Revision: 67100 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: remove pointless counter Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sun Aug 23 10:56:26 2009 @@ -932,7 +932,6 @@ # At least it's bug-free (hopefully). We can then go on optimizing # it again. later_pops = [] # pops that will be performed in reverse order - extra_on_stack = 0 loop = op.jump_target for i in range(len(op.args)): arg = op.args[i] @@ -952,7 +951,6 @@ res = stack_pos(res.position) self.assembler.regalloc_push(src) later_pops.append(res) - extra_on_stack += 1 # self.eventually_free_vars(op.args) for i in range(len(later_pops)-1, -1, -1): From pedronis at codespeak.net Sun Aug 23 11:18:33 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 11:18:33 +0200 (CEST) Subject: [pypy-svn] r67101 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090823091833.6232D1683E2@codespeak.net> Author: pedronis Date: Sun Aug 23 11:18:30 2009 New Revision: 67101 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, pedronis) don't repeat the delicate checks in the backend tests Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Sun Aug 23 11:18:30 2009 @@ -735,11 +735,13 @@ assert res == 55 self.check_loops(getfield_gc=0, setfield_gc=0) + from pypy.jit.backend.test.support import BaseCompiledMixin + if isinstance(self, BaseCompiledMixin): + return + t = get_translator() - f_graph = t.graphs[0] - assert f_graph.func is f - portal_graph = t.graphs[-1] - assert portal_graph.func is f + f_graph, portal_graph = [graph for graph in t.graphs + if getattr(graph, 'func', None) is f] init_graph = t._graphof(Frame.__init__.im_func) deref = t.rtyper.type_system_deref From pedronis at codespeak.net Sun Aug 23 11:24:39 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 11:24:39 +0200 (CEST) Subject: [pypy-svn] r67102 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823092439.D824A1683B8@codespeak.net> Author: pedronis Date: Sun Aug 23 11:24:39 2009 New Revision: 67102 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Log: (cfbolz, pedronis) readjust stack aligment computation for Mac OS X Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sun Aug 23 11:24:39 2009 @@ -202,7 +202,7 @@ self.mc2.done() stack_words = regalloc.max_stack_depth # possibly align, e.g. for Mac OS X - RET_BP = 2 # ret ip + bp = 2 words + RET_BP = 5 # ret ip + bp + bx + esi + edi = 5 words stack_words = align_stack_words(stack_words+RET_BP) tree._x86_stack_depth = stack_words-RET_BP for place in self.places_to_patch_framesize: From fijal at codespeak.net Sun Aug 23 11:42:05 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 23 Aug 2009 11:42:05 +0200 (CEST) Subject: [pypy-svn] r67103 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823094205.58B9D168079@codespeak.net> Author: fijal Date: Sun Aug 23 11:42:04 2009 New Revision: 67103 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Log: A tiny performance fix about not using registers for moving away vars. Should not matter too much but at least was easy Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sun Aug 23 11:42:04 2009 @@ -475,8 +475,13 @@ def move_variable_away(self, v, prev_loc): reg = None - loc = self.stack_loc(v) - self.Store(v, prev_loc, loc) + if self.free_regs: + loc = self.free_regs.pop() + self.reg_bindings[v] = loc + self.Load(v, prev_loc, loc) + else: + loc = self.stack_loc(v) + self.Store(v, prev_loc, loc) def force_result_in_reg(self, result_v, v, forbidden_vars): """ Make sure that result is in the same register as v Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Sun Aug 23 11:42:04 2009 @@ -130,6 +130,20 @@ None), None) regalloc._check_invariants() + def test_move_away_does_not_spill(self): + regalloc = RegAlloc(MockAssembler(), DummyTree()) + regalloc.position = 0 + resbox = BoxInt() + box = BoxInt() + regalloc.reg_bindings = {box: eax} + regalloc.free_regs = [ebx, ecx, edx, esi, edi] + regalloc._check_invariants() + regalloc.longevity = {resbox: (0, 1), box: (0, 1)} + regalloc.consider_int_add(ResOperation(rop.INT_ADD, [box, ConstInt(1)], + resbox), None) + regalloc._check_invariants() + assert len(regalloc.assembler.stores) == 0 + class BaseTestRegalloc(object): cpu = CPU(None, None) From iko at codespeak.net Sun Aug 23 12:00:49 2009 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 23 Aug 2009 12:00:49 +0200 (CEST) Subject: [pypy-svn] r67104 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090823100049.5CBD7168079@codespeak.net> Author: iko Date: Sun Aug 23 12:00:48 2009 New Revision: 67104 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, anto) remove duplicate getfields of const Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sun Aug 23 12:00:48 2009 @@ -9,7 +9,7 @@ from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs from pypy.jit.metainterp import resume, compile from pypy.rlib.objectmodel import we_are_translated - +from pypy.rpython.lltypesystem import lltype def optimize_loop_1(cpu, loop): """Optimize loop.operations to make it match the input of loop.specnodes @@ -347,8 +347,29 @@ self.values_to_clean = [] # OptValues to clean when we see an # operation with side-effects self.reached_the_end = False + self.interned_ptrs = {} + self.interned_objs = {} + + def getinterned(self, box): + if not self.cpu.is_oo and isinstance(box, ConstPtr): + key = lltype.cast_ptr_to_int(box.value) + try: + return self.interned_ptrs[key] + except KeyError: + self.interned_ptrs[key] = box + return box + elif self.cpu.is_oo and isinstance(box, ConstObj): + try: + return self.interned_objs[box.value] + except KeyError: + self.interned_objs[box.value] = box + return box + else: + return box + def getvalue(self, box): + box = self.getinterned(box) try: value = self.values[box] except KeyError: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sun Aug 23 12:00:48 2009 @@ -1004,7 +1004,6 @@ self.optimize_loop(ops, 'Not', expected) def test_duplicate_getfield_constant(self): - py.test.skip("maybe implement later") ops = """ [] i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) From arigo at codespeak.net Sun Aug 23 12:10:02 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 12:10:02 +0200 (CEST) Subject: [pypy-svn] r67105 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823101002.2EE381680AF@codespeak.net> Author: arigo Date: Sun Aug 23 12:10:01 2009 New Revision: 67105 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: Kill outdated comment. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sun Aug 23 12:10:01 2009 @@ -12,8 +12,6 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop -# esi edi and ebx can be added to this list, provided they're correctly -# saved and restored REGS = [eax, ecx, edx, ebx, esi, edi] WORD = 4 From arigo at codespeak.net Sun Aug 23 12:18:01 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 12:18:01 +0200 (CEST) Subject: [pypy-svn] r67106 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823101801.E22BD168076@codespeak.net> Author: arigo Date: Sun Aug 23 12:17:57 2009 New Revision: 67106 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: Fix a bug. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sun Aug 23 12:17:57 2009 @@ -235,6 +235,7 @@ self.mc.PUSH(ebx) self.mc.PUSH(esi) self.mc.PUSH(edi) + # NB. exactly 4 pushes above; if this changes, fix stack_pos(). self.mc.SUB(esp, imm(framesize * WORD)) for i in range(len(arglocs)): loc = arglocs[i] Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sun Aug 23 12:17:57 2009 @@ -976,7 +976,11 @@ oplist[num] = value def stack_pos(i): - res = mem(ebp, -WORD * (1 + i)) + # Argument is a stack position (0, 1, 2...). + # Returns (ebp-16), (ebp-20), (ebp-24)... + # This depends on the fact that our function prologue contains + # exactly 4 PUSHes. + res = mem(ebp, -WORD * (4 + i)) res.position = i return res From arigo at codespeak.net Sun Aug 23 12:22:39 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 12:22:39 +0200 (CEST) Subject: [pypy-svn] r67107 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823102239.42F1F168097@codespeak.net> Author: arigo Date: Sun Aug 23 12:22:38 2009 New Revision: 67107 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Log: Also fix gc.py. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sun Aug 23 12:22:38 2009 @@ -236,6 +236,7 @@ self.mc.PUSH(esi) self.mc.PUSH(edi) # NB. exactly 4 pushes above; if this changes, fix stack_pos(). + # You must also keep _get_callshape() in sync. self.mc.SUB(esp, imm(framesize * WORD)) for i in range(len(arglocs)): loc = arglocs[i] Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Sun Aug 23 12:22:38 2009 @@ -232,14 +232,11 @@ return self._compress_callshape(shape) def _get_callshape(self, gclocs): - # The return address is always found at 4(%ebp); and - # the three registers %ebx, %esi, %edi are not used at all - # so far, so their value always comes from the caller. - shape = [self.LOC_EBP_BASED | 4, - self.LOC_REG | 0, - self.LOC_REG | 4, - self.LOC_REG | 8, - self.LOC_EBP_BASED | 0, + shape = [self.LOC_EBP_BASED | 4, # return addr: at 4(%ebp) + self.LOC_EBP_BASED | (-4), # saved %ebx: at -4(%ebp) + self.LOC_EBP_BASED | (-8), # saved %esi: at -8(%ebp) + self.LOC_EBP_BASED | (-12), # saved %edi: at -12(%ebp) + self.LOC_EBP_BASED | 0, # saved %ebp: at (%ebp) 0] for loc in gclocs: assert isinstance(loc, MODRM) From iko at codespeak.net Sun Aug 23 12:45:55 2009 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 23 Aug 2009 12:45:55 +0200 (CEST) Subject: [pypy-svn] r67108 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090823104555.7FE121683B8@codespeak.net> Author: iko Date: Sun Aug 23 12:45:54 2009 New Revision: 67108 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, anto) also remove duplicate getfield for boxes which the optimzer finds to be constant. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sun Aug 23 12:45:54 2009 @@ -1,5 +1,5 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj -from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj +from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode @@ -351,18 +351,22 @@ self.interned_objs = {} def getinterned(self, box): - if not self.cpu.is_oo and isinstance(box, ConstPtr): - key = lltype.cast_ptr_to_int(box.value) + if not self.is_constant(box): + return box + if not self.cpu.is_oo and box.type == PTR: + value = box.getptr_base() + key = lltype.cast_ptr_to_int(value) try: return self.interned_ptrs[key] except KeyError: self.interned_ptrs[key] = box return box - elif self.cpu.is_oo and isinstance(box, ConstObj): + elif self.cpu.is_oo and box.type == OBJ: + value = box.getobj() try: - return self.interned_objs[box.value] + return self.interned_objs[value] except KeyError: - self.interned_objs[box.value] = box + self.interned_objs[value] = box return box else: return box Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sun Aug 23 12:45:54 2009 @@ -1021,6 +1021,28 @@ """ self.optimize_loop(ops, '', expected) + def test_duplicate_getfield_guard_value_const(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + i1 = getfield_gc(p1, descr=valuedescr) + i2 = getfield_gc(ConstPtr(myptr), descr=valuedescr) + escape(i1) + escape(i2) + jump(p1) + """ + expected = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) + escape(i1) + escape(i1) + jump(ConstPtr(myptr)) + """ + self.optimize_loop(ops, 'Not', expected, p1=self.nodebox.value) + def test_duplicate_getfield_sideeffects_1(self): ops = """ [p1] From pedronis at codespeak.net Sun Aug 23 12:48:45 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 12:48:45 +0200 (CEST) Subject: [pypy-svn] r67109 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090823104845.8FFE0168075@codespeak.net> Author: pedronis Date: Sun Aug 23 12:48:44 2009 New Revision: 67109 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, pedronis) passing test about virtualizable virtually created in the scope of another one Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Sun Aug 23 12:48:44 2009 @@ -759,6 +759,38 @@ assert direct_calls(init_graph) == [] + def test_virtual_child_frame(self): + myjitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + + def __init__(self, x, y): + self = hint(self, access_directly=True) + self.x = x + self.y = y + + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def f(n): + frame = Frame(n, 0) + somewhere_else.top_frame = frame # escapes + frame = hint(frame, access_directly=True) + while frame.x > 0: + myjitdriver.can_enter_jit(frame=frame) + myjitdriver.jit_merge_point(frame=frame) + child_frame = Frame(frame.x, 1) + frame.y += child_frame.x + frame.x -= 1 + return somewhere_else.top_frame.y + + res = self.meta_interp(f, [10]) + assert res == 55 + self.check_loops(new_with_vtable=0) + class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): From pedronis at codespeak.net Sun Aug 23 12:59:52 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 12:59:52 +0200 (CEST) Subject: [pypy-svn] r67110 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090823105952.38F3E1680AB@codespeak.net> Author: pedronis Date: Sun Aug 23 12:59:51 2009 New Revision: 67110 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, pedronis) wip test about frame construction Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Sun Aug 23 12:59:51 2009 @@ -791,6 +791,39 @@ assert res == 55 self.check_loops(new_with_vtable=0) + def test_virtual_child_frame_with_arrays(self): + py.test.skip("WIP") + myjitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x[*]'] + + #@dont_look_inside + def __init__(self, x, y): + self = hint(self, access_directly=True) + self.x = [x, y] + + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def f(n): + frame = Frame(n, 0) + somewhere_else.top_frame = frame # escapes + frame = hint(frame, access_directly=True) + while frame.x[0] > 0: + myjitdriver.can_enter_jit(frame=frame) + myjitdriver.jit_merge_point(frame=frame) + child_frame = Frame(frame.x[0], 1) + frame.x[1] += child_frame.x[0] + frame.x[0] -= 1 + return somewhere_else.top_frame.x[1] + + res = self.meta_interp(f, [10], listops=True) + assert res == 55 + self.check_loops(new_with_vtable=0) + class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): From arigo at codespeak.net Sun Aug 23 14:16:07 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 14:16:07 +0200 (CEST) Subject: [pypy-svn] r67111 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823121607.93902168077@codespeak.net> Author: arigo Date: Sun Aug 23 14:16:06 2009 New Revision: 67111 Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (contents, props changed) pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (contents, props changed) Log: (benjamin, arigo) Start writing a better remapper of stack locations at JUMPs. We are thinking about copying remap_stack_layout() from pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/regalloc.py at 57000. Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 14:16:06 2009 @@ -0,0 +1,4 @@ + + +def remap_stack_layout(assembler, src_locations, dst_locations): + pass Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 14:16:06 2009 @@ -0,0 +1,20 @@ +from pypy.jit.backend.x86.ri386 import * +from pypy.jit.backend.x86.jump import remap_stack_layout + +class MockAssembler: + def __init__(self): + self.ops = [] + +def test_trivial(): + assembler = MockAssembler() + remap_stack_layout(assembler, [], []) + assert assembler.ops == [] + remap_stack_layout(assembler, [eax, ebx, ecx, edx, esi, edi], + [eax, ebx, ecx, edx, esi, edi]) + assert assembler.ops == [] + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + remap_stack_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], + [eax, ebx, ecx, s20, s8, edx, s12, esi, edi]) + assert assembler.ops == [] From arigo at codespeak.net Sun Aug 23 14:26:28 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 14:26:28 +0200 (CEST) Subject: [pypy-svn] r67112 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823122628.325391680AB@codespeak.net> Author: arigo Date: Sun Aug 23 14:26:26 2009 New Revision: 67112 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Implement simple register moving. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 14:26:26 2009 @@ -1,4 +1,8 @@ def remap_stack_layout(assembler, src_locations, dst_locations): - pass + for i in range(len(dst_locations)): + src = src_locations[i] + dst = dst_locations[i] + if src is not dst: + assembler.regalloc_load(src, dst) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 14:26:26 2009 @@ -5,6 +5,13 @@ def __init__(self): self.ops = [] + def regalloc_load(self, from_loc, to_loc): + self.ops.append(('load', from_loc, to_loc)) + + def regalloc_store(self, from_loc, to_loc): + self.ops.append(('store', from_loc, to_loc)) + + def test_trivial(): assembler = MockAssembler() remap_stack_layout(assembler, [], []) @@ -18,3 +25,10 @@ remap_stack_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], [eax, ebx, ecx, s20, s8, edx, s12, esi, edi]) assert assembler.ops == [] + +def test_simple_registers(): + assembler = MockAssembler() + remap_stack_layout(assembler, [eax, ebx, ecx], [edx, esi, edi]) + assert assembler.ops == [('load', eax, edx), + ('load', ebx, esi), + ('load', ecx, edi)] From arigo at codespeak.net Sun Aug 23 14:43:00 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 14:43:00 +0200 (CEST) Subject: [pypy-svn] r67113 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823124300.45DC01680C1@codespeak.net> Author: arigo Date: Sun Aug 23 14:42:59 2009 New Revision: 67113 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Handle simple stack moves. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 14:42:59 2009 @@ -1,8 +1,16 @@ +from pypy.jit.backend.x86.ri386 import MODRM -def remap_stack_layout(assembler, src_locations, dst_locations): +def remap_stack_layout(assembler, src_locations, dst_locations, free_regs=[]): for i in range(len(dst_locations)): src = src_locations[i] dst = dst_locations[i] if src is not dst: - assembler.regalloc_load(src, dst) + if isinstance(dst, MODRM): + if isinstance(src, MODRM): + tmp = free_regs[0] + assembler.regalloc_load(src, tmp) + src = tmp + assembler.regalloc_store(src, dst) + else: + assembler.regalloc_load(src, dst) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 14:42:59 2009 @@ -32,3 +32,15 @@ assert assembler.ops == [('load', eax, edx), ('load', ebx, esi), ('load', ecx, edi)] + +def test_simple_stacklocs(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], [edx, esi]) + assert assembler.ops == [('load', s8, edx), + ('store', edx, s20), + ('store', eax, s24), + ('load', s12, edi)] From arigo at codespeak.net Sun Aug 23 14:52:07 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 14:52:07 +0200 (CEST) Subject: [pypy-svn] r67114 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823125207.C607B168097@codespeak.net> Author: arigo Date: Sun Aug 23 14:52:06 2009 New Revision: 67114 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Push and pop a random register if needed. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 14:52:06 2009 @@ -1,16 +1,24 @@ -from pypy.jit.backend.x86.ri386 import MODRM +from pypy.jit.backend.x86.ri386 import MODRM, eax def remap_stack_layout(assembler, src_locations, dst_locations, free_regs=[]): + pending_pops = [] for i in range(len(dst_locations)): src = src_locations[i] dst = dst_locations[i] if src is not dst: if isinstance(dst, MODRM): if isinstance(src, MODRM): - tmp = free_regs[0] + if free_regs: + tmp = free_regs[0] + else: + assembler.regalloc_push(eax) + pending_pops.append(eax) + tmp = eax assembler.regalloc_load(src, tmp) src = tmp assembler.regalloc_store(src, dst) else: assembler.regalloc_load(src, dst) + for reg in pending_pops: + assembler.regalloc_pop(reg) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 14:52:06 2009 @@ -11,6 +11,12 @@ def regalloc_store(self, from_loc, to_loc): self.ops.append(('store', from_loc, to_loc)) + def regalloc_push(self, loc): + self.ops.append(('push', loc)) + + def regalloc_pop(self, loc): + self.ops.append(('pop', loc)) + def test_trivial(): assembler = MockAssembler() @@ -44,3 +50,17 @@ ('store', edx, s20), ('store', eax, s24), ('load', s12, edi)] + +def test_simple_stacklocs_no_free_reg(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + remap_stack_layout(assembler, [s8, ebx, s12], [s20, s24, edi], []) + assert assembler.ops == [('push', eax), + ('load', s8, eax), + ('store', eax, s20), + ('store', ebx, s24), + ('load', s12, edi), + ('pop', eax)] From arigo at codespeak.net Sun Aug 23 15:09:55 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 15:09:55 +0200 (CEST) Subject: [pypy-svn] r67115 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823130955.686951680A3@codespeak.net> Author: arigo Date: Sun Aug 23 15:09:54 2009 New Revision: 67115 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Deal with: no free regs and eax is a source. Add a code comparison function to the test. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 15:09:54 2009 @@ -1,24 +1,26 @@ -from pypy.jit.backend.x86.ri386 import MODRM, eax +from pypy.jit.backend.x86.ri386 import * def remap_stack_layout(assembler, src_locations, dst_locations, free_regs=[]): - pending_pops = [] + pushed_eax = False for i in range(len(dst_locations)): src = src_locations[i] dst = dst_locations[i] if src is not dst: + if pushed_eax and src is eax: + assembler.regalloc_load(mem(esp, 0), src) if isinstance(dst, MODRM): if isinstance(src, MODRM): if free_regs: tmp = free_regs[0] else: assembler.regalloc_push(eax) - pending_pops.append(eax) + pushed_eax = True tmp = eax assembler.regalloc_load(src, tmp) src = tmp assembler.regalloc_store(src, dst) else: assembler.regalloc_load(src, dst) - for reg in pending_pops: - assembler.regalloc_pop(reg) + if pushed_eax: + assembler.regalloc_pop(eax) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 15:09:54 2009 @@ -17,6 +17,22 @@ def regalloc_pop(self, loc): self.ops.append(('pop', loc)) + def got(self, expected): + print '------------------------ comparing ---------------------------' + for op1, op2 in zip(self.ops, expected): + print '%-38s| %-38s' % (op1, op2) + if op1 == op2: + continue + assert len(op1) == len(op2) + for x, y in zip(op1, op2): + if isinstance(x, MODRM) and isinstance(y, MODRM): + assert x.byte == y.byte + assert x.extradata == y.extradata + else: + assert x == y + assert len(self.ops) == len(expected) + return True + def test_trivial(): assembler = MockAssembler() @@ -64,3 +80,19 @@ ('store', ebx, s24), ('load', s12, edi), ('pop', eax)] + +def test_simple_stacklocs_no_free_reg_2(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + p0 = mem(esp, 0) + remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], []) + assert assembler.got([('push', eax), + ('load', s8, eax), + ('store', eax, s20), + ('load', p0, eax), + ('store', eax, s24), + ('load', s12, edi), + ('pop', eax)]) From arigo at codespeak.net Sun Aug 23 15:27:32 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 15:27:32 +0200 (CEST) Subject: [pypy-svn] r67116 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823132732.72F9F168054@codespeak.net> Author: arigo Date: Sun Aug 23 15:27:31 2009 New Revision: 67116 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Handle the case where dst is eax (and eax was needed before as a temporary location). Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sun Aug 23 15:27:31 2009 @@ -290,6 +290,9 @@ def regalloc_pop(self, loc): self.mc.POP(loc) + def regalloc_stackdiscard(self, count): + self.mc.ADD(esp, imm(WORD * count)) + def regalloc_perform(self, op, arglocs, resloc): genop_list[op.opnum](self, op, arglocs, resloc) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 15:27:31 2009 @@ -14,13 +14,17 @@ if free_regs: tmp = free_regs[0] else: - assembler.regalloc_push(eax) - pushed_eax = True + if not pushed_eax: + assembler.regalloc_push(eax) + pushed_eax = True tmp = eax assembler.regalloc_load(src, tmp) src = tmp assembler.regalloc_store(src, dst) else: assembler.regalloc_load(src, dst) + if pushed_eax and dst is eax: + assembler.regalloc_stackdiscard(1) + pushed_eax = False if pushed_eax: assembler.regalloc_pop(eax) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 15:27:31 2009 @@ -17,6 +17,9 @@ def regalloc_pop(self, loc): self.ops.append(('pop', loc)) + def regalloc_stackdiscard(self, count): + self.ops.append(('stackdiscard', count)) + def got(self, expected): print '------------------------ comparing ---------------------------' for op1, op2 in zip(self.ops, expected): @@ -96,3 +99,66 @@ ('store', eax, s24), ('load', s12, edi), ('pop', eax)]) + +def test_simple_stacklocs_no_free_reg_3(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + p0 = mem(esp, 0) + remap_stack_layout(assembler, [s8, ecx, s12], [s20, s24, eax], []) + assert assembler.got([('push', eax), + ('load', s8, eax), + ('store', eax, s20), + ('store', ecx, s24), + ('load', s12, eax), + ('stackdiscard', 1)]) + +def test_simple_stacklocs_no_free_reg_4(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + p0 = mem(esp, 0) + remap_stack_layout(assembler, [s12, s24], [s8, s20], []) + assert assembler.got([('push', eax), + ('load', s12, eax), + ('store', eax, s8), + ('load', s24, eax), + ('store', eax, s20), + ('pop', eax)]) + +def test_simple_stacklocs_no_free_reg_5(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + p0 = mem(esp, 0) + remap_stack_layout(assembler, [s12, s24], [eax, s20], []) + assert assembler.got([('load', s12, eax), + ('push', eax), + ('load', s24, eax), + ('store', eax, s20), + ('pop', eax)]) + +def test_simple_stacklocs_no_free_reg_6(): + assembler = MockAssembler() + s8 = mem(ebp, -8) + s12 = mem(ebp, -12) + s20 = mem(ebp, -20) + s24 = mem(ebp, -24) + s28 = mem(ebp, -28) + p0 = mem(esp, 0) + remap_stack_layout(assembler, [s8, s12, s24], [s28, eax, s20], []) + assert assembler.got([('push', eax), + ('load', s8, eax), + ('store', eax, s28), + ('load', s12, eax), + ('stackdiscard', 1), + ('push', eax), + ('load', s24, eax), + ('store', eax, s20), + ('pop', eax)]) From pedronis at codespeak.net Sun Aug 23 15:28:54 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 15:28:54 +0200 (CEST) Subject: [pypy-svn] r67117 - in pypy/branch/pyjitpl5/pypy: jit/metainterp/test rpython rpython/lltypesystem rpython/test Message-ID: <20090823132854.9A017168054@codespeak.net> Author: pedronis Date: Sun Aug 23 15:28:53 2009 New Revision: 67117 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/opimpl.py pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, pedronis) always insert promote_virtualizable to remember the instance flags, conversion to a call or removal is postponed to the replace phase Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Sun Aug 23 15:28:53 2009 @@ -1,4 +1,5 @@ import py +from pypy.rpython.extregistry import ExtRegistryEntry from pypy.rpython.lltypesystem import lltype, lloperation, rclass, llmemory from pypy.rpython.annlowlevel import llhelper from pypy.jit.metainterp.policy import StopAtXPolicy @@ -11,7 +12,25 @@ from pypy.jit.metainterp import history, heaptracker, simple_optimize from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin -promote_virtualizable = lloperation.llop.promote_virtualizable +def promote_virtualizable(*args): + pass +class Entry(ExtRegistryEntry): + "Annotation and rtyping of LLOp instances, which are callable." + _about_ = promote_virtualizable + + def compute_result_annotation(self, *args): + from pypy.annotation.model import lltype_to_annotation + return lltype_to_annotation(lltype.Void) + + def specialize_call(self, hop): + op = self.instance # the LLOp object that was called + args_v = [hop.inputarg(hop.args_r[0], 0), + hop.inputconst(lltype.Void, hop.args_v[1].value), + hop.inputconst(lltype.Void, {})] + hop.exception_cannot_occur() + return hop.genop('promote_virtualizable', + args_v, resulttype=lltype.Void) + debug_print = lloperation.llop.debug_print # ____________________________________________________________ @@ -50,7 +69,7 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n) myjitdriver.jit_merge_point(xy=xy, n=n) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') x = xy.inst_x xy.inst_x = x + 1 n -= 1 @@ -69,11 +88,11 @@ myjitdriver.can_enter_jit(xy=xy, n=n) myjitdriver.jit_merge_point(xy=xy, n=n) if n > 0: - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') x = xy.inst_x xy.inst_x = x + 1 else: - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') x = xy.inst_x xy.inst_x = x + 10 n -= 1 @@ -92,7 +111,7 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n) myjitdriver.jit_merge_point(xy=xy, n=n) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') x = xy.inst_x if n <= 10: x += 1000 @@ -110,7 +129,7 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n) myjitdriver.jit_merge_point(xy=xy, n=n) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x += 1 n -= 1 def f(n): @@ -135,7 +154,7 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n, m=m) myjitdriver.jit_merge_point(xy=xy, n=n, m=m) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') x = xy.inst_x xy.inst_x = x + 1 m = (m+1) & 3 # the loop gets unrolled 4 times @@ -163,10 +182,10 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n, other=other) myjitdriver.jit_merge_point(xy=xy, n=n, other=other) - promote_virtualizable(lltype.Void, other, 'inst_x') + promote_virtualizable(other, 'inst_x') value = other.inst_x # getfield_gc other.inst_x = value + 1 # setfield_gc - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x = value + 100 # virtualized away n -= 1 return xy.inst_x @@ -182,7 +201,7 @@ outer = Outer() def ext(): xy = outer.xy - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x + 2 def f(n): xy = self.setup() @@ -192,10 +211,10 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n, m=m) myjitdriver.jit_merge_point(xy=xy, n=n, m=m) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x = n + 9998 # virtualized away m += ext() # 2x setfield_gc, 2x getfield_gc - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x = 10 # virtualized away n -= 1 return m @@ -214,7 +233,7 @@ outer = Outer() def ext(): xy = outer.xy - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x += 2 def f(n): xy = self.setup() @@ -224,10 +243,10 @@ while n > 0: myjitdriver.can_enter_jit(xy=xy, n=n, m=m) myjitdriver.jit_merge_point(xy=xy, n=n, m=m) - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x = n + 9998 # virtualized away ext() # 2x setfield_gc, 2x getfield_gc - promote_virtualizable(lltype.Void, xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') m += xy.inst_x # virtualized away n -= 1 return m @@ -394,11 +413,11 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n, other=other) myjitdriver.jit_merge_point(xy2=xy2, n=n, other=other) - promote_virtualizable(lltype.Void, other, 'inst_l2') + promote_virtualizable(other, 'inst_l2') length = len(other.inst_l2) # getfield_gc/arraylen_gc value = other.inst_l2[0] # getfield_gc/getarrayitem_gc other.inst_l2[0] = value + length # getfield_gc/setarrayitem_gc - promote_virtualizable(lltype.Void, xy2, 'inst_l2') + promote_virtualizable(xy2, 'inst_l2') xy2.inst_l2[0] = value + 100 # virtualized away n -= 1 return xy2.inst_l2[0] Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/opimpl.py Sun Aug 23 15:28:53 2009 @@ -382,7 +382,7 @@ print arg, print -def op_promote_virtualizable(object, fieldname): +def op_promote_virtualizable(object, fieldname, flags): pass # XXX should do something # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py Sun Aug 23 15:28:53 2009 @@ -48,9 +48,10 @@ return vptr def hook_access_field(self, vinst, cname, llops, flags): - if not flags.get('access_directly'): - if cname.value in self.my_redirected_fields: - llops.genop('promote_virtualizable', [vinst, cname]) + #if not flags.get('access_directly'): + if cname.value in self.my_redirected_fields: + cflags = inputconst(lltype.Void, flags) + llops.genop('promote_virtualizable', [vinst, cname, cflags]) def replace_promote_virtualizable_with_call(graphs, VTYPEPTR, funcptr): @@ -59,13 +60,18 @@ count = 0 for graph in graphs: for block in graph.iterblocks(): + newoplist = [] for i, op in enumerate(block.operations): if (op.opname == 'promote_virtualizable' and match_virtualizable_type(op.args[0].concretetype, VTYPEPTR)): + if op.args[-1].value.get('access_directly', False): + continue op.opname = 'direct_call' op.args = [c_funcptr, op.args[0]] count += 1 + newoplist.append(op) + block.operations = newoplist log("replaced %d 'promote_virtualizable' with %r" % (count, funcptr)) def match_virtualizable_type(TYPE, VTYPEPTR): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Sun Aug 23 15:28:53 2009 @@ -26,6 +26,13 @@ def __init__(self, v0): self.v0 = v0 +def get_promote_virtualizable_flags(graph): + res = [] + for block, op in graph.iterblockops(): + if op.opname == 'promote_virtualizable': + res.append(op.args[-1].value) + return res + class BaseTest(BaseRtypingTest): def test_generate_promote_virtualizable(self): def fn(n): @@ -39,6 +46,7 @@ v_inst = op_getfield.args[0] assert op_promote.opname == 'promote_virtualizable' assert op_promote.args[0] is v_inst + assert op_promote.args[-1].value == {} def test_no_promote_virtualizable_for_other_fields(self): def fn(n): @@ -65,6 +73,7 @@ v_inst = op_getfield.args[0] assert op_promote.opname == 'promote_virtualizable' assert op_promote.args[0] is v_inst + assert op_promote.args[-1].value == {} def test_accessor(self): class Base(object): @@ -99,18 +108,16 @@ TYPE = self.gettype(w_inst) assert 'virtualizable2_accessor' not in TYPE._hints - def test_replace_promote_virtualizable_with_call(self): - def fn(n): - vinst = V(n) - return vinst.v - _, rtyper, graph = self.gengraph(fn, [int]) - block = graph.startblock - op_getfield = block.operations[-1] - assert op_getfield.opname in ('getfield', 'oogetfield') - v_inst_ll_type = op_getfield.args[0].concretetype - # + def replace_promote_virtualizable(self, rtyper, graphs): from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator + graph = graphs[0] + + for block, op in graph.iterblockops(): + if op.opname == 'promote_virtualizable': + v_inst_ll_type = op.args[0].concretetype + break + def mycall(vinst_ll): pass annhelper = MixLevelHelperAnnotator(rtyper) @@ -120,9 +127,19 @@ s_vinst = annmodel.SomeOOInstance(v_inst_ll_type) funcptr = annhelper.delayedfunction(mycall, [s_vinst], annmodel.s_None) annhelper.finish() - replace_promote_virtualizable_with_call([graph], v_inst_ll_type, + replace_promote_virtualizable_with_call(graphs, v_inst_ll_type, funcptr) - # + return funcptr + + def test_replace_promote_virtualizable_with_call(self): + def fn(n): + vinst = V(n) + return vinst.v + _, rtyper, graph = self.gengraph(fn, [int]) + block = graph.startblock + op_getfield = block.operations[-1] + assert op_getfield.opname in ('getfield', 'oogetfield') + funcptr = self.replace_promote_virtualizable(rtyper, [graph]) op_promote = block.operations[-2] op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') @@ -141,6 +158,11 @@ t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(g) + + expected = [{'access_directly': True}] + assert get_promote_virtualizable_flags(g_graph) == expected + + self.replace_promote_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 1} res = self.interpret(f, [23]) @@ -162,7 +184,15 @@ assert len(g_graphs) == 2 g_graphs.sort() assert g_graphs[0][0] is None - assert summary(g_graphs[0][1]) == {'promote_virtualizable': 1, self.GETFIELD: 1} + + assert get_promote_virtualizable_flags(g_graphs[0][1]) == [{}] + expected = [{'access_directly': True}] + assert get_promote_virtualizable_flags(g_graphs[1][1]) == expected + + self.replace_promote_virtualizable(typer, [g_graphs[0][1], + g_graphs[1][1]]) + + assert summary(g_graphs[0][1]) == {'direct_call': 1, self.GETFIELD: 1} assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} res = self.interpret(f, [23]) @@ -196,6 +226,7 @@ h_graph = t._graphof(h) assert summary(h_graph) == {'promote_virtualizable': 1, self.GETFIELD: 1} + assert get_promote_virtualizable_flags(h_graph) == [{}] res = self.interpret(f, [23]) assert res == 23 @@ -220,6 +251,9 @@ t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(A.g.im_func) + + self.replace_promote_virtualizable(typer, [g_graph]) + assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} res = self.interpret(f, [23]) From arigo at codespeak.net Sun Aug 23 16:15:48 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 16:15:48 +0200 (CEST) Subject: [pypy-svn] r67118 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823141548.8942D168072@codespeak.net> Author: arigo Date: Sun Aug 23 16:15:47 2009 New Revision: 67118 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo, fijal) Delete logic to fetch a temporary register. Instead, we assume that such a temporary register is passed from outside (as might be the case from regalloc.py). Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 16:15:47 2009 @@ -1,30 +1,15 @@ from pypy.jit.backend.x86.ri386 import * -def remap_stack_layout(assembler, src_locations, dst_locations, free_regs=[]): - pushed_eax = False +def remap_stack_layout(assembler, src_locations, dst_locations, tmpreg): for i in range(len(dst_locations)): src = src_locations[i] dst = dst_locations[i] if src is not dst: - if pushed_eax and src is eax: - assembler.regalloc_load(mem(esp, 0), src) if isinstance(dst, MODRM): if isinstance(src, MODRM): - if free_regs: - tmp = free_regs[0] - else: - if not pushed_eax: - assembler.regalloc_push(eax) - pushed_eax = True - tmp = eax - assembler.regalloc_load(src, tmp) - src = tmp + assembler.regalloc_load(src, tmpreg) + src = tmpreg assembler.regalloc_store(src, dst) else: assembler.regalloc_load(src, dst) - if pushed_eax and dst is eax: - assembler.regalloc_stackdiscard(1) - pushed_eax = False - if pushed_eax: - assembler.regalloc_pop(eax) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 16:15:47 2009 @@ -17,9 +17,6 @@ def regalloc_pop(self, loc): self.ops.append(('pop', loc)) - def regalloc_stackdiscard(self, count): - self.ops.append(('stackdiscard', count)) - def got(self, expected): print '------------------------ comparing ---------------------------' for op1, op2 in zip(self.ops, expected): @@ -39,21 +36,22 @@ def test_trivial(): assembler = MockAssembler() - remap_stack_layout(assembler, [], []) + remap_stack_layout(assembler, [], [], '?') assert assembler.ops == [] remap_stack_layout(assembler, [eax, ebx, ecx, edx, esi, edi], - [eax, ebx, ecx, edx, esi, edi]) + [eax, ebx, ecx, edx, esi, edi], '?') assert assembler.ops == [] s8 = mem(ebp, -8) s12 = mem(ebp, -12) s20 = mem(ebp, -20) remap_stack_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], - [eax, ebx, ecx, s20, s8, edx, s12, esi, edi]) + [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], + '?') assert assembler.ops == [] def test_simple_registers(): assembler = MockAssembler() - remap_stack_layout(assembler, [eax, ebx, ecx], [edx, esi, edi]) + remap_stack_layout(assembler, [eax, ebx, ecx], [edx, esi, edi], '?') assert assembler.ops == [('load', eax, edx), ('load', ebx, esi), ('load', ecx, edi)] @@ -64,101 +62,8 @@ s12 = mem(ebp, -12) s20 = mem(ebp, -20) s24 = mem(ebp, -24) - remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], [edx, esi]) + remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], edx) assert assembler.ops == [('load', s8, edx), ('store', edx, s20), ('store', eax, s24), ('load', s12, edi)] - -def test_simple_stacklocs_no_free_reg(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - remap_stack_layout(assembler, [s8, ebx, s12], [s20, s24, edi], []) - assert assembler.ops == [('push', eax), - ('load', s8, eax), - ('store', eax, s20), - ('store', ebx, s24), - ('load', s12, edi), - ('pop', eax)] - -def test_simple_stacklocs_no_free_reg_2(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - p0 = mem(esp, 0) - remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], []) - assert assembler.got([('push', eax), - ('load', s8, eax), - ('store', eax, s20), - ('load', p0, eax), - ('store', eax, s24), - ('load', s12, edi), - ('pop', eax)]) - -def test_simple_stacklocs_no_free_reg_3(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - p0 = mem(esp, 0) - remap_stack_layout(assembler, [s8, ecx, s12], [s20, s24, eax], []) - assert assembler.got([('push', eax), - ('load', s8, eax), - ('store', eax, s20), - ('store', ecx, s24), - ('load', s12, eax), - ('stackdiscard', 1)]) - -def test_simple_stacklocs_no_free_reg_4(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - p0 = mem(esp, 0) - remap_stack_layout(assembler, [s12, s24], [s8, s20], []) - assert assembler.got([('push', eax), - ('load', s12, eax), - ('store', eax, s8), - ('load', s24, eax), - ('store', eax, s20), - ('pop', eax)]) - -def test_simple_stacklocs_no_free_reg_5(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - p0 = mem(esp, 0) - remap_stack_layout(assembler, [s12, s24], [eax, s20], []) - assert assembler.got([('load', s12, eax), - ('push', eax), - ('load', s24, eax), - ('store', eax, s20), - ('pop', eax)]) - -def test_simple_stacklocs_no_free_reg_6(): - assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) - s28 = mem(ebp, -28) - p0 = mem(esp, 0) - remap_stack_layout(assembler, [s8, s12, s24], [s28, eax, s20], []) - assert assembler.got([('push', eax), - ('load', s8, eax), - ('store', eax, s28), - ('load', s12, eax), - ('stackdiscard', 1), - ('push', eax), - ('load', s24, eax), - ('store', eax, s20), - ('pop', eax)]) From iko at codespeak.net Sun Aug 23 17:15:25 2009 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 23 Aug 2009 17:15:25 +0200 (CEST) Subject: [pypy-svn] r67120 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090823151525.5549C16805D@codespeak.net> Author: iko Date: Sun Aug 23 17:15:24 2009 New Revision: 67120 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, anto, armin around) introduce constant spec node to store exact known value of constant instance nodes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Sun Aug 23 17:15:24 2009 @@ -1,9 +1,10 @@ from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode -from pypy.jit.metainterp.history import AbstractValue, ConstInt +from pypy.jit.metainterp.history import AbstractValue, ConstInt, Const from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs @@ -29,6 +30,8 @@ origfields = None # optimization; equivalent to an empty dict curfields = None # optimization; equivalent to an empty dict + knownvaluebox = None # Used to store value of this box if constant + # fields used to store the shape of the potential VirtualList arraydescr = None # set only on freshly-allocated or fromstart arrays #arraysize = .. # valid if and only if arraydescr is not None @@ -106,6 +109,12 @@ self.nodes = {} # Box -> InstanceNode def getnode(self, box): + if isinstance(box, Const): + node = InstanceNode() + node.unique = UNIQUE_NO + node.knownvaluebox = box + self.nodes[box] = node + return node return self.nodes.get(box, self.node_escaped) def find_nodes(self, operations): @@ -157,6 +166,10 @@ if instnode.fromstart: # only useful in this case instnode.knownclsbox = op.args[1] + def find_nodes_GUARD_VALUE(self, op): + instnode = self.getnode(op.args[0]) + instnode.knownvaluebox = op.args[1] + def find_nodes_SETFIELD_GC(self, op): instnode = self.getnode(op.args[0]) fieldnode = self.getnode(op.args[1]) @@ -282,6 +295,9 @@ assert inputnode.fromstart if inputnode.escaped: return prebuiltNotSpecNode + if inputnode.knownvaluebox is not None and \ + inputnode.knownvaluebox == exitnode.knownvaluebox: + return ConstantSpecNode(inputnode.knownvaluebox) unique = exitnode.unique if unique == UNIQUE_NO: return prebuiltNotSpecNode Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py Sun Aug 23 17:15:24 2009 @@ -19,6 +19,14 @@ prebuiltNotSpecNode = NotSpecNode() +class ConstantSpecNode(SpecNode): + def __init__(self, constbox): + self.constbox = constbox + + def equals(self, other): + return isinstance(other, ConstantSpecNode) and \ + self.constbox == other.constbox + class AbstractVirtualStructSpecNode(SpecNode): def __init__(self, fields): self.fields = fields # list: [(fieldofs, subspecnode)] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Aug 23 17:15:24 2009 @@ -15,6 +15,7 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.test.oparser import parse @@ -130,12 +131,22 @@ self.cpu) else: return ConstObj(ootype.cast_to_object(cls_vtable)) + def constant(value): + if isinstance(lltype.typeOf(value), lltype.Ptr): + return ConstPtr(value) + elif isinstance(ootype.typeOf(value), ootype.OOType): + return ConstObj(ootype.cast_to_object(value)) + else: + return ConstInt(value) + def parsefields(kwds_fields): fields = [] for key, value in kwds_fields.items(): fields.append((self.namespace[key], value)) fields.sort(key = lambda (x, _): x.sort_key()) return fields + def makeConstant(value): + return ConstantSpecNode(constant(value)) def makeVirtual(cls_vtable, **kwds_fields): fields = parsefields(kwds_fields) return VirtualInstanceSpecNode(constclass(cls_vtable), fields) @@ -146,6 +157,7 @@ return VirtualStructSpecNode(typedescr, fields) # context = {'Not': prebuiltNotSpecNode, + 'Constant': makeConstant, 'Virtual': makeVirtual, 'VArray': makeVirtualArray, 'VStruct': makeVirtualStruct} @@ -467,7 +479,7 @@ """ # The answer must contain the 'value' field, because otherwise # we might get incorrect results: when tracing, maybe i0 was not 0. - self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Constant(0))') def test_find_nodes_nonvirtual_guard_class(self): ops = """ @@ -633,6 +645,19 @@ """ self.find_nodes(ops, 'Not, Not') + def test_find_nodes_guard_value_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + expected = """ + [p1] + jump(p1) + """ + self.find_nodes(ops, 'Constant(myptr)') + # ------------------------------ # Bridge tests Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sun Aug 23 17:15:24 2009 @@ -1041,7 +1041,7 @@ escape(i1) jump(ConstPtr(myptr)) """ - self.optimize_loop(ops, 'Not', expected, p1=self.nodebox.value) + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) def test_duplicate_getfield_sideeffects_1(self): ops = """ From arigo at codespeak.net Sun Aug 23 17:17:31 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 17:17:31 +0200 (CEST) Subject: [pypy-svn] r67121 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823151731.9FC9B16805D@codespeak.net> Author: arigo Date: Sun Aug 23 17:17:29 2009 New Revision: 67121 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo, fijal around) Start implementing the "real" algorithm from rgenop.py at 57000. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 17:17:29 2009 @@ -1,15 +1,53 @@ +import sys +from pypy.tool.pairtype import extendabletype from pypy.jit.backend.x86.ri386 import * +class __extend__(REG): + __metaclass__ = extendabletype + def _getregkey(self): + return ~self.op + +class __extend__(MODRM): + __metaclass__ = extendabletype + def _getregkey(self): + return self.position + def remap_stack_layout(assembler, src_locations, dst_locations, tmpreg): + pending_dests = len(dst_locations) + srccount = {} # maps dst_locations to how many times the same + # location appears in src_locations + for dst in dst_locations: + srccount[dst._getregkey()] = 0 for i in range(len(dst_locations)): src = src_locations[i] - dst = dst_locations[i] - if src is not dst: - if isinstance(dst, MODRM): - if isinstance(src, MODRM): - assembler.regalloc_load(src, tmpreg) - src = tmpreg - assembler.regalloc_store(src, dst) + key = src._getregkey() + if key in srccount: + if key == dst_locations[i]._getregkey(): + srccount[key] = -sys.maxint # ignore a move "x = x" + pending_dests -= 1 else: - assembler.regalloc_load(src, dst) + srccount[key] += 1 + + while pending_dests > 0: + for i in range(len(dst_locations)): + dst = dst_locations[i] + key = dst._getregkey() + if srccount[key] == 0: + srccount[key] = -1 # means "it's done" + pending_dests -= 1 + src = src_locations[i] + key = src._getregkey() + if key in srccount: + srccount[key] -= 1 + _move(assembler, src, dst, tmpreg) + + +def _move(assembler, src, dst, tmpreg): + if isinstance(dst, MODRM): + if isinstance(src, MODRM): + assembler.regalloc_load(src, tmpreg) + src = tmpreg + assembler.regalloc_store(src, dst) + else: + assembler.regalloc_load(src, dst) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 17:17:29 2009 @@ -1,4 +1,5 @@ from pypy.jit.backend.x86.ri386 import * +from pypy.jit.backend.x86.regalloc import stack_pos from pypy.jit.backend.x86.jump import remap_stack_layout class MockAssembler: @@ -41,9 +42,9 @@ remap_stack_layout(assembler, [eax, ebx, ecx, edx, esi, edi], [eax, ebx, ecx, edx, esi, edi], '?') assert assembler.ops == [] - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) + s8 = stack_pos(1) + s12 = stack_pos(31) + s20 = stack_pos(6) remap_stack_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], '?') @@ -58,12 +59,25 @@ def test_simple_stacklocs(): assembler = MockAssembler() - s8 = mem(ebp, -8) - s12 = mem(ebp, -12) - s20 = mem(ebp, -20) - s24 = mem(ebp, -24) + s8 = stack_pos(0) + s12 = stack_pos(13) + s20 = stack_pos(20) + s24 = stack_pos(221) remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], edx) assert assembler.ops == [('load', s8, edx), ('store', edx, s20), ('store', eax, s24), ('load', s12, edi)] + +def test_reordering(): + assembler = MockAssembler() + s8 = stack_pos(8) + s12 = stack_pos(12) + s20 = stack_pos(19) + s24 = stack_pos(1) + remap_stack_layout(assembler, [eax, s8, s20, ebx], + [s8, ebx, eax, edi], '?') + assert assembler.got([('load', ebx, edi), + ('load', s8, ebx), + ('store', eax, s8), + ('load', s20, eax)]) From iko at codespeak.net Sun Aug 23 17:32:25 2009 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 23 Aug 2009 17:32:25 +0200 (CEST) Subject: [pypy-svn] r67122 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090823153225.F405216805D@codespeak.net> Author: iko Date: Sun Aug 23 17:32:25 2009 New Revision: 67122 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, anto) remove guard_value on known constants Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sun Aug 23 17:32:25 2009 @@ -1,7 +1,7 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.metainterp.specnode import SpecNode +from pypy.jit.metainterp.specnode import SpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode @@ -18,7 +18,7 @@ if not. """ optimizer = Optimizer(cpu, loop) - optimizer.setup_virtuals() + optimizer.setup_virtuals_and_constants() optimizer.propagate_forward() def optimize_bridge_1(cpu, bridge): @@ -295,9 +295,15 @@ class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) + def setup_constant_node(self, optimizer, box): + pass def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) +class __extend__(ConstantSpecNode): + def setup_constant_node(self, optimizer, box): + optimizer.make_constant(box) + class __extend__(AbstractVirtualStructSpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): vvalue = self._setup_virtual_node_1(optimizer, box) @@ -456,13 +462,14 @@ # ---------- - def setup_virtuals(self): + def setup_virtuals_and_constants(self): inputargs = self.loop.inputargs specnodes = self.loop.specnodes assert len(inputargs) == len(specnodes) newinputargs = [] for i in range(len(inputargs)): specnodes[i].setup_virtual_node(self, inputargs[i], newinputargs) + specnodes[i].setup_constant_node(self, inputargs[i]) self.loop.inputargs = newinputargs # ---------- Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sun Aug 23 17:32:25 2009 @@ -223,6 +223,19 @@ """ self.optimize_loop(ops, 'Not', expected, i0=0, i1=1, i2=3) + def test_remove_guard_value_if_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + expected = """ + [p1] + jump(ConstPtr(myptr)) + """ + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) + def test_ooisnull_oononnull_1(self): ops = """ [p0] @@ -1034,8 +1047,6 @@ """ expected = """ [p1] - guard_value(p1, ConstPtr(myptr)) - fail() i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) escape(i1) escape(i1) From arigo at codespeak.net Sun Aug 23 17:42:32 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 17:42:32 +0200 (CEST) Subject: [pypy-svn] r67123 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823154232.1C63416805D@codespeak.net> Author: arigo Date: Sun Aug 23 17:42:31 2009 New Revision: 67123 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Finish porting the code from rgenop.py at 57000. Works with cycles correctly, too, as far as we have tested. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 17:42:31 2009 @@ -30,6 +30,7 @@ srccount[key] += 1 while pending_dests > 0: + progress = False for i in range(len(dst_locations)): dst = dst_locations[i] key = dst._getregkey() @@ -41,7 +42,33 @@ if key in srccount: srccount[key] -= 1 _move(assembler, src, dst, tmpreg) - + progress = True + if not progress: + # we are left with only pure disjoint cycles + sources = {} # maps dst_locations to src_locations + for i in range(len(dst_locations)): + src = src_locations[i] + dst = dst_locations[i] + sources[dst._getregkey()] = src + # + for i in range(len(dst_locations)): + dst = dst_locations[i] + originalkey = dst._getregkey() + if srccount[originalkey] >= 0: + assembler.regalloc_push(dst) + while True: + key = dst._getregkey() + assert srccount[key] == 1 + # ^^^ because we are in a simple cycle + srccount[key] = -1 + pending_dests -= 1 + src = sources[key] + if src._getregkey() == originalkey: + break + _move(assembler, src, dst, tmpreg) + dst = src + assembler.regalloc_pop(dst) + assert pending_dests == 0 def _move(assembler, src, dst, tmpreg): if isinstance(dst, MODRM): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 17:42:31 2009 @@ -81,3 +81,17 @@ ('load', s8, ebx), ('store', eax, s8), ('load', s20, eax)]) + +def test_cycle(): + assembler = MockAssembler() + s8 = stack_pos(8) + s12 = stack_pos(12) + s20 = stack_pos(19) + s24 = stack_pos(1) + remap_stack_layout(assembler, [eax, s8, s20, ebx], + [s8, ebx, eax, s20], '?') + assert assembler.got([('push', s8), + ('store', eax, s8), + ('load', s20, eax), + ('store', ebx, s20), + ('pop', ebx)]) From arigo at codespeak.net Sun Aug 23 17:55:53 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 17:55:53 +0200 (CEST) Subject: [pypy-svn] r67124 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090823155553.7837D16805D@codespeak.net> Author: arigo Date: Sun Aug 23 17:55:52 2009 New Revision: 67124 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Yay. Really complicated horrible test passing. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 17:55:52 2009 @@ -95,3 +95,28 @@ ('load', s20, eax), ('store', ebx, s20), ('pop', ebx)]) + +def test_cycle_2(): + assembler = MockAssembler() + s8 = stack_pos(8) + s12 = stack_pos(12) + s20 = stack_pos(19) + s24 = stack_pos(1) + s2 = stack_pos(2) + s3 = stack_pos(3) + remap_stack_layout(assembler, [eax, s8, s20, eax, s20, s24, esi, s2, s3], + [s8, s20, eax, edx, s24, ebx, s12, s3, s2], + ecx) + assert assembler.got([('load', eax, edx), + ('load', s24, ebx), + ('store', esi, s12), + ('load', s20, ecx), + ('store', ecx, s24), + ('push', s8), + ('store', eax, s8), + ('load', s20, eax), + ('pop', s20), + ('push', s3), + ('load', s2, ecx), + ('store', ecx, s3), + ('pop', s2)]) From arigo at codespeak.net Sun Aug 23 17:58:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 17:58:09 +0200 (CEST) Subject: [pypy-svn] r67125 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090823155809.4F9E516805D@codespeak.net> Author: arigo Date: Sun Aug 23 17:58:08 2009 New Revision: 67125 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Also test this case in that test. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 17:58:08 2009 @@ -104,8 +104,9 @@ s24 = stack_pos(1) s2 = stack_pos(2) s3 = stack_pos(3) - remap_stack_layout(assembler, [eax, s8, s20, eax, s20, s24, esi, s2, s3], - [s8, s20, eax, edx, s24, ebx, s12, s3, s2], + remap_stack_layout(assembler, + [eax, s8, edi, s20, eax, s20, s24, esi, s2, s3], + [s8, s20, edi, eax, edx, s24, ebx, s12, s3, s2], ecx) assert assembler.got([('load', eax, edx), ('load', s24, ebx), From cfbolz at codespeak.net Sun Aug 23 18:04:52 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 23 Aug 2009 18:04:52 +0200 (CEST) Subject: [pypy-svn] r67126 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph backend/test metainterp/test Message-ID: <20090823160452.F31CE168058@codespeak.net> Author: cfbolz Date: Sun Aug 23 18:04:51 2009 New Revision: 67126 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Log: (pedronis, cfbolz): AAAARGH. the new_array operation of the llgraph backend does not zero its content. took ages to find. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sun Aug 23 18:04:51 2009 @@ -1058,7 +1058,7 @@ def do_new_array(arraynum, count): TYPE = symbolic.Size2Type[arraynum] - x = lltype.malloc(TYPE, count) + x = lltype.malloc(TYPE, count, zero=True) return cast_to_ptr(x) def do_setarrayitem_gc_int(array, index, newvalue, memocast): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Sun Aug 23 18:04:51 2009 @@ -686,6 +686,7 @@ 'ptr', descr=arraydescr) assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(A), r1.value) + assert a[0] == 0 assert len(a) == 342 def test_new_string(self): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Sun Aug 23 18:04:51 2009 @@ -110,6 +110,21 @@ res = self.meta_interp(f, [21], listops=True) assert res == 2 + def test_make_list(self): + from pypy.jit.metainterp import simple_optimize + myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) + def f(n): + lst = None + while n > 0: + lst = [0] * 10 + myjitdriver.can_enter_jit(n=n, lst=lst) + myjitdriver.jit_merge_point(n=n, lst=lst) + n -= 1 + return lst[n] + res = self.meta_interp(f, [21], listops=True, optimizer=simple_optimize) + assert res == 0 + + class TestOOtype(ListTests, OOJitMixin): pass From pedronis at codespeak.net Sun Aug 23 18:11:01 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 18:11:01 +0200 (CEST) Subject: [pypy-svn] r67127 - in pypy/branch/pyjitpl5/pypy: jit/metainterp jit/metainterp/test jit/tl rlib Message-ID: <20090823161101.25493168058@codespeak.net> Author: pedronis Date: Sun Aug 23 18:11:00 2009 New Revision: 67127 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/tl/tl.py pypy/branch/pyjitpl5/pypy/rlib/jit.py Log: (cfbolz, pedronis) introduce fresh_virtualizable hint to use to expose the construction of virtualizables to the jit, to be used carefully Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Sun Aug 23 18:11:00 2009 @@ -384,6 +384,7 @@ self.var_positions = {} self.vable_array_vars = {} self.immutable_arrays = {} + self.vable_flags = {} for arg in self.force_block_args_order(block): self.register_var(arg, verbose=False) self.emit(label(block)) @@ -914,11 +915,19 @@ return False if not vinfo.is_vtypeptr(op.args[0].concretetype): return False + res = False if op.args[1].value in vinfo.static_field_to_extra_box: - return True + res = True if op.args[1].value in vinfo.array_fields: - raise VirtualizableArrayField(self.graph) - return False + res = VirtualizableArrayField(self.graph) + + if res: + flags = self.vable_flags[op.args[0]] + if 'fresh_virtualizable' in flags: + return False + if isinstance(res, Exception): + raise res + return res def handle_getfield_typeptr(self, op): # special-casing for getting the typeptr of an object @@ -1376,6 +1385,7 @@ vinfo = self.codewriter.metainterp_sd.virtualizable_info assert vinfo is not None assert vinfo.is_vtypeptr(op.args[0].concretetype) + self.vable_flags[op.args[0]] = op.args[2].value serialize_op_oostring = handle_builtin_call serialize_op_oounicode = handle_builtin_call Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Sun Aug 23 18:11:00 2009 @@ -171,6 +171,9 @@ del meth_func._look_inside_me_ class TestOOtype(ToyLanguageTests, OOJitMixin): + def test_tl_call(self): + py.test.skip("virtualizables: in-progress with ootype") + def test_tl_call_full_of_residuals(self): py.test.skip("virtualizables: in-progress with ootype") Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Sun Aug 23 18:11:00 2009 @@ -73,6 +73,7 @@ x = xy.inst_x xy.inst_x = x + 1 n -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [20]) assert res == 30 @@ -96,6 +97,7 @@ x = xy.inst_x xy.inst_x = x + 10 n -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x assert f(5) == 185 res = self.meta_interp(f, [5]) @@ -115,8 +117,10 @@ x = xy.inst_x if n <= 10: x += 1000 + promote_virtualizable(xy, 'inst_x') xy.inst_x = x + 1 n -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [18]) assert res == 10118 @@ -159,6 +163,7 @@ xy.inst_x = x + 1 m = (m+1) & 3 # the loop gets unrolled 4 times n -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x def f(n): res = 0 @@ -188,6 +193,7 @@ promote_virtualizable(xy, 'inst_x') xy.inst_x = value + 100 # virtualized away n -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [20]) assert res == 134 @@ -296,8 +302,11 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) + promote_virtualizable(xy2, 'inst_l1') + promote_virtualizable(xy2, 'inst_l2') xy2.inst_l1[2] += xy2.inst_l2[0] n -= 1 + promote_virtualizable(xy2, 'inst_l1') return xy2.inst_l1[2] res = self.meta_interp(f, [16]) assert res == 3001 + 16 * 80 @@ -312,6 +321,8 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) + promote_virtualizable(xy2, 'inst_x') + promote_virtualizable(xy2, 'inst_l2') xy2.inst_l2[0] += xy2.inst_x n -= 1 def f(n): @@ -341,6 +352,8 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) + promote_virtualizable(xy2, 'inst_l1') + promote_virtualizable(xy2, 'inst_l2') xy2.inst_l1[1] += len(xy2.inst_l2) n -= 1 def f(n): @@ -374,6 +387,7 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) + promote_virtualizable(xy2, 'inst_l1') xy2.inst_l1[1] = xy2.inst_l1[1] + len(h(xy2)) n -= 1 def f(n): @@ -420,6 +434,7 @@ promote_virtualizable(xy2, 'inst_l2') xy2.inst_l2[0] = value + 100 # virtualized away n -= 1 + promote_virtualizable(xy2, 'inst_l2') return xy2.inst_l2[0] expected = f(20) res = self.meta_interp(f, [20], optimizer=simple_optimize) @@ -451,7 +466,10 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) - xy2.parent.inst_l2[0] += xy2.parent.inst_x + parent = xy2.parent + promote_virtualizable(parent, 'inst_x') + promote_virtualizable(parent, 'inst_l2') + parent.inst_l2[0] += parent.inst_x n -= 1 def f(n): xy2 = self.setup2sub() @@ -811,16 +829,15 @@ self.check_loops(new_with_vtable=0) def test_virtual_child_frame_with_arrays(self): - py.test.skip("WIP") myjitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) class Frame(object): _virtualizable2_ = ['x[*]'] - #@dont_look_inside def __init__(self, x, y): - self = hint(self, access_directly=True) + self = hint(self, access_directly=True, + fresh_virtualizable=True) self.x = [x, y] class SomewhereElse: @@ -846,7 +863,12 @@ class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): - pass + + def test_subclass_of_virtualizable(self): + py.test.skip("oo virtualizable support incomplete") + + def test_virtual_child_frame_with_arrays(self): + py.test.skip("oo virtualizable support incomplete") class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, Modified: pypy/branch/pyjitpl5/pypy/jit/tl/tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/tl.py Sun Aug 23 18:11:00 2009 @@ -13,9 +13,8 @@ class Stack(object): _virtualizable2_ = ['stackpos', 'stack[*]'] - @dont_look_inside def __init__(self, size): - self = hint(self, access_directly=True) + self = hint(self, access_directly=True, fresh_virtualizable=True) self.stack = [0] * size self.stackpos = 0 Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Sun Aug 23 18:11:00 2009 @@ -19,7 +19,10 @@ def compute_result_annotation(self, s_x, **kwds_s): from pypy.annotation import model as annmodel s_x = annmodel.not_const(s_x) - if 's_access_directly' in kwds_s: + access_directly = 's_access_directly' in kwds_s + fresh_virtualizable = 's_fresh_virtualizable' in kwds_s + if access_directly or fresh_virtualizable: + assert access_directly, "lone fresh_virtualizable hint" if isinstance(s_x, annmodel.SomeInstance): from pypy.objspace.flow.model import Constant classdesc = s_x.classdef.classdesc @@ -28,6 +31,8 @@ if virtualizable is not None: flags = s_x.flags.copy() flags['access_directly'] = True + if fresh_virtualizable: + flags['fresh_virtualizable'] = True s_x = annmodel.SomeInstance(s_x.classdef, s_x.can_be_None, flags) From arigo at codespeak.net Sun Aug 23 18:41:44 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 18:41:44 +0200 (CEST) Subject: [pypy-svn] r67128 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823164144.3A6F5168060@codespeak.net> Author: arigo Date: Sun Aug 23 18:41:42 2009 New Revision: 67128 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Log: (benjamin, arigo) We don't need that any more. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sun Aug 23 18:41:42 2009 @@ -290,9 +290,6 @@ def regalloc_pop(self, loc): self.mc.POP(loc) - def regalloc_stackdiscard(self, count): - self.mc.ADD(esp, imm(WORD * count)) - def regalloc_perform(self, op, arglocs, resloc): genop_list[op.opnum](self, op, arglocs, resloc) From arigo at codespeak.net Sun Aug 23 18:41:58 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 18:41:58 +0200 (CEST) Subject: [pypy-svn] r67129 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090823164158.796FF168060@codespeak.net> Author: arigo Date: Sun Aug 23 18:41:57 2009 New Revision: 67129 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Log: (benjamin, arigo) Handle constants. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/jump.py Sun Aug 23 18:41:57 2009 @@ -21,6 +21,8 @@ srccount[dst._getregkey()] = 0 for i in range(len(dst_locations)): src = src_locations[i] + if isinstance(src, IMM32): + continue key = src._getregkey() if key in srccount: if key == dst_locations[i]._getregkey(): @@ -38,9 +40,10 @@ srccount[key] = -1 # means "it's done" pending_dests -= 1 src = src_locations[i] - key = src._getregkey() - if key in srccount: - srccount[key] -= 1 + if not isinstance(src, IMM32): + key = src._getregkey() + if key in srccount: + srccount[key] -= 1 _move(assembler, src, dst, tmpreg) progress = True if not progress: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_jump.py Sun Aug 23 18:41:57 2009 @@ -121,3 +121,24 @@ ('load', s2, ecx), ('store', ecx, s3), ('pop', s2)]) + +def test_constants(): + assembler = MockAssembler() + c3 = imm(3) + remap_stack_layout(assembler, [c3], [eax], '?') + assert assembler.ops == [('load', c3, eax)] + assembler = MockAssembler() + s12 = stack_pos(12) + remap_stack_layout(assembler, [c3], [s12], '?') + assert assembler.ops == [('store', c3, s12)] + +def test_constants_and_cycle(): + assembler = MockAssembler() + c3 = imm(3) + s12 = stack_pos(13) + remap_stack_layout(assembler, [ebx, c3, s12], + [s12, eax, ebx], edi) + assert assembler.ops == [('load', c3, eax), + ('push', s12), + ('store', ebx, s12), + ('pop', ebx)] From pedronis at codespeak.net Sun Aug 23 18:48:48 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Aug 2009 18:48:48 +0200 (CEST) Subject: [pypy-svn] r67130 - in pypy/branch/pyjitpl5/pypy/rpython: . test Message-ID: <20090823164848.7AD60168060@codespeak.net> Author: pedronis Date: Sun Aug 23 18:48:48 2009 New Revision: 67130 Modified: pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, pedronis) test and fix Modified: pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py Sun Aug 23 18:48:48 2009 @@ -60,6 +60,8 @@ count = 0 for graph in graphs: for block in graph.iterblocks(): + if not block.operations: + continue newoplist = [] for i, op in enumerate(block.operations): if (op.opname == 'promote_virtualizable' and Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Sun Aug 23 18:48:48 2009 @@ -168,6 +168,27 @@ res = self.interpret(f, [23]) assert res == 23 + def test_access_directly_exception(self): + def g(b): + return b.v0 + + def f(n): + b = B(n) + b = hint(b, access_directly=True) + if not b.v0: + raise Exception + return g(b) + + t, typer, graph = self.gengraph(f, [int]) + f_graph = t._graphof(f) + g_graph = t._graphof(g) + + self.replace_promote_virtualizable(typer, [f_graph, g_graph]) + t.checkgraphs() + + res = self.interpret(f, [23]) + assert res == 23 + def test_access_directly_specialized(self): def g(b): return b.v0 From arigo at codespeak.net Sun Aug 23 19:01:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 19:01:36 +0200 (CEST) Subject: [pypy-svn] r67131 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090823170136.EA2AC168060@codespeak.net> Author: arigo Date: Sun Aug 23 19:01:25 2009 New Revision: 67131 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Log: (benjamin, arigo) Use jump.py from regalloc.py. Things seem to pass. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Sun Aug 23 19:01:25 2009 @@ -10,6 +10,7 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.rlib import rgc from pypy.jit.backend.x86 import symbolic +from pypy.jit.backend.x86.jump import remap_stack_layout from pypy.jit.metainterp.resoperation import rop REGS = [eax, ecx, edx, ebx, esi, edi] @@ -515,6 +516,10 @@ # more optimal inputargs = tree.inputargs locs = [None] * len(inputargs) + # Don't use REGS[0] for passing arguments around a loop. + # Must be kept in sync with consider_jump(). + tmpreg = self.free_regs.pop(0) + assert tmpreg == REGS[0] for i in range(len(inputargs)): arg = inputargs[i] assert not isinstance(arg, Const) @@ -527,6 +532,7 @@ loc = self.stack_loc(arg) locs[i] = loc # otherwise we have it saved on stack, so no worry + self.free_regs.insert(0, tmpreg) tree.arglocs = locs self.assembler.make_merge_point(tree, locs) self.eventually_free_vars(inputargs) @@ -931,33 +937,17 @@ consider_unicodegetitem = consider_strgetitem def consider_jump(self, op, ignored): - # This is a simplified version of the code that was there until r64970. - # At least it's bug-free (hopefully). We can then go on optimizing - # it again. - later_pops = [] # pops that will be performed in reverse order loop = op.jump_target - for i in range(len(op.args)): - arg = op.args[i] - src = self.loc(arg) - res = loop.arglocs[i] - if src is res: - continue # nothing needed to copy in this case - if (isinstance(src, MODRM) and - isinstance(res, MODRM) and - src.position == res.position): - continue # already at the correct stack position - # write the code that moves the correct value into 'res', in two - # steps: generate a pair PUSH (immediately) / POP (later) - if isinstance(src, MODRM): - src = stack_pos(src.position) - if isinstance(res, MODRM): - res = stack_pos(res.position) - self.assembler.regalloc_push(src) - later_pops.append(res) - # + # compute 'tmploc' to be REGS[0] by spilling what is there + box = TempBox() + tmploc = self.force_allocate_reg(box, [], selected_reg=REGS[0]) + src_locations = [self.loc(arg) for arg in op.args] + dst_locations = loop.arglocs + assert tmploc not in dst_locations + remap_stack_layout(self.assembler, src_locations, + dst_locations, tmploc) + self.eventually_free_var(box) self.eventually_free_vars(op.args) - for i in range(len(later_pops)-1, -1, -1): - self.assembler.regalloc_pop(later_pops[i]) self.PerformDiscard(op, []) def consider_debug_merge_point(self, op, ignored): From arigo at codespeak.net Sun Aug 23 19:05:23 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Aug 2009 19:05:23 +0200 (CEST) Subject: [pypy-svn] r67132 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090823170523.96509168065@codespeak.net> Author: arigo Date: Sun Aug 23 19:05:18 2009 New Revision: 67132 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py Log: Fix the test to match r67107. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py Sun Aug 23 19:05:18 2009 @@ -116,12 +116,12 @@ def test_GcRootMap_asmgcc(): gcrootmap = GcRootMap_asmgcc() shape = gcrootmap._get_callshape([stack_pos(1), stack_pos(55)]) - assert shape == [6, 1, 5, 9, 2, 0, -8|2, -224|2] + assert shape == [6, -2, -6, -10, 2, 0, -8|2, -224|2] # shapeaddr = gcrootmap.encode_callshape([stack_pos(1), stack_pos(55)]) PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) - for i, expected in enumerate([131, 59, 11, 0, 4, 18, 10, 2, 12]): + for i, expected in enumerate([131, 59, 11, 0, 4, 19, 11, 3, 12]): assert p[i] == expected # retaddr = rffi.cast(llmemory.Address, 1234567890) From cfbolz at codespeak.net Sun Aug 23 19:45:01 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 23 Aug 2009 19:45:01 +0200 (CEST) Subject: [pypy-svn] r67133 - pypy/branch/pyjitpl5/pypy/interpreter Message-ID: <20090823174501.394E4168064@codespeak.net> Author: cfbolz Date: Sun Aug 23 19:45:00 2009 New Revision: 67133 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Log: (pedronis, cfbolz): use the new fresh_virtualizable hint in PyFrame.__init__. Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Sun Aug 23 19:45:00 2009 @@ -47,9 +47,8 @@ instr_prev = -1 is_being_profiled = False - @jit.dont_look_inside def __init__(self, space, code, w_globals, closure): - #self = hint(self, access_directly=True) + self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) self.pycode = code eval.Frame.__init__(self, space, w_globals, code.co_nlocals) From cfbolz at codespeak.net Sun Aug 23 20:21:06 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 23 Aug 2009 20:21:06 +0200 (CEST) Subject: [pypy-svn] r67134 - in pypy/branch/pyjitpl5/pypy/rlib: . test Message-ID: <20090823182106.2C6C3168069@codespeak.net> Author: cfbolz Date: Sun Aug 23 20:21:04 2009 New Revision: 67134 Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py Log: we_are_jitted cannot raise Modified: pypy/branch/pyjitpl5/pypy/rlib/jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/jit.py Sun Aug 23 20:21:04 2009 @@ -70,6 +70,7 @@ def specialize_call(self, hop): from pypy.rpython.lltypesystem import lltype + hop.exception_cannot_occur() return hop.inputconst(lltype.Signed, _we_are_jitted) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/rlib/test/test_jit.py Sun Aug 23 20:21:04 2009 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import hint +from pypy.rlib.jit import hint, we_are_jitted from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin @@ -10,3 +10,15 @@ return x res = self.interpret(f, []) assert res == 5 + + def test_we_are_jitted(self): + def f(x): + try: + if we_are_jitted(): + return x + return x + 1 + except Exception: + return 5 + res = self.interpret(f, [4]) + assert res == 5 + From fijal at codespeak.net Sun Aug 23 20:58:59 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 23 Aug 2009 20:58:59 +0200 (CEST) Subject: [pypy-svn] r67135 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090823185859.D2D71168067@codespeak.net> Author: fijal Date: Sun Aug 23 20:58:54 2009 New Revision: 67135 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: Revert 67120 and 67122 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Sun Aug 23 20:58:54 2009 @@ -1,10 +1,9 @@ from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode -from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode -from pypy.jit.metainterp.history import AbstractValue, ConstInt, Const +from pypy.jit.metainterp.history import AbstractValue, ConstInt from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs @@ -30,8 +29,6 @@ origfields = None # optimization; equivalent to an empty dict curfields = None # optimization; equivalent to an empty dict - knownvaluebox = None # Used to store value of this box if constant - # fields used to store the shape of the potential VirtualList arraydescr = None # set only on freshly-allocated or fromstart arrays #arraysize = .. # valid if and only if arraydescr is not None @@ -109,12 +106,6 @@ self.nodes = {} # Box -> InstanceNode def getnode(self, box): - if isinstance(box, Const): - node = InstanceNode() - node.unique = UNIQUE_NO - node.knownvaluebox = box - self.nodes[box] = node - return node return self.nodes.get(box, self.node_escaped) def find_nodes(self, operations): @@ -166,10 +157,6 @@ if instnode.fromstart: # only useful in this case instnode.knownclsbox = op.args[1] - def find_nodes_GUARD_VALUE(self, op): - instnode = self.getnode(op.args[0]) - instnode.knownvaluebox = op.args[1] - def find_nodes_SETFIELD_GC(self, op): instnode = self.getnode(op.args[0]) fieldnode = self.getnode(op.args[1]) @@ -295,9 +282,6 @@ assert inputnode.fromstart if inputnode.escaped: return prebuiltNotSpecNode - if inputnode.knownvaluebox is not None and \ - inputnode.knownvaluebox == exitnode.knownvaluebox: - return ConstantSpecNode(inputnode.knownvaluebox) unique = exitnode.unique if unique == UNIQUE_NO: return prebuiltNotSpecNode Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sun Aug 23 20:58:54 2009 @@ -1,7 +1,7 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.metainterp.specnode import SpecNode, ConstantSpecNode +from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode @@ -18,7 +18,7 @@ if not. """ optimizer = Optimizer(cpu, loop) - optimizer.setup_virtuals_and_constants() + optimizer.setup_virtuals() optimizer.propagate_forward() def optimize_bridge_1(cpu, bridge): @@ -295,15 +295,9 @@ class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) - def setup_constant_node(self, optimizer, box): - pass def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) -class __extend__(ConstantSpecNode): - def setup_constant_node(self, optimizer, box): - optimizer.make_constant(box) - class __extend__(AbstractVirtualStructSpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): vvalue = self._setup_virtual_node_1(optimizer, box) @@ -462,14 +456,13 @@ # ---------- - def setup_virtuals_and_constants(self): + def setup_virtuals(self): inputargs = self.loop.inputargs specnodes = self.loop.specnodes assert len(inputargs) == len(specnodes) newinputargs = [] for i in range(len(inputargs)): specnodes[i].setup_virtual_node(self, inputargs[i], newinputargs) - specnodes[i].setup_constant_node(self, inputargs[i]) self.loop.inputargs = newinputargs # ---------- Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py Sun Aug 23 20:58:54 2009 @@ -19,14 +19,6 @@ prebuiltNotSpecNode = NotSpecNode() -class ConstantSpecNode(SpecNode): - def __init__(self, constbox): - self.constbox = constbox - - def equals(self, other): - return isinstance(other, ConstantSpecNode) and \ - self.constbox == other.constbox - class AbstractVirtualStructSpecNode(SpecNode): def __init__(self, fields): self.fields = fields # list: [(fieldofs, subspecnode)] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Aug 23 20:58:54 2009 @@ -15,7 +15,6 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode -from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.test.oparser import parse @@ -131,22 +130,12 @@ self.cpu) else: return ConstObj(ootype.cast_to_object(cls_vtable)) - def constant(value): - if isinstance(lltype.typeOf(value), lltype.Ptr): - return ConstPtr(value) - elif isinstance(ootype.typeOf(value), ootype.OOType): - return ConstObj(ootype.cast_to_object(value)) - else: - return ConstInt(value) - def parsefields(kwds_fields): fields = [] for key, value in kwds_fields.items(): fields.append((self.namespace[key], value)) fields.sort(key = lambda (x, _): x.sort_key()) return fields - def makeConstant(value): - return ConstantSpecNode(constant(value)) def makeVirtual(cls_vtable, **kwds_fields): fields = parsefields(kwds_fields) return VirtualInstanceSpecNode(constclass(cls_vtable), fields) @@ -157,7 +146,6 @@ return VirtualStructSpecNode(typedescr, fields) # context = {'Not': prebuiltNotSpecNode, - 'Constant': makeConstant, 'Virtual': makeVirtual, 'VArray': makeVirtualArray, 'VStruct': makeVirtualStruct} @@ -479,7 +467,7 @@ """ # The answer must contain the 'value' field, because otherwise # we might get incorrect results: when tracing, maybe i0 was not 0. - self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Constant(0))') + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') def test_find_nodes_nonvirtual_guard_class(self): ops = """ @@ -645,19 +633,6 @@ """ self.find_nodes(ops, 'Not, Not') - def test_find_nodes_guard_value_constant(self): - ops = """ - [p1] - guard_value(p1, ConstPtr(myptr)) - fail() - jump(ConstPtr(myptr)) - """ - expected = """ - [p1] - jump(p1) - """ - self.find_nodes(ops, 'Constant(myptr)') - # ------------------------------ # Bridge tests Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sun Aug 23 20:58:54 2009 @@ -223,19 +223,6 @@ """ self.optimize_loop(ops, 'Not', expected, i0=0, i1=1, i2=3) - def test_remove_guard_value_if_constant(self): - ops = """ - [p1] - guard_value(p1, ConstPtr(myptr)) - fail() - jump(ConstPtr(myptr)) - """ - expected = """ - [p1] - jump(ConstPtr(myptr)) - """ - self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) - def test_ooisnull_oononnull_1(self): ops = """ [p0] @@ -1047,12 +1034,14 @@ """ expected = """ [p1] + guard_value(p1, ConstPtr(myptr)) + fail() i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) escape(i1) escape(i1) jump(ConstPtr(myptr)) """ - self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) + self.optimize_loop(ops, 'Not', expected, p1=self.nodebox.value) def test_duplicate_getfield_sideeffects_1(self): ops = """ From cfbolz at codespeak.net Mon Aug 24 10:36:56 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 24 Aug 2009 10:36:56 +0200 (CEST) Subject: [pypy-svn] r67139 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090824083656.641A61683E9@codespeak.net> Author: cfbolz Date: Mon Aug 24 10:36:54 2009 New Revision: 67139 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Mon Aug 24 10:36:54 2009 @@ -99,27 +99,27 @@ - make x86 not recompile everything - think about code memory management - inlining on the Python level - - store sinking (removing consecutive getfields/setfields) (Iko, Anto) + - store sinking (removing consecutive getfields/setfields) DONE - build a pypy-c-jit from before the sprint for comparison IN-PROGRESS - green virtualizable fields ABANDONED - - remove the numerous checks for frame.vable_rti in the - interpreter (non-JITting) part DONE - - parser for the ops files that pypy-c-jit produces DONE - add infrastructure to test the loops that pypy-c-jit produces DONE - - kill the minimal backend DONE - - getting confused IN-PROGRESS - - fix the CLI backend DONE - - fix config tests DONE + - constant specnode support (Iko, Anto, Armin around) + + - getting confused MOSTLY DONE - merge the compiler branch - general wizardry - - change x86 backend to utilize more registers DONE - - look at calls performance? (Samuele, Carl Friedrich) - - fix virtualizable tests (Samuele, Carl Friedrich) - - fix the backend tests (Maciek, Armin, Wyvern around) + - look at calls performance? PROGRESS EXISTS + - fix virtualizable tests DONE + - fix the GC backend tests - write sprint blog post (Maciek, Carl Friedrich) - - get rid of pups and poshes at the end of the loop in x86 backend (Benjamin, Armin) + - get rid of pups and poshes at the end of the loop in x86 backend DONE + - investigate lib-python tests (Carl Friedrich, Samuele) + - decide on benchmarks that represent calls (Benjamin) + - decide what to do with resizable lists (Maciek, Armin) + + - find out what's really going on with richards From antocuni at codespeak.net Mon Aug 24 10:41:17 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 10:41:17 +0200 (CEST) Subject: [pypy-svn] r67140 - pypy/branch/pyjitpl5-constspecnode Message-ID: <20090824084117.9FA2A1683E8@codespeak.net> Author: antocuni Date: Mon Aug 24 10:41:17 2009 New Revision: 67140 Added: pypy/branch/pyjitpl5-constspecnode/ - copied from r67139, pypy/branch/pyjitpl5/ Log: (iko, antocuni) a branch to implement ConstantSpecNode From antocuni at codespeak.net Mon Aug 24 10:50:05 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 10:50:05 +0200 (CEST) Subject: [pypy-svn] r67141 - in pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp: . test Message-ID: <20090824085005.964ED16805D@codespeak.net> Author: antocuni Date: Mon Aug 24 10:50:02 2009 New Revision: 67141 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, antocuni) merge again r67120 and r67122, which add ConstantSpecNode Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py Mon Aug 24 10:50:02 2009 @@ -1,9 +1,10 @@ from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode -from pypy.jit.metainterp.history import AbstractValue, ConstInt +from pypy.jit.metainterp.history import AbstractValue, ConstInt, Const from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs @@ -29,6 +30,8 @@ origfields = None # optimization; equivalent to an empty dict curfields = None # optimization; equivalent to an empty dict + knownvaluebox = None # Used to store value of this box if constant + # fields used to store the shape of the potential VirtualList arraydescr = None # set only on freshly-allocated or fromstart arrays #arraysize = .. # valid if and only if arraydescr is not None @@ -106,6 +109,12 @@ self.nodes = {} # Box -> InstanceNode def getnode(self, box): + if isinstance(box, Const): + node = InstanceNode() + node.unique = UNIQUE_NO + node.knownvaluebox = box + self.nodes[box] = node + return node return self.nodes.get(box, self.node_escaped) def find_nodes(self, operations): @@ -157,6 +166,10 @@ if instnode.fromstart: # only useful in this case instnode.knownclsbox = op.args[1] + def find_nodes_GUARD_VALUE(self, op): + instnode = self.getnode(op.args[0]) + instnode.knownvaluebox = op.args[1] + def find_nodes_SETFIELD_GC(self, op): instnode = self.getnode(op.args[0]) fieldnode = self.getnode(op.args[1]) @@ -282,6 +295,9 @@ assert inputnode.fromstart if inputnode.escaped: return prebuiltNotSpecNode + if inputnode.knownvaluebox is not None and \ + inputnode.knownvaluebox == exitnode.knownvaluebox: + return ConstantSpecNode(inputnode.knownvaluebox) unique = exitnode.unique if unique == UNIQUE_NO: return prebuiltNotSpecNode Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py Mon Aug 24 10:50:02 2009 @@ -1,7 +1,7 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.metainterp.specnode import SpecNode +from pypy.jit.metainterp.specnode import SpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode @@ -18,7 +18,7 @@ if not. """ optimizer = Optimizer(cpu, loop) - optimizer.setup_virtuals() + optimizer.setup_virtuals_and_constants() optimizer.propagate_forward() def optimize_bridge_1(cpu, bridge): @@ -295,9 +295,15 @@ class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) + def setup_constant_node(self, optimizer, box): + pass def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) +class __extend__(ConstantSpecNode): + def setup_constant_node(self, optimizer, box): + optimizer.make_constant(box) + class __extend__(AbstractVirtualStructSpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): vvalue = self._setup_virtual_node_1(optimizer, box) @@ -456,13 +462,14 @@ # ---------- - def setup_virtuals(self): + def setup_virtuals_and_constants(self): inputargs = self.loop.inputargs specnodes = self.loop.specnodes assert len(inputargs) == len(specnodes) newinputargs = [] for i in range(len(inputargs)): specnodes[i].setup_virtual_node(self, inputargs[i], newinputargs) + specnodes[i].setup_constant_node(self, inputargs[i]) self.loop.inputargs = newinputargs # ---------- Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py Mon Aug 24 10:50:02 2009 @@ -19,6 +19,14 @@ prebuiltNotSpecNode = NotSpecNode() +class ConstantSpecNode(SpecNode): + def __init__(self, constbox): + self.constbox = constbox + + def equals(self, other): + return isinstance(other, ConstantSpecNode) and \ + self.constbox == other.constbox + class AbstractVirtualStructSpecNode(SpecNode): def __init__(self, fields): self.fields = fields # list: [(fieldofs, subspecnode)] Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 10:50:02 2009 @@ -15,6 +15,7 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.test.oparser import parse @@ -130,12 +131,22 @@ self.cpu) else: return ConstObj(ootype.cast_to_object(cls_vtable)) + def constant(value): + if isinstance(lltype.typeOf(value), lltype.Ptr): + return ConstPtr(value) + elif isinstance(ootype.typeOf(value), ootype.OOType): + return ConstObj(ootype.cast_to_object(value)) + else: + return ConstInt(value) + def parsefields(kwds_fields): fields = [] for key, value in kwds_fields.items(): fields.append((self.namespace[key], value)) fields.sort(key = lambda (x, _): x.sort_key()) return fields + def makeConstant(value): + return ConstantSpecNode(constant(value)) def makeVirtual(cls_vtable, **kwds_fields): fields = parsefields(kwds_fields) return VirtualInstanceSpecNode(constclass(cls_vtable), fields) @@ -146,6 +157,7 @@ return VirtualStructSpecNode(typedescr, fields) # context = {'Not': prebuiltNotSpecNode, + 'Constant': makeConstant, 'Virtual': makeVirtual, 'VArray': makeVirtualArray, 'VStruct': makeVirtualStruct} @@ -467,7 +479,7 @@ """ # The answer must contain the 'value' field, because otherwise # we might get incorrect results: when tracing, maybe i0 was not 0. - self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Constant(0))') def test_find_nodes_nonvirtual_guard_class(self): ops = """ @@ -633,6 +645,19 @@ """ self.find_nodes(ops, 'Not, Not') + def test_find_nodes_guard_value_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + expected = """ + [p1] + jump(p1) + """ + self.find_nodes(ops, 'Constant(myptr)') + # ------------------------------ # Bridge tests Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py Mon Aug 24 10:50:02 2009 @@ -223,6 +223,19 @@ """ self.optimize_loop(ops, 'Not', expected, i0=0, i1=1, i2=3) + def test_remove_guard_value_if_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + expected = """ + [p1] + jump(ConstPtr(myptr)) + """ + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) + def test_ooisnull_oononnull_1(self): ops = """ [p0] @@ -1034,14 +1047,12 @@ """ expected = """ [p1] - guard_value(p1, ConstPtr(myptr)) - fail() i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) escape(i1) escape(i1) jump(ConstPtr(myptr)) """ - self.optimize_loop(ops, 'Not', expected, p1=self.nodebox.value) + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) def test_duplicate_getfield_sideeffects_1(self): ops = """ From antocuni at codespeak.net Mon Aug 24 10:57:49 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 10:57:49 +0200 (CEST) Subject: [pypy-svn] r67142 - in pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp: . test Message-ID: <20090824085749.EC39A168075@codespeak.net> Author: antocuni Date: Mon Aug 24 10:57:48 2009 New Revision: 67142 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py Log: (iko, antocuni) optimize away constants from inputargs and exitargs Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py Mon Aug 24 10:57:48 2009 @@ -295,14 +295,14 @@ class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) - def setup_constant_node(self, optimizer, box): - pass def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) class __extend__(ConstantSpecNode): - def setup_constant_node(self, optimizer, box): + def setup_virtual_node(self, optimizer, box, newinputargs): optimizer.make_constant(box) + def teardown_virtual_node(self, optimizer, value, newexitargs): + pass class __extend__(AbstractVirtualStructSpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): @@ -469,7 +469,6 @@ newinputargs = [] for i in range(len(inputargs)): specnodes[i].setup_virtual_node(self, inputargs[i], newinputargs) - specnodes[i].setup_constant_node(self, inputargs[i]) self.loop.inputargs = newinputargs # ---------- Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py Mon Aug 24 10:57:48 2009 @@ -5,6 +5,12 @@ __metaclass__ = extendabletype # extended in optimizefindnode.py __slots__ = () + def equals(self, other): + raise NotImplementedError + + def extract_runtime_data(self, cpu, valuebox, resultlist): + raise NotImplementedError + class NotSpecNode(SpecNode): __slots__ = () @@ -27,6 +33,10 @@ return isinstance(other, ConstantSpecNode) and \ self.constbox == other.constbox + def extract_runtime_data(self, cpu, valuebox, resultlist): + raise NotImplementedError + + class AbstractVirtualStructSpecNode(SpecNode): def __init__(self, fields): self.fields = fields # list: [(fieldofs, subspecnode)] Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizeopt.py Mon Aug 24 10:57:48 2009 @@ -231,8 +231,8 @@ jump(ConstPtr(myptr)) """ expected = """ - [p1] - jump(ConstPtr(myptr)) + [] + jump() """ self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) @@ -1046,11 +1046,11 @@ jump(p1) """ expected = """ - [p1] + [] i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) escape(i1) escape(i1) - jump(ConstPtr(myptr)) + jump() """ self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) From antocuni at codespeak.net Mon Aug 24 11:10:04 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 11:10:04 +0200 (CEST) Subject: [pypy-svn] r67143 - in pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp: . test Message-ID: <20090824091004.83B411683DE@codespeak.net> Author: antocuni Date: Mon Aug 24 11:10:04 2009 New Revision: 67143 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_specnode.py Log: (iko, antocuni, arigato) write unit tests for ConstantSpecNode Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/specnode.py Mon Aug 24 11:10:04 2009 @@ -34,7 +34,7 @@ self.constbox == other.constbox def extract_runtime_data(self, cpu, valuebox, resultlist): - raise NotImplementedError + pass class AbstractVirtualStructSpecNode(SpecNode): Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_specnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_specnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_specnode.py Mon Aug 24 11:10:04 2009 @@ -4,6 +4,7 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import equals_specnodes from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin @@ -40,6 +41,16 @@ assert equals_specnodes([sspecnode1], [sspecnode1]) assert not equals_specnodes([sspecnode1], [prebuiltNotSpecNode]) assert not equals_specnodes([prebuiltNotSpecNode], [sspecnode1]) + # + assert equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('foo')]) + assert not equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('bar')]) + assert not equals_specnodes([ConstantSpecNode('foo')], [prebuiltNotSpecNode]) + +def test_extract_runtime_data_0(): + res = [] + node = ConstantSpecNode('foo') + node.extract_runtime_data("cpu", "box1", res) + assert res == [] def test_extract_runtime_data_1(): res = [] From benjamin at codespeak.net Mon Aug 24 11:43:08 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 24 Aug 2009 11:43:08 +0200 (CEST) Subject: [pypy-svn] r67144 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test/loopdata Message-ID: <20090824094308.B27A91683EE@codespeak.net> Author: benjamin Date: Mon Aug 24 11:43:08 2009 New Revision: 67144 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Log: fix for blank lines Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Mon Aug 24 11:43:08 2009 @@ -206,6 +206,8 @@ def parse_next_instruction(self, lines, i): line = lines[i].strip() + if not line: + return i + 1 if line.startswith('LOOP END'): raise EndOfBlock() if line.startswith('LOOP'): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Mon Aug 24 11:43:08 2009 @@ -13,4 +13,5 @@ #(no jitdriver.get_printable_location!) 6:jump bi(0,6),bi(5,3),bi(3,24) #19 + LOOP END From antocuni at codespeak.net Mon Aug 24 11:51:47 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 11:51:47 +0200 (CEST) Subject: [pypy-svn] r67145 - in pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp: . test Message-ID: <20090824095147.DC2E81683BC@codespeak.net> Author: antocuni Date: Mon Aug 24 11:51:46 2009 New Revision: 67145 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (iko, antocuni) implement bridge support for ConstantSpecNode Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py Mon Aug 24 11:51:46 2009 @@ -384,6 +384,14 @@ def matches_instance_node(self, exitnode): return True +class __extend__(ConstantSpecNode): + def make_instance_node(self): + raise AssertionError, "not implemented (but not used actually)" + def matches_instance_node(self, exitnode): + if exitnode.knownvaluebox is None: + return False + return self.constbox.equals(exitnode.knownvaluebox) + class __extend__(VirtualInstanceSpecNode): def make_instance_node(self): instnode = InstanceNode() Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 11:51:46 2009 @@ -52,6 +52,7 @@ node = lltype.malloc(NODE) nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) myptr = nodebox.value + myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE)) nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) @@ -90,6 +91,7 @@ node = ootype.new(NODE) nodebox = BoxObj(ootype.cast_to_object(node)) myptr = nodebox.value + myptr2 = ootype.cast_to_object(ootype.new(NODE)) nodebox2 = BoxObj(ootype.cast_to_object(node)) valuedescr = cpu.fielddescrof(NODE, 'value') nextdescr = cpu.fielddescrof(NODE, 'next') @@ -692,6 +694,17 @@ """ self.find_bridge(ops, 'Not', 'Not') + def test_bridge_simple_constant(self): + ops = """ + [p0] + guard_value(p0, ConstPtr(myptr)) + fail() + jump(p0) + """ + self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, 'Not', 'Constant(myptr)') + self.find_bridge(ops, 'Not', 'Constant(myptr2)', mismatch=True) + def test_bridge_simple_virtual_1(self): ops = """ [i0] From fijal at codespeak.net Mon Aug 24 11:52:18 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 11:52:18 +0200 (CEST) Subject: [pypy-svn] r67146 - pypy/branch/pyjitpl5-call-if Message-ID: <20090824095218.E5BD01683BC@codespeak.net> Author: fijal Date: Mon Aug 24 11:52:18 2009 New Revision: 67146 Added: pypy/branch/pyjitpl5-call-if/ - copied from r67144, pypy/branch/pyjitpl5/ Log: (arigo, fijal) Start a new, hopefully short-lived branch for making eg resizable list operations not perform call (in the common case). From benjamin at codespeak.net Mon Aug 24 12:16:45 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 24 Aug 2009 12:16:45 +0200 (CEST) Subject: [pypy-svn] r67147 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test test/loopdata Message-ID: <20090824101645.121771683EF@codespeak.net> Author: benjamin Date: Mon Aug 24 12:16:44 2009 New Revision: 67147 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Log: handle guards which have results Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Mon Aug 24 12:16:44 2009 @@ -239,20 +239,40 @@ args = [] _, opname = opname.split(":") if lines[i + 1].startswith(" " * (self.current_indentation + 2)): - if lines[i + 1].strip().startswith('BEGIN'): - self.current_indentation += 2 - guard_op = GuardOperation(opname, args) - self.current_block.add(guard_op) - return self.parse_block(lines, i + 2, guard_op) - marker, result = lines[i + 1].strip().split(" ") - assert marker == '=>' - result, = self._parse_boxes(result) - self.current_block.add(Operation(opname, args, result, descr)) + # Could be the beginning of a guard or the result of an + # operation. (Or the result of a guard operation.) + result = self._parse_guard(lines, i + 1, opname, args) + if result != -1: + return result + # If there's not a BEGIN line, there must be a result. + op_result = self._parse_result(lines[i + 1]) + # BEGIN might appear after the result. guard_exception has a + # result. + result = self._parse_guard(lines, i + 2, opname, args, op_result) + if result != -1: + return result + # Definitely not a guard. + self.current_block.add(Operation(opname, args, op_result, descr)) return i + 2 else: self.current_block.add(Operation(opname, args, descr=descr)) return i + 1 + def _parse_guard(self, lines, i, opname, args, op_result=None): + if lines[i].lstrip().startswith('BEGIN'): + self.current_indentation += 2 + guard_op = GuardOperation(opname, args, op_result) + self.current_block.add(guard_op) + return self.parse_block(lines, i + 1, guard_op) + return -1 + + def _parse_result(self, line): + line = line.strip() + marker, result = line.split(" ") + assert marker == "=>" + result, = self._parse_boxes(result) + return result + def _parse(self, lines, i): try: while True: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Mon Aug 24 12:16:44 2009 @@ -13,5 +13,9 @@ #(no jitdriver.get_printable_location!) 6:jump bi(0,6),bi(5,3),bi(3,24) #19 - +8:guard_exception ci(85,138082236) + => bp(86,138081800) + BEGIN(0) + 0:fail bi(2,18)[] + END LOOP END Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Mon Aug 24 12:16:44 2009 @@ -12,7 +12,7 @@ assert len(topblock.inputargs) == 3 for arg in topblock.inputargs: assert isinstance(arg, BoxInt) - assert len(topblock.operations) == 8 + assert len(topblock.operations) == 9 assert isinstance(topblock.operations[0], Comment) assert topblock.operations[0].text == \ "(no jitdriver.get_printable_location!)" @@ -20,7 +20,8 @@ assert isinstance(topblock.operations[4], GuardOperation) assert ([op.opname for op in topblock.operations if not isinstance(op, Comment)] == - ['int_add', 'int_sub', 'int_gt', 'guard_true', 'jump']) + ['int_add', 'int_sub', 'int_gt', 'guard_true', 'jump', + 'guard_exception']) subops = topblock.operations[4].suboperations assert len(subops) == 1 assert subops[0].opname == 'fail' @@ -42,6 +43,10 @@ assert isinstance(code_comment, ByteCodeRef) assert code_comment.text == " #19" assert code_comment.address == 19 + guard_exception = topblock.operations[8] + assert isinstance(guard_exception, GuardOperation) + assert isinstance(guard_exception.result, BoxPtr) + assert guard_exception.result.value == 138081800 def test_two_paths(self): loops = self.parse("two_paths.ops") From fijal at codespeak.net Mon Aug 24 12:52:47 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 12:52:47 +0200 (CEST) Subject: [pypy-svn] r67148 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090824105247.111431683F3@codespeak.net> Author: fijal Date: Mon Aug 24 12:52:46 2009 New Revision: 67148 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py Log: Check in collapsing of int_is_true followed by guard_true or guard_false Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Mon Aug 24 12:52:46 2009 @@ -435,12 +435,6 @@ loc2 = cl self.mc.SHR(loc, loc2) - def genop_int_is_true(self, op, arglocs, resloc): - argloc = arglocs[0] - self.mc.TEST(argloc, argloc) - self.mc.MOV(resloc, imm8(0)) - self.mc.SETNZ(lower_byte(resloc)) - def genop_guard_oononnull(self, op, guard_op, addr, arglocs, resloc): loc = arglocs[0] self.mc.TEST(loc, loc) @@ -457,11 +451,16 @@ else: self.implement_guard(addr, guard_op, self.mc.JZ) + + genop_guard_int_is_true = genop_guard_oononnull + def genop_oononnull(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) self.mc.MOV(resloc, imm8(0)) self.mc.SETNE(lower_byte(resloc)) + genop_int_is_true = genop_oononnull + def genop_ooisnull(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) self.mc.MOV(resloc, imm8(0)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py Mon Aug 24 12:52:46 2009 @@ -877,12 +877,6 @@ consider_getfield_raw = consider_getfield_gc consider_getarrayitem_gc_pure = consider_getarrayitem_gc - def consider_int_is_true(self, op, ignored): - argloc = self.make_sure_var_in_reg(op.args[0], []) - resloc = self.force_allocate_reg(op.result, op.args, - need_lower_byte=True) - self.eventually_free_var(op.args[0]) - self.Perform(op, [argloc], resloc) def _consider_nullity(self, op, guard_op): # doesn't need a register in arg @@ -900,7 +894,8 @@ resloc = self.force_allocate_reg(op.result, [], need_lower_byte=True) self.Perform(op, [argloc], resloc) - + + consider_int_is_true = _consider_nullity consider_ooisnull = _consider_nullity consider_oononnull = _consider_nullity Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py Mon Aug 24 12:52:46 2009 @@ -301,17 +301,21 @@ assert res.value == 1 def test_nullity_with_guard(self): - allops = [rop.OONONNULL, rop.OOISNULL] + allops = [rop.OONONNULL, rop.OOISNULL, rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) - p = BoxPtr(p) nullptr = lltype.nullptr(llmemory.GCREF.TO) - n = BoxPtr(nullptr) f = BoxInt() - for b in (p, n): - for op in allops: - for guard in guards: + for op in allops: + for guard in guards: + if op == rop.INT_IS_TRUE: + bp = BoxInt(1) + n = BoxInt(0) + else: + bp = BoxPtr(p) + n = BoxPtr(nullptr) + for b in (bp, n): ops = [ ResOperation(op, [b], f), ResOperation(guard, [f], None), @@ -322,7 +326,10 @@ loop.operations = ops loop.inputargs = [b] self.cpu.compile_operations(loop) - self.cpu.set_future_value_ptr(0, b.value) + if op == rop.INT_IS_TRUE: + self.cpu.set_future_value_int(0, b.value) + else: + self.cpu.set_future_value_ptr(0, b.value) r = self.cpu.execute_operations(loop) result = self.cpu.get_latest_value_int(0) if guard == rop.GUARD_FALSE: From antocuni at codespeak.net Mon Aug 24 12:53:32 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 12:53:32 +0200 (CEST) Subject: [pypy-svn] r67149 - in pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp: . test Message-ID: <20090824105332.C509C1683F3@codespeak.net> Author: antocuni Date: Mon Aug 24 12:53:31 2009 New Revision: 67149 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (antocuni, iko) (in-progress) make ConstantSpecNode even if the values comes from a same_as, which is exactly the case that happens in pypy. A bridge test fails now :-/ Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizefindnode.py Mon Aug 24 12:53:31 2009 @@ -48,6 +48,9 @@ def __init__(self, fromstart=False): self.fromstart = fromstart # for loops only: present since the start + def is_constant(self): + return self.knownvaluebox is not None + def add_escape_dependency(self, other): assert not self.escaped if self.dependencies is None: @@ -110,13 +113,16 @@ def getnode(self, box): if isinstance(box, Const): - node = InstanceNode() - node.unique = UNIQUE_NO - node.knownvaluebox = box - self.nodes[box] = node - return node + return self.set_constant_node(box) return self.nodes.get(box, self.node_escaped) + def set_constant_node(self, box): + node = InstanceNode() + node.unique = UNIQUE_NO + node.knownvaluebox = box + self.nodes[box] = node + return node + def find_nodes(self, operations): for op in operations: opnum = op.opnum @@ -128,6 +134,13 @@ self.find_nodes_default(op) def find_nodes_default(self, op): + if op.is_always_pure(): + for arg in op.args: + node = self.getnode(arg) + if not node.is_constant(): + break + else: + self.set_constant_node(op.result) # default case: mark the arguments as escaping for box in op.args: self.getnode(box).mark_escaped() @@ -163,12 +176,13 @@ def find_nodes_GUARD_CLASS(self, op): instnode = self.getnode(op.args[0]) - if instnode.fromstart: # only useful in this case + if instnode.fromstart: # only useful (and safe) in this case instnode.knownclsbox = op.args[1] def find_nodes_GUARD_VALUE(self, op): instnode = self.getnode(op.args[0]) - instnode.knownvaluebox = op.args[1] + if instnode.fromstart: # only useful (and safe) in this case + instnode.knownvaluebox = op.args[1] def find_nodes_SETFIELD_GC(self, op): instnode = self.getnode(op.args[0]) @@ -295,8 +309,9 @@ assert inputnode.fromstart if inputnode.escaped: return prebuiltNotSpecNode - if inputnode.knownvaluebox is not None and \ - inputnode.knownvaluebox == exitnode.knownvaluebox: + if inputnode.is_constant() and \ + exitnode.is_constant() and \ + inputnode.knownvaluebox.equals(exitnode.knownvaluebox): return ConstantSpecNode(inputnode.knownvaluebox) unique = exitnode.unique if unique == UNIQUE_NO: Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 12:53:31 2009 @@ -177,9 +177,10 @@ class BaseTestOptimizeFindNode(BaseTest): - def find_nodes(self, ops, spectext, boxkinds=None): + def find_nodes(self, ops, spectext, boxkinds=None, **values): assert boxkinds is None or isinstance(boxkinds, dict) loop = self.parse(ops, boxkinds=boxkinds) + loop.setvalues(**values) perfect_specialization_finder = PerfectSpecializationFinder() perfect_specialization_finder.find_nodes_loop(loop) self.check_specnodes(loop.specnodes, spectext) @@ -481,7 +482,7 @@ """ # The answer must contain the 'value' field, because otherwise # we might get incorrect results: when tracing, maybe i0 was not 0. - self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Constant(0))') + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') def test_find_nodes_nonvirtual_guard_class(self): ops = """ @@ -654,21 +655,29 @@ fail() jump(ConstPtr(myptr)) """ - expected = """ + self.find_nodes(ops, 'Constant(myptr)') + + def test_find_nodes_guard_value_same_as_constant(self): + ops = """ [p1] - jump(p1) + guard_value(p1, ConstPtr(myptr)) + fail() + p2 = same_as(ConstPtr(myptr)) + jump(p2) """ - self.find_nodes(ops, 'Constant(myptr)') + self.find_nodes(ops, 'Constant(myptr)', p2=self.myptr) + # ------------------------------ # Bridge tests def find_bridge(self, ops, inputspectext, outputspectext, boxkinds=None, - mismatch=False): + mismatch=False, **values): assert boxkinds is None or isinstance(boxkinds, dict) inputspecnodes = self.unpack_specnodes(inputspectext) outputspecnodes = self.unpack_specnodes(outputspectext) bridge = self.parse(ops, boxkinds=boxkinds) + bridge.setvalues(**values) bridge_specialization_finder = BridgeSpecializationFinder() bridge_specialization_finder.find_nodes_bridge(bridge, inputspecnodes) matches = bridge_specialization_finder.bridge_matches(outputspecnodes) @@ -695,15 +704,16 @@ self.find_bridge(ops, 'Not', 'Not') def test_bridge_simple_constant(self): + py.test.skip('fixme') ops = """ [p0] guard_value(p0, ConstPtr(myptr)) fail() jump(p0) """ - self.find_bridge(ops, 'Not', 'Not') - self.find_bridge(ops, 'Not', 'Constant(myptr)') - self.find_bridge(ops, 'Not', 'Constant(myptr2)', mismatch=True) + #self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, None, 'Constant(myptr)', p0=self.myptr) + #self.find_bridge(ops, 'Not', 'Constant(myptr2)', mismatch=True) def test_bridge_simple_virtual_1(self): ops = """ From fijal at codespeak.net Mon Aug 24 12:53:46 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 12:53:46 +0200 (CEST) Subject: [pypy-svn] r67150 - in pypy/branch/pyjitpl5-call-if/pypy/jit: backend metainterp metainterp/test Message-ID: <20090824105346.CE73E1683F3@codespeak.net> Author: fijal Date: Mon Aug 24 12:53:46 2009 New Revision: 67150 Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Log: (arigo, fijal) Start implementing resizable list operations as something less obscure than calls Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py Mon Aug 24 12:53:46 2009 @@ -156,6 +156,9 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_if(self, args, calldescr): + raise NotImplementedError + def do_cast_int_to_ptr(self, args, descr=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py Mon Aug 24 12:53:46 2009 @@ -241,51 +241,6 @@ self.class_sizes.append((cls, typedescr)) - if 0: # disabled - def fixed_list_descr_for_tp(self, TP): - try: - return self.fixed_list_cache[TP.TO] - except KeyError: - OF = TP.TO.OF - rtyper = self.rtyper - setfunc, _ = support.builtin_func_for_spec(rtyper, 'list.setitem', - [TP, lltype.Signed, OF], - lltype.Void) - getfunc, _ = support.builtin_func_for_spec(rtyper, 'list.getitem', - [TP, lltype.Signed], OF) - malloc_func, _ = support.builtin_func_for_spec(rtyper, 'newlist', - [lltype.Signed, OF], - TP) - len_func, _ = support.builtin_func_for_spec(rtyper, 'list.len', - [TP], lltype.Signed) -## if isinstance(TP.TO, lltype.GcStruct): -## append_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.append', -## [TP, OF], lltype.Void) -## pop_func, _ = support.builtin_func_for_spec(rtyper, 'list.pop', -## [TP], OF) -## insert_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.insert', [TP, lltype.Signed, OF], lltype.Void) - tp = getkind(OF) -## if isinstance(TP.TO, lltype.GcStruct): -## ld = ListDescr(history.ConstAddr(getfunc.value, self.cpu), -## history.ConstAddr(setfunc.value, self.cpu), -## history.ConstAddr(malloc_func.value, self.cpu), -## history.ConstAddr(append_func.value, self.cpu), -## history.ConstAddr(pop_func.value, self.cpu), -## history.ConstAddr(insert_func.value, self.cpu), -## history.ConstAddr(len_func.value, self.cpu), -## history.ConstAddr(nonzero_func.value, self.cpu), -## tp) -## else: - ld = FixedListDescr(history.ConstAddr(getfunc.value, self.cpu), - history.ConstAddr(setfunc.value, self.cpu), - history.ConstAddr(malloc_func.value, self.cpu), - history.ConstAddr(len_func.value, self.cpu), - tp) - self.fixed_list_cache[TP.TO] = ld - return ld - class BytecodeMaker(object): debug = False @@ -1049,24 +1004,6 @@ elif op.args[0].value == 'can_enter_jit': self.emit('can_enter_jit') -## def _eventualy_builtin(self, arg, need_length=True): -## if isinstance(arg.concretetype, lltype.Ptr): -## # XXX very complex logic for getting all things -## # that are pointers, but not objects -## is_list = False -## if isinstance(arg.concretetype.TO, lltype.GcArray): -## is_list = True -## if isinstance(arg.concretetype.TO, lltype.GcStruct): -## if arg.concretetype.TO._hints.get('list'): -## is_list = True -## if is_list: -## descr = self.codewriter.list_descr_for_tp(arg.concretetype) -## self.emit('guard_builtin', self.var_position(arg), -## self.get_position(descr)) -## if need_length: -## self.emit('guard_len', self.var_position(arg), -## self.get_position(descr)) - def serialize_op_direct_call(self, op): kind = self.codewriter.policy.guess_call_kind(op) return getattr(self, 'handle_%s_call' % kind)(op) @@ -1174,32 +1111,6 @@ if self.codewriter.metainterp_sd.options.listops: if self.handle_list_call(op, oopspec_name, args, TP): return -## if oopspec_name.startswith('list.getitem'): -## opname = oopspec_name[len('list.'):] -## elif oopspec_name.startswith('list.setitem'): -## opname = oopspec_name[len('list.'):] -## elif oopspec_name == 'newlist': -## opname = 'newlist' -## elif oopspec_name == 'list.append': -## opname = 'append' -## elif oopspec_name == 'list.pop': -## opname = 'pop' -## elif oopspec_name == 'list.len': -## opname = 'len' -## elif oopspec_name == 'list.insert': -## opname = 'insert' -## elif oopspec_name == 'list.nonzero': -## opname = 'listnonzero' -## else: -## raise NotImplementedError("not supported %s" % oopspec_name) -## self.emit(opname) -## ld = self.codewriter.list_descr_for_tp(TP) -## self.emit(self.get_position(ld)) -## self.emit_varargs(args) -## self.register_var(op.result) -## if opname == 'newlist': -## self._eventualy_builtin(op.result, False) -## return if oopspec_name.endswith('_foldable'): opname = 'residual_call_pure' # XXX not for possibly-raising calls else: @@ -1218,11 +1129,31 @@ else: return ARRAY.OF == lltype.Void + def handle_resizable_list_call(self, op, oopspec_name, args, LIST): + assert isinstance(LIST.TO, lltype.GcStruct) + # no ootype + ARRAY = LIST.TO.items.TO + if self._array_of_voids(ARRAY): + return False # arrays of voids: not supported + arraydescr = self.cpu.arraydescrof(ARRAY) + lengthdescr = self.cpu.fielddescrof(LIST.TO, 'length') + itemsdescr = self.cpu.fielddescrof(LIST.TO, 'items') + if oopspec_name == 'list.getitem': + return self.handle_resizable_list_getitem(op, arraydescr, + itemsdescr, lengthdescr, args) + if oopspec_name == 'list.len': + xxx + return False + def handle_list_call(self, op, oopspec_name, args, LIST): if not (oopspec_name.startswith('list.') or oopspec_name == 'newlist'): return False if not isinstance(deref(LIST), (lltype.GcArray, ootype.Array)): - return False # resizable lists + if isinstance(deref(LIST), lltype.GcStruct): + return self.handle_resizable_list_call(op, oopspec_name, args, + LIST) + else: + return False # resizable lists on ootype ARRAY = deref(LIST) if self._array_of_voids(ARRAY): return False # arrays of voids: not supported @@ -1260,7 +1191,8 @@ self.var_position(args[1]), self.var_position(args[2])) return True - index = self.prepare_list_getset(op, arraydescr, args) + index = self.prepare_list_getset(op, arraydescr, args, + 'check_neg_index') if index is None: return False self.emit('setarrayitem_gc') @@ -1299,7 +1231,8 @@ return True elif args[0] in self.immutable_arrays: opname = "getarrayitem_gc_pure" - index = self.prepare_list_getset(op, arraydescr, args) + index = self.prepare_list_getset(op, arraydescr, args, + 'check_neg_index') if index is None: return False self.emit(opname) @@ -1309,7 +1242,21 @@ self.register_var(op.result) return True - def prepare_list_getset(self, op, arraydescr, args): + def handle_resizable_list_getitem(self, op, arraydescr, itemsdescr, + lengthdescr, args): + index = self.prepare_list_getset(op, lengthdescr, args, + 'check_resizable_neg_index') + if index is None: + return False + self.emit('getlistitem_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(index)) + self.register_var(op.result) + return True + + def prepare_list_getset(self, op, descr, args, checkname): if op.opname == 'oosend': SELFTYPE, _, meth = support.lookup_oosend_method(op) func = meth._callable @@ -1333,9 +1280,9 @@ if non_negative: v_posindex = args[1] else: - self.emit('check_neg_index') + self.emit(checkname) self.emit(self.var_position(args[0])) - self.emit(self.get_position(arraydescr)) + self.emit(self.get_position(descr)) self.emit(self.var_position(args[1])) v_posindex = Variable('posindex') v_posindex.concretetype = lltype.Signed Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 12:53:46 2009 @@ -374,6 +374,13 @@ rop.INT_ADD, [indexbox, lenbox]) self.make_result_box(indexbox) + @arguments("box", "descr", "descr", "box") + def opimpl_getlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox): + arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC, + [listbox], descr=itemsdescr) + self.execute(rop.GETARRAYITEM_GC, [arraybox, indexbox], + descr=arraydescr) + @arguments("orgpc", "box") def opimpl_check_zerodivisionerror(self, pc, box): nonzerobox = self.metainterp.execute_and_record( Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py Mon Aug 24 12:53:46 2009 @@ -189,6 +189,7 @@ 'NEW_ARRAY', '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- + 'CALL_IF', 'SETARRAYITEM_GC', 'SETFIELD_GC', 'SETFIELD_RAW', Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Mon Aug 24 12:53:46 2009 @@ -6,6 +6,7 @@ class ListTests: def test_basic_list(self): + py.test.skip("not yet") myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) def f(n): lst = [] @@ -19,6 +20,7 @@ assert res == 9 def test_list_operations(self): + py.test.skip("not yet") class FooBar: def __init__(self, z): self.z = z @@ -35,68 +37,6 @@ res = self.interp_operations(f, [11], listops=True) assert res == 49 - def test_lazy_getitem_1(self): - myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) - def f(n): - lst = [0] - while n > 0: - myjitdriver.can_enter_jit(n=n, lst=lst) - myjitdriver.jit_merge_point(n=n, lst=lst) - lst[0] += 2 - n -= 1 - return lst[0] - res = self.meta_interp(f, [21], listops=True) - assert res == 42 - # no more list operations in the loop - py.test.skip("not a ModifiedList yet") - self.check_loops(call=0) - - def test_lazy_getitem_2(self): - py.test.skip("BUG!") - class Escape: - pass - escape = Escape() - def g(): - return escape.lst[0] - def f(n): - lst = [0] - escape.lst = lst - while n > 0: - lst[0] += 2 - n -= g() - return lst[0] - res = self.meta_interp(f, [50], policy=StopAtXPolicy(g)) - assert res == f(50) - # the list operations stay in the loop - self.check_loops(call=3) - - def test_lazy_getitem_3(self): - py.test.skip("in-progress") - def f(n): - lst = [[0]] - while n > 0: - lst[0][0] = lst[0][0] + 2 - n -= 1 - return lst[0][0] - res = self.meta_interp(f, [21]) - assert res == 42 - # two levels of list operations removed from the loop - self.check_loops(call=0) - - def test_lazy_getitem_4(self): - myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) - def f(n): - lst = [0] - while n > 0: - myjitdriver.can_enter_jit(n=n, lst=lst) - myjitdriver.jit_merge_point(n=n, lst=lst) - lst[-1] += 2 - n -= 1 - return lst[0] - res = self.meta_interp(f, [21], listops=True) - assert res == 42 - py.test.skip("not virtualized away so far") - def test_list_of_voids(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) def f(n): @@ -124,9 +64,26 @@ res = self.meta_interp(f, [21], listops=True, optimizer=simple_optimize) assert res == 0 + def test_resizable_list(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'lst', 'i']) + def f(n): + lst = [] + for i in range(n): + lst.append(i) + i = 0 + while n > 0: + myjitdriver.can_enter_jit(n=n, lst=lst, i=i) + myjitdriver.jit_merge_point(n=n, lst=lst, i=i) + n -= lst[i] + i += 1 + return lst[i] + res = self.meta_interp(f, [21], listops=True) + assert res == f(21) + self.check_loops(call=0, call_if=0) -class TestOOtype(ListTests, OOJitMixin): - pass +# we don't support resizable lists on ootype +#class TestOOtype(ListTests, OOJitMixin): +# pass class TestLLtype(ListTests, LLJitMixin): pass From fijal at codespeak.net Mon Aug 24 14:05:10 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 14:05:10 +0200 (CEST) Subject: [pypy-svn] r67151 - in pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp: . test Message-ID: <20090824120510.A36541683CD@codespeak.net> Author: fijal Date: Mon Aug 24 14:05:09 2009 New Revision: 67151 Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Log: Support a bit more advanced list operations Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/codewriter.py Mon Aug 24 14:05:09 2009 @@ -110,11 +110,6 @@ return jitcode def annotation_hacks(self, jitcode): - # xxx annotation hack: make sure there is at least one ConstAddr around - #if self.rtyper.type_system.name == 'lltypesystem': - # jitcode.constants.append(history.ConstAddr(llmemory.NULL, - # self.cpu)) - # xxx annotation hack: make sure class_sizes is not empty if not self.class_sizes: if self.rtyper.type_system.name == 'lltypesystem': STRUCT = lltype.GcStruct('empty') @@ -1129,6 +1124,21 @@ else: return ARRAY.OF == lltype.Void + def handle_resizable_list_setitem(self, op, arraydescr, itemsdescr, + lengthdescr, args): + index = self.prepare_list_getset(op, lengthdescr, args, + 'check_resizable_neg_index') + if index is None: + return False + self.emit('setlistitem_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(index)) + self.emit(self.var_position(args[2])) + self.register_var(op.result) + return True + def handle_resizable_list_call(self, op, oopspec_name, args, LIST): assert isinstance(LIST.TO, lltype.GcStruct) # no ootype @@ -1138,11 +1148,35 @@ arraydescr = self.cpu.arraydescrof(ARRAY) lengthdescr = self.cpu.fielddescrof(LIST.TO, 'length') itemsdescr = self.cpu.fielddescrof(LIST.TO, 'items') + structdescr = self.cpu.sizeof(LIST.TO) if oopspec_name == 'list.getitem': return self.handle_resizable_list_getitem(op, arraydescr, itemsdescr, lengthdescr, args) + if oopspec_name == 'list.setitem': + return self.handle_resizable_list_setitem(op, arraydescr, + itemsdescr, lengthdescr, args) if oopspec_name == 'list.len': - xxx + self.emit('getfield_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(lengthdescr)) + self.register_var(op.result) + return True + if oopspec_name == 'newlist': + if len(args) < 1: + args.append(Constant(0, lltype.Signed)) + if len(args) > 1: + v_default = args[1] + if (not isinstance(v_default, Constant) or + v_default.value != arrayItem(ARRAY)._defl()): + return False # variable or non-null initial value + self.emit('newlist') + self.emit(self.get_position(structdescr)) + self.emit(self.get_position(lengthdescr)) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(args[0])) + self.register_var(op.result) + return True return False def handle_list_call(self, op, oopspec_name, args, LIST): Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 14:05:09 2009 @@ -374,6 +374,19 @@ rop.INT_ADD, [indexbox, lenbox]) self.make_result_box(indexbox) + @arguments("descr", "descr", "descr", "descr", "box") + def opimpl_newlist(self, structdescr, lengthdescr, itemsdescr, arraydescr, + sizebox): + sbox = self.metainterp.execute_and_record(rop.NEW, [], + descr=structdescr) + self.metainterp.execute_and_record(rop.SETFIELD_GC, [sbox, sizebox], + descr=lengthdescr) + abox = self.metainterp.execute_and_record(rop.NEW_ARRAY, [sizebox], + descr=arraydescr) + self.metainterp.execute_and_record(rop.SETFIELD_GC, [sbox, abox], + descr=itemsdescr) + self.make_result_box(sbox) + @arguments("box", "descr", "descr", "box") def opimpl_getlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox): arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC, @@ -381,6 +394,14 @@ self.execute(rop.GETARRAYITEM_GC, [arraybox, indexbox], descr=arraydescr) + @arguments("box", "descr", "descr", "box", "box") + def opimpl_setlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox, + valuebox): + arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC, + [listbox], descr=itemsdescr) + self.execute(rop.SETARRAYITEM_GC, [arraybox, indexbox, valuebox], + descr=arraydescr) + @arguments("orgpc", "box") def opimpl_check_zerodivisionerror(self, pc, box): nonzerobox = self.metainterp.execute_and_record( Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Mon Aug 24 14:05:09 2009 @@ -20,7 +20,6 @@ assert res == 9 def test_list_operations(self): - py.test.skip("not yet") class FooBar: def __init__(self, z): self.z = z @@ -36,6 +35,9 @@ return m res = self.interp_operations(f, [11], listops=True) assert res == 49 + import pdb + pdb.set_trace() + self.check_history_(call=5) def test_list_of_voids(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) @@ -64,7 +66,7 @@ res = self.meta_interp(f, [21], listops=True, optimizer=simple_optimize) assert res == 0 - def test_resizable_list(self): + def test_getitem(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'lst', 'i']) def f(n): lst = [] From fijal at codespeak.net Mon Aug 24 14:07:08 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 14:07:08 +0200 (CEST) Subject: [pypy-svn] r67152 - in pypy/branch/pyjitpl5-call-if/pypy/jit: backend backend/llgraph metainterp metainterp/test Message-ID: <20090824120708.A99241683CD@codespeak.net> Author: fijal Date: Mon Aug 24 14:07:07 2009 New Revision: 67152 Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Log: Revert the CALL_IF operation as we don't need it so far Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/backend/llgraph/runner.py Mon Aug 24 14:07:07 2009 @@ -223,6 +223,7 @@ @staticmethod def sizeof(S): + assert not isinstance(S, lltype.Ptr) return Descr(symbolic.get_size(S)) @staticmethod Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/backend/model.py Mon Aug 24 14:07:07 2009 @@ -156,9 +156,6 @@ def do_call(self, args, calldescr): raise NotImplementedError - def do_call_if(self, args, calldescr): - raise NotImplementedError - def do_cast_int_to_ptr(self, args, descr=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/resoperation.py Mon Aug 24 14:07:07 2009 @@ -189,7 +189,6 @@ 'NEW_ARRAY', '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- - 'CALL_IF', 'SETARRAYITEM_GC', 'SETFIELD_GC', 'SETFIELD_RAW', Modified: pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5-call-if/pypy/jit/metainterp/test/test_slist.py Mon Aug 24 14:07:07 2009 @@ -35,8 +35,6 @@ return m res = self.interp_operations(f, [11], listops=True) assert res == 49 - import pdb - pdb.set_trace() self.check_history_(call=5) def test_list_of_voids(self): @@ -81,7 +79,7 @@ return lst[i] res = self.meta_interp(f, [21], listops=True) assert res == f(21) - self.check_loops(call=0, call_if=0) + self.check_loops(call=0) # we don't support resizable lists on ootype #class TestOOtype(ListTests, OOJitMixin): From fijal at codespeak.net Mon Aug 24 14:15:19 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 14:15:19 +0200 (CEST) Subject: [pypy-svn] r67153 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph backend/x86/test metainterp metainterp/test Message-ID: <20090824121519.381A11683DE@codespeak.net> Author: fijal Date: Mon Aug 24 14:15:18 2009 New Revision: 67153 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_slist.py pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Log: (arigo, fijal) Merge the pyjitpl5-call-if branch Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Mon Aug 24 14:15:18 2009 @@ -223,6 +223,7 @@ @staticmethod def sizeof(S): + assert not isinstance(S, lltype.Ptr) return Descr(symbolic.get_size(S)) @staticmethod Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_slist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_slist.py Mon Aug 24 14:15:18 2009 @@ -1,9 +1,9 @@ - -from pypy.jit.metainterp.test import test_slist, test_dlist +import py +from pypy.jit.metainterp.test import test_slist from pypy.jit.backend.x86.test.test_basic import Jit386Mixin -class TestSList(Jit386Mixin, test_slist.ListTests, test_dlist.ListTests): +class TestSList(Jit386Mixin, test_slist.ListTests): # for the individual tests see # ====> ../../../metainterp/test/test_slist.py - # ====> ../../../metainterp/test/test_dlist.py - pass + def test_list_of_voids(self): + py.test.skip("list of voids unsupported by ll2ctypes") Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Mon Aug 24 14:15:18 2009 @@ -110,11 +110,6 @@ return jitcode def annotation_hacks(self, jitcode): - # xxx annotation hack: make sure there is at least one ConstAddr around - #if self.rtyper.type_system.name == 'lltypesystem': - # jitcode.constants.append(history.ConstAddr(llmemory.NULL, - # self.cpu)) - # xxx annotation hack: make sure class_sizes is not empty if not self.class_sizes: if self.rtyper.type_system.name == 'lltypesystem': STRUCT = lltype.GcStruct('empty') @@ -241,51 +236,6 @@ self.class_sizes.append((cls, typedescr)) - if 0: # disabled - def fixed_list_descr_for_tp(self, TP): - try: - return self.fixed_list_cache[TP.TO] - except KeyError: - OF = TP.TO.OF - rtyper = self.rtyper - setfunc, _ = support.builtin_func_for_spec(rtyper, 'list.setitem', - [TP, lltype.Signed, OF], - lltype.Void) - getfunc, _ = support.builtin_func_for_spec(rtyper, 'list.getitem', - [TP, lltype.Signed], OF) - malloc_func, _ = support.builtin_func_for_spec(rtyper, 'newlist', - [lltype.Signed, OF], - TP) - len_func, _ = support.builtin_func_for_spec(rtyper, 'list.len', - [TP], lltype.Signed) -## if isinstance(TP.TO, lltype.GcStruct): -## append_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.append', -## [TP, OF], lltype.Void) -## pop_func, _ = support.builtin_func_for_spec(rtyper, 'list.pop', -## [TP], OF) -## insert_func, _ = support.builtin_func_for_spec(rtyper, -## 'list.insert', [TP, lltype.Signed, OF], lltype.Void) - tp = getkind(OF) -## if isinstance(TP.TO, lltype.GcStruct): -## ld = ListDescr(history.ConstAddr(getfunc.value, self.cpu), -## history.ConstAddr(setfunc.value, self.cpu), -## history.ConstAddr(malloc_func.value, self.cpu), -## history.ConstAddr(append_func.value, self.cpu), -## history.ConstAddr(pop_func.value, self.cpu), -## history.ConstAddr(insert_func.value, self.cpu), -## history.ConstAddr(len_func.value, self.cpu), -## history.ConstAddr(nonzero_func.value, self.cpu), -## tp) -## else: - ld = FixedListDescr(history.ConstAddr(getfunc.value, self.cpu), - history.ConstAddr(setfunc.value, self.cpu), - history.ConstAddr(malloc_func.value, self.cpu), - history.ConstAddr(len_func.value, self.cpu), - tp) - self.fixed_list_cache[TP.TO] = ld - return ld - class BytecodeMaker(object): debug = False @@ -1049,24 +999,6 @@ elif op.args[0].value == 'can_enter_jit': self.emit('can_enter_jit') -## def _eventualy_builtin(self, arg, need_length=True): -## if isinstance(arg.concretetype, lltype.Ptr): -## # XXX very complex logic for getting all things -## # that are pointers, but not objects -## is_list = False -## if isinstance(arg.concretetype.TO, lltype.GcArray): -## is_list = True -## if isinstance(arg.concretetype.TO, lltype.GcStruct): -## if arg.concretetype.TO._hints.get('list'): -## is_list = True -## if is_list: -## descr = self.codewriter.list_descr_for_tp(arg.concretetype) -## self.emit('guard_builtin', self.var_position(arg), -## self.get_position(descr)) -## if need_length: -## self.emit('guard_len', self.var_position(arg), -## self.get_position(descr)) - def serialize_op_direct_call(self, op): kind = self.codewriter.policy.guess_call_kind(op) return getattr(self, 'handle_%s_call' % kind)(op) @@ -1174,32 +1106,6 @@ if self.codewriter.metainterp_sd.options.listops: if self.handle_list_call(op, oopspec_name, args, TP): return -## if oopspec_name.startswith('list.getitem'): -## opname = oopspec_name[len('list.'):] -## elif oopspec_name.startswith('list.setitem'): -## opname = oopspec_name[len('list.'):] -## elif oopspec_name == 'newlist': -## opname = 'newlist' -## elif oopspec_name == 'list.append': -## opname = 'append' -## elif oopspec_name == 'list.pop': -## opname = 'pop' -## elif oopspec_name == 'list.len': -## opname = 'len' -## elif oopspec_name == 'list.insert': -## opname = 'insert' -## elif oopspec_name == 'list.nonzero': -## opname = 'listnonzero' -## else: -## raise NotImplementedError("not supported %s" % oopspec_name) -## self.emit(opname) -## ld = self.codewriter.list_descr_for_tp(TP) -## self.emit(self.get_position(ld)) -## self.emit_varargs(args) -## self.register_var(op.result) -## if opname == 'newlist': -## self._eventualy_builtin(op.result, False) -## return if oopspec_name.endswith('_foldable'): opname = 'residual_call_pure' # XXX not for possibly-raising calls else: @@ -1218,11 +1124,70 @@ else: return ARRAY.OF == lltype.Void + def handle_resizable_list_setitem(self, op, arraydescr, itemsdescr, + lengthdescr, args): + index = self.prepare_list_getset(op, lengthdescr, args, + 'check_resizable_neg_index') + if index is None: + return False + self.emit('setlistitem_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(index)) + self.emit(self.var_position(args[2])) + self.register_var(op.result) + return True + + def handle_resizable_list_call(self, op, oopspec_name, args, LIST): + assert isinstance(LIST.TO, lltype.GcStruct) + # no ootype + ARRAY = LIST.TO.items.TO + if self._array_of_voids(ARRAY): + return False # arrays of voids: not supported + arraydescr = self.cpu.arraydescrof(ARRAY) + lengthdescr = self.cpu.fielddescrof(LIST.TO, 'length') + itemsdescr = self.cpu.fielddescrof(LIST.TO, 'items') + structdescr = self.cpu.sizeof(LIST.TO) + if oopspec_name == 'list.getitem': + return self.handle_resizable_list_getitem(op, arraydescr, + itemsdescr, lengthdescr, args) + if oopspec_name == 'list.setitem': + return self.handle_resizable_list_setitem(op, arraydescr, + itemsdescr, lengthdescr, args) + if oopspec_name == 'list.len': + self.emit('getfield_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(lengthdescr)) + self.register_var(op.result) + return True + if oopspec_name == 'newlist': + if len(args) < 1: + args.append(Constant(0, lltype.Signed)) + if len(args) > 1: + v_default = args[1] + if (not isinstance(v_default, Constant) or + v_default.value != arrayItem(ARRAY)._defl()): + return False # variable or non-null initial value + self.emit('newlist') + self.emit(self.get_position(structdescr)) + self.emit(self.get_position(lengthdescr)) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(args[0])) + self.register_var(op.result) + return True + return False + def handle_list_call(self, op, oopspec_name, args, LIST): if not (oopspec_name.startswith('list.') or oopspec_name == 'newlist'): return False if not isinstance(deref(LIST), (lltype.GcArray, ootype.Array)): - return False # resizable lists + if isinstance(deref(LIST), lltype.GcStruct): + return self.handle_resizable_list_call(op, oopspec_name, args, + LIST) + else: + return False # resizable lists on ootype ARRAY = deref(LIST) if self._array_of_voids(ARRAY): return False # arrays of voids: not supported @@ -1260,7 +1225,8 @@ self.var_position(args[1]), self.var_position(args[2])) return True - index = self.prepare_list_getset(op, arraydescr, args) + index = self.prepare_list_getset(op, arraydescr, args, + 'check_neg_index') if index is None: return False self.emit('setarrayitem_gc') @@ -1299,7 +1265,8 @@ return True elif args[0] in self.immutable_arrays: opname = "getarrayitem_gc_pure" - index = self.prepare_list_getset(op, arraydescr, args) + index = self.prepare_list_getset(op, arraydescr, args, + 'check_neg_index') if index is None: return False self.emit(opname) @@ -1309,7 +1276,21 @@ self.register_var(op.result) return True - def prepare_list_getset(self, op, arraydescr, args): + def handle_resizable_list_getitem(self, op, arraydescr, itemsdescr, + lengthdescr, args): + index = self.prepare_list_getset(op, lengthdescr, args, + 'check_resizable_neg_index') + if index is None: + return False + self.emit('getlistitem_gc') + self.emit(self.var_position(args[0])) + self.emit(self.get_position(itemsdescr)) + self.emit(self.get_position(arraydescr)) + self.emit(self.var_position(index)) + self.register_var(op.result) + return True + + def prepare_list_getset(self, op, descr, args, checkname): if op.opname == 'oosend': SELFTYPE, _, meth = support.lookup_oosend_method(op) func = meth._callable @@ -1333,9 +1314,9 @@ if non_negative: v_posindex = args[1] else: - self.emit('check_neg_index') + self.emit(checkname) self.emit(self.var_position(args[0])) - self.emit(self.get_position(arraydescr)) + self.emit(self.get_position(descr)) self.emit(self.var_position(args[1])) v_posindex = Variable('posindex') v_posindex.concretetype = lltype.Signed Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 14:15:18 2009 @@ -374,6 +374,34 @@ rop.INT_ADD, [indexbox, lenbox]) self.make_result_box(indexbox) + @arguments("descr", "descr", "descr", "descr", "box") + def opimpl_newlist(self, structdescr, lengthdescr, itemsdescr, arraydescr, + sizebox): + sbox = self.metainterp.execute_and_record(rop.NEW, [], + descr=structdescr) + self.metainterp.execute_and_record(rop.SETFIELD_GC, [sbox, sizebox], + descr=lengthdescr) + abox = self.metainterp.execute_and_record(rop.NEW_ARRAY, [sizebox], + descr=arraydescr) + self.metainterp.execute_and_record(rop.SETFIELD_GC, [sbox, abox], + descr=itemsdescr) + self.make_result_box(sbox) + + @arguments("box", "descr", "descr", "box") + def opimpl_getlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox): + arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC, + [listbox], descr=itemsdescr) + self.execute(rop.GETARRAYITEM_GC, [arraybox, indexbox], + descr=arraydescr) + + @arguments("box", "descr", "descr", "box", "box") + def opimpl_setlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox, + valuebox): + arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC, + [listbox], descr=itemsdescr) + self.execute(rop.SETARRAYITEM_GC, [arraybox, indexbox, valuebox], + descr=arraydescr) + @arguments("orgpc", "box") def opimpl_check_zerodivisionerror(self, pc, box): nonzerobox = self.metainterp.execute_and_record( Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Mon Aug 24 14:15:18 2009 @@ -6,6 +6,7 @@ class ListTests: def test_basic_list(self): + py.test.skip("not yet") myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) def f(n): lst = [] @@ -34,68 +35,7 @@ return m res = self.interp_operations(f, [11], listops=True) assert res == 49 - - def test_lazy_getitem_1(self): - myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) - def f(n): - lst = [0] - while n > 0: - myjitdriver.can_enter_jit(n=n, lst=lst) - myjitdriver.jit_merge_point(n=n, lst=lst) - lst[0] += 2 - n -= 1 - return lst[0] - res = self.meta_interp(f, [21], listops=True) - assert res == 42 - # no more list operations in the loop - py.test.skip("not a ModifiedList yet") - self.check_loops(call=0) - - def test_lazy_getitem_2(self): - py.test.skip("BUG!") - class Escape: - pass - escape = Escape() - def g(): - return escape.lst[0] - def f(n): - lst = [0] - escape.lst = lst - while n > 0: - lst[0] += 2 - n -= g() - return lst[0] - res = self.meta_interp(f, [50], policy=StopAtXPolicy(g)) - assert res == f(50) - # the list operations stay in the loop - self.check_loops(call=3) - - def test_lazy_getitem_3(self): - py.test.skip("in-progress") - def f(n): - lst = [[0]] - while n > 0: - lst[0][0] = lst[0][0] + 2 - n -= 1 - return lst[0][0] - res = self.meta_interp(f, [21]) - assert res == 42 - # two levels of list operations removed from the loop - self.check_loops(call=0) - - def test_lazy_getitem_4(self): - myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) - def f(n): - lst = [0] - while n > 0: - myjitdriver.can_enter_jit(n=n, lst=lst) - myjitdriver.jit_merge_point(n=n, lst=lst) - lst[-1] += 2 - n -= 1 - return lst[0] - res = self.meta_interp(f, [21], listops=True) - assert res == 42 - py.test.skip("not virtualized away so far") + self.check_history_(call=5) def test_list_of_voids(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'lst']) @@ -124,9 +64,26 @@ res = self.meta_interp(f, [21], listops=True, optimizer=simple_optimize) assert res == 0 + def test_getitem(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'lst', 'i']) + def f(n): + lst = [] + for i in range(n): + lst.append(i) + i = 0 + while n > 0: + myjitdriver.can_enter_jit(n=n, lst=lst, i=i) + myjitdriver.jit_merge_point(n=n, lst=lst, i=i) + n -= lst[i] + i += 1 + return lst[i] + res = self.meta_interp(f, [21], listops=True) + assert res == f(21) + self.check_loops(call=0) -class TestOOtype(ListTests, OOJitMixin): - pass +# we don't support resizable lists on ootype +#class TestOOtype(ListTests, OOJitMixin): +# pass class TestLLtype(ListTests, LLJitMixin): pass From arigo at codespeak.net Mon Aug 24 14:21:30 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 14:21:30 +0200 (CEST) Subject: [pypy-svn] r67154 - pypy/branch/pyjitpl5-call-if Message-ID: <20090824122130.E15BA168069@codespeak.net> Author: arigo Date: Mon Aug 24 14:21:30 2009 New Revision: 67154 Removed: pypy/branch/pyjitpl5-call-if/ Log: Kill merged branch. From cfbolz at codespeak.net Mon Aug 24 14:52:35 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 24 Aug 2009 14:52:35 +0200 (CEST) Subject: [pypy-svn] r67155 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090824125235.E4EBC1683E2@codespeak.net> Author: cfbolz Date: Mon Aug 24 14:52:34 2009 New Revision: 67155 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Log: refactor metainterp to use a method instead of an isinstance call everywhere Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 14:52:34 2009 @@ -588,7 +588,7 @@ self.make_result_box(ConstInt(result)) def perform_call(self, jitcode, varargs): - if (isinstance(self.metainterp.history, history.BlackHole) and + if (self.metainterp.is_blackholing() and jitcode.calldescr is not None): # when producing only a BlackHole, we can implement this by # calling the subfunction directly instead of interpreting it @@ -790,7 +790,7 @@ pass # xxx? def generate_merge_point(self, pc, varargs): - if isinstance(self.metainterp.history, history.BlackHole): + if self.metainterp.is_blackholing(): raise self.metainterp.staticdata.ContinueRunningNormally(varargs) num_green_args = self.metainterp.staticdata.num_green_args for i in range(num_green_args): @@ -908,7 +908,7 @@ if isinstance(box, Const): # no need for a guard return metainterp = self.metainterp - if isinstance(metainterp.history, history.BlackHole): + if metainterp.is_blackholing(): return saved_pc = self.pc self.pc = pc @@ -1087,6 +1087,9 @@ if not we_are_translated(): self._debug_history = staticdata.globaldata._debug_history + def is_blackholing(self): + return isinstance(self.history, history.BlackHole) + def newframe(self, jitcode): if not we_are_translated(): self._debug_history.append(['enter', jitcode, None]) @@ -1105,7 +1108,7 @@ self.framestack[-1].make_result_box(resultbox) return True else: - if not isinstance(self.history, history.BlackHole): + if not self.is_blackholing(): self.compile_done_with_this_frame(resultbox) sd = self.staticdata if sd.result_type == 'void': @@ -1141,7 +1144,7 @@ if not we_are_translated(): self._debug_history.append(['leave_exc', frame.jitcode, None]) self.framestack.pop() - if not isinstance(self.history, history.BlackHole): + if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) if self.cpu.is_oo: raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getobj()) @@ -1222,7 +1225,7 @@ while True: self.framestack[-1].run_one_step() finally: - if isinstance(self.history, history.BlackHole): + if self.is_blackholing(): self.staticdata.profiler.end_blackhole() else: self.staticdata.profiler.end_tracing() From antocuni at codespeak.net Mon Aug 24 14:56:12 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 14:56:12 +0200 (CEST) Subject: [pypy-svn] r67156 - pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test Message-ID: <20090824125612.DB06B1683B7@codespeak.net> Author: antocuni Date: Mon Aug 24 14:56:11 2009 New Revision: 67156 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Log: (antocuni, iko, arigato around) fix the test by changing it :-). Add another one Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 14:56:11 2009 @@ -704,16 +704,21 @@ self.find_bridge(ops, 'Not', 'Not') def test_bridge_simple_constant(self): - py.test.skip('fixme') + ops = """ + [] + jump(ConstPtr(myptr)) + """ + self.find_bridge(ops, '', 'Not') + self.find_bridge(ops, '', 'Constant(myptr)') + self.find_bridge(ops, '', 'Constant(myptr2)', mismatch=True) + + def test_bridge_simple_constant_mismatch(self): ops = """ [p0] - guard_value(p0, ConstPtr(myptr)) - fail() jump(p0) """ - #self.find_bridge(ops, 'Not', 'Not') - self.find_bridge(ops, None, 'Constant(myptr)', p0=self.myptr) - #self.find_bridge(ops, 'Not', 'Constant(myptr2)', mismatch=True) + self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, 'Not', 'Constant(myptr)', mismatch=True) def test_bridge_simple_virtual_1(self): ops = """ From pedronis at codespeak.net Mon Aug 24 15:04:52 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Aug 2009 15:04:52 +0200 (CEST) Subject: [pypy-svn] r67157 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824130452.234101683BE@codespeak.net> Author: pedronis Date: Mon Aug 24 15:04:52 2009 New Revision: 67157 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, pedronis): Two tests about virtualizables and blackholes. One of them s fixed, the other skipped. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 15:04:52 2009 @@ -1553,7 +1553,9 @@ # as it contains the old values (before the call)! self.gen_store_back_in_virtualizable_no_perform() return True # must call after_generate_residual_call() - return False # don't call after_generate_residual_call() + # xxx don't call after_generate_residual_call() or + # in the case of blackholing abuse it to resynchronize + return self.is_blackholing() def after_generate_residual_call(self): # Called after generating a residual call, and only if Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Mon Aug 24 15:04:52 2009 @@ -860,6 +860,86 @@ assert res == 55 self.check_loops(new_with_vtable=0) + def test_blackhole_should_not_pay_attention(self): + myjitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + + def __init__(self, x, y): + self = hint(self, access_directly=True) + self.x = x + self.y = y + + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def g(frame): + frame.y += 100 + + def f(n): + frame = Frame(n, 0) + somewhere_else.top_frame = frame # escapes + frame = hint(frame, access_directly=True) + while frame.x > 0: + myjitdriver.can_enter_jit(frame=frame) + myjitdriver.jit_merge_point(frame=frame) + if frame.x == 2: + g(frame) + frame.y += frame.x + frame.x -= 1 + return somewhere_else.top_frame.y + + res = self.meta_interp(f, [10]) + assert res == 155 + self.check_loops(getfield_gc=0, setfield_gc=0) + + def test_blackhole_should_not_reenter(self): + py.test.skip("WIP") + myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + + def __init__(self, x, y): + self = hint(self, access_directly=True) + self.x = x + self.y = y + + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def jump_back(frame, fail): + myjitdriver.can_enter_jit(frame=frame, fail=fail) + + def f(n, fail): + frame = Frame(n, 0) + somewhere_else.top_frame = frame # escapes + frame = hint(frame, access_directly=True) + while frame.x > 0: + myjitdriver.jit_merge_point(frame=frame, fail=fail) + frame.x -= 1 + if fail or frame.x > 2: + frame.y += frame.x + jump_back(frame, fail) + + return somewhere_else.top_frame.y + + def main(): + f(10, True) + f(10, True) + f(10, True) + f(10, True) + return f(10, False) + + res = self.meta_interp(main, []) + assert res == 55 + self.check_loops(getfield_gc=0, setfield_gc=0) + class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): @@ -870,6 +950,12 @@ def test_virtual_child_frame_with_arrays(self): py.test.skip("oo virtualizable support incomplete") + def test_blackhole_should_not_pay_attention(self): + py.test.skip("oo virtualizable support incomplete") + + def test_blackhole_should_not_reenter(self): + py.test.skip("oo virtualizable support incomplete") + class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, LLJitMixin): From antocuni at codespeak.net Mon Aug 24 15:10:48 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 15:10:48 +0200 (CEST) Subject: [pypy-svn] r67158 - pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp Message-ID: <20090824131048.23C1C168050@codespeak.net> Author: antocuni Date: Mon Aug 24 15:10:47 2009 New Revision: 67158 Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py Log: (iko, antocuni, arigato) oups, we wanted to __extend__ NotSpecNode, although as it was it worked too Modified: pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-constspecnode/pypy/jit/metainterp/optimizeopt.py Mon Aug 24 15:10:47 2009 @@ -1,7 +1,7 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.metainterp.specnode import SpecNode, ConstantSpecNode +from pypy.jit.metainterp.specnode import SpecNode, NotSpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode @@ -291,9 +291,14 @@ if itemvalue is not None: itemvalue.get_args_for_fail(modifier) - class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): + raise NotImplementedError + def teardown_virtual_node(self, optimizer, value, newexitargs): + raise NotImplementedError + +class __extend__(NotSpecNode): + def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) From arigo at codespeak.net Mon Aug 24 15:20:48 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 15:20:48 +0200 (CEST) Subject: [pypy-svn] r67159 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824132048.D91901683E8@codespeak.net> Author: arigo Date: Mon Aug 24 15:20:48 2009 New Revision: 67159 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Log: Oups, we forgot to add opimpl_check_resizable_neg_index to pyjitpl.py. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 15:20:48 2009 @@ -402,6 +402,21 @@ self.execute(rop.SETARRAYITEM_GC, [arraybox, indexbox, valuebox], descr=arraydescr) + @arguments("orgpc", "box", "descr", "box") + def opimpl_check_resizable_neg_index(self, pc, listbox, lengthdesc, + indexbox): + negbox = self.metainterp.execute_and_record( + rop.INT_LT, [indexbox, ConstInt(0)]) + # xxx inefficient + negbox = self.implement_guard_value(pc, negbox) + if negbox.getint(): + # the index is < 0; add the array length to it + lenbox = self.metainterp.execute_and_record( + rop.GETFIELD_GC, [listbox], descr=lengthdesc) + indexbox = self.metainterp.execute_and_record( + rop.INT_ADD, [indexbox, lenbox]) + self.make_result_box(indexbox) + @arguments("orgpc", "box") def opimpl_check_zerodivisionerror(self, pc, box): nonzerobox = self.metainterp.execute_and_record( Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Mon Aug 24 15:20:48 2009 @@ -81,6 +81,15 @@ assert res == f(21) self.check_loops(call=0) + def test_getitem_neg(self): + def f(n): + lst = [41] + lst.append(42) + return lst[n] + res = self.interp_operations(f, [-2], listops=True) + assert res == 41 + self.check_history_(call=1) + # we don't support resizable lists on ootype #class TestOOtype(ListTests, OOJitMixin): # pass From arigo at codespeak.net Mon Aug 24 15:54:33 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 15:54:33 +0200 (CEST) Subject: [pypy-svn] r67160 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824135433.43FF41683F5@codespeak.net> Author: arigo Date: Mon Aug 24 15:54:31 2009 New Revision: 67160 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: (fijal, arigo) Optimize INT_IS_TRUE like OONONNULL. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Mon Aug 24 15:54:31 2009 @@ -611,6 +611,9 @@ def optimize_OOISNULL(self, op): self._optimize_nullness(op, False) + def optimize_INT_IS_TRUE(self, op): + self._optimize_nullness(op, True) + def optimize_OOISNOT(self, op): value0 = self.getvalue(op.args[0]) value1 = self.getvalue(op.args[1]) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Mon Aug 24 15:54:31 2009 @@ -244,6 +244,26 @@ """ self.optimize_loop(ops, 'Not', expected, i0=1, i1=0) + def test_int_is_true_1(self): + ops = """ + [i0] + i1 = int_is_true(i0) + guard_true(i1) + fail() + i2 = int_is_true(i0) + guard_true(i2) + fail() + jump(i0) + """ + expected = """ + [i0] + i1 = int_is_true(i0) + guard_true(i1) + fail() + jump(i0) + """ + self.optimize_loop(ops, 'Not', expected, i0=123, i1=1, i2=1) + def test_ooisnull_oononnull_2(self): ops = """ [p0] From cfbolz at codespeak.net Mon Aug 24 15:55:11 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 24 Aug 2009 15:55:11 +0200 (CEST) Subject: [pypy-svn] r67161 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824135511.590A61683F4@codespeak.net> Author: cfbolz Date: Mon Aug 24 15:55:10 2009 New Revision: 67161 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: (cfbolz, pedronis): fix the test: add a sanity check to make sure that you don't enter the frame that the blackholing tracer is currently looking at. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 24 15:55:10 2009 @@ -607,15 +607,23 @@ jitcode.calldescr is not None): # when producing only a BlackHole, we can implement this by # calling the subfunction directly instead of interpreting it + staticdata = self.metainterp.staticdata + globaldata = staticdata.globaldata + vi = staticdata.virtualizable_info + if vi: + globaldata.blackhole_virtualizable = vi.unwrap_virtualizable_box(self.metainterp.virtualizable_boxes[-1]) if jitcode.cfnptr is not None: # for non-oosends varargs = [jitcode.cfnptr] + varargs - return self.execute_with_exc(rop.CALL, varargs, + res = self.execute_with_exc(rop.CALL, varargs, descr=jitcode.calldescr) else: # for oosends (ootype only): calldescr is a MethDescr - return self.execute_with_exc(rop.OOSEND, varargs, + res = self.execute_with_exc(rop.OOSEND, varargs, descr=jitcode.calldescr) + if vi: + globaldata.blackhole_virtualizable = vi.null_vable + return res else: # when tracing, this bytecode causes the subfunction to be entered f = self.metainterp.newframe(jitcode) @@ -1091,6 +1099,8 @@ else: self.compiled_merge_points = {} # for tests only; not RPython self.unpack_greenkey = tuple + if staticdata.virtualizable_info: + self.blackhole_virtualizable = staticdata.virtualizable_info.null_vable # ____________________________________________________________ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Mon Aug 24 15:55:10 2009 @@ -897,7 +897,6 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): - py.test.skip("WIP") myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'], virtualizables = ['frame']) @@ -936,9 +935,8 @@ f(10, True) return f(10, False) - res = self.meta_interp(main, []) - assert res == 55 - self.check_loops(getfield_gc=0, setfield_gc=0) + einfo = py.test.raises(AssertionError, self.meta_interp, main, []) + assert einfo.value.args[0] == "reentering same frame via blackhole" class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Mon Aug 24 15:55:10 2009 @@ -40,6 +40,10 @@ VTYPEPTR = VTYPEPTR._superclass self.VTYPEPTR = VTYPEPTR self.VTYPE = VTYPE = deref(VTYPEPTR) + if not self.is_oo: + self.null_vable = lltype.nullptr(VTYPE) + else: + self.null_vable = ootype.null(VTYPE) # accessor = VTYPE._hints['virtualizable2_accessor'] all_fields = accessor.fields Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Mon Aug 24 15:55:10 2009 @@ -772,6 +772,10 @@ greenargs = args[:num_green_args] argshash = self.getkeyhash(*greenargs) & self.hashtablemask counter = self.mccounters[argshash] + if vinfo: + virtualizable = args[vinfo.index_of_virtualizable] + virtualizable = vinfo.cast_to_vtype(virtualizable) + assert virtualizable != metainterp_sd.globaldata.blackhole_virtualizable, "reentering same frame via blackhole" if counter >= 0: # update the profiling counter n = counter + self.increment_threshold From cfbolz at codespeak.net Mon Aug 24 15:56:13 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 24 Aug 2009 15:56:13 +0200 (CEST) Subject: [pypy-svn] r67162 - in pypy/branch/pyjitpl5/pypy: interpreter objspace/std Message-ID: <20090824135613.4AF361683F4@codespeak.net> Author: cfbolz Date: Mon Aug 24 15:56:13 2009 New Revision: 67162 Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py pypy/branch/pyjitpl5/pypy/objspace/std/objspace.py Log: make sure that we don't see tracing when jitted Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Mon Aug 24 15:56:13 2009 @@ -111,7 +111,8 @@ executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: - executioncontext.call_trace(self) + if not we_are_jitted(): + executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. @@ -122,9 +123,11 @@ rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: - executioncontext.return_trace(self, self.space.w_None) + if not we_are_jitted(): + executioncontext.return_trace(self, self.space.w_None) raise - executioncontext.return_trace(self, w_exitvalue) + if not we_are_jitted(): + executioncontext.return_trace(self, w_exitvalue) # on exit, we try to release self.last_exception -- breaks an # obvious reference cycle, so it helps refcounting implementations self.last_exception = None Modified: pypy/branch/pyjitpl5/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/objspace.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/objspace.py Mon Aug 24 15:56:13 2009 @@ -168,9 +168,11 @@ def call_likely_builtin(f, w_function, nargs): if isinstance(w_function, function.Function): executioncontext = self.getexecutioncontext() - executioncontext.c_call_trace(f, w_function) + if not we_are_jitted(): + executioncontext.c_call_trace(f, w_function) res = w_function.funccall_valuestack(nargs, f) - executioncontext.c_return_trace(f, w_function) + if not we_are_jitted(): + executioncontext.c_return_trace(f, w_function) return res args = f.make_arguments(nargs) try: From arigo at codespeak.net Mon Aug 24 16:00:38 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 16:00:38 +0200 (CEST) Subject: [pypy-svn] r67163 - pypy/branch/pyjitpl5-noframestack Message-ID: <20090824140038.AFFF616803E@codespeak.net> Author: arigo Date: Mon Aug 24 16:00:38 2009 New Revision: 67163 Added: pypy/branch/pyjitpl5-noframestack/ - copied from r67162, pypy/branch/pyjitpl5/ Log: (fijal, arigo) A branch in which to make another attempt at removing the ExecutionContext.framestack. From antocuni at codespeak.net Mon Aug 24 16:11:01 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 16:11:01 +0200 (CEST) Subject: [pypy-svn] r67164 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824141101.1545A1683E6@codespeak.net> Author: antocuni Date: Mon Aug 24 16:11:00 2009 New Revision: 67164 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py Log: (antocuni, iko) merge the -constspecnode branch Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Mon Aug 24 16:11:00 2009 @@ -1,9 +1,10 @@ from pypy.jit.metainterp.specnode import SpecNode from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode -from pypy.jit.metainterp.history import AbstractValue, ConstInt +from pypy.jit.metainterp.history import AbstractValue, ConstInt, Const from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs @@ -29,6 +30,8 @@ origfields = None # optimization; equivalent to an empty dict curfields = None # optimization; equivalent to an empty dict + knownvaluebox = None # Used to store value of this box if constant + # fields used to store the shape of the potential VirtualList arraydescr = None # set only on freshly-allocated or fromstart arrays #arraysize = .. # valid if and only if arraydescr is not None @@ -45,6 +48,9 @@ def __init__(self, fromstart=False): self.fromstart = fromstart # for loops only: present since the start + def is_constant(self): + return self.knownvaluebox is not None + def add_escape_dependency(self, other): assert not self.escaped if self.dependencies is None: @@ -106,8 +112,17 @@ self.nodes = {} # Box -> InstanceNode def getnode(self, box): + if isinstance(box, Const): + return self.set_constant_node(box) return self.nodes.get(box, self.node_escaped) + def set_constant_node(self, box): + node = InstanceNode() + node.unique = UNIQUE_NO + node.knownvaluebox = box + self.nodes[box] = node + return node + def find_nodes(self, operations): for op in operations: opnum = op.opnum @@ -119,6 +134,13 @@ self.find_nodes_default(op) def find_nodes_default(self, op): + if op.is_always_pure(): + for arg in op.args: + node = self.getnode(arg) + if not node.is_constant(): + break + else: + self.set_constant_node(op.result) # default case: mark the arguments as escaping for box in op.args: self.getnode(box).mark_escaped() @@ -154,9 +176,14 @@ def find_nodes_GUARD_CLASS(self, op): instnode = self.getnode(op.args[0]) - if instnode.fromstart: # only useful in this case + if instnode.fromstart: # only useful (and safe) in this case instnode.knownclsbox = op.args[1] + def find_nodes_GUARD_VALUE(self, op): + instnode = self.getnode(op.args[0]) + if instnode.fromstart: # only useful (and safe) in this case + instnode.knownvaluebox = op.args[1] + def find_nodes_SETFIELD_GC(self, op): instnode = self.getnode(op.args[0]) fieldnode = self.getnode(op.args[1]) @@ -282,6 +309,10 @@ assert inputnode.fromstart if inputnode.escaped: return prebuiltNotSpecNode + if inputnode.is_constant() and \ + exitnode.is_constant() and \ + inputnode.knownvaluebox.equals(exitnode.knownvaluebox): + return ConstantSpecNode(inputnode.knownvaluebox) unique = exitnode.unique if unique == UNIQUE_NO: return prebuiltNotSpecNode @@ -368,6 +399,14 @@ def matches_instance_node(self, exitnode): return True +class __extend__(ConstantSpecNode): + def make_instance_node(self): + raise AssertionError, "not implemented (but not used actually)" + def matches_instance_node(self, exitnode): + if exitnode.knownvaluebox is None: + return False + return self.constbox.equals(exitnode.knownvaluebox) + class __extend__(VirtualInstanceSpecNode): def make_instance_node(self): instnode = InstanceNode() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Mon Aug 24 16:11:00 2009 @@ -1,7 +1,7 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.metainterp.specnode import SpecNode +from pypy.jit.metainterp.specnode import SpecNode, NotSpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode @@ -18,7 +18,7 @@ if not. """ optimizer = Optimizer(cpu, loop) - optimizer.setup_virtuals() + optimizer.setup_virtuals_and_constants() optimizer.propagate_forward() def optimize_bridge_1(cpu, bridge): @@ -291,13 +291,24 @@ if itemvalue is not None: itemvalue.get_args_for_fail(modifier) - class __extend__(SpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): + raise NotImplementedError + def teardown_virtual_node(self, optimizer, value, newexitargs): + raise NotImplementedError + +class __extend__(NotSpecNode): + def setup_virtual_node(self, optimizer, box, newinputargs): newinputargs.append(box) def teardown_virtual_node(self, optimizer, value, newexitargs): newexitargs.append(value.force_box()) +class __extend__(ConstantSpecNode): + def setup_virtual_node(self, optimizer, box, newinputargs): + optimizer.make_constant(box) + def teardown_virtual_node(self, optimizer, value, newexitargs): + pass + class __extend__(AbstractVirtualStructSpecNode): def setup_virtual_node(self, optimizer, box, newinputargs): vvalue = self._setup_virtual_node_1(optimizer, box) @@ -456,7 +467,7 @@ # ---------- - def setup_virtuals(self): + def setup_virtuals_and_constants(self): inputargs = self.loop.inputargs specnodes = self.loop.specnodes assert len(inputargs) == len(specnodes) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py Mon Aug 24 16:11:00 2009 @@ -5,6 +5,12 @@ __metaclass__ = extendabletype # extended in optimizefindnode.py __slots__ = () + def equals(self, other): + raise NotImplementedError + + def extract_runtime_data(self, cpu, valuebox, resultlist): + raise NotImplementedError + class NotSpecNode(SpecNode): __slots__ = () @@ -19,6 +25,18 @@ prebuiltNotSpecNode = NotSpecNode() +class ConstantSpecNode(SpecNode): + def __init__(self, constbox): + self.constbox = constbox + + def equals(self, other): + return isinstance(other, ConstantSpecNode) and \ + self.constbox == other.constbox + + def extract_runtime_data(self, cpu, valuebox, resultlist): + pass + + class AbstractVirtualStructSpecNode(SpecNode): def __init__(self, fields): self.fields = fields # list: [(fieldofs, subspecnode)] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 16:11:00 2009 @@ -15,6 +15,7 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.test.oparser import parse @@ -51,6 +52,7 @@ node = lltype.malloc(NODE) nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) myptr = nodebox.value + myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE)) nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) @@ -89,6 +91,7 @@ node = ootype.new(NODE) nodebox = BoxObj(ootype.cast_to_object(node)) myptr = nodebox.value + myptr2 = ootype.cast_to_object(ootype.new(NODE)) nodebox2 = BoxObj(ootype.cast_to_object(node)) valuedescr = cpu.fielddescrof(NODE, 'value') nextdescr = cpu.fielddescrof(NODE, 'next') @@ -130,12 +133,22 @@ self.cpu) else: return ConstObj(ootype.cast_to_object(cls_vtable)) + def constant(value): + if isinstance(lltype.typeOf(value), lltype.Ptr): + return ConstPtr(value) + elif isinstance(ootype.typeOf(value), ootype.OOType): + return ConstObj(ootype.cast_to_object(value)) + else: + return ConstInt(value) + def parsefields(kwds_fields): fields = [] for key, value in kwds_fields.items(): fields.append((self.namespace[key], value)) fields.sort(key = lambda (x, _): x.sort_key()) return fields + def makeConstant(value): + return ConstantSpecNode(constant(value)) def makeVirtual(cls_vtable, **kwds_fields): fields = parsefields(kwds_fields) return VirtualInstanceSpecNode(constclass(cls_vtable), fields) @@ -146,6 +159,7 @@ return VirtualStructSpecNode(typedescr, fields) # context = {'Not': prebuiltNotSpecNode, + 'Constant': makeConstant, 'Virtual': makeVirtual, 'VArray': makeVirtualArray, 'VStruct': makeVirtualStruct} @@ -163,9 +177,10 @@ class BaseTestOptimizeFindNode(BaseTest): - def find_nodes(self, ops, spectext, boxkinds=None): + def find_nodes(self, ops, spectext, boxkinds=None, **values): assert boxkinds is None or isinstance(boxkinds, dict) loop = self.parse(ops, boxkinds=boxkinds) + loop.setvalues(**values) perfect_specialization_finder = PerfectSpecializationFinder() perfect_specialization_finder.find_nodes_loop(loop) self.check_specnodes(loop.specnodes, spectext) @@ -633,15 +648,36 @@ """ self.find_nodes(ops, 'Not, Not') + def test_find_nodes_guard_value_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + self.find_nodes(ops, 'Constant(myptr)') + + def test_find_nodes_guard_value_same_as_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + p2 = same_as(ConstPtr(myptr)) + jump(p2) + """ + self.find_nodes(ops, 'Constant(myptr)', p2=self.myptr) + + # ------------------------------ # Bridge tests def find_bridge(self, ops, inputspectext, outputspectext, boxkinds=None, - mismatch=False): + mismatch=False, **values): assert boxkinds is None or isinstance(boxkinds, dict) inputspecnodes = self.unpack_specnodes(inputspectext) outputspecnodes = self.unpack_specnodes(outputspectext) bridge = self.parse(ops, boxkinds=boxkinds) + bridge.setvalues(**values) bridge_specialization_finder = BridgeSpecializationFinder() bridge_specialization_finder.find_nodes_bridge(bridge, inputspecnodes) matches = bridge_specialization_finder.bridge_matches(outputspecnodes) @@ -667,6 +703,23 @@ """ self.find_bridge(ops, 'Not', 'Not') + def test_bridge_simple_constant(self): + ops = """ + [] + jump(ConstPtr(myptr)) + """ + self.find_bridge(ops, '', 'Not') + self.find_bridge(ops, '', 'Constant(myptr)') + self.find_bridge(ops, '', 'Constant(myptr2)', mismatch=True) + + def test_bridge_simple_constant_mismatch(self): + ops = """ + [p0] + jump(p0) + """ + self.find_bridge(ops, 'Not', 'Not') + self.find_bridge(ops, 'Not', 'Constant(myptr)', mismatch=True) + def test_bridge_simple_virtual_1(self): ops = """ [i0] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Mon Aug 24 16:11:00 2009 @@ -223,6 +223,19 @@ """ self.optimize_loop(ops, 'Not', expected, i0=0, i1=1, i2=3) + def test_remove_guard_value_if_constant(self): + ops = """ + [p1] + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + expected = """ + [] + jump() + """ + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) + def test_ooisnull_oononnull_1(self): ops = """ [p0] @@ -1053,15 +1066,13 @@ jump(p1) """ expected = """ - [p1] - guard_value(p1, ConstPtr(myptr)) - fail() + [] i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr) escape(i1) escape(i1) - jump(ConstPtr(myptr)) + jump() """ - self.optimize_loop(ops, 'Not', expected, p1=self.nodebox.value) + self.optimize_loop(ops, 'Constant(myptr)', expected, p1=self.nodebox.value) def test_duplicate_getfield_sideeffects_1(self): ops = """ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py Mon Aug 24 16:11:00 2009 @@ -4,6 +4,7 @@ from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode from pypy.jit.metainterp.specnode import VirtualArraySpecNode from pypy.jit.metainterp.specnode import VirtualStructSpecNode +from pypy.jit.metainterp.specnode import ConstantSpecNode from pypy.jit.metainterp.specnode import equals_specnodes from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin @@ -40,6 +41,16 @@ assert equals_specnodes([sspecnode1], [sspecnode1]) assert not equals_specnodes([sspecnode1], [prebuiltNotSpecNode]) assert not equals_specnodes([prebuiltNotSpecNode], [sspecnode1]) + # + assert equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('foo')]) + assert not equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('bar')]) + assert not equals_specnodes([ConstantSpecNode('foo')], [prebuiltNotSpecNode]) + +def test_extract_runtime_data_0(): + res = [] + node = ConstantSpecNode('foo') + node.extract_runtime_data("cpu", "box1", res) + assert res == [] def test_extract_runtime_data_1(): res = [] From antocuni at codespeak.net Mon Aug 24 16:11:41 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 16:11:41 +0200 (CEST) Subject: [pypy-svn] r67165 - pypy/branch/pyjitpl5-constspecnode Message-ID: <20090824141141.1695A1683E6@codespeak.net> Author: antocuni Date: Mon Aug 24 16:11:41 2009 New Revision: 67165 Removed: pypy/branch/pyjitpl5-constspecnode/ Log: (antocuni, iko) kill merged branch From antocuni at codespeak.net Mon Aug 24 17:03:36 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 17:03:36 +0200 (CEST) Subject: [pypy-svn] r67166 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090824150336.4BC131680C1@codespeak.net> Author: antocuni Date: Mon Aug 24 17:03:35 2009 New Revision: 67166 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py Log: (antocuni, iko) use .equals instead of == to compare boxes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py Mon Aug 24 17:03:35 2009 @@ -27,11 +27,12 @@ class ConstantSpecNode(SpecNode): def __init__(self, constbox): + assert constbox is not None self.constbox = constbox def equals(self, other): return isinstance(other, ConstantSpecNode) and \ - self.constbox == other.constbox + self.constbox.equals(other.constbox) def extract_runtime_data(self, cpu, valuebox, resultlist): pass Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_specnode.py Mon Aug 24 17:03:35 2009 @@ -22,6 +22,12 @@ [(LLtypeMixin.adescr, prebuiltNotSpecNode), (LLtypeMixin.bdescr, prebuiltNotSpecNode)]) +def _get_cspecnode(s): + from pypy.rpython.module.support import LLSupport + llstr = lltype.cast_opaque_ptr(llmemory.GCREF, LLSupport.to_rstr(s)) + box = BoxPtr(llstr) + return ConstantSpecNode(box) + def test_equals_specnodes(): assert equals_specnodes([prebuiltNotSpecNode, prebuiltNotSpecNode], [prebuiltNotSpecNode, prebuiltNotSpecNode]) @@ -42,9 +48,11 @@ assert not equals_specnodes([sspecnode1], [prebuiltNotSpecNode]) assert not equals_specnodes([prebuiltNotSpecNode], [sspecnode1]) # - assert equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('foo')]) - assert not equals_specnodes([ConstantSpecNode('foo')], [ConstantSpecNode('bar')]) - assert not equals_specnodes([ConstantSpecNode('foo')], [prebuiltNotSpecNode]) + foonode = _get_cspecnode('foo') + barnode = _get_cspecnode('bar') + assert equals_specnodes([foonode], [foonode]) + assert not equals_specnodes([foonode], [barnode]) + assert not equals_specnodes([foonode], [prebuiltNotSpecNode]) def test_extract_runtime_data_0(): res = [] From antocuni at codespeak.net Mon Aug 24 17:31:16 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 17:31:16 +0200 (CEST) Subject: [pypy-svn] r67167 - pypy/branch/pyjitpl5/pypy/translator/cli Message-ID: <20090824153116.B88EA1680A3@codespeak.net> Author: antocuni Date: Mon Aug 24 17:31:16 2009 New Revision: 67167 Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Log: catch ArithmeticException only if needed Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Mon Aug 24 17:31:16 2009 @@ -18,9 +18,10 @@ def _abs(type_): return [PushAllArgs, 'call %s class [mscorlib]System.Math::Abs(%s)' % (type_, type_), StoreResult] -def _check_ovf(op): - mapping = [('[mscorlib]System.OverflowException', 'exceptions.OverflowError'), - ('[mscorlib]System.ArithmeticException', 'exceptions.OverflowError')] +def _check_ovf(op, catch_arithmexic_exception=False): + mapping = [('[mscorlib]System.OverflowException', 'exceptions.OverflowError')] + if catch_arithmexic_exception: + mapping.append(('[mscorlib]System.ArithmeticException', 'exceptions.OverflowError')) return [MapException(op, mapping)] def _check_zer(op): @@ -174,7 +175,7 @@ 'int_sub_ovf': _check_ovf('sub.ovf'), 'int_mul_ovf': _check_ovf('mul.ovf'), 'int_floordiv_ovf': _check_ovf('div'), - 'int_mod_ovf': _check_ovf('rem'), + 'int_mod_ovf': _check_ovf('rem', catch_arithmexic_exception=True), 'int_lt_ovf': 'clt', 'int_le_ovf': _not('cgt'), 'int_eq_ovf': 'ceq', From arigo at codespeak.net Mon Aug 24 17:43:47 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 17:43:47 +0200 (CEST) Subject: [pypy-svn] r67168 - in pypy/branch/pyjitpl5-noframestack/pypy: interpreter module/__builtin__ module/_stackless module/signal module/sys objspace objspace/flow objspace/std tool/pytest Message-ID: <20090824154347.10FC2168065@codespeak.net> Author: arigo Date: Mon Aug 24 17:43:46 2009 New Revision: 67168 Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/baseobjspace.py pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py pypy/branch/pyjitpl5-noframestack/pypy/interpreter/pyframe.py pypy/branch/pyjitpl5-noframestack/pypy/module/__builtin__/compiling.py pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_clonable.py pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_greenlet.py pypy/branch/pyjitpl5-noframestack/pypy/module/signal/interp_signal.py pypy/branch/pyjitpl5-noframestack/pypy/module/sys/vm.py pypy/branch/pyjitpl5-noframestack/pypy/objspace/flow/flowcontext.py pypy/branch/pyjitpl5-noframestack/pypy/objspace/std/typeobject.py pypy/branch/pyjitpl5-noframestack/pypy/objspace/taint.py pypy/branch/pyjitpl5-noframestack/pypy/tool/pytest/appsupport.py Log: Intermediate check-in. I haven't run the tests yet. Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/interpreter/baseobjspace.py Mon Aug 24 17:43:46 2009 @@ -479,8 +479,8 @@ def getexecutioncontext(self): "Return what we consider to be the active execution context." - # Important: the annotator must not see a prebuilt ExecutionContext - # for reasons related to the specialization of the framestack attribute + # Important: the annotator must not see a prebuilt ExecutionContext: + # you should not see frames while you translate # so we make sure that the threadlocals never *have* an # ExecutionContext during translation. if self.config.translating and not we_are_translated(): Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py Mon Aug 24 17:43:46 2009 @@ -3,11 +3,9 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit -def new_framestack(): - return Stack() - def app_profile_call(space, w_callable, frame, event, w_arg): space.call_function(w_callable, space.wrap(frame), @@ -19,7 +17,10 @@ def __init__(self, space): self.space = space - self.framestack = new_framestack() + # 'some_frame' points to any frame from this thread's frame stack + # (although in general it should point to the top one). + self.some_frame = None + self.framestackdepth = 0 # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. @@ -29,40 +30,68 @@ self.profilefunc = None self.w_profilefuncarg = None + def gettopframe(self): + frame = self.some_frame + if frame is not None: + while frame.f_forward is not None: + frame = frame.f_forward + return frame + + def gettopframe_nohidden(self): + frame = self.gettopframe() + while frame and frame.hide(): + frame = frame.f_back + return frame + + def getnextframe_nohidden(frame): + frame = frame.f_back + while frame and frame.hide(): + frame = frame.f_back + return frame + getnextframe_nohidden = staticmethod(getnextframe_nohidden) + def enter(self, frame): - if self.framestack.depth() > self.space.sys.recursionlimit: + if self.framestackdepth > self.space.sys.recursionlimit: raise OperationError(self.space.w_RuntimeError, self.space.wrap("maximum recursion depth exceeded")) - try: - frame.f_back = self.framestack.top() - except IndexError: - frame.f_back = None - - if not frame.hide(): - self.framestack.push(frame) + self.framestackdepth += 1 + # + curtopframe = self.gettopframe() + frame.f_back = curtopframe + if curtopframe is not None: + curtopframe.f_forward = frame + if not we_are_jitted(): + self.some_frame = frame def leave(self, frame): if self.profilefunc: self._trace(frame, 'leaveframe', self.space.w_None) - - if not frame.hide(): - self.framestack.pop() - if self.w_tracefunc is not None: - self.space.frame_trace_action.fire() + + #assert frame is self.gettopframe() --- slowish + f_back = frame.f_back + if f_back is not None: + f_back.f_forward = None + if not we_are_jitted() or self.some_frame is frame: + self.some_frame = f_back + + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() class Subcontext(object): # coroutine: subcontext support def __init__(self): - self.framestack = new_framestack() + self.topframe = None + self.framestackdepth = 0 self.w_tracefunc = None self.profilefunc = None self.w_profilefuncarg = None self.is_tracing = 0 def enter(self, ec): - ec.framestack = self.framestack + ec.some_frame = self.topframe + ec.framestackdepth = self.framestackdepth ec.w_tracefunc = self.w_tracefunc ec.profilefunc = self.profilefunc ec.w_profilefuncarg = self.w_profilefuncarg @@ -70,30 +99,52 @@ ec.space.frame_trace_action.fire() def leave(self, ec): - self.framestack = ec.framestack + self.topframe = ec.gettopframe() + self.framestackdepth = ec.framestackdepth self.w_tracefunc = ec.w_tracefunc self.profilefunc = ec.profilefunc self.w_profilefuncarg = ec.w_profilefuncarg self.is_tracing = ec.is_tracing + def clear_framestack(self): + self.topframe = None + self.framestackdepth = 0 + # the following interface is for pickling and unpickling def getstate(self, space): - # we just save the framestack - items = [space.wrap(item) for item in self.framestack.items] - return space.newtuple(items) - - def setstate(self, space, w_state): - from pypy.interpreter.pyframe import PyFrame - items = [space.interp_w(PyFrame, w_item) - for w_item in space.unpackiterable(w_state)] - self.framestack.items = items + # we just save the top frame, which brings the whole frame stack + f = self.topframe + return space.wrap(f) + + def setstate(self, space, w_frame): + f = space.interp_w(PyFrame, w_frame) + self.topframe = f + count = 0 + if f: + count = 1 + while f.f_back: + count += 1 + f = f.f_back + self.framestackdepth = count + + def getframestack(self): + index = self.framestackdepth + lst = [None] * index + f = self.topframe + while index > 0: + index -= 1 + lst[index] = f + f = f.f_back + assert f is None + return lst # coroutine: I think this is all, folks! def get_builtin(self): - try: - return self.framestack.top().builtin - except IndexError: + frame = self.gettopframe_nohidden() + if frame is not None: + return frame.builtin + else: return self.space.builtin # XXX this one should probably be dropped in favor of a module @@ -129,16 +180,6 @@ else: self._trace(frame, 'c_exception', w_exc) - def _llprofile(self, event, w_arg): - fr = self.framestack.items - space = self.space - w_callback = self.profilefunc - if w_callback is not None: - frame = None - if fr: - frame = fr[0] - self.profilefunc(space, self.w_profilefuncarg, frame, event, w_arg) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" @@ -177,10 +218,11 @@ def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!! """Implements sys.exc_info(). Return an OperationError instance or None.""" - for i in range(self.framestack.depth()): - frame = self.framestack.top(i) + frame = self.gettopframe_nohidden() + while frame: if frame.last_exception is not None: return frame.last_exception + frame = self.getnextframe_nohidden(frame) return None def settrace(self, w_func): @@ -204,8 +246,10 @@ if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - for frame in self.framestack.items: + frame = self.gettopframe_nohidden() + while frame: frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) self.w_profilefuncarg = w_arg def call_tracing(self, w_func, w_args): Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/interpreter/pyframe.py Mon Aug 24 17:43:46 2009 @@ -39,7 +39,8 @@ frame_finished_execution = False last_instr = -1 last_exception = None - f_back = None + f_back = None # these two should be modified together + f_forward = None # they make a doubly-linked list w_f_trace = None # For tracing instr_lb = 0 Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/__builtin__/compiling.py Mon Aug 24 17:43:46 2009 @@ -31,11 +31,8 @@ ec = space.getexecutioncontext() if not dont_inherit: - try: - caller = ec.framestack.top() - except IndexError: - pass - else: + caller = ec.gettopframe_nohidden() + if caller: flags |= ec.compiler.getcodeflags(caller.getcode()) if mode not in ('exec', 'eval', 'single'): @@ -70,11 +67,7 @@ raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) - try: - caller = space.getexecutioncontext().framestack.top() - except IndexError: - caller = None - + caller = space.getexecutioncontext().gettopframe_nohidden() if w_globals is None or space.is_w(w_globals, space.w_None): if caller is None: w_globals = w_locals = space.newdict() Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_clonable.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_clonable.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_clonable.py Mon Aug 24 17:43:46 2009 @@ -65,7 +65,7 @@ class AppClonableCoState(AppCoState): def post_install(self): self.current = self.main = AppClonableCoroutine(self.space, state=self) - self.main.subctx.framestack = None # wack + self.main.subctx.clear_framestack() # wack def post_install(module): makeStaticMethod(module, 'clonable', 'getcurrent') Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py Mon Aug 24 17:43:46 2009 @@ -174,7 +174,7 @@ def descr__setstate__(self, space, w_args): try: - w_flags, w_state, w_thunk, w_parent = space.unpackiterable(w_args, + w_flags, w_frame, w_thunk, w_parent = space.unpackiterable(w_args, expected_length=4) except UnpackValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) @@ -183,7 +183,7 @@ w_parent = self.w_getmain(space) self.parent = space.interp_w(AppCoroutine, w_parent) ec = self.space.getexecutioncontext() - self.subctx.setstate(self.space, w_state) + self.subctx.setstate(space, w_frame) self.reconstruct_framechain() if space.is_w(w_thunk, space.w_None): self.thunk = None @@ -199,7 +199,7 @@ def reconstruct_framechain(self): from pypy.interpreter.pyframe import PyFrame from pypy.rlib.rstack import resume_state_create - if self.subctx.framestack.empty(): + if self.subctx.topframe is None: self.frame = None return @@ -213,7 +213,7 @@ # ("appthunk", costate, returns=w_result) appthunk_frame = resume_state_create(_bind_frame, "appthunk", costate) chain = appthunk_frame - for frame in self.subctx.framestack.items: + for frame in self.subctx.getframestack(): assert isinstance(frame, PyFrame) # ("execute_frame", self, executioncontext, returns=w_exitvalue) chain = resume_state_create(chain, "execute_frame", frame, ec) @@ -270,11 +270,15 @@ def w_descr__framestack(space, self): assert isinstance(self, AppCoroutine) - if self.subctx.framestack is not None: - items = [space.wrap(item) for item in self.subctx.framestack.items] - return space.newtuple(items) - else: - return space.newtuple([]) + index = self.subctx.framestackdepth + items = [None] * index + f = self.subctx.topframe + while index > 0: + index -= 1 + items[index] = space.wrap(f) + f = f.f_back + assert f is None + return space.newtuple(items) def makeStaticMethod(module, classname, funcname): space = module.space @@ -333,7 +337,7 @@ def post_install(self): self.current = self.main = AppCoroutine(self.space, state=self) - self.main.subctx.framestack = None # wack + self.main.subctx.clear_framestack() # wack def return_main(space): return AppCoroutine._get_state(space).main Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_greenlet.py Mon Aug 24 17:43:46 2009 @@ -52,7 +52,7 @@ self.active = is_main self.subctx = space.getexecutioncontext().Subcontext() if is_main: - self.subctx.framestack = None # wack + self.subctx.clear_framestack() # wack else: self.bind(GreenletThunk(self)) @@ -191,10 +191,7 @@ if not self.active or self.costate.current is self: f = None else: - try: - f = self.subctx.framestack.top(0) - except IndexError: - f = None + f = self.subctx.topframe return space.wrap(f) def get(space, name): Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/signal/interp_signal.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/signal/interp_signal.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/signal/interp_signal.py Mon Aug 24 17:43:46 2009 @@ -103,10 +103,7 @@ # invoke the app-level handler space = self.space ec = space.getexecutioncontext() - try: - w_frame = ec.framestack.top() - except IndexError: - w_frame = space.w_None + w_frame = space.wrap(ec.gettopframe_nohidden()) space.call_function(w_handler, space.wrap(n), w_frame) def report_pending_signals(self): Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/sys/vm.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/sys/vm.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/sys/vm.py Mon Aug 24 17:43:46 2009 @@ -26,14 +26,19 @@ This function should be used for internal and specialized purposes only.""" depth = space.int_w(w_depth) - try: - f = space.getexecutioncontext().framestack.top(depth) - except IndexError: - raise OperationError(space.w_ValueError, - space.wrap("call stack is not deep enough")) - except ValueError: + if depth < 0: raise OperationError(space.w_ValueError, space.wrap("frame index must not be negative")) + ec = space.getexecutioncontext() + f = ec.gettopframe_nohidden() + while True: + if f is None: + raise OperationError(space.w_ValueError, + space.wrap("call stack is not deep enough")) + if depth == 0: + break + depth -= 1 + f = ec.getnextframe_nohidden(f) return space.wrap(f) # directly from the C code in ceval.c, might be moved somewhere else. Modified: pypy/branch/pyjitpl5-noframestack/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/objspace/flow/flowcontext.py Mon Aug 24 17:43:46 2009 @@ -259,7 +259,8 @@ except StopFlowing: continue # restarting a dead SpamBlock try: - self.framestack.push(frame) + old_frame = self.some_frame + self.some_frame = frame self.crnt_frame = frame try: w_result = frame.dispatch(frame.pycode, @@ -267,7 +268,7 @@ self) finally: self.crnt_frame = None - self.framestack.pop() + self.some_frame = old_frame except OperationThatShouldNotBePropagatedError, e: raise Exception( Modified: pypy/branch/pyjitpl5-noframestack/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/objspace/std/typeobject.py Mon Aug 24 17:43:46 2009 @@ -535,11 +535,8 @@ # initialize __module__ in the dict (user-defined types only) if '__module__' not in w_self.dict_w: space = w_self.space - try: - caller = space.getexecutioncontext().framestack.top() - except IndexError: - pass - else: + caller = space.getexecutioncontext().gettopframe_nohidden() + if caller is not None: w_globals = caller.w_globals w_name = space.finditem(w_globals, space.wrap('__name__')) if w_name is not None: Modified: pypy/branch/pyjitpl5-noframestack/pypy/objspace/taint.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/objspace/taint.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/objspace/taint.py Mon Aug 24 17:43:46 2009 @@ -43,15 +43,11 @@ def record_debug_info(self): ec = self.space.getexecutioncontext() - try: - frame = ec.framestack.top() - except IndexError: - pass - else: - if isinstance(frame, PyFrame): - self.filename = frame.pycode.co_filename - self.codename = frame.pycode.co_name - self.codeline = frame.get_last_lineno() + frame = ec.gettopframe_nohidden() + if isinstance(frame, PyFrame): # and, in particular, frame != None + self.filename = frame.pycode.co_filename + self.codename = frame.pycode.co_name + self.codeline = frame.get_last_lineno() if get_debug_level(self.space) > 0: self.debug_dump() @@ -177,15 +173,11 @@ filename = '?' codename = '?' codeline = 0 - try: - frame = ec.framestack.top() - except IndexError: - pass - else: - if isinstance(frame, PyFrame): - filename = frame.pycode.co_filename - codename = frame.pycode.co_name - codeline = frame.get_last_lineno() + frame = ec.gettopframe_nohidden() + if isinstance(frame, PyFrame): # and, in particular, frame != None + filename = frame.pycode.co_filename + codename = frame.pycode.co_name + codeline = frame.get_last_lineno() os.write(2, 'Taint Bomb in file "%s", line %d, in %s\n %s\n' % ( filename, codeline, codename, operr.errorstr(space))) Modified: pypy/branch/pyjitpl5-noframestack/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/tool/pytest/appsupport.py Mon Aug 24 17:43:46 2009 @@ -139,18 +139,16 @@ w_parent_init = space.getattr(w_BuiltinAssertionError, space.wrap('__init__')) space.call_args(w_parent_init, __args__.prepend(w_self)) - framestack = space.getexecutioncontext().framestack ## # Argh! we may see app-level helpers in the frame stack! ## # that's very probably very bad... -## if frame.code.co_name == 'normalize_exception': -## frame = framestack.top(1) +## ^^^the above comment may be outdated, but we are not sure # if the assertion provided a message, don't do magic args_w, kwargs_w = __args__.unpack() if args_w: w_msg = args_w[0] else: - frame = framestack.top(0) + frame = space.getexecutioncontext().gettopframe() runner = AppFrame(space, frame) try: source = runner.statement @@ -192,7 +190,7 @@ "after a string expression")) expr = space.unwrap(w_expr) source = py.code.Source(expr) - frame = space.getexecutioncontext().framestack.top() + frame = space.getexecutioncontext().gettopframe() w_locals = frame.getdictscope() w_locals = space.call_method(w_locals, 'copy') for key, w_value in kwds_w.items(): From antocuni at codespeak.net Mon Aug 24 17:45:38 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 24 Aug 2009 17:45:38 +0200 (CEST) Subject: [pypy-svn] r67169 - pypy/branch/pyjitpl5/pypy/jit/backend/cli Message-ID: <20090824154538.C1C99168069@codespeak.net> Author: antocuni Date: Mon Aug 24 17:45:34 2009 New Revision: 67169 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Log: emit *_ovf operations differently. This is only slightly more efficient now, but having a separate method for them will make optimizing it easier in the future Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Mon Aug 24 17:45:34 2009 @@ -383,6 +383,18 @@ self.il.Emit(OpCodes.Stfld, self.exc_value_field) self.il.EndExceptionBlock() + def emit_ovf_op(self, op, emit_op): + # clear the overflow flag + self.il.Emit(OpCodes.Ldc_I4_0) + self.av_ovf_flag.store(self) + lbl = self.il.BeginExceptionBlock() + emit_op(self, op) + self.il.Emit(OpCodes.Leave, lbl) + self.il.BeginCatchBlock(dotnet.typeof(System.OverflowException)) + self.il.Emit(OpCodes.Ldc_I4_1) + self.av_ovf_flag.store(self) + self.il.EndExceptionBlock() + def mark(self, msg): self.il.Emit(OpCodes.Ldstr, msg) self.il.Emit(OpCodes.Pop) @@ -724,14 +736,21 @@ value = instrlist[0] exctypes = [parse_exctype(exctype) for exctype, _ in value.mapping] exctypes = ['dotnet.typeof(%s)' % exctype for exctype in exctypes] + is_ovf = (exctypes == ['dotnet.typeof(System.OverflowException)']) impl_func = render_op(methname + '_impl', value.instr) if not impl_func: return - src = py.code.Source(""" - def %s(self, op): - exctypes = [%s] - self.emit_raising_op(op, impl_func, exctypes) - """ % (methname, ', '.join(exctypes))) + if is_ovf: + src = py.code.Source(""" + def %s(self, op): + self.emit_ovf_op(op, impl_func) + """ % (methname,)) + else: + src = py.code.Source(""" + def %s(self, op): + exctypes = [%s] + self.emit_raising_op(op, impl_func, exctypes) + """ % (methname, ', '.join(exctypes))) dic = {'System': System, 'dotnet': dotnet, 'impl_func': impl_func} From arigo at codespeak.net Mon Aug 24 18:02:37 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 18:02:37 +0200 (CEST) Subject: [pypy-svn] r67170 - in pypy/branch/pyjitpl5-noframestack/pypy: interpreter module/_stackless Message-ID: <20090824160237.6FB2A168077@codespeak.net> Author: arigo Date: Mon Aug 24 18:02:36 2009 New Revision: 67170 Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py Log: Some fixes. Modified: pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/interpreter/executioncontext.py Mon Aug 24 18:02:36 2009 @@ -73,6 +73,7 @@ f_back.f_forward = None if not we_are_jitted() or self.some_frame is frame: self.some_frame = f_back + self.framestackdepth -= 1 if self.w_tracefunc is not None and not frame.hide(): self.space.frame_trace_action.fire() @@ -112,20 +113,19 @@ # the following interface is for pickling and unpickling def getstate(self, space): - # we just save the top frame, which brings the whole frame stack - f = self.topframe - return space.wrap(f) - - def setstate(self, space, w_frame): - f = space.interp_w(PyFrame, w_frame) - self.topframe = f - count = 0 - if f: - count = 1 - while f.f_back: - count += 1 - f = f.f_back - self.framestackdepth = count + # XXX we could just save the top frame, which brings + # the whole frame stack, but right now we get the whole stack + items = [space.wrap(f) for f in self.getframestack()] + return space.newtuple(items) + + def setstate(self, space, w_state): + from pypy.interpreter.pyframe import PyFrame + frames_w = space.unpackiterable(w_state) + if len(frames_w) > 0: + self.topframe = space.interp_w(PyFrame, frames_w[-1]) + else: + self.topframe = None + self.framestackdepth = len(frames_w) def getframestack(self): index = self.framestackdepth Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/_stackless/interp_coroutine.py Mon Aug 24 18:02:36 2009 @@ -174,7 +174,7 @@ def descr__setstate__(self, space, w_args): try: - w_flags, w_frame, w_thunk, w_parent = space.unpackiterable(w_args, + w_flags, w_state, w_thunk, w_parent = space.unpackiterable(w_args, expected_length=4) except UnpackValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) @@ -183,7 +183,7 @@ w_parent = self.w_getmain(space) self.parent = space.interp_w(AppCoroutine, w_parent) ec = self.space.getexecutioncontext() - self.subctx.setstate(space, w_frame) + self.subctx.setstate(space, w_state) self.reconstruct_framechain() if space.is_w(w_thunk, space.w_None): self.thunk = None From fijal at codespeak.net Mon Aug 24 18:04:25 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 18:04:25 +0200 (CEST) Subject: [pypy-svn] r67171 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090824160425.D33D1168077@codespeak.net> Author: fijal Date: Mon Aug 24 18:04:25 2009 New Revision: 67171 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Log: (pedronis, cfbolz, fijal, gcc -E, emacs) Found out that macros expand differently than we thought before. It makes JIT-based mallocs not slower than normal ones under boehm. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Mon Aug 24 18:04:25 2009 @@ -31,7 +31,7 @@ def __init__(self, gcdescr, cpu): # grab a pointer to the Boehm 'malloc' function compilation_info = ExternalCompilationInfo(libraries=['gc']) - malloc_fn_ptr = rffi.llexternal("GC_malloc", + malloc_fn_ptr = rffi.llexternal("GC_local_malloc", [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, From fijal at codespeak.net Mon Aug 24 18:51:37 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 24 Aug 2009 18:51:37 +0200 (CEST) Subject: [pypy-svn] r67172 - pypy/branch/pyjitpl5-noframestack/pypy/module/pypyjit Message-ID: <20090824165137.12DF5168053@codespeak.net> Author: fijal Date: Mon Aug 24 18:51:35 2009 New Revision: 67172 Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/pypyjit/interp_jit.py Log: *ARGH* Make f_forward a virtualizable Modified: pypy/branch/pyjitpl5-noframestack/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5-noframestack/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5-noframestack/pypy/module/pypyjit/interp_jit.py Mon Aug 24 18:51:35 2009 @@ -22,7 +22,7 @@ PyFrame._virtualizable2_ = ['last_instr', 'pycode', 'valuestackdepth', 'valuestack_w[*]', - 'fastlocals_w[*]', + 'fastlocals_w[*]', 'f_forward', ] JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] From arigo at codespeak.net Mon Aug 24 19:44:34 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 19:44:34 +0200 (CEST) Subject: [pypy-svn] r67173 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test Message-ID: <20090824174434.326C616805D@codespeak.net> Author: arigo Date: Mon Aug 24 19:44:33 2009 New Revision: 67173 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py Log: Rumble rumble rumble. Fix this formula to match the formula in regalloc.py. Also fix the test to fail because of it (thanks Samuele). Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py Mon Aug 24 19:44:33 2009 @@ -241,7 +241,7 @@ for loc in gclocs: assert isinstance(loc, MODRM) assert loc.is_relative_to_ebp() - shape.append(self.LOC_EBP_BASED | (-4 * (1 + loc.position))) + shape.append(self.LOC_EBP_BASED | (-4 * (4 + loc.position))) return shape def _compress_callshape(self, shape): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py Mon Aug 24 19:44:33 2009 @@ -116,12 +116,17 @@ def test_GcRootMap_asmgcc(): gcrootmap = GcRootMap_asmgcc() shape = gcrootmap._get_callshape([stack_pos(1), stack_pos(55)]) - assert shape == [6, -2, -6, -10, 2, 0, -8|2, -224|2] + num1 = stack_pos(1).ofs_relative_to_ebp() + num2 = stack_pos(55).ofs_relative_to_ebp() + assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2] # shapeaddr = gcrootmap.encode_callshape([stack_pos(1), stack_pos(55)]) PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) - for i, expected in enumerate([131, 59, 11, 0, 4, 19, 11, 3, 12]): + num1a = -2*(num1|2)-1 + num2a = ((-2*(num2|2)-1) >> 7) | 128 + num2b = (-2*(num2|2)-1) & 127 + for i, expected in enumerate([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]): assert p[i] == expected # retaddr = rffi.cast(llmemory.Address, 1234567890) From arigo at codespeak.net Mon Aug 24 20:54:26 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Aug 2009 20:54:26 +0200 (CEST) Subject: [pypy-svn] r67174 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090824185426.86AB7168069@codespeak.net> Author: arigo Date: Mon Aug 24 20:54:25 2009 New Revision: 67174 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: ARGH. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 24 20:54:25 2009 @@ -667,6 +667,17 @@ """ self.find_nodes(ops, 'Constant(myptr)', p2=self.myptr) + def test_find_nodes_call_escapes(self): + py.test.skip("ARGH, bug") + ops = """ + [i0, p1, p4] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, p2, descr=nextdescr) + call(i0) + p3 = getfield_gc(p1, descr=nextdescr) + jump(i0, p1, p3) + """ + self.find_nodes(ops, 'Not, Not, Not') # ------------------------------ # Bridge tests From arigo at codespeak.net Tue Aug 25 09:16:19 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 09:16:19 +0200 (CEST) Subject: [pypy-svn] r67175 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090825071619.DE0E61683B8@codespeak.net> Author: arigo Date: Tue Aug 25 09:16:16 2009 New Revision: 67175 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Log: This fix is probably related to the introduction of ConstantSpecNode. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Tue Aug 25 09:16:16 2009 @@ -100,15 +100,14 @@ assert res == 5040 self.check_loops({'int_mul':1, 'jump':1, 'int_sub':1, 'int_is_true':1, 'int_le':1, - 'guard_false':1, 'guard_value':1}) + 'guard_false':1}) def test_tl_2(self): res = self.meta_interp(self.main.im_func, [1, 10], listops=True, backendopt=True) assert res == self.main.im_func(1, 10) self.check_loops({'int_sub':1, 'int_le':1, - 'int_is_true':1, 'guard_false':1, 'jump':1, - 'guard_value':1}) + 'int_is_true':1, 'guard_false':1, 'jump':1}) def test_tl_call(self, listops=True, policy=None): from pypy.jit.tl.tl import interp From arigo at codespeak.net Tue Aug 25 09:19:59 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 09:19:59 +0200 (CEST) Subject: [pypy-svn] r67176 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090825071959.0B52D1683D3@codespeak.net> Author: arigo Date: Tue Aug 25 09:19:58 2009 New Revision: 67176 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: Fix two issues with optimizefindnode: - The dependencies order was ignored when doing set_unique_nodes(). Fixing it also has he result of making all "p123" tests give a saner outcome. - We would not produce a ConstantSpecNode for escaped nodes, but we should as far as I can tell. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Tue Aug 25 09:19:58 2009 @@ -66,9 +66,13 @@ self.dependencies = None for box in deps: box.mark_escaped() + # see test_find_nodes_store_into_loop_constant_1 for this: + box.unique = UNIQUE_NO def set_unique_nodes(self): - if self.escaped or self.fromstart or self.unique != UNIQUE_UNKNOWN: + if self.fromstart: + self.mark_escaped() + if self.escaped or self.unique != UNIQUE_UNKNOWN: # this node is not suitable for being a virtual, or we # encounter it more than once when doing the recursion self.unique = UNIQUE_NO @@ -307,12 +311,12 @@ def intersect(self, inputnode, exitnode): assert inputnode.fromstart - if inputnode.escaped: - return prebuiltNotSpecNode if inputnode.is_constant() and \ exitnode.is_constant() and \ inputnode.knownvaluebox.equals(exitnode.knownvaluebox): return ConstantSpecNode(inputnode.knownvaluebox) + if inputnode.escaped: + return prebuiltNotSpecNode unique = exitnode.unique if unique == UNIQUE_NO: return prebuiltNotSpecNode Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 25 09:19:58 2009 @@ -206,9 +206,11 @@ i1 = int_sub(i0, 1) p2 = getfield_gc(p0, descr=nextdescr) setfield_gc(p2, i1, descr=valuedescr) - jump(p0) + p3 = new_with_vtable(ConstClass(node_vtable)) + jump(p3) """ - boxes, getnode = self.find_nodes(ops, 'Not') + boxes, getnode = self.find_nodes(ops, + 'Virtual(node_vtable, nextdescr=Not)') assert not getnode(boxes.p0).escaped assert not getnode(boxes.p1).escaped assert not getnode(boxes.p2).escaped @@ -228,9 +230,11 @@ setfield_gc(p3, i1, descr=valuedescr) p4 = getfield_gc(p1, descr=nextdescr) setfield_gc(p4, i1, descr=valuedescr) - jump(p0) + p5 = new_with_vtable(ConstClass(node_vtable)) + jump(p5) """ - boxes, getnode = self.find_nodes(ops, 'Not') + boxes, getnode = self.find_nodes(ops, + 'Virtual(node_vtable, nextdescr=Not)') assert not getnode(boxes.p0).escaped assert getnode(boxes.p1).escaped assert getnode(boxes.p2).escaped # forced by p1 @@ -493,6 +497,15 @@ """ self.find_nodes(ops, 'Not') + def test_find_nodes_p12_simple(self): + ops = """ + [p1] + i3 = getfield_gc(p1, descr=valuedescr) + escape(i3) + jump(p1) + """ + self.find_nodes(ops, 'Not') + def test_find_nodes_p123_simple(self): ops = """ [i1, p2, p3] @@ -503,7 +516,19 @@ jump(i1, p1, p2) """ # We cannot track virtuals that survive for more than two iterations. - self.find_nodes(ops, 'Not, Virtual(node_vtable, valuedescr=Not), Not') + self.find_nodes(ops, 'Not, Not, Not') + + def test_find_nodes_p1234_simple(self): + ops = """ + [i1, p2, p3, p4] + i4 = getfield_gc(p4, descr=valuedescr) + escape(i4) + p1 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, i1, descr=valuedescr) + jump(i1, p1, p2, p3) + """ + # We cannot track virtuals that survive for more than two iterations. + self.find_nodes(ops, 'Not, Not, Not, Not') def test_find_nodes_p123_guard_class(self): ops = """ @@ -517,7 +542,7 @@ jump(i1, p1, p2) """ # We cannot track virtuals that survive for more than two iterations. - self.find_nodes(ops, 'Not, Virtual(node_vtable, valuedescr=Not), Not') + self.find_nodes(ops, 'Not, Not, Not') def test_find_nodes_p123_rec(self): ops = """ @@ -533,7 +558,7 @@ """ # We cannot track virtuals that survive for more than two iterations. self.find_nodes(ops, '''Not, - Virtual(node_vtable, valuedescr=Not), + Not, Virtual(node_vtable, nextdescr=Not)''') def test_find_nodes_setfield_bug(self): @@ -657,6 +682,16 @@ """ self.find_nodes(ops, 'Constant(myptr)') + def test_find_nodes_guard_value_escaping_constant(self): + ops = """ + [p1] + escape(p1) + guard_value(p1, ConstPtr(myptr)) + fail() + jump(ConstPtr(myptr)) + """ + self.find_nodes(ops, 'Constant(myptr)') + def test_find_nodes_guard_value_same_as_constant(self): ops = """ [p1] @@ -667,18 +702,34 @@ """ self.find_nodes(ops, 'Constant(myptr)', p2=self.myptr) - def test_find_nodes_call_escapes(self): - py.test.skip("ARGH, bug") + def test_find_nodes_store_into_loop_constant_1(self): ops = """ [i0, p1, p4] p2 = new_with_vtable(ConstClass(node_vtable)) setfield_gc(p1, p2, descr=nextdescr) - call(i0) - p3 = getfield_gc(p1, descr=nextdescr) - jump(i0, p1, p3) + jump(i0, p1, p2) + """ + self.find_nodes(ops, 'Not, Not, Not') + + def test_find_nodes_store_into_loop_constant_2(self): + ops = """ + [i0, p4, p1] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, p2, descr=nextdescr) + jump(i0, p2, p1) """ self.find_nodes(ops, 'Not, Not, Not') + def test_find_nodes_store_into_loop_constant_3(self): + ops = """ + [i0, p1] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, p2, descr=nextdescr) + call(i0) + jump(i0, p1) + """ + self.find_nodes(ops, 'Not, Not') + # ------------------------------ # Bridge tests Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 25 09:19:58 2009 @@ -415,18 +415,8 @@ setfield_gc(p1, i1, descr=valuedescr) jump(i1, p1, p2) """ - expected = """ - [i1, i2, p3] - i3 = getfield_gc(p3, descr=valuedescr) - escape(i3) - p2b = new_with_vtable(ConstClass(node_vtable)) - setfield_gc(p2b, i2, descr=valuedescr) - jump(i1, i1, p2b) - """ # We cannot track virtuals that survive for more than two iterations. - self.optimize_loop(ops, - 'Not, Virtual(node_vtable, valuedescr=Not), Not', - expected) + self.optimize_loop(ops, 'Not, Not, Not', ops) def test_p123_nested(self): ops = """ @@ -434,32 +424,15 @@ i3 = getfield_gc(p3, descr=valuedescr) escape(i3) p1 = new_with_vtable(ConstClass(node_vtable)) - p1sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p1, i1, descr=valuedescr) - setfield_gc(p1, p1sub, descr=nextdescr) + p1sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p1sub, i1, descr=valuedescr) + setfield_gc(p1, p1sub, descr=nextdescr) jump(i1, p1, p2) """ - expected = """ - [i1, i2, i2sub, p3] - i3 = getfield_gc(p3, descr=valuedescr) - escape(i3) - p2b = new_with_vtable(ConstClass(node_vtable)) - setfield_gc(p2b, i2, descr=valuedescr) - p2sub = new_with_vtable(ConstClass(node_vtable2)) - setfield_gc(p2sub, i2sub, descr=valuedescr) - setfield_gc(p2b, p2sub, descr=nextdescr) - jump(i1, i1, i1, p2b) - """ # The same as test_p123_simple, but with a virtual containing another # virtual. - self.optimize_loop(ops, '''Not, - Virtual(node_vtable, - valuedescr=Not, - nextdescr=Virtual(node_vtable2, - valuedescr=Not)), - Not''', - expected) + self.optimize_loop(ops, 'Not, Not, Not', ops) def test_p123_anti_nested(self): ops = """ @@ -467,26 +440,15 @@ p3sub = getfield_gc(p3, descr=nextdescr) i3 = getfield_gc(p3sub, descr=valuedescr) escape(i3) - p1 = new_with_vtable(ConstClass(node_vtable)) p2sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p2sub, i1, descr=valuedescr) setfield_gc(p2, p2sub, descr=nextdescr) + p1 = new_with_vtable(ConstClass(node_vtable)) jump(i1, p1, p2) """ - expected = """ - [i1, p3] - p3sub = getfield_gc(p3, descr=nextdescr) - i3 = getfield_gc(p3sub, descr=valuedescr) - escape(i3) - p2b = new_with_vtable(ConstClass(node_vtable)) - p2sub = new_with_vtable(ConstClass(node_vtable2)) - setfield_gc(p2sub, i1, descr=valuedescr) - setfield_gc(p2b, p2sub, descr=nextdescr) - jump(i1, p2b) - """ # The same as test_p123_simple, but in the end the "old" p2 contains # a "young" virtual p2sub. Make sure it is all forced. - self.optimize_loop(ops, 'Not, Virtual(node_vtable), Not', expected) + self.optimize_loop(ops, 'Not, Not, Not', ops) # ---------- @@ -911,17 +873,8 @@ setarrayitem_gc(p1, 0, i1, descr=arraydescr) jump(i1, p1, p2) """ - expected = """ - [i1, i2, p3] - i3 = getarrayitem_gc(p3, 0, descr=arraydescr) - escape(i3) - p2b = new_array(1, descr=arraydescr) - setarrayitem_gc(p2b, 0, i2, descr=arraydescr) - jump(i1, i1, p2b) - """ # We cannot track virtuals that survive for more than two iterations. - self.optimize_loop(ops, 'Not, VArray(arraydescr, Not), Not', - expected) + self.optimize_loop(ops, 'Not, Not, Not', ops) def test_varray_forced_1(self): ops = """ @@ -970,17 +923,8 @@ setfield_gc(p1, i1, descr=adescr) jump(i1, p1, p2) """ - expected = """ - [i1, i2, p3] - i3 = getfield_gc(p3, descr=adescr) - escape(i3) - p2b = new(descr=ssize) - setfield_gc(p2b, i2, descr=adescr) - jump(i1, i1, p2b) - """ # We cannot track virtuals that survive for more than two iterations. - self.optimize_loop(ops, 'Not, VStruct(ssize, adescr=Not), Not', - expected) + self.optimize_loop(ops, 'Not, Not, Not', ops) def test_duplicate_getfield_1(self): ops = """ From antocuni at codespeak.net Tue Aug 25 10:11:35 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 10:11:35 +0200 (CEST) Subject: [pypy-svn] r67177 - pypy/branch/pyjitpl5/pypy/translator/cli Message-ID: <20090825081135.EF0251683D6@codespeak.net> Author: antocuni Date: Tue Aug 25 10:11:35 2009 New Revision: 67177 Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Log: *div_ovf needs to also catch ArithmeticException; this fixes jit test test_zrpy_basic.test_div_overflow Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Tue Aug 25 10:11:35 2009 @@ -174,7 +174,7 @@ 'int_add_nonneg_ovf': _check_ovf('add.ovf'), 'int_sub_ovf': _check_ovf('sub.ovf'), 'int_mul_ovf': _check_ovf('mul.ovf'), - 'int_floordiv_ovf': _check_ovf('div'), + 'int_floordiv_ovf': _check_ovf('div', catch_arithmexic_exception=True), 'int_mod_ovf': _check_ovf('rem', catch_arithmexic_exception=True), 'int_lt_ovf': 'clt', 'int_le_ovf': _not('cgt'), From cfbolz at codespeak.net Tue Aug 25 11:53:17 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 25 Aug 2009 11:53:17 +0200 (CEST) Subject: [pypy-svn] r67178 - pypy/extradoc/sprintinfo/gothenburg-2009 Message-ID: <20090825095317.1C8911683E6@codespeak.net> Author: cfbolz Date: Tue Aug 25 11:53:15 2009 New Revision: 67178 Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Log: (all): planning for today and various discussions Modified: pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt (original) +++ pypy/extradoc/sprintinfo/gothenburg-2009/planning.txt Tue Aug 25 11:53:15 2009 @@ -83,51 +83,70 @@ - lookups of various kinds - calls? +ootype discussion +------------------ + +- try to unify interfaces to make doing the right thing for ootype easier +- different constraints for different groups of people +- what to do with ootype jit support after Anto finished his PhD? + +inlining discussion +-------------------- + +- need to trace aggressively +- give up when trace becomes too long +- need to remember when we gave up +- need to reset counters +- tracing aggressively will put pressure on the speed of tracing +- what should we do about recursive calls? +- connecting compiled loops accross a call? + TASKS ----- look at tests - - more or less full coverage for optimize*.py - - add GC tests for x86 backend DONE - - find bug in x86 backend related to GC DONE + - run tests on branch concerned with the framestack removal and merge if + none fail (Armin) + - merge the compiler branch (Benjamin, Armin) + - write sprint blog post (Maciek, Carl Friedrich) + - set up test_ll_random to run nightly with x86 backend - update things in metainterp/doc - compare backend vs gcc quality - make x86 not recompile everything - think about code memory management - - inlining on the Python level - - store sinking (removing consecutive getfields/setfields) DONE - - build a pypy-c-jit from before the sprint for comparison IN-PROGRESS - - green virtualizable fields ABANDONED - - add infrastructure to test the loops that pypy-c-jit produces DONE + - constant specnode support DONE - - constant specnode support (Iko, Anto, Armin around) - - - getting confused MOSTLY DONE - - merge the compiler branch - general wizardry - look at calls performance? PROGRESS EXISTS - - fix virtualizable tests DONE - - fix the GC backend tests - - write sprint blog post (Maciek, Carl Friedrich) + - fix the GC backend tests DONE - get rid of pups and poshes at the end of the loop in x86 backend DONE - - investigate lib-python tests (Carl Friedrich, Samuele) + - investigate lib-python tests DONE - decide on benchmarks that represent calls (Benjamin) - - decide what to do with resizable lists (Maciek, Armin) + - decide what to do with resizable lists DONE - - find out what's really going on with richards + - find out what's really going on with richards DONE + - write small tests that cover virtualizables and inlining in conjunction + (Armin, Benjamin) + - fix ll2ctypes (Samuele, Maciek) + - look into virtualizables on ootype (Anto, Carl Friedrich) -Ater the Sprint ----------------- +After the Sprint +----------------- +- migrate tasks to extradoc/planning/jit.txt - merge the jit branch to trunk - upgrade python on wyvern - improve test running, compile only once -- can we have a buildbot download button for pypy-cs? -- sort out a benchmark server (Open End?) +- sort out a benchmark infrastructure. graphs!!! +- investigate test coverage +- inlining on the Python level +- streamline calls +- stability? +- nightly run of checks on output of pypy-c-jit From benjamin at codespeak.net Tue Aug 25 11:57:26 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 11:57:26 +0200 (CEST) Subject: [pypy-svn] r67179 - in pypy/branch/pyjitpl5/pypy: interpreter module/__builtin__ module/_stackless module/pypyjit module/signal module/sys objspace objspace/flow objspace/std tool/pytest Message-ID: <20090825095726.DA6191683EA@codespeak.net> Author: benjamin Date: Tue Aug 25 11:57:26 2009 New Revision: 67179 Modified: pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py pypy/branch/pyjitpl5/pypy/module/__builtin__/compiling.py pypy/branch/pyjitpl5/pypy/module/_stackless/interp_clonable.py pypy/branch/pyjitpl5/pypy/module/_stackless/interp_coroutine.py pypy/branch/pyjitpl5/pypy/module/_stackless/interp_greenlet.py pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py pypy/branch/pyjitpl5/pypy/module/sys/vm.py pypy/branch/pyjitpl5/pypy/objspace/flow/flowcontext.py pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py pypy/branch/pyjitpl5/pypy/objspace/taint.py pypy/branch/pyjitpl5/pypy/tool/pytest/appsupport.py Log: (arigo, fijal) use a doubly linked list of frames instead of a list for the framestack Modified: pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/baseobjspace.py Tue Aug 25 11:57:26 2009 @@ -479,8 +479,8 @@ def getexecutioncontext(self): "Return what we consider to be the active execution context." - # Important: the annotator must not see a prebuilt ExecutionContext - # for reasons related to the specialization of the framestack attribute + # Important: the annotator must not see a prebuilt ExecutionContext: + # you should not see frames while you translate # so we make sure that the threadlocals never *have* an # ExecutionContext during translation. if self.config.translating and not we_are_translated(): Modified: pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/executioncontext.py Tue Aug 25 11:57:26 2009 @@ -3,11 +3,9 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit -def new_framestack(): - return Stack() - def app_profile_call(space, w_callable, frame, event, w_arg): space.call_function(w_callable, space.wrap(frame), @@ -19,7 +17,10 @@ def __init__(self, space): self.space = space - self.framestack = new_framestack() + # 'some_frame' points to any frame from this thread's frame stack + # (although in general it should point to the top one). + self.some_frame = None + self.framestackdepth = 0 # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. @@ -29,40 +30,69 @@ self.profilefunc = None self.w_profilefuncarg = None + def gettopframe(self): + frame = self.some_frame + if frame is not None: + while frame.f_forward is not None: + frame = frame.f_forward + return frame + + def gettopframe_nohidden(self): + frame = self.gettopframe() + while frame and frame.hide(): + frame = frame.f_back + return frame + + def getnextframe_nohidden(frame): + frame = frame.f_back + while frame and frame.hide(): + frame = frame.f_back + return frame + getnextframe_nohidden = staticmethod(getnextframe_nohidden) + def enter(self, frame): - if self.framestack.depth() > self.space.sys.recursionlimit: + if self.framestackdepth > self.space.sys.recursionlimit: raise OperationError(self.space.w_RuntimeError, self.space.wrap("maximum recursion depth exceeded")) - try: - frame.f_back = self.framestack.top() - except IndexError: - frame.f_back = None - - if not frame.hide(): - self.framestack.push(frame) + self.framestackdepth += 1 + # + curtopframe = self.gettopframe() + frame.f_back = curtopframe + if curtopframe is not None: + curtopframe.f_forward = frame + if not we_are_jitted(): + self.some_frame = frame def leave(self, frame): if self.profilefunc: self._trace(frame, 'leaveframe', self.space.w_None) - - if not frame.hide(): - self.framestack.pop() - if self.w_tracefunc is not None: - self.space.frame_trace_action.fire() + + #assert frame is self.gettopframe() --- slowish + f_back = frame.f_back + if f_back is not None: + f_back.f_forward = None + if not we_are_jitted() or self.some_frame is frame: + self.some_frame = f_back + self.framestackdepth -= 1 + + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() class Subcontext(object): # coroutine: subcontext support def __init__(self): - self.framestack = new_framestack() + self.topframe = None + self.framestackdepth = 0 self.w_tracefunc = None self.profilefunc = None self.w_profilefuncarg = None self.is_tracing = 0 def enter(self, ec): - ec.framestack = self.framestack + ec.some_frame = self.topframe + ec.framestackdepth = self.framestackdepth ec.w_tracefunc = self.w_tracefunc ec.profilefunc = self.profilefunc ec.w_profilefuncarg = self.w_profilefuncarg @@ -70,30 +100,51 @@ ec.space.frame_trace_action.fire() def leave(self, ec): - self.framestack = ec.framestack + self.topframe = ec.gettopframe() + self.framestackdepth = ec.framestackdepth self.w_tracefunc = ec.w_tracefunc self.profilefunc = ec.profilefunc self.w_profilefuncarg = ec.w_profilefuncarg self.is_tracing = ec.is_tracing + def clear_framestack(self): + self.topframe = None + self.framestackdepth = 0 + # the following interface is for pickling and unpickling def getstate(self, space): - # we just save the framestack - items = [space.wrap(item) for item in self.framestack.items] + # XXX we could just save the top frame, which brings + # the whole frame stack, but right now we get the whole stack + items = [space.wrap(f) for f in self.getframestack()] return space.newtuple(items) def setstate(self, space, w_state): from pypy.interpreter.pyframe import PyFrame - items = [space.interp_w(PyFrame, w_item) - for w_item in space.unpackiterable(w_state)] - self.framestack.items = items + frames_w = space.unpackiterable(w_state) + if len(frames_w) > 0: + self.topframe = space.interp_w(PyFrame, frames_w[-1]) + else: + self.topframe = None + self.framestackdepth = len(frames_w) + + def getframestack(self): + index = self.framestackdepth + lst = [None] * index + f = self.topframe + while index > 0: + index -= 1 + lst[index] = f + f = f.f_back + assert f is None + return lst # coroutine: I think this is all, folks! def get_builtin(self): - try: - return self.framestack.top().builtin - except IndexError: + frame = self.gettopframe_nohidden() + if frame is not None: + return frame.builtin + else: return self.space.builtin # XXX this one should probably be dropped in favor of a module @@ -129,16 +180,6 @@ else: self._trace(frame, 'c_exception', w_exc) - def _llprofile(self, event, w_arg): - fr = self.framestack.items - space = self.space - w_callback = self.profilefunc - if w_callback is not None: - frame = None - if fr: - frame = fr[0] - self.profilefunc(space, self.w_profilefuncarg, frame, event, w_arg) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" @@ -177,10 +218,11 @@ def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!! """Implements sys.exc_info(). Return an OperationError instance or None.""" - for i in range(self.framestack.depth()): - frame = self.framestack.top(i) + frame = self.gettopframe_nohidden() + while frame: if frame.last_exception is not None: return frame.last_exception + frame = self.getnextframe_nohidden(frame) return None def settrace(self, w_func): @@ -204,8 +246,10 @@ if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - for frame in self.framestack.items: + frame = self.gettopframe_nohidden() + while frame: frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) self.w_profilefuncarg = w_arg def call_tracing(self, w_func, w_args): Modified: pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py (original) +++ pypy/branch/pyjitpl5/pypy/interpreter/pyframe.py Tue Aug 25 11:57:26 2009 @@ -39,7 +39,8 @@ frame_finished_execution = False last_instr = -1 last_exception = None - f_back = None + f_back = None # these two should be modified together + f_forward = None # they make a doubly-linked list w_f_trace = None # For tracing instr_lb = 0 Modified: pypy/branch/pyjitpl5/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/pyjitpl5/pypy/module/__builtin__/compiling.py Tue Aug 25 11:57:26 2009 @@ -31,11 +31,8 @@ ec = space.getexecutioncontext() if not dont_inherit: - try: - caller = ec.framestack.top() - except IndexError: - pass - else: + caller = ec.gettopframe_nohidden() + if caller: flags |= ec.compiler.getcodeflags(caller.getcode()) if mode not in ('exec', 'eval', 'single'): @@ -70,11 +67,7 @@ raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) - try: - caller = space.getexecutioncontext().framestack.top() - except IndexError: - caller = None - + caller = space.getexecutioncontext().gettopframe_nohidden() if w_globals is None or space.is_w(w_globals, space.w_None): if caller is None: w_globals = w_locals = space.newdict() Modified: pypy/branch/pyjitpl5/pypy/module/_stackless/interp_clonable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/_stackless/interp_clonable.py (original) +++ pypy/branch/pyjitpl5/pypy/module/_stackless/interp_clonable.py Tue Aug 25 11:57:26 2009 @@ -65,7 +65,7 @@ class AppClonableCoState(AppCoState): def post_install(self): self.current = self.main = AppClonableCoroutine(self.space, state=self) - self.main.subctx.framestack = None # wack + self.main.subctx.clear_framestack() # wack def post_install(module): makeStaticMethod(module, 'clonable', 'getcurrent') Modified: pypy/branch/pyjitpl5/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/pyjitpl5/pypy/module/_stackless/interp_coroutine.py Tue Aug 25 11:57:26 2009 @@ -183,7 +183,7 @@ w_parent = self.w_getmain(space) self.parent = space.interp_w(AppCoroutine, w_parent) ec = self.space.getexecutioncontext() - self.subctx.setstate(self.space, w_state) + self.subctx.setstate(space, w_state) self.reconstruct_framechain() if space.is_w(w_thunk, space.w_None): self.thunk = None @@ -199,7 +199,7 @@ def reconstruct_framechain(self): from pypy.interpreter.pyframe import PyFrame from pypy.rlib.rstack import resume_state_create - if self.subctx.framestack.empty(): + if self.subctx.topframe is None: self.frame = None return @@ -213,7 +213,7 @@ # ("appthunk", costate, returns=w_result) appthunk_frame = resume_state_create(_bind_frame, "appthunk", costate) chain = appthunk_frame - for frame in self.subctx.framestack.items: + for frame in self.subctx.getframestack(): assert isinstance(frame, PyFrame) # ("execute_frame", self, executioncontext, returns=w_exitvalue) chain = resume_state_create(chain, "execute_frame", frame, ec) @@ -270,11 +270,15 @@ def w_descr__framestack(space, self): assert isinstance(self, AppCoroutine) - if self.subctx.framestack is not None: - items = [space.wrap(item) for item in self.subctx.framestack.items] - return space.newtuple(items) - else: - return space.newtuple([]) + index = self.subctx.framestackdepth + items = [None] * index + f = self.subctx.topframe + while index > 0: + index -= 1 + items[index] = space.wrap(f) + f = f.f_back + assert f is None + return space.newtuple(items) def makeStaticMethod(module, classname, funcname): space = module.space @@ -333,7 +337,7 @@ def post_install(self): self.current = self.main = AppCoroutine(self.space, state=self) - self.main.subctx.framestack = None # wack + self.main.subctx.clear_framestack() # wack def return_main(space): return AppCoroutine._get_state(space).main Modified: pypy/branch/pyjitpl5/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/branch/pyjitpl5/pypy/module/_stackless/interp_greenlet.py Tue Aug 25 11:57:26 2009 @@ -52,7 +52,7 @@ self.active = is_main self.subctx = space.getexecutioncontext().Subcontext() if is_main: - self.subctx.framestack = None # wack + self.subctx.clear_framestack() # wack else: self.bind(GreenletThunk(self)) @@ -191,10 +191,7 @@ if not self.active or self.costate.current is self: f = None else: - try: - f = self.subctx.framestack.top(0) - except IndexError: - f = None + f = self.subctx.topframe return space.wrap(f) def get(space, name): Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Tue Aug 25 11:57:26 2009 @@ -22,7 +22,7 @@ PyFrame._virtualizable2_ = ['last_instr', 'pycode', 'valuestackdepth', 'valuestack_w[*]', - 'fastlocals_w[*]', + 'fastlocals_w[*]', 'f_forward', ] JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] Modified: pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py (original) +++ pypy/branch/pyjitpl5/pypy/module/signal/interp_signal.py Tue Aug 25 11:57:26 2009 @@ -103,10 +103,7 @@ # invoke the app-level handler space = self.space ec = space.getexecutioncontext() - try: - w_frame = ec.framestack.top() - except IndexError: - w_frame = space.w_None + w_frame = space.wrap(ec.gettopframe_nohidden()) space.call_function(w_handler, space.wrap(n), w_frame) def report_pending_signals(self): Modified: pypy/branch/pyjitpl5/pypy/module/sys/vm.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/sys/vm.py (original) +++ pypy/branch/pyjitpl5/pypy/module/sys/vm.py Tue Aug 25 11:57:26 2009 @@ -26,14 +26,19 @@ This function should be used for internal and specialized purposes only.""" depth = space.int_w(w_depth) - try: - f = space.getexecutioncontext().framestack.top(depth) - except IndexError: - raise OperationError(space.w_ValueError, - space.wrap("call stack is not deep enough")) - except ValueError: + if depth < 0: raise OperationError(space.w_ValueError, space.wrap("frame index must not be negative")) + ec = space.getexecutioncontext() + f = ec.gettopframe_nohidden() + while True: + if f is None: + raise OperationError(space.w_ValueError, + space.wrap("call stack is not deep enough")) + if depth == 0: + break + depth -= 1 + f = ec.getnextframe_nohidden(f) return space.wrap(f) # directly from the C code in ceval.c, might be moved somewhere else. Modified: pypy/branch/pyjitpl5/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/flow/flowcontext.py Tue Aug 25 11:57:26 2009 @@ -259,7 +259,8 @@ except StopFlowing: continue # restarting a dead SpamBlock try: - self.framestack.push(frame) + old_frame = self.some_frame + self.some_frame = frame self.crnt_frame = frame try: w_result = frame.dispatch(frame.pycode, @@ -267,7 +268,7 @@ self) finally: self.crnt_frame = None - self.framestack.pop() + self.some_frame = old_frame except OperationThatShouldNotBePropagatedError, e: raise Exception( Modified: pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/typeobject.py Tue Aug 25 11:57:26 2009 @@ -535,11 +535,8 @@ # initialize __module__ in the dict (user-defined types only) if '__module__' not in w_self.dict_w: space = w_self.space - try: - caller = space.getexecutioncontext().framestack.top() - except IndexError: - pass - else: + caller = space.getexecutioncontext().gettopframe_nohidden() + if caller is not None: w_globals = caller.w_globals w_name = space.finditem(w_globals, space.wrap('__name__')) if w_name is not None: Modified: pypy/branch/pyjitpl5/pypy/objspace/taint.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/taint.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/taint.py Tue Aug 25 11:57:26 2009 @@ -43,15 +43,11 @@ def record_debug_info(self): ec = self.space.getexecutioncontext() - try: - frame = ec.framestack.top() - except IndexError: - pass - else: - if isinstance(frame, PyFrame): - self.filename = frame.pycode.co_filename - self.codename = frame.pycode.co_name - self.codeline = frame.get_last_lineno() + frame = ec.gettopframe_nohidden() + if isinstance(frame, PyFrame): # and, in particular, frame != None + self.filename = frame.pycode.co_filename + self.codename = frame.pycode.co_name + self.codeline = frame.get_last_lineno() if get_debug_level(self.space) > 0: self.debug_dump() @@ -177,15 +173,11 @@ filename = '?' codename = '?' codeline = 0 - try: - frame = ec.framestack.top() - except IndexError: - pass - else: - if isinstance(frame, PyFrame): - filename = frame.pycode.co_filename - codename = frame.pycode.co_name - codeline = frame.get_last_lineno() + frame = ec.gettopframe_nohidden() + if isinstance(frame, PyFrame): # and, in particular, frame != None + filename = frame.pycode.co_filename + codename = frame.pycode.co_name + codeline = frame.get_last_lineno() os.write(2, 'Taint Bomb in file "%s", line %d, in %s\n %s\n' % ( filename, codeline, codename, operr.errorstr(space))) Modified: pypy/branch/pyjitpl5/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/pyjitpl5/pypy/tool/pytest/appsupport.py Tue Aug 25 11:57:26 2009 @@ -139,18 +139,16 @@ w_parent_init = space.getattr(w_BuiltinAssertionError, space.wrap('__init__')) space.call_args(w_parent_init, __args__.prepend(w_self)) - framestack = space.getexecutioncontext().framestack ## # Argh! we may see app-level helpers in the frame stack! ## # that's very probably very bad... -## if frame.code.co_name == 'normalize_exception': -## frame = framestack.top(1) +## ^^^the above comment may be outdated, but we are not sure # if the assertion provided a message, don't do magic args_w, kwargs_w = __args__.unpack() if args_w: w_msg = args_w[0] else: - frame = framestack.top(0) + frame = space.getexecutioncontext().gettopframe() runner = AppFrame(space, frame) try: source = runner.statement @@ -192,7 +190,7 @@ "after a string expression")) expr = space.unwrap(w_expr) source = py.code.Source(expr) - frame = space.getexecutioncontext().framestack.top() + frame = space.getexecutioncontext().gettopframe() w_locals = frame.getdictscope() w_locals = space.call_method(w_locals, 'copy') for key, w_value in kwds_w.items(): From benjamin at codespeak.net Tue Aug 25 11:57:57 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 11:57:57 +0200 (CEST) Subject: [pypy-svn] r67180 - pypy/branch/pyjitpl5-noframestack Message-ID: <20090825095757.2F7071683EA@codespeak.net> Author: benjamin Date: Tue Aug 25 11:57:56 2009 New Revision: 67180 Removed: pypy/branch/pyjitpl5-noframestack/ Log: remove merged branch From arigo at codespeak.net Tue Aug 25 12:13:30 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 12:13:30 +0200 (CEST) Subject: [pypy-svn] r67181 - pypy/trunk/lib-python Message-ID: <20090825101330.5144D1683BC@codespeak.net> Author: arigo Date: Tue Aug 25 12:13:28 2009 New Revision: 67181 Added: pypy/trunk/lib-python/conftest.py.merge.tmp - copied, changed from r67180, pypy/trunk/lib-python/conftest.py Log: (benjamin) expose AST to the applevel through the _ast module Copied: pypy/trunk/lib-python/conftest.py.merge.tmp (from r67180, pypy/trunk/lib-python/conftest.py) ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py.merge.tmp Tue Aug 25 12:13:28 2009 @@ -129,7 +129,7 @@ RegrTest('test__locale.py', skip=skip_win32), RegrTest('test_aepack.py', skip=True), RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', skip="unsupported module _ast"), + RegrTest('test_ast.py', core=True), RegrTest('test_anydbm.py'), RegrTest('test_applesingle.py', skip=True), RegrTest('test_array.py', core=True, usemodules='struct'), From arigo at codespeak.net Tue Aug 25 12:13:32 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 12:13:32 +0200 (CEST) Subject: [pypy-svn] r67182 - pypy/trunk/pypy Message-ID: <20090825101332.B660B1683BC@codespeak.net> Author: arigo Date: Tue Aug 25 12:13:31 2009 New Revision: 67182 Added: pypy/trunk/pypy/conftest.py.merge.tmp - copied, changed from r67180, pypy/trunk/pypy/conftest.py Log: (benjamin) emulate pypyraises when running with -A Copied: pypy/trunk/pypy/conftest.py.merge.tmp (from r67180, pypy/trunk/pypy/conftest.py) ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py.merge.tmp Tue Aug 25 12:13:31 2009 @@ -188,13 +188,21 @@ # Interfacing/Integrating with py.test's collection process # # -def ensure_pytest_builtin_helpers(helpers='skip raises'.split()): + +def _pytest_raises_wrapper(*args, **kwargs): + """Emulate the API of appsupport.pypyraises.""" + __tracebackhide__ = True + return py.test.raises(*args, **kwargs)._excinfo + +def ensure_pytest_builtin_helpers(helpers='skip'.split()): """ hack (py.test.) raises and skip into builtins, needed for applevel tests to run directly on cpython but apparently earlier on "raises" was already added to module's globals. """ import __builtin__ + if not hasattr(__builtin__, "raises"): + __builtin__.raises = _pytest_raises_wrapper for helper in helpers: if not hasattr(__builtin__, helper): setattr(__builtin__, helper, getattr(py.test, helper)) From antocuni at codespeak.net Tue Aug 25 12:15:23 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 12:15:23 +0200 (CEST) Subject: [pypy-svn] r67183 - in pypy/branch/pyjitpl5/pypy/rpython: ootypesystem test Message-ID: <20090825101523.27EA21683BC@codespeak.net> Author: antocuni Date: Tue Aug 25 12:15:22 2009 New Revision: 67183 Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: propagate flags to getfield() also on ootype. This makes all rvirtualizable2 tests passing, but it seems that there is no tests for the setfield equivalent Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py Tue Aug 25 12:15:22 2009 @@ -426,7 +426,8 @@ mangled = mangle(attr, self.rtyper.getconfig()) if mangled in self.allfields: # regular instance attributes - return self.getfield(v_inst, attr, hop.llops) + return self.getfield(v_inst, attr, hop.llops, + flags=hop.args_s[0].flags) elif mangled in self.allmethods: # special case for methods: represented as their 'self' only # (see MethodsPBCRepr) @@ -467,12 +468,12 @@ v_inst, _, v_newval = hop.inputargs(self, ootype.Void, r_value) self.setfield(v_inst, attr, v_newval, hop.llops) - def getfield(self, v_inst, attr, llops): + def getfield(self, v_inst, attr, llops, flags={}): mangled = mangle(attr, self.rtyper.getconfig()) v_attr = inputconst(ootype.Void, mangled) r_value = self.allfields[mangled] self.lowleveltype._check_field(mangled) - self.hook_access_field(v_inst, v_attr, llops, {}) # XXX flags + self.hook_access_field(v_inst, v_attr, llops, flags) return llops.genop('oogetfield', [v_inst, v_attr], resulttype = r_value) Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Tue Aug 25 12:15:22 2009 @@ -351,11 +351,3 @@ def gettype(self, v): return v.concretetype - - def test_access_directly(self): - py.test.skip("ootype doesn't pass around flags") - - test_access_directly_specialized = test_access_directly - - test_access_directly_method = test_access_directly - From arigo at codespeak.net Tue Aug 25 12:17:00 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 12:17:00 +0200 (CEST) Subject: [pypy-svn] r67184 - in pypy/trunk: lib-python lib-python/modified-2.5.2 pypy pypy/config pypy/doc/config pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/pyparser pypy/interpreter/test pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/_ast pypy/module/dyngram pypy/module/parser pypy/module/recparser pypy/module/symbol pypy/module/token pypy/objspace/std pypy/objspace/std/test pypy/tool pypy/tool/pytest Message-ID: <20090825101700.77F8C1683B7@codespeak.net> Author: arigo Date: Tue Aug 25 12:16:57 2009 New Revision: 67184 Added: pypy/trunk/lib-python/conftest.py - copied unchanged from r67183, pypy/trunk/lib-python/conftest.py.merge.tmp pypy/trunk/lib-python/modified-2.5.2/ - copied from r67183, pypy/branch/parser-compiler/lib-python/modified-2.5.2/ pypy/trunk/pypy/config/pypyoption.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/config/pypyoption.py pypy/trunk/pypy/conftest.py - copied unchanged from r67183, pypy/trunk/pypy/conftest.py.merge.tmp pypy/trunk/pypy/doc/config/ - copied from r67183, pypy/branch/parser-compiler/pypy/doc/config/ pypy/trunk/pypy/interpreter/astcompiler/ - copied from r67183, pypy/branch/parser-compiler/pypy/interpreter/astcompiler/ pypy/trunk/pypy/interpreter/baseobjspace.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/pycompiler.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py pypy/trunk/pypy/interpreter/pyparser/ - copied from r67183, pypy/branch/parser-compiler/pypy/interpreter/pyparser/ pypy/trunk/pypy/interpreter/test/test_compiler.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/interpreter/test/test_compiler.py pypy/trunk/pypy/interpreter/test/test_syntax.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/interpreter/test/test_syntax.py pypy/trunk/pypy/module/__builtin__/compiling.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/module/__builtin__/compiling.py pypy/trunk/pypy/module/__builtin__/test/test_builtin.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/module/__builtin__/test/test_builtin.py pypy/trunk/pypy/module/_ast/ - copied from r67183, pypy/branch/parser-compiler/pypy/module/_ast/ pypy/trunk/pypy/module/parser/ - copied from r67183, pypy/branch/parser-compiler/pypy/module/parser/ pypy/trunk/pypy/module/symbol/ - copied from r67183, pypy/branch/parser-compiler/pypy/module/symbol/ pypy/trunk/pypy/module/token/ - copied from r67183, pypy/branch/parser-compiler/pypy/module/token/ pypy/trunk/pypy/objspace/std/objspace.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/test/test_viewlist.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/objspace/std/test/test_viewlist.py pypy/trunk/pypy/objspace/std/viewlist.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/objspace/std/viewlist.py pypy/trunk/pypy/tool/pytest/ - copied from r67183, pypy/branch/parser-compiler/pypy/tool/pytest/ pypy/trunk/pypy/tool/stdlib_opcode.py - copied unchanged from r67183, pypy/branch/parser-compiler/pypy/tool/stdlib_opcode.py Removed: pypy/trunk/lib-python/conftest.py.merge.tmp pypy/trunk/pypy/conftest.py.merge.tmp pypy/trunk/pypy/module/dyngram/ pypy/trunk/pypy/module/recparser/ Log: (benjamin, arigo) Merge the branch/parser-compiler, introducing a completely new parser and compiler with modern AST which is much cleaner than the old one. From benjamin at codespeak.net Tue Aug 25 12:17:53 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 12:17:53 +0200 (CEST) Subject: [pypy-svn] r67185 - pypy/branch/parser-compiler Message-ID: <20090825101753.703D61683BC@codespeak.net> Author: benjamin Date: Tue Aug 25 12:17:52 2009 New Revision: 67185 Removed: pypy/branch/parser-compiler/ Log: remove merged branch From antocuni at codespeak.net Tue Aug 25 12:20:59 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 12:20:59 +0200 (CEST) Subject: [pypy-svn] r67186 - in pypy/branch/pyjitpl5/pypy/rpython: ootypesystem test Message-ID: <20090825102059.3AAA51683BC@codespeak.net> Author: antocuni Date: Tue Aug 25 12:20:58 2009 New Revision: 67186 Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, antocuni) test flags also for setfield, and fix it for ootype Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py Tue Aug 25 12:20:58 2009 @@ -466,7 +466,8 @@ self.lowleveltype._check_field(mangled) r_value = self.allfields[mangled] v_inst, _, v_newval = hop.inputargs(self, ootype.Void, r_value) - self.setfield(v_inst, attr, v_newval, hop.llops) + self.setfield(v_inst, attr, v_newval, hop.llops, + flags=hop.args_s[0].flags) def getfield(self, v_inst, attr, llops, flags={}): mangled = mangle(attr, self.rtyper.getconfig()) @@ -477,10 +478,10 @@ return llops.genop('oogetfield', [v_inst, v_attr], resulttype = r_value) - def setfield(self, vinst, attr, vvalue, llops): + def setfield(self, vinst, attr, vvalue, llops, flags={}): mangled_name = mangle(attr, self.rtyper.getconfig()) cname = inputconst(ootype.Void, mangled_name) - self.hook_access_field(vinst, cname, llops, {}) # XXX flags + self.hook_access_field(vinst, cname, llops, flags) llops.genop('oosetfield', [vinst, cname, vvalue]) def hook_access_field(self, vinst, cname, llops, flags): Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Tue Aug 25 12:20:58 2009 @@ -149,6 +149,7 @@ def test_access_directly(self): def g(b): + b.v0 += 1 return b.v0 def f(n): @@ -159,14 +160,14 @@ t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(g) - expected = [{'access_directly': True}] + expected = [{'access_directly': True}] * 3 assert get_promote_virtualizable_flags(g_graph) == expected self.replace_promote_virtualizable(typer, [g_graph]) - assert summary(g_graph) == {self.GETFIELD: 1} + assert summary(g_graph) == {self.GETFIELD: 2, self.SETFIELD: 1, 'int_add': 1} - res = self.interpret(f, [23]) - assert res == 23 + res = self.interpret(f, [23]) + assert res == 24 def test_access_directly_exception(self): def g(b): From antocuni at codespeak.net Tue Aug 25 12:24:03 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 12:24:03 +0200 (CEST) Subject: [pypy-svn] r67187 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090825102403.29AC51683BC@codespeak.net> Author: antocuni Date: Tue Aug 25 12:24:02 2009 New Revision: 67187 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, antocuni) these tests pass now Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Tue Aug 25 12:24:02 2009 @@ -945,14 +945,6 @@ def test_subclass_of_virtualizable(self): py.test.skip("oo virtualizable support incomplete") - def test_virtual_child_frame_with_arrays(self): - py.test.skip("oo virtualizable support incomplete") - - def test_blackhole_should_not_pay_attention(self): - py.test.skip("oo virtualizable support incomplete") - - def test_blackhole_should_not_reenter(self): - py.test.skip("oo virtualizable support incomplete") class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, From antocuni at codespeak.net Tue Aug 25 12:25:39 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 12:25:39 +0200 (CEST) Subject: [pypy-svn] r67188 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090825102539.284941683BC@codespeak.net> Author: antocuni Date: Tue Aug 25 12:25:38 2009 New Revision: 67188 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Log: (cfbolz, antocuni) these tests pass now Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Tue Aug 25 12:25:38 2009 @@ -170,11 +170,7 @@ del meth_func._look_inside_me_ class TestOOtype(ToyLanguageTests, OOJitMixin): - def test_tl_call(self): - py.test.skip("virtualizables: in-progress with ootype") - - def test_tl_call_full_of_residuals(self): - py.test.skip("virtualizables: in-progress with ootype") + pass class TestLLtype(ToyLanguageTests, LLJitMixin): pass From antocuni at codespeak.net Tue Aug 25 12:34:48 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 12:34:48 +0200 (CEST) Subject: [pypy-svn] r67189 - pypy/branch/pyjitpl5/pypy/rpython Message-ID: <20090825103448.51279168074@codespeak.net> Author: antocuni Date: Tue Aug 25 12:34:48 2009 New Revision: 67189 Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py Log: (cfbolz, antocuni) kill rest of old way to do virtualizables Modified: pypy/branch/pyjitpl5/pypy/rpython/rclass.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rclass.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rclass.py Tue Aug 25 12:34:48 2009 @@ -49,7 +49,6 @@ if classdef is None: unboxed = [] - virtualizable = False virtualizable2 = False else: unboxed = [subdef for subdef in classdef.getallsubdefs() From benjamin at codespeak.net Tue Aug 25 13:04:43 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 13:04:43 +0200 (CEST) Subject: [pypy-svn] r67190 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090825110443.1461C1683D4@codespeak.net> Author: benjamin Date: Tue Aug 25 13:04:42 2009 New Revision: 67190 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (arigo, benjamin) add test with inlining virtualizables Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Tue Aug 25 13:04:42 2009 @@ -938,6 +938,39 @@ einfo = py.test.raises(AssertionError, self.meta_interp, main, []) assert einfo.value.args[0] == "reentering same frame via blackhole" + def test_inlining(self): + class Frame(object): + _virtualizable2_ = ['x', 'next'] + + def __init__(self, x): + self = hint(self, access_directly=True) + self.x = x + self.next = None + + driver = JitDriver(greens=[], reds=['frame', 'result'], + virtualizables=['frame']) + + def interp(caller): + f = Frame(caller.x) + caller.next = f + f = hint(f, access_directly=True) + result = 0 + while f.x > 0: + driver.can_enter_jit(frame=f, result=result) + driver.jit_merge_point(frame=f, result=result) + f.x -= 1 + result += indirection(f) + return result + def indirection(arg): + return interp(arg) + def run_interp(n): + f = hint(Frame(n), access_directly=True) + return interp(f) + + res = self.meta_interp(run_interp, [4]) + assert res == run_interp(4) + + class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): From antocuni at codespeak.net Tue Aug 25 13:07:33 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 13:07:33 +0200 (CEST) Subject: [pypy-svn] r67191 - in pypy/branch/pyjitpl5/pypy: jit/metainterp/test rpython rpython/test Message-ID: <20090825110733.506E51683BA@codespeak.net> Author: antocuni Date: Tue Aug 25 13:07:32 2009 New Revision: 67191 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Log: (cfbolz, antocuni) add a test for subclasses of virtualizables; fix it for ootype; the last virtualizable failing jit test now passes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Tue Aug 25 13:07:32 2009 @@ -974,11 +974,9 @@ class TestOOtype(#ExplicitVirtualizableTests, ImplicitVirtualizableTests, OOJitMixin): + pass - def test_subclass_of_virtualizable(self): - py.test.skip("oo virtualizable support incomplete") - class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, LLJitMixin): Modified: pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/rvirtualizable2.py Tue Aug 25 13:07:32 2009 @@ -39,8 +39,10 @@ self.my_redirected_fields = self._parse_field_list(c_vfields.value, self.accessor) else: - self.my_redirected_fields = {} self._super()._setup_repr() + # ootype needs my_redirected_fields even for subclass. lltype does + # not need it, but it doesn't hurt to have it anyway + self.my_redirected_fields = self.rbase.my_redirected_fields def new_instance(self, llops, classcallhop=None): vptr = self._super().new_instance(llops, classcallhop) Modified: pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/test/test_rvirtualizable2.py Tue Aug 25 13:07:32 2009 @@ -13,6 +13,9 @@ self.v = v self.w = v+1 +class SubclassV(V): + pass + class VArray(object): _virtualizable2_ = ['lst[*]'] @@ -48,6 +51,21 @@ assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} + def test_generate_promote_virtualizable_subclass(self): + def fn(n): + V(n) # to attach v to V + vinst = SubclassV(n) + return vinst.v + _, _, graph = self.gengraph(fn, [int]) + block = graph.startblock + op_promote = block.operations[-2] + op_getfield = block.operations[-1] + assert op_getfield.opname in ('getfield', 'oogetfield') + v_inst = op_getfield.args[0] + assert op_promote.opname == 'promote_virtualizable' + assert op_promote.args[0] is v_inst + assert op_promote.args[-1].value == {} + def test_no_promote_virtualizable_for_other_fields(self): def fn(n): vinst = V(n) From antocuni at codespeak.net Tue Aug 25 13:09:32 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 25 Aug 2009 13:09:32 +0200 (CEST) Subject: [pypy-svn] r67192 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090825110932.3C1831683D3@codespeak.net> Author: antocuni Date: Tue Aug 25 13:09:31 2009 New Revision: 67192 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: (cfbolz, antocuni) this test also passes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Tue Aug 25 13:09:31 2009 @@ -788,9 +788,6 @@ for block, op in graph.iterblockops() if op.opname == 'direct_call'] - if isinstance(self, OOJitMixin): - py.test.skip("oo virtualizable support incomplete") - assert direct_calls(f_graph) == ['__init__', 'force_if_necessary', 'll_portal_runner'] assert direct_calls(portal_graph) == ['force_if_necessary', 'maybe_enter_jit'] From benjamin at codespeak.net Tue Aug 25 13:23:31 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 13:23:31 +0200 (CEST) Subject: [pypy-svn] r67193 - in pypy/trunk/pypy: interpreter objspace/std objspace/std/test Message-ID: <20090825112331.619031683E6@codespeak.net> Author: benjamin Date: Tue Aug 25 13:23:29 2009 New Revision: 67193 Removed: pypy/trunk/pypy/objspace/std/test/test_viewlist.py pypy/trunk/pypy/objspace/std/viewlist.py Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/objspace/std/objspace.py Log: remove unused viewlist Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Aug 25 13:23:29 2009 @@ -1205,7 +1205,6 @@ 'is_w', 'newtuple', 'newlist', - 'newviewlist', 'newdict', 'newslice', 'call_args', Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Aug 25 13:23:29 2009 @@ -589,15 +589,6 @@ from pypy.objspace.std.listobject import W_ListObject return W_ListObject(list_w) - def newviewlist(self, context, getitem, setitem, delitem, append, length): - assert self.config.objspace.std.withmultilist, "view lists require " \ - "multilists" - from pypy.objspace.std.listmultiobject import W_ListMultiObject - from pypy.objspace.std.viewlist import ViewListImplementation - impl = ViewListImplementation(self, context, getitem, setitem, delitem, - append, length) - return W_ListMultiObject(self, impl) - def newdict(self, module=False): if self.config.objspace.std.withmultidict and module: from pypy.objspace.std.dictmultiobject import W_DictMultiObject From benjamin at codespeak.net Tue Aug 25 13:40:08 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 13:40:08 +0200 (CEST) Subject: [pypy-svn] r67194 - pypy/trunk/pypy/interpreter/astcompiler Message-ID: <20090825114008.608681683ED@codespeak.net> Author: benjamin Date: Tue Aug 25 13:40:07 2009 New Revision: 67194 Modified: pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py Log: shut up annotator warnings Modified: pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py Tue Aug 25 13:40:07 2009 @@ -10,6 +10,15 @@ setattr(ast, "UnacceptableExpressionContext", UnacceptableExpressionContext) +class __extend__(ast.AST): + + def as_node_list(self, space): + raise AssertionError("only for expressions") + + def set_context(self, ctx): + raise AssertionError("should only be on expressions") + + class __extend__(ast.expr): constant = False From arigo at codespeak.net Tue Aug 25 16:09:03 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 16:09:03 +0200 (CEST) Subject: [pypy-svn] r67196 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/cli backend/llvm backend/x86 metainterp Message-ID: <20090825140903.E2D58168076@codespeak.net> Author: arigo Date: Tue Aug 25 16:09:02 2009 New Revision: 67196 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/logger.py pypy/branch/pyjitpl5/pypy/jit/backend/model.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Log: Push and pull all over the place to get the logger class to optimize.py. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Tue Aug 25 16:09:02 2009 @@ -1,7 +1,6 @@ import py import os from pypy.tool.pairtype import extendabletype -from pypy.rlib.objectmodel import compute_unique_id from pypy.rpython.ootypesystem import ootype from pypy.translator.cli import dotnet from pypy.translator.cli.dotnet import CLR @@ -34,6 +33,7 @@ return AbstractLogger.repr_of_descr(self, descr) logger = CliLogger() +runner.CliCPU.logger_cls = CliLogger # xxx hack class __extend__(AbstractValue): __metaclass__ = extendabletype @@ -163,8 +163,7 @@ # ---- logger.create_log() - logger.eventually_log_operations(loop.inputargs, loop.operations, None, - compute_unique_id(loop)) + logger.eventually_log_loop(loop) # ---- self.box2type = {} if self.nocast: Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Tue Aug 25 16:09:02 2009 @@ -16,6 +16,7 @@ class LLVMCPU(object): is_oo = False + logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/logger.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/logger.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/logger.py Tue Aug 25 16:09:02 2009 @@ -11,13 +11,13 @@ def __init__(self): self._log_fd = -1 - def create_log(self): + def create_log(self, extension='.ops'): if self._log_fd != -1: return self._log_fd s = os.environ.get('PYPYJITLOG') if not s: return -1 - s += '.ops' + s += extension try: flags = os.O_WRONLY|os.O_CREAT|os.O_TRUNC self._log_fd = os.open(s, flags, 0666) @@ -26,6 +26,10 @@ return -1 return self._log_fd + def eventually_log_loop(self, loop): + self.eventually_log_operations(loop.inputargs, loop.operations, None, + compute_unique_id(loop)) + def repr_of_descr(self, descr): return '' Modified: pypy/branch/pyjitpl5/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/model.py Tue Aug 25 16:09:02 2009 @@ -1,4 +1,6 @@ class AbstractCPU(object): + logger_cls = None + def set_class_sizes(self, class_sizes): self.class_sizes = class_sizes Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Tue Aug 25 16:09:02 2009 @@ -9,7 +9,7 @@ from pypy.tool.uid import fixid from pypy.jit.backend.x86.regalloc import (RegAlloc, WORD, REGS, TempBox, lower_byte, stack_pos) -from pypy.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.jit.backend.x86 import codebuf from pypy.jit.backend.x86.ri386 import * from pypy.jit.metainterp.resoperation import rop @@ -192,8 +192,7 @@ self.tree = tree self.make_sure_mc_exists() inputargs = tree.inputargs - self.logger.eventually_log_operations(tree.inputargs, tree.operations, None, - compute_unique_id(tree)) + self.logger.eventually_log_loop(tree) regalloc = RegAlloc(self, tree, self.cpu.translate_support_code) self._regalloc = regalloc regalloc.walk_operations(tree) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 25 16:09:02 2009 @@ -12,6 +12,7 @@ from pypy.jit.metainterp.history import (ResOperation, Box, Const, ConstInt, ConstPtr, BoxInt, BoxPtr, ConstAddr, AbstractDescr) from pypy.jit.backend.x86.assembler import Assembler386, WORD, MAX_FAIL_BOXES +from pypy.jit.backend.x86.assembler import x86Logger from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop, opname from pypy.rlib.objectmodel import r_dict @@ -48,6 +49,7 @@ class CPU386(object): debug = True is_oo = False + logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Tue Aug 25 16:09:02 2009 @@ -753,6 +753,7 @@ # ---------------------------------------------------------------- class Options: + logger_noopt = None def __init__(self, specialize=True, listops=False, inline=False): self.specialize = specialize self.listops = listops Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py Tue Aug 25 16:09:02 2009 @@ -10,7 +10,8 @@ return old_loops[0] else: return None - #loop.dump() + if options.logger_noopt is not None: + options.logger_noopt.eventually_log_loop(loop) finder = PerfectSpecializationFinder() finder.find_nodes_loop(loop) for old_loop in old_loops: @@ -27,6 +28,8 @@ def optimize_bridge(options, old_loops, bridge, cpu): if not options.specialize: # for tests only return old_loops[0] + if options.logger_noopt is not None: + options.logger_noopt.eventually_log_loop(bridge) finder = BridgeSpecializationFinder() finder.find_nodes_bridge(bridge) for old_loop in old_loops: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Tue Aug 25 16:09:02 2009 @@ -993,6 +993,8 @@ self.cpu = cpu self.stats = stats self.options = options + if cpu.logger_cls is not None: + options.logger_noopt = cpu.logger_cls() RESULT = portal_graph.getreturnvar().concretetype self.result_type = history.getkind(RESULT) @@ -1049,6 +1051,8 @@ self.profiler.start() self.profiler.initialized = True self.globaldata.initialized = True + if self.options.logger_noopt is not None: + self.options.logger_noopt.create_log('.noopt') def _setup_class_sizes(self): class_sizes = {} From benjamin at codespeak.net Tue Aug 25 16:09:16 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 16:09:16 +0200 (CEST) Subject: [pypy-svn] r67197 - in pypy/trunk/pypy: interpreter/astcompiler interpreter/astcompiler/tools module/_ast/test Message-ID: <20090825140916.9716A168076@codespeak.net> Author: benjamin Date: Tue Aug 25 16:09:15 2009 New Revision: 67197 Modified: pypy/trunk/pypy/interpreter/astcompiler/ast.py pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py pypy/trunk/pypy/module/_ast/test/test_ast.py Log: fix syncing of optional fields Modified: pypy/trunk/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/ast.py Tue Aug 25 16:09:15 2009 @@ -343,7 +343,8 @@ else: if not self.initialization_state & 1: self.value = None - self.value.sync_app_attrs(space) + if self.value: + self.value.sync_app_attrs(space) class Delete(stmt): @@ -487,7 +488,8 @@ else: if not self.initialization_state & 1: self.dest = None - self.dest.sync_app_attrs(space) + if self.dest: + self.dest.sync_app_attrs(space) w_list = self.w_values if w_list is not None: list_w = space.viewiterable(w_list) @@ -701,7 +703,8 @@ if not self.initialization_state & 2: self.optional_vars = None self.context_expr.sync_app_attrs(space) - self.optional_vars.sync_app_attrs(space) + if self.optional_vars: + self.optional_vars.sync_app_attrs(space) w_list = self.w_body if w_list is not None: list_w = space.viewiterable(w_list) @@ -750,9 +753,12 @@ self.inst = None if not self.initialization_state & 4: self.tback = None - self.type.sync_app_attrs(space) - self.inst.sync_app_attrs(space) - self.tback.sync_app_attrs(space) + if self.type: + self.type.sync_app_attrs(space) + if self.inst: + self.inst.sync_app_attrs(space) + if self.tback: + self.tback.sync_app_attrs(space) class TryExcept(stmt): @@ -900,7 +906,8 @@ if not self.initialization_state & 2: self.msg = None self.test.sync_app_attrs(space) - self.msg.sync_app_attrs(space) + if self.msg: + self.msg.sync_app_attrs(space) class Import(stmt): @@ -1014,8 +1021,10 @@ if not self.initialization_state & 4: self.locals = None self.body.sync_app_attrs(space) - self.globals.sync_app_attrs(space) - self.locals.sync_app_attrs(space) + if self.globals: + self.globals.sync_app_attrs(space) + if self.locals: + self.locals.sync_app_attrs(space) class Global(stmt): @@ -1474,7 +1483,8 @@ else: if not self.initialization_state & 1: self.value = None - self.value.sync_app_attrs(space) + if self.value: + self.value.sync_app_attrs(space) class Compare(expr): @@ -1587,8 +1597,10 @@ if self.keywords is not None: for node in self.keywords: node.sync_app_attrs(space) - self.starargs.sync_app_attrs(space) - self.kwargs.sync_app_attrs(space) + if self.starargs: + self.starargs.sync_app_attrs(space) + if self.kwargs: + self.kwargs.sync_app_attrs(space) class Repr(expr): @@ -1967,9 +1979,12 @@ self.upper = None if not self.initialization_state & 4: self.step = None - self.lower.sync_app_attrs(space) - self.upper.sync_app_attrs(space) - self.step.sync_app_attrs(space) + if self.lower: + self.lower.sync_app_attrs(space) + if self.upper: + self.upper.sync_app_attrs(space) + if self.step: + self.step.sync_app_attrs(space) class ExtSlice(slice): @@ -2323,8 +2338,10 @@ self.type = None if not self.initialization_state & 2: self.name = None - self.type.sync_app_attrs(space) - self.name.sync_app_attrs(space) + if self.type: + self.type.sync_app_attrs(space) + if self.name: + self.name.sync_app_attrs(space) w_list = self.w_body if w_list is not None: list_w = space.viewiterable(w_list) Modified: pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Aug 25 16:09:15 2009 @@ -161,7 +161,11 @@ elif attr.type.value not in asdl.builtin_types and \ attr.type.value not in self.data.simple_types: doing_something = True - self.emit("self.%s.sync_app_attrs(space)" % (attr.name,), 2) + level = 2 + if attr.opt: + self.emit("if self.%s:" % (attr.name,), 2) + level += 1 + self.emit("self.%s.sync_app_attrs(space)" % (attr.name,), level) self.emit("") def make_constructor(self, fields, node, extras=None, base=None): Modified: pypy/trunk/pypy/module/_ast/test/test_ast.py ============================================================================== --- pypy/trunk/pypy/module/_ast/test/test_ast.py (original) +++ pypy/trunk/pypy/module/_ast/test/test_ast.py Tue Aug 25 16:09:15 2009 @@ -95,6 +95,15 @@ const.value = 5 assert const.value == 5 + def test_optional(self): + mod = self.get_ast("x(32)", "eval") + call = mod.body + assert call.starargs is None + assert call.kwargs is None + co = compile(mod, "", "eval") + ns = {"x" : lambda x: x} + assert eval(co, ns) == 32 + def test_list_syncing(self): ast = self.ast mod = ast.Module([ast.Lt()]) From pedronis at codespeak.net Tue Aug 25 16:25:18 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Aug 2009 16:25:18 +0200 (CEST) Subject: [pypy-svn] r67198 - in pypy/branch/pyjitpl5/pypy: jit/backend/x86 jit/backend/x86/test rpython/lltypesystem rpython/lltypesystem/test Message-ID: <20090825142518.658F11683B8@codespeak.net> Author: pedronis Date: Tue Aug 25 16:25:15 2009 New Revision: 67198 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lltype.py pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Log: (fijal, pedronis, a bit of cfboly) fix gcref ll2ctypes/lltypes comparisons by making the old _llgcref into an opaque like container wrapper by a pointer Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 25 16:25:15 2009 @@ -569,11 +569,7 @@ def cast_int_to_adr(x): if not we_are_translated(): _check_addr_range(x) - if we_are_translated(): - return rffi.cast(llmemory.Address, x) - else: - # indirect casting because the above doesn't work with ll2ctypes - return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x)) + return rffi.cast(llmemory.Address, x) def cast_gcref_to_int(self, x): return rffi.cast(lltype.Signed, x) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py Tue Aug 25 16:25:15 2009 @@ -120,7 +120,10 @@ 'void') assert u.chars[2] == u'z' assert u.chars[3] == u'd' - + + @staticmethod + def _resbuf(res, item_tp=ctypes.c_int): + return ctypes.cast(res.value._obj.intval, ctypes.POINTER(item_tp)) def test_allocations(self): from pypy.rpython.lltypesystem import rstr @@ -139,17 +142,17 @@ saved_addr = self.cpu.assembler.malloc_func_addr self.cpu.assembler.malloc_func_addr = addr ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ptr') assert allocs[0] == 7 + ofs + WORD - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_int)) + resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ptr') assert allocs[0] == 7 + ofs + WORD - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_int)) + resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ @@ -161,7 +164,7 @@ res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ptr', descr) assert allocs[0] == 10*WORD + ofs + WORD - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_int)) + resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 # ------------------------------------------------------------ @@ -169,7 +172,7 @@ res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], 'ptr', descr) assert allocs[0] == 10*WORD + ofs + WORD - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_int)) + resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 finally: @@ -182,7 +185,7 @@ res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ptr') self.execute_operation(rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void') - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_char)) + resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' self.execute_operation(rop.STRSETITEM, [res, BoxInt(2), ConstInt(ord('z'))], 'void') assert resbuf[ofs + ofs_items + 2] == 'z' @@ -196,7 +199,7 @@ descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ptr', descr) - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_int)) + resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, ConstInt(2), BoxInt(38)], @@ -235,7 +238,7 @@ descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ptr', descr) - resbuf = ctypes.cast(res.value.intval, ctypes.POINTER(ctypes.c_char)) + resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs] == chr(10) for i in range(10): self.execute_operation(rop.SETARRAYITEM_GC, [res, Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/ll2ctypes.py Tue Aug 25 16:25:15 2009 @@ -533,8 +533,8 @@ if T is base_ptr_lltype(): return new_opaque_object(llobj) if T == llmemory.GCREF: - if isinstance(llobj, _llgcref): - return ctypes.c_void_p(llobj.intval) + if isinstance(llobj._obj, _llgcopaque): + return ctypes.c_void_p(llobj._obj.intval) container = llobj._obj.container T = lltype.Ptr(lltype.typeOf(container)) # otherwise it came from integer and we want a c_void_p with @@ -721,8 +721,7 @@ _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: - # XXX obscure hack - return _llgcref(cobj) + container = _llgcopaque(cobj) else: container = lltype._opaque(T.TO) else: @@ -1085,8 +1084,9 @@ def __ne__(self, other): return not self == other -class _llgcref(object): - _TYPE = llmemory.GCREF +class _llgcopaque(lltype._container): + _TYPE = llmemory.GCREF.TO + _name = "_llgcopaque" def __init__(self, void_p): if isinstance(void_p, (int, long)): @@ -1095,24 +1095,23 @@ self.intval = intmask(void_p.value) def __eq__(self, other): - if isinstance(other, _llgcref): + if isinstance(other, _llgcopaque): return self.intval == other.intval - return force_cast(lltype.Signed, other) == self.intval + if other.container._storage in (None, True): + return False + return force_cast(lltype.Signed, other._as_ptr()) == self.intval def __ne__(self, other): return not self == other - def __nonzero__(self): - return bool(self.intval) - def _cast_to_ptr(self, PTRTYPE): - return force_cast(PTRTYPE, self.intval) + return force_cast(PTRTYPE, self.intval) - def _cast_to_int(self): - return self.intval +## def _cast_to_int(self): +## return self.intval - def _cast_to_adr(self): - return _lladdress(self.intval) +## def _cast_to_adr(self): +## return _lladdress(self.intval) def cast_adr_to_int(addr): if isinstance(addr, llmemory.fakeaddress): Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/lltype.py Tue Aug 25 16:25:15 2009 @@ -798,8 +798,8 @@ "%s to %s" % (CURTYPE, PTRTYPE)) if (isinstance(CURTYPE.TO, OpaqueType) and not isinstance(PTRTYPE.TO, OpaqueType)): - if hasattr(ptr, '_cast_to_ptr'): - return ptr._cast_to_ptr(PTRTYPE) + if hasattr(ptr._obj, '_cast_to_ptr'): + return ptr._obj._cast_to_ptr(PTRTYPE) if not ptr: return nullptr(PTRTYPE.TO) try: @@ -1696,7 +1696,7 @@ def __eq__(self, other): if self.__class__ is not other.__class__: - return False + return NotImplemented if hasattr(self, 'container') and hasattr(other, 'container'): obj1 = self.container._normalizedcontainer() obj2 = other.container._normalizedcontainer() @@ -1705,6 +1705,8 @@ return self is other def __ne__(self, other): + if self.__class__ is not other.__class__: + return NotImplemented return not (self == other) def __hash__(self): Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Tue Aug 25 16:25:15 2009 @@ -998,7 +998,7 @@ assert v v2 = ctypes2lltype(llmemory.GCREF, ctypes.c_void_p(1235)) assert v2 != v - + def test_gcref_type(self): NODE = lltype.GcStruct('NODE') node = lltype.malloc(NODE) @@ -1020,3 +1020,77 @@ ref = llmemory.NULL value = rffi.cast(lltype.Signed, ref) assert value == 0 + + def test_gcref_truth(self): + p0 = ctypes.c_void_p(0) + ref0 = ctypes2lltype(llmemory.GCREF, p0) + assert not ref0 + + p1234 = ctypes.c_void_p(1234) + ref1234 = ctypes2lltype(llmemory.GCREF, p1234) + assert p1234 + + def test_gcref_casts(self): + p0 = ctypes.c_void_p(0) + ref0 = ctypes2lltype(llmemory.GCREF, p0) + + assert lltype.cast_ptr_to_int(ref0) == 0 + assert llmemory.cast_ptr_to_adr(ref0) == llmemory.NULL + + NODE = lltype.GcStruct('NODE') + assert lltype.cast_opaque_ptr(lltype.Ptr(NODE), ref0) == lltype.nullptr(NODE) + + node = lltype.malloc(NODE) + ref1 = lltype.cast_opaque_ptr(llmemory.GCREF, node) + + intval = rffi.cast(lltype.Signed, node) + intval1 = rffi.cast(lltype.Signed, ref1) + + assert intval == intval1 + + ref2 = ctypes2lltype(llmemory.GCREF, intval1) + + assert lltype.cast_opaque_ptr(lltype.Ptr(NODE), ref2) == node + + #addr = llmemory.cast_ptr_to_adr(ref1) + #assert llmemory.cast_adr_to_int(addr) == intval + + #assert lltype.cast_ptr_to_int(ref1) == intval + + def test_mixed_gcref_comparison(self): + NODE = lltype.GcStruct('NODE') + node = lltype.malloc(NODE) + ref1 = lltype.cast_opaque_ptr(llmemory.GCREF, node) + ref2 = rffi.cast(llmemory.GCREF, 123) + + assert ref1 != ref2 + assert not (ref1 == ref2) + + assert ref2 != ref1 + assert not (ref2 == ref1) + + assert node._obj._storage is True + + # forced! + rffi.cast(lltype.Signed, ref1) + assert node._obj._storage not in (True, None) + + assert ref1 != ref2 + assert not (ref1 == ref2) + + assert ref2 != ref1 + assert not (ref2 == ref1) + + def test_gcref_comparisons_back_and_forth(self): + NODE = lltype.GcStruct('NODE') + node = lltype.malloc(NODE) + ref1 = lltype.cast_opaque_ptr(llmemory.GCREF, node) + numb = rffi.cast(lltype.Signed, ref1) + ref2 = rffi.cast(llmemory.GCREF, numb) + assert ref1 == ref2 + assert ref2 == ref1 + assert not (ref1 != ref2) + assert not (ref2 != ref1) + + + From cfbolz at codespeak.net Tue Aug 25 16:40:18 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 25 Aug 2009 16:40:18 +0200 (CEST) Subject: [pypy-svn] r67199 - pypy/branch/pyjitpl5/pypy/jit/backend/x86 Message-ID: <20090825144018.5A3D516802D@codespeak.net> Author: cfbolz Date: Tue Aug 25 16:40:17 2009 New Revision: 67199 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Log: (arigo, cfbolz): this check makes no sense Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Tue Aug 25 16:40:17 2009 @@ -580,8 +580,6 @@ return rffi.cast(llmemory.GCREF, x) def cast_adr_to_gcref(self, x): - if not we_are_translated(): - _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) CPU = CPU386 From benjamin at codespeak.net Tue Aug 25 16:40:22 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 16:40:22 +0200 (CEST) Subject: [pypy-svn] r67200 - in pypy/trunk/pypy: interpreter/astcompiler module/_ast/test Message-ID: <20090825144022.7CF711683BA@codespeak.net> Author: benjamin Date: Tue Aug 25 16:40:20 2009 New Revision: 67200 Modified: pypy/trunk/pypy/interpreter/astcompiler/misc.py pypy/trunk/pypy/module/_ast/test/test_ast.py Log: fix incorrect identification of docstrings Modified: pypy/trunk/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/misc.py Tue Aug 25 16:40:20 2009 @@ -38,7 +38,7 @@ else: return 0, 0 for stmt in body: - if isinstance(stmt, ast.Str): + if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Str): if have_docstring: break else: Modified: pypy/trunk/pypy/module/_ast/test/test_ast.py ============================================================================== --- pypy/trunk/pypy/module/_ast/test/test_ast.py (original) +++ pypy/trunk/pypy/module/_ast/test/test_ast.py Tue Aug 25 16:40:20 2009 @@ -164,6 +164,9 @@ def test_future(self): mod = self.get_ast("from __future__ import with_statement") compile(mod, "", "exec") + mod = self.get_ast(""""I'm a docstring."\n +from __future__ import generators""") + compile(mod, "", "exec") mod = self.get_ast("from __future__ import with_statement; import y; " \ "from __future__ import nested_scopes") raises(SyntaxError, compile, mod, "", "exec") From cfbolz at codespeak.net Tue Aug 25 16:40:35 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 25 Aug 2009 16:40:35 +0200 (CEST) Subject: [pypy-svn] r67201 - pypy/branch/pyjitpl5/pypy/jit/backend/x86/test Message-ID: <20090825144035.0B7EA16802D@codespeak.net> Author: cfbolz Date: Tue Aug 25 16:40:34 2009 New Revision: 67201 Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zll_random.py (contents, props changed) Log: run test_ll_random at night with x86 backend Added: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zll_random.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zll_random.py Tue Aug 25 16:40:34 2009 @@ -0,0 +1,12 @@ +from pypy.jit.backend.test.test_random import check_random_function, Random +from pypy.jit.backend.test.test_ll_random import LLtypeOperationBuilder +from pypy.jit.backend.x86.runner import CPU386 + +def test_stress(): + cpu = CPU386(None, None) + r = Random() + for i in range(1000): + check_random_function(cpu, LLtypeOperationBuilder, r, i, 1000) + + + From benjamin at codespeak.net Tue Aug 25 17:03:28 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 17:03:28 +0200 (CEST) Subject: [pypy-svn] r67202 - in pypy/trunk/pypy/interpreter/pyparser: . data Message-ID: <20090825150328.2FBC316805C@codespeak.net> Author: benjamin Date: Tue Aug 25 17:03:27 2009 New Revision: 67202 Added: pypy/trunk/pypy/interpreter/pyparser/data/Grammar2.5 - copied unchanged from r67185, pypy/trunk/pypy/interpreter/pyparser/data/Grammar2.5_2 Removed: pypy/trunk/pypy/interpreter/pyparser/data/Grammar2.5_2 Modified: pypy/trunk/pypy/interpreter/pyparser/pygram.py Log: use Grammar2.5_2 as the default grammar Modified: pypy/trunk/pypy/interpreter/pyparser/pygram.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pygram.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/pygram.py Tue Aug 25 17:03:27 2009 @@ -9,7 +9,7 @@ def _get_python_grammar(): here = os.path.dirname(__file__) - fp = open(os.path.join(here, "data", "Grammar2.5_2")) + fp = open(os.path.join(here, "data", "Grammar2.5")) try: gram_source = fp.read() finally: From arigo at codespeak.net Tue Aug 25 17:16:58 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 17:16:58 +0200 (CEST) Subject: [pypy-svn] r67203 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090825151658.7616016805C@codespeak.net> Author: arigo Date: Tue Aug 25 17:16:55 2009 New Revision: 67203 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: Kill kill kill these helpers that are no longer invoked any more since r67176. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Tue Aug 25 17:16:55 2009 @@ -151,8 +151,7 @@ def force_box(self): if self.box is None: - if self.source_op is None: - self.prepare_force_box() + assert self.source_op is not None newoperations = self.optimizer.newoperations newoperations.append(self.source_op) self.box = box = self.source_op.result @@ -169,9 +168,6 @@ self._fields = None return self.box - def prepare_force_box(self): - raise NotImplementedError - def get_args_for_fail(self, modifier): if self.box is None and not modifier.is_virtual(self.keybox): # modifier.is_virtual() checks for recursion: it is False unless @@ -194,18 +190,6 @@ AbstractVirtualStructValue.__init__(self, optimizer, keybox, source_op) self.known_class = known_class - def prepare_force_box(self): - # rare case (shown by test_p123_simple) to force a Virtual - # from a specnode computed by optimizefindnode. - assert self.optimizer.reached_the_end - # The previous check is done for safety reasons: - # this function should only be used from teardown_virtual_node(); - # if we call force_box() from somewhere else and we get - # source_op=None, it is really a bug. - self.source_op = ResOperation(rop.NEW_WITH_VTABLE, - [self.known_class], - self.optimizer.new_ptr_box()) - def _make_virtual(self, modifier, fielddescrs, fieldboxes): modifier.make_virtual(self.keybox, self.known_class, fielddescrs, fieldboxes) @@ -217,14 +201,6 @@ AbstractVirtualStructValue.__init__(self, optimizer, keybox, source_op) self.structdescr = structdescr - def prepare_force_box(self): - # rare case (shown by test_p123_vstruct) to force a Virtual - # from a specnode computed by optimizefindnode. - assert self.optimizer.reached_the_end - self.source_op = ResOperation(rop.NEW, [], - self.optimizer.new_ptr_box(), - descr=self.structdescr) - def _make_virtual(self, modifier, fielddescrs, fieldboxes): modifier.make_vstruct(self.keybox, self.structdescr, fielddescrs, fieldboxes) @@ -252,8 +228,7 @@ def force_box(self): if self.box is None: - if self.source_op is None: - self.prepare_force_box() + assert self.source_op is not None newoperations = self.optimizer.newoperations newoperations.append(self.source_op) self.box = box = self.source_op.result @@ -267,15 +242,6 @@ newoperations.append(op) return self.box - def prepare_force_box(self): - # rare case (shown by test_p123_varray) to force a VirtualArray - # from a specnode computed by optimizefindnode. - assert self.optimizer.reached_the_end - self.source_op = ResOperation(rop.NEW_ARRAY, - [ConstInt(self.getlength())], - self.optimizer.new_ptr_box(), - descr=self.arraydescr) - def get_args_for_fail(self, modifier): if self.box is None and not modifier.is_virtual(self.keybox): # modifier.is_virtual() checks for recursion: it is False unless @@ -357,7 +323,6 @@ self.values = {} self.values_to_clean = [] # OptValues to clean when we see an # operation with side-effects - self.reached_the_end = False self.interned_ptrs = {} self.interned_objs = {} @@ -558,7 +523,6 @@ self.emit_operation(op) def optimize_JUMP(self, op): - self.reached_the_end = True orgop = self.loop.operations[-1] exitargs = [] specnodes = orgop.jump_target.specnodes From benjamin at codespeak.net Tue Aug 25 18:50:46 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 25 Aug 2009 18:50:46 +0200 (CEST) Subject: [pypy-svn] r67204 - pypy/trunk/pypy/translator/goal Message-ID: <20090825165046.C2D82168050@codespeak.net> Author: benjamin Date: Tue Aug 25 18:50:44 2009 New Revision: 67204 Modified: pypy/trunk/pypy/translator/goal/ (props changed) Log: remove llvm relic From arigo at codespeak.net Tue Aug 25 19:22:22 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 19:22:22 +0200 (CEST) Subject: [pypy-svn] r67205 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090825172222.0CD5F16805A@codespeak.net> Author: arigo Date: Tue Aug 25 19:22:21 2009 New Revision: 67205 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Log: Tests and (hopefully) fix. I'm not 100% convinced that the fix is the Best Possible Solution, but it's a minimal change... Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Tue Aug 25 19:22:21 2009 @@ -396,6 +396,9 @@ def nonconstbox(self): return self + def changevalue_box(self, srcbox): + raise NotImplementedError + def __repr__(self): result = str(self) if self._extended_display: @@ -457,6 +460,9 @@ def repr_rpython(self): return repr_rpython(self, 'bi') + def changevalue_box(self, srcbox): + self.changevalue_int(srcbox.getint()) + changevalue_int = __init__ class BoxPtr(Box): @@ -491,6 +497,9 @@ def repr_rpython(self): return repr_rpython(self, 'bp') + def changevalue_box(self, srcbox): + self.changevalue_ptr(srcbox.getptr_base()) + _getrepr_ = repr_pointer changevalue_ptr = __init__ @@ -529,6 +538,9 @@ def repr_rpython(self): return repr_rpython(self, 'bo') + def changevalue_box(self, srcbox): + self.changevalue_obj(srcbox.getobj()) + _getrepr_ = repr_object changevalue_obj = __init__ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Tue Aug 25 19:22:21 2009 @@ -30,15 +30,16 @@ # ____________________________________________________________ -LEVEL_UNKNOWN = 0 -LEVEL_NONNULL = 1 -LEVEL_KNOWNCLASS = 2 # might also mean KNOWNARRAYDESCR, for arrays -LEVEL_CONSTANT = 3 +LEVEL_UNKNOWN = '\x00' +LEVEL_NONNULL = '\x01' +LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays +LEVEL_CONSTANT = '\x03' class OptValue(object): - _attrs_ = ('box', 'level', '_fields') + _attrs_ = ('box', 'level', 'missing', '_fields') level = LEVEL_UNKNOWN + missing = False # is True if we don't know the value yet (for virtuals) _fields = None def __init__(self, box): @@ -55,6 +56,14 @@ def get_args_for_fail(self, modifier): pass + def initialize_if_missing(self, srcbox): + if self.missing: + dstbox = self.box + if dstbox is not None: + assert isinstance(dstbox, Box) + dstbox.changevalue_box(srcbox) + self.missing = False + def is_constant(self): return self.level == LEVEL_CONSTANT @@ -281,7 +290,9 @@ for ofs, subspecnode in self.fields: subbox = optimizer.new_box(ofs) subspecnode.setup_virtual_node(optimizer, subbox, newinputargs) - vvalue.setfield(ofs, optimizer.getvalue(subbox)) + vvaluefield = optimizer.getvalue(subbox) + vvaluefield.missing = True + vvalue.setfield(ofs, vvaluefield) def _setup_virtual_node_1(self, optimizer, box): raise NotImplementedError def teardown_virtual_node(self, optimizer, value, newexitargs): @@ -305,7 +316,9 @@ subbox = optimizer.new_box_item(self.arraydescr) subspecnode = self.items[index] subspecnode.setup_virtual_node(optimizer, subbox, newinputargs) - vvalue.setitem(index, optimizer.getvalue(subbox)) + vvalueitem = optimizer.getvalue(subbox) + vvalueitem.missing = True + vvalue.setitem(index, vvalueitem) def teardown_virtual_node(self, optimizer, value, newexitargs): assert value.is_virtual() const = optimizer.new_const_item(self.arraydescr) @@ -346,7 +359,6 @@ return box else: return box - def getvalue(self, box): box = self.getinterned(box) @@ -623,6 +635,7 @@ # optimizefindnode should ensure that fieldvalue is found fieldvalue = value.getfield(op.descr, None) assert fieldvalue is not None + fieldvalue.initialize_if_missing(op.result) self.make_equal_to(op.result, fieldvalue) else: # check if the field was read from another getfield_gc just before @@ -688,6 +701,7 @@ # optimizefindnode should ensure that itemvalue is found itemvalue = value.getitem(indexbox.getint(), None) assert itemvalue is not None + itemvalue.initialize_if_missing(op.result) self.make_equal_to(op.result, itemvalue) else: value.make_nonnull() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Tue Aug 25 19:22:21 2009 @@ -67,6 +67,7 @@ ssize = cpu.sizeof(S) adescr = cpu.fielddescrof(S, 'a') bdescr = cpu.fielddescrof(S, 'b') + sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S))) cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), @@ -106,6 +107,7 @@ ssize = cpu.typedescrof(S) adescr = cpu.fielddescrof(S, 'a') bdescr = cpu.fielddescrof(S, 'b') + sbox = BoxObj(ootype.cast_to_object(ootype.new(S))) arraydescr2 = cpu.arraydescrof(ootype.Array(S)) # force a consistent order Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 25 19:22:21 2009 @@ -1041,6 +1041,66 @@ """ self.optimize_loop(ops, 'Not, Not', ops) + def test_bug_1(self): + ops = """ + [i0, p1] + p4 = getfield_gc(p1, descr=nextdescr) + i2 = ooisnull(p4) + guard_false(i2) + fail() + escape(p4) + # + p2 = new_with_vtable(ConstClass(node_vtable)) + p3 = escape() + setfield_gc(p2, p3, descr=nextdescr) + jump(i0, p2) + """ + expected = """ + [i0, p4] + i2 = ooisnull(p4) + guard_false(i2) + fail() + escape(p4) + # + p3 = escape() + jump(i0, p3) + """ + self.optimize_loop(ops, 'Not, Virtual(node_vtable, nextdescr=Not)', + expected, i2=0, + p1=self.nodebox.value, + p2=self.nodebox.value, + p3=self.nodebox.value, + p4=self.nodebox.value) + + def test_bug_2(self): + ops = """ + [i0, p1] + p4 = getarrayitem_gc(p1, 0, descr=arraydescr2) + i2 = ooisnull(p4) + guard_false(i2) + fail() + escape(p4) + # + p2 = new_array(1, descr=arraydescr2) + p3 = escape() + setarrayitem_gc(p2, 0, p3, descr=arraydescr2) + jump(i0, p2) + """ + expected = """ + [i0, p4] + i2 = ooisnull(p4) + guard_false(i2) + fail() + escape(p4) + # + p3 = escape() + jump(i0, p3) + """ + self.optimize_loop(ops, 'Not, VArray(arraydescr2, Not)', + expected, i2=0, + p3=self.sbox.value, + p4=self.sbox.value) + # ---------- def make_fail_descr(self): @@ -1216,7 +1276,8 @@ fail(i3, i2, p3, descr=fdescr) jump(i2, 1, i3, p3) """ - self.optimize_loop(ops, 'Not, Not, Not, Not', expected, i1=1) + self.optimize_loop(ops, 'Not, Not, Not, Not', expected, i1=1, + p3=self.nodebox.value) self.check_expanded_fail_descr('''p1, i3 where p1 is a node_vtable, valuedescr=1, nextdescr=p2 where p2 is a node_vtable, valuedescr=i2, nextdescr=p3 From arigo at codespeak.net Tue Aug 25 19:56:48 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 19:56:48 +0200 (CEST) Subject: [pypy-svn] r67206 - pypy/trunk/pypy/doc/jit Message-ID: <20090825175648.705A316805C@codespeak.net> Author: arigo Date: Tue Aug 25 19:56:47 2009 New Revision: 67206 Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt Log: Use the "jit" label in the blog. Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/trunk/pypy/doc/jit/pyjitpl5.txt Tue Aug 25 19:56:47 2009 @@ -9,15 +9,6 @@ .. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit.pdf -as well as blog posts (oldest first): +as well as the `blog posts with the JIT tag.`__ -* http://morepypy.blogspot.com/2008/06/hi-all-some-news-from-jit-front.html -* http://morepypy.blogspot.com/2008/10/prolog-jit-masters-thesis-finished.html -* http://morepypy.blogspot.com/2009/03/applying-tracing-jit-to-interpreter.html -* http://morepypy.blogspot.com/2009/03/jit-bit-of-look-inside.html -* http://morepypy.blogspot.com/2009/03/good-news-everyone.html -* http://morepypy.blogspot.com/2009/04/roadmap-for-jit.html -* http://morepypy.blogspot.com/2009/04/4-weeks-of-gdb.html -* http://morepypy.blogspot.com/2009/05/icooolps-submissions.html -* http://morepypy.blogspot.com/2009/06/news-from-jit-front.html -* http://morepypy.blogspot.com/2009/06/jit-progress.html +.. __: http://morepypy.blogspot.com/search/label/jit From arigo at codespeak.net Tue Aug 25 20:07:27 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Aug 2009 20:07:27 +0200 (CEST) Subject: [pypy-svn] r67207 - pypy/trunk/pypy/doc/jit Message-ID: <20090825180727.4C514168035@codespeak.net> Author: arigo Date: Tue Aug 25 20:07:26 2009 New Revision: 67207 Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt Log: The article was published. Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/trunk/pypy/doc/jit/pyjitpl5.txt Tue Aug 25 20:07:26 2009 @@ -3,7 +3,7 @@ ======================================================================== The documentation about the current JIT is available as a -first submitted article: +first published article: * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ From arigo at codespeak.net Wed Aug 26 12:48:12 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 26 Aug 2009 12:48:12 +0200 (CEST) Subject: [pypy-svn] r67211 - pypy/branch/pyjitpl5/pypy/translator/c/gcc Message-ID: <20090826104812.81C0016801B@codespeak.net> Author: arigo Date: Wed Aug 26 12:48:11 2009 New Revision: 67211 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Log: Add an operation to ignore. Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Wed Aug 26 12:48:11 2009 @@ -515,7 +515,7 @@ # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', - 'bswap', + 'bswap', 'bt', # zero-extending moves should not produce GC pointers 'movz', ]) From arigo at codespeak.net Wed Aug 26 13:16:57 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 26 Aug 2009 13:16:57 +0200 (CEST) Subject: [pypy-svn] r67212 - in pypy/branch/pyjitpl5/pypy/translator/c: . gcc Message-ID: <20090826111657.8EC61168030@codespeak.net> Author: arigo Date: Wed Aug 26 13:16:55 2009 New Revision: 67212 Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py pypy/branch/pyjitpl5/pypy/translator/c/genc.py Log: Fix trackgcroot to not overwrite the .s file with its new version. Instead, produces a .lbl.s file. Fix the Makefile accordingly. This is "how things should done" and in particular it lets us use the Makefile normally -- e.g. modifying a .c source and typing "make" remakes only what is needed. Modified: pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/gcc/trackgcroot.py Wed Aug 26 13:16:55 2009 @@ -1112,7 +1112,6 @@ format = 'elf' tracker = GcRootTracker(verbose=verbose, shuffle=shuffle, format=format) for fn in sys.argv[1:]: - tmpfn = fn + '.TMP' f = open(fn, 'r') firstline = f.readline() f.seek(0) @@ -1120,12 +1119,12 @@ tracker.reload_raw_table(f) f.close() else: - g = open(tmpfn, 'w') + assert fn.endswith('.s') + lblfn = fn[:-2] + '.lbl.s' + g = open(lblfn, 'w') tracker.process(f, g, filename=fn) f.close() g.close() - os.unlink(fn) - os.rename(tmpfn, fn) if output_raw_table: tracker.dump_raw_table(sys.stdout) tracker.clear() Modified: pypy/branch/pyjitpl5/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/c/genc.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/c/genc.py Wed Aug 26 13:16:55 2009 @@ -483,14 +483,14 @@ mk.rule(*rule) if self.config.translation.gcrootfinder == 'asmgcc': - ofiles = ['%s.s' % (cfile[:-2],) for cfile in mk.cfiles] + lblsfiles = ['%s.lbl.s' % (cfile[:-2],) for cfile in mk.cfiles] gcmapfiles = ['%s.gcmap' % (cfile[:-2],) for cfile in mk.cfiles] - mk.definition('ASMFILES', ofiles) + mk.definition('ASMLBLFILES', lblsfiles) mk.definition('GCMAPFILES', gcmapfiles) - mk.definition('OBJECTS', '$(ASMFILES) gcmaptable.s') + mk.definition('OBJECTS', '$(ASMLBLFILES) gcmaptable.s') mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') - mk.rule('%.gcmap', '%.s', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1)') - mk.rule('gcmaptable.s', '$(GCMAPFILES)', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1)') + mk.rule('%.lbl.s %.gcmap', '%.s', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $*.gcmap') + mk.rule('gcmaptable.s', '$(GCMAPFILES)', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@') mk.write() #self.translator.platform, From antocuni at codespeak.net Wed Aug 26 14:59:07 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 26 Aug 2009 14:59:07 +0200 (CEST) Subject: [pypy-svn] r67214 - pypy/branch/pyjitpl5-nonnull-dictkeys Message-ID: <20090826125907.A325916802A@codespeak.net> Author: antocuni Date: Wed Aug 26 14:59:05 2009 New Revision: 67214 Added: pypy/branch/pyjitpl5-nonnull-dictkeys/ - copied from r67213, pypy/branch/pyjitpl5/ Log: a (hopefully short-lived) branch to require that dict keys cannot be none From antocuni at codespeak.net Wed Aug 26 15:26:16 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 26 Aug 2009 15:26:16 +0200 (CEST) Subject: [pypy-svn] r67215 - in pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation: . test Message-ID: <20090826132616.795EB16802D@codespeak.net> Author: antocuni Date: Wed Aug 26 15:26:14 2009 New Revision: 67215 Modified: pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/dictdef.py pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/test/test_annrpython.py Log: check that dict keys cannot be none, with the exception of dict whose key is always None, and dict whose key is degenerated (as some tests rely on it) Modified: pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/dictdef.py ============================================================================== --- pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/dictdef.py (original) +++ pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/dictdef.py Wed Aug 26 15:26:14 2009 @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeInteger, s_Bool, unionof -from pypy.annotation.model import SomeInstance +from pypy.annotation.model import SomeInstance, s_None, isdegenerated from pypy.annotation.listdef import ListItem @@ -135,6 +135,11 @@ def generalize_key(self, s_key): self.dictkey.generalize(s_key) + s_value = self.dictkey.s_value + # we allow degenerated keys because some tests rely on it, although is + # not really supported by RPython in a broader sense + if s_value != s_None and not isdegenerated(s_value) and s_value.can_be_none(): + raise Exception("dictionary keys cannot be None") def generalize_value(self, s_value): self.dictvalue.generalize(s_value) Modified: pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/test/test_annrpython.py Wed Aug 26 15:26:14 2009 @@ -495,6 +495,25 @@ s = a.build_types(snippet.dict_keys2, []) assert not isinstance(listitem(s), annmodel.SomeString) + def test_dict_keys_cannot_be_None(self): + a = self.RPythonAnnotator() + def f(): + d = {} + d['foo'] = 42 + d[None] = 43 + return d + py.test.raises(Exception, a.build_types, f, []) + + def test_dict_keys_void(self): + a = self.RPythonAnnotator() + def f(): + d = {} + d[None] = 43 + return d + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeDict) + assert s.dictdef.dictkey.s_value == annmodel.s_None + def test_dict_values(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values, []) @@ -525,7 +544,7 @@ assert isinstance(dictkey(s), annmodel.SomeString) assert isinstance(dictvalue(s), annmodel.SomeInteger) assert not dictvalue(s).nonneg - + def test_exception_deduction(self): a = self.RPythonAnnotator() s = a.build_types(snippet.exception_deduction, []) From antocuni at codespeak.net Wed Aug 26 16:38:03 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 26 Aug 2009 16:38:03 +0200 (CEST) Subject: [pypy-svn] r67216 - pypy/branch/pyjitpl5/pypy/translator/backendopt Message-ID: <20090826143803.A647B168039@codespeak.net> Author: antocuni Date: Wed Aug 26 16:38:01 2009 New Revision: 67216 Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Log: in rare cases, it might happend that we want to downcast instead of upcasting. Unfortunately, I spent 1 day searching for a failing test without success :-/ Modified: pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py (original) +++ pypy/branch/pyjitpl5/pypy/translator/backendopt/inline.py Wed Aug 26 16:38:01 2009 @@ -485,10 +485,14 @@ INPUT_SELF = inputv.concretetype if LINK_SELF != INPUT_SELF: # need to insert an upcast - assert ootype.isSubclass(LINK_SELF, INPUT_SELF) + if ootype.isSubclass(LINK_SELF, INPUT_SELF): + opname = 'ooupcast' + else: + assert ootype.isSubclass(INPUT_SELF, LINK_SELF) + opname = 'oodowncast' v = Variable() v.concretetype = INPUT_SELF - upcast = SpaceOperation('ooupcast', [linkv], v) + upcast = SpaceOperation(opname, [linkv], v) block.operations.append(upcast) passon_args[0] = v From antocuni at codespeak.net Wed Aug 26 16:38:58 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 26 Aug 2009 16:38:58 +0200 (CEST) Subject: [pypy-svn] r67217 - pypy/branch/pyjitpl5/pypy/jit/backend/cli Message-ID: <20090826143858.EBEB5168039@codespeak.net> Author: antocuni Date: Wed Aug 26 16:38:58 2009 New Revision: 67217 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Log: implement missing methods in the cli backend Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Wed Aug 26 16:38:58 2009 @@ -1,6 +1,7 @@ from pypy.tool.pairtype import extendabletype from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import we_are_translated +from pypy.jit.metainterp import history from pypy.jit.metainterp.history import AbstractDescr, AbstractMethDescr from pypy.jit.metainterp.history import Box, BoxInt, BoxObj, ConstObj, Const from pypy.jit.metainterp.history import TreeLoop @@ -318,6 +319,11 @@ self.instanceof = instanceof self.ooclass = get_class_for_type(TYPE) self.typename = TYPE._short_name() + self._is_array_of_pointers = (history.getkind(TYPE) == 'obj') + + def is_array_of_pointers(self): + # for arrays, TYPE is the type of the array item. + return self._is_array_of_pointers def get_clitype(self): return dotnet.class2type(self.ooclass) @@ -448,6 +454,10 @@ self.selfclass = ootype.runtimeClass(TYPE) self.fieldname = fieldname self.key = key_manager.getkey((TYPE, fieldname)) + self._is_pointer_field = (history.getkind(T) == 'obj') + + def is_pointer_field(self): + return self._is_pointer_field def equals(self, other): assert isinstance(other, FieldDescr) From antocuni at codespeak.net Wed Aug 26 17:19:59 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 26 Aug 2009 17:19:59 +0200 (CEST) Subject: [pypy-svn] r67218 - pypy/branch/pyjitpl5/pypy/jit/backend/cli Message-ID: <20090826151959.69A0016802F@codespeak.net> Author: antocuni Date: Wed Aug 26 17:19:57 2009 New Revision: 67218 Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/README.txt (contents, props changed) Log: quick instructions on how to run cli jit tests Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/README.txt ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/README.txt Wed Aug 26 17:19:57 2009 @@ -0,0 +1,23 @@ +What you need to run CLI jit tests +================================== + +Translated tests +----------------- + +Recent versions of mono contains a bug that prevents jit tests to run correctly: +http://bugzilla.novell.com/show_bug.cgi?id=474718 + +To run them, you either need: + + - an old version of mono (1.9 is known to work; probably versions up to 2.2 + works too but I'm not sure) + + - to run mono with -O=-branch; something like alias mono="mono -O=-branch" + should work, but I never tried + + +Direct tests +------------ + +You need Pythonnet: instructions on how to install it are here: +http://codespeak.net/pypy/dist/pypy/doc/cli-backend.html From arigo at codespeak.net Wed Aug 26 22:09:40 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 26 Aug 2009 22:09:40 +0200 (CEST) Subject: [pypy-svn] r67223 - pypy/build/bot2/pypybuildbot Message-ID: <20090826200940.6104F168032@codespeak.net> Author: arigo Date: Wed Aug 26 22:09:39 2009 New Revision: 67223 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Translate pypy-c-jit with our own GC now, to avoid seeing in lib-python the memory-not-freed-early-enough bugs common to pypy-c-boehm. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Wed Aug 26 22:09:39 2009 @@ -200,7 +200,7 @@ setup_steps(platform, self) - self.addStep(Translate(['-Ojit', '--gc=boehm'], + self.addStep(Translate(['-Ojit', '--gc=hybrid','--gcrootfinder=asmgcc'], ['--withoutmod-thread'])) self.addStep(ShellCmd( From antocuni at codespeak.net Thu Aug 27 10:11:18 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 10:11:18 +0200 (CEST) Subject: [pypy-svn] r67225 - pypy/trunk/pypy/doc Message-ID: <20090827081118.C9F1316805F@codespeak.net> Author: antocuni Date: Thu Aug 27 10:11:17 2009 New Revision: 67225 Modified: pypy/trunk/pypy/doc/extradoc.txt Log: these two papers have been published Modified: pypy/trunk/pypy/doc/extradoc.txt ============================================================================== --- pypy/trunk/pypy/doc/extradoc.txt (original) +++ pypy/trunk/pypy/doc/extradoc.txt Thu Aug 27 10:11:17 2009 @@ -7,6 +7,12 @@ *Articles about PyPy published so far, most recent first:* (bibtex_ file) +* `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, + C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo + +* `Faster than C#: Efficient Implementation of Dynamic Languages on .NET`_, + A. Cuni, D. Ancona and A. Rigo + * `Automatic JIT Compiler Generation with Runtime Partial Evaluation`_ (Master Thesis), C.F. Bolz @@ -21,12 +27,6 @@ *Non-published articles (only submitted so far, or technical reports):* -* `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, - C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo - -* `Faster than C#: Efficient Implementation of Dynamic Languages on .NET`_, - A. Cuni, D. Ancona and A. Rigo - * `Automatic generation of JIT compilers for dynamic languages in .NET`_, D. Ancona, C.F. Bolz, A. Cuni and A. Rigo From antocuni at codespeak.net Thu Aug 27 10:30:52 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 10:30:52 +0200 (CEST) Subject: [pypy-svn] r67226 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test Message-ID: <20090827083052.8915716805C@codespeak.net> Author: antocuni Date: Thu Aug 27 10:30:51 2009 New Revision: 67226 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_slist.py Log: skip this test for now Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_slist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_slist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_slist.py Thu Aug 27 10:30:51 2009 @@ -1,4 +1,5 @@ import py +py.test.skip('decide what to do') from pypy.jit.backend.cli.test.test_zrpy_basic import CliTranslatedJitMixin from pypy.jit.metainterp.test import test_slist From antocuni at codespeak.net Thu Aug 27 10:38:53 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 10:38:53 +0200 (CEST) Subject: [pypy-svn] r67227 - pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation Message-ID: <20090827083853.99C4716805C@codespeak.net> Author: antocuni Date: Thu Aug 27 10:38:53 2009 New Revision: 67227 Modified: pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/model.py Log: add can_be_none() to SomeOOInstance, to make it usable as a dictionary key. Modified: pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/model.py ============================================================================== --- pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/model.py (original) +++ pypy/branch/pyjitpl5-nonnull-dictkeys/pypy/annotation/model.py Thu Aug 27 10:38:53 2009 @@ -549,6 +549,9 @@ self.ootype = ootype self.can_be_None = can_be_None + def can_be_none(self): + return self.can_be_None + class SomeOOBoundMeth(SomeObject): immutable = True def __init__(self, ootype, name): From pedronis at codespeak.net Thu Aug 27 11:16:53 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Aug 2009 11:16:53 +0200 (CEST) Subject: [pypy-svn] r67228 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090827091653.8F33D168044@codespeak.net> Author: pedronis Date: Thu Aug 27 11:16:52 2009 New Revision: 67228 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Log: skip this test in the backends Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Thu Aug 27 11:16:52 2009 @@ -894,6 +894,10 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): + from pypy.jit.backend.test.support import BaseCompiledMixin + if isinstance(self, BaseCompiledMixin): + py.test.skip("purely frontend test") + myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'], virtualizables = ['frame']) From fijal at codespeak.net Thu Aug 27 12:57:29 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 27 Aug 2009 12:57:29 +0200 (CEST) Subject: [pypy-svn] r67230 - in pypy/build/benchmark: . test Message-ID: <20090827105729.5D981168029@codespeak.net> Author: fijal Date: Thu Aug 27 12:57:28 2009 New Revision: 67230 Added: pypy/build/benchmark/ pypy/build/benchmark/__init__.py (contents, props changed) pypy/build/benchmark/test/ pypy/build/benchmark/test/__init__.py (contents, props changed) Log: Start a directory for benchmark infrastructure. Added: pypy/build/benchmark/__init__.py ============================================================================== Added: pypy/build/benchmark/test/__init__.py ============================================================================== From pedronis at codespeak.net Thu Aug 27 13:30:20 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Aug 2009 13:30:20 +0200 (CEST) Subject: [pypy-svn] r67231 - pypy/branch/pyjitpl5 Message-ID: <20090827113020.99664168030@codespeak.net> Author: pedronis Date: Thu Aug 27 13:30:18 2009 New Revision: 67231 Modified: pypy/branch/pyjitpl5/ (props changed) Log: move the svn:externals to use py.lib 1.0.2 for this branch, solves the confusing reporting issues - will move trunk when its testing situation is sorted out From antocuni at codespeak.net Thu Aug 27 14:26:22 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 14:26:22 +0200 (CEST) Subject: [pypy-svn] r67232 - pypy/branch/pyjitpl5-nonnull-dictkeys Message-ID: <20090827122622.4197E16802F@codespeak.net> Author: antocuni Date: Thu Aug 27 14:26:20 2009 New Revision: 67232 Removed: pypy/branch/pyjitpl5-nonnull-dictkeys/ Log: abandon this branch; the idea is kind of nice, but after a while I realized that fixing the whole translation would take too much work for little benefit From antocuni at codespeak.net Thu Aug 27 14:58:29 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 14:58:29 +0200 (CEST) Subject: [pypy-svn] r67234 - pypy/branch/pyjitpl5-less-is_oo Message-ID: <20090827125829.7D491168026@codespeak.net> Author: antocuni Date: Thu Aug 27 14:58:28 2009 New Revision: 67234 Added: pypy/branch/pyjitpl5-less-is_oo/ - copied from r67233, pypy/branch/pyjitpl5/ Log: a branch to reduce the number of "if is_oo" and move to a more object-oriented style From cfbolz at codespeak.net Thu Aug 27 15:03:37 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 15:03:37 +0200 (CEST) Subject: [pypy-svn] r67235 - pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test Message-ID: <20090827130337.071BA168026@codespeak.net> Author: cfbolz Date: Thu Aug 27 15:03:36 2009 New Revision: 67235 Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Log: there were two tests with the name test_qsort Modified: pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/branch/pyjitpl5/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Thu Aug 27 15:03:36 2009 @@ -804,7 +804,7 @@ assert f() == 6 - def test_qsort(self): + def test_qsort_callback(self): TP = rffi.CArrayPtr(rffi.INT) a = lltype.malloc(TP.TO, 5, flavor='raw') a[0] = 5 From cfbolz at codespeak.net Thu Aug 27 15:04:42 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 15:04:42 +0200 (CEST) Subject: [pypy-svn] r67236 - pypy/extradoc/planning Message-ID: <20090827130442.5919D168026@codespeak.net> Author: cfbolz Date: Thu Aug 27 15:04:41 2009 New Revision: 67236 Added: pypy/extradoc/planning/jit.txt (contents, props changed) Log: migrate sprint planning file Added: pypy/extradoc/planning/jit.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/jit.txt Thu Aug 27 15:04:41 2009 @@ -0,0 +1,89 @@ +TASKS +----- + +- update things in metainterp/doc + +- compare backend vs gcc quality +- make x86 not recompile everything + - think about code memory management + +- migrate tasks to extradoc/planning/jit.txt +- merge the jit branch to trunk +- upgrade python on wyvern +- improve test running, compile only once +- sort out a benchmark infrastructure. graphs!!! +- investigate test coverage +- inlining on the Python level +- streamline calls +- stability? +- nightly run of checks on output of pypy-c-jit + + +Goals/Benchmarks +----------------- + +Goal: be somehow faster than CPython in real programs + +Benchmarks: + - Richards + - Pystone + - mako, gadfly, templess + - port some of the JS benchmarks? + - look at unladden-swallow benchmarks + - Sympy + - Simpy? + - Pyrolog + +later: + - translate.py + +- there should be a unified way to run these benchmark +- benchmarks should be run nightly +- we might need a benchmarking server + + +State of Tests +--------------- + +- we need tests for pypy-jit behaviour that explicitely check whether the loops + make sense +- the tragedy of the skipped tests + +things we know are missing +--------------------------- + +metainterp/frontend: +- virtualizables are not finished +- there is no restriction on the length of the trace +- proper inlining logic +- loop nesting (across calls) + +- speed of tracing and fallbacks? + +backend: +- recompilation after every bridge is bad +- memory management for the code +- speed of backend? + +Python interpreter: +- lookups of various kinds +- calls? + +ootype discussion +------------------ + +- try to unify interfaces to make doing the right thing for ootype easier +- different constraints for different groups of people +- what to do with ootype jit support after Anto finished his PhD? + +inlining discussion +-------------------- + +- need to trace aggressively +- give up when trace becomes too long +- need to remember when we gave up +- need to reset counters +- tracing aggressively will put pressure on the speed of tracing +- what should we do about recursive calls? +- connecting compiled loops accross a call? + From antocuni at codespeak.net Thu Aug 27 15:07:57 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 15:07:57 +0200 (CEST) Subject: [pypy-svn] r67237 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli backend/llgraph backend/llvm backend/x86 metainterp metainterp/test tl/spli/test Message-ID: <20090827130757.2F23F16800E@codespeak.net> Author: antocuni Date: Thu Aug 27 15:07:56 2009 New Revision: 67237 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Log: attach the ts helper to the cpu instead of to the staticdata. This already simplifies things a bit, and moreover assure that ts will be available wherever is_oo is tested Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu Aug 27 15:07:56 2009 @@ -11,6 +11,7 @@ from pypy.jit.backend.llgraph.runner import KeyManager from pypy.translator.cli import dotnet from pypy.translator.cli.dotnet import CLR +from pypy.jit.metainterp.typesystem import oohelper System = CLR.System OpCodes = System.Reflection.Emit.OpCodes @@ -29,7 +30,8 @@ class CliCPU(model.AbstractCPU): - + + ts = oohelper is_oo = True def __init__(self, rtyper, stats, translate_support_code=False, Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Thu Aug 27 15:07:56 2009 @@ -12,7 +12,7 @@ from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic - +from pypy.jit.metainterp.typesystem import llhelper, oohelper class MiniStats: pass @@ -242,6 +242,7 @@ class LLtypeCPU(BaseCPU): is_oo = False + ts = llhelper def __init__(self, *args, **kwds): BaseCPU.__init__(self, *args, **kwds) @@ -443,6 +444,7 @@ class OOtypeCPU(BaseCPU): is_oo = True + ts = oohelper @staticmethod def fielddescrof(T, fieldname): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Thu Aug 27 15:07:56 2009 @@ -10,11 +10,13 @@ from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86 import symbolic # xxx +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._llvm_compiled_index = -1 class LLVMCPU(object): + ts = llhelper is_oo = False logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Thu Aug 27 15:07:56 2009 @@ -16,6 +16,7 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop, opname from pypy.rlib.objectmodel import r_dict +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._x86_compiled = 0 history.TreeLoop._x86_bootstrap_code = 0 @@ -49,6 +50,7 @@ class CPU386(object): debug = True is_oo = False + ts = llhelper logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Thu Aug 27 15:07:56 2009 @@ -48,7 +48,7 @@ self.values = [] for graph in graphs: fnptr = codewriter.rtyper.getcallable(graph) - fnaddress = codewriter.ts.cast_fnptr_to_root(fnptr) + fnaddress = codewriter.cpu.ts.cast_fnptr_to_root(fnptr) self.keys.append(fnaddress) self.values.append(codewriter.get_jitcode(graph)) self.dict = None @@ -80,7 +80,7 @@ class CodeWriter(object): portal_graph = None - def __init__(self, metainterp_sd, policy, ts): + def __init__(self, metainterp_sd, policy): self.all_prebuilt_values = dict_equal_consts() self.all_graphs = {} self.all_indirectcallsets = {} @@ -91,7 +91,6 @@ self.rtyper = metainterp_sd.cpu.rtyper self.cpu = metainterp_sd.cpu self.policy = policy - self.ts = ts self.counter = 0 self.raise_analyzer = RaiseAnalyzer(self.rtyper.annotator.translator) self.class_sizes = [] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 15:07:56 2009 @@ -9,7 +9,6 @@ from pypy.jit.metainterp.history import Const, ConstInt, Box from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import codewriter, executor -from pypy.jit.metainterp import typesystem from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -845,7 +844,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) - constloc = sd.ts.conststr(loc) + constloc = self.metainterp.cpu.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -861,7 +860,7 @@ def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): assert isinstance(self.exception_box, Const) # XXX cpu = self.metainterp.cpu - ts = self.metainterp.staticdata.ts + ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): self.pc = next_exc_target @@ -966,7 +965,7 @@ return box # no promotion needed, already a Const def cls_of_box(self, box): - return self.metainterp.staticdata.ts.cls_of_box(self.metainterp.cpu, box) + return self.metainterp.cpu.ts.cls_of_box(self.metainterp.cpu, box) @specialize.arg(1) def execute(self, opnum, argboxes, descr=None): @@ -1007,11 +1006,6 @@ self.optimize_loop = optimizer.optimize_loop self.optimize_bridge = optimizer.optimize_bridge - if self.cpu.is_oo: - self.ts = typesystem.oohelper - else: - self.ts = typesystem.llhelper - if profile is not None: self.profiler = profile() else: @@ -1065,8 +1059,8 @@ class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) - def generate_bytecode(self, policy, ts): - self._codewriter = codewriter.CodeWriter(self, policy, ts) + def generate_bytecode(self, policy): + self._codewriter = codewriter.CodeWriter(self, policy) self.portal_code = self._codewriter.make_portal_bytecode( self.portal_graph) self._class_sizes = self._codewriter.class_sizes @@ -1158,7 +1152,7 @@ # - all subclasses of JitException if we_are_translated(): from pypy.jit.metainterp.warmspot import JitException - e = self.staticdata.ts.get_exception_obj(excvaluebox) + e = self.cpu.ts.get_exception_obj(excvaluebox) if isinstance(e, JitException) or isinstance(e, AssertionError): raise Exception, e # @@ -1183,14 +1177,14 @@ def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def raise_zero_division_error(self): etype, evalue = self.cpu.get_zero_division_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def create_empty_history(self): self.history = history.History(self.cpu) @@ -1392,20 +1386,20 @@ # save and restore all the boxes that are also used by callers. if self.history.inputargs is not None: for box in self.history.inputargs: - self.staticdata.ts.clean_box(box) + self.cpu.ts.clean_box(box) lists = [self.history.operations] while lists: for op in lists.pop(): if op is None: continue if op.result is not None: - self.staticdata.ts.clean_box(op.result) + self.cpu.ts.clean_box(op.result) if op.suboperations is not None: lists.append(op.suboperations) if op.optimized is not None: lists.append(op.optimized.suboperations) if op.optimized.result is not None: - self.staticdata.ts.clean_box(op.optimized.result) + self.cpu.ts.clean_box(op.optimized.result) def prepare_resume_from_failure(self, opnum): if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now @@ -1600,8 +1594,8 @@ self.cpu.clear_exception() frame = self.framestack[-1] if etype: - exception_box = self.staticdata.ts.get_exception_box(etype) - exc_value_box = self.staticdata.ts.get_exc_value_box(evalue) + exception_box = self.cpu.ts.get_exception_box(etype) + exc_value_box = self.cpu.ts.get_exc_value_box(evalue) op = frame.generate_guard(frame.pc, rop.GUARD_EXCEPTION, None, [exception_box]) if op: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Thu Aug 27 15:07:56 2009 @@ -73,7 +73,7 @@ self.type_system, policy=policy, optimizer=simple_optimize, **kwds) - cw = codewriter.CodeWriter(metainterp.staticdata, policy, self.ts) + cw = codewriter.CodeWriter(metainterp.staticdata, policy) graph = rtyper.annotator.translator.graphs[0] graph_key = (graph, None) maingraph = cw.make_one_bytecode(graph_key, False) @@ -103,7 +103,6 @@ class LLJitMixin(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() @staticmethod def Ptr(T): @@ -130,7 +129,6 @@ class OOJitMixin(JitMixin): type_system = 'ootype' CPUClass = runner.OOtypeCPU - ts = OOTypeHelper() @staticmethod def Ptr(T): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Thu Aug 27 15:07:56 2009 @@ -93,9 +93,9 @@ self.array_field_descrs = [cpu.fielddescrof(VTYPE, name) for name in array_fields] # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = cpu.ts.getlength + getarrayitem = cpu.ts.getarrayitem + setarrayitem = cpu.ts.setarrayitem # def read_boxes(cpu, virtualizable): boxes = [] @@ -178,7 +178,7 @@ force_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs - ts = self.warmrunnerdesc.ts + ts = self.warmrunnerdesc.cpu.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) rvirtualizable2.replace_promote_virtualizable_with_call( Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 27 15:07:56 2009 @@ -145,7 +145,7 @@ if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) - self.metainterp_sd.generate_bytecode(policy, self.ts) + self.metainterp_sd.generate_bytecode(policy) self.make_enter_function() self.rewrite_can_enter_jit() self.rewrite_set_param() @@ -164,11 +164,6 @@ def set_translator(self, translator): self.translator = translator - if translator.rtyper.type_system.name == 'lltypesystem': - self.ts = LLTypeHelper() - else: - assert translator.rtyper.type_system.name == 'ootypesystem' - self.ts = OOTypeHelper() self.gcdescr = gc.get_description(translator.config) def find_portal(self): @@ -277,7 +272,7 @@ annhelper = MixLevelHelperAnnotator(self.translator.rtyper) s_result = annotationoftype(rettype) RETTYPE = annhelper.rtyper.getrepr(s_result).lowleveltype - FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, RETTYPE) + FUNC, PTR = self.cpu.ts.get_FuncType(self.green_args_spec, RETTYPE) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] graph = annhelper.getgraph(func, args_s, s_result) funcptr = annhelper.graph2delayed(graph, FUNC) @@ -300,9 +295,9 @@ self.red_args_types.append(history.getkind(TYPE)) RESTYPE = graph.getreturnvar().concretetype (self.JIT_ENTER_FUNCTYPE, - self.PTR_JIT_ENTER_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, lltype.Void) + self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, - self.PTR_PORTAL_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, RESTYPE) + self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) def rewrite_can_enter_jit(self): @@ -374,7 +369,7 @@ # ____________________________________________________________ # Prepare the portal_runner() helper # - portal_ptr = self.ts.functionptr(PORTALFUNC, 'portal', + portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal', graph = portalgraph) portalfunc_ARGS = unrolling_iterable( [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)]) @@ -526,8 +521,8 @@ def rewrite_set_param(self): closures = {} graphs = self.translator.graphs - _, PTR_SET_PARAM_FUNCTYPE = self.ts.get_FuncType([lltype.Signed], - lltype.Void) + _, PTR_SET_PARAM_FUNCTYPE = self.cpu.ts.get_FuncType([lltype.Signed], + lltype.Void) def make_closure(fullfuncname): state = self.state def closure(i): @@ -666,9 +661,9 @@ MAX_HASH_TABLE_BITS = 1 THRESHOLD_LIMIT = sys.maxint // 2 # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = warmrunnerdesc.cpu.ts.getlength + getarrayitem = warmrunnerdesc.cpu.ts.getarrayitem + setarrayitem = warmrunnerdesc.cpu.ts.setarrayitem # rtyper = warmrunnerdesc.translator.rtyper can_inline_ptr = warmrunnerdesc.can_inline_ptr Modified: pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Thu Aug 27 15:07:56 2009 @@ -9,7 +9,6 @@ class TestSPLIJit(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() def interpret(self, f, args): coderepr = serializer.serialize(f.func_code) From antocuni at codespeak.net Thu Aug 27 15:21:16 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 15:21:16 +0200 (CEST) Subject: [pypy-svn] r67238 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli backend/llgraph backend/llvm backend/x86 metainterp metainterp/test tl/spli/test Message-ID: <20090827132116.4A45716800E@codespeak.net> Author: antocuni Date: Thu Aug 27 15:21:15 2009 New Revision: 67238 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Log: revert r67237, as it was supposed to go to a branch (thanks pedronis) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu Aug 27 15:21:15 2009 @@ -11,7 +11,6 @@ from pypy.jit.backend.llgraph.runner import KeyManager from pypy.translator.cli import dotnet from pypy.translator.cli.dotnet import CLR -from pypy.jit.metainterp.typesystem import oohelper System = CLR.System OpCodes = System.Reflection.Emit.OpCodes @@ -30,8 +29,7 @@ class CliCPU(model.AbstractCPU): - - ts = oohelper + is_oo = True def __init__(self, rtyper, stats, translate_support_code=False, Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Thu Aug 27 15:21:15 2009 @@ -12,7 +12,7 @@ from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic -from pypy.jit.metainterp.typesystem import llhelper, oohelper + class MiniStats: pass @@ -242,7 +242,6 @@ class LLtypeCPU(BaseCPU): is_oo = False - ts = llhelper def __init__(self, *args, **kwds): BaseCPU.__init__(self, *args, **kwds) @@ -444,7 +443,6 @@ class OOtypeCPU(BaseCPU): is_oo = True - ts = oohelper @staticmethod def fielddescrof(T, fieldname): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Thu Aug 27 15:21:15 2009 @@ -10,13 +10,11 @@ from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86 import symbolic # xxx -from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._llvm_compiled_index = -1 class LLVMCPU(object): - ts = llhelper is_oo = False logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Thu Aug 27 15:21:15 2009 @@ -16,7 +16,6 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop, opname from pypy.rlib.objectmodel import r_dict -from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._x86_compiled = 0 history.TreeLoop._x86_bootstrap_code = 0 @@ -50,7 +49,6 @@ class CPU386(object): debug = True is_oo = False - ts = llhelper logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Thu Aug 27 15:21:15 2009 @@ -48,7 +48,7 @@ self.values = [] for graph in graphs: fnptr = codewriter.rtyper.getcallable(graph) - fnaddress = codewriter.cpu.ts.cast_fnptr_to_root(fnptr) + fnaddress = codewriter.ts.cast_fnptr_to_root(fnptr) self.keys.append(fnaddress) self.values.append(codewriter.get_jitcode(graph)) self.dict = None @@ -80,7 +80,7 @@ class CodeWriter(object): portal_graph = None - def __init__(self, metainterp_sd, policy): + def __init__(self, metainterp_sd, policy, ts): self.all_prebuilt_values = dict_equal_consts() self.all_graphs = {} self.all_indirectcallsets = {} @@ -91,6 +91,7 @@ self.rtyper = metainterp_sd.cpu.rtyper self.cpu = metainterp_sd.cpu self.policy = policy + self.ts = ts self.counter = 0 self.raise_analyzer = RaiseAnalyzer(self.rtyper.annotator.translator) self.class_sizes = [] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 15:21:15 2009 @@ -9,6 +9,7 @@ from pypy.jit.metainterp.history import Const, ConstInt, Box from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import codewriter, executor +from pypy.jit.metainterp import typesystem from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -844,7 +845,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) - constloc = self.metainterp.cpu.ts.conststr(loc) + constloc = sd.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -860,7 +861,7 @@ def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): assert isinstance(self.exception_box, Const) # XXX cpu = self.metainterp.cpu - ts = self.metainterp.cpu.ts + ts = self.metainterp.staticdata.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): self.pc = next_exc_target @@ -965,7 +966,7 @@ return box # no promotion needed, already a Const def cls_of_box(self, box): - return self.metainterp.cpu.ts.cls_of_box(self.metainterp.cpu, box) + return self.metainterp.staticdata.ts.cls_of_box(self.metainterp.cpu, box) @specialize.arg(1) def execute(self, opnum, argboxes, descr=None): @@ -1006,6 +1007,11 @@ self.optimize_loop = optimizer.optimize_loop self.optimize_bridge = optimizer.optimize_bridge + if self.cpu.is_oo: + self.ts = typesystem.oohelper + else: + self.ts = typesystem.llhelper + if profile is not None: self.profiler = profile() else: @@ -1059,8 +1065,8 @@ class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) - def generate_bytecode(self, policy): - self._codewriter = codewriter.CodeWriter(self, policy) + def generate_bytecode(self, policy, ts): + self._codewriter = codewriter.CodeWriter(self, policy, ts) self.portal_code = self._codewriter.make_portal_bytecode( self.portal_graph) self._class_sizes = self._codewriter.class_sizes @@ -1152,7 +1158,7 @@ # - all subclasses of JitException if we_are_translated(): from pypy.jit.metainterp.warmspot import JitException - e = self.cpu.ts.get_exception_obj(excvaluebox) + e = self.staticdata.ts.get_exception_obj(excvaluebox) if isinstance(e, JitException) or isinstance(e, AssertionError): raise Exception, e # @@ -1177,14 +1183,14 @@ def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() return self.finishframe_exception( - self.cpu.ts.get_exception_box(etype), - self.cpu.ts.get_exc_value_box(evalue)) + self.staticdata.ts.get_exception_box(etype), + self.staticdata.ts.get_exc_value_box(evalue)) def raise_zero_division_error(self): etype, evalue = self.cpu.get_zero_division_error() return self.finishframe_exception( - self.cpu.ts.get_exception_box(etype), - self.cpu.ts.get_exc_value_box(evalue)) + self.staticdata.ts.get_exception_box(etype), + self.staticdata.ts.get_exc_value_box(evalue)) def create_empty_history(self): self.history = history.History(self.cpu) @@ -1386,20 +1392,20 @@ # save and restore all the boxes that are also used by callers. if self.history.inputargs is not None: for box in self.history.inputargs: - self.cpu.ts.clean_box(box) + self.staticdata.ts.clean_box(box) lists = [self.history.operations] while lists: for op in lists.pop(): if op is None: continue if op.result is not None: - self.cpu.ts.clean_box(op.result) + self.staticdata.ts.clean_box(op.result) if op.suboperations is not None: lists.append(op.suboperations) if op.optimized is not None: lists.append(op.optimized.suboperations) if op.optimized.result is not None: - self.cpu.ts.clean_box(op.optimized.result) + self.staticdata.ts.clean_box(op.optimized.result) def prepare_resume_from_failure(self, opnum): if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now @@ -1594,8 +1600,8 @@ self.cpu.clear_exception() frame = self.framestack[-1] if etype: - exception_box = self.cpu.ts.get_exception_box(etype) - exc_value_box = self.cpu.ts.get_exc_value_box(evalue) + exception_box = self.staticdata.ts.get_exception_box(etype) + exc_value_box = self.staticdata.ts.get_exc_value_box(evalue) op = frame.generate_guard(frame.pc, rop.GUARD_EXCEPTION, None, [exception_box]) if op: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Thu Aug 27 15:21:15 2009 @@ -73,7 +73,7 @@ self.type_system, policy=policy, optimizer=simple_optimize, **kwds) - cw = codewriter.CodeWriter(metainterp.staticdata, policy) + cw = codewriter.CodeWriter(metainterp.staticdata, policy, self.ts) graph = rtyper.annotator.translator.graphs[0] graph_key = (graph, None) maingraph = cw.make_one_bytecode(graph_key, False) @@ -103,6 +103,7 @@ class LLJitMixin(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU + ts = LLTypeHelper() @staticmethod def Ptr(T): @@ -129,6 +130,7 @@ class OOJitMixin(JitMixin): type_system = 'ootype' CPUClass = runner.OOtypeCPU + ts = OOTypeHelper() @staticmethod def Ptr(T): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Thu Aug 27 15:21:15 2009 @@ -93,9 +93,9 @@ self.array_field_descrs = [cpu.fielddescrof(VTYPE, name) for name in array_fields] # - getlength = cpu.ts.getlength - getarrayitem = cpu.ts.getarrayitem - setarrayitem = cpu.ts.setarrayitem + getlength = warmrunnerdesc.ts.getlength + getarrayitem = warmrunnerdesc.ts.getarrayitem + setarrayitem = warmrunnerdesc.ts.setarrayitem # def read_boxes(cpu, virtualizable): boxes = [] @@ -178,7 +178,7 @@ force_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs - ts = self.warmrunnerdesc.cpu.ts + ts = self.warmrunnerdesc.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) rvirtualizable2.replace_promote_virtualizable_with_call( Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 27 15:21:15 2009 @@ -145,7 +145,7 @@ if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) - self.metainterp_sd.generate_bytecode(policy) + self.metainterp_sd.generate_bytecode(policy, self.ts) self.make_enter_function() self.rewrite_can_enter_jit() self.rewrite_set_param() @@ -164,6 +164,11 @@ def set_translator(self, translator): self.translator = translator + if translator.rtyper.type_system.name == 'lltypesystem': + self.ts = LLTypeHelper() + else: + assert translator.rtyper.type_system.name == 'ootypesystem' + self.ts = OOTypeHelper() self.gcdescr = gc.get_description(translator.config) def find_portal(self): @@ -272,7 +277,7 @@ annhelper = MixLevelHelperAnnotator(self.translator.rtyper) s_result = annotationoftype(rettype) RETTYPE = annhelper.rtyper.getrepr(s_result).lowleveltype - FUNC, PTR = self.cpu.ts.get_FuncType(self.green_args_spec, RETTYPE) + FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, RETTYPE) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] graph = annhelper.getgraph(func, args_s, s_result) funcptr = annhelper.graph2delayed(graph, FUNC) @@ -295,9 +300,9 @@ self.red_args_types.append(history.getkind(TYPE)) RESTYPE = graph.getreturnvar().concretetype (self.JIT_ENTER_FUNCTYPE, - self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) + self.PTR_JIT_ENTER_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, - self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) + self.PTR_PORTAL_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, RESTYPE) def rewrite_can_enter_jit(self): @@ -369,7 +374,7 @@ # ____________________________________________________________ # Prepare the portal_runner() helper # - portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal', + portal_ptr = self.ts.functionptr(PORTALFUNC, 'portal', graph = portalgraph) portalfunc_ARGS = unrolling_iterable( [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)]) @@ -521,8 +526,8 @@ def rewrite_set_param(self): closures = {} graphs = self.translator.graphs - _, PTR_SET_PARAM_FUNCTYPE = self.cpu.ts.get_FuncType([lltype.Signed], - lltype.Void) + _, PTR_SET_PARAM_FUNCTYPE = self.ts.get_FuncType([lltype.Signed], + lltype.Void) def make_closure(fullfuncname): state = self.state def closure(i): @@ -661,9 +666,9 @@ MAX_HASH_TABLE_BITS = 1 THRESHOLD_LIMIT = sys.maxint // 2 # - getlength = warmrunnerdesc.cpu.ts.getlength - getarrayitem = warmrunnerdesc.cpu.ts.getarrayitem - setarrayitem = warmrunnerdesc.cpu.ts.setarrayitem + getlength = warmrunnerdesc.ts.getlength + getarrayitem = warmrunnerdesc.ts.getarrayitem + setarrayitem = warmrunnerdesc.ts.setarrayitem # rtyper = warmrunnerdesc.translator.rtyper can_inline_ptr = warmrunnerdesc.can_inline_ptr Modified: pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Thu Aug 27 15:21:15 2009 @@ -9,6 +9,7 @@ class TestSPLIJit(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU + ts = LLTypeHelper() def interpret(self, f, args): coderepr = serializer.serialize(f.func_code) From pedronis at codespeak.net Thu Aug 27 15:22:11 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Aug 2009 15:22:11 +0200 (CEST) Subject: [pypy-svn] r67239 - in pypy/extradoc/planning: . attic attic/malaga_exhibition_feb2006 malaga_exhibition_feb2006 Message-ID: <20090827132211.F404216800E@codespeak.net> Author: pedronis Date: Thu Aug 27 15:22:11 2009 New Revision: 67239 Added: pypy/extradoc/planning/attic/ pypy/extradoc/planning/attic/conference-planning.txt (props changed) - copied unchanged from r67237, pypy/extradoc/planning/conference-planning.txt pypy/extradoc/planning/attic/malaga_exhibition_feb2006/ (props changed) - copied from r67237, pypy/extradoc/planning/malaga_exhibition_feb2006/ pypy/extradoc/planning/attic/phase2_projectactivities_051015.txt (props changed) - copied unchanged from r67237, pypy/extradoc/planning/phase2_projectactivities_051015.txt pypy/extradoc/planning/attic/sprint-planning.txt (props changed) - copied unchanged from r67237, pypy/extradoc/planning/sprint-planning.txt pypy/extradoc/planning/attic/summer-of-pypy-announce.txt (props changed) - copied unchanged from r67237, pypy/extradoc/planning/summer-of-pypy-announce.txt Removed: pypy/extradoc/planning/conference-planning.txt pypy/extradoc/planning/malaga_exhibition_feb2006/ pypy/extradoc/planning/phase2_projectactivities_051015.txt pypy/extradoc/planning/sprint-planning.txt pypy/extradoc/planning/summer-of-pypy-announce.txt Log: some spring cleaning From antocuni at codespeak.net Thu Aug 27 15:23:03 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 15:23:03 +0200 (CEST) Subject: [pypy-svn] r67240 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend/cli backend/llgraph backend/llvm backend/x86 metainterp metainterp/test tl/spli/test Message-ID: <20090827132303.5DC1216800E@codespeak.net> Author: antocuni Date: Thu Aug 27 15:23:01 2009 New Revision: 67240 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/tl/spli/test/test_jit.py Log: attach the ts helper to the cpu instead of to the staticdata. This already simplifies things a bit, and moreover assure that ts will be available wherever is_oo is tested Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py Thu Aug 27 15:23:01 2009 @@ -11,6 +11,7 @@ from pypy.jit.backend.llgraph.runner import KeyManager from pypy.translator.cli import dotnet from pypy.translator.cli.dotnet import CLR +from pypy.jit.metainterp.typesystem import oohelper System = CLR.System OpCodes = System.Reflection.Emit.OpCodes @@ -29,7 +30,8 @@ class CliCPU(model.AbstractCPU): - + + ts = oohelper is_oo = True def __init__(self, rtyper, stats, translate_support_code=False, Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Thu Aug 27 15:23:01 2009 @@ -12,7 +12,7 @@ from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic - +from pypy.jit.metainterp.typesystem import llhelper, oohelper class MiniStats: pass @@ -242,6 +242,7 @@ class LLtypeCPU(BaseCPU): is_oo = False + ts = llhelper def __init__(self, *args, **kwds): BaseCPU.__init__(self, *args, **kwds) @@ -443,6 +444,7 @@ class OOtypeCPU(BaseCPU): is_oo = True + ts = oohelper @staticmethod def fielddescrof(T, fieldname): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py Thu Aug 27 15:23:01 2009 @@ -10,11 +10,13 @@ from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86 import symbolic # xxx +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._llvm_compiled_index = -1 class LLVMCPU(object): + ts = llhelper is_oo = False logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Thu Aug 27 15:23:01 2009 @@ -16,6 +16,7 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop, opname from pypy.rlib.objectmodel import r_dict +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._x86_compiled = 0 history.TreeLoop._x86_bootstrap_code = 0 @@ -49,6 +50,7 @@ class CPU386(object): debug = True is_oo = False + ts = llhelper logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py Thu Aug 27 15:23:01 2009 @@ -48,7 +48,7 @@ self.values = [] for graph in graphs: fnptr = codewriter.rtyper.getcallable(graph) - fnaddress = codewriter.ts.cast_fnptr_to_root(fnptr) + fnaddress = codewriter.cpu.ts.cast_fnptr_to_root(fnptr) self.keys.append(fnaddress) self.values.append(codewriter.get_jitcode(graph)) self.dict = None @@ -80,7 +80,7 @@ class CodeWriter(object): portal_graph = None - def __init__(self, metainterp_sd, policy, ts): + def __init__(self, metainterp_sd, policy): self.all_prebuilt_values = dict_equal_consts() self.all_graphs = {} self.all_indirectcallsets = {} @@ -91,7 +91,6 @@ self.rtyper = metainterp_sd.cpu.rtyper self.cpu = metainterp_sd.cpu self.policy = policy - self.ts = ts self.counter = 0 self.raise_analyzer = RaiseAnalyzer(self.rtyper.annotator.translator) self.class_sizes = [] Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 15:23:01 2009 @@ -9,7 +9,6 @@ from pypy.jit.metainterp.history import Const, ConstInt, Box from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import codewriter, executor -from pypy.jit.metainterp import typesystem from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -845,7 +844,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) - constloc = sd.ts.conststr(loc) + constloc = self.metainterp.cpu.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -861,7 +860,7 @@ def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): assert isinstance(self.exception_box, Const) # XXX cpu = self.metainterp.cpu - ts = self.metainterp.staticdata.ts + ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): self.pc = next_exc_target @@ -966,7 +965,7 @@ return box # no promotion needed, already a Const def cls_of_box(self, box): - return self.metainterp.staticdata.ts.cls_of_box(self.metainterp.cpu, box) + return self.metainterp.cpu.ts.cls_of_box(self.metainterp.cpu, box) @specialize.arg(1) def execute(self, opnum, argboxes, descr=None): @@ -1007,11 +1006,6 @@ self.optimize_loop = optimizer.optimize_loop self.optimize_bridge = optimizer.optimize_bridge - if self.cpu.is_oo: - self.ts = typesystem.oohelper - else: - self.ts = typesystem.llhelper - if profile is not None: self.profiler = profile() else: @@ -1065,8 +1059,8 @@ class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) - def generate_bytecode(self, policy, ts): - self._codewriter = codewriter.CodeWriter(self, policy, ts) + def generate_bytecode(self, policy): + self._codewriter = codewriter.CodeWriter(self, policy) self.portal_code = self._codewriter.make_portal_bytecode( self.portal_graph) self._class_sizes = self._codewriter.class_sizes @@ -1158,7 +1152,7 @@ # - all subclasses of JitException if we_are_translated(): from pypy.jit.metainterp.warmspot import JitException - e = self.staticdata.ts.get_exception_obj(excvaluebox) + e = self.cpu.ts.get_exception_obj(excvaluebox) if isinstance(e, JitException) or isinstance(e, AssertionError): raise Exception, e # @@ -1183,14 +1177,14 @@ def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def raise_zero_division_error(self): etype, evalue = self.cpu.get_zero_division_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def create_empty_history(self): self.history = history.History(self.cpu) @@ -1392,20 +1386,20 @@ # save and restore all the boxes that are also used by callers. if self.history.inputargs is not None: for box in self.history.inputargs: - self.staticdata.ts.clean_box(box) + self.cpu.ts.clean_box(box) lists = [self.history.operations] while lists: for op in lists.pop(): if op is None: continue if op.result is not None: - self.staticdata.ts.clean_box(op.result) + self.cpu.ts.clean_box(op.result) if op.suboperations is not None: lists.append(op.suboperations) if op.optimized is not None: lists.append(op.optimized.suboperations) if op.optimized.result is not None: - self.staticdata.ts.clean_box(op.optimized.result) + self.cpu.ts.clean_box(op.optimized.result) def prepare_resume_from_failure(self, opnum): if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now @@ -1600,8 +1594,8 @@ self.cpu.clear_exception() frame = self.framestack[-1] if etype: - exception_box = self.staticdata.ts.get_exception_box(etype) - exc_value_box = self.staticdata.ts.get_exc_value_box(evalue) + exception_box = self.cpu.ts.get_exception_box(etype) + exc_value_box = self.cpu.ts.get_exc_value_box(evalue) op = frame.generate_guard(frame.pc, rop.GUARD_EXCEPTION, None, [exception_box]) if op: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py Thu Aug 27 15:23:01 2009 @@ -73,7 +73,7 @@ self.type_system, policy=policy, optimizer=simple_optimize, **kwds) - cw = codewriter.CodeWriter(metainterp.staticdata, policy, self.ts) + cw = codewriter.CodeWriter(metainterp.staticdata, policy) graph = rtyper.annotator.translator.graphs[0] graph_key = (graph, None) maingraph = cw.make_one_bytecode(graph_key, False) @@ -103,7 +103,6 @@ class LLJitMixin(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() @staticmethod def Ptr(T): @@ -130,7 +129,6 @@ class OOJitMixin(JitMixin): type_system = 'ootype' CPUClass = runner.OOtypeCPU - ts = OOTypeHelper() @staticmethod def Ptr(T): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Thu Aug 27 15:23:01 2009 @@ -93,9 +93,9 @@ self.array_field_descrs = [cpu.fielddescrof(VTYPE, name) for name in array_fields] # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = cpu.ts.getlength + getarrayitem = cpu.ts.getarrayitem + setarrayitem = cpu.ts.setarrayitem # def read_boxes(cpu, virtualizable): boxes = [] @@ -178,7 +178,7 @@ force_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs - ts = self.warmrunnerdesc.ts + ts = self.warmrunnerdesc.cpu.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) rvirtualizable2.replace_promote_virtualizable_with_call( Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 15:23:01 2009 @@ -145,7 +145,7 @@ if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) - self.metainterp_sd.generate_bytecode(policy, self.ts) + self.metainterp_sd.generate_bytecode(policy) self.make_enter_function() self.rewrite_can_enter_jit() self.rewrite_set_param() @@ -164,11 +164,6 @@ def set_translator(self, translator): self.translator = translator - if translator.rtyper.type_system.name == 'lltypesystem': - self.ts = LLTypeHelper() - else: - assert translator.rtyper.type_system.name == 'ootypesystem' - self.ts = OOTypeHelper() self.gcdescr = gc.get_description(translator.config) def find_portal(self): @@ -277,7 +272,7 @@ annhelper = MixLevelHelperAnnotator(self.translator.rtyper) s_result = annotationoftype(rettype) RETTYPE = annhelper.rtyper.getrepr(s_result).lowleveltype - FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, RETTYPE) + FUNC, PTR = self.cpu.ts.get_FuncType(self.green_args_spec, RETTYPE) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] graph = annhelper.getgraph(func, args_s, s_result) funcptr = annhelper.graph2delayed(graph, FUNC) @@ -300,9 +295,9 @@ self.red_args_types.append(history.getkind(TYPE)) RESTYPE = graph.getreturnvar().concretetype (self.JIT_ENTER_FUNCTYPE, - self.PTR_JIT_ENTER_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, lltype.Void) + self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, - self.PTR_PORTAL_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, RESTYPE) + self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) def rewrite_can_enter_jit(self): @@ -374,7 +369,7 @@ # ____________________________________________________________ # Prepare the portal_runner() helper # - portal_ptr = self.ts.functionptr(PORTALFUNC, 'portal', + portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal', graph = portalgraph) portalfunc_ARGS = unrolling_iterable( [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)]) @@ -526,8 +521,8 @@ def rewrite_set_param(self): closures = {} graphs = self.translator.graphs - _, PTR_SET_PARAM_FUNCTYPE = self.ts.get_FuncType([lltype.Signed], - lltype.Void) + _, PTR_SET_PARAM_FUNCTYPE = self.cpu.ts.get_FuncType([lltype.Signed], + lltype.Void) def make_closure(fullfuncname): state = self.state def closure(i): @@ -666,9 +661,9 @@ MAX_HASH_TABLE_BITS = 1 THRESHOLD_LIMIT = sys.maxint // 2 # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = warmrunnerdesc.cpu.ts.getlength + getarrayitem = warmrunnerdesc.cpu.ts.getarrayitem + setarrayitem = warmrunnerdesc.cpu.ts.setarrayitem # rtyper = warmrunnerdesc.translator.rtyper can_inline_ptr = warmrunnerdesc.can_inline_ptr Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/tl/spli/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/tl/spli/test/test_jit.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/tl/spli/test/test_jit.py Thu Aug 27 15:23:01 2009 @@ -9,7 +9,6 @@ class TestSPLIJit(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() def interpret(self, f, args): coderepr = serializer.serialize(f.func_code) From fijal at codespeak.net Thu Aug 27 15:31:50 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 27 Aug 2009 15:31:50 +0200 (CEST) Subject: [pypy-svn] r67241 - in pypy/build/benchmark: . test Message-ID: <20090827133150.D9D0E16801B@codespeak.net> Author: fijal Date: Thu Aug 27 15:31:50 2009 New Revision: 67241 Added: pypy/build/benchmark/runner.py (contents, props changed) pypy/build/benchmark/test/test_runner.py (contents, props changed) Modified: pypy/build/benchmark/ (props changed) pypy/build/benchmark/test/ (props changed) Log: Start writing some code & fixeol Added: pypy/build/benchmark/runner.py ============================================================================== --- (empty file) +++ pypy/build/benchmark/runner.py Thu Aug 27 15:31:50 2009 @@ -0,0 +1,60 @@ + +import sys +import py +import re +import subprocess +from pypy.tool.udir import udir + +class ErrorExecuting(Exception): + pass + +class OutputDidNotMatch(Exception): + pass + +class AbstractRunner(object): + def run(self, n=1): + """ Runs a benchmark returning list of results + """ + t = [] + for i in range(n): + t.append(self.run_once()) + return t + + def run_once(self): + raise NotImplementedError("abstract base class") + +class ScriptRunner(AbstractRunner): + tmpdir = None + + def __init__(self, name, source, executable=sys.executable): + self.name = name + self.source = source + self.executable = executable + + @classmethod + def setup_tmpdir(cls): + if cls.tmpdir is None: + cls.tmpdir = udir.join('benchmark_runner') + cls.tmpdir.ensure(dir=True) + + def run_once(self): + self.setup_tmpdir() + fname = self.tmpdir.join(self.name + '.py') + fname.write(self.source) + pipe = subprocess.Popen([sys.executable, str(fname)], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + res = pipe.wait() + if res: + raise ErrorExecuting(res, pipe.stderr, pipe.stdout) + t = self.read_output(pipe.stdout.read()) + return t + + def read_output(self, output): + """ override this + """ + m = re.match("^time: ([\d.]+)$", output) + if not m: + raise OutputDidNotMatch("got %s" % output) + return float(m.group(1)) + Added: pypy/build/benchmark/test/test_runner.py ============================================================================== --- (empty file) +++ pypy/build/benchmark/test/test_runner.py Thu Aug 27 15:31:50 2009 @@ -0,0 +1,18 @@ + +import py +from benchmark.runner import ScriptRunner, ErrorExecuting + +class TestRunner(object): + def test_script_runner(self): + runner = ScriptRunner("test1", "print 'time: 0'") + t = runner.run(5) + assert t == [0, 0, 0, 0, 0] + + def test_scipt_runner_float(self): + runner = ScriptRunner("test2", "print 'time: 0.3'") + t = runner.run(5) + assert t == [0.3, 0.3, 0.3, 0.3, 0.3] + + def test_script_runner_fail(self): + runner = ScriptRunner("test3", "import sys; sys.exit(1)") + py.test.raises(ErrorExecuting, runner.run) From pedronis at codespeak.net Thu Aug 27 15:44:06 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Aug 2009 15:44:06 +0200 (CEST) Subject: [pypy-svn] r67242 - pypy/extradoc/planning Message-ID: <20090827134406.79A0416801B@codespeak.net> Author: pedronis Date: Thu Aug 27 15:44:05 2009 New Revision: 67242 Modified: pypy/extradoc/planning/jit.txt Log: reorganize, remove some duplication Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Thu Aug 27 15:44:05 2009 @@ -1,23 +1,68 @@ TASKS ----- -- update things in metainterp/doc - -- compare backend vs gcc quality -- make x86 not recompile everything - - think about code memory management +- inlining on the Python level (see discussion) +- streamline calls +- stability! -- migrate tasks to extradoc/planning/jit.txt - merge the jit branch to trunk + - upgrade python on wyvern - improve test running, compile only once - sort out a benchmark infrastructure. graphs!!! -- investigate test coverage -- inlining on the Python level -- streamline calls -- stability? -- nightly run of checks on output of pypy-c-jit +- nightly run of checks on output of pypy-c-jit: we need tests for + pypy-jit behaviour that explicitely check whether the loops make + sense + +- the tragedy of the skipped tests +- keep test coverage in check + +- make x86 not recompile everything + - think about code memory management + +- compare backend vs gcc quality + +- asmgcc: support callbacks (threads?) + +- update things in metainterp/doc + +inlining discussion +-------------------- + +- need to trace aggressively +- give up when trace becomes too long +- need to remember when we gave up +- need to reset counters +- tracing aggressively will put pressure on the speed of tracing +- what should we do about recursive calls? +- connecting compiled loops accross a call? + +things we know are missing +--------------------------- + +metainterp/frontend: +- virtualizables are not finished: + fix 'test_external_read_sometimes' + +- float support + +- speed of tracing and fallbacks? +- save space on all the guard operations (see resume.py) + +backend: +- recompilation after every bridge is bad +- memory management for the code (free unused code) +- speed of backend? + +- support threads again! + +Python interpreter: +- lookups of various kinds +- calls??? + +tests: +- find a test for r64742 (JitException capture) Goals/Benchmarks ----------------- @@ -42,48 +87,9 @@ - we might need a benchmarking server -State of Tests ---------------- - -- we need tests for pypy-jit behaviour that explicitely check whether the loops - make sense -- the tragedy of the skipped tests - -things we know are missing ---------------------------- - -metainterp/frontend: -- virtualizables are not finished -- there is no restriction on the length of the trace -- proper inlining logic -- loop nesting (across calls) - -- speed of tracing and fallbacks? - -backend: -- recompilation after every bridge is bad -- memory management for the code -- speed of backend? - -Python interpreter: -- lookups of various kinds -- calls? - ootype discussion ------------------ - try to unify interfaces to make doing the right thing for ootype easier - different constraints for different groups of people - what to do with ootype jit support after Anto finished his PhD? - -inlining discussion --------------------- - -- need to trace aggressively -- give up when trace becomes too long -- need to remember when we gave up -- need to reset counters -- tracing aggressively will put pressure on the speed of tracing -- what should we do about recursive calls? -- connecting compiled loops accross a call? - From pedronis at codespeak.net Thu Aug 27 15:44:35 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Aug 2009 15:44:35 +0200 (CEST) Subject: [pypy-svn] r67243 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090827134435.47E7F16801B@codespeak.net> Author: pedronis Date: Thu Aug 27 15:44:34 2009 New Revision: 67243 Removed: pypy/branch/pyjitpl5/pypy/jit/metainterp/TODO Log: these have moved to extradoc/planning/jit.txt From cfbolz at codespeak.net Thu Aug 27 16:03:39 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 16:03:39 +0200 (CEST) Subject: [pypy-svn] r67244 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090827140339.2A7FB168025@codespeak.net> Author: cfbolz Date: Thu Aug 27 16:03:38 2009 New Revision: 67244 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py Log: with the new store sinking stuff, this test passes Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py Thu Aug 27 16:03:38 2009 @@ -34,7 +34,6 @@ self.check_loop_count(1) def test_loop_with_delayed_setfield(self): - py.test.skip("Disabled") myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res', 'a']) class A(object): def __init__(self): From antocuni at codespeak.net Thu Aug 27 16:15:43 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 16:15:43 +0200 (CEST) Subject: [pypy-svn] r67245 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli backend/llgraph backend/llgraph/test backend/llvm backend/test backend/x86 metainterp metainterp/test Message-ID: <20090827141543.586ED168029@codespeak.net> Author: antocuni Date: Thu Aug 27 16:15:42 2009 New Revision: 67245 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: unify {Const,Box}{Obj,Ptr} interfaces: - rename getptr_base and getobj to getref_base - rename getptr to getref - introduce getref for objects, which helps to get rid of a lot of ootype.cast_from_object(...) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu Aug 27 16:15:42 2009 @@ -71,7 +71,7 @@ assert False, 'cannot store() to Constant' def get_cliobj(self): - return dotnet.cast_to_native_object(self.getobj()) + return dotnet.cast_to_native_object(self.getref_base()) class __extend__(ConstInt): __metaclass__ = extendabletype @@ -228,7 +228,6 @@ # initialize the array of genconsts consts = dotnet.new_array(System.Object, len(self.consts)) for av_const, i in self.consts.iteritems(): - #consts[i] = dotnet.cast_to_native_object(av_const.getobj()) consts[i] = av_const.get_cliobj() # build the delegate func = self.meth_wrapper.create_delegate(delegatetype, consts) @@ -459,7 +458,7 @@ il_label = self.newbranch(op) classbox = op.args[0] assert isinstance(classbox, ConstObj) - oocls = ootype.cast_from_object(ootype.Class, classbox.getobj()) + oocls = classbox.getref(ootype.Class) clitype = dotnet.class2type(oocls) self.av_inputargs.load(self) self.il.Emit(OpCodes.Ldfld, self.exc_value_field) @@ -507,7 +506,7 @@ def emit_op_new_with_vtable(self, op): clsbox = op.args[0] assert isinstance(clsbox, ConstObj) - cls = clsbox.getobj() + cls = clsbox.getref_base() descr = self.cpu.class_sizes[cls] assert isinstance(descr, runner.TypeDescr) clitype = descr.get_clitype() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu Aug 27 16:15:42 2009 @@ -160,7 +160,7 @@ #assert len(args) == 1 # but we don't need it, so ignore assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -171,7 +171,7 @@ def do_runtimenew(self, args, descr): classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return BoxObj(ootype.cast_to_object(res)) @@ -294,21 +294,21 @@ n = lengthbox.getint() return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() if TYPE is not ootype.Void: return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): if isinstance(TYPE, ootype.Instance): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return BoxInt(ootype.instanceof(obj, TYPE)) return None self.create = create @@ -349,7 +349,7 @@ from pypy.jit.backend.llgraph.runner import boxresult, make_getargs getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = funcobj(*funcargs) if RESULT is not ootype.Void: @@ -392,7 +392,7 @@ METH = ootype.typeOf(meth) getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = meth(*methargs) @@ -441,11 +441,11 @@ from pypy.jit.metainterp.warmspot import unwrap _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Thu Aug 27 16:15:42 2009 @@ -277,34 +277,34 @@ # ---------- the backend-dependent operations ---------- def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() return history.BoxInt(llimpl.do_arraylen_gc(arraydescr, array)) def do_strlen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_strlen(0, string)) def do_strgetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_strgetitem(0, string, index)) def do_unicodelen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_unicodelen(0, string)) def do_unicodegetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_unicodegetitem(0, string, index)) def do_getarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() if arraydescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getarrayitem_gc_ptr(array, index)) @@ -314,7 +314,7 @@ def do_getfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() + struct = args[0].getref_base() if fielddescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)) @@ -354,10 +354,10 @@ def do_setarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() if arraydescr.typeinfo == 'p': - newvalue = args[2].getptr_base() + newvalue = args[2].getref_base() llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) else: newvalue = args[2].getint() @@ -366,9 +366,9 @@ def do_setfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() + struct = args[0].getref_base() if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + newvalue = args[1].getref_base() llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: newvalue = args[1].getint() @@ -379,7 +379,7 @@ assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + newvalue = args[1].getref_base() llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memo_cast) else: @@ -402,14 +402,14 @@ def do_strsetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_strsetitem(0, string, index, newvalue) def do_unicodesetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_unicodesetitem(0, string, index, newvalue) @@ -420,7 +420,7 @@ for arg in args[1:]: if (isinstance(arg, history.BoxPtr) or isinstance(arg, history.ConstPtr)): - llimpl.do_call_pushptr(arg.getptr_base()) + llimpl.do_call_pushptr(arg.getref_base()) else: llimpl.do_call_pushint(arg.getint()) if calldescr.typeinfo == 'p': @@ -438,7 +438,7 @@ def do_cast_ptr_to_int(self, args, descr=None): assert descr is None - return history.BoxInt(llimpl.cast_to_int(args[0].getptr_base(), + return history.BoxInt(llimpl.cast_to_int(args[0].getref_base(), self.memo_cast)) class OOtypeCPU(BaseCPU): @@ -495,7 +495,7 @@ def do_new_with_vtable(self, args, descr=None): assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -512,7 +512,7 @@ def do_runtimenew(self, args, descr): "NOT_RPYTHON" classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return history.BoxObj(ootype.cast_to_object(res)) @@ -626,7 +626,7 @@ self.FUNC = FUNC getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) if RESULT is not ootype.Void: @@ -648,7 +648,7 @@ RESULT = METH.RESULT getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) @@ -674,22 +674,22 @@ return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return history.BoxInt(ootype.instanceof(obj, TYPE)) self.create = create @@ -718,11 +718,11 @@ _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py Thu Aug 27 16:15:42 2009 @@ -109,7 +109,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -142,7 +142,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -171,7 +171,7 @@ [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], descrfld_ry) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # rs.y = lltype.nullptr(A) cpu.do_setfield_raw( @@ -182,7 +182,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -190,29 +190,29 @@ cpu.set_class_sizes({vtable2_int: descrsize2}) x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) - assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' class TestLLTypeLLGraph(LLtypeBackendTest, LLGraphTests): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Thu Aug 27 16:15:42 2009 @@ -454,37 +454,37 @@ # do_xxx methods def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) res = len(p) return BoxInt(res) def do_strlen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = len(p.chars) return BoxInt(res) def do_strgetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_unicodelen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = len(p.chars) return BoxInt(res) def do_unicodegetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index @@ -527,7 +527,7 @@ return BoxInt(res) def do_getfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() return self._do_getfield(struct, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -564,13 +564,13 @@ self.array_index_length) def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index if itemsize_index == self.SIZE_GCPTR: p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getptr_base() + res = args[2].getref_base() p[index] = res elif itemsize_index == self.SIZE_INT: p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) @@ -593,7 +593,7 @@ size_index = fielddescr.size_index if size_index == self.SIZE_GCPTR: p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getptr_base() + res = v_value.getref_base() p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res elif size_index == self.SIZE_INT: p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) @@ -611,7 +611,7 @@ raise BadSizeError def do_setfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() self._do_setfield(struct, args[1], fielddescr) def do_setfield_raw(self, args, fielddescr): @@ -629,13 +629,13 @@ self.unicode_index_length) def do_strsetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = chr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) p.chars[args[1].getint()] = res def do_unicodesetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = unichr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) p.chars[args[1].getint()] = res @@ -687,7 +687,7 @@ return BoxPtr(res) def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getptr_base() + ptr = args[0].getref_base() res = rffi.cast(lltype.Signed, ptr) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Thu Aug 27 16:15:42 2009 @@ -24,10 +24,10 @@ self.cpu.set_future_value_int(j, box.getint()) j += 1 elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ptr(j, box.getptr_base()) + self.cpu.set_future_value_ptr(j, box.getref_base()) j += 1 elif isinstance(box, BoxObj): - self.cpu.set_future_value_obj(j, box.getobj()) + self.cpu.set_future_value_obj(j, box.getref_base()) j += 1 res = self.cpu.execute_operations(loop) if res is loop.operations[-1]: @@ -118,7 +118,7 @@ assert x.value == 142 if self.type_system == 'lltype': s = execute(cpu, rop.NEWSTR, [BoxInt(8)]) - assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8 + assert len(s.getref(lltype.Ptr(rstr.STR)).chars) == 8 def test_lshift(self): res = execute(self.cpu, rop.INT_LSHIFT, [BoxInt(10), ConstInt(4)]) @@ -728,7 +728,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -761,7 +761,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -792,7 +792,7 @@ # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], # descrfld_ry) #assert isinstance(x, BoxPtr) - #assert x.getptr(lltype.Ptr(A)) == a + #assert x.getref(lltype.Ptr(A)) == a # #rs.y = lltype.nullptr(A) #cpu.do_setfield_raw( @@ -803,7 +803,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -812,29 +812,29 @@ x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) # well... - #assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' # x = cpu.do_newstr([BoxInt(5)]) y = cpu.do_cast_ptr_to_int([x]) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Thu Aug 27 16:15:42 2009 @@ -263,7 +263,7 @@ class GetArrayItemOperation(ArrayOperation): def field_descr(self, builder, r): v, A = builder.get_arrayptr_var(r) - array = v.getptr(lltype.Ptr(A)) + array = v.getref(lltype.Ptr(A)) v_index = builder.get_index(len(array), r) descr = self.array_descr(builder, A) return v, A, v_index, descr @@ -344,7 +344,7 @@ current = getattr(builder, self.builder_cache) if current and r.random() < .8: v_string = r.choice(current) - string = v_string.getptr(self.ptr) + string = v_string.getref(self.ptr) else: string = self.alloc(builder.get_index(500, r).getint()) v_string = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, string)) @@ -357,13 +357,13 @@ class AbstractGetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_result = builder.do(self.opnum, [v_string, v_index]) class AbstractSetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_target = ConstInt(r.random_integer() % self.max) builder.do(self.opnum, [v_string, v_index, v_target]) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Thu Aug 27 16:15:42 2009 @@ -279,13 +279,13 @@ def do_arraylen_gc(self, args, arraydescr): ofs = self.gc_ll_descr.array_length_ofs - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] return BoxInt(length) def do_getarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift if size == 1: @@ -303,7 +303,7 @@ def do_setarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift vbox = args[2] @@ -315,7 +315,7 @@ a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = vbox.getint() else: - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = self.cast_gcref_to_int(ptr) @@ -326,7 +326,7 @@ def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] return BoxInt(v) return do_strlen @@ -337,7 +337,7 @@ def do_strgetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) @@ -345,7 +345,7 @@ def do_unicodegetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() basesize = basesize // itemsize v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] @@ -368,7 +368,7 @@ return BoxInt(v) def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) return self._base_do_getfield(gcref, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -387,7 +387,7 @@ if ptr: assert lltype.typeOf(gcref) is not lltype.Signed, ( "can't handle write barriers for setfield_raw") - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD] = self.cast_gcref_to_int(ptr) @@ -398,7 +398,7 @@ raise NotImplementedError("size = %d" % size) def do_setfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) self._base_do_setfield(fielddescr, gcref, args[1]) def do_setfield_raw(self, args, fielddescr): @@ -439,7 +439,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) def do_unicodesetitem(self, args, descr=None): @@ -447,7 +447,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) @@ -468,7 +468,7 @@ return BoxInt(self.get_latest_value_int(0)) def do_cast_ptr_to_int(self, args, descr=None): - return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) + return BoxInt(self.cast_gcref_to_int(args[0].getref_base())) def do_cast_int_to_ptr(self, args, descr=None): return BoxPtr(self.cast_int_to_gcref(args[0].getint())) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py Thu Aug 27 16:15:42 2009 @@ -158,7 +158,7 @@ result = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getptr_base() + result = resultbox.getref_base() raise metainterp_sd.DoneWithThisFramePtr(result) class DoneWithThisFrameDescrObj(AbstractDescr): @@ -169,7 +169,7 @@ result = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getobj() + result = resultbox.getref_base() raise metainterp_sd.DoneWithThisFrameObj(result) class ExitFrameWithExceptionDescrPtr(AbstractDescr): @@ -180,7 +180,7 @@ value = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getptr_base() + value = valuebox.getref_base() raise metainterp_sd.ExitFrameWithExceptionPtr(value) class ExitFrameWithExceptionDescrObj(AbstractDescr): @@ -191,7 +191,7 @@ value = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getobj() + value = valuebox.getref_base() raise metainterp_sd.ExitFrameWithExceptionObj(value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() @@ -297,11 +297,11 @@ if isinstance(dstbox, BoxInt): dstbox.changevalue_int(srcbox.getint()) elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr): - dstbox.changevalue_ptr(srcbox.getptr_base()) + dstbox.changevalue_ptr(srcbox.getref_base()) elif isinstance(dstbox, Const): pass elif metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxObj): - dstbox.changevalue_obj(srcbox.getobj()) + dstbox.changevalue_obj(srcbox.getref_base()) else: assert False Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Thu Aug 27 16:15:42 2009 @@ -107,10 +107,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getptr_base()) + x = bool(args[0].getref_base()) else: assert tp == OBJ - x = bool(args[0].getobj()) + x = bool(args[0].getref_base()) return ConstInt(x) def do_ooisnull(cpu, args, descr=None): @@ -118,10 +118,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getptr_base()) + x = bool(args[0].getref_base()) else: assert tp == OBJ - x = bool(args[0].getobj()) + x = bool(args[0].getref_base()) return ConstInt(not x) def do_oois(cpu, args, descr=None): @@ -130,10 +130,10 @@ if tp == INT: x = args[0].getint() == args[1].getint() elif tp == PTR: - x = args[0].getptr_base() == args[1].getptr_base() + x = args[0].getref_base() == args[1].getref_base() else: assert tp == OBJ - x = args[0].getobj() == args[1].getobj() + x = args[0].getref_base() == args[1].getref_base() return ConstInt(x) def do_ooisnot(cpu, args, descr=None): @@ -142,22 +142,22 @@ if tp == INT: x = args[0].getint() != args[1].getint() elif tp == PTR: - x = args[0].getptr_base() != args[1].getptr_base() + x = args[0].getref_base() != args[1].getref_base() else: assert tp == OBJ - x = args[0].getobj() != args[1].getobj() + x = args[0].getref_base() != args[1].getref_base() return ConstInt(x) def do_ooidentityhash(cpu, args, descr=None): - obj = args[0].getobj() + obj = args[0].getref_base() return ConstInt(ootype.ooidentityhash(obj)) def do_subclassof(self, args, descr=None): assert len(args) == 2 box1, box2 = args - cls1 = ootype.cast_from_object(ootype.Class, box1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, box2.getobj()) + cls1 = box1.getref(ootype.Class) + cls2 = box2.getref(ootype.Class) res = ootype.subclassof(cls1, cls2) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Thu Aug 27 16:15:42 2009 @@ -80,15 +80,12 @@ def getint(self): raise NotImplementedError - def getptr_base(self): + def getref_base(self): raise NotImplementedError - def getptr(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getptr_base()) - getptr._annspecialcase_ = 'specialize:arg(1)' - - def getobj(self): + def getref(self, TYPE): raise NotImplementedError + getref._annspecialcase_ = 'specialize:arg(1)' def get_(self): raise NotImplementedError @@ -296,9 +293,13 @@ nonconstbox = clonebox - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): return lltype.cast_ptr_to_int(self.value) @@ -312,7 +313,7 @@ cpu.set_future_value_ptr(j, self.value) def equals(self, other): - return self.value == other.getptr_base() + return self.value == other.getref_base() _getrepr_ = repr_pointer @@ -338,9 +339,13 @@ nonconstbox = clonebox - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -360,7 +365,7 @@ ## return self.value def equals(self, other): - return self.value == other.getobj() + return self.value == other.getref_base() _getrepr_ = repr_object @@ -479,9 +484,13 @@ def constbox(self): return ConstPtr(self.value) - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def getaddr(self, cpu): return llmemory.cast_ptr_to_adr(self.value) @@ -498,7 +507,7 @@ return repr_rpython(self, 'bp') def changevalue_box(self, srcbox): - self.changevalue_ptr(srcbox.getptr_base()) + self.changevalue_ptr(srcbox.getref_base()) _getrepr_ = repr_pointer changevalue_ptr = __init__ @@ -520,9 +529,13 @@ def constbox(self): return ConstObj(self.value) - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -539,7 +552,7 @@ return repr_rpython(self, 'bo') def changevalue_box(self, srcbox): - self.changevalue_obj(srcbox.getobj()) + self.changevalue_obj(srcbox.getref_base()) _getrepr_ = repr_object changevalue_obj = __init__ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 16:15:42 2009 @@ -343,7 +343,7 @@ if not self.is_constant(box): return box if not self.cpu.is_oo and box.type == PTR: - value = box.getptr_base() + value = box.getref_base() key = lltype.cast_ptr_to_int(value) try: return self.interned_ptrs[key] @@ -351,7 +351,7 @@ self.interned_ptrs[key] = box return box elif self.cpu.is_oo and box.type == OBJ: - value = box.getobj() + value = box.getref_base() try: return self.interned_objs[value] except KeyError: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 16:15:42 2009 @@ -716,7 +716,7 @@ box = self.implement_guard_value(pc, box) cpu = self.metainterp.cpu if cpu.is_oo: - key = box.getobj() + key = box.getref_base() else: key = box.getaddr(cpu) jitcode = indirectcallset.bytecode_for_address(key) @@ -730,7 +730,7 @@ clsbox = self.cls_of_box(objbox) if isinstance(objbox, Box): self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox]) - oocls = ootype.cast_from_object(ootype.Class, clsbox.getobj()) + oocls = clsbox.getref(ootype.Class) jitcode = methdescr.get_jitcode_for_class(oocls) return self.perform_call(jitcode, varargs) @@ -1146,9 +1146,9 @@ elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) elif sd.result_type == 'ptr': - raise sd.DoneWithThisFramePtr(resultbox.getptr_base()) + raise sd.DoneWithThisFramePtr(resultbox.getref_base()) elif self.cpu.is_oo and sd.result_type == 'obj': - raise sd.DoneWithThisFrameObj(resultbox.getobj()) + raise sd.DoneWithThisFrameObj(resultbox.getref_base()) else: assert False @@ -1176,9 +1176,9 @@ if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) if self.cpu.is_oo: - raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getobj()) + raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getref_base()) else: - raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getptr_base()) + raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getref_base()) def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Thu Aug 27 16:15:42 2009 @@ -1155,10 +1155,9 @@ tag, resolved, fieldstext = virtuals[varname] if tag[0] == 'virtual': if not self.cpu.is_oo: - assert box.getptr(rclass.OBJECTPTR).typeptr == tag[1] + assert box.getref(rclass.OBJECTPTR).typeptr == tag[1] else: - root = box.getobj() - root = ootype.cast_from_object(ootype.ROOT, root) + root = box.getref(ootype.ROOT) assert ootype.classof(root) == tag[1] elif tag[0] == 'varray': pass # xxx check arraydescr Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py Thu Aug 27 16:15:42 2009 @@ -56,7 +56,7 @@ return llmemory.cast_ptr_to_adr(fnptr) def cls_of_box(self, cpu, box): - obj = box.getptr(lltype.Ptr(rclass.OBJECT)) + obj = box.getref(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(cpu.cast_adr_to_int(cls)) @@ -75,7 +75,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getptr(lltype.Ptr(rclass.OBJECT)) + obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): @@ -116,13 +116,13 @@ return ootype.cast_to_object(fnptr) def cls_of_box(self, cpu, box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) oocls = ootype.classof(obj) return history.ConstObj(ootype.cast_to_object(oocls)) def subclassOf(self, cpu, clsbox1, clsbox2): - cls1 = ootype.cast_from_object(ootype.Class, clsbox1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, clsbox2.getobj()) + cls1 = clsbox1.getref(ootype.Class) + cls2 = clsbox2.getref(ootype.Class) return ootype.subclassof(cls1, cls2) def get_exception_box(self, etype): @@ -133,7 +133,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = ootype.cast_from_object(ootype.ROOT, evaluebox.getobj()) + obj = evaluebox.getref(ootype.ROOT) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Thu Aug 27 16:15:42 2009 @@ -186,10 +186,9 @@ def unwrap_virtualizable_box(self, virtualizable_box): if not self.is_oo: - return virtualizable_box.getptr(self.VTYPEPTR) + return virtualizable_box.getref(self.VTYPEPTR) else: - obj = virtualizable_box.getobj() - return ootype.cast_from_object(self.VTYPE, obj) + return virtualizable_box.getref(self.VTYPE) def cast_to_vtype(self, virtualizable): if not self.is_oo: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 27 16:15:42 2009 @@ -584,9 +584,9 @@ if TYPE is lltype.Void: return None if isinstance(TYPE, lltype.Ptr): - return box.getptr(TYPE) + return box.getref(TYPE) if isinstance(TYPE, ootype.OOType): - return ootype.cast_from_object(TYPE, box.getobj()) + return box.getref(TYPE) else: return lltype.cast_primitive(TYPE, box.getint()) unwrap._annspecialcase_ = 'specialize:arg(0)' From antocuni at codespeak.net Thu Aug 27 16:19:36 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 16:19:36 +0200 (CEST) Subject: [pypy-svn] r67246 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli backend/llgraph backend/llgraph/test backend/llvm backend/test backend/x86 metainterp metainterp/test Message-ID: <20090827141936.E171A168029@codespeak.net> Author: antocuni Date: Thu Aug 27 16:19:33 2009 New Revision: 67246 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Log: revert r67245, as I committed it to the wrong branch again :-/ Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu Aug 27 16:19:33 2009 @@ -71,7 +71,7 @@ assert False, 'cannot store() to Constant' def get_cliobj(self): - return dotnet.cast_to_native_object(self.getref_base()) + return dotnet.cast_to_native_object(self.getobj()) class __extend__(ConstInt): __metaclass__ = extendabletype @@ -228,6 +228,7 @@ # initialize the array of genconsts consts = dotnet.new_array(System.Object, len(self.consts)) for av_const, i in self.consts.iteritems(): + #consts[i] = dotnet.cast_to_native_object(av_const.getobj()) consts[i] = av_const.get_cliobj() # build the delegate func = self.meth_wrapper.create_delegate(delegatetype, consts) @@ -458,7 +459,7 @@ il_label = self.newbranch(op) classbox = op.args[0] assert isinstance(classbox, ConstObj) - oocls = classbox.getref(ootype.Class) + oocls = ootype.cast_from_object(ootype.Class, classbox.getobj()) clitype = dotnet.class2type(oocls) self.av_inputargs.load(self) self.il.Emit(OpCodes.Ldfld, self.exc_value_field) @@ -506,7 +507,7 @@ def emit_op_new_with_vtable(self, op): clsbox = op.args[0] assert isinstance(clsbox, ConstObj) - cls = clsbox.getref_base() + cls = clsbox.getobj() descr = self.cpu.class_sizes[cls] assert isinstance(descr, runner.TypeDescr) clitype = descr.get_clitype() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu Aug 27 16:19:33 2009 @@ -160,7 +160,7 @@ #assert len(args) == 1 # but we don't need it, so ignore assert descr is None assert len(args) == 1 - cls = args[0].getref_base() + cls = args[0].getobj() typedescr = self.class_sizes[cls] return typedescr.create() @@ -171,7 +171,7 @@ def do_runtimenew(self, args, descr): classbox = args[0] - classobj = classbox.getref(ootype.Class) + classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) res = ootype.runtimenew(classobj) return BoxObj(ootype.cast_to_object(res)) @@ -294,21 +294,21 @@ n = lengthbox.getint() return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) i = ibox.getint() if TYPE is not ootype.Void: return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): if isinstance(TYPE, ootype.Instance): - obj = box.getref(ootype.ROOT) + obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) return BoxInt(ootype.instanceof(obj, TYPE)) return None self.create = create @@ -349,7 +349,7 @@ from pypy.jit.backend.llgraph.runner import boxresult, make_getargs getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = funcbox.getref(FUNC) + funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) funcargs = getargs(argboxes) res = funcobj(*funcargs) if RESULT is not ootype.Void: @@ -392,7 +392,7 @@ METH = ootype.typeOf(meth) getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = selfbox.getref(SELFTYPE) + selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = meth(*methargs) @@ -441,11 +441,11 @@ from pypy.jit.metainterp.warmspot import unwrap _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = objbox.getref(TYPE) + obj = ootype.cast_from_object(TYPE, objbox.getobj()) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = objbox.getref(TYPE) + obj = ootype.cast_from_object(TYPE, objbox.getobj()) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Thu Aug 27 16:19:33 2009 @@ -277,34 +277,34 @@ # ---------- the backend-dependent operations ---------- def do_arraylen_gc(self, args, arraydescr): - array = args[0].getref_base() + array = args[0].getptr_base() return history.BoxInt(llimpl.do_arraylen_gc(arraydescr, array)) def do_strlen(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() return history.BoxInt(llimpl.do_strlen(0, string)) def do_strgetitem(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() index = args[1].getint() return history.BoxInt(llimpl.do_strgetitem(0, string, index)) def do_unicodelen(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() return history.BoxInt(llimpl.do_unicodelen(0, string)) def do_unicodegetitem(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() index = args[1].getint() return history.BoxInt(llimpl.do_unicodegetitem(0, string, index)) def do_getarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getref_base() + array = args[0].getptr_base() index = args[1].getint() if arraydescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getarrayitem_gc_ptr(array, index)) @@ -314,7 +314,7 @@ def do_getfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getref_base() + struct = args[0].getptr_base() if fielddescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)) @@ -354,10 +354,10 @@ def do_setarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getref_base() + array = args[0].getptr_base() index = args[1].getint() if arraydescr.typeinfo == 'p': - newvalue = args[2].getref_base() + newvalue = args[2].getptr_base() llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) else: newvalue = args[2].getint() @@ -366,9 +366,9 @@ def do_setfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getref_base() + struct = args[0].getptr_base() if fielddescr.typeinfo == 'p': - newvalue = args[1].getref_base() + newvalue = args[1].getptr_base() llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: newvalue = args[1].getint() @@ -379,7 +379,7 @@ assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) if fielddescr.typeinfo == 'p': - newvalue = args[1].getref_base() + newvalue = args[1].getptr_base() llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memo_cast) else: @@ -402,14 +402,14 @@ def do_strsetitem(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_strsetitem(0, string, index, newvalue) def do_unicodesetitem(self, args, descr=None): assert descr is None - string = args[0].getref_base() + string = args[0].getptr_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_unicodesetitem(0, string, index, newvalue) @@ -420,7 +420,7 @@ for arg in args[1:]: if (isinstance(arg, history.BoxPtr) or isinstance(arg, history.ConstPtr)): - llimpl.do_call_pushptr(arg.getref_base()) + llimpl.do_call_pushptr(arg.getptr_base()) else: llimpl.do_call_pushint(arg.getint()) if calldescr.typeinfo == 'p': @@ -438,7 +438,7 @@ def do_cast_ptr_to_int(self, args, descr=None): assert descr is None - return history.BoxInt(llimpl.cast_to_int(args[0].getref_base(), + return history.BoxInt(llimpl.cast_to_int(args[0].getptr_base(), self.memo_cast)) class OOtypeCPU(BaseCPU): @@ -495,7 +495,7 @@ def do_new_with_vtable(self, args, descr=None): assert descr is None assert len(args) == 1 - cls = args[0].getref_base() + cls = args[0].getobj() typedescr = self.class_sizes[cls] return typedescr.create() @@ -512,7 +512,7 @@ def do_runtimenew(self, args, descr): "NOT_RPYTHON" classbox = args[0] - classobj = classbox.getref(ootype.Class) + classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) res = ootype.runtimenew(classobj) return history.BoxObj(ootype.cast_to_object(res)) @@ -626,7 +626,7 @@ self.FUNC = FUNC getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = funcbox.getref(FUNC) + funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) funcargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) if RESULT is not ootype.Void: @@ -648,7 +648,7 @@ RESULT = METH.RESULT getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = selfbox.getref(SELFTYPE) + selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) @@ -674,22 +674,22 @@ return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) i = ibox.getint() return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = arraybox.getref(ARRAY) + array = ootype.cast_from_object(ARRAY, arraybox.getobj()) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): - obj = box.getref(ootype.ROOT) + obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) return history.BoxInt(ootype.instanceof(obj, TYPE)) self.create = create @@ -718,11 +718,11 @@ _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = objbox.getref(TYPE) + obj = ootype.cast_from_object(TYPE, objbox.getobj()) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = objbox.getref(TYPE) + obj = ootype.cast_from_object(TYPE, objbox.getobj()) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py Thu Aug 27 16:19:33 2009 @@ -109,7 +109,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getref(lltype.Ptr(A)) == a + assert x.getptr(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -142,7 +142,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getref(lltype.Ptr(A)) == a + assert x.getptr(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -171,7 +171,7 @@ [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], descrfld_ry) assert isinstance(x, BoxPtr) - assert x.getref(lltype.Ptr(A)) == a + assert x.getptr(lltype.Ptr(A)) == a # rs.y = lltype.nullptr(A) cpu.do_setfield_raw( @@ -182,7 +182,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getref(lltype.Ptr(S)) + x.getptr(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -190,29 +190,29 @@ cpu.set_class_sizes({vtable2_int: descrsize2}) x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) - assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 + assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getref(lltype.Ptr(A))) == 7 + assert len(x.getptr(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getref(lltype.Ptr(A))[5] == '*' + assert x.getptr(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getref(lltype.Ptr(A)) + assert b[1] == x.getptr(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' class TestLLTypeLLGraph(LLtypeBackendTest, LLGraphTests): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Thu Aug 27 16:19:33 2009 @@ -454,37 +454,37 @@ # do_xxx methods def do_arraylen_gc(self, args, arraydescr): - array = args[0].getref_base() + array = args[0].getptr_base() p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) res = len(p) return BoxInt(res) def do_strlen(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = len(p.chars) return BoxInt(res) def do_strgetitem(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_unicodelen(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = len(p.chars) return BoxInt(res) def do_unicodegetitem(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() + array = args[0].getptr_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index @@ -527,7 +527,7 @@ return BoxInt(res) def do_getfield_gc(self, args, fielddescr): - struct = args[0].getref_base() + struct = args[0].getptr_base() return self._do_getfield(struct, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -564,13 +564,13 @@ self.array_index_length) def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() + array = args[0].getptr_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index if itemsize_index == self.SIZE_GCPTR: p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getref_base() + res = args[2].getptr_base() p[index] = res elif itemsize_index == self.SIZE_INT: p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) @@ -593,7 +593,7 @@ size_index = fielddescr.size_index if size_index == self.SIZE_GCPTR: p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getref_base() + res = v_value.getptr_base() p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res elif size_index == self.SIZE_INT: p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) @@ -611,7 +611,7 @@ raise BadSizeError def do_setfield_gc(self, args, fielddescr): - struct = args[0].getref_base() + struct = args[0].getptr_base() self._do_setfield(struct, args[1], fielddescr) def do_setfield_raw(self, args, fielddescr): @@ -629,13 +629,13 @@ self.unicode_index_length) def do_strsetitem(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() res = chr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) p.chars[args[1].getint()] = res def do_unicodesetitem(self, args, descr=None): - s = args[0].getref_base() + s = args[0].getptr_base() res = unichr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) p.chars[args[1].getint()] = res @@ -687,7 +687,7 @@ return BoxPtr(res) def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getref_base() + ptr = args[0].getptr_base() res = rffi.cast(lltype.Signed, ptr) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Thu Aug 27 16:19:33 2009 @@ -24,10 +24,10 @@ self.cpu.set_future_value_int(j, box.getint()) j += 1 elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ptr(j, box.getref_base()) + self.cpu.set_future_value_ptr(j, box.getptr_base()) j += 1 elif isinstance(box, BoxObj): - self.cpu.set_future_value_obj(j, box.getref_base()) + self.cpu.set_future_value_obj(j, box.getobj()) j += 1 res = self.cpu.execute_operations(loop) if res is loop.operations[-1]: @@ -118,7 +118,7 @@ assert x.value == 142 if self.type_system == 'lltype': s = execute(cpu, rop.NEWSTR, [BoxInt(8)]) - assert len(s.getref(lltype.Ptr(rstr.STR)).chars) == 8 + assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8 def test_lshift(self): res = execute(self.cpu, rop.INT_LSHIFT, [BoxInt(10), ConstInt(4)]) @@ -728,7 +728,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getref(lltype.Ptr(A)) == a + assert x.getptr(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -761,7 +761,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getref(lltype.Ptr(A)) == a + assert x.getptr(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -792,7 +792,7 @@ # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], # descrfld_ry) #assert isinstance(x, BoxPtr) - #assert x.getref(lltype.Ptr(A)) == a + #assert x.getptr(lltype.Ptr(A)) == a # #rs.y = lltype.nullptr(A) #cpu.do_setfield_raw( @@ -803,7 +803,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getref(lltype.Ptr(S)) + x.getptr(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -812,29 +812,29 @@ x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) # well... - #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 + #assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getref(lltype.Ptr(A))) == 7 + assert len(x.getptr(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getref(lltype.Ptr(A))[5] == '*' + assert x.getptr(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getref(lltype.Ptr(A)) + assert b[1] == x.getptr(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' # x = cpu.do_newstr([BoxInt(5)]) y = cpu.do_cast_ptr_to_int([x]) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Thu Aug 27 16:19:33 2009 @@ -263,7 +263,7 @@ class GetArrayItemOperation(ArrayOperation): def field_descr(self, builder, r): v, A = builder.get_arrayptr_var(r) - array = v.getref(lltype.Ptr(A)) + array = v.getptr(lltype.Ptr(A)) v_index = builder.get_index(len(array), r) descr = self.array_descr(builder, A) return v, A, v_index, descr @@ -344,7 +344,7 @@ current = getattr(builder, self.builder_cache) if current and r.random() < .8: v_string = r.choice(current) - string = v_string.getref(self.ptr) + string = v_string.getptr(self.ptr) else: string = self.alloc(builder.get_index(500, r).getint()) v_string = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, string)) @@ -357,13 +357,13 @@ class AbstractGetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) v_result = builder.do(self.opnum, [v_string, v_index]) class AbstractSetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) v_target = ConstInt(r.random_integer() % self.max) builder.do(self.opnum, [v_string, v_index, v_target]) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Thu Aug 27 16:19:33 2009 @@ -279,13 +279,13 @@ def do_arraylen_gc(self, args, arraydescr): ofs = self.gc_ll_descr.array_length_ofs - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] return BoxInt(length) def do_getarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift if size == 1: @@ -303,7 +303,7 @@ def do_setarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift vbox = args[2] @@ -315,7 +315,7 @@ a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = vbox.getint() else: - ptr = vbox.getref(llmemory.GCREF) + ptr = vbox.getptr(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = self.cast_gcref_to_int(ptr) @@ -326,7 +326,7 @@ def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, self.translate_support_code) - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] return BoxInt(v) return do_strlen @@ -337,7 +337,7 @@ def do_strgetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, self.translate_support_code) - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) i = args[1].getint() v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) @@ -345,7 +345,7 @@ def do_unicodegetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code) - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) i = args[1].getint() basesize = basesize // itemsize v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] @@ -368,7 +368,7 @@ return BoxInt(v) def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) return self._base_do_getfield(gcref, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -387,7 +387,7 @@ if ptr: assert lltype.typeOf(gcref) is not lltype.Signed, ( "can't handle write barriers for setfield_raw") - ptr = vbox.getref(llmemory.GCREF) + ptr = vbox.getptr(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD] = self.cast_gcref_to_int(ptr) @@ -398,7 +398,7 @@ raise NotImplementedError("size = %d" % size) def do_setfield_gc(self, args, fielddescr): - gcref = args[0].getref(llmemory.GCREF) + gcref = args[0].getptr(llmemory.GCREF) self._base_do_setfield(fielddescr, gcref, args[1]) def do_setfield_raw(self, args, fielddescr): @@ -439,7 +439,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getref(llmemory.GCREF) + a = args[0].getptr(llmemory.GCREF) rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) def do_unicodesetitem(self, args, descr=None): @@ -447,7 +447,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getref(llmemory.GCREF) + a = args[0].getptr(llmemory.GCREF) basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) @@ -468,7 +468,7 @@ return BoxInt(self.get_latest_value_int(0)) def do_cast_ptr_to_int(self, args, descr=None): - return BoxInt(self.cast_gcref_to_int(args[0].getref_base())) + return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) def do_cast_int_to_ptr(self, args, descr=None): return BoxPtr(self.cast_int_to_gcref(args[0].getint())) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py Thu Aug 27 16:19:33 2009 @@ -158,7 +158,7 @@ result = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getref_base() + result = resultbox.getptr_base() raise metainterp_sd.DoneWithThisFramePtr(result) class DoneWithThisFrameDescrObj(AbstractDescr): @@ -169,7 +169,7 @@ result = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getref_base() + result = resultbox.getobj() raise metainterp_sd.DoneWithThisFrameObj(result) class ExitFrameWithExceptionDescrPtr(AbstractDescr): @@ -180,7 +180,7 @@ value = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getref_base() + value = valuebox.getptr_base() raise metainterp_sd.ExitFrameWithExceptionPtr(value) class ExitFrameWithExceptionDescrObj(AbstractDescr): @@ -191,7 +191,7 @@ value = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getref_base() + value = valuebox.getobj() raise metainterp_sd.ExitFrameWithExceptionObj(value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() @@ -297,11 +297,11 @@ if isinstance(dstbox, BoxInt): dstbox.changevalue_int(srcbox.getint()) elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr): - dstbox.changevalue_ptr(srcbox.getref_base()) + dstbox.changevalue_ptr(srcbox.getptr_base()) elif isinstance(dstbox, Const): pass elif metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxObj): - dstbox.changevalue_obj(srcbox.getref_base()) + dstbox.changevalue_obj(srcbox.getobj()) else: assert False Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Thu Aug 27 16:19:33 2009 @@ -107,10 +107,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getref_base()) + x = bool(args[0].getptr_base()) else: assert tp == OBJ - x = bool(args[0].getref_base()) + x = bool(args[0].getobj()) return ConstInt(x) def do_ooisnull(cpu, args, descr=None): @@ -118,10 +118,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getref_base()) + x = bool(args[0].getptr_base()) else: assert tp == OBJ - x = bool(args[0].getref_base()) + x = bool(args[0].getobj()) return ConstInt(not x) def do_oois(cpu, args, descr=None): @@ -130,10 +130,10 @@ if tp == INT: x = args[0].getint() == args[1].getint() elif tp == PTR: - x = args[0].getref_base() == args[1].getref_base() + x = args[0].getptr_base() == args[1].getptr_base() else: assert tp == OBJ - x = args[0].getref_base() == args[1].getref_base() + x = args[0].getobj() == args[1].getobj() return ConstInt(x) def do_ooisnot(cpu, args, descr=None): @@ -142,22 +142,22 @@ if tp == INT: x = args[0].getint() != args[1].getint() elif tp == PTR: - x = args[0].getref_base() != args[1].getref_base() + x = args[0].getptr_base() != args[1].getptr_base() else: assert tp == OBJ - x = args[0].getref_base() != args[1].getref_base() + x = args[0].getobj() != args[1].getobj() return ConstInt(x) def do_ooidentityhash(cpu, args, descr=None): - obj = args[0].getref_base() + obj = args[0].getobj() return ConstInt(ootype.ooidentityhash(obj)) def do_subclassof(self, args, descr=None): assert len(args) == 2 box1, box2 = args - cls1 = box1.getref(ootype.Class) - cls2 = box2.getref(ootype.Class) + cls1 = ootype.cast_from_object(ootype.Class, box1.getobj()) + cls2 = ootype.cast_from_object(ootype.Class, box2.getobj()) res = ootype.subclassof(cls1, cls2) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Thu Aug 27 16:19:33 2009 @@ -80,12 +80,15 @@ def getint(self): raise NotImplementedError - def getref_base(self): + def getptr_base(self): raise NotImplementedError - def getref(self, TYPE): + def getptr(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getptr_base()) + getptr._annspecialcase_ = 'specialize:arg(1)' + + def getobj(self): raise NotImplementedError - getref._annspecialcase_ = 'specialize:arg(1)' def get_(self): raise NotImplementedError @@ -293,13 +296,9 @@ nonconstbox = clonebox - def getref_base(self): + def getptr_base(self): return self.value - def getref(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getref_base()) - getref._annspecialcase_ = 'specialize:arg(1)' - def get_(self): return lltype.cast_ptr_to_int(self.value) @@ -313,7 +312,7 @@ cpu.set_future_value_ptr(j, self.value) def equals(self, other): - return self.value == other.getref_base() + return self.value == other.getptr_base() _getrepr_ = repr_pointer @@ -339,13 +338,9 @@ nonconstbox = clonebox - def getref_base(self): + def getobj(self): return self.value - def getref(self, OBJ): - return ootype.cast_from_object(OBJ, self.getref_base()) - getref._annspecialcase_ = 'specialize:arg(1)' - def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -365,7 +360,7 @@ ## return self.value def equals(self, other): - return self.value == other.getref_base() + return self.value == other.getobj() _getrepr_ = repr_object @@ -484,13 +479,9 @@ def constbox(self): return ConstPtr(self.value) - def getref_base(self): + def getptr_base(self): return self.value - def getref(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getref_base()) - getref._annspecialcase_ = 'specialize:arg(1)' - def getaddr(self, cpu): return llmemory.cast_ptr_to_adr(self.value) @@ -507,7 +498,7 @@ return repr_rpython(self, 'bp') def changevalue_box(self, srcbox): - self.changevalue_ptr(srcbox.getref_base()) + self.changevalue_ptr(srcbox.getptr_base()) _getrepr_ = repr_pointer changevalue_ptr = __init__ @@ -529,13 +520,9 @@ def constbox(self): return ConstObj(self.value) - def getref_base(self): + def getobj(self): return self.value - def getref(self, OBJ): - return ootype.cast_from_object(OBJ, self.getref_base()) - getref._annspecialcase_ = 'specialize:arg(1)' - def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -552,7 +539,7 @@ return repr_rpython(self, 'bo') def changevalue_box(self, srcbox): - self.changevalue_obj(srcbox.getref_base()) + self.changevalue_obj(srcbox.getobj()) _getrepr_ = repr_object changevalue_obj = __init__ Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 16:19:33 2009 @@ -343,7 +343,7 @@ if not self.is_constant(box): return box if not self.cpu.is_oo and box.type == PTR: - value = box.getref_base() + value = box.getptr_base() key = lltype.cast_ptr_to_int(value) try: return self.interned_ptrs[key] @@ -351,7 +351,7 @@ self.interned_ptrs[key] = box return box elif self.cpu.is_oo and box.type == OBJ: - value = box.getref_base() + value = box.getobj() try: return self.interned_objs[value] except KeyError: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 16:19:33 2009 @@ -716,7 +716,7 @@ box = self.implement_guard_value(pc, box) cpu = self.metainterp.cpu if cpu.is_oo: - key = box.getref_base() + key = box.getobj() else: key = box.getaddr(cpu) jitcode = indirectcallset.bytecode_for_address(key) @@ -730,7 +730,7 @@ clsbox = self.cls_of_box(objbox) if isinstance(objbox, Box): self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox]) - oocls = clsbox.getref(ootype.Class) + oocls = ootype.cast_from_object(ootype.Class, clsbox.getobj()) jitcode = methdescr.get_jitcode_for_class(oocls) return self.perform_call(jitcode, varargs) @@ -1146,9 +1146,9 @@ elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) elif sd.result_type == 'ptr': - raise sd.DoneWithThisFramePtr(resultbox.getref_base()) + raise sd.DoneWithThisFramePtr(resultbox.getptr_base()) elif self.cpu.is_oo and sd.result_type == 'obj': - raise sd.DoneWithThisFrameObj(resultbox.getref_base()) + raise sd.DoneWithThisFrameObj(resultbox.getobj()) else: assert False @@ -1176,9 +1176,9 @@ if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) if self.cpu.is_oo: - raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getref_base()) + raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getobj()) else: - raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getref_base()) + raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getptr_base()) def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Thu Aug 27 16:19:33 2009 @@ -1155,9 +1155,10 @@ tag, resolved, fieldstext = virtuals[varname] if tag[0] == 'virtual': if not self.cpu.is_oo: - assert box.getref(rclass.OBJECTPTR).typeptr == tag[1] + assert box.getptr(rclass.OBJECTPTR).typeptr == tag[1] else: - root = box.getref(ootype.ROOT) + root = box.getobj() + root = ootype.cast_from_object(ootype.ROOT, root) assert ootype.classof(root) == tag[1] elif tag[0] == 'varray': pass # xxx check arraydescr Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py Thu Aug 27 16:19:33 2009 @@ -56,7 +56,7 @@ return llmemory.cast_ptr_to_adr(fnptr) def cls_of_box(self, cpu, box): - obj = box.getref(lltype.Ptr(rclass.OBJECT)) + obj = box.getptr(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(cpu.cast_adr_to_int(cls)) @@ -75,7 +75,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) + obj = evaluebox.getptr(lltype.Ptr(rclass.OBJECT)) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): @@ -116,13 +116,13 @@ return ootype.cast_to_object(fnptr) def cls_of_box(self, cpu, box): - obj = box.getref(ootype.ROOT) + obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) oocls = ootype.classof(obj) return history.ConstObj(ootype.cast_to_object(oocls)) def subclassOf(self, cpu, clsbox1, clsbox2): - cls1 = clsbox1.getref(ootype.Class) - cls2 = clsbox2.getref(ootype.Class) + cls1 = ootype.cast_from_object(ootype.Class, clsbox1.getobj()) + cls2 = ootype.cast_from_object(ootype.Class, clsbox2.getobj()) return ootype.subclassof(cls1, cls2) def get_exception_box(self, etype): @@ -133,7 +133,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getref(ootype.ROOT) + obj = ootype.cast_from_object(ootype.ROOT, evaluebox.getobj()) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Thu Aug 27 16:19:33 2009 @@ -186,9 +186,10 @@ def unwrap_virtualizable_box(self, virtualizable_box): if not self.is_oo: - return virtualizable_box.getref(self.VTYPEPTR) + return virtualizable_box.getptr(self.VTYPEPTR) else: - return virtualizable_box.getref(self.VTYPE) + obj = virtualizable_box.getobj() + return ootype.cast_from_object(self.VTYPE, obj) def cast_to_vtype(self, virtualizable): if not self.is_oo: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Thu Aug 27 16:19:33 2009 @@ -584,9 +584,9 @@ if TYPE is lltype.Void: return None if isinstance(TYPE, lltype.Ptr): - return box.getref(TYPE) + return box.getptr(TYPE) if isinstance(TYPE, ootype.OOType): - return box.getref(TYPE) + return ootype.cast_from_object(TYPE, box.getobj()) else: return lltype.cast_primitive(TYPE, box.getint()) unwrap._annspecialcase_ = 'specialize:arg(0)' From cfbolz at codespeak.net Thu Aug 27 16:20:33 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 16:20:33 +0200 (CEST) Subject: [pypy-svn] r67247 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090827142033.DFCE4168029@codespeak.net> Author: cfbolz Date: Thu Aug 27 16:20:33 2009 New Revision: 67247 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_send.py Log: this is working as well Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_send.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_send.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_send.py Thu Aug 27 16:20:33 2009 @@ -425,7 +425,6 @@ self.check_tree_loop_count(2) def test_bug1(self): - py.test.skip("BUG") myjitdriver = JitDriver(greens = [], reds = ['node', 'n']) class Base: pass From antocuni at codespeak.net Thu Aug 27 16:21:55 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 16:21:55 +0200 (CEST) Subject: [pypy-svn] r67248 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend/cli backend/llgraph backend/llgraph/test backend/llvm backend/test backend/x86 metainterp metainterp/test Message-ID: <20090827142155.8FDA7168029@codespeak.net> Author: antocuni Date: Thu Aug 27 16:21:54 2009 New Revision: 67248 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: unify {Const,Box}{Obj,Ptr} interfaces: - rename getptr_base and getobj to getref_base - rename getptr to getref - introduce getref for objects, which helps to get rid of a lot of ootype.cast_from_object(...) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py Thu Aug 27 16:21:54 2009 @@ -71,7 +71,7 @@ assert False, 'cannot store() to Constant' def get_cliobj(self): - return dotnet.cast_to_native_object(self.getobj()) + return dotnet.cast_to_native_object(self.getref_base()) class __extend__(ConstInt): __metaclass__ = extendabletype @@ -228,7 +228,6 @@ # initialize the array of genconsts consts = dotnet.new_array(System.Object, len(self.consts)) for av_const, i in self.consts.iteritems(): - #consts[i] = dotnet.cast_to_native_object(av_const.getobj()) consts[i] = av_const.get_cliobj() # build the delegate func = self.meth_wrapper.create_delegate(delegatetype, consts) @@ -459,7 +458,7 @@ il_label = self.newbranch(op) classbox = op.args[0] assert isinstance(classbox, ConstObj) - oocls = ootype.cast_from_object(ootype.Class, classbox.getobj()) + oocls = classbox.getref(ootype.Class) clitype = dotnet.class2type(oocls) self.av_inputargs.load(self) self.il.Emit(OpCodes.Ldfld, self.exc_value_field) @@ -507,7 +506,7 @@ def emit_op_new_with_vtable(self, op): clsbox = op.args[0] assert isinstance(clsbox, ConstObj) - cls = clsbox.getobj() + cls = clsbox.getref_base() descr = self.cpu.class_sizes[cls] assert isinstance(descr, runner.TypeDescr) clitype = descr.get_clitype() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py Thu Aug 27 16:21:54 2009 @@ -162,7 +162,7 @@ #assert len(args) == 1 # but we don't need it, so ignore assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -173,7 +173,7 @@ def do_runtimenew(self, args, descr): classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return BoxObj(ootype.cast_to_object(res)) @@ -296,21 +296,21 @@ n = lengthbox.getint() return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() if TYPE is not ootype.Void: return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): if isinstance(TYPE, ootype.Instance): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return BoxInt(ootype.instanceof(obj, TYPE)) return None self.create = create @@ -351,7 +351,7 @@ from pypy.jit.backend.llgraph.runner import boxresult, make_getargs getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = funcobj(*funcargs) if RESULT is not ootype.Void: @@ -394,7 +394,7 @@ METH = ootype.typeOf(meth) getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = meth(*methargs) @@ -443,11 +443,11 @@ from pypy.jit.metainterp.warmspot import unwrap _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Thu Aug 27 16:21:54 2009 @@ -278,34 +278,34 @@ # ---------- the backend-dependent operations ---------- def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() return history.BoxInt(llimpl.do_arraylen_gc(arraydescr, array)) def do_strlen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_strlen(0, string)) def do_strgetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_strgetitem(0, string, index)) def do_unicodelen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_unicodelen(0, string)) def do_unicodegetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_unicodegetitem(0, string, index)) def do_getarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() if arraydescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getarrayitem_gc_ptr(array, index)) @@ -315,7 +315,7 @@ def do_getfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() + struct = args[0].getref_base() if fielddescr.typeinfo == 'p': return history.BoxPtr(llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)) @@ -355,10 +355,10 @@ def do_setarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() if arraydescr.typeinfo == 'p': - newvalue = args[2].getptr_base() + newvalue = args[2].getref_base() llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) else: newvalue = args[2].getint() @@ -367,9 +367,9 @@ def do_setfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() + struct = args[0].getref_base() if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + newvalue = args[1].getref_base() llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: newvalue = args[1].getint() @@ -380,7 +380,7 @@ assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + newvalue = args[1].getref_base() llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memo_cast) else: @@ -403,14 +403,14 @@ def do_strsetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_strsetitem(0, string, index, newvalue) def do_unicodesetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_unicodesetitem(0, string, index, newvalue) @@ -421,7 +421,7 @@ for arg in args[1:]: if (isinstance(arg, history.BoxPtr) or isinstance(arg, history.ConstPtr)): - llimpl.do_call_pushptr(arg.getptr_base()) + llimpl.do_call_pushptr(arg.getref_base()) else: llimpl.do_call_pushint(arg.getint()) if calldescr.typeinfo == 'p': @@ -439,7 +439,7 @@ def do_cast_ptr_to_int(self, args, descr=None): assert descr is None - return history.BoxInt(llimpl.cast_to_int(args[0].getptr_base(), + return history.BoxInt(llimpl.cast_to_int(args[0].getref_base(), self.memo_cast)) class OOtypeCPU(BaseCPU): @@ -497,7 +497,7 @@ def do_new_with_vtable(self, args, descr=None): assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -514,7 +514,7 @@ def do_runtimenew(self, args, descr): "NOT_RPYTHON" classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return history.BoxObj(ootype.cast_to_object(res)) @@ -628,7 +628,7 @@ self.FUNC = FUNC getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) if RESULT is not ootype.Void: @@ -650,7 +650,7 @@ RESULT = METH.RESULT getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) @@ -676,22 +676,22 @@ return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return history.BoxInt(ootype.instanceof(obj, TYPE)) self.create = create @@ -720,11 +720,11 @@ _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/test/test_llgraph.py Thu Aug 27 16:21:54 2009 @@ -109,7 +109,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -142,7 +142,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -171,7 +171,7 @@ [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], descrfld_ry) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # rs.y = lltype.nullptr(A) cpu.do_setfield_raw( @@ -182,7 +182,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -190,29 +190,29 @@ cpu.set_class_sizes({vtable2_int: descrsize2}) x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) - assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' class TestLLTypeLLGraph(LLtypeBackendTest, LLGraphTests): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py Thu Aug 27 16:21:54 2009 @@ -456,37 +456,37 @@ # do_xxx methods def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) res = len(p) return BoxInt(res) def do_strlen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = len(p.chars) return BoxInt(res) def do_strgetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_unicodelen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = len(p.chars) return BoxInt(res) def do_unicodegetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index @@ -529,7 +529,7 @@ return BoxInt(res) def do_getfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() return self._do_getfield(struct, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -566,13 +566,13 @@ self.array_index_length) def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index if itemsize_index == self.SIZE_GCPTR: p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getptr_base() + res = args[2].getref_base() p[index] = res elif itemsize_index == self.SIZE_INT: p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) @@ -595,7 +595,7 @@ size_index = fielddescr.size_index if size_index == self.SIZE_GCPTR: p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getptr_base() + res = v_value.getref_base() p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res elif size_index == self.SIZE_INT: p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) @@ -613,7 +613,7 @@ raise BadSizeError def do_setfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() self._do_setfield(struct, args[1], fielddescr) def do_setfield_raw(self, args, fielddescr): @@ -631,13 +631,13 @@ self.unicode_index_length) def do_strsetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = chr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) p.chars[args[1].getint()] = res def do_unicodesetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = unichr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) p.chars[args[1].getint()] = res @@ -689,7 +689,7 @@ return BoxPtr(res) def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getptr_base() + ptr = args[0].getref_base() res = rffi.cast(lltype.Signed, ptr) return BoxInt(res) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py Thu Aug 27 16:21:54 2009 @@ -24,10 +24,10 @@ self.cpu.set_future_value_int(j, box.getint()) j += 1 elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ptr(j, box.getptr_base()) + self.cpu.set_future_value_ptr(j, box.getref_base()) j += 1 elif isinstance(box, BoxObj): - self.cpu.set_future_value_obj(j, box.getobj()) + self.cpu.set_future_value_obj(j, box.getref_base()) j += 1 res = self.cpu.execute_operations(loop) if res is loop.operations[-1]: @@ -118,7 +118,7 @@ assert x.value == 142 if self.type_system == 'lltype': s = execute(cpu, rop.NEWSTR, [BoxInt(8)]) - assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8 + assert len(s.getref(lltype.Ptr(rstr.STR)).chars) == 8 def test_lshift(self): res = execute(self.cpu, rop.INT_LSHIFT, [BoxInt(10), ConstInt(4)]) @@ -728,7 +728,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -761,7 +761,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -792,7 +792,7 @@ # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], # descrfld_ry) #assert isinstance(x, BoxPtr) - #assert x.getptr(lltype.Ptr(A)) == a + #assert x.getref(lltype.Ptr(A)) == a # #rs.y = lltype.nullptr(A) #cpu.do_setfield_raw( @@ -803,7 +803,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -812,29 +812,29 @@ x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) # well... - #assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' # x = cpu.do_newstr([BoxInt(5)]) y = cpu.do_cast_ptr_to_int([x]) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py Thu Aug 27 16:21:54 2009 @@ -263,7 +263,7 @@ class GetArrayItemOperation(ArrayOperation): def field_descr(self, builder, r): v, A = builder.get_arrayptr_var(r) - array = v.getptr(lltype.Ptr(A)) + array = v.getref(lltype.Ptr(A)) v_index = builder.get_index(len(array), r) descr = self.array_descr(builder, A) return v, A, v_index, descr @@ -344,7 +344,7 @@ current = getattr(builder, self.builder_cache) if current and r.random() < .8: v_string = r.choice(current) - string = v_string.getptr(self.ptr) + string = v_string.getref(self.ptr) else: string = self.alloc(builder.get_index(500, r).getint()) v_string = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, string)) @@ -357,13 +357,13 @@ class AbstractGetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_result = builder.do(self.opnum, [v_string, v_index]) class AbstractSetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_target = ConstInt(r.random_integer() % self.max) builder.do(self.opnum, [v_string, v_index, v_target]) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Thu Aug 27 16:21:54 2009 @@ -281,13 +281,13 @@ def do_arraylen_gc(self, args, arraydescr): ofs = self.gc_ll_descr.array_length_ofs - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] return BoxInt(length) def do_getarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift if size == 1: @@ -305,7 +305,7 @@ def do_setarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift vbox = args[2] @@ -317,7 +317,7 @@ a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = vbox.getint() else: - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = self.cast_gcref_to_int(ptr) @@ -328,7 +328,7 @@ def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] return BoxInt(v) return do_strlen @@ -339,7 +339,7 @@ def do_strgetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) @@ -347,7 +347,7 @@ def do_unicodegetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() basesize = basesize // itemsize v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] @@ -370,7 +370,7 @@ return BoxInt(v) def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) return self._base_do_getfield(gcref, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -389,7 +389,7 @@ if ptr: assert lltype.typeOf(gcref) is not lltype.Signed, ( "can't handle write barriers for setfield_raw") - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD] = self.cast_gcref_to_int(ptr) @@ -400,7 +400,7 @@ raise NotImplementedError("size = %d" % size) def do_setfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) self._base_do_setfield(fielddescr, gcref, args[1]) def do_setfield_raw(self, args, fielddescr): @@ -441,7 +441,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) def do_unicodesetitem(self, args, descr=None): @@ -449,7 +449,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) @@ -470,7 +470,7 @@ return BoxInt(self.get_latest_value_int(0)) def do_cast_ptr_to_int(self, args, descr=None): - return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) + return BoxInt(self.cast_gcref_to_int(args[0].getref_base())) def do_cast_int_to_ptr(self, args, descr=None): return BoxPtr(self.cast_int_to_gcref(args[0].getint())) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 16:21:54 2009 @@ -158,7 +158,7 @@ result = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getptr_base() + result = resultbox.getref_base() raise metainterp_sd.DoneWithThisFramePtr(result) class DoneWithThisFrameDescrObj(AbstractDescr): @@ -169,7 +169,7 @@ result = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getobj() + result = resultbox.getref_base() raise metainterp_sd.DoneWithThisFrameObj(result) class ExitFrameWithExceptionDescrPtr(AbstractDescr): @@ -180,7 +180,7 @@ value = metainterp_sd.cpu.get_latest_value_ptr(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getptr_base() + value = valuebox.getref_base() raise metainterp_sd.ExitFrameWithExceptionPtr(value) class ExitFrameWithExceptionDescrObj(AbstractDescr): @@ -191,7 +191,7 @@ value = metainterp_sd.cpu.get_latest_value_obj(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getobj() + value = valuebox.getref_base() raise metainterp_sd.ExitFrameWithExceptionObj(value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() @@ -297,11 +297,11 @@ if isinstance(dstbox, BoxInt): dstbox.changevalue_int(srcbox.getint()) elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr): - dstbox.changevalue_ptr(srcbox.getptr_base()) + dstbox.changevalue_ptr(srcbox.getref_base()) elif isinstance(dstbox, Const): pass elif metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxObj): - dstbox.changevalue_obj(srcbox.getobj()) + dstbox.changevalue_obj(srcbox.getref_base()) else: assert False Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py Thu Aug 27 16:21:54 2009 @@ -107,10 +107,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getptr_base()) + x = bool(args[0].getref_base()) else: assert tp == OBJ - x = bool(args[0].getobj()) + x = bool(args[0].getref_base()) return ConstInt(x) def do_ooisnull(cpu, args, descr=None): @@ -118,10 +118,10 @@ if tp == INT: x = bool(args[0].getint()) elif tp == PTR: - x = bool(args[0].getptr_base()) + x = bool(args[0].getref_base()) else: assert tp == OBJ - x = bool(args[0].getobj()) + x = bool(args[0].getref_base()) return ConstInt(not x) def do_oois(cpu, args, descr=None): @@ -130,10 +130,10 @@ if tp == INT: x = args[0].getint() == args[1].getint() elif tp == PTR: - x = args[0].getptr_base() == args[1].getptr_base() + x = args[0].getref_base() == args[1].getref_base() else: assert tp == OBJ - x = args[0].getobj() == args[1].getobj() + x = args[0].getref_base() == args[1].getref_base() return ConstInt(x) def do_ooisnot(cpu, args, descr=None): @@ -142,22 +142,22 @@ if tp == INT: x = args[0].getint() != args[1].getint() elif tp == PTR: - x = args[0].getptr_base() != args[1].getptr_base() + x = args[0].getref_base() != args[1].getref_base() else: assert tp == OBJ - x = args[0].getobj() != args[1].getobj() + x = args[0].getref_base() != args[1].getref_base() return ConstInt(x) def do_ooidentityhash(cpu, args, descr=None): - obj = args[0].getobj() + obj = args[0].getref_base() return ConstInt(ootype.ooidentityhash(obj)) def do_subclassof(self, args, descr=None): assert len(args) == 2 box1, box2 = args - cls1 = ootype.cast_from_object(ootype.Class, box1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, box2.getobj()) + cls1 = box1.getref(ootype.Class) + cls2 = box2.getref(ootype.Class) res = ootype.subclassof(cls1, cls2) return BoxInt(res) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Thu Aug 27 16:21:54 2009 @@ -80,15 +80,12 @@ def getint(self): raise NotImplementedError - def getptr_base(self): + def getref_base(self): raise NotImplementedError - def getptr(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getptr_base()) - getptr._annspecialcase_ = 'specialize:arg(1)' - - def getobj(self): + def getref(self, TYPE): raise NotImplementedError + getref._annspecialcase_ = 'specialize:arg(1)' def get_(self): raise NotImplementedError @@ -296,9 +293,13 @@ nonconstbox = clonebox - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): return lltype.cast_ptr_to_int(self.value) @@ -312,7 +313,7 @@ cpu.set_future_value_ptr(j, self.value) def equals(self, other): - return self.value == other.getptr_base() + return self.value == other.getref_base() _getrepr_ = repr_pointer @@ -338,9 +339,13 @@ nonconstbox = clonebox - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -360,7 +365,7 @@ ## return self.value def equals(self, other): - return self.value == other.getobj() + return self.value == other.getref_base() _getrepr_ = repr_object @@ -479,9 +484,13 @@ def constbox(self): return ConstPtr(self.value) - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def getaddr(self, cpu): return llmemory.cast_ptr_to_adr(self.value) @@ -498,7 +507,7 @@ return repr_rpython(self, 'bp') def changevalue_box(self, srcbox): - self.changevalue_ptr(srcbox.getptr_base()) + self.changevalue_ptr(srcbox.getref_base()) _getrepr_ = repr_pointer changevalue_ptr = __init__ @@ -520,9 +529,13 @@ def constbox(self): return ConstObj(self.value) - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -539,7 +552,7 @@ return repr_rpython(self, 'bo') def changevalue_box(self, srcbox): - self.changevalue_obj(srcbox.getobj()) + self.changevalue_obj(srcbox.getref_base()) _getrepr_ = repr_object changevalue_obj = __init__ Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 16:21:54 2009 @@ -343,7 +343,7 @@ if not self.is_constant(box): return box if not self.cpu.is_oo and box.type == PTR: - value = box.getptr_base() + value = box.getref_base() key = lltype.cast_ptr_to_int(value) try: return self.interned_ptrs[key] @@ -351,7 +351,7 @@ self.interned_ptrs[key] = box return box elif self.cpu.is_oo and box.type == OBJ: - value = box.getobj() + value = box.getref_base() try: return self.interned_objs[value] except KeyError: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 16:21:54 2009 @@ -715,7 +715,7 @@ box = self.implement_guard_value(pc, box) cpu = self.metainterp.cpu if cpu.is_oo: - key = box.getobj() + key = box.getref_base() else: key = box.getaddr(cpu) jitcode = indirectcallset.bytecode_for_address(key) @@ -729,7 +729,7 @@ clsbox = self.cls_of_box(objbox) if isinstance(objbox, Box): self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox]) - oocls = ootype.cast_from_object(ootype.Class, clsbox.getobj()) + oocls = clsbox.getref(ootype.Class) jitcode = methdescr.get_jitcode_for_class(oocls) return self.perform_call(jitcode, varargs) @@ -1140,9 +1140,9 @@ elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) elif sd.result_type == 'ptr': - raise sd.DoneWithThisFramePtr(resultbox.getptr_base()) + raise sd.DoneWithThisFramePtr(resultbox.getref_base()) elif self.cpu.is_oo and sd.result_type == 'obj': - raise sd.DoneWithThisFrameObj(resultbox.getobj()) + raise sd.DoneWithThisFrameObj(resultbox.getref_base()) else: assert False @@ -1170,9 +1170,9 @@ if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) if self.cpu.is_oo: - raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getobj()) + raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getref_base()) else: - raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getptr_base()) + raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getref_base()) def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py Thu Aug 27 16:21:54 2009 @@ -1155,10 +1155,9 @@ tag, resolved, fieldstext = virtuals[varname] if tag[0] == 'virtual': if not self.cpu.is_oo: - assert box.getptr(rclass.OBJECTPTR).typeptr == tag[1] + assert box.getref(rclass.OBJECTPTR).typeptr == tag[1] else: - root = box.getobj() - root = ootype.cast_from_object(ootype.ROOT, root) + root = box.getref(ootype.ROOT) assert ootype.classof(root) == tag[1] elif tag[0] == 'varray': pass # xxx check arraydescr Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 16:21:54 2009 @@ -56,7 +56,7 @@ return llmemory.cast_ptr_to_adr(fnptr) def cls_of_box(self, cpu, box): - obj = box.getptr(lltype.Ptr(rclass.OBJECT)) + obj = box.getref(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(cpu.cast_adr_to_int(cls)) @@ -75,7 +75,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getptr(lltype.Ptr(rclass.OBJECT)) + obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): @@ -116,13 +116,13 @@ return ootype.cast_to_object(fnptr) def cls_of_box(self, cpu, box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) oocls = ootype.classof(obj) return history.ConstObj(ootype.cast_to_object(oocls)) def subclassOf(self, cpu, clsbox1, clsbox2): - cls1 = ootype.cast_from_object(ootype.Class, clsbox1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, clsbox2.getobj()) + cls1 = clsbox1.getref(ootype.Class) + cls2 = clsbox2.getref(ootype.Class) return ootype.subclassof(cls1, cls2) def get_exception_box(self, etype): @@ -133,7 +133,7 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = ootype.cast_from_object(ootype.ROOT, evaluebox.getobj()) + obj = evaluebox.getref(ootype.ROOT) return cast_base_ptr_to_instance(Exception, obj) def clean_box(self, box): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Thu Aug 27 16:21:54 2009 @@ -186,10 +186,9 @@ def unwrap_virtualizable_box(self, virtualizable_box): if not self.is_oo: - return virtualizable_box.getptr(self.VTYPEPTR) + return virtualizable_box.getref(self.VTYPEPTR) else: - obj = virtualizable_box.getobj() - return ootype.cast_from_object(self.VTYPE, obj) + return virtualizable_box.getref(self.VTYPE) def cast_to_vtype(self, virtualizable): if not self.is_oo: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 16:21:54 2009 @@ -579,9 +579,9 @@ if TYPE is lltype.Void: return None if isinstance(TYPE, lltype.Ptr): - return box.getptr(TYPE) + return box.getref(TYPE) if isinstance(TYPE, ootype.OOType): - return ootype.cast_from_object(TYPE, box.getobj()) + return box.getref(TYPE) else: return lltype.cast_primitive(TYPE, box.getint()) unwrap._annspecialcase_ = 'specialize:arg(0)' From cfbolz at codespeak.net Thu Aug 27 16:37:54 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 16:37:54 +0200 (CEST) Subject: [pypy-svn] r67249 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090827143754.56325168025@codespeak.net> Author: cfbolz Date: Thu Aug 27 16:37:52 2009 New Revision: 67249 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtual.py Log: reorganize tests a bit and make them more precise. Also unskip a subclass. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtual.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtual.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtual.py Thu Aug 27 16:37:52 2009 @@ -160,15 +160,16 @@ while n >= 0: myjitdriver.can_enter_jit(n=n) myjitdriver.jit_merge_point(n=n) - foo = Foo() - foo.n = n + foo = self._new() + foo.value = n if n < 10: break - n = foo.n - 1 + n = foo.value - 1 return n res = self.meta_interp(f, [20]) assert res == 9 + self.check_loops(new_with_vtable=0, new=0) def test_immutable_constant_getfield(self): myjitdriver = JitDriver(greens = ['stufflist'], reds = ['n', 'i']) @@ -199,10 +200,6 @@ def test_escapes(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'parent']) - class Node(object): - def __init__(self, x): - self.x = x - class Parent(object): def __init__(self, node): self.node = node @@ -211,18 +208,23 @@ pass def f(n): - parent = Parent(Node(3)) + node = self._new() + node.value = 3 + parent = Parent(node) while n > 0: myjitdriver.can_enter_jit(n=n, parent=parent) myjitdriver.jit_merge_point(n=n, parent=parent) node = parent.node g(node) - parent = Parent(Node(node.x)) + newnode = self._new() + newnode.value = 3 + parent = Parent(newnode) n -= 1 - return parent.node.x + return parent.node.value res = self.meta_interp(f, [10], policy=StopAtXPolicy(g)) assert res == 3 + self.check_loops(**{self._new_op: 1}) def test_virtual_on_virtual(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'parent']) @@ -236,39 +238,44 @@ self.f = f def f(n): - node = Node(SubNode(3)) + subnode = self._new() + subnode.value = 3 + node = Node(subnode) while n > 0: myjitdriver.can_enter_jit(n=n, parent=node) myjitdriver.jit_merge_point(n=n, parent=node) - node = Node(SubNode(n + 1)) + subnode = self._new() + subnode.value = n + 1 + node = Node(subnode) if n == -3: return 8 n -= 1 - return node.f.f + return node.f.value res = self.meta_interp(f, [10]) assert res == 2 + self.check_loops(new=0, new_with_vtable=0) def test_bridge_from_interpreter(self): mydriver = JitDriver(reds = ['n', 'f'], greens = []) - class Foo: - pass - def f(n): - f = Foo() - f.n = 0 + f = self._new() + f.value = 0 while n > 0: mydriver.can_enter_jit(n=n, f=f) mydriver.jit_merge_point(n=n, f=f) - prev = f.n - f = Foo() - f.n = prev + n + prev = f.value + f = self._new() + f.value = prev + n n -= 2 return f res = self.meta_interp(f, [21], repeat=7) - assert res.inst_n == f(21).n + # hack + assert (getattr(res, "inst_value", -100) == f(21).value or + getattr(res, "value", -100) == f(21).value) + self.check_tree_loop_count(2) # the loop and the entry path # we get: # ENTER - compile the new loop @@ -302,9 +309,6 @@ class TestLLtype_NotObject(VirtualTests, LLJitMixin): _new_op = 'new' - def setup_class(cls): - py.test.skip("not supported yet") - @staticmethod def _new(): return lltype.malloc(NODE) From antocuni at codespeak.net Thu Aug 27 16:38:34 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 16:38:34 +0200 (CEST) Subject: [pypy-svn] r67250 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend/cli backend/x86 metainterp Message-ID: <20090827143834.D0435168025@codespeak.net> Author: antocuni Date: Thu Aug 27 16:38:33 2009 New Revision: 67250 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: unify history.PTR and history.OBJ into history.REF; this let us to remove a bit of code duplication here and there Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py Thu Aug 27 16:38:33 2009 @@ -44,7 +44,7 @@ if self.type == history.INT: return dotnet.typeof(System.Int32) - elif self.type == history.OBJ: + elif self.type == history.REF: return dotnet.typeof(System.Object) else: assert False, 'Unknown type: %s' % self.type @@ -282,7 +282,7 @@ t = dotnet.typeof(InputArgs) if type == history.INT: fieldname = 'ints' - elif type == history.OBJ: + elif type == history.REF: fieldname = 'objs' else: assert False, 'Unknown type %s' % type Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py Thu Aug 27 16:38:33 2009 @@ -1,7 +1,7 @@ import sys, os import ctypes from pypy.jit.backend.x86 import symbolic -from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR +from pypy.jit.metainterp.history import Const, Box, BoxPtr, REF from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -240,7 +240,7 @@ for i in range(len(arglocs)): loc = arglocs[i] if not isinstance(loc, REG): - if args[i].type == PTR: + if args[i].type == REF: # This uses XCHG to put zeroes in fail_boxes_ptr after # reading them self.mc.XOR(ecx, ecx) @@ -253,7 +253,7 @@ for i in range(len(arglocs)): loc = arglocs[i] if isinstance(loc, REG): - if args[i].type == PTR: + if args[i].type == REF: # This uses XCHG to put zeroes in fail_boxes_ptr after # reading them self.mc.XOR(loc, loc) @@ -718,7 +718,7 @@ for i in range(len(locs)): loc = locs[i] if isinstance(loc, REG): - if op.args[i].type == PTR: + if op.args[i].type == REF: base = self.fail_box_ptr_addr else: base = self.fail_box_int_addr @@ -726,7 +726,7 @@ for i in range(len(locs)): loc = locs[i] if not isinstance(loc, REG): - if op.args[i].type == PTR: + if op.args[i].type == REF: base = self.fail_box_ptr_addr else: base = self.fail_box_int_addr Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Thu Aug 27 16:38:33 2009 @@ -179,7 +179,7 @@ if calldescr.call_loop is not None: if not we_are_translated(): assert (calldescr.shape == - ([arg.type == history.PTR for arg in args[1:]], ptr)) + ([arg.type == history.REF for arg in args[1:]], ptr)) return calldescr.call_loop args = [arg.clonebox() for arg in args] result = self._new_box(ptr) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/executor.py Thu Aug 27 16:38:33 2009 @@ -7,7 +7,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr -from pypy.jit.metainterp.history import INT, PTR, OBJ +from pypy.jit.metainterp.history import INT, REF from pypy.jit.metainterp.resoperation import rop @@ -106,22 +106,20 @@ tp = args[0].type if tp == INT: x = bool(args[0].getint()) - elif tp == PTR: + elif tp == REF: x = bool(args[0].getref_base()) else: - assert tp == OBJ - x = bool(args[0].getref_base()) + assert False return ConstInt(x) def do_ooisnull(cpu, args, descr=None): tp = args[0].type if tp == INT: x = bool(args[0].getint()) - elif tp == PTR: + elif tp == REF: x = bool(args[0].getref_base()) else: - assert tp == OBJ - x = bool(args[0].getref_base()) + assert False return ConstInt(not x) def do_oois(cpu, args, descr=None): @@ -129,11 +127,10 @@ assert tp == args[1].type if tp == INT: x = args[0].getint() == args[1].getint() - elif tp == PTR: + elif tp == REF: x = args[0].getref_base() == args[1].getref_base() else: - assert tp == OBJ - x = args[0].getref_base() == args[1].getref_base() + assert False return ConstInt(x) def do_ooisnot(cpu, args, descr=None): @@ -141,11 +138,10 @@ assert tp == args[1].type if tp == INT: x = args[0].getint() != args[1].getint() - elif tp == PTR: + elif tp == REF: x = args[0].getref_base() != args[1].getref_base() else: - assert tp == OBJ - x = args[0].getref_base() != args[1].getref_base() + assert False return ConstInt(x) def do_ooidentityhash(cpu, args, descr=None): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Thu Aug 27 16:38:33 2009 @@ -17,8 +17,7 @@ # ____________________________________________________________ INT = 'i' -PTR = 'p' -OBJ = 'o' +REF = 'r' def getkind(TYPE): if TYPE is lltype.Void: @@ -280,7 +279,7 @@ return repr_rpython(self, 'ca') class ConstPtr(Const): - type = PTR + type = REF value = lltype.nullptr(llmemory.GCREF.TO) _attrs_ = ('value',) @@ -326,7 +325,7 @@ return hlstr(lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), self.value)) class ConstObj(Const): - type = OBJ + type = REF value = ootype.NULL _attrs_ = ('value',) @@ -471,7 +470,7 @@ changevalue_int = __init__ class BoxPtr(Box): - type = PTR + type = REF _attrs_ = ('value',) def __init__(self, value=lltype.nullptr(llmemory.GCREF.TO)): @@ -516,7 +515,7 @@ class BoxObj(Box): - type = OBJ + type = REF _attrs_ = ('value',) def __init__(self, value=ootype.NULL): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 16:38:33 2009 @@ -1,5 +1,5 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj -from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ +from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, REF from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp.specnode import SpecNode, NotSpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode @@ -336,26 +336,18 @@ self.values = {} self.values_to_clean = [] # OptValues to clean when we see an # operation with side-effects - self.interned_ptrs = {} - self.interned_objs = {} + self.interned_refs = {} def getinterned(self, box): if not self.is_constant(box): return box - if not self.cpu.is_oo and box.type == PTR: + if box.type == REF: value = box.getref_base() - key = lltype.cast_ptr_to_int(value) + key = self.cpu.ts.cast_ref_to_hashable(value) try: - return self.interned_ptrs[key] + return self.interned_refs[key] except KeyError: - self.interned_ptrs[key] = box - return box - elif self.cpu.is_oo and box.type == OBJ: - value = box.getref_base() - try: - return self.interned_objs[value] - except KeyError: - self.interned_objs[value] = box + self.interned_refs[key] = box return box else: return box Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 16:38:33 2009 @@ -1,10 +1,8 @@ -#from pypy.rpython.annlowlevel import base_ptr_lltype, base_obj_ootype -#from pypy.rpython.annlowlevel import cast_instance_to_base_ptr -#from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, llstr, oostr from pypy.jit.metainterp import history +from pypy.jit.metainterp import history def deref(T): if isinstance(T, lltype.Ptr): @@ -39,10 +37,8 @@ name = 'lltype' functionptr = staticmethod(lltype.functionptr) - #ROOT_TYPE = llmemory.Address - #BASE_OBJ_TYPE = base_ptr_lltype() - #NULL_OBJECT = base_ptr_lltype()._defl() - #cast_instance_to_base_ptr = staticmethod(cast_instance_to_base_ptr) + BoxRef = history.BoxPtr + ConstRef = history.ConstPtr def get_typeptr(self, obj): return obj.typeptr @@ -95,15 +91,15 @@ ll = llstr(str) return history.ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ll)) + def cast_ref_to_hashable(self, ptr): + return lltype.cast_ptr_to_int(ptr) class OOTypeHelper(TypeSystemHelper): name = 'ootype' functionptr = staticmethod(ootype.static_meth) - #ROOT_TYPE = ootype.Object - #BASE_OBJ_TYPE = base_obj_ootype() - #NULL_OBJECT = base_obj_ootype()._defl() - #cast_instance_to_base_ptr = staticmethod(cast_instance_to_base_obj) + BoxRef = history.BoxObj + ConstRef = history.ConstObj def get_typeptr(self, obj): return obj.meta @@ -153,6 +149,9 @@ oo = oostr(str) return history.ConstObj(ootype.cast_to_object(oo)) + def cast_ref_to_hashable(self, obj): + return obj + llhelper = LLTypeHelper() oohelper = OOTypeHelper() From antocuni at codespeak.net Thu Aug 27 16:53:09 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 16:53:09 +0200 (CEST) Subject: [pypy-svn] r67251 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827145309.6C251168025@codespeak.net> Author: antocuni Date: Thu Aug 27 16:53:08 2009 New Revision: 67251 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: remove one more "if is_oo" by introducing a helper method in ts Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 16:53:08 2009 @@ -343,7 +343,7 @@ return box if box.type == REF: value = box.getref_base() - key = self.cpu.ts.cast_ref_to_hashable(value) + key = self.cpu.ts.cast_ref_to_hashable(self.cpu, value) try: return self.interned_refs[key] except KeyError: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 16:53:08 2009 @@ -1051,11 +1051,7 @@ def _setup_class_sizes(self): class_sizes = {} for vtable, sizedescr in self._class_sizes: - if not self.cpu.is_oo: - vtable = llmemory.cast_ptr_to_adr(vtable) - vtable = self.cpu.cast_adr_to_int(vtable) - else: - vtable = ootype.cast_to_object(vtable) + vtable = self.cpu.ts.cast_ref_to_hashable(self.cpu, vtable) class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 16:53:08 2009 @@ -91,8 +91,9 @@ ll = llstr(str) return history.ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ll)) - def cast_ref_to_hashable(self, ptr): - return lltype.cast_ptr_to_int(ptr) + def cast_ref_to_hashable(self, cpu, ptr): + adr = llmemory.cast_ptr_to_adr(ptr) + return cpu.cast_adr_to_int(adr) class OOTypeHelper(TypeSystemHelper): @@ -149,8 +150,8 @@ oo = oostr(str) return history.ConstObj(ootype.cast_to_object(oo)) - def cast_ref_to_hashable(self, obj): - return obj + def cast_ref_to_hashable(self, cpu, obj): + return ootype.cast_to_object(obj) llhelper = LLTypeHelper() From cfbolz at codespeak.net Thu Aug 27 17:13:14 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Aug 2009 17:13:14 +0200 (CEST) Subject: [pypy-svn] r67252 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090827151314.15FE1168025@codespeak.net> Author: cfbolz Date: Thu Aug 27 17:13:14 2009 New Revision: 67252 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py Log: unskip some tests about fixed-sized lists Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py Thu Aug 27 17:13:14 2009 @@ -8,7 +8,6 @@ class ListTests: def check_all_virtualized(self): - py.test.skip("virtualization of lists not supported for now") self.check_loops(new_array=0, setarrayitem_gc=0, getarrayitem_gc=0, arraylen_gc=0) From antocuni at codespeak.net Thu Aug 27 17:50:14 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 17:50:14 +0200 (CEST) Subject: [pypy-svn] r67253 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827155014.3619A168029@codespeak.net> Author: antocuni Date: Thu Aug 27 17:50:11 2009 New Revision: 67253 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: unify ExitFrameWithException{Obj,Ptr} into ExitFrameWithExceptionRef Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 17:50:11 2009 @@ -181,7 +181,7 @@ else: assert isinstance(valuebox, history.Const) value = valuebox.getref_base() - raise metainterp_sd.ExitFrameWithExceptionPtr(value) + raise metainterp_sd.ExitFrameWithExceptionRef(metainterp_sd.cpu, value) class ExitFrameWithExceptionDescrObj(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): @@ -192,7 +192,7 @@ else: assert isinstance(valuebox, history.Const) value = valuebox.getref_base() - raise metainterp_sd.ExitFrameWithExceptionObj(value) + raise metainterp_sd.ExitFrameWithExceptionRef(metainterp_sd.cpu, value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() done_with_this_frame_descr_int = DoneWithThisFrameDescrInt() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 17:50:11 2009 @@ -1051,7 +1051,7 @@ def _setup_class_sizes(self): class_sizes = {} for vtable, sizedescr in self._class_sizes: - vtable = self.cpu.ts.cast_ref_to_hashable(self.cpu, vtable) + vtable = self.cpu.ts.cast_baseclass_to_hashable(self.cpu, vtable) class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) @@ -1165,10 +1165,7 @@ self.framestack.pop() if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) - if self.cpu.is_oo: - raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getref_base()) - else: - raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getref_base()) + raise self.staticdata.ExitFrameWithExceptionRef(self.cpu, excvaluebox.getref_base()) def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 17:50:11 2009 @@ -37,6 +37,7 @@ name = 'lltype' functionptr = staticmethod(lltype.functionptr) + BASETYPE = llmemory.GCREF BoxRef = history.BoxPtr ConstRef = history.ConstPtr @@ -74,6 +75,9 @@ obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) return cast_base_ptr_to_instance(Exception, obj) + def cast_to_baseclass(self, value): + return lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), value) + def clean_box(self, box): if isinstance(box, history.BoxPtr): box.value = lltype.nullptr(llmemory.GCREF.TO) @@ -95,15 +99,21 @@ adr = llmemory.cast_ptr_to_adr(ptr) return cpu.cast_adr_to_int(adr) + def cast_baseclass_to_hashable(self, cpu, ptr): + adr = llmemory.cast_ptr_to_adr(ptr) + return cpu.cast_adr_to_int(adr) + + class OOTypeHelper(TypeSystemHelper): name = 'ootype' functionptr = staticmethod(ootype.static_meth) + BASETYPE = ootype.Object BoxRef = history.BoxObj ConstRef = history.ConstObj def get_typeptr(self, obj): - return obj.meta + return ootype.classof(obj) def get_FuncType(self, ARGS, RESULT): FUNCTYPE = ootype.StaticMethod(ARGS, RESULT) @@ -133,6 +143,9 @@ obj = evaluebox.getref(ootype.ROOT) return cast_base_ptr_to_instance(Exception, obj) + def cast_to_baseclass(self, value): + return ootype.cast_from_object(ootype.ROOT, value) + def clean_box(self, box): if isinstance(box, history.BoxObj): box.value = ootype.NULL @@ -153,6 +166,8 @@ def cast_ref_to_hashable(self, cpu, obj): return ootype.cast_to_object(obj) + def cast_baseclass_to_hashable(self, cpu, obj): + return ootype.cast_to_object(obj) llhelper = LLTypeHelper() oohelper = OOTypeHelper() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 17:50:11 2009 @@ -399,19 +399,12 @@ def __str__(self): return 'DoneWithThisFrameObj(%s)' % (self.result,) - class ExitFrameWithExceptionPtr(JitException): - def __init__(self, value): - assert lltype.typeOf(value) == llmemory.GCREF + class ExitFrameWithExceptionRef(JitException): + def __init__(self, cpu, value): + assert lltype.typeOf(value) == cpu.ts.BASETYPE self.value = value def __str__(self): - return 'ExitFrameWithExceptionPtr(%s)' % (self.value,) - - class ExitFrameWithExceptionObj(JitException): - def __init__(self, value): - assert lltype.typeOf(value) == ootype.Object - self.value = value - def __str__(self): - return 'ExitFrameWithExceptionObj(%s)' % (self.value,) + return 'ExitFrameWithExceptionRef(%s)' % (self.value,) class ContinueRunningNormally(JitException): def __init__(self, argboxes): @@ -430,20 +423,19 @@ self.DoneWithThisFrameInt = DoneWithThisFrameInt self.DoneWithThisFramePtr = DoneWithThisFramePtr self.DoneWithThisFrameObj = DoneWithThisFrameObj - self.ExitFrameWithExceptionPtr = ExitFrameWithExceptionPtr - self.ExitFrameWithExceptionObj = ExitFrameWithExceptionObj + self.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.ContinueRunningNormally = ContinueRunningNormally self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt self.metainterp_sd.DoneWithThisFramePtr = DoneWithThisFramePtr self.metainterp_sd.DoneWithThisFrameObj = DoneWithThisFrameObj - self.metainterp_sd.ExitFrameWithExceptionPtr = ExitFrameWithExceptionPtr - self.metainterp_sd.ExitFrameWithExceptionObj = ExitFrameWithExceptionObj + self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally rtyper = self.translator.rtyper RESULT = PORTALFUNC.RESULT result_kind = history.getkind(RESULT) is_oo = self.cpu.is_oo + ts = self.cpu.ts def ll_portal_runner(*args): while 1: @@ -467,20 +459,10 @@ except DoneWithThisFrameObj, e: assert result_kind == 'obj' return ootype.cast_from_object(RESULT, e.result) - except ExitFrameWithExceptionPtr, e: - assert not is_oo - value = lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), - e.value) - if not we_are_translated(): - raise LLException(value.typeptr, value) - else: - value = cast_base_ptr_to_instance(Exception, value) - raise Exception, value - except ExitFrameWithExceptionObj, e: - assert is_oo - value = ootype.cast_from_object(ootype.ROOT, e.value) + except ExitFrameWithExceptionRef, e: + value = ts.cast_to_baseclass(e.value) if not we_are_translated(): - raise LLException(ootype.classof(value), value) + raise LLException(ts.get_typeptr(value), value) else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value From fijal at codespeak.net Thu Aug 27 17:53:28 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 27 Aug 2009 17:53:28 +0200 (CEST) Subject: [pypy-svn] r67254 - in pypy/build/benchmark/specific: . test Message-ID: <20090827155328.966FA168029@codespeak.net> Author: fijal Date: Thu Aug 27 17:53:28 2009 New Revision: 67254 Added: pypy/build/benchmark/specific/ pypy/build/benchmark/specific/__init__.py (contents, props changed) pypy/build/benchmark/specific/pystone.py (contents, props changed) pypy/build/benchmark/specific/test/ pypy/build/benchmark/specific/test/__init__.py (contents, props changed) pypy/build/benchmark/specific/test/test_benchmarks.py (contents, props changed) Log: Add pystone runner Added: pypy/build/benchmark/specific/__init__.py ============================================================================== Added: pypy/build/benchmark/specific/pystone.py ============================================================================== --- (empty file) +++ pypy/build/benchmark/specific/pystone.py Thu Aug 27 17:53:28 2009 @@ -0,0 +1,13 @@ + +from benchmark.runner import ScriptRunner + +RUN_PYSTONE = 'from test import pystone; print pystone.pystones()' + +class PystoneRunner(ScriptRunner): + def __init__(self): + ScriptRunner.__init__(self, 'pystone', RUN_PYSTONE) + + def read_output(self, output): + output = output.strip('()\n') + time, pystones = output.split(", ") + return float(time) Added: pypy/build/benchmark/specific/test/__init__.py ============================================================================== Added: pypy/build/benchmark/specific/test/test_benchmarks.py ============================================================================== --- (empty file) +++ pypy/build/benchmark/specific/test/test_benchmarks.py Thu Aug 27 17:53:28 2009 @@ -0,0 +1,7 @@ + +from benchmark.specific.pystone import PystoneRunner + +def test_pystone(): + runner = PystoneRunner() + times = [runner.run(1)] + assert len(times) == 1 From fijal at codespeak.net Thu Aug 27 18:09:33 2009 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 27 Aug 2009 18:09:33 +0200 (CEST) Subject: [pypy-svn] r67255 - in pypy/build/benchmark: . specific specific/test test Message-ID: <20090827160933.89264168032@codespeak.net> Author: fijal Date: Thu Aug 27 18:09:33 2009 New Revision: 67255 Added: pypy/build/benchmark/specific/richards.py (contents, props changed) Modified: pypy/build/benchmark/runner.py pypy/build/benchmark/specific/ (props changed) pypy/build/benchmark/specific/test/ (props changed) pypy/build/benchmark/specific/test/test_benchmarks.py pypy/build/benchmark/test/test_runner.py Log: Add richards, fixeol Modified: pypy/build/benchmark/runner.py ============================================================================== --- pypy/build/benchmark/runner.py (original) +++ pypy/build/benchmark/runner.py Thu Aug 27 18:09:33 2009 @@ -24,6 +24,9 @@ raise NotImplementedError("abstract base class") class ScriptRunner(AbstractRunner): + """ this benchmark runner executes script provided as a source code + """ + tmpdir = None def __init__(self, name, source, executable=sys.executable): @@ -37,10 +40,14 @@ cls.tmpdir = udir.join('benchmark_runner') cls.tmpdir.ensure(dir=True) - def run_once(self): + def get_script_name(self): self.setup_tmpdir() fname = self.tmpdir.join(self.name + '.py') fname.write(self.source) + return fname + + def run_once(self): + fname = self.get_script_name() pipe = subprocess.Popen([sys.executable, str(fname)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -58,3 +65,12 @@ raise OutputDidNotMatch("got %s" % output) return float(m.group(1)) +class ProgramRunner(ScriptRunner): + """ this benchmark runner executes an existing python script + """ + def __init__(self, name, path): + self.path = path + self.name = name + + def get_script_name(self): + return str(self.path) Added: pypy/build/benchmark/specific/richards.py ============================================================================== --- (empty file) +++ pypy/build/benchmark/specific/richards.py Thu Aug 27 18:09:33 2009 @@ -0,0 +1,17 @@ + +import py +import pypy +import re +from benchmark.runner import ProgramRunner, OutputDidNotMatch + +RICHARDS_PATH = ('..', 'translator', 'goal', 'richards.py') +class RichardsRunner(ProgramRunner): + def __init__(self): + richards_fname = py.path.local(pypy.__file__).join(*RICHARDS_PATH) + ProgramRunner.__init__(self, 'richards', richards_fname) + + def read_output(self, output): + m = re.search("Average time per iteration: ([\d.]+)", output) + if not m: + raise OutputDidNotMatch("got " + output) + return float(m.group(1)) Modified: pypy/build/benchmark/specific/test/test_benchmarks.py ============================================================================== --- pypy/build/benchmark/specific/test/test_benchmarks.py (original) +++ pypy/build/benchmark/specific/test/test_benchmarks.py Thu Aug 27 18:09:33 2009 @@ -1,7 +1,15 @@ from benchmark.specific.pystone import PystoneRunner +from benchmark.specific.richards import RichardsRunner def test_pystone(): runner = PystoneRunner() - times = [runner.run(1)] + times = runner.run(1) assert len(times) == 1 + assert isinstance(times[0], float) + +def test_richards(): + runner = RichardsRunner() + times = runner.run(1) + assert len(times) == 1 + assert isinstance(times[0], float) Modified: pypy/build/benchmark/test/test_runner.py ============================================================================== --- pypy/build/benchmark/test/test_runner.py (original) +++ pypy/build/benchmark/test/test_runner.py Thu Aug 27 18:09:33 2009 @@ -1,6 +1,7 @@ import py -from benchmark.runner import ScriptRunner, ErrorExecuting +from benchmark.runner import ScriptRunner, ErrorExecuting, ProgramRunner +from pypy.tool.udir import udir class TestRunner(object): def test_script_runner(self): @@ -16,3 +17,12 @@ def test_script_runner_fail(self): runner = ScriptRunner("test3", "import sys; sys.exit(1)") py.test.raises(ErrorExecuting, runner.run) + + def test_program_runner(self): + tmpdir = udir.join("benchmark_testdir") + tmpdir.ensure(dir=True) + f = tmpdir.join("xxx.py") + f.write("print 'time: 0'") + runner = ProgramRunner("test4", str(f)) + t = runner.run(3) + assert t == [0, 0, 0] From antocuni at codespeak.net Thu Aug 27 18:11:52 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 18:11:52 +0200 (CEST) Subject: [pypy-svn] r67256 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend backend/cli backend/llgraph backend/llvm backend/test backend/x86 backend/x86/test metainterp Message-ID: <20090827161152.065D3168032@codespeak.net> Author: antocuni Date: Thu Aug 27 18:11:51 2009 New Revision: 67256 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/model.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_regalloc.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: - rename set_future_value_{obj,ptr} to *_ref; the same for get_lastest_value_{obj,ptr) - unify ExitFrameWithExceptionDescr{Obj,Ptr} ExitFrameWithExceptionDescrRef Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py Thu Aug 27 18:11:51 2009 @@ -105,14 +105,14 @@ def set_future_value_int(self, index, intvalue): self.get_inputargs().set_int(index, intvalue) - def set_future_value_obj(self, index, objvalue): + def set_future_value_ref(self, index, objvalue): obj = dotnet.cast_to_native_object(objvalue) self.get_inputargs().set_obj(index, obj) def get_latest_value_int(self, index): return self.get_inputargs().get_int(index) - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): obj = self.get_inputargs().get_obj(index) return dotnet.cast_from_native_object(obj) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py Thu Aug 27 18:11:51 2009 @@ -866,12 +866,7 @@ assert len(_future_values) == index _future_values.append(value) -def set_future_value_ptr(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) - -def set_future_value_obj(index, value): +def set_future_value_ref(index, value): del _future_values[index:] assert len(_future_values) == index _future_values.append(value) @@ -1274,8 +1269,7 @@ setannotation(new_frame, s_Frame) setannotation(frame_clear, annmodel.s_None) setannotation(set_future_value_int, annmodel.s_None) -setannotation(set_future_value_ptr, annmodel.s_None) -setannotation(set_future_value_obj, annmodel.s_None) +setannotation(set_future_value_ref, annmodel.s_None) setannotation(frame_execute, annmodel.SomeInteger()) setannotation(frame_int_getvalue, annmodel.SomeInteger()) setannotation(frame_ptr_getvalue, annmodel.SomePtr(llmemory.GCREF)) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Thu Aug 27 18:11:51 2009 @@ -187,19 +187,13 @@ def set_future_value_int(self, index, intvalue): llimpl.set_future_value_int(index, intvalue) - def set_future_value_ptr(self, index, ptrvalue): - llimpl.set_future_value_ptr(index, ptrvalue) - - def set_future_value_obj(self, index, objvalue): - llimpl.set_future_value_obj(index, objvalue) + def set_future_value_ref(self, index, objvalue): + llimpl.set_future_value_ref(index, objvalue) def get_latest_value_int(self, index): return llimpl.frame_int_getvalue(self.latest_frame, index) - def get_latest_value_ptr(self, index): - return llimpl.frame_ptr_getvalue(self.latest_frame, index) - - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): return llimpl.frame_ptr_getvalue(self.latest_frame, index) # ---------- Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py Thu Aug 27 18:11:51 2009 @@ -310,7 +310,7 @@ p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) p[0] = intvalue - def set_future_value_ptr(self, index, ptrvalue): + def set_future_value_ref(self, index, ptrvalue): p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) p[0] = ptrvalue @@ -331,7 +331,7 @@ p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) return p[0] - def get_latest_value_ptr(self, index): + def get_latest_value_ref(self, index): p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) return p[0] @@ -679,7 +679,7 @@ if calldescr.res_index < 0: return None elif calldescr.res_index == self.SIZE_GCPTR: - return BoxPtr(self.get_latest_value_ptr(0)) + return BoxPtr(self.get_latest_value_ref(0)) else: return BoxInt(self.get_latest_value_int(0)) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/model.py Thu Aug 27 18:11:51 2009 @@ -23,11 +23,7 @@ """Set the value for the index'th argument for the loop to run.""" raise NotImplementedError - def set_future_value_ptr(self, index, ptrvalue): - """Set the value for the index'th argument for the loop to run.""" - raise NotImplementedError - - def set_future_value_obj(self, index, objvalue): + def set_future_value_ref(self, index, objvalue): """Set the value for the index'th argument for the loop to run.""" raise NotImplementedError @@ -36,14 +32,9 @@ lastest rop.FAIL. Returns an int.""" raise NotImplementedError - def get_latest_value_ptr(self, index): - """Returns the value for the index'th argument to the - lastest rop.FAIL. Returns a ptr.""" - raise NotImplementedError - - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the - lastest rop.FAIL. Returns an obj.""" + lastest rop.FAIL. Returns a ptr or an obj.""" raise NotImplementedError def get_exception(self): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py Thu Aug 27 18:11:51 2009 @@ -24,10 +24,10 @@ self.cpu.set_future_value_int(j, box.getint()) j += 1 elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ptr(j, box.getref_base()) + self.cpu.set_future_value_ref(j, box.getref_base()) j += 1 elif isinstance(box, BoxObj): - self.cpu.set_future_value_obj(j, box.getref_base()) + self.cpu.set_future_value_ref(j, box.getref_base()) j += 1 res = self.cpu.execute_operations(loop) if res is loop.operations[-1]: @@ -37,7 +37,7 @@ if result_type == 'int': return BoxInt(self.cpu.get_latest_value_int(0)) elif result_type == 'ptr': - return BoxPtr(self.cpu.get_latest_value_ptr(0)) + return BoxPtr(self.cpu.get_latest_value_ref(0)) elif result_type == 'void': return None else: @@ -885,7 +885,7 @@ self.cpu.set_future_value_int(0, 1) self.cpu.execute_operations(loop) assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_ptr(1) == xptr + assert self.cpu.get_latest_value_ref(1) == xptr self.cpu.clear_exception() self.cpu.set_future_value_int(0, 0) self.cpu.execute_operations(loop) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Thu Aug 27 18:11:51 2009 @@ -216,14 +216,14 @@ assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_int[index] = intvalue - def set_future_value_ptr(self, index, ptrvalue): + def set_future_value_ref(self, index, ptrvalue): assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_ptr[index] = ptrvalue def get_latest_value_int(self, index): return self.assembler.fail_boxes_int[index] - def get_latest_value_ptr(self, index): + def get_latest_value_ref(self, index): ptrvalue = self.assembler.fail_boxes_ptr[index] # clear after reading self.assembler.fail_boxes_ptr[index] = lltype.nullptr( @@ -465,7 +465,7 @@ if size == 0: return None elif ptr: - return BoxPtr(self.get_latest_value_ptr(0)) + return BoxPtr(self.get_latest_value_ref(0)) else: return BoxInt(self.get_latest_value_int(0)) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_regalloc.py Thu Aug 27 18:11:51 2009 @@ -177,7 +177,7 @@ else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) - self.cpu.set_future_value_ptr(i, llgcref) + self.cpu.set_future_value_ref(i, llgcref) if run: self.cpu.execute_operations(loop) return loop @@ -190,7 +190,7 @@ index in range(0, end)] def getptr(self, index, T): - gcref = self.cpu.get_latest_value_ptr(index) + gcref = self.cpu.get_latest_value_ref(index) return lltype.cast_opaque_ptr(T, gcref) def attach_bridge(self, ops, loop, guard_op): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py Thu Aug 27 18:11:51 2009 @@ -332,7 +332,7 @@ if op == rop.INT_IS_TRUE: self.cpu.set_future_value_int(0, b.value) else: - self.cpu.set_future_value_ptr(0, b.value) + self.cpu.set_future_value_ref(0, b.value) r = self.cpu.execute_operations(loop) result = self.cpu.get_latest_value_int(0) if guard == rop.GUARD_FALSE: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 18:11:51 2009 @@ -155,7 +155,7 @@ assert metainterp_sd.result_type == 'ptr' resultbox = fail_op.args[0] if isinstance(resultbox, BoxPtr): - result = metainterp_sd.cpu.get_latest_value_ptr(0) + result = metainterp_sd.cpu.get_latest_value_ref(0) else: assert isinstance(resultbox, history.Const) result = resultbox.getref_base() @@ -166,40 +166,29 @@ assert metainterp_sd.result_type == 'obj' resultbox = fail_op.args[0] if isinstance(resultbox, BoxObj): - result = metainterp_sd.cpu.get_latest_value_obj(0) + result = metainterp_sd.cpu.get_latest_value_ref(0) else: assert isinstance(resultbox, history.Const) result = resultbox.getref_base() raise metainterp_sd.DoneWithThisFrameObj(result) -class ExitFrameWithExceptionDescrPtr(AbstractDescr): +class ExitFrameWithExceptionDescrRef(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): assert len(fail_op.args) == 1 valuebox = fail_op.args[0] - if isinstance(valuebox, BoxPtr): - value = metainterp_sd.cpu.get_latest_value_ptr(0) - else: - assert isinstance(valuebox, history.Const) - value = valuebox.getref_base() - raise metainterp_sd.ExitFrameWithExceptionRef(metainterp_sd.cpu, value) - -class ExitFrameWithExceptionDescrObj(AbstractDescr): - def handle_fail_op(self, metainterp_sd, fail_op): - assert len(fail_op.args) == 1 - valuebox = fail_op.args[0] - if isinstance(valuebox, BoxObj): - value = metainterp_sd.cpu.get_latest_value_obj(0) + cpu = metainterp_sd.cpu + if isinstance(valuebox, cpu.ts.BoxRef): + value = cpu.get_latest_value_ref(0) else: assert isinstance(valuebox, history.Const) value = valuebox.getref_base() - raise metainterp_sd.ExitFrameWithExceptionRef(metainterp_sd.cpu, value) + raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() done_with_this_frame_descr_int = DoneWithThisFrameDescrInt() done_with_this_frame_descr_ptr = DoneWithThisFrameDescrPtr() done_with_this_frame_descr_obj = DoneWithThisFrameDescrObj() -exit_frame_with_exception_descr_ptr = ExitFrameWithExceptionDescrPtr() -exit_frame_with_exception_descr_obj = ExitFrameWithExceptionDescrObj() +exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef() class TerminatingLoop(TreeLoop): pass @@ -234,13 +223,13 @@ _loop = TerminatingLoop('exit_frame_with_exception_ptr') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] -_loop.finishdescr = exit_frame_with_exception_descr_ptr +_loop.finishdescr = exit_frame_with_exception_descr_ref loops_exit_frame_with_exception_ptr = [_loop] _loop = TerminatingLoop('exit_frame_with_exception_obj') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] -_loop.finishdescr = exit_frame_with_exception_descr_obj +_loop.finishdescr = exit_frame_with_exception_descr_ref loops_exit_frame_with_exception_obj = [_loop] del _loop @@ -279,10 +268,10 @@ srcvalue = cpu.get_latest_value_int(i) box.changevalue_int(srcvalue) elif not cpu.is_oo and isinstance(box, BoxPtr): - srcvalue = cpu.get_latest_value_ptr(i) + srcvalue = cpu.get_latest_value_ref(i) box.changevalue_ptr(srcvalue) elif cpu.is_oo and isinstance(box, BoxObj): - srcvalue = cpu.get_latest_value_obj(i) + srcvalue = cpu.get_latest_value_ref(i) box.changevalue_obj(srcvalue) elif isinstance(box, Const): pass # we don't need to do anything Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Thu Aug 27 18:11:51 2009 @@ -309,7 +309,7 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_ptr(j, self.value) + cpu.set_future_value_ref(j, self.value) def equals(self, other): return self.value == other.getref_base() @@ -355,7 +355,7 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_obj(j, self.value) + cpu.set_future_value_ref(j, self.value) ## def getaddr(self, cpu): ## # so far this is used only when calling @@ -500,7 +500,7 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_ptr(j, self.value) + cpu.set_future_value_ref(j, self.value) def repr_rpython(self): return repr_rpython(self, 'bp') @@ -545,7 +545,7 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_obj(j, self.value) + cpu.set_future_value_ref(j, self.value) def repr_rpython(self): return repr_rpython(self, 'bo') Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 18:11:51 2009 @@ -691,10 +691,10 @@ cpu = metainterp_sd.cpu if typecode == 'ptr': ptrvalue = lltype.cast_opaque_ptr(llmemory.GCREF, value) - cpu.set_future_value_ptr(j, ptrvalue) + cpu.set_future_value_ref(j, ptrvalue) elif typecode == 'obj': objvalue = ootype.cast_to_object(value) - cpu.set_future_value_obj(j, objvalue) + cpu.set_future_value_ref(j, objvalue) elif typecode == 'int': intvalue = lltype.cast_primitive(lltype.Signed, value) cpu.set_future_value_int(j, intvalue) From antocuni at codespeak.net Thu Aug 27 18:29:55 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 18:29:55 +0200 (CEST) Subject: [pypy-svn] r67257 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend/llgraph backend/test backend/x86/test metainterp Message-ID: <20090827162955.E605D16803C@codespeak.net> Author: antocuni Date: Thu Aug 27 18:29:54 2009 New Revision: 67257 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: make history.getkind returning 'ref' instead of 'ptr' or 'obj'; fix a lot of places that used 'p' instead of history.PTR to use the new history.REF instead Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py Thu Aug 27 18:29:54 2009 @@ -8,7 +8,7 @@ from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, ConstObj, - BoxInt, BoxPtr, BoxObj) + BoxInt, BoxPtr, BoxObj, REF) from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.module.support import LLSupport, OOSupport @@ -83,56 +83,56 @@ 'uint_xor' : (('int', 'int'), 'int'), 'uint_rshift' : (('int', 'int'), 'int'), 'same_as' : (('int',), 'int'), # could also be ptr=>ptr - 'new_with_vtable' : (('ptr',), 'ptr'), - 'new' : ((), 'ptr'), - 'new_array' : (('int',), 'ptr'), - 'oononnull' : (('ptr',), 'bool'), - 'ooisnull' : (('ptr',), 'bool'), - 'oois' : (('ptr', 'ptr'), 'bool'), - 'ooisnot' : (('ptr', 'ptr'), 'bool'), - 'instanceof' : (('ptr',), 'bool'), - 'subclassof' : (('ptr', 'ptr'), 'bool'), - 'setfield_gc' : (('ptr', 'intorptr'), None), - 'getfield_gc' : (('ptr',), 'intorptr'), - 'getfield_gc_pure': (('ptr',), 'intorptr'), - 'setfield_raw' : (('ptr', 'intorptr'), None), - 'getfield_raw' : (('ptr',), 'intorptr'), - 'getfield_raw_pure': (('ptr',), 'intorptr'), - 'setarrayitem_gc' : (('ptr', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ptr', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ptr', 'int'), 'intorptr'), - 'arraylen_gc' : (('ptr',), 'int'), - 'call' : (('ptr', 'varargs'), 'intorptr'), - 'call_pure' : (('ptr', 'varargs'), 'intorptr'), + 'new_with_vtable' : (('ref',), 'ref'), + 'new' : ((), 'ref'), + 'new_array' : (('int',), 'ref'), + 'oononnull' : (('ref',), 'bool'), + 'ooisnull' : (('ref',), 'bool'), + 'oois' : (('ref', 'ref'), 'bool'), + 'ooisnot' : (('ref', 'ref'), 'bool'), + 'instanceof' : (('ref',), 'bool'), + 'subclassof' : (('ref', 'ref'), 'bool'), + 'setfield_gc' : (('ref', 'intorptr'), None), + 'getfield_gc' : (('ref',), 'intorptr'), + 'getfield_gc_pure': (('ref',), 'intorptr'), + 'setfield_raw' : (('ref', 'intorptr'), None), + 'getfield_raw' : (('ref',), 'intorptr'), + 'getfield_raw_pure': (('ref',), 'intorptr'), + 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), + 'arraylen_gc' : (('ref',), 'int'), + 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_pure' : (('ref', 'varargs'), 'intorptr'), 'oosend' : (('varargs',), 'intorptr'), 'oosend_pure' : (('varargs',), 'intorptr'), 'guard_true' : (('bool',), None), 'guard_false' : (('bool',), None), 'guard_value' : (('int', 'int'), None), - 'guard_class' : (('ptr', 'ptr'), None), + 'guard_class' : (('ref', 'ref'), None), 'guard_no_exception' : ((), None), - 'guard_exception' : (('ptr',), 'ptr'), + 'guard_exception' : (('ref',), 'ref'), 'guard_no_overflow' : ((), None), 'guard_overflow' : ((), None), - 'newstr' : (('int',), 'ptr'), - 'strlen' : (('ptr',), 'int'), - 'strgetitem' : (('ptr', 'int'), 'int'), - 'strsetitem' : (('ptr', 'int', 'int'), None), - 'newunicode' : (('int',), 'ptr'), - 'unicodelen' : (('ptr',), 'int'), - 'unicodegetitem' : (('ptr', 'int'), 'int'), - 'unicodesetitem' : (('ptr', 'int', 'int'), 'int'), - 'cast_ptr_to_int' : (('ptr',), 'int'), - 'cast_int_to_ptr' : (('int',), 'ptr'), - 'debug_merge_point': (('ptr',), None), - #'getitem' : (('void', 'ptr', 'int'), 'int'), - #'setitem' : (('void', 'ptr', 'int', 'int'), None), - #'newlist' : (('void', 'varargs'), 'ptr'), - #'append' : (('void', 'ptr', 'int'), None), - #'insert' : (('void', 'ptr', 'int', 'int'), None), - #'pop' : (('void', 'ptr',), 'int'), - #'len' : (('void', 'ptr',), 'int'), - #'listnonzero' : (('void', 'ptr',), 'int'), + 'newstr' : (('int',), 'ref'), + 'strlen' : (('ref',), 'int'), + 'strgetitem' : (('ref', 'int'), 'int'), + 'strsetitem' : (('ref', 'int', 'int'), None), + 'newunicode' : (('int',), 'ref'), + 'unicodelen' : (('ref',), 'int'), + 'unicodegetitem' : (('ref', 'int'), 'int'), + 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), + 'cast_ptr_to_int' : (('ref',), 'int'), + 'cast_int_to_ptr' : (('int',), 'ref'), + 'debug_merge_point': (('ref',), None), + #'getitem' : (('void', 'ref', 'int'), 'int'), + #'setitem' : (('void', 'ref', 'int', 'int'), None), + #'newlist' : (('void', 'varargs'), 'ref'), + #'append' : (('void', 'ref', 'int'), None), + #'insert' : (('void', 'ref', 'int', 'int'), None), + #'pop' : (('void', 'ref',), 'int'), + #'len' : (('void', 'ref',), 'int'), + #'listnonzero' : (('void', 'ref',), 'int'), } # ____________________________________________________________ @@ -215,14 +215,14 @@ if tp == "intorptr": TYPE = lltype.typeOf(x) if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - tp = "ptr" + tp = "ref" else: tp = "int" if tp == 'int': return str(x) elif tp == 'void': return '---' - elif tp == 'ptr': + elif tp == 'ref': if not x: return '(* None)' if isinstance(x, int): @@ -624,7 +624,7 @@ # delegating to the builtins do_xxx() (done automatically for simple cases) def op_getarrayitem_gc(self, arraydescr, array, index): - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: return do_getarrayitem_gc_ptr(array, index) else: return do_getarrayitem_gc_int(array, index, self.memocast) @@ -632,7 +632,7 @@ op_getarrayitem_gc_pure = op_getarrayitem_gc def op_getfield_gc(self, fielddescr, struct): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return do_getfield_gc_ptr(struct, fielddescr.ofs) else: return do_getfield_gc_int(struct, fielddescr.ofs, self.memocast) @@ -640,7 +640,7 @@ op_getfield_gc_pure = op_getfield_gc def op_getfield_raw(self, fielddescr, struct): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return do_getfield_raw_ptr(struct, fielddescr.ofs, self.memocast) else: return do_getfield_raw_int(struct, fielddescr.ofs, self.memocast) @@ -657,20 +657,20 @@ return result def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: do_setarrayitem_gc_ptr(array, index, newvalue) else: do_setarrayitem_gc_int(array, index, newvalue, self.memocast) def op_setfield_gc(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: do_setfield_gc_int(struct, fielddescr.ofs, newvalue, self.memocast) def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memocast) else: @@ -681,7 +681,7 @@ _call_args[:] = args if calldescr.typeinfo == 'v': err_result = None - elif calldescr.typeinfo == 'p': + elif calldescr.typeinfo == REF: err_result = lltype.nullptr(llmemory.GCREF.TO) else: assert calldescr.typeinfo == 'i' Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Thu Aug 27 18:29:54 2009 @@ -8,6 +8,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.llinterp import LLInterpreter from pypy.jit.metainterp import history +from pypy.jit.metainterp.history import REF from pypy.jit.metainterp.warmspot import unwrap from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend import model @@ -44,10 +45,10 @@ return self.ofs def is_pointer_field(self): - return self.typeinfo == 'p' + return self.typeinfo == REF def is_array_of_pointers(self): - return self.typeinfo == 'p' + return self.typeinfo == REF def equals(self, other): if not isinstance(other, Descr): @@ -301,7 +302,7 @@ assert isinstance(arraydescr, Descr) array = args[0].getref_base() index = args[1].getint() - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getarrayitem_gc_ptr(array, index)) else: return history.BoxInt(llimpl.do_getarrayitem_gc_int(array, index, @@ -310,7 +311,7 @@ def do_getfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = args[0].getref_base() - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)) else: @@ -320,7 +321,7 @@ def do_getfield_raw(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs, self.memo_cast)) @@ -351,7 +352,7 @@ assert isinstance(arraydescr, Descr) array = args[0].getref_base() index = args[1].getint() - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: newvalue = args[2].getref_base() llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) else: @@ -362,7 +363,7 @@ def do_setfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = args[0].getref_base() - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: newvalue = args[1].getref_base() llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: @@ -373,7 +374,7 @@ def do_setfield_raw(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: newvalue = args[1].getref_base() llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memo_cast) @@ -418,7 +419,7 @@ llimpl.do_call_pushptr(arg.getref_base()) else: llimpl.do_call_pushint(arg.getint()) - if calldescr.typeinfo == 'p': + if calldescr.typeinfo == REF: return history.BoxPtr(llimpl.do_call_ptr(func, self.memo_cast)) elif calldescr.typeinfo == 'i': return history.BoxInt(llimpl.do_call_int(func, self.memo_cast)) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py Thu Aug 27 18:29:54 2009 @@ -36,7 +36,7 @@ self.guard_failed = True if result_type == 'int': return BoxInt(self.cpu.get_latest_value_int(0)) - elif result_type == 'ptr': + elif result_type == 'ref': return BoxPtr(self.cpu.get_latest_value_ref(0)) elif result_type == 'void': return None @@ -49,7 +49,7 @@ result = None elif result_type == 'int': result = BoxInt() - elif result_type == 'ptr': + elif result_type == 'ref': result = BoxPtr() else: raise ValueError(result_type) @@ -306,7 +306,7 @@ 'void', descr=fielddescr2) assert res is None res = self.execute_operation(rop.GETFIELD_GC, [t_box], - 'ptr', descr=fielddescr2) + 'ref', descr=fielddescr2) assert res.value == u_box.value # null_const = self.null_instance().constbox() @@ -314,7 +314,7 @@ 'void', descr=fielddescr2) assert res is None res = self.execute_operation(rop.GETFIELD_GC, [t_box], - 'ptr', descr=fielddescr2) + 'ref', descr=fielddescr2) assert res.value == null_const.value def test_passing_guards(self): @@ -443,7 +443,7 @@ 'void', descr=arraydescr) assert r is None r = self.execute_operation(rop.GETARRAYITEM_GC, [b_box, BoxInt(1)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) assert r.value == a_box.value # # Unsigned should work the same as Signed @@ -529,7 +529,7 @@ r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int') assert r.value == 5 u_box = self.alloc_unicode(u"hello\u1234") - r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ptr') + r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ref') assert r.value == u_box.value @@ -611,12 +611,12 @@ res = self.execute_operation(rop.CAST_PTR_TO_INT, [BoxPtr(x)], 'int').value res2 = self.execute_operation(rop.CAST_INT_TO_PTR, - [BoxInt(res)], 'ptr').value + [BoxInt(res)], 'ref').value x = lltype.cast_opaque_ptr(llmemory.GCREF, x) res = self.execute_operation(rop.CAST_PTR_TO_INT, [ConstPtr(x)], 'int').value res2 = self.execute_operation(rop.CAST_INT_TO_PTR, - [ConstInt(res)], 'ptr').value + [ConstInt(res)], 'ref').value assert res2 == x def test_ooops_non_gc(self): @@ -636,8 +636,8 @@ cpu = self.cpu S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Char)) sizedescr = cpu.sizeof(S) - r1 = self.execute_operation(rop.NEW, [], 'ptr', descr=sizedescr) - r2 = self.execute_operation(rop.NEW, [], 'ptr', descr=sizedescr) + r1 = self.execute_operation(rop.NEW, [], 'ref', descr=sizedescr) + r2 = self.execute_operation(rop.NEW, [], 'ref', descr=sizedescr) assert r1.value != r2.value xdescr = cpu.fielddescrof(S, 'x') ydescr = cpu.fielddescrof(S, 'y') @@ -653,8 +653,8 @@ cpu = self.cpu t_box, T_box = self.alloc_instance(self.T) cpu.set_class_sizes({T_box.value: cpu.sizeof(self.T)}) - r1 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ptr') - r2 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ptr') + r1 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ref') + r2 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ref') assert r1.value != r2.value descr1 = cpu.fielddescrof(self.S, 'chr1') descr2 = cpu.fielddescrof(self.S, 'chr2') @@ -681,24 +681,24 @@ A = lltype.GcArray(lltype.Signed) arraydescr = self.cpu.arraydescrof(A) r1 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) r2 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(A), r1.value) assert a[0] == 0 assert len(a) == 342 def test_new_string(self): - r1 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ptr') - r2 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ptr') + r1 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') + r2 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), r1.value) assert len(a.chars) == 342 def test_new_unicode(self): - r1 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ptr') - r2 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ptr') + r1 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') + r2 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), r1.value) assert len(a.chars) == 342 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_ll_random.py Thu Aug 27 18:29:54 2009 @@ -426,7 +426,7 @@ """ % funcargs).compile() vtableptr = v._hints['vtable']._as_ptr() d = { - 'ptr': S.value, + 'ref': S.value, 'vtable' : vtableptr, 'LLException' : LLException, } Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/test/test_runner.py Thu Aug 27 18:29:54 2009 @@ -143,14 +143,14 @@ self.cpu.assembler.malloc_func_addr = addr ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ - res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 @@ -162,7 +162,7 @@ descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 @@ -170,7 +170,7 @@ # ------------------------------------------------------------ res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], - 'ptr', descr) + 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 @@ -183,7 +183,7 @@ ofs = symbolic.get_field_token(STR, 'chars', False)[0] ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0] - res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref') self.execute_operation(rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void') resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' @@ -198,7 +198,7 @@ itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, @@ -237,7 +237,7 @@ itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs] == chr(10) for i in range(10): @@ -260,7 +260,7 @@ ('c2', lltype.Char), ('c3', lltype.Char)) res = self.execute_operation(rop.NEW, [], - 'ptr', self.cpu.sizeof(TP)) + 'ref', self.cpu.sizeof(TP)) ofs_s = self.cpu.fielddescrof(TP, 's') #ofs_f = self.cpu.fielddescrof(TP, 'f') ofs_u = self.cpu.fielddescrof(TP, 'u') Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 18:29:54 2009 @@ -152,7 +152,7 @@ class DoneWithThisFrameDescrPtr(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): - assert metainterp_sd.result_type == 'ptr' + assert metainterp_sd.result_type == 'ref' resultbox = fail_op.args[0] if isinstance(resultbox, BoxPtr): result = metainterp_sd.cpu.get_latest_value_ref(0) @@ -163,7 +163,7 @@ class DoneWithThisFrameDescrObj(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): - assert metainterp_sd.result_type == 'obj' + assert metainterp_sd.result_type == 'ref' resultbox = fail_op.args[0] if isinstance(resultbox, BoxObj): result = metainterp_sd.cpu.get_latest_value_ref(0) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Thu Aug 27 18:29:54 2009 @@ -33,9 +33,9 @@ if TYPE.TO._gckind == 'raw': return "int" else: - return "ptr" + return "ref" elif isinstance(TYPE, ootype.OOType): - return "obj" + return "ref" else: raise NotImplementedError("type %s not supported" % TYPE) @@ -153,12 +153,8 @@ else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) - elif kind == "ptr": - ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) - return ConstPtr(ptrval) - elif kind == "obj": - obj = ootype.cast_to_object(x) - return ConstObj(obj) + elif kind == "ref": + return cpu.ts.new_ConstRef(x) else: raise NotImplementedError(kind) @@ -388,7 +384,8 @@ if kind == "int": intval = lltype.cast_primitive(lltype.Signed, x) return BoxInt(intval) - elif kind == "ptr": + elif kind == "ref": + # XXX add ootype support? ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) return BoxPtr(ptrval) else: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 18:29:54 2009 @@ -1135,9 +1135,9 @@ raise sd.DoneWithThisFrameVoid() elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) - elif sd.result_type == 'ptr': + elif sd.result_type == 'ref': raise sd.DoneWithThisFramePtr(resultbox.getref_base()) - elif self.cpu.is_oo and sd.result_type == 'obj': + elif self.cpu.is_oo and sd.result_type == 'obj': # XXX raise sd.DoneWithThisFrameObj(resultbox.getref_base()) else: assert False @@ -1445,10 +1445,10 @@ elif sd.result_type == 'int': exits = [exitbox] loops = compile.loops_done_with_this_frame_int - elif sd.result_type == 'ptr': + elif not sd.cpu.is_oo and sd.result_type == 'ref': exits = [exitbox] loops = compile.loops_done_with_this_frame_ptr - elif sd.cpu.is_oo and sd.result_type == 'obj': + elif sd.cpu.is_oo and sd.result_type == 'ref': exits = [exitbox] loops = compile.loops_done_with_this_frame_obj else: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 18:29:54 2009 @@ -41,6 +41,10 @@ BoxRef = history.BoxPtr ConstRef = history.ConstPtr + def new_ConstRef(self, x): + ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) + return history.ConstPtr(ptrval) + def get_typeptr(self, obj): return obj.typeptr @@ -112,6 +116,10 @@ BoxRef = history.BoxObj ConstRef = history.ConstObj + def new_ConstRef(self, x): + obj = ootype.cast_to_object(x) + return history.ConstObj(obj) + def get_typeptr(self, obj): return ootype.classof(obj) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 18:29:54 2009 @@ -454,10 +454,10 @@ assert result_kind == 'int' return lltype.cast_primitive(RESULT, e.result) except DoneWithThisFramePtr, e: - assert result_kind == 'ptr' + assert result_kind == 'ref' return lltype.cast_opaque_ptr(RESULT, e.result) except DoneWithThisFrameObj, e: - assert result_kind == 'obj' + assert result_kind == 'ref' return ootype.cast_from_object(RESULT, e.result) except ExitFrameWithExceptionRef, e: value = ts.cast_to_baseclass(e.value) @@ -689,10 +689,10 @@ def set_future_value(j, value, typecode): cpu = metainterp_sd.cpu - if typecode == 'ptr': + if not cpu.is_oo and typecode == 'ref': ptrvalue = lltype.cast_opaque_ptr(llmemory.GCREF, value) cpu.set_future_value_ref(j, ptrvalue) - elif typecode == 'obj': + elif cpu.is_oo and typecode == 'ref': objvalue = ootype.cast_to_object(value) cpu.set_future_value_ref(j, objvalue) elif typecode == 'int': From antocuni at codespeak.net Thu Aug 27 18:32:57 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 18:32:57 +0200 (CEST) Subject: [pypy-svn] r67258 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827163257.8BF9016803C@codespeak.net> Author: antocuni Date: Thu Aug 27 18:32:56 2009 New Revision: 67258 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Log: oups, forgot to fix this place Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 18:32:56 2009 @@ -1135,9 +1135,9 @@ raise sd.DoneWithThisFrameVoid() elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) - elif sd.result_type == 'ref': + elif not self.cpu.is_oo and sd.result_type == 'ref': raise sd.DoneWithThisFramePtr(resultbox.getref_base()) - elif self.cpu.is_oo and sd.result_type == 'obj': # XXX + elif self.cpu.is_oo and sd.result_type == 'ref': raise sd.DoneWithThisFrameObj(resultbox.getref_base()) else: assert False From antocuni at codespeak.net Thu Aug 27 22:00:53 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 22:00:53 +0200 (CEST) Subject: [pypy-svn] r67259 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827200053.09AE6168044@codespeak.net> Author: antocuni Date: Thu Aug 27 22:00:52 2009 New Revision: 67259 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: unify DoneWithThisFrame{Obj,Ptr} Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 22:00:52 2009 @@ -150,27 +150,17 @@ result = resultbox.getint() raise metainterp_sd.DoneWithThisFrameInt(result) -class DoneWithThisFrameDescrPtr(AbstractDescr): +class DoneWithThisFrameDescrRef(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): assert metainterp_sd.result_type == 'ref' resultbox = fail_op.args[0] - if isinstance(resultbox, BoxPtr): - result = metainterp_sd.cpu.get_latest_value_ref(0) - else: - assert isinstance(resultbox, history.Const) - result = resultbox.getref_base() - raise metainterp_sd.DoneWithThisFramePtr(result) - -class DoneWithThisFrameDescrObj(AbstractDescr): - def handle_fail_op(self, metainterp_sd, fail_op): - assert metainterp_sd.result_type == 'ref' - resultbox = fail_op.args[0] - if isinstance(resultbox, BoxObj): - result = metainterp_sd.cpu.get_latest_value_ref(0) + cpu = metainterp_sd.cpu + if isinstance(resultbox, cpu.ts.BoxRef): + result = cpu.get_latest_value_ref(0) else: assert isinstance(resultbox, history.Const) result = resultbox.getref_base() - raise metainterp_sd.DoneWithThisFrameObj(result) + raise metainterp_sd.DoneWithThisFrameRef(cpu, result) class ExitFrameWithExceptionDescrRef(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): @@ -186,8 +176,7 @@ done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() done_with_this_frame_descr_int = DoneWithThisFrameDescrInt() -done_with_this_frame_descr_ptr = DoneWithThisFrameDescrPtr() -done_with_this_frame_descr_obj = DoneWithThisFrameDescrObj() +done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef() exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef() class TerminatingLoop(TreeLoop): @@ -205,13 +194,13 @@ _loop = TerminatingLoop('done_with_this_frame_ptr') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] -_loop.finishdescr = done_with_this_frame_descr_ptr +_loop.finishdescr = done_with_this_frame_descr_ref loops_done_with_this_frame_ptr = [_loop] _loop = TerminatingLoop('done_with_this_frame_obj') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] -_loop.finishdescr = done_with_this_frame_descr_obj +_loop.finishdescr = done_with_this_frame_descr_ref loops_done_with_this_frame_obj = [_loop] _loop = TerminatingLoop('done_with_this_frame_void') Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 22:00:52 2009 @@ -1135,10 +1135,8 @@ raise sd.DoneWithThisFrameVoid() elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) - elif not self.cpu.is_oo and sd.result_type == 'ref': - raise sd.DoneWithThisFramePtr(resultbox.getref_base()) - elif self.cpu.is_oo and sd.result_type == 'ref': - raise sd.DoneWithThisFrameObj(resultbox.getref_base()) + elif sd.result_type == 'ref': + raise sd.DoneWithThisFrameRef(self.cpu, resultbox.getref_base()) else: assert False Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 22:00:52 2009 @@ -107,6 +107,10 @@ adr = llmemory.cast_ptr_to_adr(ptr) return cpu.cast_adr_to_int(adr) + def cast_opaque_ptr(self, TYPE, value): + return lltype.cast_opaque_ptr(TYPE, value) + cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + class OOTypeHelper(TypeSystemHelper): @@ -177,5 +181,9 @@ def cast_baseclass_to_hashable(self, cpu, obj): return ootype.cast_to_object(obj) + def cast_opaque_ptr(self, TYPE, value): + return ootype.cast_from_object(TYPE, value) + cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + llhelper = LLTypeHelper() oohelper = OOTypeHelper() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 22:00:52 2009 @@ -385,19 +385,12 @@ def __str__(self): return 'DoneWithThisFrameInt(%s)' % (self.result,) - class DoneWithThisFramePtr(JitException): - def __init__(self, result): - assert lltype.typeOf(result) == llmemory.GCREF + class DoneWithThisFrameRef(JitException): + def __init__(self, cpu, result): + assert lltype.typeOf(result) == cpu.ts.BASETYPE self.result = result def __str__(self): - return 'DoneWithThisFramePtr(%s)' % (self.result,) - - class DoneWithThisFrameObj(JitException): - def __init__(self, result): - assert ootype.typeOf(result) == ootype.Object - self.result = result - def __str__(self): - return 'DoneWithThisFrameObj(%s)' % (self.result,) + return 'DoneWithThisFrameRef(%s)' % (self.result,) class ExitFrameWithExceptionRef(JitException): def __init__(self, cpu, value): @@ -421,14 +414,12 @@ self.DoneWithThisFrameVoid = DoneWithThisFrameVoid self.DoneWithThisFrameInt = DoneWithThisFrameInt - self.DoneWithThisFramePtr = DoneWithThisFramePtr - self.DoneWithThisFrameObj = DoneWithThisFrameObj + self.DoneWithThisFrameRef = DoneWithThisFrameRef self.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.ContinueRunningNormally = ContinueRunningNormally self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt - self.metainterp_sd.DoneWithThisFramePtr = DoneWithThisFramePtr - self.metainterp_sd.DoneWithThisFrameObj = DoneWithThisFrameObj + self.metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally rtyper = self.translator.rtyper @@ -453,12 +444,9 @@ except DoneWithThisFrameInt, e: assert result_kind == 'int' return lltype.cast_primitive(RESULT, e.result) - except DoneWithThisFramePtr, e: - assert result_kind == 'ref' - return lltype.cast_opaque_ptr(RESULT, e.result) - except DoneWithThisFrameObj, e: + except DoneWithThisFrameRef, e: assert result_kind == 'ref' - return ootype.cast_from_object(RESULT, e.result) + return ts.cast_opaque_ptr(RESULT, e.result) except ExitFrameWithExceptionRef, e: value = ts.cast_to_baseclass(e.value) if not we_are_translated(): From antocuni at codespeak.net Thu Aug 27 22:07:36 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 22:07:36 +0200 (CEST) Subject: [pypy-svn] r67260 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827200736.772B916804A@codespeak.net> Author: antocuni Date: Thu Aug 27 22:07:35 2009 New Revision: 67260 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Log: unify Box.changevalue_{obj,ptr} and get rid of a couple of is_oo Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 22:07:35 2009 @@ -256,12 +256,9 @@ if isinstance(box, BoxInt): srcvalue = cpu.get_latest_value_int(i) box.changevalue_int(srcvalue) - elif not cpu.is_oo and isinstance(box, BoxPtr): + elif isinstance(box, cpu.ts.BoxRef): srcvalue = cpu.get_latest_value_ref(i) - box.changevalue_ptr(srcvalue) - elif cpu.is_oo and isinstance(box, BoxObj): - srcvalue = cpu.get_latest_value_ref(i) - box.changevalue_obj(srcvalue) + box.changevalue_ref(srcvalue) elif isinstance(box, Const): pass # we don't need to do anything else: @@ -274,12 +271,10 @@ dstbox = fail_op.args[i] if isinstance(dstbox, BoxInt): dstbox.changevalue_int(srcbox.getint()) - elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr): - dstbox.changevalue_ptr(srcbox.getref_base()) + elif isinstance(dstbox, metainterp_sd.cpu.ts.BoxRef): + dstbox.changevalue_ref(srcbox.getref_base()) elif isinstance(dstbox, Const): pass - elif metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxObj): - dstbox.changevalue_obj(srcbox.getref_base()) else: assert False Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/history.py Thu Aug 27 22:07:35 2009 @@ -503,10 +503,10 @@ return repr_rpython(self, 'bp') def changevalue_box(self, srcbox): - self.changevalue_ptr(srcbox.getref_base()) + self.changevalue_ref(srcbox.getref_base()) _getrepr_ = repr_pointer - changevalue_ptr = __init__ + changevalue_ref = __init__ NULLBOX = BoxPtr() @@ -548,10 +548,10 @@ return repr_rpython(self, 'bo') def changevalue_box(self, srcbox): - self.changevalue_obj(srcbox.getref_base()) + self.changevalue_ref(srcbox.getref_base()) _getrepr_ = repr_object - changevalue_obj = __init__ + changevalue_ref = __init__ def set_future_values(cpu, boxes): From antocuni at codespeak.net Thu Aug 27 22:12:02 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 22:12:02 +0200 (CEST) Subject: [pypy-svn] r67261 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827201202.AC7CF168052@codespeak.net> Author: antocuni Date: Thu Aug 27 22:12:02 2009 New Revision: 67261 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: get rid of one more is_oo Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 22:12:02 2009 @@ -714,10 +714,7 @@ def opimpl_indirect_call(self, pc, indirectcallset, box, varargs): box = self.implement_guard_value(pc, box) cpu = self.metainterp.cpu - if cpu.is_oo: - key = box.getref_base() - else: - key = box.getaddr(cpu) + key = cpu.ts.getaddr_for_box(cpu, box) jitcode = indirectcallset.bytecode_for_address(key) f = self.metainterp.newframe(jitcode) f.setup_call(varargs) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 22:12:02 2009 @@ -111,6 +111,8 @@ return lltype.cast_opaque_ptr(TYPE, value) cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + def getaddr_for_box(self, cpu, box): + return box.getaddr(cpu) class OOTypeHelper(TypeSystemHelper): @@ -185,5 +187,8 @@ return ootype.cast_from_object(TYPE, value) cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + def getaddr_for_box(self, cpu, box): + return box.getref_base() + llhelper = LLTypeHelper() oohelper = OOTypeHelper() From antocuni at codespeak.net Thu Aug 27 22:19:05 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 22:19:05 +0200 (CEST) Subject: [pypy-svn] r67262 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827201905.CDE30168057@codespeak.net> Author: antocuni Date: Thu Aug 27 22:19:02 2009 New Revision: 67262 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: unify loops_done_with_this_frame_{obj,ptr} and loops_exit_frame_with_exception_{obj,ptr} Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/compile.py Thu Aug 27 22:19:02 2009 @@ -10,6 +10,7 @@ Const from pypy.jit.metainterp import history from pypy.jit.metainterp.specnode import NotSpecNode +from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.debug import debug_print def compile_new_loop(metainterp, old_loops, greenkey, start=0): @@ -191,17 +192,17 @@ _loop.finishdescr = done_with_this_frame_descr_int loops_done_with_this_frame_int = [_loop] -_loop = TerminatingLoop('done_with_this_frame_ptr') +_loop = TerminatingLoop('done_with_this_frame_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] _loop.finishdescr = done_with_this_frame_descr_ref -loops_done_with_this_frame_ptr = [_loop] +llhelper.loops_done_with_this_frame_ref = [_loop] -_loop = TerminatingLoop('done_with_this_frame_obj') +_loop = TerminatingLoop('done_with_this_frame_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] _loop.finishdescr = done_with_this_frame_descr_ref -loops_done_with_this_frame_obj = [_loop] +oohelper.loops_done_with_this_frame_ref = [_loop] _loop = TerminatingLoop('done_with_this_frame_void') _loop.specnodes = [] @@ -209,17 +210,17 @@ _loop.finishdescr = done_with_this_frame_descr_void loops_done_with_this_frame_void = [_loop] -_loop = TerminatingLoop('exit_frame_with_exception_ptr') +_loop = TerminatingLoop('exit_frame_with_exception_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] _loop.finishdescr = exit_frame_with_exception_descr_ref -loops_exit_frame_with_exception_ptr = [_loop] +llhelper.loops_exit_frame_with_exception_ref = [_loop] -_loop = TerminatingLoop('exit_frame_with_exception_obj') +_loop = TerminatingLoop('exit_frame_with_exception_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] _loop.finishdescr = exit_frame_with_exception_descr_ref -loops_exit_frame_with_exception_obj = [_loop] +oohelper.loops_exit_frame_with_exception_ref = [_loop] del _loop Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Thu Aug 27 22:19:02 2009 @@ -1440,12 +1440,9 @@ elif sd.result_type == 'int': exits = [exitbox] loops = compile.loops_done_with_this_frame_int - elif not sd.cpu.is_oo and sd.result_type == 'ref': + elif sd.result_type == 'ref': exits = [exitbox] - loops = compile.loops_done_with_this_frame_ptr - elif sd.cpu.is_oo and sd.result_type == 'ref': - exits = [exitbox] - loops = compile.loops_done_with_this_frame_obj + loops = sd.cpu.ts.loops_done_with_this_frame_ref else: assert False self.history.record(rop.JUMP, exits, None) @@ -1456,10 +1453,7 @@ self.gen_store_back_in_virtualizable() # temporarily put a JUMP to a pseudo-loop self.history.record(rop.JUMP, [valuebox], None) - if self.cpu.is_oo: - loops = compile.loops_exit_frame_with_exception_obj - else: - loops = compile.loops_exit_frame_with_exception_ptr + loops = self.cpu.ts.loops_exit_frame_with_exception_ref target_loop = compile.compile_new_bridge(self, loops, self.resumekey) assert target_loop is loops[0] Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 22:19:02 2009 @@ -40,6 +40,7 @@ BASETYPE = llmemory.GCREF BoxRef = history.BoxPtr ConstRef = history.ConstPtr + loops_done_with_this_frame_ref = None # patched by compile.py def new_ConstRef(self, x): ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) @@ -121,7 +122,8 @@ BASETYPE = ootype.Object BoxRef = history.BoxObj ConstRef = history.ConstObj - + loops_done_with_this_frame_ref = None # patched by compile.py + def new_ConstRef(self, x): obj = ootype.cast_to_object(x) return history.ConstObj(obj) From antocuni at codespeak.net Thu Aug 27 22:26:25 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 22:26:25 +0200 (CEST) Subject: [pypy-svn] r67263 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827202625.B8006168013@codespeak.net> Author: antocuni Date: Thu Aug 27 22:26:24 2009 New Revision: 67263 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Log: remove last is_oos from warmspot.py Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 22:26:24 2009 @@ -108,10 +108,13 @@ adr = llmemory.cast_ptr_to_adr(ptr) return cpu.cast_adr_to_int(adr) - def cast_opaque_ptr(self, TYPE, value): + def cast_from_ref(self, TYPE, value): return lltype.cast_opaque_ptr(TYPE, value) - cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + cast_from_ref._annspecialcase_ = 'specialize:arg(1)' + def cast_to_ref(self, value): + return lltype.cast_opaque_ptr(llmemory.GCREF, value) + def getaddr_for_box(self, cpu, box): return box.getaddr(cpu) @@ -185,9 +188,12 @@ def cast_baseclass_to_hashable(self, cpu, obj): return ootype.cast_to_object(obj) - def cast_opaque_ptr(self, TYPE, value): + def cast_from_ref(self, TYPE, value): return ootype.cast_from_object(TYPE, value) - cast_opaque_ptr._annspecialcase_ = 'specialize:arg(1)' + cast_from_ref._annspecialcase_ = 'specialize:arg(1)' + + def cast_to_ref(self, value): + return ootype.cast_to_object(value) def getaddr_for_box(self, cpu, box): return box.getref_base() Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/warmspot.py Thu Aug 27 22:26:24 2009 @@ -425,7 +425,6 @@ rtyper = self.translator.rtyper RESULT = PORTALFUNC.RESULT result_kind = history.getkind(RESULT) - is_oo = self.cpu.is_oo ts = self.cpu.ts def ll_portal_runner(*args): @@ -446,7 +445,7 @@ return lltype.cast_primitive(RESULT, e.result) except DoneWithThisFrameRef, e: assert result_kind == 'ref' - return ts.cast_opaque_ptr(RESULT, e.result) + return ts.cast_from_ref(RESULT, e.result) except ExitFrameWithExceptionRef, e: value = ts.cast_to_baseclass(e.value) if not we_are_translated(): @@ -677,12 +676,9 @@ def set_future_value(j, value, typecode): cpu = metainterp_sd.cpu - if not cpu.is_oo and typecode == 'ref': - ptrvalue = lltype.cast_opaque_ptr(llmemory.GCREF, value) - cpu.set_future_value_ref(j, ptrvalue) - elif cpu.is_oo and typecode == 'ref': - objvalue = ootype.cast_to_object(value) - cpu.set_future_value_ref(j, objvalue) + if typecode == 'ref': + refvalue = cpu.ts.cast_to_ref(value) + cpu.set_future_value_ref(j, refvalue) elif typecode == 'int': intvalue = lltype.cast_primitive(lltype.Signed, value) cpu.set_future_value_int(j, intvalue) From benjamin at codespeak.net Thu Aug 27 23:41:15 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 27 Aug 2009 23:41:15 +0200 (CEST) Subject: [pypy-svn] r67264 - in pypy/trunk/pypy: . tool/pytest/test Message-ID: <20090827214115.025E616803E@codespeak.net> Author: benjamin Date: Thu Aug 27 23:41:14 2009 New Revision: 67264 Modified: pypy/trunk/pypy/conftest.py pypy/trunk/pypy/tool/pytest/test/test_appsupport.py Log: fix app tests using raises with a string instead of a callable argument and I thought just using sys._getframe() was bad enough... :( Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Thu Aug 27 23:41:14 2009 @@ -189,10 +189,17 @@ # # -def _pytest_raises_wrapper(*args, **kwargs): +def _pytest_raises_wrapper(*__args, **__kwargs): """Emulate the API of appsupport.pypyraises.""" __tracebackhide__ = True - return py.test.raises(*args, **kwargs)._excinfo + # Horrible, nasty, terrible, hideous, ugly hack to help another one. + if len(__args) == 2 and isinstance(__args[1], str): + me = sys._getframe() + them = sys._getframe(1) + me.f_globals.update(them.f_globals) + me.f_locals.update(them.f_locals) + del me, them + return py.test.raises(*__args, **__kwargs)._excinfo def ensure_pytest_builtin_helpers(helpers='skip'.split()): """ hack (py.test.) raises and skip into builtins, needed Modified: pypy/trunk/pypy/tool/pytest/test/test_appsupport.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/test/test_appsupport.py (original) +++ pypy/trunk/pypy/tool/pytest/test/test_appsupport.py Thu Aug 27 23:41:14 2009 @@ -4,3 +4,6 @@ info = raises(TypeError, id) assert info[0] is TypeError assert isinstance(info[1], TypeError) + + x = 43 + raises(ZeroDivisionError, "x/0") From antocuni at codespeak.net Thu Aug 27 23:42:30 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 23:42:30 +0200 (CEST) Subject: [pypy-svn] r67265 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827214230.76B4E16803E@codespeak.net> Author: antocuni Date: Thu Aug 27 23:42:29 2009 New Revision: 67265 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Log: get rid of the various is_oo in virtualizable.py Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 23:42:29 2009 @@ -1,6 +1,8 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, llstr, oostr +from pypy.rpython.annlowlevel import cast_instance_to_base_ptr +from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.jit.metainterp import history from pypy.jit.metainterp import history @@ -37,11 +39,16 @@ name = 'lltype' functionptr = staticmethod(lltype.functionptr) + nullptr = staticmethod(lltype.nullptr) + cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) BASETYPE = llmemory.GCREF BoxRef = history.BoxPtr ConstRef = history.ConstPtr loops_done_with_this_frame_ref = None # patched by compile.py + from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR as VABLERTI + null_vable_rti = lltype.nullptr(VABLERTI.TO) + def new_ConstRef(self, x): ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) return history.ConstPtr(ptrval) @@ -54,6 +61,13 @@ FUNCPTRTYPE = lltype.Ptr(FUNCTYPE) return FUNCTYPE, FUNCPTRTYPE + def get_superclass(self, TYPE): + return lltype.Ptr(TYPE.TO._first_struct()[1]) + + def cast_to_instance_maybe(self, TYPE, instance): + return lltype.cast_pointer(TYPE, instance) + cast_to_instance_maybe._annspecialcase_ = 'specialize:arg(1)' + def cast_fnptr_to_root(self, fnptr): return llmemory.cast_ptr_to_adr(fnptr) @@ -122,11 +136,16 @@ name = 'ootype' functionptr = staticmethod(ootype.static_meth) + nullptr = staticmethod(ootype.null) + cast_instance_to_base_ref = staticmethod(cast_instance_to_base_obj) BASETYPE = ootype.Object BoxRef = history.BoxObj ConstRef = history.ConstObj loops_done_with_this_frame_ref = None # patched by compile.py + from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI + null_vable_rti = ootype.make_null_instance(VABLERTI) + def new_ConstRef(self, x): obj = ootype.cast_to_object(x) return history.ConstObj(obj) @@ -138,6 +157,13 @@ FUNCTYPE = ootype.StaticMethod(ARGS, RESULT) return FUNCTYPE, FUNCTYPE + def get_superclass(self, TYPE): + return TYPE._superclass + + def cast_to_instance_maybe(self, TYPE, instance): + return instance + cast_to_instance_maybe._annspecialcase_ = 'specialize:arg(1)' + def cast_fnptr_to_root(self, fnptr): return ootype.cast_to_object(fnptr) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Thu Aug 27 23:42:29 2009 @@ -1,12 +1,10 @@ from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype -from pypy.rpython.annlowlevel import cast_instance_to_base_ptr -from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.rpython.annlowlevel import cast_base_ptr_to_instance from pypy.rpython import rvirtualizable2 from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.typesystem import deref +from pypy.jit.metainterp.typesystem import deref, fieldType, arrayItem from pypy.jit.metainterp import history from pypy.jit.metainterp.warmspot import wrap, unwrap @@ -16,17 +14,10 @@ self.warmrunnerdesc = warmrunnerdesc jitdriver = warmrunnerdesc.jitdriver cpu = warmrunnerdesc.cpu - self.is_oo = cpu.is_oo - if not self.is_oo: - from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR - self.VABLERTI = VABLERTIPTR - self.null_vable_rti = lltype.nullptr(VABLERTIPTR.TO) - self.BoxArray = history.BoxPtr - else: - from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI - self.VABLERTI = VABLERTI - self.null_vable_rti = ootype.make_null_instance(VABLERTI) - self.BoxArray = history.BoxObj + self.cpu = cpu + self.VABLERTI = cpu.ts.VABLERTI + self.null_vable_rti = cpu.ts.null_vable_rti + self.BoxArray = cpu.ts.BoxRef # assert len(jitdriver.virtualizables) == 1 # for now [vname] = jitdriver.virtualizables @@ -34,16 +25,10 @@ self.index_of_virtualizable = index VTYPEPTR = warmrunnerdesc.JIT_ENTER_FUNCTYPE.ARGS[index] while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints: - if not self.is_oo: - VTYPEPTR = lltype.Ptr(VTYPEPTR.TO._first_struct()[1]) - else: - VTYPEPTR = VTYPEPTR._superclass + VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR) self.VTYPEPTR = VTYPEPTR self.VTYPE = VTYPE = deref(VTYPEPTR) - if not self.is_oo: - self.null_vable = lltype.nullptr(VTYPE) - else: - self.null_vable = ootype.null(VTYPE) + self.null_vable = cpu.ts.nullptr(VTYPE) # accessor = VTYPE._hints['virtualizable2_accessor'] all_fields = accessor.fields @@ -57,26 +42,16 @@ self.static_fields = static_fields self.array_fields = array_fields # - if not self.is_oo: # lltype - assert isinstance(VTYPEPTR, lltype.Ptr) - FIELDTYPES = [getattr(VTYPE, name) for name in static_fields] - ARRAYITEMTYPES = [] - for name in array_fields: - ARRAYPTR = getattr(VTYPE, name) - assert isinstance(ARRAYPTR, lltype.Ptr) - assert isinstance(ARRAYPTR.TO, lltype.GcArray) - ARRAYITEMTYPES.append(ARRAYPTR.TO.OF) - self.array_descrs = [cpu.arraydescrof(getattr(VTYPE, name).TO) - for name in array_fields] - else: # ootype - FIELDTYPES = [VTYPE._field_type(name) for name in static_fields] - ARRAYITEMTYPES = [] - for name in array_fields: - ARRAY = VTYPE._field_type(name) - assert isinstance(ARRAY, ootype.Array) - ARRAYITEMTYPES.append(ARRAY.ITEM) - self.array_descrs = [cpu.arraydescrof(VTYPE._field_type(name)) - for name in array_fields] + FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields] + ARRAYITEMTYPES = [] + for name in array_fields: + ARRAYPTR = fieldType(VTYPE, name) + ARRAY = deref(ARRAYPTR) + assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array)) + assert isinstance(ARRAY, (lltype.GcArray, ootype.Array)) + ARRAYITEMTYPES.append(arrayItem(ARRAY)) + self.array_descrs = [cpu.arraydescrof(deref(fieldType(VTYPE, name))) + for name in array_fields] # self.num_static_extra_boxes = len(static_fields) self.num_arrays = len(array_fields) @@ -185,16 +160,10 @@ all_graphs, self.VTYPEPTR, funcptr) def unwrap_virtualizable_box(self, virtualizable_box): - if not self.is_oo: - return virtualizable_box.getref(self.VTYPEPTR) - else: - return virtualizable_box.getref(self.VTYPE) + return virtualizable_box.getref(self.VTYPEPTR) def cast_to_vtype(self, virtualizable): - if not self.is_oo: - return lltype.cast_pointer(self.VTYPEPTR, virtualizable) - else: - return virtualizable + return self.cpu.ts.cast_to_instance_maybe(self.VTYPEPTR, virtualizable) cast_to_vtype._annspecialcase_ = 'specialize:ll' def is_vtypeptr(self, TYPE): @@ -202,10 +171,7 @@ def cast_instance_to_base_ptr(self, vable_rti): if we_are_translated(): - if not self.is_oo: - return cast_instance_to_base_ptr(vable_rti) - else: - return cast_instance_to_base_obj(vable_rti) + return self.cpu.ts.cast_instance_to_base_ref(vable_rti) else: vable_rti._TYPE = self.VABLERTI # hack for non-translated mode return vable_rti From antocuni at codespeak.net Thu Aug 27 23:48:12 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 23:48:12 +0200 (CEST) Subject: [pypy-svn] r67266 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827214812.4A18616803E@codespeak.net> Author: antocuni Date: Thu Aug 27 23:48:10 2009 New Revision: 67266 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: rpython fix Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 23:48:10 2009 @@ -128,6 +128,7 @@ def cast_to_ref(self, value): return lltype.cast_opaque_ptr(llmemory.GCREF, value) + cast_to_ref._annspecialcase_ = 'specialize:ll' def getaddr_for_box(self, cpu, box): return box.getaddr(cpu) @@ -220,6 +221,7 @@ def cast_to_ref(self, value): return ootype.cast_to_object(value) + cast_to_ref._annspecialcase_ = 'specialize:ll' def getaddr_for_box(self, cpu, box): return box.getref_base() From antocuni at codespeak.net Thu Aug 27 23:57:55 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 27 Aug 2009 23:57:55 +0200 (CEST) Subject: [pypy-svn] r67267 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090827215755.4502E16803E@codespeak.net> Author: antocuni Date: Thu Aug 27 23:57:54 2009 New Revision: 67267 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: get rid of is_oos in optimizeopt.py Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/optimizeopt.py Thu Aug 27 23:57:54 2009 @@ -8,6 +8,7 @@ from pypy.jit.metainterp.specnode import VirtualStructSpecNode from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs from pypy.jit.metainterp import resume, compile +from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype @@ -124,8 +125,8 @@ self.box = box CVAL_ZERO = ConstantValue(ConstInt(0)) -CVAL_NULLPTR = ConstantValue(ConstPtr(ConstPtr.value)) -CVAL_NULLOBJ = ConstantValue(ConstObj(ConstObj.value)) +llhelper.CVAL_NULLREF = ConstantValue(ConstPtr(ConstPtr.value)) +oohelper.CVAL_NULLREF = ConstantValue(ConstObj(ConstObj.value)) class AbstractVirtualValue(OptValue): @@ -399,10 +400,7 @@ return value def new_ptr_box(self): - if not self.cpu.is_oo: - return BoxPtr() - else: - return BoxObj() + return self.cpu.ts.BoxRef() def new_box(self, fieldofs): if fieldofs.is_pointer_field(): @@ -412,10 +410,7 @@ def new_const(self, fieldofs): if fieldofs.is_pointer_field(): - if not self.cpu.is_oo: - return CVAL_NULLPTR - else: - return CVAL_NULLOBJ + return self.cpu.ts.CVAL_NULLREF else: return CVAL_ZERO @@ -427,10 +422,7 @@ def new_const_item(self, arraydescr): if arraydescr.is_array_of_pointers(): - if not self.cpu.is_oo: - return CVAL_NULLPTR - else: - return CVAL_NULLOBJ + return self.cpu.ts.CVAL_NULLREF else: return CVAL_ZERO Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Thu Aug 27 23:57:54 2009 @@ -45,6 +45,7 @@ BoxRef = history.BoxPtr ConstRef = history.ConstPtr loops_done_with_this_frame_ref = None # patched by compile.py + CVAL_NULLREF = None # patched by optimizeopt.py from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR as VABLERTI null_vable_rti = lltype.nullptr(VABLERTI.TO) @@ -143,6 +144,7 @@ BoxRef = history.BoxObj ConstRef = history.ConstObj loops_done_with_this_frame_ref = None # patched by compile.py + CVAL_NULLREF = None # patched by optimizeopt.py from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI null_vable_rti = ootype.make_null_instance(VABLERTI) From antocuni at codespeak.net Fri Aug 28 00:05:28 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 28 Aug 2009 00:05:28 +0200 (CEST) Subject: [pypy-svn] r67268 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend: cli llgraph Message-ID: <20090827220528.1BD79168039@codespeak.net> Author: antocuni Date: Fri Aug 28 00:05:27 2009 New Revision: 67268 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Log: these changes belong to r67257 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py Fri Aug 28 00:05:27 2009 @@ -321,7 +321,7 @@ self.instanceof = instanceof self.ooclass = get_class_for_type(TYPE) self.typename = TYPE._short_name() - self._is_array_of_pointers = (history.getkind(TYPE) == 'obj') + self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') def is_array_of_pointers(self): # for arrays, TYPE is the type of the array item. @@ -456,7 +456,7 @@ self.selfclass = ootype.runtimeClass(TYPE) self.fieldname = fieldname self.key = key_manager.getkey((TYPE, fieldname)) - self._is_pointer_field = (history.getkind(T) == 'obj') + self._is_pointer_field = (history.getkind(T) == 'ref') def is_pointer_field(self): return self._is_pointer_field Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Fri Aug 28 00:05:27 2009 @@ -695,7 +695,7 @@ self.setarrayitem = setarrayitem self.getarraylength = getarraylength self.instanceof = instanceof - self._is_array_of_pointers = (history.getkind(TYPE) == 'obj') + self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') def is_array_of_pointers(self): # for arrays, TYPE is the type of the array item. @@ -725,7 +725,7 @@ self.getfield = getfield self.setfield = setfield - self._is_pointer_field = (history.getkind(T) == 'obj') + self._is_pointer_field = (history.getkind(T) == 'ref') def sort_key(self): return self._keys.getkey((self.TYPE, self.fieldname)) From pedronis at codespeak.net Fri Aug 28 12:18:19 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Aug 2009 12:18:19 +0200 (CEST) Subject: [pypy-svn] r67271 - in pypy/trunk/pypy: . module/_ast/test tool/pytest tool/pytest/test Message-ID: <20090828101819.13BCB16803D@codespeak.net> Author: pedronis Date: Fri Aug 28 12:18:18 2009 New Revision: 67271 Modified: pypy/trunk/pypy/conftest.py pypy/trunk/pypy/module/_ast/test/test_ast.py pypy/trunk/pypy/tool/pytest/appsupport.py pypy/trunk/pypy/tool/pytest/test/test_appsupport.py Log: rework 67264, 67182 make the app-level test 'raises' have an interface which is a subset of the py.lib one, avoids having to wrap the latter in the -A case which avoids some silliness. adjusted test_appsupport.py Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Fri Aug 28 12:18:18 2009 @@ -189,27 +189,13 @@ # # -def _pytest_raises_wrapper(*__args, **__kwargs): - """Emulate the API of appsupport.pypyraises.""" - __tracebackhide__ = True - # Horrible, nasty, terrible, hideous, ugly hack to help another one. - if len(__args) == 2 and isinstance(__args[1], str): - me = sys._getframe() - them = sys._getframe(1) - me.f_globals.update(them.f_globals) - me.f_locals.update(them.f_locals) - del me, them - return py.test.raises(*__args, **__kwargs)._excinfo - -def ensure_pytest_builtin_helpers(helpers='skip'.split()): +def ensure_pytest_builtin_helpers(helpers='skip raises'.split()): """ hack (py.test.) raises and skip into builtins, needed for applevel tests to run directly on cpython but apparently earlier on "raises" was already added to module's globals. """ import __builtin__ - if not hasattr(__builtin__, "raises"): - __builtin__.raises = _pytest_raises_wrapper for helper in helpers: if not hasattr(__builtin__, helper): setattr(__builtin__, helper, getattr(py.test, helper)) Modified: pypy/trunk/pypy/module/_ast/test/test_ast.py ============================================================================== --- pypy/trunk/pypy/module/_ast/test/test_ast.py (original) +++ pypy/trunk/pypy/module/_ast/test/test_ast.py Fri Aug 28 12:18:18 2009 @@ -56,13 +56,13 @@ return compile(node, "", "exec") mod = ast.Module() raises(AttributeError, getattr, mod, "body") - exc = raises(TypeError, com, mod)[1] + exc = raises(TypeError, com, mod).value assert str(exc) == "required attribute 'body' missing from Module" expr = ast.Name() expr.id = "hi" expr.ctx = ast.Load() expr.lineno = 4 - exc = raises(TypeError, com, ast.Module([ast.Expr(expr, 0, 0)]))[1] + exc = raises(TypeError, com, ast.Module([ast.Expr(expr, 0, 0)])).value assert str(exc) == "required attribute 'col_offset' missing from Name" def test_int(self): @@ -156,7 +156,7 @@ assert fr.body is body assert fr.lineno == 0 assert fr.col_offset == 1 - exc = raises(TypeError, ast.Module, 1, 2)[1] + exc = raises(TypeError, ast.Module, 1, 2).value msg = str(exc) assert msg == "Module constructor takes 0 or 1 positional arguments" raises(AttributeError, ast.Module, nothing=23) Modified: pypy/trunk/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/appsupport.py (original) +++ pypy/trunk/pypy/tool/pytest/appsupport.py Fri Aug 28 12:18:18 2009 @@ -189,8 +189,17 @@ frame = space.getexecutioncontext().framestack.top() old = frame.last_exception frame.last_exception = err + if not hasattr(space, '_w_ExceptionInfo'): + space._w_ExceptionInfo = space.appexec([], """(): + class _ExceptionInfo(object): + def __init__(self): + import sys + self.type, self.value, _ = sys.exc_info() + + return _ExceptionInfo +""") try: - return space.sys.call("exc_info") + return space.call_function(space._w_ExceptionInfo) finally: frame.last_exception = old Modified: pypy/trunk/pypy/tool/pytest/test/test_appsupport.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/test/test_appsupport.py (original) +++ pypy/trunk/pypy/tool/pytest/test/test_appsupport.py Fri Aug 28 12:18:18 2009 @@ -2,8 +2,10 @@ def app_test_raises(): info = raises(TypeError, id) - assert info[0] is TypeError - assert isinstance(info[1], TypeError) + assert info.type is TypeError + assert isinstance(info.value, TypeError) x = 43 - raises(ZeroDivisionError, "x/0") + info = raises(ZeroDivisionError, "x/0") + assert info.type is ZeroDivisionError + assert isinstance(info.value, ZeroDivisionError) From pedronis at codespeak.net Fri Aug 28 14:01:50 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Aug 2009 14:01:50 +0200 (CEST) Subject: [pypy-svn] r67272 - in pypy/trunk/pypy/lib: . test2 Message-ID: <20090828120150.5160B168045@codespeak.net> Author: pedronis Date: Fri Aug 28 14:01:49 2009 New Revision: 67272 Removed: pypy/trunk/pypy/lib/optimizers.py pypy/trunk/pypy/lib/test2/test_optimizers.py Log: this code is not applicable anymore From pedronis at codespeak.net Fri Aug 28 14:10:17 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Aug 2009 14:10:17 +0200 (CEST) Subject: [pypy-svn] r67273 - pypy/trunk/pypy/doc/config Message-ID: <20090828121017.B60EE16804C@codespeak.net> Author: pedronis Date: Fri Aug 28 14:10:16 2009 New Revision: 67273 Added: pypy/trunk/pypy/doc/config/objspace.usemodules._ast.txt (contents, props changed) pypy/trunk/pypy/doc/config/objspace.usemodules.parser.txt (contents, props changed) pypy/trunk/pypy/doc/config/objspace.usemodules.token.txt (contents, props changed) Removed: pypy/trunk/pypy/doc/config/objspace.usemodules.recparser.txt Log: fix doc/config Added: pypy/trunk/pypy/doc/config/objspace.usemodules._ast.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/objspace.usemodules._ast.txt Fri Aug 28 14:10:16 2009 @@ -0,0 +1,2 @@ +Use the '_ast' module. +This module is expected to be working and is included by default. Added: pypy/trunk/pypy/doc/config/objspace.usemodules.parser.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/objspace.usemodules.parser.txt Fri Aug 28 14:10:16 2009 @@ -0,0 +1,4 @@ +Use the 'parser' module. +This is PyPy implementation of the standard library 'parser' module (e.g. if +this option is enabled and you say ``import parser`` you get this module). +It is enabled by default. Added: pypy/trunk/pypy/doc/config/objspace.usemodules.token.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/objspace.usemodules.token.txt Fri Aug 28 14:10:16 2009 @@ -0,0 +1,2 @@ +Use the 'token' module. +This module is expected to be working and is included by default. From pedronis at codespeak.net Fri Aug 28 14:14:55 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Aug 2009 14:14:55 +0200 (CEST) Subject: [pypy-svn] r67274 - pypy/trunk/pypy/doc Message-ID: <20090828121455.4EC4B168035@codespeak.net> Author: pedronis Date: Fri Aug 28 14:14:54 2009 New Revision: 67274 Modified: pypy/trunk/pypy/doc/cpython_differences.txt Log: fix this doc file Modified: pypy/trunk/pypy/doc/cpython_differences.txt ============================================================================== --- pypy/trunk/pypy/doc/cpython_differences.txt (original) +++ pypy/trunk/pypy/doc/cpython_differences.txt Fri Aug 28 14:14:54 2009 @@ -31,7 +31,6 @@ bz2 cStringIO crypt - `dyngram`_ errno exceptions fcntl @@ -42,9 +41,9 @@ md5 mmap operator + parser posix pyexpat - recparser select sha signal @@ -54,6 +53,7 @@ termios thread time + token unicodedata zipimport zlib @@ -85,7 +85,6 @@ .. _`__pypy__`: __pypy__-module.html .. _`_rawffi`: ctypes-implementation.html .. _`_minimal_curses`: config/objspace.usemodules._minimal_curses.html -.. _`dyngram`: config/objspace.usemodules.dyngram.html .. _Stackless: stackless.html From benjamin at codespeak.net Fri Aug 28 14:58:40 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 28 Aug 2009 14:58:40 +0200 (CEST) Subject: [pypy-svn] r67276 - pypy/trunk/pypy/interpreter/pyparser Message-ID: <20090828125840.BFDC916803E@codespeak.net> Author: benjamin Date: Fri Aug 28 14:58:40 2009 New Revision: 67276 Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py Log: appease 2.4 Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/metaparser.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/metaparser.py Fri Aug 28 14:58:40 2009 @@ -14,7 +14,7 @@ class PgenError(Exception): def __init__(self, msg, location=None): - super(PgenError, self).__init__(msg) + Exception.__init__(self, msg) self.location = location From benjamin at codespeak.net Fri Aug 28 15:16:56 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 28 Aug 2009 15:16:56 +0200 (CEST) Subject: [pypy-svn] r67277 - pypy/trunk/pypy/interpreter/astcompiler/test Message-ID: <20090828131656.3560A168030@codespeak.net> Author: benjamin Date: Fri Aug 28 15:16:54 2009 New Revision: 67277 Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py Log: provide all() if it doesn't exist Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py Fri Aug 28 15:16:54 2009 @@ -10,6 +10,16 @@ from pypy.interpreter.astcompiler import ast, consts +try: + all +except NameError: + def all(iterable): + for x in iterable: + if not x: + return False + return True + + class TestAstBuilder: def setup_class(cls): From benjamin at codespeak.net Fri Aug 28 15:28:31 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 28 Aug 2009 15:28:31 +0200 (CEST) Subject: [pypy-svn] r67278 - pypy/trunk/pypy/interpreter/test Message-ID: <20090828132831.6857F16803D@codespeak.net> Author: benjamin Date: Fri Aug 28 15:28:30 2009 New Revision: 67278 Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py Log: 2.4 raises a UnicodeError Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Fri Aug 28 15:28:30 2009 @@ -652,6 +652,7 @@ elif sys.version_info < (2, 5): def skip_on_2_4(self): py.test.skip("syntax not supported by the CPython 2.4 compiler") + _unicode_error_kind = "w_UnicodeError" test_continue_in_nested_finally = skip_on_2_4 test_try_except_finally = skip_on_2_4 test_yield_in_finally = skip_on_2_4 From arigo at codespeak.net Fri Aug 28 16:03:38 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 16:03:38 +0200 (CEST) Subject: [pypy-svn] r67279 - pypy/branch/pyjitpl5-c Message-ID: <20090828140338.BD53C168035@codespeak.net> Author: arigo Date: Fri Aug 28 16:03:38 2009 New Revision: 67279 Added: pypy/branch/pyjitpl5-c/ - copied from r67278, pypy/branch/pyjitpl5/ Log: A branch in which to do the C backend. From arigo at codespeak.net Fri Aug 28 16:05:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 16:05:09 +0200 (CEST) Subject: [pypy-svn] r67280 - in pypy/branch/pyjitpl5-c/pypy/jit/backend/c: . test Message-ID: <20090828140509.48DDA168035@codespeak.net> Author: arigo Date: Fri Aug 28 16:05:08 2009 New Revision: 67280 Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/ (props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/__init__.py (contents, props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (contents, props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (contents, props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/ (props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/__init__.py (contents, props changed) pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/test_runner.py (contents, props changed) Log: Initial check-in, work in progress. Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/__init__.py ============================================================================== Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 16:05:08 2009 @@ -0,0 +1,143 @@ +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.tool.udir import udir +from pypy.rlib import libffi +from pypy.rlib.objectmodel import we_are_translated +from pypy.jit.metainterp import resoperation +from pypy.jit.metainterp.resoperation import rop +import os + + +class Compiler: + FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT)) + + def __init__(self): + self.fn_counter = 0 + self.filename_counter = 0 + self.c_jit_al = None + self.c_jit_ap = None + self.guard_operations = [] + + def run(self, loop): + res = loop._c_jit_func() + res = rffi.cast(lltype.Signed, res) + return self.guard_operations[res] + + def compile_operations(self, loop, guard_op=None): + if guard_op is None: + loop._c_jit_counter = self.fn_counter + if loop.operations[-1].opnum == rop.JUMP: + simpleloop = loop.operations[-1].jump_target is loop + else: + simpleloop = False + fn, funcname = self.write(loop.inputargs, + loop.operations, simpleloop) + else: + fn, _ = self.write(guard_op.inputargs, + guard_op.suboperations, False) + funcname = None + sofn = self.compile_file(fn) + self.load_file(sofn, loop, funcname) + + def get_next_filename(self): + fn = '_c_jit%s.i' % self.filename_counter + self.filename_counter += 1 + return str(udir.ensure('c_jit', dir=1).join(fn)) + + def write(self, inputargs, operations, simpleloop): + fn = self.get_next_filename() + f = open(fn, 'w') + notfirst = self.c_jit_al is not None + print >> f, '%slong _c_jit_al[1000];' % ('extern ' * notfirst) + print >> f, '%svoid*_c_jit_ap[1000];' % ('extern ' * notfirst) + if operations[-1].opnum == rop.JUMP and not simpleloop: + print >> f, 'extern int _c_jit_f%d(void);' % ( + operations[-1].jump_target._c_jit_counter) + self.simpleloop = simpleloop + # + guard_counter = self.fn_counter + 1 + for op in operations: + if op.is_guard(): + assert op.suboperations[0].opnum == rop.FAIL + op.inputargs = op.suboperations[0].args + print >> f, 'int _c_jit_f%d()__attribute__((weak));' % ( + guard_counter) + print >> f, 'int _c_jit_f%d(){return %d;}' % ( + guard_counter, guard_counter) + self.set_guard_operation(op.suboperations[0], guard_counter) + guard_counter += 1 + # + funcname = '_c_jit_f%d' % self.fn_counter + print >> f, 'int %s(){' % funcname + self.argnum = {} + j = 0 + for arg in inputargs: + self.argnum[arg] = j + print >> f, 'long v%d=_c_jit_al[%d];' % (j, j) + j += 1 + if simpleloop: + print >> f, 'while(1){' + for op in operations: + meth = getattr(self, 'generate_' + resoperation.opname[op.opnum]) + meth(f, op) + print >> f, '}' + # + f.close() + self.fn_counter = guard_counter + return fn, funcname + + def compile_file(self, fn): + import subprocess + basename = os.path.basename(fn) + output_fn = basename[:-2]+'.so' + retcode = subprocess.call( + ['gcc', basename, '-shared', '-o', output_fn], + cwd=os.path.dirname(fn)) + if retcode != 0: + raise CompilerError(fn) + return os.path.join(os.path.dirname(fn), output_fn) + + def load_file(self, fn, loop, funcname): + handle = libffi.dlopen(fn, libffi.RTLD_GLOBAL | libffi.RTLD_NOW) + if self.c_jit_al is None: + c_jit_al = libffi.dlsym(handle, "_c_jit_al") + self.c_jit_al = rffi.cast(rffi.LONGP, c_jit_al) + if funcname is not None: + c_func = libffi.dlsym(handle, funcname) + loop._c_jit_func = rffi.cast(self.FUNCPTR, c_func) + + def set_guard_operation(self, op, counter): + while len(self.guard_operations) <= counter: + self.guard_operations.append(None) + self.guard_operations[counter] = op + + # ____________________________________________________________ + + def _binary(binop): + def generate_binary(self, f, op): + argnum = self.argnum + argnum[op.result] = j = len(argnum) + print >> f, 'long v%d=v%d%sv%d;' % (j, argnum[op.args[0]], + binop, argnum[op.args[1]]) + return generate_binary + + generate_INT_LT = _binary('<') + + def generate_FAIL(self, f, op): + for j in range(len(op.args)): + print >> f, '_c_jit_al[%d]=v%d;' % (j, self.argnum[op.args[j]]) + print >> f, 'return %d;' % self.fn_counter + self.set_guard_operation(op, self.fn_counter) + + def generate_JUMP(self, f, op): + if self.simpleloop: + for j in range(len(op.args)): + print >> f, 'long w%d=v%d;' % (j, self.argnum[op.args[j]]) + for j in range(len(op.args)): + print >> f, 'v%d=w%d;' % (j, j) + print >> f, '}' + else: + xxx + + +class CompilerError(Exception): + pass Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 16:05:08 2009 @@ -0,0 +1,42 @@ +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.jit.backend.model import AbstractCPU +from pypy.jit.backend.c.compile import Compiler +from pypy.jit.metainterp.history import AbstractDescr, getkind + + +class CCPU(AbstractCPU): + is_oo = False + + def __init__(self, rtyper, stats): + self.rtyper = rtyper + self.call_descr = {'int': CallDescr('long'), + 'ptr': CallDescr('char*')} + self.compiler = Compiler() + + def compile_operations(self, loop, guard_op=None): + self.compiler.compile_operations(loop, guard_op) + + def calldescrof(self, FUNC, ARGS, RESULT): + return self.call_descr[getkind(RESULT)] + + @staticmethod + def cast_adr_to_int(addr): + return rffi.cast(lltype.Signed, addr) + + def set_future_value_int(self, index, intvalue): + self.compiler.c_jit_al[index] = intvalue + + def execute_operations(self, loop): + return self.compiler.run(loop) + + def get_latest_value_int(self, index): + return self.compiler.c_jit_al[index] + + +CPU = CCPU + +# ____________________________________________________________ + +class CallDescr(AbstractDescr): + def __init__(self, ret_c_type): + self.ret_c_type = ret_c_type Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/__init__.py ============================================================================== Added: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/test_runner.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/test/test_runner.py Fri Aug 28 16:05:08 2009 @@ -0,0 +1,14 @@ +from pypy.jit.backend.c.runner import CPU +from pypy.jit.backend.test.runner_test import LLtypeBackendTest + +class FakeStats(object): + pass + + +class TestC(LLtypeBackendTest): + + # for the individual tests see + # ====> ../../test/runner_test.py + + def setup_class(cls): + cls.cpu = CPU(rtyper=None, stats=FakeStats()) From arigo at codespeak.net Fri Aug 28 16:09:51 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 16:09:51 +0200 (CEST) Subject: [pypy-svn] r67281 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828140951.2668A16803A@codespeak.net> Author: arigo Date: Fri Aug 28 16:09:50 2009 New Revision: 67281 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Log: test_compare_operations passes. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 16:09:50 2009 @@ -112,15 +112,25 @@ # ____________________________________________________________ - def _binary(binop): + def _binary(expr): def generate_binary(self, f, op): argnum = self.argnum argnum[op.result] = j = len(argnum) - print >> f, 'long v%d=v%d%sv%d;' % (j, argnum[op.args[0]], - binop, argnum[op.args[1]]) + expr2 = expr % (argnum[op.args[0]], argnum[op.args[1]]) + print >> f, 'long v%d=%s;' % (j, expr2) return generate_binary - generate_INT_LT = _binary('<') + generate_INT_LT = _binary('v%dv%d') + generate_INT_GE = _binary('v%d>=v%d') + + generate_UINT_LT = _binary('((unsigned long)v%d)<(unsigned long)v%d') + generate_UINT_LE = _binary('((unsigned long)v%d)<=(unsigned long)v%d') + generate_UINT_GT = _binary('((unsigned long)v%d)>(unsigned long)v%d') + generate_UINT_GE = _binary('((unsigned long)v%d)>=(unsigned long)v%d') def generate_FAIL(self, f, op): for j in range(len(op.args)): From arigo at codespeak.net Fri Aug 28 16:12:16 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 16:12:16 +0200 (CEST) Subject: [pypy-svn] r67282 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828141216.7243016803A@codespeak.net> Author: arigo Date: Fri Aug 28 16:12:16 2009 New Revision: 67282 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Log: test_binary_operations passes. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 16:12:16 2009 @@ -120,13 +120,24 @@ print >> f, 'long v%d=%s;' % (j, expr2) return generate_binary + generate_INT_ADD = _binary('v%d+v%d') + generate_INT_SUB = _binary('v%d-v%d') + generate_INT_MUL = _binary('v%d*v%d') + generate_INT_FLOORDIV = _binary('v%d/v%d') + generate_INT_MOD = _binary('v%d%%v%d') + generate_INT_AND = _binary('v%d&v%d') + generate_INT_OR = _binary('v%d|v%d') + generate_INT_XOR = _binary('v%d^v%d') + generate_INT_RSHIFT = _binary('v%d>>v%d') + generate_INT_LSHIFT = _binary('v%d<>v%d') + generate_INT_LT = _binary('v%dv%d') generate_INT_GE = _binary('v%d>=v%d') - generate_UINT_LT = _binary('((unsigned long)v%d)<(unsigned long)v%d') generate_UINT_LE = _binary('((unsigned long)v%d)<=(unsigned long)v%d') generate_UINT_GT = _binary('((unsigned long)v%d)>(unsigned long)v%d') From arigo at codespeak.net Fri Aug 28 16:15:07 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 16:15:07 +0200 (CEST) Subject: [pypy-svn] r67283 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828141507.2B99616803A@codespeak.net> Author: arigo Date: Fri Aug 28 16:15:06 2009 New Revision: 67283 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Log: test_unary_operations passes. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 16:15:06 2009 @@ -112,6 +112,20 @@ # ____________________________________________________________ + def _unary(expr): + def generate_unary(self, f, op): + argnum = self.argnum + argnum[op.result] = j = len(argnum) + expr2 = expr % (argnum[op.args[0]],) + print >> f, 'long v%d=%s;' % (j, expr2) + return generate_unary + + generate_SAME_AS = _unary('v%d') + generate_INT_IS_TRUE = _unary('v%d!=0') + generate_INT_NEG = _unary('-v%d') + generate_INT_INVERT = _unary('~v%d') + generate_BOOL_NOT = _unary('!v%d') + def _binary(expr): def generate_binary(self, f, op): argnum = self.argnum From arigo at codespeak.net Fri Aug 28 17:33:12 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 17:33:12 +0200 (CEST) Subject: [pypy-svn] r67284 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828153312.AD416168026@codespeak.net> Author: arigo Date: Fri Aug 28 17:33:10 2009 New Revision: 67284 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Log: Progress. Now test_call passes. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 17:33:10 2009 @@ -2,11 +2,16 @@ from pypy.tool.udir import udir from pypy.rlib import libffi from pypy.rlib.objectmodel import we_are_translated -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop +from pypy.jit.metainterp import resoperation, history +from pypy.jit.metainterp.resoperation import ResOperation, rop +from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr import os +class CompilerError(Exception): + pass + + class Compiler: FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT)) @@ -68,11 +73,11 @@ # funcname = '_c_jit_f%d' % self.fn_counter print >> f, 'int %s(){' % funcname - self.argnum = {} + self.argname = {} j = 0 for arg in inputargs: - self.argnum[arg] = j - print >> f, 'long v%d=_c_jit_al[%d];' % (j, j) + self.argname[arg] = name = 'v%d' % j + print >> f, 'long %s=_c_jit_al[%d];' % (name, j) j += 1 if simpleloop: print >> f, 'while(1){' @@ -112,61 +117,81 @@ # ____________________________________________________________ + def vexpr(self, v): + if isinstance(v, Box): + return self.argname[v] + else: + xxx + + def generate(self, f, op, expr): + if op.result is None: + print >> f, '%s;' % expr + else: + argname = self.argname + argname[op.result] = name = 'v%d' % len(argname) + print >> f, '%s %s=%s;' % (op.result._c_jit_type, name, expr) + def _unary(expr): def generate_unary(self, f, op): - argnum = self.argnum - argnum[op.result] = j = len(argnum) - expr2 = expr % (argnum[op.args[0]],) - print >> f, 'long v%d=%s;' % (j, expr2) + self.generate(f, op, expr % (self.vexpr(op.args[0]),)) return generate_unary - generate_SAME_AS = _unary('v%d') - generate_INT_IS_TRUE = _unary('v%d!=0') - generate_INT_NEG = _unary('-v%d') - generate_INT_INVERT = _unary('~v%d') - generate_BOOL_NOT = _unary('!v%d') + generate_SAME_AS = _unary('%s') + generate_INT_IS_TRUE = _unary('%s!=0') + generate_INT_NEG = _unary('-%s') + generate_INT_INVERT = _unary('~%s') + generate_BOOL_NOT = _unary('!%s') def _binary(expr): def generate_binary(self, f, op): - argnum = self.argnum - argnum[op.result] = j = len(argnum) - expr2 = expr % (argnum[op.args[0]], argnum[op.args[1]]) - print >> f, 'long v%d=%s;' % (j, expr2) + self.generate(f, op, expr % (self.vexpr(op.args[0]), + self.vexpr(op.args[1]))) return generate_binary - generate_INT_ADD = _binary('v%d+v%d') - generate_INT_SUB = _binary('v%d-v%d') - generate_INT_MUL = _binary('v%d*v%d') - generate_INT_FLOORDIV = _binary('v%d/v%d') - generate_INT_MOD = _binary('v%d%%v%d') - generate_INT_AND = _binary('v%d&v%d') - generate_INT_OR = _binary('v%d|v%d') - generate_INT_XOR = _binary('v%d^v%d') - generate_INT_RSHIFT = _binary('v%d>>v%d') - generate_INT_LSHIFT = _binary('v%d<>v%d') - - generate_INT_LT = _binary('v%dv%d') - generate_INT_GE = _binary('v%d>=v%d') - generate_UINT_LT = _binary('((unsigned long)v%d)<(unsigned long)v%d') - generate_UINT_LE = _binary('((unsigned long)v%d)<=(unsigned long)v%d') - generate_UINT_GT = _binary('((unsigned long)v%d)>(unsigned long)v%d') - generate_UINT_GE = _binary('((unsigned long)v%d)>=(unsigned long)v%d') + generate_INT_ADD = _binary('%s+%s') + generate_INT_SUB = _binary('%s-%s') + generate_INT_MUL = _binary('%s*%s') + generate_INT_FLOORDIV = _binary('%s/%s') + generate_INT_MOD = _binary('%s%%%s') + generate_INT_AND = _binary('%s&%s') + generate_INT_OR = _binary('%s|%s') + generate_INT_XOR = _binary('%s^%s') + generate_INT_RSHIFT = _binary('%s>>%s') + generate_INT_LSHIFT = _binary('%s<<%s') + generate_UINT_RSHIFT = _binary('((unsigned long)%s)>>%s') + + generate_INT_LT = _binary('%s<%s') + generate_INT_LE = _binary('%s<=%s') + generate_INT_EQ = _binary('%s==%s') + generate_INT_NE = _binary('%s!=%s') + generate_INT_GT = _binary('%s>%s') + generate_INT_GE = _binary('%s>=%s') + generate_UINT_LT = _binary('((unsigned long)%s)<(unsigned long)%s') + generate_UINT_LE = _binary('((unsigned long)%s)<=(unsigned long)%s') + generate_UINT_GT = _binary('((unsigned long)%s)>(unsigned long)%s') + generate_UINT_GE = _binary('((unsigned long)%s)>=(unsigned long)%s') + + def generate_CALL(self, f, op): + calldescr = op.descr + assert isinstance(calldescr, CallDescr) + args_expr = ','.join([self.vexpr(v_arg) for v_arg in op.args[1:]]) + expr = '((%s)%s)(%s)' % (calldescr.func_c_type, self.vexpr(op.args[0]), + args_expr) + self.generate(f, op, expr) + + def generate_GUARD_NO_EXCEPTION(self, f, op): + pass # XXX def generate_FAIL(self, f, op): for j in range(len(op.args)): - print >> f, '_c_jit_al[%d]=v%d;' % (j, self.argnum[op.args[j]]) + print >> f, '_c_jit_al[%d]=%s;' % (j, self.vexpr(op.args[j])) print >> f, 'return %d;' % self.fn_counter self.set_guard_operation(op, self.fn_counter) def generate_JUMP(self, f, op): if self.simpleloop: for j in range(len(op.args)): - print >> f, 'long w%d=v%d;' % (j, self.argnum[op.args[j]]) + print >> f, 'long w%d=%s;' % (j, self.vexpr(op.args[j])) for j in range(len(op.args)): print >> f, 'v%d=w%d;' % (j, j) print >> f, '}' @@ -174,5 +199,64 @@ xxx -class CompilerError(Exception): - pass +# ____________________________________________________________ + +def get_c_type(TYPE): + if TYPE is lltype.Void: + return 'void' + if isinstance(TYPE, lltype.Ptr): + return 'char*' + return _c_type_by_size[rffi.sizeof(TYPE)] + +_c_type_by_size = { + rffi.sizeof(rffi.CHAR): 'char', + rffi.sizeof(rffi.SHORT): 'short', + rffi.sizeof(rffi.INT): 'int', + rffi.sizeof(rffi.LONG): 'long', + } + +def get_class_for_type(TYPE): + if TYPE is lltype.Void: + return None + elif history.getkind(TYPE) == 'ptr': + return BoxPtr + else: + return BoxInt + +BoxInt._c_jit_type = 'long' +BoxPtr._c_jit_type = 'char*' + +class CallDescr(AbstractDescr): + call_loop = None + + def __init__(self, arg_classes, ret_class, ret_c_type): + self.arg_classes = arg_classes + self.ret_class = ret_class + self.ret_c_type = ret_c_type + if arg_classes: + arg_c_types = [cls._c_jit_type for cls in arg_classes] + arg_c_types = ','.join(arg_c_types) + else: + arg_c_types = 'void' + self.func_c_type = '%s(*)(%s)' % (ret_c_type, arg_c_types) + + def get_loop_for_call(self, compiler): + if self.call_loop is None: + args = [BoxInt()] + [cls() for cls in self.arg_classes] + if self.ret_class is None: + result = None + result_list = [] + else: + result = self.ret_class() + result_list = [result] + operations = [ + ResOperation(rop.CALL, args, result, self), + ResOperation(rop.GUARD_NO_EXCEPTION, [], None), + ResOperation(rop.FAIL, result_list, None)] + operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] + loop = history.TreeLoop('call') + loop.inputargs = args + loop.operations = operations + compiler.compile_operations(loop) + self.call_loop = loop + return self.call_loop Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 17:33:10 2009 @@ -1,7 +1,9 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.jit.backend.model import AbstractCPU -from pypy.jit.backend.c.compile import Compiler -from pypy.jit.metainterp.history import AbstractDescr, getkind +from pypy.jit.backend.c.compile import Compiler, get_c_type, get_class_for_type +from pypy.jit.backend.c.compile import CallDescr +from pypy.jit.metainterp import history +from pypy.jit.metainterp.history import BoxInt, BoxPtr class CCPU(AbstractCPU): @@ -9,20 +11,12 @@ def __init__(self, rtyper, stats): self.rtyper = rtyper - self.call_descr = {'int': CallDescr('long'), - 'ptr': CallDescr('char*')} + self.call_descrs = {} self.compiler = Compiler() def compile_operations(self, loop, guard_op=None): self.compiler.compile_operations(loop, guard_op) - def calldescrof(self, FUNC, ARGS, RESULT): - return self.call_descr[getkind(RESULT)] - - @staticmethod - def cast_adr_to_int(addr): - return rffi.cast(lltype.Signed, addr) - def set_future_value_int(self, index, intvalue): self.compiler.c_jit_al[index] = intvalue @@ -32,11 +26,36 @@ def get_latest_value_int(self, index): return self.compiler.c_jit_al[index] + def calldescrof(self, FUNC, ARGS, RESULT): + args_cls = [get_class_for_type(ARG) for ARG in ARGS] + cls_result = get_class_for_type(RESULT) + ct_result = get_c_type(RESULT) + key = (tuple(args_cls), cls_result, ct_result) + try: + return self.call_descrs[key] + except KeyError: + pass + descr = CallDescr(args_cls, cls_result, ct_result) + self.call_descrs[key] = descr + return descr + + def do_call(self, args, calldescr): + assert isinstance(calldescr, CallDescr) + loop = calldescr.get_loop_for_call(self.compiler) + history.set_future_values(self, args) + self.compiler.run(loop) + # Note: if an exception is set, the rest of the code does a bit of + # nonsense but nothing wrong (the return value should be ignored) + if calldescr.ret_class is None: + return None + elif calldescr.ret_class is BoxPtr: + return BoxPtr(self.get_latest_value_ptr(0)) + else: + return BoxInt(self.get_latest_value_int(0)) -CPU = CCPU + @staticmethod + def cast_adr_to_int(addr): + return rffi.cast(lltype.Signed, addr) -# ____________________________________________________________ -class CallDescr(AbstractDescr): - def __init__(self, ret_c_type): - self.ret_c_type = ret_c_type +CPU = CCPU From arigo at codespeak.net Fri Aug 28 17:57:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 17:57:25 +0200 (CEST) Subject: [pypy-svn] r67285 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828155725.9CAFD168026@codespeak.net> Author: arigo Date: Fri Aug 28 17:57:24 2009 New Revision: 67285 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Log: Test simple guards. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 17:57:24 2009 @@ -68,11 +68,11 @@ guard_counter) print >> f, 'int _c_jit_f%d(){return %d;}' % ( guard_counter, guard_counter) - self.set_guard_operation(op.suboperations[0], guard_counter) guard_counter += 1 # funcname = '_c_jit_f%d' % self.fn_counter print >> f, 'int %s(){' % funcname + self.guard_counter = self.fn_counter + 1 self.argname = {} j = 0 for arg in inputargs: @@ -121,7 +121,7 @@ if isinstance(v, Box): return self.argname[v] else: - xxx + return str(v.get_()) def generate(self, f, op, expr): if op.result is None: @@ -179,13 +179,35 @@ args_expr) self.generate(f, op, expr) + def generate_failure(self, f, op, return_expr): + assert op.opnum == rop.FAIL + for j in range(len(op.args)): + print >> f, '_c_jit_al[%d]=%s;' % (j, self.vexpr(op.args[j])) + print >> f, 'return %s;' % return_expr + + def generate_guard(self, f, op, expr): + print >> f, 'if (__builtin_expect(%s,0)){' % expr + fail_op = op.suboperations[0] + self.generate_failure(f, fail_op, '_c_jit_f%d()' % self.guard_counter) + self.set_guard_operation(fail_op, self.guard_counter) + self.guard_counter += 1 + print >> f, '}' + + def generate_GUARD_TRUE(self, f, op): + self.generate_guard(f, op, '!%s' % self.vexpr(op.args[0])) + + def generate_GUARD_FALSE(self, f, op): + self.generate_guard(f, op, self.vexpr(op.args[0])) + + def generate_GUARD_VALUE(self, f, op): + self.generate_guard(f, op, '%s!=%s' % (self.vexpr(op.args[0]), + self.vexpr(op.args[1]))) + def generate_GUARD_NO_EXCEPTION(self, f, op): pass # XXX def generate_FAIL(self, f, op): - for j in range(len(op.args)): - print >> f, '_c_jit_al[%d]=%s;' % (j, self.vexpr(op.args[j])) - print >> f, 'return %d;' % self.fn_counter + self.generate_failure(f, op, str(self.fn_counter)) self.set_guard_operation(op, self.fn_counter) def generate_JUMP(self, f, op): From arigo at codespeak.net Fri Aug 28 18:13:19 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 18:13:19 +0200 (CEST) Subject: [pypy-svn] r67286 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828161319.B4EFE168020@codespeak.net> Author: arigo Date: Fri Aug 28 18:13:18 2009 New Revision: 67286 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Log: Start working on Ptrs; test_same_as passes. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 18:13:18 2009 @@ -1,10 +1,11 @@ -from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.tool.udir import udir from pypy.rlib import libffi from pypy.rlib.objectmodel import we_are_translated from pypy.jit.metainterp import resoperation, history from pypy.jit.metainterp.resoperation import ResOperation, rop -from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr +from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr, INT +from pypy.jit.metainterp.history import ConstPtr import os @@ -14,7 +15,8 @@ class Compiler: FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT)) - + CHARPP = lltype.Ptr(lltype.Array(llmemory.GCREF, hints={'nolength': True})) + def __init__(self): self.fn_counter = 0 self.filename_counter = 0 @@ -77,7 +79,10 @@ j = 0 for arg in inputargs: self.argname[arg] = name = 'v%d' % j - print >> f, 'long %s=_c_jit_al[%d];' % (name, j) + if arg.type == INT: + print >> f, 'long %s=_c_jit_al[%d];' % (name, j) + else: + print >> f, 'char*%s=_c_jit_ap[%d];' % (name, j) j += 1 if simpleloop: print >> f, 'while(1){' @@ -105,7 +110,9 @@ handle = libffi.dlopen(fn, libffi.RTLD_GLOBAL | libffi.RTLD_NOW) if self.c_jit_al is None: c_jit_al = libffi.dlsym(handle, "_c_jit_al") + c_jit_ap = libffi.dlsym(handle, "_c_jit_ap") self.c_jit_al = rffi.cast(rffi.LONGP, c_jit_al) + self.c_jit_ap = rffi.cast(self.CHARPP, c_jit_ap) if funcname is not None: c_func = libffi.dlsym(handle, funcname) loop._c_jit_func = rffi.cast(self.FUNCPTR, c_func) @@ -120,8 +127,10 @@ def vexpr(self, v): if isinstance(v, Box): return self.argname[v] + elif isinstance(v, ConstPtr): + return str(rffi.cast(lltype.Signed, v.value)) else: - return str(v.get_()) + return str(v.getint()) def generate(self, f, op, expr): if op.result is None: @@ -182,7 +191,11 @@ def generate_failure(self, f, op, return_expr): assert op.opnum == rop.FAIL for j in range(len(op.args)): - print >> f, '_c_jit_al[%d]=%s;' % (j, self.vexpr(op.args[j])) + box = op.args[j] + if box.type == INT: + print >> f, '_c_jit_al[%d]=%s;' % (j, self.vexpr(box)) + else: + print >> f, '_c_jit_ap[%d]=%s;' % (j, self.vexpr(box)) print >> f, 'return %s;' % return_expr def generate_guard(self, f, op, expr): Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 18:13:18 2009 @@ -1,4 +1,4 @@ -from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.c.compile import Compiler, get_c_type, get_class_for_type from pypy.jit.backend.c.compile import CallDescr @@ -20,12 +20,18 @@ def set_future_value_int(self, index, intvalue): self.compiler.c_jit_al[index] = intvalue + def set_future_value_ptr(self, index, ptrvalue): + self.compiler.c_jit_ap[index] = ptrvalue + def execute_operations(self, loop): return self.compiler.run(loop) def get_latest_value_int(self, index): return self.compiler.c_jit_al[index] + def get_latest_value_ptr(self, index): + return self.compiler.c_jit_ap[index] + def calldescrof(self, FUNC, ARGS, RESULT): args_cls = [get_class_for_type(ARG) for ARG in ARGS] cls_result = get_class_for_type(RESULT) @@ -53,9 +59,15 @@ else: return BoxInt(self.get_latest_value_int(0)) + def do_newstr(self, args, descr=None): + xxx#... + @staticmethod def cast_adr_to_int(addr): return rffi.cast(lltype.Signed, addr) CPU = CCPU + +import pypy.jit.metainterp.executor +pypy.jit.metainterp.executor.make_execute_list(CPU) From arigo at codespeak.net Fri Aug 28 18:19:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 18:19:09 +0200 (CEST) Subject: [pypy-svn] r67287 - pypy/branch/pyjitpl5-c/pypy/jit/backend/test Message-ID: <20090828161909.4A793168020@codespeak.net> Author: arigo Date: Fri Aug 28 18:19:08 2009 New Revision: 67287 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/test/runner_test.py Log: Fix the test, which would occasionally pass the same Box several times in loop.inputargs. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/test/runner_test.py Fri Aug 28 18:19:08 2009 @@ -65,7 +65,10 @@ [ConstInt(-13)], None)] loop = TreeLoop('single op') loop.operations = operations - loop.inputargs = [box for box in valueboxes if isinstance(box, Box)] + loop.inputargs = [] + for box in valueboxes: + if isinstance(box, Box) and box not in loop.inputargs: + loop.inputargs.append(box) self.cpu.compile_operations(loop) return loop From arigo at codespeak.net Fri Aug 28 18:19:17 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 18:19:17 +0200 (CEST) Subject: [pypy-svn] r67288 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828161917.9B4F1168026@codespeak.net> Author: arigo Date: Fri Aug 28 18:19:16 2009 New Revision: 67288 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Log: test_ooois. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 18:19:16 2009 @@ -78,6 +78,7 @@ self.argname = {} j = 0 for arg in inputargs: + assert arg not in self.argname self.argname[arg] = name = 'v%d' % j if arg.type == INT: print >> f, 'long %s=_c_jit_al[%d];' % (name, j) @@ -180,6 +181,11 @@ generate_UINT_GT = _binary('((unsigned long)%s)>(unsigned long)%s') generate_UINT_GE = _binary('((unsigned long)%s)>=(unsigned long)%s') + generate_OOISNULL = _unary('%s==0') + generate_OONONNULL = _unary('%s!=0') + generate_OOIS = _binary('%s==%s') + generate_OOISNOT = _binary('%s!=%s') + def generate_CALL(self, f, op): calldescr = op.descr assert isinstance(calldescr, CallDescr) From arigo at codespeak.net Fri Aug 28 19:00:37 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 19:00:37 +0200 (CEST) Subject: [pypy-svn] r67289 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828170037.91101168025@codespeak.net> Author: arigo Date: Fri Aug 28 19:00:36 2009 New Revision: 67289 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Log: test_string_basic. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 19:00:36 2009 @@ -1,4 +1,4 @@ -from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr from pypy.tool.udir import udir from pypy.rlib import libffi from pypy.rlib.objectmodel import we_are_translated @@ -6,6 +6,7 @@ from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr, INT from pypy.jit.metainterp.history import ConstPtr +from pypy.jit.backend.x86 import symbolic import os @@ -17,12 +18,13 @@ FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT)) CHARPP = lltype.Ptr(lltype.Array(llmemory.GCREF, hints={'nolength': True})) - def __init__(self): + def __init__(self, translate_support_code): self.fn_counter = 0 self.filename_counter = 0 self.c_jit_al = None self.c_jit_ap = None self.guard_operations = [] + self.translate_support_code = translate_support_code def run(self, loop): res = loop._c_jit_func() @@ -101,7 +103,8 @@ basename = os.path.basename(fn) output_fn = basename[:-2]+'.so' retcode = subprocess.call( - ['gcc', basename, '-shared', '-o', output_fn], + ['gcc', '-fomit-frame-pointer', '-O2', basename, + '-shared', '-o', output_fn], cwd=os.path.dirname(fn)) if retcode != 0: raise CompilerError(fn) @@ -194,6 +197,29 @@ args_expr) self.generate(f, op, expr) + def generate_STRLEN(self, f, op): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + self.generate(f, op, '*(long*)(%s+%d)' % (self.vexpr(op.args[0]), + ofs_length)) + + def generate_STRGETITEM(self, f, op): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + self.generate(f, op, '(unsigned char)%s[%d+%s]' % ( + self.vexpr(op.args[0]), + basesize, + self.vexpr(op.args[1]))) + + def generate_STRSETITEM(self, f, op): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + print >> f, '%s[%d+%s]=%s;' % ( + self.vexpr(op.args[0]), + basesize, + self.vexpr(op.args[1]), + self.vexpr(op.args[2])) + def generate_failure(self, f, op, return_expr): assert op.opnum == rop.FAIL for j in range(len(op.args)): @@ -232,7 +258,8 @@ def generate_JUMP(self, f, op): if self.simpleloop: for j in range(len(op.args)): - print >> f, 'long w%d=%s;' % (j, self.vexpr(op.args[j])) + print >> f, '%s w%d=%s;' % (op.args[j]._c_jit_type, + j, self.vexpr(op.args[j])) for j in range(len(op.args)): print >> f, 'v%d=w%d;' % (j, j) print >> f, '}' Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 19:00:36 2009 @@ -9,10 +9,10 @@ class CCPU(AbstractCPU): is_oo = False - def __init__(self, rtyper, stats): + def __init__(self, rtyper, stats, translate_support_code=False): self.rtyper = rtyper self.call_descrs = {} - self.compiler = Compiler() + self.compiler = Compiler(translate_support_code) def compile_operations(self, loop, guard_op=None): self.compiler.compile_operations(loop, guard_op) From arigo at codespeak.net Fri Aug 28 19:25:44 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 19:25:44 +0200 (CEST) Subject: [pypy-svn] r67290 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828172544.D4A46168025@codespeak.net> Author: arigo Date: Fri Aug 28 19:25:41 2009 New Revision: 67290 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Log: More stuff. The do_xxx methods are mostly or entirely copy-pastes from the x86 backend... Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 19:25:41 2009 @@ -294,6 +294,31 @@ BoxInt._c_jit_type = 'long' BoxPtr._c_jit_type = 'char*' +BoxInt._c_jit_make = staticmethod(lambda value: BoxInt(value)) +BoxPtr._c_jit_make = staticmethod(lambda value: BoxPtr( + rffi.cast(llmemory.GCREF, value))) + + +class ArrayDescr(AbstractDescr): + def __init__(self, item_cls, item_c_type, item_size): + self.item_cls = item_cls + self.item_c_type = item_c_type + self.item_size = item_size + +def get_c_array_descr(ITEM): + assert ITEM is not lltype.Void + cls = get_class_for_type(ITEM) + c_type = get_c_type(ITEM) + try: + return _c_array_type_for_item_type[cls, c_type] + except KeyError: + descr = ArrayDescr(cls, c_type, rffi.sizeof(ITEM)) + _c_array_type_for_item_type[cls, c_type] = descr + return descr + +_c_array_type_for_item_type = {} + + class CallDescr(AbstractDescr): call_loop = None Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 19:25:41 2009 @@ -1,9 +1,12 @@ -from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.c.compile import Compiler, get_c_type, get_class_for_type -from pypy.jit.backend.c.compile import CallDescr +from pypy.jit.backend.c.compile import CallDescr, ArrayDescr, get_c_array_descr from pypy.jit.metainterp import history from pypy.jit.metainterp.history import BoxInt, BoxPtr +from pypy.jit.backend.x86 import symbolic + +WORD = rffi.sizeof(lltype.Signed) class CCPU(AbstractCPU): @@ -13,6 +16,7 @@ self.rtyper = rtyper self.call_descrs = {} self.compiler = Compiler(translate_support_code) + self.translate_support_code = translate_support_code def compile_operations(self, loop, guard_op=None): self.compiler.compile_operations(loop, guard_op) @@ -32,6 +36,10 @@ def get_latest_value_ptr(self, index): return self.compiler.c_jit_ap[index] + @staticmethod + def arraydescrof(A): + return get_c_array_descr(A.OF) + def calldescrof(self, FUNC, ARGS, RESULT): args_cls = [get_class_for_type(ARG) for ARG in ARGS] cls_result = get_class_for_type(RESULT) @@ -45,6 +53,48 @@ self.call_descrs[key] = descr return descr + def do_arraylen_gc(self, args, arraydescr): + ofs = 0 #self.gc_ll_descr.array_length_ofs + gcref = args[0].getptr(llmemory.GCREF) + length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] + return BoxInt(length) + + def do_getarrayitem_gc(self, args, arraydescr): + assert isinstance(arraydescr, ArrayDescr) + field = args[1].getint() + gcref = args[0].getptr(llmemory.GCREF) + size = arraydescr.item_size + ofs = WORD #XXX! + if size == 1: + return BoxInt(ord(rffi.cast(rffi.CArrayPtr(lltype.Char), gcref) + [ofs + field])) + elif size == WORD: + val = (rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) + [ofs/WORD + field]) + return arraydescr.item_cls._c_jit_make(val) + else: + raise NotImplementedError("size = %d" % size) + + def _new_do_len(TP): + def do_strlen(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(TP, + self.translate_support_code) + gcref = args[0].getptr(llmemory.GCREF) + v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] + return BoxInt(v) + return do_strlen + + do_strlen = _new_do_len(rstr.STR) + do_unicodelen = _new_do_len(rstr.UNICODE) + + def do_strgetitem(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + gcref = args[0].getptr(llmemory.GCREF) + i = args[1].getint() + v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] + return BoxInt(ord(v)) + def do_call(self, args, calldescr): assert isinstance(calldescr, CallDescr) loop = calldescr.get_loop_for_call(self.compiler) From arigo at codespeak.net Fri Aug 28 19:39:00 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Aug 2009 19:39:00 +0200 (CEST) Subject: [pypy-svn] r67291 - pypy/branch/pyjitpl5-c/pypy/jit/backend/c Message-ID: <20090828173900.D78EC168025@codespeak.net> Author: arigo Date: Fri Aug 28 19:38:59 2009 New Revision: 67291 Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Log: More random progress. Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/compile.py Fri Aug 28 19:38:59 2009 @@ -299,6 +299,14 @@ rffi.cast(llmemory.GCREF, value))) +class FieldDescr(AbstractDescr): + def __init__(self, field_ofs, field_cls, field_c_type, field_size): + self.field_ofs = field_ofs + self.field_cls = field_cls + self.field_c_type = field_c_type + self.field_size = field_size + + class ArrayDescr(AbstractDescr): def __init__(self, item_cls, item_c_type, item_size): self.item_cls = item_cls Modified: pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py ============================================================================== --- pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py (original) +++ pypy/branch/pyjitpl5-c/pypy/jit/backend/c/runner.py Fri Aug 28 19:38:59 2009 @@ -2,6 +2,7 @@ from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.c.compile import Compiler, get_c_type, get_class_for_type from pypy.jit.backend.c.compile import CallDescr, ArrayDescr, get_c_array_descr +from pypy.jit.backend.c.compile import FieldDescr from pypy.jit.metainterp import history from pypy.jit.metainterp.history import BoxInt, BoxPtr from pypy.jit.backend.x86 import symbolic @@ -14,6 +15,7 @@ def __init__(self, rtyper, stats, translate_support_code=False): self.rtyper = rtyper + self.field_descrs = {} self.call_descrs = {} self.compiler = Compiler(translate_support_code) self.translate_support_code = translate_support_code @@ -36,6 +38,19 @@ def get_latest_value_ptr(self, index): return self.compiler.c_jit_ap[index] + def fielddescrof(self, S, fieldname): + try: + return self.field_descrs[S, fieldname] + except KeyError: + pass + ofs, size = symbolic.get_field_token(S, fieldname, + self.translate_support_code) + cls = get_class_for_type(getattr(S, fieldname)) + c_type = get_c_type(getattr(S, fieldname)) + descr = FieldDescr(ofs, cls, c_type, size) + self.field_descrs[S, fieldname] = descr + return descr + @staticmethod def arraydescrof(A): return get_c_array_descr(A.OF) @@ -53,6 +68,22 @@ self.call_descrs[key] = descr return descr + def do_getfield_gc(self, args, fielddescr): + assert isinstance(fielddescr, FieldDescr) + gcref = args[0].getptr(llmemory.GCREF) + ofs = fielddescr.field_ofs + size = fielddescr.field_size + if size == 1: + v = ord(rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[ofs]) + elif size == 2: + v = rffi.cast(rffi.CArrayPtr(rffi.USHORT), gcref)[ofs/2] + v = rffi.cast(lltype.Signed, v) + elif size == WORD: + v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] + else: + raise NotImplementedError("size = %d" % size) + return fielddescr.field_cls._c_jit_make(v) + def do_arraylen_gc(self, args, arraydescr): ofs = 0 #self.gc_ll_descr.array_length_ofs gcref = args[0].getptr(llmemory.GCREF) From david at codespeak.net Fri Aug 28 22:36:16 2009 From: david at codespeak.net (david at codespeak.net) Date: Fri, 28 Aug 2009 22:36:16 +0200 (CEST) Subject: [pypy-svn] r67292 - in pypy/branch/io-lang/pypy/lang/io: . test Message-ID: <20090828203616.49976168023@codespeak.net> Author: david Date: Fri Aug 28 22:36:14 2009 New Revision: 67292 Modified: pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py pypy/branch/io-lang/pypy/lang/io/objspace.py pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Log: switching and resuming coroutines Modified: pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py (original) +++ pypy/branch/io-lang/pypy/lang/io/coroutinemodel.py Fri Aug 28 22:36:14 2009 @@ -26,6 +26,9 @@ return W_Coroutine._get_state(space).current @staticmethod + def w_getmain(space): + return W_Coroutine._get_state(space).main + @staticmethod def _get_state(space): # XXX: Need a propper caching machinery if not hasattr(space, '_coroutine_state'): @@ -34,19 +37,24 @@ return space._coroutine_state def run(self, space, w_receiver, w_context): - t = IoThunk(space, self.slots['runMessage'], w_receiver, w_context) - self.bind(t) + if self.thunk is None: + t = IoThunk(space, self.slots['runMessage'], self, w_context) + self.bind(t) + p = self.lookup('parentCoroutine') + if not space.isnil(p): + self.parent = p + self.switch() class AppCoState(BaseCoState): def __init__(self, space): BaseCoState.__init__(self) - self.w_tempval = space.w_nil self.space = space def post_install(self): - self.current = self.main = W_Coroutine(self.space, self, [self.space.w_object]) - # self.main.subctx.framestack = None # wack + self.main = W_Coroutine(self.space, self, [self.space.w_object]) + self.current = self.main.clone() + # self.current.slots['parentCoroutine'] = self.main class IoThunk(AbstractThunk): def __init__(self, space, w_message, w_receiver, w_context): @@ -57,4 +65,4 @@ def call(self): t = self.w_message.eval(self.space, self.w_receiver, self.w_context) - self.w_receiver.slots['result'] = t \ No newline at end of file + self.w_receiver.slots['result'] = thunk \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/objspace.py (original) +++ pypy/branch/io-lang/pypy/lang/io/objspace.py Fri Aug 28 22:36:14 2009 @@ -28,7 +28,7 @@ self.w_list = W_List(self, [self.w_object]) self.w_call = W_Object(self, [self.w_object]) self.w_map = W_Map(self, [self.w_object]) - self.w_coroutine = W_Coroutine.w_getcurrent(self) + self.w_coroutine = W_Coroutine.w_getmain(self) # flow control objects self.w_normal = W_Object(self, [self.w_object]) self.w_break = W_Object(self, [self.w_object]) @@ -191,6 +191,9 @@ if value: return self.w_true return self.w_false + + def isnil(self, w_object): + return w_object is self.w_nil def init_stored_messages(self): self.w_print_message = W_Message(self, 'print', []) \ No newline at end of file Modified: pypy/branch/io-lang/pypy/lang/io/test/test_coro.py ============================================================================== --- pypy/branch/io-lang/pypy/lang/io/test/test_coro.py (original) +++ pypy/branch/io-lang/pypy/lang/io/test/test_coro.py Fri Aug 28 22:36:14 2009 @@ -65,16 +65,34 @@ res, space = interpret(inp) assert res.slots['result'].value == 99 -def test_coro_resume(): - py.test.skip() +def test_coro_parent_resume_switch(): + # py.test.skip() inp = """ - b := message(Coroutine currentCoroutine setResult(23); Coroutine currentCoroutine parentCoroutine resume; "bye" print) - a := Coroutine currentCoroutine clone + back := currentCoro + p := Coroutine currentCoroutine clone do( + name := "p" + setRunMessage( + message( + p setResult(99); + back resume + ) + ) + ) + b := message( + Coroutine currentCoroutine setResult(23); + Coroutine currentCoroutine parentCoroutine run; + 24 + ) + a := Coroutine currentCoroutine clone do( + name := "a" + ) + a setParentCoroutine(p) a setRunMessage(b) run - a result """ res,space = interpret(inp) - assert res.value == 23 + + assert space.w_lobby.slots['a'].slots['result'].value == 23 + assert space.w_lobby.slots['p'].slots['result'].value == 99 def test_coro_resume2(): inp = """ From antocuni at codespeak.net Sat Aug 29 11:00:52 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 11:00:52 +0200 (CEST) Subject: [pypy-svn] r67293 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp Message-ID: <20090829090052.EC803168011@codespeak.net> Author: antocuni Date: Sat Aug 29 11:00:51 2009 New Revision: 67293 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Log: veeery obscure. If we import rvirtualizable2 in the class body, it indirectly triggers the importing of rpython.exceptiondata *before* py.test's magic has patched AssertionError; as a consequence, exceptiondata.standardexceptions contains the standard AssertionError, but it will causes troubles later when the code will reference py.__.magic.AssertionError. I'm not sure if the fault is mine, of py.test or of exceptiondata, but deferring the importing of rvirtualizable2 fixes the issue. Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Sat Aug 29 11:00:51 2009 @@ -47,8 +47,9 @@ loops_done_with_this_frame_ref = None # patched by compile.py CVAL_NULLREF = None # patched by optimizeopt.py - from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR as VABLERTI - null_vable_rti = lltype.nullptr(VABLERTI.TO) + def get_VABLERTI(self): + from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR + return VABLERTIPTR def new_ConstRef(self, x): ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) @@ -145,9 +146,10 @@ ConstRef = history.ConstObj loops_done_with_this_frame_ref = None # patched by compile.py CVAL_NULLREF = None # patched by optimizeopt.py - - from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI - null_vable_rti = ootype.make_null_instance(VABLERTI) + + def get_VABLERTI(self): + from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI + return VABLERTI def new_ConstRef(self, x): obj = ootype.cast_to_object(x) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/virtualizable.py Sat Aug 29 11:00:51 2009 @@ -15,8 +15,8 @@ jitdriver = warmrunnerdesc.jitdriver cpu = warmrunnerdesc.cpu self.cpu = cpu - self.VABLERTI = cpu.ts.VABLERTI - self.null_vable_rti = cpu.ts.null_vable_rti + self.VABLERTI = cpu.ts.get_VABLERTI() + self.null_vable_rti = cpu.ts.nullptr(deref(self.VABLERTI)) self.BoxArray = cpu.ts.BoxRef # assert len(jitdriver.virtualizables) == 1 # for now From antocuni at codespeak.net Sat Aug 29 11:11:41 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 11:11:41 +0200 (CEST) Subject: [pypy-svn] r67294 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test Message-ID: <20090829091141.8C81C168020@codespeak.net> Author: antocuni Date: Sat Aug 29 11:11:41 2009 New Revision: 67294 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py Log: fix test_casts, which had been broken by r67259 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_basic.py Sat Aug 29 11:11:41 2009 @@ -62,6 +62,10 @@ class DoneWithThisFrame(Exception): pass + + class DoneWithThisFrameRef(DoneWithThisFrame): + def __init__(self, cpu, *args): + DoneWithThisFrame.__init__(self, *args) class FakeWarmRunnerDesc: def attach_unoptimized_bridge_from_interp(self, greenkey, newloop): @@ -84,8 +88,7 @@ metainterp.staticdata._class_sizes = cw.class_sizes metainterp.staticdata.state = FakeWarmRunnerDesc() metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame - metainterp.staticdata.DoneWithThisFramePtr = DoneWithThisFrame - metainterp.staticdata.DoneWithThisFrameObj = DoneWithThisFrame + metainterp.staticdata.DoneWithThisFrameRef = DoneWithThisFrameRef self.metainterp = metainterp try: metainterp.compile_and_run_once(*args) From antocuni at codespeak.net Sat Aug 29 11:27:59 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 11:27:59 +0200 (CEST) Subject: [pypy-svn] r67295 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test Message-ID: <20090829092759.ADEA3168022@codespeak.net> Author: antocuni Date: Sat Aug 29 11:27:56 2009 New Revision: 67295 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py Log: remove one more is_oo Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizefindnode.py Sat Aug 29 11:27:56 2009 @@ -37,6 +37,10 @@ class LLtypeMixin(object): type_system = 'lltype' + def get_class_of_box(self, box): + from pypy.rpython.lltypesystem import rclass + return box.getref(rclass.OBJECTPTR).typeptr + node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) @@ -76,9 +80,12 @@ class OOtypeMixin(object): type_system = 'ootype' + + def get_class_of_box(self, box): + root = box.getref(ootype.ROOT) + return ootype.classof(root) cpu = runner.OOtypeCPU(None) - NODE = ootype.Instance('NODE', ootype.ROOT, {}) NODE._add_fields({'value': ootype.Signed, 'next': NODE}) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_optimizeopt.py Sat Aug 29 11:27:56 2009 @@ -1,5 +1,4 @@ import py -from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import instantiate from pypy.jit.metainterp.test.test_resume import MyMetaInterp @@ -1154,11 +1153,7 @@ else: tag, resolved, fieldstext = virtuals[varname] if tag[0] == 'virtual': - if not self.cpu.is_oo: - assert box.getref(rclass.OBJECTPTR).typeptr == tag[1] - else: - root = box.getref(ootype.ROOT) - assert ootype.classof(root) == tag[1] + assert self.get_class_of_box(box) == tag[1] elif tag[0] == 'varray': pass # xxx check arraydescr elif tag[0] == 'vstruct': From antocuni at codespeak.net Sat Aug 29 11:38:16 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 11:38:16 +0200 (CEST) Subject: [pypy-svn] r67297 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp: . test Message-ID: <20090829093816.A15F4168015@codespeak.net> Author: antocuni Date: Sat Aug 29 11:38:16 2009 New Revision: 67297 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/oparser.py Log: get rid of two more is_oos Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/codewriter.py Sat Aug 29 11:38:16 2009 @@ -144,7 +144,7 @@ if self.portal_graph is None or graph is self.portal_graph: return () fnptr = self.rtyper.getcallable(graph) - if self.cpu.is_oo: + if self.rtyper.type_system.name == 'ootypesystem': if oosend_methdescr: return (None, oosend_methdescr) else: Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/oparser.py Sat Aug 29 11:38:16 2009 @@ -3,9 +3,10 @@ in a nicer fashion """ -from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\ - ConstAddr, ConstObj, ConstPtr, Box, BoxObj +from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt,\ + ConstAddr, ConstObj, ConstPtr, Box from pypy.jit.metainterp.resoperation import rop, ResOperation +from pypy.jit.metainterp.typesystem import llhelper from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype @@ -70,10 +71,8 @@ _box_counter_more_than(elem[1:]) elif elem.startswith('p'): # pointer - if getattr(self.cpu, 'is_oo', False): - box = BoxObj() - else: - box = BoxPtr() + ts = getattr(self.cpu, 'ts', llhelper) + box = ts.BoxRef() _box_counter_more_than(elem[1:]) else: for prefix, boxclass in self.boxkinds.iteritems(): From arigo at codespeak.net Sat Aug 29 11:46:05 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 11:46:05 +0200 (CEST) Subject: [pypy-svn] r67298 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090829094605.2659B168015@codespeak.net> Author: arigo Date: Sat Aug 29 11:46:04 2009 New Revision: 67298 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: Merge r67287 from pyjitpl5-c: Fix the test, which would occasionally pass the same Box several times in loop.inputargs. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Sat Aug 29 11:46:04 2009 @@ -65,7 +65,10 @@ [ConstInt(-13)], None)] loop = TreeLoop('single op') loop.operations = operations - loop.inputargs = [box for box in valueboxes if isinstance(box, Box)] + loop.inputargs = [] + for box in valueboxes: + if isinstance(box, Box) and box not in loop.inputargs: + loop.inputargs.append(box) self.cpu.compile_operations(loop) return loop From arigo at codespeak.net Sat Aug 29 11:56:39 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 11:56:39 +0200 (CEST) Subject: [pypy-svn] r67299 - pypy/branch/pyjitpl5-llmodel Message-ID: <20090829095639.EF754168016@codespeak.net> Author: arigo Date: Sat Aug 29 11:56:39 2009 New Revision: 67299 Added: pypy/branch/pyjitpl5-llmodel/ - copied from r67298, pypy/branch/pyjitpl5/ Log: A branch to try to extract as much of the x86 backend as possible into generic code for LL backends. From arigo at codespeak.net Sat Aug 29 13:00:21 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 13:00:21 +0200 (CEST) Subject: [pypy-svn] r67300 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport llsupport/test x86 Message-ID: <20090829110021.6E843168015@codespeak.net> Author: arigo Date: Sat Aug 29 13:00:19 2009 New Revision: 67300 Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/ (props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/__init__.py (contents, props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (contents, props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py - copied, changed from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (contents, props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py - copied, changed from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/ (props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/__init__.py (contents, props changed) pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (contents, props changed) Removed: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py Log: Start to move some things from the x86 backend to a generic llsupport directory. Write an optimized implementation of field and array descrs. Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/__init__.py ============================================================================== Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 13:00:19 2009 @@ -0,0 +1,117 @@ +from pypy.rpython.lltypesystem import lltype +from pypy.jit.backend.llsupport import symbolic +from pypy.jit.metainterp.history import AbstractDescr + +# The point of the class organization in this file is to make instances +# as compact as possible. This is done by not storing the field size or +# the 'is_pointer_field' flag in the instance itself but in the class +# (in methods actually) using a few classes instead of just one. + + +# ____________________________________________________________ +# FieldDescrs + +class AbstractFieldDescr(AbstractDescr): + + def __init__(self, offset): + self.offset = offset + + def sort_key(self): + return self.offset + + def get_field_size(self, translate_support_code): + raise NotImplementedError + + def is_pointer_field(self): + return False # unless overridden by GcPtrFieldDescr + + +class NonGcPtrFieldDescr(AbstractFieldDescr): + def get_field_size(self, translate_support_code): + return symbolic.get_size_of_ptr(translate_support_code) + +class GcPtrFieldDescr(NonGcPtrFieldDescr): + def is_pointer_field(self): + return True + +def getFieldDescrClass(TYPE): + return getDescrClass(TYPE, AbstractFieldDescr, GcPtrFieldDescr, + NonGcPtrFieldDescr, 'Field') + +def get_field_descr(STRUCT, fieldname, translate_support_code, _cache={}): + try: + return _cache[STRUCT, fieldname, translate_support_code] + except KeyError: + offset, _ = symbolic.get_field_token(STRUCT, fieldname, + translate_support_code) + FIELDTYPE = getattr(STRUCT, fieldname) + fielddescr = getFieldDescrClass(FIELDTYPE)(offset) + _cache[STRUCT, fieldname, translate_support_code] = fielddescr + return fielddescr + + +# ____________________________________________________________ +# ArrayDescrs + +_A = lltype.GcArray(lltype.Signed) # a random gcarray + + +class AbstractArrayDescr(AbstractDescr): + + def get_base_size(self, translate_support_code): + basesize, _, _ = symbolic.get_array_token(_A, translate_support_code) + return basesize + + def get_ofs_length(self, translate_support_code): + _, _, ofslength = symbolic.get_array_token(_A, translate_support_code) + return ofslength + + def get_item_size(self, translate_support_code): + raise NotImplementedError + + def is_array_of_pointers(self): + return False # unless overridden by GcPtrArrayDescr + + +class NonGcPtrArrayDescr(AbstractArrayDescr): + def get_item_size(self, translate_support_code): + return symbolic.get_size_of_ptr(translate_support_code) + +class GcPtrArrayDescr(NonGcPtrArrayDescr): + def is_array_of_pointers(self): + return True + +def getArrayDescrClass(ARRAY): + return getDescrClass(ARRAY.OF, AbstractArrayDescr, GcPtrArrayDescr, + NonGcPtrArrayDescr, 'Array') + +def get_array_descr(ARRAY, _cache={}): + try: + return _cache[ARRAY] + except KeyError: + arraydescr = getArrayDescrClass(ARRAY)() + _cache[ARRAY] = arraydescr + return arraydescr + + +# ____________________________________________________________ + +def getDescrClass(TYPE, AbstractDescr, GcPtrDescr, NonGcPtrDescr, + nameprefix, _cache={}): + if isinstance(TYPE, lltype.Ptr): + if TYPE.TO._gckind == 'gc': + return GcPtrDescr + else: + return NonGcPtrDescr + try: + return _cache[nameprefix, TYPE] + except KeyError: + # + class Descr(AbstractDescr): + def get_field_size(self, translate_support_code): + return symbolic.get_size(TYPE, translate_support_code) + get_item_size = get_field_size + # + Descr.__name__ = '%s%sDescr' % (TYPE._name, nameprefix) + _cache[nameprefix, TYPE] = Descr + return Descr Copied: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py) ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 13:00:19 2009 @@ -3,11 +3,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.jit.backend.x86 import symbolic -from pypy.jit.backend.x86.runner import ConstDescr3 -from pypy.jit.backend.x86.ri386 import MODRM, IMM32, mem, imm32, rel32, heap -from pypy.jit.backend.x86.ri386 import REG, eax, ecx, edx -from pypy.jit.backend.x86.assembler import WORD +from pypy.jit.backend.llsupport import symbolic # ____________________________________________________________ Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 13:00:19 2009 @@ -0,0 +1,19 @@ +from pypy.jit.backend.model import AbstractCPU +from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr + + +class AbstractLLCPU(AbstractCPU): + + def __init__(self, rtyper, stats, translate_support_code=False, + gcdescr=None): + from pypy.jit.backend.llsupport.gc import get_ll_description + self.rtyper = rtyper + self.stats = stats + self.translate_support_code = translate_support_code + self.gc_ll_descr = get_ll_description(gcdescr, self) + + def fielddescrof(self, STRUCT, fieldname): + return get_field_descr(STRUCT, fieldname, self.translate_support_code) + + def arraydescrof(self, A): + return get_array_descr(A) Copied: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py (from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py) ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py Sat Aug 29 13:00:19 2009 @@ -21,6 +21,10 @@ return ctypes.sizeof(ctype) @specialize.memo() +def get_size_of_ptr(translate_support_code): + return get_size(llmemory.GCREF, translate_support_code) + + at specialize.memo() def get_array_token(T, translate_support_code): # T can be an array or a var-sized structure if translate_support_code: Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/__init__.py ============================================================================== Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 13:00:19 2009 @@ -0,0 +1,86 @@ +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.jit.backend.llsupport.descr import * +from pypy.rlib.objectmodel import Symbolic + + +def test_get_field_descr(): + U = lltype.Struct('U') + T = lltype.GcStruct('T') + S = lltype.GcStruct('S', ('x', lltype.Char), + ('y', lltype.Ptr(T)), + ('z', lltype.Ptr(U))) + assert getFieldDescrClass(lltype.Ptr(T)) is GcPtrFieldDescr + assert getFieldDescrClass(lltype.Ptr(U)) is NonGcPtrFieldDescr + cls = getFieldDescrClass(lltype.Char) + assert cls != getFieldDescrClass(lltype.Signed) + assert cls == getFieldDescrClass(lltype.Char) + # + assert get_field_descr(S, 'y', False) == get_field_descr(S, 'y', False) + assert get_field_descr(S, 'y', False) != get_field_descr(S, 'y', True) + for tsc in [False, True]: + descr_x = get_field_descr(S, 'x', tsc) + descr_y = get_field_descr(S, 'y', tsc) + descr_z = get_field_descr(S, 'z', tsc) + assert descr_x.__class__ is cls + assert descr_y.__class__ is GcPtrFieldDescr + assert descr_z.__class__ is NonGcPtrFieldDescr + if not tsc: + assert descr_x.offset < descr_y.offset < descr_z.offset + assert descr_x.get_field_size(False) == rffi.sizeof(lltype.Char) + assert descr_y.get_field_size(False) == rffi.sizeof(lltype.Ptr(T)) + assert descr_z.get_field_size(False) == rffi.sizeof(lltype.Ptr(U)) + else: + assert isinstance(descr_x.offset, Symbolic) + assert isinstance(descr_y.offset, Symbolic) + assert isinstance(descr_z.offset, Symbolic) + assert isinstance(descr_x.get_field_size(True), Symbolic) + assert isinstance(descr_y.get_field_size(True), Symbolic) + assert isinstance(descr_z.get_field_size(True), Symbolic) + assert not descr_x.is_pointer_field() + assert descr_y.is_pointer_field() + assert not descr_z.is_pointer_field() + + +def test_get_array_descr(): + U = lltype.Struct('U') + T = lltype.GcStruct('T') + A1 = lltype.GcArray(lltype.Char) + A2 = lltype.GcArray(lltype.Ptr(T)) + A3 = lltype.GcArray(lltype.Ptr(U)) + assert getArrayDescrClass(A2) is GcPtrArrayDescr + assert getArrayDescrClass(A3) is NonGcPtrArrayDescr + cls = getArrayDescrClass(A1) + assert cls != getArrayDescrClass(lltype.GcArray(lltype.Signed)) + assert cls == getArrayDescrClass(lltype.GcArray(lltype.Char)) + # + descr1 = get_array_descr(A1) + descr2 = get_array_descr(A2) + descr3 = get_array_descr(A3) + assert descr1.__class__ is cls + assert descr2.__class__ is GcPtrArrayDescr + assert descr3.__class__ is NonGcPtrArrayDescr + assert descr1 == get_array_descr(lltype.GcArray(lltype.Char)) + assert not descr1.is_array_of_pointers() + assert descr2.is_array_of_pointers() + assert not descr3.is_array_of_pointers() + # + WORD = rffi.sizeof(lltype.Signed) + assert descr1.get_base_size(False) == WORD + assert descr2.get_base_size(False) == WORD + assert descr3.get_base_size(False) == WORD + assert descr1.get_ofs_length(False) == 0 + assert descr2.get_ofs_length(False) == 0 + assert descr3.get_ofs_length(False) == 0 + assert descr1.get_item_size(False) == rffi.sizeof(lltype.Char) + assert descr2.get_item_size(False) == rffi.sizeof(lltype.Ptr(T)) + assert descr3.get_item_size(False) == rffi.sizeof(lltype.Ptr(U)) + # + assert isinstance(descr1.get_base_size(True), Symbolic) + assert isinstance(descr2.get_base_size(True), Symbolic) + assert isinstance(descr3.get_base_size(True), Symbolic) + assert isinstance(descr1.get_ofs_length(True), Symbolic) + assert isinstance(descr2.get_ofs_length(True), Symbolic) + assert isinstance(descr3.get_ofs_length(True), Symbolic) + assert isinstance(descr1.get_item_size(True), Symbolic) + assert isinstance(descr2.get_item_size(True), Symbolic) + assert isinstance(descr3.get_item_size(True), Symbolic) From antocuni at codespeak.net Sat Aug 29 13:24:19 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 13:24:19 +0200 (CEST) Subject: [pypy-svn] r67301 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test Message-ID: <20090829112419.D87E716801B@codespeak.net> Author: antocuni Date: Sat Aug 29 13:24:17 2009 New Revision: 67301 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_zrpy_recursive.py Log: this test has been failing for ages probably, as the nightly tests don't pass --slow. Mark it as expected to fail Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_zrpy_recursive.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_zrpy_recursive.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/test/test_zrpy_recursive.py Sat Aug 29 13:24:17 2009 @@ -13,3 +13,7 @@ sys.setrecursionlimit(cls._recursion_limit) # ==========> test_recursive.py + + @py.test.mark.xfail + def test_inline_faulty_can_inline(self): + test_recursive.RecursiveTests.test_inline_faulty_can_inline(self) From antocuni at codespeak.net Sat Aug 29 13:26:07 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 13:26:07 +0200 (CEST) Subject: [pypy-svn] r67302 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test Message-ID: <20090829112607.B9C4C16801B@codespeak.net> Author: antocuni Date: Sat Aug 29 13:26:07 2009 New Revision: 67302 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py Log: remove yet another is_oo Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/runner_test.py Sat Aug 29 13:26:07 2009 @@ -235,10 +235,7 @@ ] ops[1].suboperations = [ResOperation(rop.FAIL, [], None)] else: - if self.cpu.is_oo: - v_exc = BoxObj() - else: - v_exc = BoxPtr() + v_exc = self.cpu.ts.BoxRef() ops = [ ResOperation(opnum, [v1, v2], v_res), ResOperation(rop.GUARD_OVERFLOW, [], None), From antocuni at codespeak.net Sat Aug 29 13:37:59 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 13:37:59 +0200 (CEST) Subject: [pypy-svn] r67303 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph Message-ID: <20090829113759.E2ACA16801B@codespeak.net> Author: antocuni Date: Sat Aug 29 13:37:59 2009 New Revision: 67303 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Log: unify llimpl.compile_start_{obj,ptr}_var and remove one is_oo Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py Sat Aug 29 13:37:59 2009 @@ -267,21 +267,11 @@ _variables.append(v) return r -def compile_start_ptr_var(loop): +def compile_start_ref_var(loop, TYPE): loop = _from_opaque(loop) assert not loop.operations v = Variable() - v.concretetype = llmemory.GCREF - loop.inputargs.append(v) - r = len(_variables) - _variables.append(v) - return r - -def compile_start_obj_var(loop): - loop = _from_opaque(loop) - assert not loop.operations - v = Variable() - v.concretetype = ootype.Object + v.concretetype = TYPE loop.inputargs.append(v) r = len(_variables) _variables.append(v) @@ -1252,8 +1242,7 @@ setannotation(compile_start, s_CompiledLoop) setannotation(compile_start_int_var, annmodel.SomeInteger()) -setannotation(compile_start_ptr_var, annmodel.SomeInteger()) -setannotation(compile_start_obj_var, annmodel.SomeInteger()) +setannotation(compile_start_ref_var, annmodel.SomeInteger()) setannotation(compile_add, annmodel.s_None) setannotation(compile_add_descr, annmodel.s_None) setannotation(compile_add_var, annmodel.s_None) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Sat Aug 29 13:37:59 2009 @@ -115,10 +115,9 @@ for box in loop.inputargs: if isinstance(box, history.BoxInt): var2index[box] = llimpl.compile_start_int_var(c) - elif isinstance(box, history.BoxPtr): - var2index[box] = llimpl.compile_start_ptr_var(c) - elif self.is_oo and isinstance(box, history.BoxObj): - var2index[box] = llimpl.compile_start_obj_var(c) + elif isinstance(box, self.ts.BoxRef): + TYPE = self.ts.BASETYPE + var2index[box] = llimpl.compile_start_ref_var(c, TYPE) else: raise Exception("box is: %r" % (box,)) self._compile_branch(c, loop.operations, var2index) From antocuni at codespeak.net Sat Aug 29 13:43:15 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 13:43:15 +0200 (CEST) Subject: [pypy-svn] r67304 - pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph Message-ID: <20090829114315.18D4916801B@codespeak.net> Author: antocuni Date: Sat Aug 29 13:43:14 2009 New Revision: 67304 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Log: unify llimpl.compile_add_{ptr,obj}_const and llimpl.compile_add_{ptr,obj}_result Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/llimpl.py Sat Aug 29 13:43:14 2009 @@ -300,7 +300,7 @@ op = loop.operations[-1] op.args.append(const) -def compile_add_ptr_const(loop, value, TYPE=llmemory.GCREF): +def compile_add_ref_const(loop, value, TYPE): loop = _from_opaque(loop) const = Constant(value) const.concretetype = TYPE @@ -317,7 +317,7 @@ _variables.append(v) return r -def compile_add_ptr_result(loop, TYPE=llmemory.GCREF): +def compile_add_ref_result(loop, TYPE): loop = _from_opaque(loop) v = Variable() v.concretetype = TYPE @@ -1247,9 +1247,9 @@ setannotation(compile_add_descr, annmodel.s_None) setannotation(compile_add_var, annmodel.s_None) setannotation(compile_add_int_const, annmodel.s_None) -setannotation(compile_add_ptr_const, annmodel.s_None) +setannotation(compile_add_ref_const, annmodel.s_None) setannotation(compile_add_int_result, annmodel.SomeInteger()) -setannotation(compile_add_ptr_result, annmodel.SomeInteger()) +setannotation(compile_add_ref_result, annmodel.SomeInteger()) setannotation(compile_add_jump_target, annmodel.s_None) setannotation(compile_add_fail, annmodel.s_None) setannotation(compile_suboperations, s_CompiledLoop) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llgraph/runner.py Sat Aug 29 13:43:14 2009 @@ -140,12 +140,10 @@ llimpl.compile_add_var(c, var2index[x]) elif isinstance(x, history.ConstInt): llimpl.compile_add_int_const(c, x.value) - elif isinstance(x, history.ConstPtr): - llimpl.compile_add_ptr_const(c, x.value) + elif isinstance(x, self.ts.ConstRef): + llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE) elif isinstance(x, history.ConstAddr): llimpl.compile_add_int_const(c, x.getint()) - elif self.is_oo and isinstance(x, history.ConstObj): - llimpl.compile_add_ptr_const(c, x.value, ootype.Object) else: raise Exception("%s args contain: %r" % (op.getopname(), x)) @@ -156,10 +154,8 @@ if x is not None: if isinstance(x, history.BoxInt): var2index[x] = llimpl.compile_add_int_result(c) - elif isinstance(x, history.BoxPtr): - var2index[x] = llimpl.compile_add_ptr_result(c) - elif self.is_oo and isinstance(x, history.BoxObj): - var2index[x] = llimpl.compile_add_ptr_result(c, ootype.Object) + elif isinstance(x, self.ts.BoxRef): + var2index[x] = llimpl.compile_add_ref_result(c, self.ts.BASETYPE) else: raise Exception("%s.result contain: %r" % (op.getopname(), x)) From arigo at codespeak.net Sat Aug 29 13:57:06 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 13:57:06 +0200 (CEST) Subject: [pypy-svn] r67305 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport: . test Message-ID: <20090829115706.5A48416801B@codespeak.net> Author: arigo Date: Sat Aug 29 13:57:05 2009 New Revision: 67305 Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_runner.py (contents, props changed) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: Start copying some do_xxx operations from x86/runner.py. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 13:57:05 2009 @@ -1,5 +1,28 @@ +import sys +from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.unroll import unrolling_iterable +from pypy.jit.metainterp.history import BoxInt, BoxPtr from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr +from pypy.jit.backend.llsupport.descr import AbstractFieldDescr +from pypy.jit.backend.llsupport.descr import AbstractArrayDescr + +WORD = rffi.sizeof(lltype.Signed) +SIZEOF_CHAR = rffi.sizeof(lltype.Char) +SIZEOF_SHORT = rffi.sizeof(rffi.SHORT) +SIZEOF_INT = rffi.sizeof(rffi.INT) + +unroll_basic_sizes = unrolling_iterable([(lltype.Signed, WORD), + (lltype.Char, SIZEOF_CHAR), + (rffi.SHORT, SIZEOF_SHORT), + (rffi.INT, SIZEOF_INT)]) + +def _check_addr_range(x): + if sys.platform == 'linux2': + # this makes assumption about address ranges that are valid + # only on linux (?) + assert x == 0 or x > (1<<20) or x < (-1<<20) class AbstractLLCPU(AbstractCPU): @@ -12,8 +35,51 @@ self.translate_support_code = translate_support_code self.gc_ll_descr = get_ll_description(gcdescr, self) + # ------------------- helpers and descriptions -------------------- + + @staticmethod + def cast_adr_to_int(x): + res = rffi.cast(lltype.Signed, x) + return res + + def cast_int_to_gcref(self, x): + if not we_are_translated(): + _check_addr_range(x) + return rffi.cast(llmemory.GCREF, x) + def fielddescrof(self, STRUCT, fieldname): return get_field_descr(STRUCT, fieldname, self.translate_support_code) def arraydescrof(self, A): return get_array_descr(A) + + def do_arraylen_gc(self, args, arraydescr): + assert isinstance(arraydescr, AbstractArrayDescr) + ofs = arraydescr.get_ofs_length(self.translate_support_code) + gcref = args[0].getptr_base() + length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] + return BoxInt(length) + + def do_getarrayitem_gc(self, args, arraydescr): + assert isinstance(arraydescr, AbstractArrayDescr) + itemindex = args[1].getint() + gcref = args[0].getptr_base() + ofs = arraydescr.get_base_size(self.translate_support_code) + size = arraydescr.get_item_size(self.translate_support_code) + ptr = arraydescr.is_array_of_pointers() + # + for TYPE, itemsize in unroll_basic_sizes: + if size == itemsize: + val = (rffi.cast(rffi.CArrayPtr(TYPE), gcref) + [ofs/itemsize + itemindex]) + break + else: + raise NotImplementedError("size = %d" % size) + if ptr: + return BoxPtr(self.cast_int_to_gcref(val)) + else: + return BoxInt(rffi.cast(lltype.Signed, val)) + + +import pypy.jit.metainterp.executor +pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_runner.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_runner.py Sat Aug 29 13:57:05 2009 @@ -0,0 +1,20 @@ +import py +from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU +from pypy.jit.backend.test.runner_test import LLtypeBackendTest + + +class FakeStats(object): + pass + +class MyLLCPU(AbstractLLCPU): + def compile_operations(self, loop, guard_op=None): + py.test.skip("llsupport test: cannot compile operations") + + +class TestAbstractLLCPU(LLtypeBackendTest): + + # for the individual tests see + # ====> ../../test/runner_test.py + + def setup_class(cls): + cls.cpu = MyLLCPU(rtyper=None, stats=FakeStats()) From arigo at codespeak.net Sat Aug 29 14:06:47 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:06:47 +0200 (CEST) Subject: [pypy-svn] r67306 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829120647.92A8A16801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:06:47 2009 New Revision: 67306 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Log: Use weak dictionaries, for once. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 14:06:47 2009 @@ -1,3 +1,4 @@ +import weakref from pypy.rpython.lltypesystem import lltype from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import AbstractDescr @@ -38,15 +39,17 @@ return getDescrClass(TYPE, AbstractFieldDescr, GcPtrFieldDescr, NonGcPtrFieldDescr, 'Field') -def get_field_descr(STRUCT, fieldname, translate_support_code, _cache={}): +def get_field_descr(STRUCT, fieldname, translate_support_code, + _cache=weakref.WeakKeyDictionary()): try: - return _cache[STRUCT, fieldname, translate_support_code] + return _cache[STRUCT][fieldname, translate_support_code] except KeyError: offset, _ = symbolic.get_field_token(STRUCT, fieldname, translate_support_code) FIELDTYPE = getattr(STRUCT, fieldname) fielddescr = getFieldDescrClass(FIELDTYPE)(offset) - _cache[STRUCT, fieldname, translate_support_code] = fielddescr + cachedict = _cache.setdefault(STRUCT, {}) + cachedict[fieldname, translate_support_code] = fielddescr return fielddescr @@ -85,7 +88,7 @@ return getDescrClass(ARRAY.OF, AbstractArrayDescr, GcPtrArrayDescr, NonGcPtrArrayDescr, 'Array') -def get_array_descr(ARRAY, _cache={}): +def get_array_descr(ARRAY, _cache=weakref.WeakKeyDictionary()): try: return _cache[ARRAY] except KeyError: From arigo at codespeak.net Sat Aug 29 14:07:02 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:07:02 +0200 (CEST) Subject: [pypy-svn] r67307 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829120702.37B1716801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:07:01 2009 New Revision: 67307 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: do_getfield. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:07:01 2009 @@ -1,9 +1,10 @@ import sys -from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib.objectmodel import we_are_translated +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr +from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib.unroll import unrolling_iterable from pypy.jit.metainterp.history import BoxInt, BoxPtr from pypy.jit.backend.model import AbstractCPU +from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr from pypy.jit.backend.llsupport.descr import AbstractFieldDescr from pypy.jit.backend.llsupport.descr import AbstractArrayDescr @@ -50,9 +51,25 @@ def fielddescrof(self, STRUCT, fieldname): return get_field_descr(STRUCT, fieldname, self.translate_support_code) + def unpack_fielddescr(self, fielddescr): + assert isinstance(fielddescr, AbstractFieldDescr) + ofs = fielddescr.offset + size = fielddescr.get_field_size(self.translate_support_code) + ptr = fielddescr.is_pointer_field() + return ofs, size, ptr + unpack_fielddescr._always_inline_ = True + def arraydescrof(self, A): return get_array_descr(A) + def unpack_arraydescr(self, arraydescr): + assert isinstance(arraydescr, AbstractArrayDescr) + ofs = arraydescr.get_base_size(self.translate_support_code) + size = arraydescr.get_item_size(self.translate_support_code) + ptr = arraydescr.is_array_of_pointers() + return ofs, size, ptr + unpack_arraydescr._always_inline_ = True + def do_arraylen_gc(self, args, arraydescr): assert isinstance(arraydescr, AbstractArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) @@ -61,24 +78,64 @@ return BoxInt(length) def do_getarrayitem_gc(self, args, arraydescr): - assert isinstance(arraydescr, AbstractArrayDescr) itemindex = args[1].getint() gcref = args[0].getptr_base() - ofs = arraydescr.get_base_size(self.translate_support_code) - size = arraydescr.get_item_size(self.translate_support_code) - ptr = arraydescr.is_array_of_pointers() + ofs, size, ptr = self.unpack_arraydescr(arraydescr) # for TYPE, itemsize in unroll_basic_sizes: if size == itemsize: val = (rffi.cast(rffi.CArrayPtr(TYPE), gcref) [ofs/itemsize + itemindex]) + val = rffi.cast(lltype.Signed, val) break else: raise NotImplementedError("size = %d" % size) if ptr: return BoxPtr(self.cast_int_to_gcref(val)) else: - return BoxInt(rffi.cast(lltype.Signed, val)) + return BoxInt(val) + + def _new_do_len(TP): + def do_strlen(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(TP, + self.translate_support_code) + gcref = args[0].getptr(llmemory.GCREF) + v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] + return BoxInt(v) + return do_strlen + + do_strlen = _new_do_len(rstr.STR) + do_unicodelen = _new_do_len(rstr.UNICODE) + + def do_strgetitem(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + gcref = args[0].getptr(llmemory.GCREF) + i = args[1].getint() + v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] + return BoxInt(ord(v)) + + @specialize.argtype(1) + def _base_do_getfield(self, gcref, fielddescr): + ofs, size, ptr = self.unpack_fielddescr(fielddescr) + for TYPE, itemsize in unroll_basic_sizes: + if size == itemsize: + val = rffi.cast(rffi.CArrayPtr(TYPE), gcref)[ofs/itemsize] + val = rffi.cast(lltype.Signed, val) + break + else: + raise NotImplementedError("size = %d" % size) + if ptr: + return BoxPtr(self.cast_int_to_gcref(val)) + else: + return BoxInt(val) + + def do_getfield_gc(self, args, fielddescr): + gcref = args[0].getptr(llmemory.GCREF) + return self._base_do_getfield(gcref, fielddescr) + + def do_getfield_raw(self, args, fielddescr): + return self._base_do_getfield(args[0].getint(), fielddescr) import pypy.jit.metainterp.executor From arigo at codespeak.net Sat Aug 29 14:11:51 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:11:51 +0200 (CEST) Subject: [pypy-svn] r67308 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829121151.724D716801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:11:51 2009 New Revision: 67308 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: do_setfield. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:11:51 2009 @@ -48,6 +48,9 @@ _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) + def cast_gcref_to_int(self, x): + return rffi.cast(lltype.Signed, x) + def fielddescrof(self, STRUCT, fieldname): return get_field_descr(STRUCT, fieldname, self.translate_support_code) @@ -99,7 +102,7 @@ def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getptr_base() v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] return BoxInt(v) return do_strlen @@ -110,7 +113,7 @@ def do_strgetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getptr_base() i = args[1].getint() v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) @@ -131,12 +134,39 @@ return BoxInt(val) def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getptr_base() return self._base_do_getfield(gcref, fielddescr) def do_getfield_raw(self, args, fielddescr): return self._base_do_getfield(args[0].getint(), fielddescr) + @specialize.argtype(1) + def _base_do_setfield(self, gcref, vbox, fielddescr): + ofs, size, ptr = self.unpack_fielddescr(fielddescr) + if ptr: + assert lltype.typeOf(gcref) is not lltype.Signed, ( + "can't handle write barriers for setfield_raw") + ptr = vbox.getptr_base() + self.gc_ll_descr.do_write_barrier(gcref, ptr) + a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) + a[ofs/WORD] = self.cast_gcref_to_int(ptr) + else: + v = vbox.getint() + for TYPE, itemsize in unroll_basic_sizes: + if size == itemsize: + v = rffi.cast(TYPE, v) + rffi.cast(rffi.CArrayPtr(TYPE), gcref)[ofs] = v + break + else: + raise NotImplementedError("size = %d" % size) + + def do_setfield_gc(self, args, fielddescr): + gcref = args[0].getptr_base() + self._base_do_setfield(gcref, args[1], fielddescr) + + def do_setfield_raw(self, args, fielddescr): + self._base_do_setfield(args[0].getint(), args[1], fielddescr) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) From arigo at codespeak.net Sat Aug 29 14:21:34 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:21:34 +0200 (CEST) Subject: [pypy-svn] r67309 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: . llsupport llsupport/test Message-ID: <20090829122134.872CA16801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:21:29 2009 New Revision: 67309 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Log: do_new with Boehm. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 14:21:29 2009 @@ -10,6 +10,25 @@ # ____________________________________________________________ +# SizeDescrs + +class SizeDescr(AbstractDescr): + def __init__(self, size): + self.size = size + +def get_size_descr(STRUCT, translate_support_code, + _cache=weakref.WeakKeyDictionary()): + try: + return _cache[STRUCT][translate_support_code] + except KeyError: + size = symbolic.get_size(STRUCT, translate_support_code) + sizedescr = SizeDescr(size) + cachedict = _cache.setdefault(STRUCT, {}) + cachedict[translate_support_code] = sizedescr + return sizedescr + + +# ____________________________________________________________ # FieldDescrs class AbstractFieldDescr(AbstractDescr): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 14:21:29 2009 @@ -4,6 +4,7 @@ from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.jit.backend.llsupport import symbolic +from pypy.jit.backend.llsupport.descr import SizeDescr # ____________________________________________________________ @@ -60,10 +61,9 @@ ptr = False return ConstDescr3(basesize, itemsize, ptr) - def gc_malloc(self, descrsize): - assert isinstance(descrsize, ConstDescr3) - size = descrsize.v0 - return self.funcptr_for_new(size) + def gc_malloc(self, sizedescr): + assert isinstance(sizedescr, SizeDescr) + return self.funcptr_for_new(sizedescr.size) def gc_malloc_array(self, arraydescr, num_elem): assert isinstance(arraydescr, ConstDescr3) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:21:29 2009 @@ -5,6 +5,7 @@ from pypy.jit.metainterp.history import BoxInt, BoxPtr from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.llsupport import symbolic +from pypy.jit.backend.llsupport.descr import get_size_descr, SizeDescr from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr from pypy.jit.backend.llsupport.descr import AbstractFieldDescr from pypy.jit.backend.llsupport.descr import AbstractArrayDescr @@ -51,6 +52,9 @@ def cast_gcref_to_int(self, x): return rffi.cast(lltype.Signed, x) + def sizeof(self, S): + return get_size_descr(S, self.translate_support_code) + def fielddescrof(self, STRUCT, fieldname): return get_field_descr(STRUCT, fieldname, self.translate_support_code) @@ -167,6 +171,10 @@ def do_setfield_raw(self, args, fielddescr): self._base_do_setfield(args[0].getint(), args[1], fielddescr) + def do_new(self, args, sizedescr): + res = self.gc_ll_descr.gc_malloc(sizedescr) + return BoxPtr(res) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 14:21:29 2009 @@ -1,8 +1,24 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.jit.backend.llsupport.descr import * +from pypy.jit.backend.llsupport import symbolic from pypy.rlib.objectmodel import Symbolic +def test_get_size_descr(): + T = lltype.GcStruct('T') + S = lltype.GcStruct('S', ('x', lltype.Char), + ('y', lltype.Ptr(T))) + descr_s = get_size_descr(S, False) + descr_t = get_size_descr(T, False) + assert descr_s.size == symbolic.get_size(S, False) + assert descr_t.size == symbolic.get_size(T, False) + assert descr_s == get_size_descr(S, False) + assert descr_s != get_size_descr(S, True) + # + descr_s = get_size_descr(S, True) + assert isinstance(descr_s.size, Symbolic) + + def test_get_field_descr(): U = lltype.Struct('U') T = lltype.GcStruct('T') Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Sat Aug 29 14:21:29 2009 @@ -128,7 +128,7 @@ def do_new(self, args, sizedescr): raise NotImplementedError - def do_new_with_vtable(self, args, sizedescr): + def do_new_with_vtable(self, args, descr=None): raise NotImplementedError def do_new_array(self, args, arraydescr): From arigo at codespeak.net Sat Aug 29 14:23:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:23:25 +0200 (CEST) Subject: [pypy-svn] r67310 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829122325.5EE6016801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:23:24 2009 New Revision: 67310 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: do_new_with_vtable. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:23:24 2009 @@ -1,5 +1,5 @@ import sys -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib.unroll import unrolling_iterable from pypy.jit.metainterp.history import BoxInt, BoxPtr @@ -36,6 +36,12 @@ self.stats = stats self.translate_support_code = translate_support_code self.gc_ll_descr = get_ll_description(gcdescr, self) + self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, + 'typeptr', + translate_support_code) + + def set_class_sizes(self, class_sizes): + self.class_sizes = class_sizes # ------------------- helpers and descriptions -------------------- @@ -175,6 +181,15 @@ res = self.gc_ll_descr.gc_malloc(sizedescr) return BoxPtr(res) + def do_new_with_vtable(self, args, descr=None): + assert descr is None + classint = args[0].getint() + descrsize = self.class_sizes[classint] + res = self.gc_ll_descr.gc_malloc(descrsize) + as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) + as_array[self.vtable_offset/WORD] = classint + return BoxPtr(res) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) From arigo at codespeak.net Sat Aug 29 14:35:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:35:25 +0200 (CEST) Subject: [pypy-svn] r67311 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829123525.E55AC16801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:35:25 2009 New Revision: 67311 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py Log: do_new_array, do_setarrayitem_gc. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 14:35:25 2009 @@ -4,7 +4,8 @@ from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llsupport.descr import SizeDescr +from pypy.jit.backend.llsupport.symbolic import WORD +from pypy.jit.backend.llsupport.descr import SizeDescr, AbstractArrayDescr # ____________________________________________________________ @@ -27,6 +28,7 @@ def __init__(self, gcdescr, cpu): # grab a pointer to the Boehm 'malloc' function + self.translate_support_code = cpu.translate_support_code compilation_info = ExternalCompilationInfo(libraries=['gc']) malloc_fn_ptr = rffi.llexternal("GC_local_malloc", [lltype.Signed], # size_t, but good enough @@ -46,32 +48,18 @@ init_fn_ptr() - def sizeof(self, S, translate_support_code): - size = symbolic.get_size(S, translate_support_code) - return ConstDescr3(size, 0, False) - - def arraydescrof(self, A, translate_support_code): - basesize, itemsize, ofs_length = symbolic.get_array_token(A, - translate_support_code) - assert rffi.sizeof(A.OF) in [1, 2, WORD] - # assert ofs_length == 0 --- but it's symbolic... - if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc': - ptr = True - else: - ptr = False - return ConstDescr3(basesize, itemsize, ptr) - def gc_malloc(self, sizedescr): assert isinstance(sizedescr, SizeDescr) return self.funcptr_for_new(sizedescr.size) def gc_malloc_array(self, arraydescr, num_elem): - assert isinstance(arraydescr, ConstDescr3) - basesize = arraydescr.v0 - itemsize = arraydescr.v1 + assert isinstance(arraydescr, AbstractArrayDescr) + ofs_length = arraydescr.get_ofs_length(self.translate_support_code) + basesize = arraydescr.get_base_size(self.translate_support_code) + itemsize = arraydescr.get_item_size(self.translate_support_code) size = basesize + itemsize * num_elem res = self.funcptr_for_new(size) - rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[0] = num_elem + rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem return res def gc_malloc_str(self, num_elem, translate_support_code): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:35:25 2009 @@ -1,25 +1,15 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rlib.objectmodel import we_are_translated, specialize -from pypy.rlib.unroll import unrolling_iterable from pypy.jit.metainterp.history import BoxInt, BoxPtr from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.llsupport import symbolic +from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes from pypy.jit.backend.llsupport.descr import get_size_descr, SizeDescr from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr from pypy.jit.backend.llsupport.descr import AbstractFieldDescr from pypy.jit.backend.llsupport.descr import AbstractArrayDescr -WORD = rffi.sizeof(lltype.Signed) -SIZEOF_CHAR = rffi.sizeof(lltype.Char) -SIZEOF_SHORT = rffi.sizeof(rffi.SHORT) -SIZEOF_INT = rffi.sizeof(rffi.INT) - -unroll_basic_sizes = unrolling_iterable([(lltype.Signed, WORD), - (lltype.Char, SIZEOF_CHAR), - (rffi.SHORT, SIZEOF_SHORT), - (rffi.INT, SIZEOF_INT)]) - def _check_addr_range(x): if sys.platform == 'linux2': # this makes assumption about address ranges that are valid @@ -83,6 +73,8 @@ return ofs, size, ptr unpack_arraydescr._always_inline_ = True + # ____________________________________________________________ + def do_arraylen_gc(self, args, arraydescr): assert isinstance(arraydescr, AbstractArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) @@ -108,6 +100,27 @@ else: return BoxInt(val) + def do_setarrayitem_gc(self, args, arraydescr): + itemindex = args[1].getint() + gcref = args[0].getptr_base() + ofs, size, ptr = self.unpack_arraydescr(arraydescr) + vbox = args[2] + # + if ptr: + vboxptr = vbox.getptr_base() + self.gc_ll_descr.do_write_barrier(gcref, vboxptr) + a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) + a[ofs/WORD + itemindex] = self.cast_gcref_to_int(vboxptr) + else: + v = vbox.getint() + for TYPE, itemsize in unroll_basic_sizes: + if size == itemsize: + a = rffi.cast(rffi.CArrayPtr(TYPE), gcref) + a[ofs/itemsize + itemindex] = rffi.cast(TYPE, v) + break + else: + raise NotImplementedError("size = %d" % size) + def _new_do_len(TP): def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, @@ -190,6 +203,11 @@ as_array[self.vtable_offset/WORD] = classint return BoxPtr(res) + def do_new_array(self, args, arraydescr): + num_elem = args[0].getint() + res = self.gc_ll_descr.gc_malloc_array(arraydescr, num_elem) + return BoxPtr(res) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py Sat Aug 29 14:35:25 2009 @@ -1,6 +1,7 @@ import ctypes -from pypy.rpython.lltypesystem import lltype, ll2ctypes, llmemory +from pypy.rpython.lltypesystem import lltype, ll2ctypes, llmemory, rffi from pypy.rlib.objectmodel import specialize +from pypy.rlib.unroll import unrolling_iterable @specialize.memo() def get_field_token(STRUCT, fieldname, translate_support_code): @@ -54,3 +55,14 @@ itemsize = ctypes.sizeof(carrayitem) return basesize, itemsize, ofs_length +# ____________________________________________________________ + +WORD = get_size(lltype.Signed, False) +SIZEOF_CHAR = get_size(lltype.Char, False) +SIZEOF_SHORT = get_size(rffi.SHORT, False) +SIZEOF_INT = get_size(rffi.INT, False) + +unroll_basic_sizes = unrolling_iterable([(lltype.Signed, WORD), + (lltype.Char, SIZEOF_CHAR), + (rffi.SHORT, SIZEOF_SHORT), + (rffi.INT, SIZEOF_INT)]) From arigo at codespeak.net Sat Aug 29 14:37:33 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:37:33 +0200 (CEST) Subject: [pypy-svn] r67312 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829123733.03BF416801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:37:33 2009 New Revision: 67312 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: do_newstr, do_strsetitem Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 14:37:33 2009 @@ -62,18 +62,18 @@ rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem return res - def gc_malloc_str(self, num_elem, translate_support_code): + def gc_malloc_str(self, num_elem): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, - translate_support_code) + self.translate_support_code) assert itemsize == 1 size = basesize + num_elem res = self.funcptr_for_new(size) rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem return res - def gc_malloc_unicode(self, num_elem, translate_support_code): + def gc_malloc_unicode(self, num_elem): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, - translate_support_code) + self.translate_support_code) size = basesize + num_elem * itemsize res = self.funcptr_for_new(size) rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:37:33 2009 @@ -208,6 +208,33 @@ res = self.gc_ll_descr.gc_malloc_array(arraydescr, num_elem) return BoxPtr(res) + def do_newstr(self, args, descr=None): + num_elem = args[0].getint() + res = self.gc_ll_descr.gc_malloc_str(num_elem) + return BoxPtr(res) + + def do_newunicode(self, args, descr=None): + num_elem = args[0].getint() + res = self.gc_ll_descr.gc_malloc_unicode(num_elem) + return BoxPtr(res) + + def do_strsetitem(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + self.translate_support_code) + index = args[1].getint() + v = args[2].getint() + a = args[0].getptr_base() + rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) + + def do_unicodesetitem(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, + self.translate_support_code) + index = args[1].getint() + v = args[2].getint() + a = args[0].getptr_base() + basesize = basesize // itemsize + rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) From arigo at codespeak.net Sat Aug 29 14:38:29 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 14:38:29 +0200 (CEST) Subject: [pypy-svn] r67313 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829123829.A601016801B@codespeak.net> Author: arigo Date: Sat Aug 29 14:38:29 2009 New Revision: 67313 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: do_cast_xxx_to_yyy. Now test_do_operations passes. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 14:38:29 2009 @@ -235,6 +235,12 @@ basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) + def do_cast_ptr_to_int(self, args, descr=None): + return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) + + def do_cast_int_to_ptr(self, args, descr=None): + return BoxPtr(self.cast_int_to_gcref(args[0].getint())) + import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU) From antocuni at codespeak.net Sat Aug 29 14:57:26 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 14:57:26 +0200 (CEST) Subject: [pypy-svn] r67314 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit: backend backend/cli backend/test backend/test/loopdata backend/x86 metainterp Message-ID: <20090829125726.EB77F16801B@codespeak.net> Author: antocuni Date: Sat Aug 29 14:57:26 2009 New Revision: 67314 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/logger.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/string.ops pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_loopparser.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Log: remove the is_oo attribute from the loggers, and attach ts instead. As a bonus, loopparser works also with ootype now Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/method.py Sat Aug 29 14:57:26 2009 @@ -9,6 +9,7 @@ from pypy.jit.metainterp.history import (AbstractValue, Const, ConstInt, ConstObj, BoxInt) from pypy.jit.metainterp.resoperation import rop, opname +from pypy.jit.metainterp.typesystem import oohelper from pypy.jit.backend.logger import AbstractLogger from pypy.jit.backend.cli import runner from pypy.jit.backend.cli.methodfactory import get_method_wrapper @@ -24,7 +25,6 @@ cVoid = ootype.nullruntimeclass class CliLogger(AbstractLogger): - is_oo = True def repr_of_descr(self, descr): from pypy.jit.backend.cli.runner import DescrWithKey @@ -32,7 +32,7 @@ return descr.short_repr() return AbstractLogger.repr_of_descr(self, descr) -logger = CliLogger() +logger = CliLogger(oohelper) runner.CliCPU.logger_cls = CliLogger # xxx hack class __extend__(AbstractValue): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/logger.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/logger.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/logger.py Sat Aug 29 14:57:26 2009 @@ -6,10 +6,9 @@ class AbstractLogger(object): - # is_oo = ... ## need to be set by concrete classes - - def __init__(self): + def __init__(self, ts): self._log_fd = -1 + self.ts = ts def create_log(self, extension='.ops'): if self._log_fd != -1: @@ -43,16 +42,12 @@ return "ci(%d,%d)" % (mv, arg.value) elif isinstance(arg, BoxInt): return "bi(%d,%d)" % (mv, arg.value) - elif not self.is_oo and isinstance(arg, ConstPtr): - return "cp(%d,%d)" % (mv, arg.get_()) - elif not self.is_oo and isinstance(arg, BoxPtr): - return "bp(%d,%d)" % (mv, arg.get_()) - elif not self.is_oo and isinstance(arg, ConstAddr): + elif isinstance(arg, self.ts.ConstRef): + return "cr(%d,%d)" % (mv, arg.get_()) + elif isinstance(arg, self.ts.BoxRef): + return "br(%d,%d)" % (mv, arg.get_()) + elif isinstance(arg, self.ts.ConstAddr): return "ca(%d,%d)" % (mv, arg.get_()) - elif self.is_oo and isinstance(arg, ConstObj): - return "co(%d,%d)" % (mv, arg.get_()) - elif self.is_oo and isinstance(arg, BoxObj): - return "bo(%d,%d)" % (mv, arg.get_()) else: #raise NotImplementedError return "?%r" % (arg,) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/loopparser.py Sat Aug 29 14:57:26 2009 @@ -115,8 +115,8 @@ class BoxAddr(Box): pass -class BoxPtr(Box): - _var_prefix = "p" +class BoxRef(Box): + _var_prefix = "r" class Const(AbstractValue): @@ -133,19 +133,19 @@ class ConstAddr(Const): pass -class ConstPtr(Const): +class ConstRef(Const): pass box_map = { 'b' : { 'i' : BoxInt, 'a' : BoxAddr, - 'p' : BoxPtr + 'r' : BoxRef }, 'c' : { 'i' : ConstInt, 'a' : ConstAddr, - 'p' : ConstPtr + 'r' : ConstRef }, } Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/simple.ops Sat Aug 29 14:57:26 2009 @@ -14,7 +14,7 @@ 6:jump bi(0,6),bi(5,3),bi(3,24) #19 8:guard_exception ci(85,138082236) - => bp(86,138081800) + => br(86,138081800) BEGIN(0) 0:fail bi(2,18)[] END Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/string.ops ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/string.ops (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/loopdata/string.ops Sat Aug 29 14:57:26 2009 @@ -1,5 +1,5 @@ -LOOP bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3) -0:call bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3)[5,0,False] +LOOP bi(0,-1207988264),br(1,177266788),br(2,177102816),bi(3,0),bi(4,0),bi(5,3) +0:call bi(0,-1207988264),br(1,177266788),br(2,177102816),bi(3,0),bi(4,0),bi(5,3)[5,0,False] => bi(6,0) 1:guard_no_exception BEGIN(0) @@ -7,30 +7,30 @@ END 2:fail bi(6,0) LOOP END -LOOP bp(0,177266788),bi(1,97) +LOOP br(0,177266788),bi(1,97) #(no jitdriver.get_printable_location!) 1:newstr ci(2,1) - => bp(3,177102832) -2:strsetitem bp(3,177102832),ci(4,0),bi(1,97) -3:strlen bp(0,177266788) + => br(3,177102832) +2:strsetitem br(3,177102832),ci(4,0),bi(1,97) +3:strlen br(0,177266788) => bi(5,3) -4:strlen bp(3,177102832) +4:strlen br(3,177102832) => bi(6,1) 5:int_add bi(5,3),bi(6,1) => bi(7,4) 6:int_ge bi(7,4),ci(4,0) => bi(8,1) 7:newstr bi(7,4) - => bp(9,177102816) -8:call ca(10,175948220),bp(0,177266788),bp(9,177102816),ci(4,0),ci(4,0),bi(5,3)[5,0,False] + => br(9,177102816) +8:call ca(10,175948220),br(0,177266788),br(9,177102816),ci(4,0),ci(4,0),bi(5,3)[5,0,False] 9:guard_no_exception BEGIN(0) - 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + 0:fail br(0,177266788),bi(1,97),br(3,177102832),bi(5,3),bi(6,1),bi(7,4),br(9,177102816)[] END -10:call ca(10,175948220),bp(3,177102832),bp(9,177102816),ci(4,0),bi(5,3),bi(6,1)[5,0,False] +10:call ca(10,175948220),br(3,177102832),br(9,177102816),ci(4,0),bi(5,3),bi(6,1)[5,0,False] 11:guard_no_exception BEGIN(0) - 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + 0:fail br(0,177266788),bi(1,97),br(3,177102832),bi(5,3),bi(6,1),bi(7,4),br(9,177102816)[] END 12:int_sub bi(1,97),ci(2,1) => bi(11,96) @@ -38,13 +38,13 @@ => bi(13,1) 14:guard_true bi(13,1) BEGIN(0) - 0:fail bi(11,96),bp(9,177102816)[] + 0:fail bi(11,96),br(9,177102816)[] END #(no jitdriver.get_printable_location!) -16:jump bp(9,177102816),bi(11,96) +16:jump br(9,177102816),bi(11,96) LOOP END -LOOP bi(0,-1207988312),bp(1,177134016) -0:call bi(0,-1207988312),bp(1,177134016)[1,4,False] +LOOP bi(0,-1207988312),br(1,177134016) +0:call bi(0,-1207988312),br(1,177134016)[1,4,False] => bi(2,0) 1:guard_no_exception BEGIN(0) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/test/test_loopparser.py Sat Aug 29 14:57:26 2009 @@ -45,7 +45,7 @@ assert code_comment.address == 19 guard_exception = topblock.operations[8] assert isinstance(guard_exception, GuardOperation) - assert isinstance(guard_exception.result, BoxPtr) + assert isinstance(guard_exception.result, BoxRef) assert guard_exception.result.value == 138081800 def test_two_paths(self): @@ -74,7 +74,7 @@ assert len(loops) == 3 newstr = loops[1].operations[1] assert newstr.opname == "newstr" - assert isinstance(newstr.result, BoxPtr) + assert isinstance(newstr.result, BoxRef) assert len(newstr.args) == 1 assert isinstance(newstr.args[0], ConstInt) assert newstr.result.value == 177102832 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py Sat Aug 29 14:57:26 2009 @@ -107,7 +107,7 @@ self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed)) self._exception_addr = 0 self.mcstack = MachineCodeStack() - self.logger = x86Logger() + self.logger = x86Logger(cpu.ts) self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed), MAX_FAIL_BOXES, zero=True) self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF), Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/pyjitpl.py Sat Aug 29 14:57:26 2009 @@ -990,7 +990,7 @@ self.stats = stats self.options = options if cpu.logger_cls is not None: - options.logger_noopt = cpu.logger_cls() + options.logger_noopt = cpu.logger_cls(cpu.ts) RESULT = portal_graph.getreturnvar().concretetype self.result_type = history.getkind(RESULT) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/metainterp/typesystem.py Sat Aug 29 14:57:26 2009 @@ -44,6 +44,7 @@ BASETYPE = llmemory.GCREF BoxRef = history.BoxPtr ConstRef = history.ConstPtr + ConstAddr = history.ConstAddr loops_done_with_this_frame_ref = None # patched by compile.py CVAL_NULLREF = None # patched by optimizeopt.py @@ -144,6 +145,7 @@ BASETYPE = ootype.Object BoxRef = history.BoxObj ConstRef = history.ConstObj + ConstAddr = history.ConstObj loops_done_with_this_frame_ref = None # patched by compile.py CVAL_NULLREF = None # patched by optimizeopt.py From antocuni at codespeak.net Sat Aug 29 15:00:26 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 15:00:26 +0200 (CEST) Subject: [pypy-svn] r67315 - in pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend: cli llvm x86 Message-ID: <20090829130026.ECE1316801B@codespeak.net> Author: antocuni Date: Sat Aug 29 15:00:26 2009 New Revision: 67315 Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Log: remove the is_oo attribute from all backends but llgraph, where is still needed because of few hacks I don't want to fix now Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/cli/runner.py Sat Aug 29 15:00:26 2009 @@ -32,7 +32,6 @@ class CliCPU(model.AbstractCPU): ts = oohelper - is_oo = True def __init__(self, rtyper, stats, translate_support_code=False, mixlevelann=None, gcdescr=None): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/llvm/runner.py Sat Aug 29 15:00:26 2009 @@ -17,7 +17,6 @@ class LLVMCPU(object): ts = llhelper - is_oo = False logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/assembler.py Sat Aug 29 15:00:26 2009 @@ -31,8 +31,6 @@ class x86Logger(AbstractLogger): - is_oo = False - def repr_of_descr(self, descr): from pypy.jit.backend.x86.runner import ConstDescr3 if isinstance(descr, ConstDescr3): Modified: pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-less-is_oo/pypy/jit/backend/x86/runner.py Sat Aug 29 15:00:26 2009 @@ -49,7 +49,6 @@ class CPU386(object): debug = True - is_oo = False ts = llhelper logger_cls = x86Logger From arigo at codespeak.net Sat Aug 29 16:09:14 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 16:09:14 +0200 (CEST) Subject: [pypy-svn] r67316 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: . llsupport Message-ID: <20090829140914.7D855168015@codespeak.net> Author: arigo Date: Sat Aug 29 16:09:13 2009 New Revision: 67316 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Log: do_call. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 16:09:13 2009 @@ -1,7 +1,9 @@ import weakref from pypy.rpython.lltypesystem import lltype from pypy.jit.backend.llsupport import symbolic -from pypy.jit.metainterp.history import AbstractDescr +from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr +from pypy.jit.metainterp.history import TreeLoop +from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances # as compact as possible. This is done by not storing the field size or @@ -112,11 +114,99 @@ return _cache[ARRAY] except KeyError: arraydescr = getArrayDescrClass(ARRAY)() + # verify basic assumption that all arrays' basesize and ofslength + # are equal + basesize, itemsize, ofslength = symbolic.get_array_token(ARRAY, False) + assert basesize == arraydescr.get_base_size(False) + assert itemsize == arraydescr.get_item_size(False) + assert ofslength == arraydescr.get_ofs_length(False) _cache[ARRAY] = arraydescr return arraydescr # ____________________________________________________________ +# CallDescrs + +class AbstractCallDescr(AbstractDescr): + call_loop = None + + def __init__(self, arg_classes): + self.arg_classes = arg_classes # list of BoxInt/BoxPtr classes + + def returns_a_pointer(self): + return False # unless overridden by GcPtrCallDescr + + def get_result_size(self, translate_support_code): + raise NotImplementedError + + def get_loop_for_call(self, cpu): + if self.call_loop is not None: + return self.call_loop + args = [cls() for cls in self.arg_classes] + if self.get_result_size(cpu.translate_support_code) == 0: + result = None + result_list = [] + else: + if self.returns_a_pointer(): + result = BoxPtr() + else: + result = BoxInt() + result_list = [result] + operations = [ + ResOperation(rop.CALL, args, result, self), + ResOperation(rop.GUARD_NO_EXCEPTION, [], None), + ResOperation(rop.FAIL, result_list, None)] + operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] + loop = TreeLoop('call') + loop.inputargs = args + loop.operations = operations + cpu.compile_operations(loop) + self.call_loop = loop + return loop + + +class GcPtrCallDescr(AbstractCallDescr): + def returns_a_pointer(self): + return True + + def get_result_size(self, translate_support_code): + return symbolic.get_size_of_ptr(translate_support_code) + +class IntCallDescr(AbstractCallDescr): + def __init__(self, arg_classes, result_size): + AbstractCallDescr.__init__(self, arg_classes) + self.result_size = result_size + + def get_result_size(self, translate_support_code): + return self.result_size + + +def get_call_descr(ARGS, RESULT, translate_support_code, _cache={}): + arg_classes = [] + for ARG in ARGS: + kind = getkind(ARG) + if kind == 'int': arg_classes.append(BoxInt) + elif kind == 'ptr': arg_classes.append(BoxPtr) + else: + raise NotImplementedError('ARG = %r' % (ARG,)) + if RESULT is lltype.Void: + result_size = 0 + else: + result_size = symbolic.get_size(RESULT, translate_support_code) + ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc' + key = (translate_support_code, tuple(arg_classes), result_size, ptr) + try: + return _cache[key] + except KeyError: + if ptr: + calldescr = GcPtrCallDescr(arg_classes) + else: + calldescr = IntCallDescr(arg_classes, result_size) + _cache[key] = calldescr + return calldescr + + +# ____________________________________________________________ def getDescrClass(TYPE, AbstractDescr, GcPtrDescr, NonGcPtrDescr, nameprefix, _cache={}): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 16:09:13 2009 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rlib.objectmodel import we_are_translated, specialize -from pypy.jit.metainterp.history import BoxInt, BoxPtr +from pypy.jit.metainterp.history import BoxInt, BoxPtr, set_future_values from pypy.jit.backend.model import AbstractCPU from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes @@ -9,6 +9,7 @@ from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr from pypy.jit.backend.llsupport.descr import AbstractFieldDescr from pypy.jit.backend.llsupport.descr import AbstractArrayDescr +from pypy.jit.backend.llsupport.descr import get_call_descr, AbstractCallDescr def _check_addr_range(x): if sys.platform == 'linux2': @@ -18,6 +19,7 @@ class AbstractLLCPU(AbstractCPU): + is_oo = False def __init__(self, rtyper, stats, translate_support_code=False, gcdescr=None): @@ -73,6 +75,9 @@ return ofs, size, ptr unpack_arraydescr._always_inline_ = True + def calldescrof(self, FUNC, ARGS, RESULT): + return get_call_descr(ARGS, RESULT, self.translate_support_code) + # ____________________________________________________________ def do_arraylen_gc(self, args, arraydescr): @@ -235,6 +240,23 @@ basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) + def do_call(self, args, calldescr): + assert isinstance(calldescr, AbstractCallDescr) + if not we_are_translated(): + assert ([cls.type for cls in calldescr.arg_classes] == + [arg.type for arg in args[1:]]) + loop = calldescr.get_loop_for_call(self) + set_future_values(self, args) + self.execute_operations(loop) + # Note: if an exception is set, the rest of the code does a bit of + # nonsense but nothing wrong (the return value should be ignored) + if calldescr.returns_a_pointer(): + return BoxPtr(self.get_latest_value_ptr(0)) + elif calldescr.get_result_size(self.translate_support_code) != 0: + return BoxInt(self.get_latest_value_int(0)) + else: + return None + def do_cast_ptr_to_int(self, args, descr=None): return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Sat Aug 29 16:09:13 2009 @@ -79,6 +79,8 @@ @staticmethod def calldescrof(FUNC, ARGS, RESULT): + # FUNC is the original function type, but ARGS is a list of types + # with Voids removed raise NotImplementedError @staticmethod From antocuni at codespeak.net Sat Aug 29 16:20:27 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 16:20:27 +0200 (CEST) Subject: [pypy-svn] r67317 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/cli backend/llgraph backend/llgraph/test backend/llvm backend/test backend/test/loopdata backend/x86 backend/x86/test metainterp metainterp/test tl/spli/test Message-ID: <20090829142027.DE6C1168015@codespeak.net> Author: antocuni Date: Sat Aug 29 16:20:26 2009 New Revision: 67317 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/logger.py pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/model.py pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Log: merge the pyjitpl5-less-is_oo branch svn merge svn+ssh://codespeak.net/svn/pypy/branch/pyjitpl5-less-is_oo/pypy -r67234:67315 ------------------------------------------------------------------------ r67234 | antocuni | 2009-08-27 14:58:28 +0200 (Thu, 27 Aug 2009) | 3 lines a branch to reduce the number of "if is_oo" and move to a more object-oriented style ------------------------------------------------------------------------ r67240 | antocuni | 2009-08-27 15:23:01 +0200 (Thu, 27 Aug 2009) | 6 lines attach the ts helper to the cpu instead of to the staticdata. This already simplifies things a bit, and moreover assure that ts will be available wherever is_oo is tested ------------------------------------------------------------------------ r67248 | antocuni | 2009-08-27 16:21:54 +0200 (Thu, 27 Aug 2009) | 10 lines unify {Const,Box}{Obj,Ptr} interfaces: - rename getptr_base and getobj to getref_base - rename getptr to getref - introduce getref for objects, which helps to get rid of a lot of ootype.cast_from_object(...) ------------------------------------------------------------------------ r67250 | antocuni | 2009-08-27 16:38:33 +0200 (Thu, 27 Aug 2009) | 4 lines unify history.PTR and history.OBJ into history.REF; this let us to remove a bit of code duplication here and there ------------------------------------------------------------------------ r67251 | antocuni | 2009-08-27 16:53:08 +0200 (Thu, 27 Aug 2009) | 2 lines remove one more "if is_oo" by introducing a helper method in ts ------------------------------------------------------------------------ r67253 | antocuni | 2009-08-27 17:50:11 +0200 (Thu, 27 Aug 2009) | 2 lines unify ExitFrameWithException{Obj,Ptr} into ExitFrameWithExceptionRef ------------------------------------------------------------------------ r67256 | antocuni | 2009-08-27 18:11:51 +0200 (Thu, 27 Aug 2009) | 8 lines - rename set_future_value_{obj,ptr} to *_ref; the same for get_lastest_value_{obj,ptr) - unify ExitFrameWithExceptionDescr{Obj,Ptr} ExitFrameWithExceptionDescrRef ------------------------------------------------------------------------ r67257 | antocuni | 2009-08-27 18:29:54 +0200 (Thu, 27 Aug 2009) | 4 lines make history.getkind returning 'ref' instead of 'ptr' or 'obj'; fix a lot of places that used 'p' instead of history.PTR to use the new history.REF instead ------------------------------------------------------------------------ r67258 | antocuni | 2009-08-27 18:32:56 +0200 (Thu, 27 Aug 2009) | 2 lines oups, forgot to fix this place ------------------------------------------------------------------------ r67259 | antocuni | 2009-08-27 22:00:52 +0200 (Thu, 27 Aug 2009) | 2 lines unify DoneWithThisFrame{Obj,Ptr} ------------------------------------------------------------------------ r67260 | antocuni | 2009-08-27 22:07:35 +0200 (Thu, 27 Aug 2009) | 2 lines unify Box.changevalue_{obj,ptr} and get rid of a couple of is_oo ------------------------------------------------------------------------ r67261 | antocuni | 2009-08-27 22:12:02 +0200 (Thu, 27 Aug 2009) | 2 lines get rid of one more is_oo ------------------------------------------------------------------------ r67262 | antocuni | 2009-08-27 22:19:02 +0200 (Thu, 27 Aug 2009) | 3 lines unify loops_done_with_this_frame_{obj,ptr} and loops_exit_frame_with_exception_{obj,ptr} ------------------------------------------------------------------------ r67263 | antocuni | 2009-08-27 22:26:24 +0200 (Thu, 27 Aug 2009) | 3 lines remove last is_oos from warmspot.py ------------------------------------------------------------------------ r67265 | antocuni | 2009-08-27 23:42:29 +0200 (Thu, 27 Aug 2009) | 2 lines get rid of the various is_oo in virtualizable.py ------------------------------------------------------------------------ r67266 | antocuni | 2009-08-27 23:48:10 +0200 (Thu, 27 Aug 2009) | 2 lines rpython fix ------------------------------------------------------------------------ r67267 | antocuni | 2009-08-27 23:57:54 +0200 (Thu, 27 Aug 2009) | 2 lines get rid of is_oos in optimizeopt.py ------------------------------------------------------------------------ r67268 | antocuni | 2009-08-28 00:05:27 +0200 (Fri, 28 Aug 2009) | 2 lines these changes belong to r67257 ------------------------------------------------------------------------ r67293 | antocuni | 2009-08-29 11:00:51 +0200 (Sat, 29 Aug 2009) | 10 lines veeery obscure. If we import rvirtualizable2 in the class body, it indirectly triggers the importing of rpython.exceptiondata *before* py.test's magic has patched AssertionError; as a consequence, exceptiondata.standardexceptions contains the standard AssertionError, but it will causes troubles later when the code will reference py.__.magic.AssertionError. I'm not sure if the fault is mine, of py.test or of exceptiondata, but deferring the importing of rvirtualizable2 fixes the issue. ------------------------------------------------------------------------ r67294 | antocuni | 2009-08-29 11:11:41 +0200 (Sat, 29 Aug 2009) | 3 lines fix test_casts, which had been broken by r67259 ------------------------------------------------------------------------ r67295 | antocuni | 2009-08-29 11:27:56 +0200 (Sat, 29 Aug 2009) | 2 lines remove one more is_oo ------------------------------------------------------------------------ r67297 | antocuni | 2009-08-29 11:38:16 +0200 (Sat, 29 Aug 2009) | 2 lines get rid of two more is_oos ------------------------------------------------------------------------ r67301 | antocuni | 2009-08-29 13:24:17 +0200 (Sat, 29 Aug 2009) | 2 lines this test has been failing for ages probably, as the nightly tests don't pass --slow. Mark it as expected to fail ------------------------------------------------------------------------ r67302 | antocuni | 2009-08-29 13:26:07 +0200 (Sat, 29 Aug 2009) | 2 lines remove yet another is_oo ------------------------------------------------------------------------ r67303 | antocuni | 2009-08-29 13:37:59 +0200 (Sat, 29 Aug 2009) | 2 lines unify llimpl.compile_start_{obj,ptr}_var and remove one is_oo ------------------------------------------------------------------------ r67304 | antocuni | 2009-08-29 13:43:14 +0200 (Sat, 29 Aug 2009) | 3 lines unify llimpl.compile_add_{ptr,obj}_const and llimpl.compile_add_{ptr,obj}_result ------------------------------------------------------------------------ r67314 | antocuni | 2009-08-29 14:57:26 +0200 (Sat, 29 Aug 2009) | 4 lines remove the is_oo attribute from the loggers, and attach ts instead. As a bonus, loopparser works also with ootype now ------------------------------------------------------------------------ r67315 | antocuni | 2009-08-29 15:00:26 +0200 (Sat, 29 Aug 2009) | 2 lines remove the is_oo attribute from all backends but llgraph, where is still needed because of few hacks I don't want to fix now ------------------------------------------------------------------------ Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Sat Aug 29 16:20:26 2009 @@ -9,6 +9,7 @@ from pypy.jit.metainterp.history import (AbstractValue, Const, ConstInt, ConstObj, BoxInt) from pypy.jit.metainterp.resoperation import rop, opname +from pypy.jit.metainterp.typesystem import oohelper from pypy.jit.backend.logger import AbstractLogger from pypy.jit.backend.cli import runner from pypy.jit.backend.cli.methodfactory import get_method_wrapper @@ -24,7 +25,6 @@ cVoid = ootype.nullruntimeclass class CliLogger(AbstractLogger): - is_oo = True def repr_of_descr(self, descr): from pypy.jit.backend.cli.runner import DescrWithKey @@ -32,7 +32,7 @@ return descr.short_repr() return AbstractLogger.repr_of_descr(self, descr) -logger = CliLogger() +logger = CliLogger(oohelper) runner.CliCPU.logger_cls = CliLogger # xxx hack class __extend__(AbstractValue): @@ -44,7 +44,7 @@ if self.type == history.INT: return dotnet.typeof(System.Int32) - elif self.type == history.OBJ: + elif self.type == history.REF: return dotnet.typeof(System.Object) else: assert False, 'Unknown type: %s' % self.type @@ -71,7 +71,7 @@ assert False, 'cannot store() to Constant' def get_cliobj(self): - return dotnet.cast_to_native_object(self.getobj()) + return dotnet.cast_to_native_object(self.getref_base()) class __extend__(ConstInt): __metaclass__ = extendabletype @@ -228,7 +228,6 @@ # initialize the array of genconsts consts = dotnet.new_array(System.Object, len(self.consts)) for av_const, i in self.consts.iteritems(): - #consts[i] = dotnet.cast_to_native_object(av_const.getobj()) consts[i] = av_const.get_cliobj() # build the delegate func = self.meth_wrapper.create_delegate(delegatetype, consts) @@ -283,7 +282,7 @@ t = dotnet.typeof(InputArgs) if type == history.INT: fieldname = 'ints' - elif type == history.OBJ: + elif type == history.REF: fieldname = 'objs' else: assert False, 'Unknown type %s' % type @@ -459,7 +458,7 @@ il_label = self.newbranch(op) classbox = op.args[0] assert isinstance(classbox, ConstObj) - oocls = ootype.cast_from_object(ootype.Class, classbox.getobj()) + oocls = classbox.getref(ootype.Class) clitype = dotnet.class2type(oocls) self.av_inputargs.load(self) self.il.Emit(OpCodes.Ldfld, self.exc_value_field) @@ -507,7 +506,7 @@ def emit_op_new_with_vtable(self, op): clsbox = op.args[0] assert isinstance(clsbox, ConstObj) - cls = clsbox.getobj() + cls = clsbox.getref_base() descr = self.cpu.class_sizes[cls] assert isinstance(descr, runner.TypeDescr) clitype = descr.get_clitype() Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Sat Aug 29 16:20:26 2009 @@ -11,6 +11,7 @@ from pypy.jit.backend.llgraph.runner import KeyManager from pypy.translator.cli import dotnet from pypy.translator.cli.dotnet import CLR +from pypy.jit.metainterp.typesystem import oohelper System = CLR.System OpCodes = System.Reflection.Emit.OpCodes @@ -29,8 +30,8 @@ class CliCPU(model.AbstractCPU): - - is_oo = True + + ts = oohelper def __init__(self, rtyper, stats, translate_support_code=False, mixlevelann=None, gcdescr=None): @@ -103,14 +104,14 @@ def set_future_value_int(self, index, intvalue): self.get_inputargs().set_int(index, intvalue) - def set_future_value_obj(self, index, objvalue): + def set_future_value_ref(self, index, objvalue): obj = dotnet.cast_to_native_object(objvalue) self.get_inputargs().set_obj(index, obj) def get_latest_value_int(self, index): return self.get_inputargs().get_int(index) - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): obj = self.get_inputargs().get_obj(index) return dotnet.cast_from_native_object(obj) @@ -160,7 +161,7 @@ #assert len(args) == 1 # but we don't need it, so ignore assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -171,7 +172,7 @@ def do_runtimenew(self, args, descr): classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return BoxObj(ootype.cast_to_object(res)) @@ -294,21 +295,21 @@ n = lengthbox.getint() return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() if TYPE is not ootype.Void: return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): if isinstance(TYPE, ootype.Instance): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return BoxInt(ootype.instanceof(obj, TYPE)) return None self.create = create @@ -319,7 +320,7 @@ self.instanceof = instanceof self.ooclass = get_class_for_type(TYPE) self.typename = TYPE._short_name() - self._is_array_of_pointers = (history.getkind(TYPE) == 'obj') + self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') def is_array_of_pointers(self): # for arrays, TYPE is the type of the array item. @@ -349,7 +350,7 @@ from pypy.jit.backend.llgraph.runner import boxresult, make_getargs getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = funcobj(*funcargs) if RESULT is not ootype.Void: @@ -392,7 +393,7 @@ METH = ootype.typeOf(meth) getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = meth(*methargs) @@ -441,11 +442,11 @@ from pypy.jit.metainterp.warmspot import unwrap _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) @@ -454,7 +455,7 @@ self.selfclass = ootype.runtimeClass(TYPE) self.fieldname = fieldname self.key = key_manager.getkey((TYPE, fieldname)) - self._is_pointer_field = (history.getkind(T) == 'obj') + self._is_pointer_field = (history.getkind(T) == 'ref') def is_pointer_field(self): return self._is_pointer_field Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 29 16:20:26 2009 @@ -8,7 +8,7 @@ from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, ConstObj, - BoxInt, BoxPtr, BoxObj) + BoxInt, BoxPtr, BoxObj, REF) from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.module.support import LLSupport, OOSupport @@ -83,56 +83,56 @@ 'uint_xor' : (('int', 'int'), 'int'), 'uint_rshift' : (('int', 'int'), 'int'), 'same_as' : (('int',), 'int'), # could also be ptr=>ptr - 'new_with_vtable' : (('ptr',), 'ptr'), - 'new' : ((), 'ptr'), - 'new_array' : (('int',), 'ptr'), - 'oononnull' : (('ptr',), 'bool'), - 'ooisnull' : (('ptr',), 'bool'), - 'oois' : (('ptr', 'ptr'), 'bool'), - 'ooisnot' : (('ptr', 'ptr'), 'bool'), - 'instanceof' : (('ptr',), 'bool'), - 'subclassof' : (('ptr', 'ptr'), 'bool'), - 'setfield_gc' : (('ptr', 'intorptr'), None), - 'getfield_gc' : (('ptr',), 'intorptr'), - 'getfield_gc_pure': (('ptr',), 'intorptr'), - 'setfield_raw' : (('ptr', 'intorptr'), None), - 'getfield_raw' : (('ptr',), 'intorptr'), - 'getfield_raw_pure': (('ptr',), 'intorptr'), - 'setarrayitem_gc' : (('ptr', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ptr', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ptr', 'int'), 'intorptr'), - 'arraylen_gc' : (('ptr',), 'int'), - 'call' : (('ptr', 'varargs'), 'intorptr'), - 'call_pure' : (('ptr', 'varargs'), 'intorptr'), + 'new_with_vtable' : (('ref',), 'ref'), + 'new' : ((), 'ref'), + 'new_array' : (('int',), 'ref'), + 'oononnull' : (('ref',), 'bool'), + 'ooisnull' : (('ref',), 'bool'), + 'oois' : (('ref', 'ref'), 'bool'), + 'ooisnot' : (('ref', 'ref'), 'bool'), + 'instanceof' : (('ref',), 'bool'), + 'subclassof' : (('ref', 'ref'), 'bool'), + 'setfield_gc' : (('ref', 'intorptr'), None), + 'getfield_gc' : (('ref',), 'intorptr'), + 'getfield_gc_pure': (('ref',), 'intorptr'), + 'setfield_raw' : (('ref', 'intorptr'), None), + 'getfield_raw' : (('ref',), 'intorptr'), + 'getfield_raw_pure': (('ref',), 'intorptr'), + 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), + 'arraylen_gc' : (('ref',), 'int'), + 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_pure' : (('ref', 'varargs'), 'intorptr'), 'oosend' : (('varargs',), 'intorptr'), 'oosend_pure' : (('varargs',), 'intorptr'), 'guard_true' : (('bool',), None), 'guard_false' : (('bool',), None), 'guard_value' : (('int', 'int'), None), - 'guard_class' : (('ptr', 'ptr'), None), + 'guard_class' : (('ref', 'ref'), None), 'guard_no_exception' : ((), None), - 'guard_exception' : (('ptr',), 'ptr'), + 'guard_exception' : (('ref',), 'ref'), 'guard_no_overflow' : ((), None), 'guard_overflow' : ((), None), - 'newstr' : (('int',), 'ptr'), - 'strlen' : (('ptr',), 'int'), - 'strgetitem' : (('ptr', 'int'), 'int'), - 'strsetitem' : (('ptr', 'int', 'int'), None), - 'newunicode' : (('int',), 'ptr'), - 'unicodelen' : (('ptr',), 'int'), - 'unicodegetitem' : (('ptr', 'int'), 'int'), - 'unicodesetitem' : (('ptr', 'int', 'int'), 'int'), - 'cast_ptr_to_int' : (('ptr',), 'int'), - 'cast_int_to_ptr' : (('int',), 'ptr'), - 'debug_merge_point': (('ptr',), None), - #'getitem' : (('void', 'ptr', 'int'), 'int'), - #'setitem' : (('void', 'ptr', 'int', 'int'), None), - #'newlist' : (('void', 'varargs'), 'ptr'), - #'append' : (('void', 'ptr', 'int'), None), - #'insert' : (('void', 'ptr', 'int', 'int'), None), - #'pop' : (('void', 'ptr',), 'int'), - #'len' : (('void', 'ptr',), 'int'), - #'listnonzero' : (('void', 'ptr',), 'int'), + 'newstr' : (('int',), 'ref'), + 'strlen' : (('ref',), 'int'), + 'strgetitem' : (('ref', 'int'), 'int'), + 'strsetitem' : (('ref', 'int', 'int'), None), + 'newunicode' : (('int',), 'ref'), + 'unicodelen' : (('ref',), 'int'), + 'unicodegetitem' : (('ref', 'int'), 'int'), + 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), + 'cast_ptr_to_int' : (('ref',), 'int'), + 'cast_int_to_ptr' : (('int',), 'ref'), + 'debug_merge_point': (('ref',), None), + #'getitem' : (('void', 'ref', 'int'), 'int'), + #'setitem' : (('void', 'ref', 'int', 'int'), None), + #'newlist' : (('void', 'varargs'), 'ref'), + #'append' : (('void', 'ref', 'int'), None), + #'insert' : (('void', 'ref', 'int', 'int'), None), + #'pop' : (('void', 'ref',), 'int'), + #'len' : (('void', 'ref',), 'int'), + #'listnonzero' : (('void', 'ref',), 'int'), } # ____________________________________________________________ @@ -215,14 +215,14 @@ if tp == "intorptr": TYPE = lltype.typeOf(x) if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - tp = "ptr" + tp = "ref" else: tp = "int" if tp == 'int': return str(x) elif tp == 'void': return '---' - elif tp == 'ptr': + elif tp == 'ref': if not x: return '(* None)' if isinstance(x, int): @@ -267,21 +267,11 @@ _variables.append(v) return r -def compile_start_ptr_var(loop): +def compile_start_ref_var(loop, TYPE): loop = _from_opaque(loop) assert not loop.operations v = Variable() - v.concretetype = llmemory.GCREF - loop.inputargs.append(v) - r = len(_variables) - _variables.append(v) - return r - -def compile_start_obj_var(loop): - loop = _from_opaque(loop) - assert not loop.operations - v = Variable() - v.concretetype = ootype.Object + v.concretetype = TYPE loop.inputargs.append(v) r = len(_variables) _variables.append(v) @@ -310,7 +300,7 @@ op = loop.operations[-1] op.args.append(const) -def compile_add_ptr_const(loop, value, TYPE=llmemory.GCREF): +def compile_add_ref_const(loop, value, TYPE): loop = _from_opaque(loop) const = Constant(value) const.concretetype = TYPE @@ -327,7 +317,7 @@ _variables.append(v) return r -def compile_add_ptr_result(loop, TYPE=llmemory.GCREF): +def compile_add_ref_result(loop, TYPE): loop = _from_opaque(loop) v = Variable() v.concretetype = TYPE @@ -624,7 +614,7 @@ # delegating to the builtins do_xxx() (done automatically for simple cases) def op_getarrayitem_gc(self, arraydescr, array, index): - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: return do_getarrayitem_gc_ptr(array, index) else: return do_getarrayitem_gc_int(array, index, self.memocast) @@ -632,7 +622,7 @@ op_getarrayitem_gc_pure = op_getarrayitem_gc def op_getfield_gc(self, fielddescr, struct): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return do_getfield_gc_ptr(struct, fielddescr.ofs) else: return do_getfield_gc_int(struct, fielddescr.ofs, self.memocast) @@ -640,7 +630,7 @@ op_getfield_gc_pure = op_getfield_gc def op_getfield_raw(self, fielddescr, struct): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return do_getfield_raw_ptr(struct, fielddescr.ofs, self.memocast) else: return do_getfield_raw_int(struct, fielddescr.ofs, self.memocast) @@ -657,20 +647,20 @@ return result def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: do_setarrayitem_gc_ptr(array, index, newvalue) else: do_setarrayitem_gc_int(array, index, newvalue, self.memocast) def op_setfield_gc(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: do_setfield_gc_int(struct, fielddescr.ofs, newvalue, self.memocast) def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memocast) else: @@ -681,7 +671,7 @@ _call_args[:] = args if calldescr.typeinfo == 'v': err_result = None - elif calldescr.typeinfo == 'p': + elif calldescr.typeinfo == REF: err_result = lltype.nullptr(llmemory.GCREF.TO) else: assert calldescr.typeinfo == 'i' @@ -866,12 +856,7 @@ assert len(_future_values) == index _future_values.append(value) -def set_future_value_ptr(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) - -def set_future_value_obj(index, value): +def set_future_value_ref(index, value): del _future_values[index:] assert len(_future_values) == index _future_values.append(value) @@ -1257,15 +1242,14 @@ setannotation(compile_start, s_CompiledLoop) setannotation(compile_start_int_var, annmodel.SomeInteger()) -setannotation(compile_start_ptr_var, annmodel.SomeInteger()) -setannotation(compile_start_obj_var, annmodel.SomeInteger()) +setannotation(compile_start_ref_var, annmodel.SomeInteger()) setannotation(compile_add, annmodel.s_None) setannotation(compile_add_descr, annmodel.s_None) setannotation(compile_add_var, annmodel.s_None) setannotation(compile_add_int_const, annmodel.s_None) -setannotation(compile_add_ptr_const, annmodel.s_None) +setannotation(compile_add_ref_const, annmodel.s_None) setannotation(compile_add_int_result, annmodel.SomeInteger()) -setannotation(compile_add_ptr_result, annmodel.SomeInteger()) +setannotation(compile_add_ref_result, annmodel.SomeInteger()) setannotation(compile_add_jump_target, annmodel.s_None) setannotation(compile_add_fail, annmodel.s_None) setannotation(compile_suboperations, s_CompiledLoop) @@ -1274,8 +1258,7 @@ setannotation(new_frame, s_Frame) setannotation(frame_clear, annmodel.s_None) setannotation(set_future_value_int, annmodel.s_None) -setannotation(set_future_value_ptr, annmodel.s_None) -setannotation(set_future_value_obj, annmodel.s_None) +setannotation(set_future_value_ref, annmodel.s_None) setannotation(frame_execute, annmodel.SomeInteger()) setannotation(frame_int_getvalue, annmodel.SomeInteger()) setannotation(frame_ptr_getvalue, annmodel.SomePtr(llmemory.GCREF)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py Sat Aug 29 16:20:26 2009 @@ -8,11 +8,12 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.llinterp import LLInterpreter from pypy.jit.metainterp import history +from pypy.jit.metainterp.history import REF from pypy.jit.metainterp.warmspot import unwrap from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic - +from pypy.jit.metainterp.typesystem import llhelper, oohelper class MiniStats: pass @@ -44,10 +45,10 @@ return self.ofs def is_pointer_field(self): - return self.typeinfo == 'p' + return self.typeinfo == REF def is_array_of_pointers(self): - return self.typeinfo == 'p' + return self.typeinfo == REF def equals(self, other): if not isinstance(other, Descr): @@ -114,10 +115,9 @@ for box in loop.inputargs: if isinstance(box, history.BoxInt): var2index[box] = llimpl.compile_start_int_var(c) - elif isinstance(box, history.BoxPtr): - var2index[box] = llimpl.compile_start_ptr_var(c) - elif self.is_oo and isinstance(box, history.BoxObj): - var2index[box] = llimpl.compile_start_obj_var(c) + elif isinstance(box, self.ts.BoxRef): + TYPE = self.ts.BASETYPE + var2index[box] = llimpl.compile_start_ref_var(c, TYPE) else: raise Exception("box is: %r" % (box,)) self._compile_branch(c, loop.operations, var2index) @@ -140,12 +140,10 @@ llimpl.compile_add_var(c, var2index[x]) elif isinstance(x, history.ConstInt): llimpl.compile_add_int_const(c, x.value) - elif isinstance(x, history.ConstPtr): - llimpl.compile_add_ptr_const(c, x.value) + elif isinstance(x, self.ts.ConstRef): + llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE) elif isinstance(x, history.ConstAddr): llimpl.compile_add_int_const(c, x.getint()) - elif self.is_oo and isinstance(x, history.ConstObj): - llimpl.compile_add_ptr_const(c, x.value, ootype.Object) else: raise Exception("%s args contain: %r" % (op.getopname(), x)) @@ -156,10 +154,8 @@ if x is not None: if isinstance(x, history.BoxInt): var2index[x] = llimpl.compile_add_int_result(c) - elif isinstance(x, history.BoxPtr): - var2index[x] = llimpl.compile_add_ptr_result(c) - elif self.is_oo and isinstance(x, history.BoxObj): - var2index[x] = llimpl.compile_add_ptr_result(c, ootype.Object) + elif isinstance(x, self.ts.BoxRef): + var2index[x] = llimpl.compile_add_ref_result(c, self.ts.BASETYPE) else: raise Exception("%s.result contain: %r" % (op.getopname(), x)) @@ -187,19 +183,13 @@ def set_future_value_int(self, index, intvalue): llimpl.set_future_value_int(index, intvalue) - def set_future_value_ptr(self, index, ptrvalue): - llimpl.set_future_value_ptr(index, ptrvalue) - - def set_future_value_obj(self, index, objvalue): - llimpl.set_future_value_obj(index, objvalue) + def set_future_value_ref(self, index, objvalue): + llimpl.set_future_value_ref(index, objvalue) def get_latest_value_int(self, index): return llimpl.frame_int_getvalue(self.latest_frame, index) - def get_latest_value_ptr(self, index): - return llimpl.frame_ptr_getvalue(self.latest_frame, index) - - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): return llimpl.frame_ptr_getvalue(self.latest_frame, index) # ---------- @@ -242,6 +232,7 @@ class LLtypeCPU(BaseCPU): is_oo = False + ts = llhelper def __init__(self, *args, **kwds): BaseCPU.__init__(self, *args, **kwds) @@ -277,36 +268,36 @@ # ---------- the backend-dependent operations ---------- def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() return history.BoxInt(llimpl.do_arraylen_gc(arraydescr, array)) def do_strlen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_strlen(0, string)) def do_strgetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_strgetitem(0, string, index)) def do_unicodelen(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() return history.BoxInt(llimpl.do_unicodelen(0, string)) def do_unicodegetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() return history.BoxInt(llimpl.do_unicodegetitem(0, string, index)) def do_getarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() - if arraydescr.typeinfo == 'p': + if arraydescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getarrayitem_gc_ptr(array, index)) else: return history.BoxInt(llimpl.do_getarrayitem_gc_int(array, index, @@ -314,8 +305,8 @@ def do_getfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() - if fielddescr.typeinfo == 'p': + struct = args[0].getref_base() + if fielddescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)) else: @@ -325,7 +316,7 @@ def do_getfield_raw(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) - if fielddescr.typeinfo == 'p': + if fielddescr.typeinfo == REF: return history.BoxPtr(llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs, self.memo_cast)) @@ -354,10 +345,10 @@ def do_setarrayitem_gc(self, args, arraydescr): assert isinstance(arraydescr, Descr) - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() - if arraydescr.typeinfo == 'p': - newvalue = args[2].getptr_base() + if arraydescr.typeinfo == REF: + newvalue = args[2].getref_base() llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) else: newvalue = args[2].getint() @@ -366,9 +357,9 @@ def do_setfield_gc(self, args, fielddescr): assert isinstance(fielddescr, Descr) - struct = args[0].getptr_base() - if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + struct = args[0].getref_base() + if fielddescr.typeinfo == REF: + newvalue = args[1].getref_base() llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) else: newvalue = args[1].getint() @@ -378,8 +369,8 @@ def do_setfield_raw(self, args, fielddescr): assert isinstance(fielddescr, Descr) struct = self.cast_int_to_adr(args[0].getint()) - if fielddescr.typeinfo == 'p': - newvalue = args[1].getptr_base() + if fielddescr.typeinfo == REF: + newvalue = args[1].getref_base() llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue, self.memo_cast) else: @@ -402,14 +393,14 @@ def do_strsetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_strsetitem(0, string, index, newvalue) def do_unicodesetitem(self, args, descr=None): assert descr is None - string = args[0].getptr_base() + string = args[0].getref_base() index = args[1].getint() newvalue = args[2].getint() llimpl.do_unicodesetitem(0, string, index, newvalue) @@ -420,10 +411,10 @@ for arg in args[1:]: if (isinstance(arg, history.BoxPtr) or isinstance(arg, history.ConstPtr)): - llimpl.do_call_pushptr(arg.getptr_base()) + llimpl.do_call_pushptr(arg.getref_base()) else: llimpl.do_call_pushint(arg.getint()) - if calldescr.typeinfo == 'p': + if calldescr.typeinfo == REF: return history.BoxPtr(llimpl.do_call_ptr(func, self.memo_cast)) elif calldescr.typeinfo == 'i': return history.BoxInt(llimpl.do_call_int(func, self.memo_cast)) @@ -438,11 +429,12 @@ def do_cast_ptr_to_int(self, args, descr=None): assert descr is None - return history.BoxInt(llimpl.cast_to_int(args[0].getptr_base(), + return history.BoxInt(llimpl.cast_to_int(args[0].getref_base(), self.memo_cast)) class OOtypeCPU(BaseCPU): is_oo = True + ts = oohelper @staticmethod def fielddescrof(T, fieldname): @@ -495,7 +487,7 @@ def do_new_with_vtable(self, args, descr=None): assert descr is None assert len(args) == 1 - cls = args[0].getobj() + cls = args[0].getref_base() typedescr = self.class_sizes[cls] return typedescr.create() @@ -512,7 +504,7 @@ def do_runtimenew(self, args, descr): "NOT_RPYTHON" classbox = args[0] - classobj = ootype.cast_from_object(ootype.Class, classbox.getobj()) + classobj = classbox.getref(ootype.Class) res = ootype.runtimenew(classobj) return history.BoxObj(ootype.cast_to_object(res)) @@ -626,7 +618,7 @@ self.FUNC = FUNC getargs = make_getargs(FUNC.ARGS) def callfunc(funcbox, argboxes): - funcobj = ootype.cast_from_object(FUNC, funcbox.getobj()) + funcobj = funcbox.getref(FUNC) funcargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) if RESULT is not ootype.Void: @@ -648,7 +640,7 @@ RESULT = METH.RESULT getargs = make_getargs(METH.ARGS) def callmeth(selfbox, argboxes): - selfobj = ootype.cast_from_object(SELFTYPE, selfbox.getobj()) + selfobj = selfbox.getref(SELFTYPE) meth = getattr(selfobj, methname) methargs = getargs(argboxes) res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) @@ -674,22 +666,22 @@ return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) def getarrayitem(arraybox, ibox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() return boxresult(TYPE, array.ll_getitem_fast(i)) def setarrayitem(arraybox, ibox, valuebox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) i = ibox.getint() value = unwrap(TYPE, valuebox) array.ll_setitem_fast(i, value) def getarraylength(arraybox): - array = ootype.cast_from_object(ARRAY, arraybox.getobj()) + array = arraybox.getref(ARRAY) return boxresult(ootype.Signed, array.ll_length()) def instanceof(box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) return history.BoxInt(ootype.instanceof(obj, TYPE)) self.create = create @@ -698,7 +690,7 @@ self.setarrayitem = setarrayitem self.getarraylength = getarraylength self.instanceof = instanceof - self._is_array_of_pointers = (history.getkind(TYPE) == 'obj') + self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') def is_array_of_pointers(self): # for arrays, TYPE is the type of the array item. @@ -718,17 +710,17 @@ _, T = TYPE._lookup_field(fieldname) def getfield(objbox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = getattr(obj, fieldname) return boxresult(T, value) def setfield(objbox, valuebox): - obj = ootype.cast_from_object(TYPE, objbox.getobj()) + obj = objbox.getref(TYPE) value = unwrap(T, valuebox) setattr(obj, fieldname, value) self.getfield = getfield self.setfield = setfield - self._is_pointer_field = (history.getkind(T) == 'obj') + self._is_pointer_field = (history.getkind(T) == 'ref') def sort_key(self): return self._keys.getkey((self.TYPE, self.fieldname)) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py Sat Aug 29 16:20:26 2009 @@ -109,7 +109,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -142,7 +142,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -171,7 +171,7 @@ [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], descrfld_ry) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # rs.y = lltype.nullptr(A) cpu.do_setfield_raw( @@ -182,7 +182,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -190,29 +190,29 @@ cpu.set_class_sizes({vtable2_int: descrsize2}) x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) - assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' class TestLLTypeLLGraph(LLtypeBackendTest, LLGraphTests): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py Sat Aug 29 16:20:26 2009 @@ -10,12 +10,13 @@ from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.backend.x86 import symbolic # xxx +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._llvm_compiled_index = -1 class LLVMCPU(object): - is_oo = False + ts = llhelper logger_cls = None RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) @@ -308,7 +309,7 @@ p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) p[0] = intvalue - def set_future_value_ptr(self, index, ptrvalue): + def set_future_value_ref(self, index, ptrvalue): p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) p[0] = ptrvalue @@ -329,7 +330,7 @@ p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) return p[0] - def get_latest_value_ptr(self, index): + def get_latest_value_ref(self, index): p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) return p[0] @@ -454,37 +455,37 @@ # do_xxx methods def do_arraylen_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) res = len(p) return BoxInt(res) def do_strlen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = len(p.chars) return BoxInt(res) def do_strgetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_unicodelen(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = len(p.chars) return BoxInt(res) def do_unicodegetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) res = ord(p.chars[args[1].getint()]) return BoxInt(res) def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index @@ -527,7 +528,7 @@ return BoxInt(res) def do_getfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() return self._do_getfield(struct, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -564,13 +565,13 @@ self.array_index_length) def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getptr_base() + array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index if itemsize_index == self.SIZE_GCPTR: p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getptr_base() + res = args[2].getref_base() p[index] = res elif itemsize_index == self.SIZE_INT: p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) @@ -593,7 +594,7 @@ size_index = fielddescr.size_index if size_index == self.SIZE_GCPTR: p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getptr_base() + res = v_value.getref_base() p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res elif size_index == self.SIZE_INT: p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) @@ -611,7 +612,7 @@ raise BadSizeError def do_setfield_gc(self, args, fielddescr): - struct = args[0].getptr_base() + struct = args[0].getref_base() self._do_setfield(struct, args[1], fielddescr) def do_setfield_raw(self, args, fielddescr): @@ -629,13 +630,13 @@ self.unicode_index_length) def do_strsetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = chr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) p.chars[args[1].getint()] = res def do_unicodesetitem(self, args, descr=None): - s = args[0].getptr_base() + s = args[0].getref_base() res = unichr(args[2].getint()) p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) p.chars[args[1].getint()] = res @@ -677,7 +678,7 @@ if calldescr.res_index < 0: return None elif calldescr.res_index == self.SIZE_GCPTR: - return BoxPtr(self.get_latest_value_ptr(0)) + return BoxPtr(self.get_latest_value_ref(0)) else: return BoxInt(self.get_latest_value_int(0)) @@ -687,7 +688,7 @@ return BoxPtr(res) def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getptr_base() + ptr = args[0].getref_base() res = rffi.cast(lltype.Signed, ptr) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/logger.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/logger.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/logger.py Sat Aug 29 16:20:26 2009 @@ -6,10 +6,9 @@ class AbstractLogger(object): - # is_oo = ... ## need to be set by concrete classes - - def __init__(self): + def __init__(self, ts): self._log_fd = -1 + self.ts = ts def create_log(self, extension='.ops'): if self._log_fd != -1: @@ -43,16 +42,12 @@ return "ci(%d,%d)" % (mv, arg.value) elif isinstance(arg, BoxInt): return "bi(%d,%d)" % (mv, arg.value) - elif not self.is_oo and isinstance(arg, ConstPtr): - return "cp(%d,%d)" % (mv, arg.get_()) - elif not self.is_oo and isinstance(arg, BoxPtr): - return "bp(%d,%d)" % (mv, arg.get_()) - elif not self.is_oo and isinstance(arg, ConstAddr): + elif isinstance(arg, self.ts.ConstRef): + return "cr(%d,%d)" % (mv, arg.get_()) + elif isinstance(arg, self.ts.BoxRef): + return "br(%d,%d)" % (mv, arg.get_()) + elif isinstance(arg, self.ts.ConstAddr): return "ca(%d,%d)" % (mv, arg.get_()) - elif self.is_oo and isinstance(arg, ConstObj): - return "co(%d,%d)" % (mv, arg.get_()) - elif self.is_oo and isinstance(arg, BoxObj): - return "bo(%d,%d)" % (mv, arg.get_()) else: #raise NotImplementedError return "?%r" % (arg,) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Sat Aug 29 16:20:26 2009 @@ -115,8 +115,8 @@ class BoxAddr(Box): pass -class BoxPtr(Box): - _var_prefix = "p" +class BoxRef(Box): + _var_prefix = "r" class Const(AbstractValue): @@ -133,19 +133,19 @@ class ConstAddr(Const): pass -class ConstPtr(Const): +class ConstRef(Const): pass box_map = { 'b' : { 'i' : BoxInt, 'a' : BoxAddr, - 'p' : BoxPtr + 'r' : BoxRef }, 'c' : { 'i' : ConstInt, 'a' : ConstAddr, - 'p' : ConstPtr + 'r' : ConstRef }, } Modified: pypy/branch/pyjitpl5/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/model.py Sat Aug 29 16:20:26 2009 @@ -23,11 +23,7 @@ """Set the value for the index'th argument for the loop to run.""" raise NotImplementedError - def set_future_value_ptr(self, index, ptrvalue): - """Set the value for the index'th argument for the loop to run.""" - raise NotImplementedError - - def set_future_value_obj(self, index, objvalue): + def set_future_value_ref(self, index, objvalue): """Set the value for the index'th argument for the loop to run.""" raise NotImplementedError @@ -36,14 +32,9 @@ lastest rop.FAIL. Returns an int.""" raise NotImplementedError - def get_latest_value_ptr(self, index): - """Returns the value for the index'th argument to the - lastest rop.FAIL. Returns a ptr.""" - raise NotImplementedError - - def get_latest_value_obj(self, index): + def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the - lastest rop.FAIL. Returns an obj.""" + lastest rop.FAIL. Returns a ptr or an obj.""" raise NotImplementedError def get_exception(self): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/simple.ops Sat Aug 29 16:20:26 2009 @@ -14,7 +14,7 @@ 6:jump bi(0,6),bi(5,3),bi(3,24) #19 8:guard_exception ci(85,138082236) - => bp(86,138081800) + => br(86,138081800) BEGIN(0) 0:fail bi(2,18)[] END Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/loopdata/string.ops Sat Aug 29 16:20:26 2009 @@ -1,5 +1,5 @@ -LOOP bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3) -0:call bi(0,-1207988264),bp(1,177266788),bp(2,177102816),bi(3,0),bi(4,0),bi(5,3)[5,0,False] +LOOP bi(0,-1207988264),br(1,177266788),br(2,177102816),bi(3,0),bi(4,0),bi(5,3) +0:call bi(0,-1207988264),br(1,177266788),br(2,177102816),bi(3,0),bi(4,0),bi(5,3)[5,0,False] => bi(6,0) 1:guard_no_exception BEGIN(0) @@ -7,30 +7,30 @@ END 2:fail bi(6,0) LOOP END -LOOP bp(0,177266788),bi(1,97) +LOOP br(0,177266788),bi(1,97) #(no jitdriver.get_printable_location!) 1:newstr ci(2,1) - => bp(3,177102832) -2:strsetitem bp(3,177102832),ci(4,0),bi(1,97) -3:strlen bp(0,177266788) + => br(3,177102832) +2:strsetitem br(3,177102832),ci(4,0),bi(1,97) +3:strlen br(0,177266788) => bi(5,3) -4:strlen bp(3,177102832) +4:strlen br(3,177102832) => bi(6,1) 5:int_add bi(5,3),bi(6,1) => bi(7,4) 6:int_ge bi(7,4),ci(4,0) => bi(8,1) 7:newstr bi(7,4) - => bp(9,177102816) -8:call ca(10,175948220),bp(0,177266788),bp(9,177102816),ci(4,0),ci(4,0),bi(5,3)[5,0,False] + => br(9,177102816) +8:call ca(10,175948220),br(0,177266788),br(9,177102816),ci(4,0),ci(4,0),bi(5,3)[5,0,False] 9:guard_no_exception BEGIN(0) - 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + 0:fail br(0,177266788),bi(1,97),br(3,177102832),bi(5,3),bi(6,1),bi(7,4),br(9,177102816)[] END -10:call ca(10,175948220),bp(3,177102832),bp(9,177102816),ci(4,0),bi(5,3),bi(6,1)[5,0,False] +10:call ca(10,175948220),br(3,177102832),br(9,177102816),ci(4,0),bi(5,3),bi(6,1)[5,0,False] 11:guard_no_exception BEGIN(0) - 0:fail bp(0,177266788),bi(1,97),bp(3,177102832),bi(5,3),bi(6,1),bi(7,4),bp(9,177102816)[] + 0:fail br(0,177266788),bi(1,97),br(3,177102832),bi(5,3),bi(6,1),bi(7,4),br(9,177102816)[] END 12:int_sub bi(1,97),ci(2,1) => bi(11,96) @@ -38,13 +38,13 @@ => bi(13,1) 14:guard_true bi(13,1) BEGIN(0) - 0:fail bi(11,96),bp(9,177102816)[] + 0:fail bi(11,96),br(9,177102816)[] END #(no jitdriver.get_printable_location!) -16:jump bp(9,177102816),bi(11,96) +16:jump br(9,177102816),bi(11,96) LOOP END -LOOP bi(0,-1207988312),bp(1,177134016) -0:call bi(0,-1207988312),bp(1,177134016)[1,4,False] +LOOP bi(0,-1207988312),br(1,177134016) +0:call bi(0,-1207988312),br(1,177134016)[1,4,False] => bi(2,0) 1:guard_no_exception BEGIN(0) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Sat Aug 29 16:20:26 2009 @@ -24,10 +24,10 @@ self.cpu.set_future_value_int(j, box.getint()) j += 1 elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ptr(j, box.getptr_base()) + self.cpu.set_future_value_ref(j, box.getref_base()) j += 1 elif isinstance(box, BoxObj): - self.cpu.set_future_value_obj(j, box.getobj()) + self.cpu.set_future_value_ref(j, box.getref_base()) j += 1 res = self.cpu.execute_operations(loop) if res is loop.operations[-1]: @@ -36,8 +36,8 @@ self.guard_failed = True if result_type == 'int': return BoxInt(self.cpu.get_latest_value_int(0)) - elif result_type == 'ptr': - return BoxPtr(self.cpu.get_latest_value_ptr(0)) + elif result_type == 'ref': + return BoxPtr(self.cpu.get_latest_value_ref(0)) elif result_type == 'void': return None else: @@ -49,7 +49,7 @@ result = None elif result_type == 'int': result = BoxInt() - elif result_type == 'ptr': + elif result_type == 'ref': result = BoxPtr() else: raise ValueError(result_type) @@ -121,7 +121,7 @@ assert x.value == 142 if self.type_system == 'lltype': s = execute(cpu, rop.NEWSTR, [BoxInt(8)]) - assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8 + assert len(s.getref(lltype.Ptr(rstr.STR)).chars) == 8 def test_lshift(self): res = execute(self.cpu, rop.INT_LSHIFT, [BoxInt(10), ConstInt(4)]) @@ -238,10 +238,7 @@ ] ops[1].suboperations = [ResOperation(rop.FAIL, [], None)] else: - if self.cpu.is_oo: - v_exc = BoxObj() - else: - v_exc = BoxPtr() + v_exc = self.cpu.ts.BoxRef() ops = [ ResOperation(opnum, [v1, v2], v_res), ResOperation(rop.GUARD_OVERFLOW, [], None), @@ -309,7 +306,7 @@ 'void', descr=fielddescr2) assert res is None res = self.execute_operation(rop.GETFIELD_GC, [t_box], - 'ptr', descr=fielddescr2) + 'ref', descr=fielddescr2) assert res.value == u_box.value # null_const = self.null_instance().constbox() @@ -317,7 +314,7 @@ 'void', descr=fielddescr2) assert res is None res = self.execute_operation(rop.GETFIELD_GC, [t_box], - 'ptr', descr=fielddescr2) + 'ref', descr=fielddescr2) assert res.value == null_const.value def test_passing_guards(self): @@ -446,7 +443,7 @@ 'void', descr=arraydescr) assert r is None r = self.execute_operation(rop.GETARRAYITEM_GC, [b_box, BoxInt(1)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) assert r.value == a_box.value # # Unsigned should work the same as Signed @@ -532,7 +529,7 @@ r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int') assert r.value == 5 u_box = self.alloc_unicode(u"hello\u1234") - r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ptr') + r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ref') assert r.value == u_box.value @@ -614,12 +611,12 @@ res = self.execute_operation(rop.CAST_PTR_TO_INT, [BoxPtr(x)], 'int').value res2 = self.execute_operation(rop.CAST_INT_TO_PTR, - [BoxInt(res)], 'ptr').value + [BoxInt(res)], 'ref').value x = lltype.cast_opaque_ptr(llmemory.GCREF, x) res = self.execute_operation(rop.CAST_PTR_TO_INT, [ConstPtr(x)], 'int').value res2 = self.execute_operation(rop.CAST_INT_TO_PTR, - [ConstInt(res)], 'ptr').value + [ConstInt(res)], 'ref').value assert res2 == x def test_ooops_non_gc(self): @@ -639,8 +636,8 @@ cpu = self.cpu S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Char)) sizedescr = cpu.sizeof(S) - r1 = self.execute_operation(rop.NEW, [], 'ptr', descr=sizedescr) - r2 = self.execute_operation(rop.NEW, [], 'ptr', descr=sizedescr) + r1 = self.execute_operation(rop.NEW, [], 'ref', descr=sizedescr) + r2 = self.execute_operation(rop.NEW, [], 'ref', descr=sizedescr) assert r1.value != r2.value xdescr = cpu.fielddescrof(S, 'x') ydescr = cpu.fielddescrof(S, 'y') @@ -656,8 +653,8 @@ cpu = self.cpu t_box, T_box = self.alloc_instance(self.T) cpu.set_class_sizes({T_box.value: cpu.sizeof(self.T)}) - r1 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ptr') - r2 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ptr') + r1 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ref') + r2 = self.execute_operation(rop.NEW_WITH_VTABLE, [T_box], 'ref') assert r1.value != r2.value descr1 = cpu.fielddescrof(self.S, 'chr1') descr2 = cpu.fielddescrof(self.S, 'chr2') @@ -684,24 +681,24 @@ A = lltype.GcArray(lltype.Signed) arraydescr = self.cpu.arraydescrof(A) r1 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) r2 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], - 'ptr', descr=arraydescr) + 'ref', descr=arraydescr) assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(A), r1.value) assert a[0] == 0 assert len(a) == 342 def test_new_string(self): - r1 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ptr') - r2 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ptr') + r1 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') + r2 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), r1.value) assert len(a.chars) == 342 def test_new_unicode(self): - r1 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ptr') - r2 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ptr') + r1 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') + r2 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') assert r1.value != r2.value a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), r1.value) assert len(a.chars) == 342 @@ -731,7 +728,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(3)], descr_B) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s = rstr.mallocstr(6) x = cpu.do_strlen( @@ -764,7 +761,7 @@ [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))], descrfld_y) assert isinstance(x, BoxPtr) - assert x.getptr(lltype.Ptr(A)) == a + assert x.getref(lltype.Ptr(A)) == a # s.y = lltype.nullptr(A) cpu.do_setfield_gc( @@ -795,7 +792,7 @@ # [BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs)))], # descrfld_ry) #assert isinstance(x, BoxPtr) - #assert x.getptr(lltype.Ptr(A)) == a + #assert x.getref(lltype.Ptr(A)) == a # #rs.y = lltype.nullptr(A) #cpu.do_setfield_raw( @@ -806,7 +803,7 @@ descrsize = cpu.sizeof(S) x = cpu.do_new([], descrsize) assert isinstance(x, BoxPtr) - x.getptr(lltype.Ptr(S)) + x.getref(lltype.Ptr(S)) # descrsize2 = cpu.sizeof(rclass.OBJECT) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -815,29 +812,29 @@ x = cpu.do_new_with_vtable([ConstInt(vtable2_int)]) assert isinstance(x, BoxPtr) # well... - #assert x.getptr(rclass.OBJECTPTR).typeptr == vtable2 + #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) x = cpu.do_new_array([BoxInt(7)], arraydescr) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(A))) == 7 + assert len(x.getref(lltype.Ptr(A))) == 7 # cpu.do_setarrayitem_gc( [x, BoxInt(5), BoxInt(ord('*'))], descr_A) - assert x.getptr(lltype.Ptr(A))[5] == '*' + assert x.getref(lltype.Ptr(A))[5] == '*' # cpu.do_setarrayitem_gc( [BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, b)), BoxInt(1), x], descr_B) - assert b[1] == x.getptr(lltype.Ptr(A)) + assert b[1] == x.getref(lltype.Ptr(A)) # x = cpu.do_newstr([BoxInt(5)]) assert isinstance(x, BoxPtr) - assert len(x.getptr(lltype.Ptr(rstr.STR)).chars) == 5 + assert len(x.getref(lltype.Ptr(rstr.STR)).chars) == 5 # cpu.do_strsetitem([x, BoxInt(4), BoxInt(ord('/'))]) - assert x.getptr(lltype.Ptr(rstr.STR)).chars[4] == '/' + assert x.getref(lltype.Ptr(rstr.STR)).chars[4] == '/' # x = cpu.do_newstr([BoxInt(5)]) y = cpu.do_cast_ptr_to_int([x]) @@ -888,7 +885,7 @@ self.cpu.set_future_value_int(0, 1) self.cpu.execute_operations(loop) assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_ptr(1) == xptr + assert self.cpu.get_latest_value_ref(1) == xptr self.cpu.clear_exception() self.cpu.set_future_value_int(0, 0) self.cpu.execute_operations(loop) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Sat Aug 29 16:20:26 2009 @@ -263,7 +263,7 @@ class GetArrayItemOperation(ArrayOperation): def field_descr(self, builder, r): v, A = builder.get_arrayptr_var(r) - array = v.getptr(lltype.Ptr(A)) + array = v.getref(lltype.Ptr(A)) v_index = builder.get_index(len(array), r) descr = self.array_descr(builder, A) return v, A, v_index, descr @@ -344,7 +344,7 @@ current = getattr(builder, self.builder_cache) if current and r.random() < .8: v_string = r.choice(current) - string = v_string.getptr(self.ptr) + string = v_string.getref(self.ptr) else: string = self.alloc(builder.get_index(500, r).getint()) v_string = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, string)) @@ -357,13 +357,13 @@ class AbstractGetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_result = builder.do(self.opnum, [v_string, v_index]) class AbstractSetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - v_index = builder.get_index(len(v_string.getptr(self.ptr).chars), r) + v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_target = ConstInt(r.random_integer() % self.max) builder.do(self.opnum, [v_string, v_index, v_target]) @@ -426,7 +426,7 @@ """ % funcargs).compile() vtableptr = v._hints['vtable']._as_ptr() d = { - 'ptr': S.value, + 'ref': S.value, 'vtable' : vtableptr, 'LLException' : LLException, } Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py Sat Aug 29 16:20:26 2009 @@ -45,7 +45,7 @@ assert code_comment.address == 19 guard_exception = topblock.operations[8] assert isinstance(guard_exception, GuardOperation) - assert isinstance(guard_exception.result, BoxPtr) + assert isinstance(guard_exception.result, BoxRef) assert guard_exception.result.value == 138081800 def test_two_paths(self): @@ -74,7 +74,7 @@ assert len(loops) == 3 newstr = loops[1].operations[1] assert newstr.opname == "newstr" - assert isinstance(newstr.result, BoxPtr) + assert isinstance(newstr.result, BoxRef) assert len(newstr.args) == 1 assert isinstance(newstr.args[0], ConstInt) assert newstr.result.value == 177102832 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py Sat Aug 29 16:20:26 2009 @@ -1,7 +1,7 @@ import sys, os import ctypes from pypy.jit.backend.x86 import symbolic -from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR +from pypy.jit.metainterp.history import Const, Box, BoxPtr, REF from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -31,8 +31,6 @@ class x86Logger(AbstractLogger): - is_oo = False - def repr_of_descr(self, descr): from pypy.jit.backend.x86.runner import ConstDescr3 if isinstance(descr, ConstDescr3): @@ -107,7 +105,7 @@ self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed)) self._exception_addr = 0 self.mcstack = MachineCodeStack() - self.logger = x86Logger() + self.logger = x86Logger(cpu.ts) self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed), MAX_FAIL_BOXES, zero=True) self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF), @@ -240,7 +238,7 @@ for i in range(len(arglocs)): loc = arglocs[i] if not isinstance(loc, REG): - if args[i].type == PTR: + if args[i].type == REF: # This uses XCHG to put zeroes in fail_boxes_ptr after # reading them self.mc.XOR(ecx, ecx) @@ -253,7 +251,7 @@ for i in range(len(arglocs)): loc = arglocs[i] if isinstance(loc, REG): - if args[i].type == PTR: + if args[i].type == REF: # This uses XCHG to put zeroes in fail_boxes_ptr after # reading them self.mc.XOR(loc, loc) @@ -718,7 +716,7 @@ for i in range(len(locs)): loc = locs[i] if isinstance(loc, REG): - if op.args[i].type == PTR: + if op.args[i].type == REF: base = self.fail_box_ptr_addr else: base = self.fail_box_int_addr @@ -726,7 +724,7 @@ for i in range(len(locs)): loc = locs[i] if not isinstance(loc, REG): - if op.args[i].type == PTR: + if op.args[i].type == REF: base = self.fail_box_ptr_addr else: base = self.fail_box_int_addr Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py Sat Aug 29 16:20:26 2009 @@ -16,6 +16,7 @@ from pypy.jit.backend.x86 import symbolic from pypy.jit.metainterp.resoperation import rop, opname from pypy.rlib.objectmodel import r_dict +from pypy.jit.metainterp.typesystem import llhelper history.TreeLoop._x86_compiled = 0 history.TreeLoop._x86_bootstrap_code = 0 @@ -48,7 +49,7 @@ class CPU386(object): debug = True - is_oo = False + ts = llhelper logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) @@ -177,7 +178,7 @@ if calldescr.call_loop is not None: if not we_are_translated(): assert (calldescr.shape == - ([arg.type == history.PTR for arg in args[1:]], ptr)) + ([arg.type == history.REF for arg in args[1:]], ptr)) return calldescr.call_loop args = [arg.clonebox() for arg in args] result = self._new_box(ptr) @@ -214,14 +215,14 @@ assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_int[index] = intvalue - def set_future_value_ptr(self, index, ptrvalue): + def set_future_value_ref(self, index, ptrvalue): assert index < MAX_FAIL_BOXES, "overflow!" self.assembler.fail_boxes_ptr[index] = ptrvalue def get_latest_value_int(self, index): return self.assembler.fail_boxes_int[index] - def get_latest_value_ptr(self, index): + def get_latest_value_ref(self, index): ptrvalue = self.assembler.fail_boxes_ptr[index] # clear after reading self.assembler.fail_boxes_ptr[index] = lltype.nullptr( @@ -279,13 +280,13 @@ def do_arraylen_gc(self, args, arraydescr): ofs = self.gc_ll_descr.array_length_ofs - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] return BoxInt(length) def do_getarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift if size == 1: @@ -303,7 +304,7 @@ def do_setarrayitem_gc(self, args, arraydescr): field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) shift, ofs, ptr = self.unpack_arraydescr(arraydescr) size = 1 << shift vbox = args[2] @@ -315,7 +316,7 @@ a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = vbox.getint() else: - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD + field] = self.cast_gcref_to_int(ptr) @@ -326,7 +327,7 @@ def do_strlen(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(TP, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] return BoxInt(v) return do_strlen @@ -337,7 +338,7 @@ def do_strgetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) @@ -345,7 +346,7 @@ def do_unicodegetitem(self, args, descr=None): basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) i = args[1].getint() basesize = basesize // itemsize v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] @@ -368,7 +369,7 @@ return BoxInt(v) def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) return self._base_do_getfield(gcref, fielddescr) def do_getfield_raw(self, args, fielddescr): @@ -387,7 +388,7 @@ if ptr: assert lltype.typeOf(gcref) is not lltype.Signed, ( "can't handle write barriers for setfield_raw") - ptr = vbox.getptr(llmemory.GCREF) + ptr = vbox.getref(llmemory.GCREF) self.gc_ll_descr.do_write_barrier(gcref, ptr) a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) a[ofs/WORD] = self.cast_gcref_to_int(ptr) @@ -398,7 +399,7 @@ raise NotImplementedError("size = %d" % size) def do_setfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) + gcref = args[0].getref(llmemory.GCREF) self._base_do_setfield(fielddescr, gcref, args[1]) def do_setfield_raw(self, args, fielddescr): @@ -439,7 +440,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) def do_unicodesetitem(self, args, descr=None): @@ -447,7 +448,7 @@ self.translate_support_code) index = args[1].getint() v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) + a = args[0].getref(llmemory.GCREF) basesize = basesize // itemsize rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) @@ -463,12 +464,12 @@ if size == 0: return None elif ptr: - return BoxPtr(self.get_latest_value_ptr(0)) + return BoxPtr(self.get_latest_value_ref(0)) else: return BoxInt(self.get_latest_value_int(0)) def do_cast_ptr_to_int(self, args, descr=None): - return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) + return BoxInt(self.cast_gcref_to_int(args[0].getref_base())) def do_cast_int_to_ptr(self, args, descr=None): return BoxPtr(self.cast_int_to_gcref(args[0].getint())) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py Sat Aug 29 16:20:26 2009 @@ -177,7 +177,7 @@ else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) - self.cpu.set_future_value_ptr(i, llgcref) + self.cpu.set_future_value_ref(i, llgcref) if run: self.cpu.execute_operations(loop) return loop @@ -190,7 +190,7 @@ index in range(0, end)] def getptr(self, index, T): - gcref = self.cpu.get_latest_value_ptr(index) + gcref = self.cpu.get_latest_value_ref(index) return lltype.cast_opaque_ptr(T, gcref) def attach_bridge(self, ops, loop, guard_op): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py Sat Aug 29 16:20:26 2009 @@ -143,14 +143,14 @@ self.cpu.assembler.malloc_func_addr = addr ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ - res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 @@ -162,7 +162,7 @@ descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 @@ -170,7 +170,7 @@ # ------------------------------------------------------------ res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], - 'ptr', descr) + 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 @@ -183,7 +183,7 @@ ofs = symbolic.get_field_token(STR, 'chars', False)[0] ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0] - res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ptr') + res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref') self.execute_operation(rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void') resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' @@ -198,7 +198,7 @@ itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, @@ -237,7 +237,7 @@ itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ptr', descr) + 'ref', descr) resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs] == chr(10) for i in range(10): @@ -260,7 +260,7 @@ ('c2', lltype.Char), ('c3', lltype.Char)) res = self.execute_operation(rop.NEW, [], - 'ptr', self.cpu.sizeof(TP)) + 'ref', self.cpu.sizeof(TP)) ofs_s = self.cpu.fielddescrof(TP, 's') #ofs_f = self.cpu.fielddescrof(TP, 'f') ofs_u = self.cpu.fielddescrof(TP, 'u') @@ -332,7 +332,7 @@ if op == rop.INT_IS_TRUE: self.cpu.set_future_value_int(0, b.value) else: - self.cpu.set_future_value_ptr(0, b.value) + self.cpu.set_future_value_ref(0, b.value) r = self.cpu.execute_operations(loop) result = self.cpu.get_latest_value_int(0) if guard == rop.GUARD_FALSE: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Sat Aug 29 16:20:26 2009 @@ -48,7 +48,7 @@ self.values = [] for graph in graphs: fnptr = codewriter.rtyper.getcallable(graph) - fnaddress = codewriter.ts.cast_fnptr_to_root(fnptr) + fnaddress = codewriter.cpu.ts.cast_fnptr_to_root(fnptr) self.keys.append(fnaddress) self.values.append(codewriter.get_jitcode(graph)) self.dict = None @@ -80,7 +80,7 @@ class CodeWriter(object): portal_graph = None - def __init__(self, metainterp_sd, policy, ts): + def __init__(self, metainterp_sd, policy): self.all_prebuilt_values = dict_equal_consts() self.all_graphs = {} self.all_indirectcallsets = {} @@ -91,7 +91,6 @@ self.rtyper = metainterp_sd.cpu.rtyper self.cpu = metainterp_sd.cpu self.policy = policy - self.ts = ts self.counter = 0 self.raise_analyzer = RaiseAnalyzer(self.rtyper.annotator.translator) self.class_sizes = [] @@ -145,7 +144,7 @@ if self.portal_graph is None or graph is self.portal_graph: return () fnptr = self.rtyper.getcallable(graph) - if self.cpu.is_oo: + if self.rtyper.type_system.name == 'ootypesystem': if oosend_methdescr: return (None, oosend_methdescr) else: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py Sat Aug 29 16:20:26 2009 @@ -10,6 +10,7 @@ Const from pypy.jit.metainterp import history from pypy.jit.metainterp.specnode import NotSpecNode +from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.debug import debug_print def compile_new_loop(metainterp, old_loops, greenkey, start=0): @@ -150,56 +151,34 @@ result = resultbox.getint() raise metainterp_sd.DoneWithThisFrameInt(result) -class DoneWithThisFrameDescrPtr(AbstractDescr): +class DoneWithThisFrameDescrRef(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): - assert metainterp_sd.result_type == 'ptr' + assert metainterp_sd.result_type == 'ref' resultbox = fail_op.args[0] - if isinstance(resultbox, BoxPtr): - result = metainterp_sd.cpu.get_latest_value_ptr(0) - else: - assert isinstance(resultbox, history.Const) - result = resultbox.getptr_base() - raise metainterp_sd.DoneWithThisFramePtr(result) - -class DoneWithThisFrameDescrObj(AbstractDescr): - def handle_fail_op(self, metainterp_sd, fail_op): - assert metainterp_sd.result_type == 'obj' - resultbox = fail_op.args[0] - if isinstance(resultbox, BoxObj): - result = metainterp_sd.cpu.get_latest_value_obj(0) + cpu = metainterp_sd.cpu + if isinstance(resultbox, cpu.ts.BoxRef): + result = cpu.get_latest_value_ref(0) else: assert isinstance(resultbox, history.Const) - result = resultbox.getobj() - raise metainterp_sd.DoneWithThisFrameObj(result) + result = resultbox.getref_base() + raise metainterp_sd.DoneWithThisFrameRef(cpu, result) -class ExitFrameWithExceptionDescrPtr(AbstractDescr): +class ExitFrameWithExceptionDescrRef(AbstractDescr): def handle_fail_op(self, metainterp_sd, fail_op): assert len(fail_op.args) == 1 valuebox = fail_op.args[0] - if isinstance(valuebox, BoxPtr): - value = metainterp_sd.cpu.get_latest_value_ptr(0) - else: - assert isinstance(valuebox, history.Const) - value = valuebox.getptr_base() - raise metainterp_sd.ExitFrameWithExceptionPtr(value) - -class ExitFrameWithExceptionDescrObj(AbstractDescr): - def handle_fail_op(self, metainterp_sd, fail_op): - assert len(fail_op.args) == 1 - valuebox = fail_op.args[0] - if isinstance(valuebox, BoxObj): - value = metainterp_sd.cpu.get_latest_value_obj(0) + cpu = metainterp_sd.cpu + if isinstance(valuebox, cpu.ts.BoxRef): + value = cpu.get_latest_value_ref(0) else: assert isinstance(valuebox, history.Const) - value = valuebox.getobj() - raise metainterp_sd.ExitFrameWithExceptionObj(value) + value = valuebox.getref_base() + raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value) done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() done_with_this_frame_descr_int = DoneWithThisFrameDescrInt() -done_with_this_frame_descr_ptr = DoneWithThisFrameDescrPtr() -done_with_this_frame_descr_obj = DoneWithThisFrameDescrObj() -exit_frame_with_exception_descr_ptr = ExitFrameWithExceptionDescrPtr() -exit_frame_with_exception_descr_obj = ExitFrameWithExceptionDescrObj() +done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef() +exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef() class TerminatingLoop(TreeLoop): pass @@ -213,17 +192,17 @@ _loop.finishdescr = done_with_this_frame_descr_int loops_done_with_this_frame_int = [_loop] -_loop = TerminatingLoop('done_with_this_frame_ptr') +_loop = TerminatingLoop('done_with_this_frame_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] -_loop.finishdescr = done_with_this_frame_descr_ptr -loops_done_with_this_frame_ptr = [_loop] +_loop.finishdescr = done_with_this_frame_descr_ref +llhelper.loops_done_with_this_frame_ref = [_loop] -_loop = TerminatingLoop('done_with_this_frame_obj') +_loop = TerminatingLoop('done_with_this_frame_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] -_loop.finishdescr = done_with_this_frame_descr_obj -loops_done_with_this_frame_obj = [_loop] +_loop.finishdescr = done_with_this_frame_descr_ref +oohelper.loops_done_with_this_frame_ref = [_loop] _loop = TerminatingLoop('done_with_this_frame_void') _loop.specnodes = [] @@ -231,17 +210,17 @@ _loop.finishdescr = done_with_this_frame_descr_void loops_done_with_this_frame_void = [_loop] -_loop = TerminatingLoop('exit_frame_with_exception_ptr') +_loop = TerminatingLoop('exit_frame_with_exception_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxPtr()] -_loop.finishdescr = exit_frame_with_exception_descr_ptr -loops_exit_frame_with_exception_ptr = [_loop] +_loop.finishdescr = exit_frame_with_exception_descr_ref +llhelper.loops_exit_frame_with_exception_ref = [_loop] -_loop = TerminatingLoop('exit_frame_with_exception_obj') +_loop = TerminatingLoop('exit_frame_with_exception_ref') _loop.specnodes = [prebuiltNotSpecNode] _loop.inputargs = [BoxObj()] -_loop.finishdescr = exit_frame_with_exception_descr_obj -loops_exit_frame_with_exception_obj = [_loop] +_loop.finishdescr = exit_frame_with_exception_descr_ref +oohelper.loops_exit_frame_with_exception_ref = [_loop] del _loop @@ -278,12 +257,9 @@ if isinstance(box, BoxInt): srcvalue = cpu.get_latest_value_int(i) box.changevalue_int(srcvalue) - elif not cpu.is_oo and isinstance(box, BoxPtr): - srcvalue = cpu.get_latest_value_ptr(i) - box.changevalue_ptr(srcvalue) - elif cpu.is_oo and isinstance(box, BoxObj): - srcvalue = cpu.get_latest_value_obj(i) - box.changevalue_obj(srcvalue) + elif isinstance(box, cpu.ts.BoxRef): + srcvalue = cpu.get_latest_value_ref(i) + box.changevalue_ref(srcvalue) elif isinstance(box, Const): pass # we don't need to do anything else: @@ -296,12 +272,10 @@ dstbox = fail_op.args[i] if isinstance(dstbox, BoxInt): dstbox.changevalue_int(srcbox.getint()) - elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr): - dstbox.changevalue_ptr(srcbox.getptr_base()) + elif isinstance(dstbox, metainterp_sd.cpu.ts.BoxRef): + dstbox.changevalue_ref(srcbox.getref_base()) elif isinstance(dstbox, Const): pass - elif metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxObj): - dstbox.changevalue_obj(srcbox.getobj()) else: assert False Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py Sat Aug 29 16:20:26 2009 @@ -7,7 +7,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr -from pypy.jit.metainterp.history import INT, PTR, OBJ +from pypy.jit.metainterp.history import INT, REF from pypy.jit.metainterp.resoperation import rop @@ -106,22 +106,20 @@ tp = args[0].type if tp == INT: x = bool(args[0].getint()) - elif tp == PTR: - x = bool(args[0].getptr_base()) + elif tp == REF: + x = bool(args[0].getref_base()) else: - assert tp == OBJ - x = bool(args[0].getobj()) + assert False return ConstInt(x) def do_ooisnull(cpu, args, descr=None): tp = args[0].type if tp == INT: x = bool(args[0].getint()) - elif tp == PTR: - x = bool(args[0].getptr_base()) + elif tp == REF: + x = bool(args[0].getref_base()) else: - assert tp == OBJ - x = bool(args[0].getobj()) + assert False return ConstInt(not x) def do_oois(cpu, args, descr=None): @@ -129,11 +127,10 @@ assert tp == args[1].type if tp == INT: x = args[0].getint() == args[1].getint() - elif tp == PTR: - x = args[0].getptr_base() == args[1].getptr_base() + elif tp == REF: + x = args[0].getref_base() == args[1].getref_base() else: - assert tp == OBJ - x = args[0].getobj() == args[1].getobj() + assert False return ConstInt(x) def do_ooisnot(cpu, args, descr=None): @@ -141,23 +138,22 @@ assert tp == args[1].type if tp == INT: x = args[0].getint() != args[1].getint() - elif tp == PTR: - x = args[0].getptr_base() != args[1].getptr_base() + elif tp == REF: + x = args[0].getref_base() != args[1].getref_base() else: - assert tp == OBJ - x = args[0].getobj() != args[1].getobj() + assert False return ConstInt(x) def do_ooidentityhash(cpu, args, descr=None): - obj = args[0].getobj() + obj = args[0].getref_base() return ConstInt(ootype.ooidentityhash(obj)) def do_subclassof(self, args, descr=None): assert len(args) == 2 box1, box2 = args - cls1 = ootype.cast_from_object(ootype.Class, box1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, box2.getobj()) + cls1 = box1.getref(ootype.Class) + cls2 = box2.getref(ootype.Class) res = ootype.subclassof(cls1, cls2) return BoxInt(res) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py Sat Aug 29 16:20:26 2009 @@ -17,8 +17,7 @@ # ____________________________________________________________ INT = 'i' -PTR = 'p' -OBJ = 'o' +REF = 'r' def getkind(TYPE): if TYPE is lltype.Void: @@ -34,9 +33,9 @@ if TYPE.TO._gckind == 'raw': return "int" else: - return "ptr" + return "ref" elif isinstance(TYPE, ootype.OOType): - return "obj" + return "ref" else: raise NotImplementedError("type %s not supported" % TYPE) @@ -80,15 +79,12 @@ def getint(self): raise NotImplementedError - def getptr_base(self): + def getref_base(self): raise NotImplementedError - def getptr(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getptr_base()) - getptr._annspecialcase_ = 'specialize:arg(1)' - - def getobj(self): + def getref(self, TYPE): raise NotImplementedError + getref._annspecialcase_ = 'specialize:arg(1)' def get_(self): raise NotImplementedError @@ -157,12 +153,8 @@ else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) - elif kind == "ptr": - ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) - return ConstPtr(ptrval) - elif kind == "obj": - obj = ootype.cast_to_object(x) - return ConstObj(obj) + elif kind == "ref": + return cpu.ts.new_ConstRef(x) else: raise NotImplementedError(kind) @@ -283,7 +275,7 @@ return repr_rpython(self, 'ca') class ConstPtr(Const): - type = PTR + type = REF value = lltype.nullptr(llmemory.GCREF.TO) _attrs_ = ('value',) @@ -296,9 +288,13 @@ nonconstbox = clonebox - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): return lltype.cast_ptr_to_int(self.value) @@ -309,10 +305,10 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_ptr(j, self.value) + cpu.set_future_value_ref(j, self.value) def equals(self, other): - return self.value == other.getptr_base() + return self.value == other.getref_base() _getrepr_ = repr_pointer @@ -325,7 +321,7 @@ return hlstr(lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), self.value)) class ConstObj(Const): - type = OBJ + type = REF value = ootype.NULL _attrs_ = ('value',) @@ -338,9 +334,13 @@ nonconstbox = clonebox - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -351,7 +351,7 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_obj(j, self.value) + cpu.set_future_value_ref(j, self.value) ## def getaddr(self, cpu): ## # so far this is used only when calling @@ -360,7 +360,7 @@ ## return self.value def equals(self, other): - return self.value == other.getobj() + return self.value == other.getref_base() _getrepr_ = repr_object @@ -384,7 +384,8 @@ if kind == "int": intval = lltype.cast_primitive(lltype.Signed, x) return BoxInt(intval) - elif kind == "ptr": + elif kind == "ref": + # XXX add ootype support? ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) return BoxPtr(ptrval) else: @@ -466,7 +467,7 @@ changevalue_int = __init__ class BoxPtr(Box): - type = PTR + type = REF _attrs_ = ('value',) def __init__(self, value=lltype.nullptr(llmemory.GCREF.TO)): @@ -479,9 +480,13 @@ def constbox(self): return ConstPtr(self.value) - def getptr_base(self): + def getref_base(self): return self.value + def getref(self, PTR): + return lltype.cast_opaque_ptr(PTR, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def getaddr(self, cpu): return llmemory.cast_ptr_to_adr(self.value) @@ -492,22 +497,22 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_ptr(j, self.value) + cpu.set_future_value_ref(j, self.value) def repr_rpython(self): return repr_rpython(self, 'bp') def changevalue_box(self, srcbox): - self.changevalue_ptr(srcbox.getptr_base()) + self.changevalue_ref(srcbox.getref_base()) _getrepr_ = repr_pointer - changevalue_ptr = __init__ + changevalue_ref = __init__ NULLBOX = BoxPtr() class BoxObj(Box): - type = OBJ + type = REF _attrs_ = ('value',) def __init__(self, value=ootype.NULL): @@ -520,9 +525,13 @@ def constbox(self): return ConstObj(self.value) - def getobj(self): + def getref_base(self): return self.value + def getref(self, OBJ): + return ootype.cast_from_object(OBJ, self.getref_base()) + getref._annspecialcase_ = 'specialize:arg(1)' + def get_(self): if self.value: return ootype.ooidentityhash(self.value) # XXX: check me @@ -533,16 +542,16 @@ return bool(self.value) def set_future_value(self, cpu, j): - cpu.set_future_value_obj(j, self.value) + cpu.set_future_value_ref(j, self.value) def repr_rpython(self): return repr_rpython(self, 'bo') def changevalue_box(self, srcbox): - self.changevalue_obj(srcbox.getobj()) + self.changevalue_ref(srcbox.getref_base()) _getrepr_ = repr_object - changevalue_obj = __init__ + changevalue_ref = __init__ def set_future_values(cpu, boxes): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sat Aug 29 16:20:26 2009 @@ -1,5 +1,5 @@ from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj -from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, PTR, OBJ +from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, REF from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp.specnode import SpecNode, NotSpecNode, ConstantSpecNode from pypy.jit.metainterp.specnode import AbstractVirtualStructSpecNode @@ -8,6 +8,7 @@ from pypy.jit.metainterp.specnode import VirtualStructSpecNode from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs from pypy.jit.metainterp import resume, compile +from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype @@ -124,8 +125,8 @@ self.box = box CVAL_ZERO = ConstantValue(ConstInt(0)) -CVAL_NULLPTR = ConstantValue(ConstPtr(ConstPtr.value)) -CVAL_NULLOBJ = ConstantValue(ConstObj(ConstObj.value)) +llhelper.CVAL_NULLREF = ConstantValue(ConstPtr(ConstPtr.value)) +oohelper.CVAL_NULLREF = ConstantValue(ConstObj(ConstObj.value)) class AbstractVirtualValue(OptValue): @@ -336,26 +337,18 @@ self.values = {} self.values_to_clean = [] # OptValues to clean when we see an # operation with side-effects - self.interned_ptrs = {} - self.interned_objs = {} + self.interned_refs = {} def getinterned(self, box): if not self.is_constant(box): return box - if not self.cpu.is_oo and box.type == PTR: - value = box.getptr_base() - key = lltype.cast_ptr_to_int(value) + if box.type == REF: + value = box.getref_base() + key = self.cpu.ts.cast_ref_to_hashable(self.cpu, value) try: - return self.interned_ptrs[key] + return self.interned_refs[key] except KeyError: - self.interned_ptrs[key] = box - return box - elif self.cpu.is_oo and box.type == OBJ: - value = box.getobj() - try: - return self.interned_objs[value] - except KeyError: - self.interned_objs[value] = box + self.interned_refs[key] = box return box else: return box @@ -407,10 +400,7 @@ return value def new_ptr_box(self): - if not self.cpu.is_oo: - return BoxPtr() - else: - return BoxObj() + return self.cpu.ts.BoxRef() def new_box(self, fieldofs): if fieldofs.is_pointer_field(): @@ -420,10 +410,7 @@ def new_const(self, fieldofs): if fieldofs.is_pointer_field(): - if not self.cpu.is_oo: - return CVAL_NULLPTR - else: - return CVAL_NULLOBJ + return self.cpu.ts.CVAL_NULLREF else: return CVAL_ZERO @@ -435,10 +422,7 @@ def new_const_item(self, arraydescr): if arraydescr.is_array_of_pointers(): - if not self.cpu.is_oo: - return CVAL_NULLPTR - else: - return CVAL_NULLOBJ + return self.cpu.ts.CVAL_NULLREF else: return CVAL_ZERO Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Sat Aug 29 16:20:26 2009 @@ -9,7 +9,6 @@ from pypy.jit.metainterp.history import Const, ConstInt, Box from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import codewriter, executor -from pypy.jit.metainterp import typesystem from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -715,10 +714,7 @@ def opimpl_indirect_call(self, pc, indirectcallset, box, varargs): box = self.implement_guard_value(pc, box) cpu = self.metainterp.cpu - if cpu.is_oo: - key = box.getobj() - else: - key = box.getaddr(cpu) + key = cpu.ts.getaddr_for_box(cpu, box) jitcode = indirectcallset.bytecode_for_address(key) f = self.metainterp.newframe(jitcode) f.setup_call(varargs) @@ -730,7 +726,7 @@ clsbox = self.cls_of_box(objbox) if isinstance(objbox, Box): self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox]) - oocls = ootype.cast_from_object(ootype.Class, clsbox.getobj()) + oocls = clsbox.getref(ootype.Class) jitcode = methdescr.get_jitcode_for_class(oocls) return self.perform_call(jitcode, varargs) @@ -845,7 +841,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) - constloc = sd.ts.conststr(loc) + constloc = self.metainterp.cpu.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -861,7 +857,7 @@ def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): assert isinstance(self.exception_box, Const) # XXX cpu = self.metainterp.cpu - ts = self.metainterp.staticdata.ts + ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): self.pc = next_exc_target @@ -966,7 +962,7 @@ return box # no promotion needed, already a Const def cls_of_box(self, box): - return self.metainterp.staticdata.ts.cls_of_box(self.metainterp.cpu, box) + return self.metainterp.cpu.ts.cls_of_box(self.metainterp.cpu, box) @specialize.arg(1) def execute(self, opnum, argboxes, descr=None): @@ -994,7 +990,7 @@ self.stats = stats self.options = options if cpu.logger_cls is not None: - options.logger_noopt = cpu.logger_cls() + options.logger_noopt = cpu.logger_cls(cpu.ts) RESULT = portal_graph.getreturnvar().concretetype self.result_type = history.getkind(RESULT) @@ -1007,11 +1003,6 @@ self.optimize_loop = optimizer.optimize_loop self.optimize_bridge = optimizer.optimize_bridge - if self.cpu.is_oo: - self.ts = typesystem.oohelper - else: - self.ts = typesystem.llhelper - if profile is not None: self.profiler = profile() else: @@ -1057,16 +1048,12 @@ def _setup_class_sizes(self): class_sizes = {} for vtable, sizedescr in self._class_sizes: - if not self.cpu.is_oo: - vtable = llmemory.cast_ptr_to_adr(vtable) - vtable = self.cpu.cast_adr_to_int(vtable) - else: - vtable = ootype.cast_to_object(vtable) + vtable = self.cpu.ts.cast_baseclass_to_hashable(self.cpu, vtable) class_sizes[vtable] = sizedescr self.cpu.set_class_sizes(class_sizes) - def generate_bytecode(self, policy, ts): - self._codewriter = codewriter.CodeWriter(self, policy, ts) + def generate_bytecode(self, policy): + self._codewriter = codewriter.CodeWriter(self, policy) self.portal_code = self._codewriter.make_portal_bytecode( self.portal_graph) self._class_sizes = self._codewriter.class_sizes @@ -1145,10 +1132,8 @@ raise sd.DoneWithThisFrameVoid() elif sd.result_type == 'int': raise sd.DoneWithThisFrameInt(resultbox.getint()) - elif sd.result_type == 'ptr': - raise sd.DoneWithThisFramePtr(resultbox.getptr_base()) - elif self.cpu.is_oo and sd.result_type == 'obj': - raise sd.DoneWithThisFrameObj(resultbox.getobj()) + elif sd.result_type == 'ref': + raise sd.DoneWithThisFrameRef(self.cpu, resultbox.getref_base()) else: assert False @@ -1158,7 +1143,7 @@ # - all subclasses of JitException if we_are_translated(): from pypy.jit.metainterp.warmspot import JitException - e = self.staticdata.ts.get_exception_obj(excvaluebox) + e = self.cpu.ts.get_exception_obj(excvaluebox) if isinstance(e, JitException) or isinstance(e, AssertionError): raise Exception, e # @@ -1175,22 +1160,19 @@ self.framestack.pop() if not self.is_blackholing(): self.compile_exit_frame_with_exception(excvaluebox) - if self.cpu.is_oo: - raise self.staticdata.ExitFrameWithExceptionObj(excvaluebox.getobj()) - else: - raise self.staticdata.ExitFrameWithExceptionPtr(excvaluebox.getptr_base()) + raise self.staticdata.ExitFrameWithExceptionRef(self.cpu, excvaluebox.getref_base()) def raise_overflow_error(self): etype, evalue = self.cpu.get_overflow_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def raise_zero_division_error(self): etype, evalue = self.cpu.get_zero_division_error() return self.finishframe_exception( - self.staticdata.ts.get_exception_box(etype), - self.staticdata.ts.get_exc_value_box(evalue)) + self.cpu.ts.get_exception_box(etype), + self.cpu.ts.get_exc_value_box(evalue)) def create_empty_history(self): self.history = history.History(self.cpu) @@ -1392,20 +1374,20 @@ # save and restore all the boxes that are also used by callers. if self.history.inputargs is not None: for box in self.history.inputargs: - self.staticdata.ts.clean_box(box) + self.cpu.ts.clean_box(box) lists = [self.history.operations] while lists: for op in lists.pop(): if op is None: continue if op.result is not None: - self.staticdata.ts.clean_box(op.result) + self.cpu.ts.clean_box(op.result) if op.suboperations is not None: lists.append(op.suboperations) if op.optimized is not None: lists.append(op.optimized.suboperations) if op.optimized.result is not None: - self.staticdata.ts.clean_box(op.optimized.result) + self.cpu.ts.clean_box(op.optimized.result) def prepare_resume_from_failure(self, opnum): if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now @@ -1458,12 +1440,9 @@ elif sd.result_type == 'int': exits = [exitbox] loops = compile.loops_done_with_this_frame_int - elif sd.result_type == 'ptr': - exits = [exitbox] - loops = compile.loops_done_with_this_frame_ptr - elif sd.cpu.is_oo and sd.result_type == 'obj': + elif sd.result_type == 'ref': exits = [exitbox] - loops = compile.loops_done_with_this_frame_obj + loops = sd.cpu.ts.loops_done_with_this_frame_ref else: assert False self.history.record(rop.JUMP, exits, None) @@ -1474,10 +1453,7 @@ self.gen_store_back_in_virtualizable() # temporarily put a JUMP to a pseudo-loop self.history.record(rop.JUMP, [valuebox], None) - if self.cpu.is_oo: - loops = compile.loops_exit_frame_with_exception_obj - else: - loops = compile.loops_exit_frame_with_exception_ptr + loops = self.cpu.ts.loops_exit_frame_with_exception_ref target_loop = compile.compile_new_bridge(self, loops, self.resumekey) assert target_loop is loops[0] @@ -1600,8 +1576,8 @@ self.cpu.clear_exception() frame = self.framestack[-1] if etype: - exception_box = self.staticdata.ts.get_exception_box(etype) - exc_value_box = self.staticdata.ts.get_exc_value_box(evalue) + exception_box = self.cpu.ts.get_exception_box(etype) + exc_value_box = self.cpu.ts.get_exc_value_box(evalue) op = frame.generate_guard(frame.pc, rop.GUARD_EXCEPTION, None, [exception_box]) if op: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py Sat Aug 29 16:20:26 2009 @@ -3,9 +3,10 @@ in a nicer fashion """ -from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\ - ConstAddr, ConstObj, ConstPtr, Box, BoxObj +from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt,\ + ConstAddr, ConstObj, ConstPtr, Box from pypy.jit.metainterp.resoperation import rop, ResOperation +from pypy.jit.metainterp.typesystem import llhelper from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype @@ -70,10 +71,8 @@ _box_counter_more_than(elem[1:]) elif elem.startswith('p'): # pointer - if getattr(self.cpu, 'is_oo', False): - box = BoxObj() - else: - box = BoxPtr() + ts = getattr(self.cpu, 'ts', llhelper) + box = ts.BoxRef() _box_counter_more_than(elem[1:]) else: for prefix, boxclass in self.boxkinds.iteritems(): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Sat Aug 29 16:20:26 2009 @@ -62,6 +62,10 @@ class DoneWithThisFrame(Exception): pass + + class DoneWithThisFrameRef(DoneWithThisFrame): + def __init__(self, cpu, *args): + DoneWithThisFrame.__init__(self, *args) class FakeWarmRunnerDesc: def attach_unoptimized_bridge_from_interp(self, greenkey, newloop): @@ -73,7 +77,7 @@ self.type_system, policy=policy, optimizer=simple_optimize, **kwds) - cw = codewriter.CodeWriter(metainterp.staticdata, policy, self.ts) + cw = codewriter.CodeWriter(metainterp.staticdata, policy) graph = rtyper.annotator.translator.graphs[0] graph_key = (graph, None) maingraph = cw.make_one_bytecode(graph_key, False) @@ -84,8 +88,7 @@ metainterp.staticdata._class_sizes = cw.class_sizes metainterp.staticdata.state = FakeWarmRunnerDesc() metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame - metainterp.staticdata.DoneWithThisFramePtr = DoneWithThisFrame - metainterp.staticdata.DoneWithThisFrameObj = DoneWithThisFrame + metainterp.staticdata.DoneWithThisFrameRef = DoneWithThisFrameRef self.metainterp = metainterp try: metainterp.compile_and_run_once(*args) @@ -103,7 +106,6 @@ class LLJitMixin(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() @staticmethod def Ptr(T): @@ -130,7 +132,6 @@ class OOJitMixin(JitMixin): type_system = 'ootype' CPUClass = runner.OOtypeCPU - ts = OOTypeHelper() @staticmethod def Ptr(T): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Sat Aug 29 16:20:26 2009 @@ -37,6 +37,10 @@ class LLtypeMixin(object): type_system = 'lltype' + def get_class_of_box(self, box): + from pypy.rpython.lltypesystem import rclass + return box.getref(rclass.OBJECTPTR).typeptr + node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) @@ -76,9 +80,12 @@ class OOtypeMixin(object): type_system = 'ootype' + + def get_class_of_box(self, box): + root = box.getref(ootype.ROOT) + return ootype.classof(root) cpu = runner.OOtypeCPU(None) - NODE = ootype.Instance('NODE', ootype.ROOT, {}) NODE._add_fields({'value': ootype.Signed, 'next': NODE}) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizeopt.py Sat Aug 29 16:20:26 2009 @@ -1,5 +1,4 @@ import py -from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import instantiate from pypy.jit.metainterp.test.test_resume import MyMetaInterp @@ -1154,12 +1153,7 @@ else: tag, resolved, fieldstext = virtuals[varname] if tag[0] == 'virtual': - if not self.cpu.is_oo: - assert box.getptr(rclass.OBJECTPTR).typeptr == tag[1] - else: - root = box.getobj() - root = ootype.cast_from_object(ootype.ROOT, root) - assert ootype.classof(root) == tag[1] + assert self.get_class_of_box(box) == tag[1] elif tag[0] == 'varray': pass # xxx check arraydescr elif tag[0] == 'vstruct': Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py Sat Aug 29 16:20:26 2009 @@ -13,3 +13,7 @@ sys.setrecursionlimit(cls._recursion_limit) # ==========> test_recursive.py + + @py.test.mark.xfail + def test_inline_faulty_can_inline(self): + test_recursive.RecursiveTests.test_inline_faulty_can_inline(self) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/typesystem.py Sat Aug 29 16:20:26 2009 @@ -1,9 +1,9 @@ -#from pypy.rpython.annlowlevel import base_ptr_lltype, base_obj_ootype -#from pypy.rpython.annlowlevel import cast_instance_to_base_ptr -#from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, llstr, oostr +from pypy.rpython.annlowlevel import cast_instance_to_base_ptr +from pypy.rpython.annlowlevel import cast_instance_to_base_obj +from pypy.jit.metainterp import history from pypy.jit.metainterp import history def deref(T): @@ -39,10 +39,22 @@ name = 'lltype' functionptr = staticmethod(lltype.functionptr) - #ROOT_TYPE = llmemory.Address - #BASE_OBJ_TYPE = base_ptr_lltype() - #NULL_OBJECT = base_ptr_lltype()._defl() - #cast_instance_to_base_ptr = staticmethod(cast_instance_to_base_ptr) + nullptr = staticmethod(lltype.nullptr) + cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) + BASETYPE = llmemory.GCREF + BoxRef = history.BoxPtr + ConstRef = history.ConstPtr + ConstAddr = history.ConstAddr + loops_done_with_this_frame_ref = None # patched by compile.py + CVAL_NULLREF = None # patched by optimizeopt.py + + def get_VABLERTI(self): + from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR + return VABLERTIPTR + + def new_ConstRef(self, x): + ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) + return history.ConstPtr(ptrval) def get_typeptr(self, obj): return obj.typeptr @@ -52,11 +64,18 @@ FUNCPTRTYPE = lltype.Ptr(FUNCTYPE) return FUNCTYPE, FUNCPTRTYPE + def get_superclass(self, TYPE): + return lltype.Ptr(TYPE.TO._first_struct()[1]) + + def cast_to_instance_maybe(self, TYPE, instance): + return lltype.cast_pointer(TYPE, instance) + cast_to_instance_maybe._annspecialcase_ = 'specialize:arg(1)' + def cast_fnptr_to_root(self, fnptr): return llmemory.cast_ptr_to_adr(fnptr) def cls_of_box(self, cpu, box): - obj = box.getptr(lltype.Ptr(rclass.OBJECT)) + obj = box.getref(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(cpu.cast_adr_to_int(cls)) @@ -75,9 +94,12 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getptr(lltype.Ptr(rclass.OBJECT)) + obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) return cast_base_ptr_to_instance(Exception, obj) + def cast_to_baseclass(self, value): + return lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), value) + def clean_box(self, box): if isinstance(box, history.BoxPtr): box.value = lltype.nullptr(llmemory.GCREF.TO) @@ -95,34 +117,71 @@ ll = llstr(str) return history.ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, ll)) + def cast_ref_to_hashable(self, cpu, ptr): + adr = llmemory.cast_ptr_to_adr(ptr) + return cpu.cast_adr_to_int(adr) + + def cast_baseclass_to_hashable(self, cpu, ptr): + adr = llmemory.cast_ptr_to_adr(ptr) + return cpu.cast_adr_to_int(adr) + + def cast_from_ref(self, TYPE, value): + return lltype.cast_opaque_ptr(TYPE, value) + cast_from_ref._annspecialcase_ = 'specialize:arg(1)' + + def cast_to_ref(self, value): + return lltype.cast_opaque_ptr(llmemory.GCREF, value) + cast_to_ref._annspecialcase_ = 'specialize:ll' + + def getaddr_for_box(self, cpu, box): + return box.getaddr(cpu) class OOTypeHelper(TypeSystemHelper): name = 'ootype' functionptr = staticmethod(ootype.static_meth) - #ROOT_TYPE = ootype.Object - #BASE_OBJ_TYPE = base_obj_ootype() - #NULL_OBJECT = base_obj_ootype()._defl() - #cast_instance_to_base_ptr = staticmethod(cast_instance_to_base_obj) + nullptr = staticmethod(ootype.null) + cast_instance_to_base_ref = staticmethod(cast_instance_to_base_obj) + BASETYPE = ootype.Object + BoxRef = history.BoxObj + ConstRef = history.ConstObj + ConstAddr = history.ConstObj + loops_done_with_this_frame_ref = None # patched by compile.py + CVAL_NULLREF = None # patched by optimizeopt.py + + def get_VABLERTI(self): + from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI + return VABLERTI + + def new_ConstRef(self, x): + obj = ootype.cast_to_object(x) + return history.ConstObj(obj) def get_typeptr(self, obj): - return obj.meta + return ootype.classof(obj) def get_FuncType(self, ARGS, RESULT): FUNCTYPE = ootype.StaticMethod(ARGS, RESULT) return FUNCTYPE, FUNCTYPE + def get_superclass(self, TYPE): + return TYPE._superclass + + def cast_to_instance_maybe(self, TYPE, instance): + return instance + cast_to_instance_maybe._annspecialcase_ = 'specialize:arg(1)' + def cast_fnptr_to_root(self, fnptr): return ootype.cast_to_object(fnptr) def cls_of_box(self, cpu, box): - obj = ootype.cast_from_object(ootype.ROOT, box.getobj()) + obj = box.getref(ootype.ROOT) oocls = ootype.classof(obj) return history.ConstObj(ootype.cast_to_object(oocls)) def subclassOf(self, cpu, clsbox1, clsbox2): - cls1 = ootype.cast_from_object(ootype.Class, clsbox1.getobj()) - cls2 = ootype.cast_from_object(ootype.Class, clsbox2.getobj()) + cls1 = clsbox1.getref(ootype.Class) + cls2 = clsbox2.getref(ootype.Class) return ootype.subclassof(cls1, cls2) def get_exception_box(self, etype): @@ -133,9 +192,12 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = ootype.cast_from_object(ootype.ROOT, evaluebox.getobj()) + obj = evaluebox.getref(ootype.ROOT) return cast_base_ptr_to_instance(Exception, obj) + def cast_to_baseclass(self, value): + return ootype.cast_from_object(ootype.ROOT, value) + def clean_box(self, box): if isinstance(box, history.BoxObj): box.value = ootype.NULL @@ -153,6 +215,22 @@ oo = oostr(str) return history.ConstObj(ootype.cast_to_object(oo)) + def cast_ref_to_hashable(self, cpu, obj): + return ootype.cast_to_object(obj) + + def cast_baseclass_to_hashable(self, cpu, obj): + return ootype.cast_to_object(obj) + def cast_from_ref(self, TYPE, value): + return ootype.cast_from_object(TYPE, value) + cast_from_ref._annspecialcase_ = 'specialize:arg(1)' + + def cast_to_ref(self, value): + return ootype.cast_to_object(value) + cast_to_ref._annspecialcase_ = 'specialize:ll' + + def getaddr_for_box(self, cpu, box): + return box.getref_base() + llhelper = LLTypeHelper() oohelper = OOTypeHelper() Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Sat Aug 29 16:20:26 2009 @@ -1,12 +1,10 @@ from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype -from pypy.rpython.annlowlevel import cast_instance_to_base_ptr -from pypy.rpython.annlowlevel import cast_instance_to_base_obj from pypy.rpython.annlowlevel import cast_base_ptr_to_instance from pypy.rpython import rvirtualizable2 from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.typesystem import deref +from pypy.jit.metainterp.typesystem import deref, fieldType, arrayItem from pypy.jit.metainterp import history from pypy.jit.metainterp.warmspot import wrap, unwrap @@ -16,17 +14,10 @@ self.warmrunnerdesc = warmrunnerdesc jitdriver = warmrunnerdesc.jitdriver cpu = warmrunnerdesc.cpu - self.is_oo = cpu.is_oo - if not self.is_oo: - from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR - self.VABLERTI = VABLERTIPTR - self.null_vable_rti = lltype.nullptr(VABLERTIPTR.TO) - self.BoxArray = history.BoxPtr - else: - from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI - self.VABLERTI = VABLERTI - self.null_vable_rti = ootype.make_null_instance(VABLERTI) - self.BoxArray = history.BoxObj + self.cpu = cpu + self.VABLERTI = cpu.ts.get_VABLERTI() + self.null_vable_rti = cpu.ts.nullptr(deref(self.VABLERTI)) + self.BoxArray = cpu.ts.BoxRef # assert len(jitdriver.virtualizables) == 1 # for now [vname] = jitdriver.virtualizables @@ -34,16 +25,10 @@ self.index_of_virtualizable = index VTYPEPTR = warmrunnerdesc.JIT_ENTER_FUNCTYPE.ARGS[index] while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints: - if not self.is_oo: - VTYPEPTR = lltype.Ptr(VTYPEPTR.TO._first_struct()[1]) - else: - VTYPEPTR = VTYPEPTR._superclass + VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR) self.VTYPEPTR = VTYPEPTR self.VTYPE = VTYPE = deref(VTYPEPTR) - if not self.is_oo: - self.null_vable = lltype.nullptr(VTYPE) - else: - self.null_vable = ootype.null(VTYPE) + self.null_vable = cpu.ts.nullptr(VTYPE) # accessor = VTYPE._hints['virtualizable2_accessor'] all_fields = accessor.fields @@ -57,26 +42,16 @@ self.static_fields = static_fields self.array_fields = array_fields # - if not self.is_oo: # lltype - assert isinstance(VTYPEPTR, lltype.Ptr) - FIELDTYPES = [getattr(VTYPE, name) for name in static_fields] - ARRAYITEMTYPES = [] - for name in array_fields: - ARRAYPTR = getattr(VTYPE, name) - assert isinstance(ARRAYPTR, lltype.Ptr) - assert isinstance(ARRAYPTR.TO, lltype.GcArray) - ARRAYITEMTYPES.append(ARRAYPTR.TO.OF) - self.array_descrs = [cpu.arraydescrof(getattr(VTYPE, name).TO) - for name in array_fields] - else: # ootype - FIELDTYPES = [VTYPE._field_type(name) for name in static_fields] - ARRAYITEMTYPES = [] - for name in array_fields: - ARRAY = VTYPE._field_type(name) - assert isinstance(ARRAY, ootype.Array) - ARRAYITEMTYPES.append(ARRAY.ITEM) - self.array_descrs = [cpu.arraydescrof(VTYPE._field_type(name)) - for name in array_fields] + FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields] + ARRAYITEMTYPES = [] + for name in array_fields: + ARRAYPTR = fieldType(VTYPE, name) + ARRAY = deref(ARRAYPTR) + assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array)) + assert isinstance(ARRAY, (lltype.GcArray, ootype.Array)) + ARRAYITEMTYPES.append(arrayItem(ARRAY)) + self.array_descrs = [cpu.arraydescrof(deref(fieldType(VTYPE, name))) + for name in array_fields] # self.num_static_extra_boxes = len(static_fields) self.num_arrays = len(array_fields) @@ -93,9 +68,9 @@ self.array_field_descrs = [cpu.fielddescrof(VTYPE, name) for name in array_fields] # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = cpu.ts.getlength + getarrayitem = cpu.ts.getarrayitem + setarrayitem = cpu.ts.setarrayitem # def read_boxes(cpu, virtualizable): boxes = [] @@ -178,24 +153,17 @@ force_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs - ts = self.warmrunnerdesc.ts + ts = self.warmrunnerdesc.cpu.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) rvirtualizable2.replace_promote_virtualizable_with_call( all_graphs, self.VTYPEPTR, funcptr) def unwrap_virtualizable_box(self, virtualizable_box): - if not self.is_oo: - return virtualizable_box.getptr(self.VTYPEPTR) - else: - obj = virtualizable_box.getobj() - return ootype.cast_from_object(self.VTYPE, obj) + return virtualizable_box.getref(self.VTYPEPTR) def cast_to_vtype(self, virtualizable): - if not self.is_oo: - return lltype.cast_pointer(self.VTYPEPTR, virtualizable) - else: - return virtualizable + return self.cpu.ts.cast_to_instance_maybe(self.VTYPEPTR, virtualizable) cast_to_vtype._annspecialcase_ = 'specialize:ll' def is_vtypeptr(self, TYPE): @@ -203,10 +171,7 @@ def cast_instance_to_base_ptr(self, vable_rti): if we_are_translated(): - if not self.is_oo: - return cast_instance_to_base_ptr(vable_rti) - else: - return cast_instance_to_base_obj(vable_rti) + return self.cpu.ts.cast_instance_to_base_ref(vable_rti) else: vable_rti._TYPE = self.VABLERTI # hack for non-translated mode return vable_rti Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Sat Aug 29 16:20:26 2009 @@ -145,7 +145,7 @@ if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) - self.metainterp_sd.generate_bytecode(policy, self.ts) + self.metainterp_sd.generate_bytecode(policy) self.make_enter_function() self.rewrite_can_enter_jit() self.rewrite_set_param() @@ -164,11 +164,6 @@ def set_translator(self, translator): self.translator = translator - if translator.rtyper.type_system.name == 'lltypesystem': - self.ts = LLTypeHelper() - else: - assert translator.rtyper.type_system.name == 'ootypesystem' - self.ts = OOTypeHelper() self.gcdescr = gc.get_description(translator.config) def find_portal(self): @@ -277,7 +272,7 @@ annhelper = MixLevelHelperAnnotator(self.translator.rtyper) s_result = annotationoftype(rettype) RETTYPE = annhelper.rtyper.getrepr(s_result).lowleveltype - FUNC, PTR = self.ts.get_FuncType(self.green_args_spec, RETTYPE) + FUNC, PTR = self.cpu.ts.get_FuncType(self.green_args_spec, RETTYPE) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] graph = annhelper.getgraph(func, args_s, s_result) funcptr = annhelper.graph2delayed(graph, FUNC) @@ -300,9 +295,9 @@ self.red_args_types.append(history.getkind(TYPE)) RESTYPE = graph.getreturnvar().concretetype (self.JIT_ENTER_FUNCTYPE, - self.PTR_JIT_ENTER_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, lltype.Void) + self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, - self.PTR_PORTAL_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, RESTYPE) + self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) def rewrite_can_enter_jit(self): @@ -374,7 +369,7 @@ # ____________________________________________________________ # Prepare the portal_runner() helper # - portal_ptr = self.ts.functionptr(PORTALFUNC, 'portal', + portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal', graph = portalgraph) portalfunc_ARGS = unrolling_iterable( [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)]) @@ -390,33 +385,19 @@ def __str__(self): return 'DoneWithThisFrameInt(%s)' % (self.result,) - class DoneWithThisFramePtr(JitException): - def __init__(self, result): - assert lltype.typeOf(result) == llmemory.GCREF + class DoneWithThisFrameRef(JitException): + def __init__(self, cpu, result): + assert lltype.typeOf(result) == cpu.ts.BASETYPE self.result = result def __str__(self): - return 'DoneWithThisFramePtr(%s)' % (self.result,) + return 'DoneWithThisFrameRef(%s)' % (self.result,) - class DoneWithThisFrameObj(JitException): - def __init__(self, result): - assert ootype.typeOf(result) == ootype.Object - self.result = result - def __str__(self): - return 'DoneWithThisFrameObj(%s)' % (self.result,) - - class ExitFrameWithExceptionPtr(JitException): - def __init__(self, value): - assert lltype.typeOf(value) == llmemory.GCREF + class ExitFrameWithExceptionRef(JitException): + def __init__(self, cpu, value): + assert lltype.typeOf(value) == cpu.ts.BASETYPE self.value = value def __str__(self): - return 'ExitFrameWithExceptionPtr(%s)' % (self.value,) - - class ExitFrameWithExceptionObj(JitException): - def __init__(self, value): - assert lltype.typeOf(value) == ootype.Object - self.value = value - def __str__(self): - return 'ExitFrameWithExceptionObj(%s)' % (self.value,) + return 'ExitFrameWithExceptionRef(%s)' % (self.value,) class ContinueRunningNormally(JitException): def __init__(self, argboxes): @@ -433,22 +414,18 @@ self.DoneWithThisFrameVoid = DoneWithThisFrameVoid self.DoneWithThisFrameInt = DoneWithThisFrameInt - self.DoneWithThisFramePtr = DoneWithThisFramePtr - self.DoneWithThisFrameObj = DoneWithThisFrameObj - self.ExitFrameWithExceptionPtr = ExitFrameWithExceptionPtr - self.ExitFrameWithExceptionObj = ExitFrameWithExceptionObj + self.DoneWithThisFrameRef = DoneWithThisFrameRef + self.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.ContinueRunningNormally = ContinueRunningNormally self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt - self.metainterp_sd.DoneWithThisFramePtr = DoneWithThisFramePtr - self.metainterp_sd.DoneWithThisFrameObj = DoneWithThisFrameObj - self.metainterp_sd.ExitFrameWithExceptionPtr = ExitFrameWithExceptionPtr - self.metainterp_sd.ExitFrameWithExceptionObj = ExitFrameWithExceptionObj + self.metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef + self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally rtyper = self.translator.rtyper RESULT = PORTALFUNC.RESULT result_kind = history.getkind(RESULT) - is_oo = self.cpu.is_oo + ts = self.cpu.ts def ll_portal_runner(*args): while 1: @@ -466,26 +443,13 @@ except DoneWithThisFrameInt, e: assert result_kind == 'int' return lltype.cast_primitive(RESULT, e.result) - except DoneWithThisFramePtr, e: - assert result_kind == 'ptr' - return lltype.cast_opaque_ptr(RESULT, e.result) - except DoneWithThisFrameObj, e: - assert result_kind == 'obj' - return ootype.cast_from_object(RESULT, e.result) - except ExitFrameWithExceptionPtr, e: - assert not is_oo - value = lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), - e.value) - if not we_are_translated(): - raise LLException(value.typeptr, value) - else: - value = cast_base_ptr_to_instance(Exception, value) - raise Exception, value - except ExitFrameWithExceptionObj, e: - assert is_oo - value = ootype.cast_from_object(ootype.ROOT, e.value) + except DoneWithThisFrameRef, e: + assert result_kind == 'ref' + return ts.cast_from_ref(RESULT, e.result) + except ExitFrameWithExceptionRef, e: + value = ts.cast_to_baseclass(e.value) if not we_are_translated(): - raise LLException(ootype.classof(value), value) + raise LLException(ts.get_typeptr(value), value) else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value @@ -526,8 +490,8 @@ def rewrite_set_param(self): closures = {} graphs = self.translator.graphs - _, PTR_SET_PARAM_FUNCTYPE = self.ts.get_FuncType([lltype.Signed], - lltype.Void) + _, PTR_SET_PARAM_FUNCTYPE = self.cpu.ts.get_FuncType([lltype.Signed], + lltype.Void) def make_closure(fullfuncname): state = self.state def closure(i): @@ -584,9 +548,9 @@ if TYPE is lltype.Void: return None if isinstance(TYPE, lltype.Ptr): - return box.getptr(TYPE) + return box.getref(TYPE) if isinstance(TYPE, ootype.OOType): - return ootype.cast_from_object(TYPE, box.getobj()) + return box.getref(TYPE) else: return lltype.cast_primitive(TYPE, box.getint()) unwrap._annspecialcase_ = 'specialize:arg(0)' @@ -666,9 +630,9 @@ MAX_HASH_TABLE_BITS = 1 THRESHOLD_LIMIT = sys.maxint // 2 # - getlength = warmrunnerdesc.ts.getlength - getarrayitem = warmrunnerdesc.ts.getarrayitem - setarrayitem = warmrunnerdesc.ts.setarrayitem + getlength = warmrunnerdesc.cpu.ts.getlength + getarrayitem = warmrunnerdesc.cpu.ts.getarrayitem + setarrayitem = warmrunnerdesc.cpu.ts.setarrayitem # rtyper = warmrunnerdesc.translator.rtyper can_inline_ptr = warmrunnerdesc.can_inline_ptr @@ -712,12 +676,9 @@ def set_future_value(j, value, typecode): cpu = metainterp_sd.cpu - if typecode == 'ptr': - ptrvalue = lltype.cast_opaque_ptr(llmemory.GCREF, value) - cpu.set_future_value_ptr(j, ptrvalue) - elif typecode == 'obj': - objvalue = ootype.cast_to_object(value) - cpu.set_future_value_obj(j, objvalue) + if typecode == 'ref': + refvalue = cpu.ts.cast_to_ref(value) + cpu.set_future_value_ref(j, refvalue) elif typecode == 'int': intvalue = lltype.cast_primitive(lltype.Signed, value) cpu.set_future_value_int(j, intvalue) Modified: pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_jit.py Sat Aug 29 16:20:26 2009 @@ -9,7 +9,6 @@ class TestSPLIJit(JitMixin): type_system = 'lltype' CPUClass = runner.LLtypeCPU - ts = LLTypeHelper() def interpret(self, f, args): coderepr = serializer.serialize(f.func_code) From antocuni at codespeak.net Sat Aug 29 16:20:58 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 16:20:58 +0200 (CEST) Subject: [pypy-svn] r67318 - pypy/branch/pyjitpl5-less-is_oo Message-ID: <20090829142058.C4F95168015@codespeak.net> Author: antocuni Date: Sat Aug 29 16:20:57 2009 New Revision: 67318 Removed: pypy/branch/pyjitpl5-less-is_oo/ Log: remove merged branch From antocuni at codespeak.net Sat Aug 29 16:26:55 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 16:26:55 +0200 (CEST) Subject: [pypy-svn] r67319 - in pypy/branch/pyjitpl5/pypy/jit: backend backend/llgraph backend/test metainterp Message-ID: <20090829142655.6EC50168015@codespeak.net> Author: antocuni Date: Sat Aug 29 16:26:53 2009 New Revision: 67319 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5/pypy/jit/backend/logger.py pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: remove unused imports and a tiny bit of code duplication Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 29 16:26:53 2009 @@ -7,7 +7,7 @@ import sys from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, ConstObj, +from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr BoxInt, BoxPtr, BoxObj, REF) from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype Modified: pypy/branch/pyjitpl5/pypy/jit/backend/logger.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/logger.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/logger.py Sat Aug 29 16:26:53 2009 @@ -1,8 +1,8 @@ import os from pypy.rlib.objectmodel import compute_unique_id from pypy.jit.metainterp.resoperation import rop -from pypy.jit.metainterp.history import Const, ConstInt, Box, ConstPtr, BoxPtr,\ - BoxInt, ConstAddr, BoxObj, ConstObj +from pypy.jit.metainterp.history import Const, ConstInt, Box, \ + BoxInt, ConstAddr class AbstractLogger(object): Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Sat Aug 29 16:26:53 2009 @@ -23,10 +23,7 @@ if isinstance(box, BoxInt): self.cpu.set_future_value_int(j, box.getint()) j += 1 - elif isinstance(box, BoxPtr): - self.cpu.set_future_value_ref(j, box.getref_base()) - j += 1 - elif isinstance(box, BoxObj): + elif isinstance(box, (BoxPtr, BoxObj)): self.cpu.set_future_value_ref(j, box.getref_base()) j += 1 res = self.cpu.execute_operations(loop) Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sat Aug 29 16:26:53 2009 @@ -1,4 +1,4 @@ -from pypy.jit.metainterp.history import Box, BoxInt, BoxPtr, BoxObj +from pypy.jit.metainterp.history import Box, BoxInt from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstObj, REF from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp.specnode import SpecNode, NotSpecNode, ConstantSpecNode From antocuni at codespeak.net Sat Aug 29 16:33:20 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 29 Aug 2009 16:33:20 +0200 (CEST) Subject: [pypy-svn] r67320 - pypy/branch/pyjitpl5/pypy/jit/backend/llgraph Message-ID: <20090829143320.9C1E7168015@codespeak.net> Author: antocuni Date: Sat Aug 29 16:33:20 2009 New Revision: 67320 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Log: this is what happens when you don't run tests before committing :-/ Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py Sat Aug 29 16:33:20 2009 @@ -7,7 +7,7 @@ import sys from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr +from pypy.jit.metainterp.history import (ConstInt, ConstPtr, ConstAddr, BoxInt, BoxPtr, BoxObj, REF) from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype From arigo at codespeak.net Sat Aug 29 16:47:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 16:47:36 +0200 (CEST) Subject: [pypy-svn] r67321 - in pypy/branch/pyjitpl5-llmodel/pypy/jit: backend backend/llsupport backend/llsupport/test backend/x86 backend/x86/test metainterp Message-ID: <20090829144736.2D33E168016@codespeak.net> Author: arigo Date: Sat Aug 29 16:47:35 2009 New Revision: 67321 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/logger.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_runner.py pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/history.py Log: In-progress. Attach the repr_of_descr() method to Descrs. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 16:47:35 2009 @@ -18,6 +18,9 @@ def __init__(self, size): self.size = size + def repr_of_descr(self): + return '' % self.size + def get_size_descr(STRUCT, translate_support_code, _cache=weakref.WeakKeyDictionary()): try: @@ -47,12 +50,17 @@ def is_pointer_field(self): return False # unless overridden by GcPtrFieldDescr + def repr_of_descr(self): + return '<%s %s>' % (self._clsname, self.offset) + class NonGcPtrFieldDescr(AbstractFieldDescr): + _clsname = 'NonGcPtrFieldDescr' def get_field_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrFieldDescr(NonGcPtrFieldDescr): + _clsname = 'GcPtrFieldDescr' def is_pointer_field(self): return True @@ -96,12 +104,17 @@ def is_array_of_pointers(self): return False # unless overridden by GcPtrArrayDescr + def repr_of_descr(self): + return '<%s>' % self._clsname + class NonGcPtrArrayDescr(AbstractArrayDescr): + _clsname = 'NonGcPtrArrayDescr' def get_item_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrArrayDescr(NonGcPtrArrayDescr): + _clsname = 'GcPtrArrayDescr' def is_array_of_pointers(self): return True @@ -220,10 +233,11 @@ except KeyError: # class Descr(AbstractDescr): + _clsname = '%s%sDescr' % (TYPE._name, nameprefix) def get_field_size(self, translate_support_code): return symbolic.get_size(TYPE, translate_support_code) get_item_size = get_field_size # - Descr.__name__ = '%s%sDescr' % (TYPE._name, nameprefix) + Descr.__name__ = Descr._clsname _cache[nameprefix, TYPE] = Descr return Descr Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 16:47:35 2009 @@ -42,14 +42,22 @@ res = rffi.cast(lltype.Signed, x) return res - def cast_int_to_gcref(self, x): + @staticmethod + def cast_int_to_gcref(x): if not we_are_translated(): _check_addr_range(x) return rffi.cast(llmemory.GCREF, x) - def cast_gcref_to_int(self, x): + @staticmethod + def cast_gcref_to_int(x): return rffi.cast(lltype.Signed, x) + @staticmethod + def cast_int_to_adr(x): + if not we_are_translated(): + _check_addr_range(x) + return rffi.cast(llmemory.Address, x) + def sizeof(self, S): return get_size_descr(S, self.translate_support_code) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 16:47:35 2009 @@ -42,6 +42,7 @@ assert descr_z.__class__ is NonGcPtrFieldDescr if not tsc: assert descr_x.offset < descr_y.offset < descr_z.offset + assert descr_x.sort_key() < descr_y.sort_key() < descr_z.sort_key() assert descr_x.get_field_size(False) == rffi.sizeof(lltype.Char) assert descr_y.get_field_size(False) == rffi.sizeof(lltype.Ptr(T)) assert descr_z.get_field_size(False) == rffi.sizeof(lltype.Ptr(U)) @@ -100,3 +101,49 @@ assert isinstance(descr1.get_item_size(True), Symbolic) assert isinstance(descr2.get_item_size(True), Symbolic) assert isinstance(descr3.get_item_size(True), Symbolic) + + +def test_get_call_descr(): + descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False) + assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char) + assert not descr1.returns_a_pointer() + assert descr1.arg_classes == [BoxInt, BoxInt] + # + T = lltype.GcStruct('T') + descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False) + assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T)) + assert descr2.returns_a_pointer() + assert descr2.arg_classes == [BoxPtr] + # + U = lltype.GcStruct('U', ('x', lltype.Signed)) + assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False) + + +def test_repr_of_descr(): + T = lltype.GcStruct('T') + S = lltype.GcStruct('S', ('x', lltype.Char), + ('y', lltype.Ptr(T)), + ('z', lltype.Ptr(T))) + descr1 = get_size_descr(S, False) + s = symbolic.get_size(S, False) + assert descr1.repr_of_descr() == '' % s + # + descr2 = get_field_descr(S, 'y', False) + o, _ = symbolic.get_field_token(S, 'y', False) + assert descr2.repr_of_descr() == '' % o + # + descr2i = get_field_descr(S, 'x', False) + o, _ = symbolic.get_field_token(S, 'x', False) + assert descr2i.repr_of_descr() == '' % o + # + descr3 = get_array_descr(lltype.GcArray(lltype.Ptr(S))) + assert descr3.repr_of_descr() == '' + # + descr3i = get_array_descr(lltype.GcArray(lltype.Char)) + assert descr3i.repr_of_descr() == '' + # + descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S), False) + assert 'GcPtrCallDescr' in descr4.repr_of_descr() + # + descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char, False) + assert 'IntCallDescr' in descr4i.repr_of_descr() Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/logger.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/logger.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/logger.py Sat Aug 29 16:47:35 2009 @@ -31,7 +31,7 @@ compute_unique_id(loop)) def repr_of_descr(self, descr): - return '' + return descr.repr_of_descr() def repr_of_arg(self, memo, arg): try: @@ -124,3 +124,10 @@ args_s = ','.join([self.repr_of_arg(memo, box) for box in valueboxes]) os.write(self._log_fd, "CALL\n") os.write(self._log_fd, "%s %s\n" % (name, args_s)) + + +class LLLogger(AbstractLogger): + is_oo = False + +class OOLogger(AbstractLogger): + is_oo = True Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sat Aug 29 16:47:35 2009 @@ -1,6 +1,6 @@ import sys, os import ctypes -from pypy.jit.backend.x86 import symbolic +from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT @@ -29,18 +29,6 @@ def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) -class x86Logger(AbstractLogger): - - is_oo = False - - def repr_of_descr(self, descr): - from pypy.jit.backend.x86.runner import ConstDescr3 - if isinstance(descr, ConstDescr3): - return (str(descr.v0) + "," + str(descr.v1) + - "," + str(descr.flag2)) - return AbstractLogger.repr_of_descr(self, descr) - - class MachineCodeBlockWrapper(object): MC_SIZE = 1024*1024 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sat Aug 29 16:47:35 2009 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable from pypy.rlib import rgc -from pypy.jit.backend.x86 import symbolic +from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.x86.jump import remap_stack_layout from pypy.jit.metainterp.resoperation import rop Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py Sat Aug 29 16:47:35 2009 @@ -1,64 +1,28 @@ import sys import ctypes import py -from pypy.rpython.lltypesystem import lltype, llmemory, ll2ctypes, rffi, rstr +from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.objectmodel import CDefinedIntSymbolic, specialize, Symbolic -from pypy.rlib.objectmodel import we_are_translated, keepalive_until_here -from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem import rclass -from pypy.jit.metainterp import history, codewriter -from pypy.jit.metainterp.history import (ResOperation, Box, Const, - ConstInt, ConstPtr, BoxInt, BoxPtr, ConstAddr, AbstractDescr) -from pypy.jit.backend.x86.assembler import Assembler386, WORD, MAX_FAIL_BOXES +from pypy.rlib.objectmodel import we_are_translated +from pypy.jit.metainterp import history +from pypy.jit.backend.x86.assembler import Assembler386, MAX_FAIL_BOXES from pypy.jit.backend.x86.assembler import x86Logger -from pypy.jit.backend.x86 import symbolic -from pypy.jit.metainterp.resoperation import rop, opname -from pypy.rlib.objectmodel import r_dict +from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU history.TreeLoop._x86_compiled = 0 history.TreeLoop._x86_bootstrap_code = 0 -class ConstDescr3(AbstractDescr): - call_loop = None - - def __init__(self, v0, v1, flag2): - self.v0 = v0 - self.v1 = v1 - self.flag2 = flag2 - - def sort_key(self): - return self.v0 # the ofs field for fielddescrs - - def is_pointer_field(self): - return self.flag2 # for fielddescrs - - def is_array_of_pointers(self): - return self.flag2 # for arraydescrs - - def __repr__(self): - return '' % (self.v0, self.v1, self.flag2) - -def _check_addr_range(x): - if sys.platform == 'linux2': - # this makes assumption about address ranges that are valid - # only on linux (?) - assert x == 0 or x > (1<<20) or x < (-1<<20) -class CPU386(object): +class CPU386(AbstractLLCPU): debug = True - is_oo = False logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) def __init__(self, rtyper, stats, translate_support_code=False, mixlevelann=None, gcdescr=None): - from pypy.jit.backend.x86.gc import get_ll_description - self.rtyper = rtyper - self.stats = stats - self.translate_support_code = translate_support_code + AbstractLLCPU.__init__(self, rtyper, stats, translate_support_code, + gcdescr) if translate_support_code: assert mixlevelann self.mixlevelann = mixlevelann @@ -75,38 +39,10 @@ TP = lltype.GcArray(llmemory.GCREF) self._bootstrap_cache = {} self._guard_list = [] - self._compiled_ops = {} - self._builtin_implementations = {} self.setup() self.caught_exception = None if rtyper is not None: # for tests self.lltype2vtable = rtyper.lltype_to_vtable_mapping() - self._setup_prebuilt_error('ovf', OverflowError) - self._setup_prebuilt_error('zer', ZeroDivisionError) - self._descr_caches = {} - self.gc_ll_descr = get_ll_description(gcdescr, self) - self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, - 'typeptr', - translate_support_code) - - def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes - - def _setup_prebuilt_error(self, prefix, Class): - if self.rtyper is not None: # normal case - bk = self.rtyper.annotator.bookkeeper - clsdef = bk.getuniqueclassdef(Class) - ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance( - self.rtyper, clsdef) - else: - # for tests, a random emulated ll_inst will do - ll_inst = lltype.malloc(rclass.OBJECT) - ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, - immortal=True) - setattr(self.assembler, '_%s_error_vtable' % prefix, - llmemory.cast_ptr_to_adr(ll_inst.typeptr)) - setattr(self.assembler, '_%s_error_inst' % prefix, - llmemory.cast_ptr_to_adr(ll_inst)) def setup(self): self.assembler = Assembler386(self, self.translate_support_code) @@ -127,20 +63,6 @@ self.assembler._exception_bck[0] = 0 self.assembler._exception_bck[1] = 0 - def get_overflow_error(self): - self.assembler.make_sure_mc_exists() - ovf_vtable = self.cast_adr_to_int(self.assembler._ovf_error_vtable) - ovf_inst = self.cast_int_to_gcref( - self.cast_adr_to_int(self.assembler._ovf_error_inst)) - return ovf_vtable, ovf_inst - - def get_zero_division_error(self): - self.assembler.make_sure_mc_exists() - zer_vtable = self.cast_adr_to_int(self.assembler._zer_error_vtable) - zer_inst = self.cast_int_to_gcref( - self.cast_adr_to_int(self.assembler._zer_error_inst)) - return zer_vtable, zer_inst - def compile_operations(self, tree, bridge=None): old_loop = tree._x86_compiled if old_loop: @@ -168,31 +90,6 @@ func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr) return func - def _new_box(self, ptr): - if ptr: - return BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) - return BoxInt(0) - - def _get_loop_for_call(self, args, calldescr, ptr): - if calldescr.call_loop is not None: - if not we_are_translated(): - assert (calldescr.shape == - ([arg.type == history.PTR for arg in args[1:]], ptr)) - return calldescr.call_loop - args = [arg.clonebox() for arg in args] - result = self._new_box(ptr) - operations = [ - ResOperation(rop.CALL, args, result, calldescr), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.FAIL, [result], None)] - operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] - loop = history.TreeLoop('call') - loop.inputargs = args - loop.operations = operations - self.compile_operations(loop) - calldescr.call_loop = loop - return loop - def execute_operations(self, loop, verbose=False): assert isinstance(verbose, bool) func = self.get_bootstrap_code(loop) @@ -266,321 +163,6 @@ self._guard_list.append(guard_op) return index - def sizeof(self, S): - try: - return self._descr_caches['sizeof', S] - except KeyError: - pass - descr = self.gc_ll_descr.sizeof(S, self.translate_support_code) - self._descr_caches['sizeof', S] = descr - return descr - - # ------------------- backend-specific ops ------------------------ - - def do_arraylen_gc(self, args, arraydescr): - ofs = self.gc_ll_descr.array_length_ofs - gcref = args[0].getptr(llmemory.GCREF) - length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] - return BoxInt(length) - - def do_getarrayitem_gc(self, args, arraydescr): - field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) - shift, ofs, ptr = self.unpack_arraydescr(arraydescr) - size = 1 << shift - if size == 1: - return BoxInt(ord(rffi.cast(rffi.CArrayPtr(lltype.Char), gcref) - [ofs + field])) - elif size == WORD: - val = (rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) - [ofs/WORD + field]) - if not ptr: - return BoxInt(val) - else: - return BoxPtr(self.cast_int_to_gcref(val)) - else: - raise NotImplementedError("size = %d" % size) - - def do_setarrayitem_gc(self, args, arraydescr): - field = args[1].getint() - gcref = args[0].getptr(llmemory.GCREF) - shift, ofs, ptr = self.unpack_arraydescr(arraydescr) - size = 1 << shift - vbox = args[2] - if size == 1: - v = vbox.getint() - rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[ofs + field] = chr(v) - elif size == WORD: - if not ptr: - a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) - a[ofs/WORD + field] = vbox.getint() - else: - ptr = vbox.getptr(llmemory.GCREF) - self.gc_ll_descr.do_write_barrier(gcref, ptr) - a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) - a[ofs/WORD + field] = self.cast_gcref_to_int(ptr) - else: - raise NotImplementedError("size = %d" % size) - - def _new_do_len(TP): - def do_strlen(self, args, descr=None): - basesize, itemsize, ofs_length = symbolic.get_array_token(TP, - self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) - v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs_length/WORD] - return BoxInt(v) - return do_strlen - - do_strlen = _new_do_len(rstr.STR) - do_unicodelen = _new_do_len(rstr.UNICODE) - - def do_strgetitem(self, args, descr=None): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, - self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) - i = args[1].getint() - v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] - return BoxInt(ord(v)) - - def do_unicodegetitem(self, args, descr=None): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, - self.translate_support_code) - gcref = args[0].getptr(llmemory.GCREF) - i = args[1].getint() - basesize = basesize // itemsize - v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] - return BoxInt(ord(v)) - - @specialize.argtype(1) - def _base_do_getfield(self, gcref, fielddescr): - ofs, size, ptr = self.unpack_fielddescr(fielddescr) - if size == 1: - v = ord(rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[ofs]) - elif size == 2: - v = rffi.cast(rffi.CArrayPtr(rffi.USHORT), gcref)[ofs/2] - v = rffi.cast(lltype.Signed, v) - elif size == WORD: - v = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] - if ptr: - return BoxPtr(self.cast_int_to_gcref(v)) - else: - raise NotImplementedError("size = %d" % size) - return BoxInt(v) - - def do_getfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) - return self._base_do_getfield(gcref, fielddescr) - - def do_getfield_raw(self, args, fielddescr): - return self._base_do_getfield(args[0].getint(), fielddescr) - - @specialize.argtype(2) - def _base_do_setfield(self, fielddescr, gcref, vbox): - ofs, size, ptr = self.unpack_fielddescr(fielddescr) - if size == 1: - v = vbox.getint() - rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[ofs] = chr(v) - elif size == 2: - v = rffi.cast(rffi.USHORT, vbox.getint()) - rffi.cast(rffi.CArrayPtr(rffi.USHORT), gcref)[ofs/2] = v - elif size == WORD: - if ptr: - assert lltype.typeOf(gcref) is not lltype.Signed, ( - "can't handle write barriers for setfield_raw") - ptr = vbox.getptr(llmemory.GCREF) - self.gc_ll_descr.do_write_barrier(gcref, ptr) - a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) - a[ofs/WORD] = self.cast_gcref_to_int(ptr) - else: - a = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref) - a[ofs/WORD] = vbox.getint() - else: - raise NotImplementedError("size = %d" % size) - - def do_setfield_gc(self, args, fielddescr): - gcref = args[0].getptr(llmemory.GCREF) - self._base_do_setfield(fielddescr, gcref, args[1]) - - def do_setfield_raw(self, args, fielddescr): - self._base_do_setfield(fielddescr, args[0].getint(), args[1]) - - def do_new(self, args, descrsize): - res = self.gc_ll_descr.gc_malloc(descrsize) - return BoxPtr(res) - - def do_new_with_vtable(self, args, descr=None): - assert descr is None - classint = args[0].getint() - descrsize = self.class_sizes[classint] - res = self.gc_ll_descr.gc_malloc(descrsize) - as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - as_array[self.vtable_offset/WORD] = classint - return BoxPtr(res) - - def do_new_array(self, args, arraydescr): - num_elem = args[0].getint() - res = self.gc_ll_descr.gc_malloc_array(arraydescr, num_elem) - return BoxPtr(self.cast_adr_to_gcref(res)) - - def do_newstr(self, args, descr=None): - num_elem = args[0].getint() - tsc = self.translate_support_code - res = self.gc_ll_descr.gc_malloc_str(num_elem, tsc) - return BoxPtr(self.cast_adr_to_gcref(res)) - - def do_newunicode(self, args, descr=None): - num_elem = args[0].getint() - tsc = self.translate_support_code - res = self.gc_ll_descr.gc_malloc_unicode(num_elem, tsc) - return BoxPtr(self.cast_adr_to_gcref(res)) - - def do_strsetitem(self, args, descr=None): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, - self.translate_support_code) - index = args[1].getint() - v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) - rffi.cast(rffi.CArrayPtr(lltype.Char), a)[index + basesize] = chr(v) - - def do_unicodesetitem(self, args, descr=None): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, - self.translate_support_code) - index = args[1].getint() - v = args[2].getint() - a = args[0].getptr(llmemory.GCREF) - basesize = basesize // itemsize - rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) - - def do_call(self, args, calldescr): - assert isinstance(calldescr, ConstDescr3) - num_args, size, ptr = self.unpack_calldescr(calldescr) - assert num_args == len(args) - 1 - loop = self._get_loop_for_call(args, calldescr, ptr) - history.set_future_values(self, args) - self.execute_operations(loop, verbose=False) - # Note: if an exception is set, the rest of the code does a bit of - # nonsense but nothing wrong (the return value should be ignored) - if size == 0: - return None - elif ptr: - return BoxPtr(self.get_latest_value_ptr(0)) - else: - return BoxInt(self.get_latest_value_int(0)) - - def do_cast_ptr_to_int(self, args, descr=None): - return BoxInt(self.cast_gcref_to_int(args[0].getptr_base())) - - def do_cast_int_to_ptr(self, args, descr=None): - return BoxPtr(self.cast_int_to_gcref(args[0].getint())) - - # ------------------- helpers and descriptions -------------------- - - @staticmethod - def cast_adr_to_int(x): - res = rffi.cast(lltype.Signed, x) - return res - - @staticmethod - def cast_ptr_to_int(x): - adr = llmemory.cast_ptr_to_adr(x) - return CPU386.cast_adr_to_int(adr) - - def arraydescrof(self, A): - try: - return self._descr_caches['array', A] - except KeyError: - pass - assert isinstance(A, lltype.GcArray) - descr = self.gc_ll_descr.arraydescrof(A, self.translate_support_code) - self._descr_caches['array', A] = descr - return descr - - @staticmethod - def unpack_arraydescr(arraydescr): - assert isinstance(arraydescr, ConstDescr3) - basesize = arraydescr.v0 - itemsize = arraydescr.v1 - ptr = arraydescr.flag2 - counter = 0 - while itemsize != 1: - itemsize >>= 1 - counter += 1 - return counter, basesize, ptr - - @staticmethod - def _is_ptr(TP): - if isinstance(TP, lltype.Ptr) and TP.TO._gckind == 'gc': - return True - else: - return False - - def calldescrof(self, functype, argtypes, resulttype): - cachekey = ('call', functype, tuple(argtypes), resulttype) - try: - return self._descr_caches[cachekey] - except KeyError: - pass - for argtype in argtypes: - if rffi.sizeof(argtype) > WORD: - raise NotImplementedError("bigger than lltype.Signed") - if resulttype is not lltype.Void and rffi.sizeof(resulttype) > WORD: - raise NotImplementedError("bigger than lltype.Signed") - if resulttype is lltype.Void: - size = 0 - else: - size = symbolic.get_size(resulttype, self.translate_support_code) - ptr = self._is_ptr(resulttype) - descr = ConstDescr3(len(argtypes), size, ptr) - shape = ([self._is_ptr(arg) for arg in argtypes], ptr) - self._descr_caches[cachekey] = descr - descr.shape = shape - return descr - - @staticmethod - def unpack_calldescr(calldescr): - assert isinstance(calldescr, ConstDescr3) - return calldescr.v0, calldescr.v1, calldescr.flag2 - - def fielddescrof(self, S, fieldname): - try: - return self._descr_caches['field', S, fieldname] - except KeyError: - pass - ofs, size = symbolic.get_field_token(S, fieldname, - self.translate_support_code) - exp_size = rffi.sizeof(getattr(S, fieldname)) - if type(exp_size) is int: - assert exp_size in [1, 2, WORD] - if (isinstance(getattr(S, fieldname), lltype.Ptr) and - getattr(S, fieldname).TO._gckind == 'gc'): - ptr = True - else: - ptr = False - descr = ConstDescr3(ofs, size, ptr) - self._descr_caches['field', S, fieldname] = descr - return descr - - @staticmethod - def unpack_fielddescr(fielddescr): - assert isinstance(fielddescr, ConstDescr3) - return fielddescr.v0, fielddescr.v1, fielddescr.flag2 - - @staticmethod - def cast_int_to_adr(x): - if not we_are_translated(): - _check_addr_range(x) - return rffi.cast(llmemory.Address, x) - - def cast_gcref_to_int(self, x): - return rffi.cast(lltype.Signed, x) - - def cast_int_to_gcref(self, x): - if not we_are_translated(): - _check_addr_range(x) - return rffi.cast(llmemory.GCREF, x) - - def cast_adr_to_gcref(self, x): - return rffi.cast(llmemory.GCREF, x) CPU = CPU386 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_runner.py Sat Aug 29 16:47:35 2009 @@ -5,7 +5,7 @@ Box) from pypy.jit.backend.x86.runner import CPU from pypy.jit.backend.x86.regalloc import WORD -from pypy.jit.backend.x86 import symbolic +from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.executor import execute from pypy.jit.backend.test.runner_test import LLtypeBackendTest Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/history.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/history.py Sat Aug 29 16:47:35 2009 @@ -127,6 +127,8 @@ raise NotImplementedError def compile_and_attach(self, metainterp, new_loop): raise NotImplementedError + def repr_of_descr(self): + return '%r' % (self,) class AbstractMethDescr(AbstractDescr): # the base class of the result of cpu.methdescrof() From arigo at codespeak.net Sat Aug 29 17:02:58 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 17:02:58 +0200 (CEST) Subject: [pypy-svn] r67322 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport x86 Message-ID: <20090829150258.0419316801D@codespeak.net> Author: arigo Date: Sat Aug 29 17:02:58 2009 New Revision: 67322 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py Log: A few tests start to pass again. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 17:02:58 2009 @@ -79,10 +79,9 @@ rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem return res - def args_for_new(self, descrsize): - assert isinstance(descrsize, ConstDescr3) - size = descrsize.v0 - return [size] + def args_for_new(self, sizedescr): + assert isinstance(sizedescr, SizeDescr) + return [sizedescr.size] def get_funcptr_for_new(self): return self.funcptr_for_new Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 17:02:58 2009 @@ -3,6 +3,7 @@ from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.jit.metainterp.history import BoxInt, BoxPtr, set_future_values from pypy.jit.backend.model import AbstractCPU +from pypy.jit.backend.logger import LLLogger from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes from pypy.jit.backend.llsupport.descr import get_size_descr, SizeDescr @@ -20,6 +21,7 @@ class AbstractLLCPU(AbstractCPU): is_oo = False + logger_cls = LLLogger def __init__(self, rtyper, stats, translate_support_code=False, gcdescr=None): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sat Aug 29 17:02:58 2009 @@ -13,7 +13,6 @@ from pypy.jit.backend.x86 import codebuf from pypy.jit.backend.x86.ri386 import * from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.logger import AbstractLogger # our calling convention - we pass three first args as edx, ecx and eax # and the rest stays on the stack @@ -95,7 +94,7 @@ self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed)) self._exception_addr = 0 self.mcstack = MachineCodeStack() - self.logger = x86Logger() + self.logger = cpu.logger_cls() self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed), MAX_FAIL_BOXES, zero=True) self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF), @@ -103,8 +102,6 @@ def make_sure_mc_exists(self): if self.mc is None: - from pypy.jit.backend.x86.runner import ConstDescr3 - rffi.cast(lltype.Signed, self.fail_boxes_int) # workaround rffi.cast(lltype.Signed, self.fail_boxes_ptr) # workaround self.fail_box_int_addr = rffi.cast(lltype.Signed, Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sat Aug 29 17:02:58 2009 @@ -12,6 +12,7 @@ from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.x86.jump import remap_stack_layout from pypy.jit.metainterp.resoperation import rop +from pypy.jit.backend.llsupport.descr import AbstractFieldDescr REGS = [eax, ecx, edx, ebx, esi, edi] WORD = 4 @@ -798,11 +799,14 @@ def _unpack_arraydescr(self, arraydescr): from pypy.jit.backend.x86.runner import CPU386 + xxx return CPU386.unpack_arraydescr(arraydescr) def _unpack_fielddescr(self, fielddescr): - from pypy.jit.backend.x86.runner import CPU386 - ofs, size, ptr = CPU386.unpack_fielddescr(fielddescr) + assert isinstance(fielddescr, AbstractFieldDescr) + ofs = fielddescr.offset + size = fielddescr.get_field_size(self.translate_support_code) + ptr = fielddescr.is_pointer_field() return imm(ofs), imm(size), ptr def _common_consider_setfield(self, op, ignored, raw): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py Sat Aug 29 17:02:58 2009 @@ -6,7 +6,6 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.jit.metainterp import history from pypy.jit.backend.x86.assembler import Assembler386, MAX_FAIL_BOXES -from pypy.jit.backend.x86.assembler import x86Logger from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU history.TreeLoop._x86_compiled = 0 @@ -15,7 +14,6 @@ class CPU386(AbstractLLCPU): debug = True - logger_cls = x86Logger BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) @@ -163,6 +161,11 @@ self._guard_list.append(guard_op) return index + @staticmethod + def cast_ptr_to_int(x): + adr = llmemory.cast_ptr_to_adr(x) + return CPU386.cast_adr_to_int(adr) + CPU = CPU386 From arigo at codespeak.net Sat Aug 29 17:11:40 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 17:11:40 +0200 (CEST) Subject: [pypy-svn] r67323 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport x86 Message-ID: <20090829151140.20C5216801D@codespeak.net> Author: arigo Date: Sat Aug 29 17:11:39 2009 New Revision: 67323 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Log: Some progress. There must be a typo somewhere, as I get a segfault... Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 17:11:39 2009 @@ -21,6 +21,8 @@ def repr_of_descr(self): return '' % self.size +BaseSizeDescr = SizeDescr + def get_size_descr(STRUCT, translate_support_code, _cache=weakref.WeakKeyDictionary()): try: @@ -36,7 +38,7 @@ # ____________________________________________________________ # FieldDescrs -class AbstractFieldDescr(AbstractDescr): +class BaseFieldDescr(AbstractDescr): def __init__(self, offset): self.offset = offset @@ -54,7 +56,7 @@ return '<%s %s>' % (self._clsname, self.offset) -class NonGcPtrFieldDescr(AbstractFieldDescr): +class NonGcPtrFieldDescr(BaseFieldDescr): _clsname = 'NonGcPtrFieldDescr' def get_field_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) @@ -65,7 +67,7 @@ return True def getFieldDescrClass(TYPE): - return getDescrClass(TYPE, AbstractFieldDescr, GcPtrFieldDescr, + return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr, NonGcPtrFieldDescr, 'Field') def get_field_descr(STRUCT, fieldname, translate_support_code, @@ -88,7 +90,7 @@ _A = lltype.GcArray(lltype.Signed) # a random gcarray -class AbstractArrayDescr(AbstractDescr): +class BaseArrayDescr(AbstractDescr): def get_base_size(self, translate_support_code): basesize, _, _ = symbolic.get_array_token(_A, translate_support_code) @@ -108,7 +110,7 @@ return '<%s>' % self._clsname -class NonGcPtrArrayDescr(AbstractArrayDescr): +class NonGcPtrArrayDescr(BaseArrayDescr): _clsname = 'NonGcPtrArrayDescr' def get_item_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) @@ -119,7 +121,7 @@ return True def getArrayDescrClass(ARRAY): - return getDescrClass(ARRAY.OF, AbstractArrayDescr, GcPtrArrayDescr, + return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr, NonGcPtrArrayDescr, 'Array') def get_array_descr(ARRAY, _cache=weakref.WeakKeyDictionary()): @@ -140,7 +142,7 @@ # ____________________________________________________________ # CallDescrs -class AbstractCallDescr(AbstractDescr): +class BaseCallDescr(AbstractDescr): call_loop = None def __init__(self, arg_classes): @@ -155,7 +157,7 @@ def get_loop_for_call(self, cpu): if self.call_loop is not None: return self.call_loop - args = [cls() for cls in self.arg_classes] + args = [BoxInt()] + [cls() for cls in self.arg_classes] if self.get_result_size(cpu.translate_support_code) == 0: result = None result_list = [] @@ -178,16 +180,16 @@ return loop -class GcPtrCallDescr(AbstractCallDescr): +class GcPtrCallDescr(BaseCallDescr): def returns_a_pointer(self): return True def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) -class IntCallDescr(AbstractCallDescr): +class IntCallDescr(BaseCallDescr): def __init__(self, arg_classes, result_size): - AbstractCallDescr.__init__(self, arg_classes) + BaseCallDescr.__init__(self, arg_classes) self.result_size = result_size def get_result_size(self, translate_support_code): @@ -221,7 +223,7 @@ # ____________________________________________________________ -def getDescrClass(TYPE, AbstractDescr, GcPtrDescr, NonGcPtrDescr, +def getDescrClass(TYPE, BaseDescr, GcPtrDescr, NonGcPtrDescr, nameprefix, _cache={}): if isinstance(TYPE, lltype.Ptr): if TYPE.TO._gckind == 'gc': @@ -232,7 +234,7 @@ return _cache[nameprefix, TYPE] except KeyError: # - class Descr(AbstractDescr): + class Descr(BaseDescr): _clsname = '%s%sDescr' % (TYPE._name, nameprefix) def get_field_size(self, translate_support_code): return symbolic.get_size(TYPE, translate_support_code) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 17:11:39 2009 @@ -5,7 +5,7 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD -from pypy.jit.backend.llsupport.descr import SizeDescr, AbstractArrayDescr +from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr # ____________________________________________________________ @@ -49,11 +49,11 @@ init_fn_ptr() def gc_malloc(self, sizedescr): - assert isinstance(sizedescr, SizeDescr) + assert isinstance(sizedescr, BaseSizeDescr) return self.funcptr_for_new(sizedescr.size) def gc_malloc_array(self, arraydescr, num_elem): - assert isinstance(arraydescr, AbstractArrayDescr) + assert isinstance(arraydescr, BaseArrayDescr) ofs_length = arraydescr.get_ofs_length(self.translate_support_code) basesize = arraydescr.get_base_size(self.translate_support_code) itemsize = arraydescr.get_item_size(self.translate_support_code) @@ -80,7 +80,7 @@ return res def args_for_new(self, sizedescr): - assert isinstance(sizedescr, SizeDescr) + assert isinstance(sizedescr, BaseSizeDescr) return [sizedescr.size] def get_funcptr_for_new(self): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 17:11:39 2009 @@ -6,11 +6,10 @@ from pypy.jit.backend.logger import LLLogger from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes -from pypy.jit.backend.llsupport.descr import get_size_descr, SizeDescr -from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr -from pypy.jit.backend.llsupport.descr import AbstractFieldDescr -from pypy.jit.backend.llsupport.descr import AbstractArrayDescr -from pypy.jit.backend.llsupport.descr import get_call_descr, AbstractCallDescr +from pypy.jit.backend.llsupport.descr import get_size_descr, BaseSizeDescr +from pypy.jit.backend.llsupport.descr import get_field_descr, BaseFieldDescr +from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr +from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr def _check_addr_range(x): if sys.platform == 'linux2': @@ -67,7 +66,7 @@ return get_field_descr(STRUCT, fieldname, self.translate_support_code) def unpack_fielddescr(self, fielddescr): - assert isinstance(fielddescr, AbstractFieldDescr) + assert isinstance(fielddescr, BaseFieldDescr) ofs = fielddescr.offset size = fielddescr.get_field_size(self.translate_support_code) ptr = fielddescr.is_pointer_field() @@ -78,7 +77,7 @@ return get_array_descr(A) def unpack_arraydescr(self, arraydescr): - assert isinstance(arraydescr, AbstractArrayDescr) + assert isinstance(arraydescr, BaseArrayDescr) ofs = arraydescr.get_base_size(self.translate_support_code) size = arraydescr.get_item_size(self.translate_support_code) ptr = arraydescr.is_array_of_pointers() @@ -91,7 +90,7 @@ # ____________________________________________________________ def do_arraylen_gc(self, args, arraydescr): - assert isinstance(arraydescr, AbstractArrayDescr) + assert isinstance(arraydescr, BaseArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) gcref = args[0].getptr_base() length = rffi.cast(rffi.CArrayPtr(lltype.Signed), gcref)[ofs/WORD] @@ -251,7 +250,8 @@ rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v) def do_call(self, args, calldescr): - assert isinstance(calldescr, AbstractCallDescr) + assert isinstance(calldescr, BaseCallDescr) + assert len(args) == 1 + len(calldescr.arg_classes) if not we_are_translated(): assert ([cls.type for cls in calldescr.arg_classes] == [arg.type for arg in args[1:]]) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sat Aug 29 17:11:39 2009 @@ -12,7 +12,8 @@ from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.x86.jump import remap_stack_layout from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport.descr import AbstractFieldDescr +from pypy.jit.backend.llsupport.descr import BaseFieldDescr +from pypy.jit.backend.llsupport.descr import BaseCallDescr REGS = [eax, ecx, edx, ebx, esi, edi] WORD = 4 @@ -718,9 +719,9 @@ def consider_call(self, op, ignored): from pypy.jit.backend.x86.runner import CPU386 calldescr = op.descr - numargs, size, _ = CPU386.unpack_calldescr(calldescr) - assert numargs == len(op.args) - 1 - return self._call(op, [imm(size)] + + assert isinstance(calldescr, BaseCallDescr) + assert len(calldescr.arg_classes) == len(op.args) - 1 + return self._call(op, [imm(calldescr.result_size)] + [self.loc(arg) for arg in op.args]) consider_call_pure = consider_call @@ -798,12 +799,11 @@ op.result) def _unpack_arraydescr(self, arraydescr): - from pypy.jit.backend.x86.runner import CPU386 xxx return CPU386.unpack_arraydescr(arraydescr) def _unpack_fielddescr(self, fielddescr): - assert isinstance(fielddescr, AbstractFieldDescr) + assert isinstance(fielddescr, BaseFieldDescr) ofs = fielddescr.offset size = fielddescr.get_field_size(self.translate_support_code) ptr = fielddescr.is_pointer_field() From arigo at codespeak.net Sat Aug 29 17:38:26 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 17:38:26 +0200 (CEST) Subject: [pypy-svn] r67324 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport test Message-ID: <20090829153826.6C94B168016@codespeak.net> Author: arigo Date: Sat Aug 29 17:38:24 2009 New Revision: 67324 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Log: Test and fix. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 17:38:24 2009 @@ -192,7 +192,7 @@ for TYPE, itemsize in unroll_basic_sizes: if size == itemsize: v = rffi.cast(TYPE, v) - rffi.cast(rffi.CArrayPtr(TYPE), gcref)[ofs] = v + rffi.cast(rffi.CArrayPtr(TYPE), gcref)[ofs/itemsize] = v break else: raise NotImplementedError("size = %d" % size) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Sat Aug 29 17:38:24 2009 @@ -275,6 +275,11 @@ t_box, T_box = self.alloc_instance(self.T) fielddescr = self.cpu.fielddescrof(self.S, 'value') assert not fielddescr.is_pointer_field() + # + self.cpu.do_setfield_gc([t_box, BoxInt(1333)], fielddescr) + r = self.cpu.do_getfield_gc([t_box], fielddescr) + assert r.value == 1333 + # res = self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(39082)], 'void', descr=fielddescr) assert res is None @@ -674,6 +679,8 @@ r = self.cpu.do_getfield_gc([r1], descrshort) assert r.value == 1313 self.cpu.do_setfield_gc([r1, BoxInt(1333)], descrshort) + r = self.cpu.do_getfield_gc([r1], descrshort) + assert r.value == 1333 r = self.execute_operation(rop.GETFIELD_GC, [r1], 'int', descr=descrshort) assert r.value == 1333 From arigo at codespeak.net Sat Aug 29 18:23:24 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:23:24 +0200 (CEST) Subject: [pypy-svn] r67325 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport: . test Message-ID: <20090829162324.E36AD168016@codespeak.net> Author: arigo Date: Sat Aug 29 18:23:21 2009 New Revision: 67325 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Log: Found the bug. Caching of CallDescrs should not be done in a global dict because of the 'call_loop' attribute. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 18:23:21 2009 @@ -196,7 +196,7 @@ return self.result_size -def get_call_descr(ARGS, RESULT, translate_support_code, _cache={}): +def get_call_descr(ARGS, RESULT, translate_support_code, cache): arg_classes = [] for ARG in ARGS: kind = getkind(ARG) @@ -211,13 +211,13 @@ ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc' key = (translate_support_code, tuple(arg_classes), result_size, ptr) try: - return _cache[key] + return cache[key] except KeyError: if ptr: calldescr = GcPtrCallDescr(arg_classes) else: calldescr = IntCallDescr(arg_classes, result_size) - _cache[key] = calldescr + cache[key] = calldescr return calldescr Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 18:23:21 2009 @@ -28,6 +28,7 @@ self.rtyper = rtyper self.stats = stats self.translate_support_code = translate_support_code + self._call_cache = {} self.gc_ll_descr = get_ll_description(gcdescr, self) self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, 'typeptr', @@ -85,7 +86,8 @@ unpack_arraydescr._always_inline_ = True def calldescrof(self, FUNC, ARGS, RESULT): - return get_call_descr(ARGS, RESULT, self.translate_support_code) + return get_call_descr(ARGS, RESULT, self.translate_support_code, + self._call_cache) # ____________________________________________________________ @@ -155,6 +157,15 @@ v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i] return BoxInt(ord(v)) + def do_unicodegetitem(self, args, descr=None): + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, + self.translate_support_code) + gcref = args[0].getptr_base() + i = args[1].getint() + basesize = basesize // itemsize + v = rffi.cast(rffi.CArrayPtr(lltype.UniChar), gcref)[basesize + i] + return BoxInt(ord(v)) + @specialize.argtype(1) def _base_do_getfield(self, gcref, fielddescr): ofs, size, ptr = self.unpack_fielddescr(fielddescr) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 18:23:21 2009 @@ -104,19 +104,22 @@ def test_get_call_descr(): - descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False) + cache = {} + descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False, + cache) assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char) assert not descr1.returns_a_pointer() assert descr1.arg_classes == [BoxInt, BoxInt] # T = lltype.GcStruct('T') - descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False) + descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False, cache) assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T)) assert descr2.returns_a_pointer() assert descr2.arg_classes == [BoxPtr] # U = lltype.GcStruct('U', ('x', lltype.Signed)) - assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False) + assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False, + cache) def test_repr_of_descr(): @@ -142,8 +145,11 @@ descr3i = get_array_descr(lltype.GcArray(lltype.Char)) assert descr3i.repr_of_descr() == '' # - descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S), False) + cache = {} + descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S), + False, cache) assert 'GcPtrCallDescr' in descr4.repr_of_descr() # - descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char, False) + descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char, + False, cache) assert 'IntCallDescr' in descr4i.repr_of_descr() From arigo at codespeak.net Sat Aug 29 18:23:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:23:36 +0200 (CEST) Subject: [pypy-svn] r67326 - in pypy/branch/pyjitpl5-llmodel/pypy/jit: backend/test backend/x86 backend/x86/test metainterp Message-ID: <20090829162336.E4F5016801D@codespeak.net> Author: arigo Date: Sat Aug 29 18:23:36 2009 New Revision: 67326 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_symbolic.py pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/executor.py Log: In-progress, more tests pass. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Sat Aug 29 18:23:36 2009 @@ -400,6 +400,13 @@ a_box, A = self.alloc_array_of(lltype.Signed, 342) arraydescr = self.cpu.arraydescrof(A) assert not arraydescr.is_array_of_pointers() + # + r = self.cpu.do_arraylen_gc([a_box], arraydescr) + assert r.value == 342 + self.cpu.do_setarrayitem_gc([a_box, BoxInt(311), BoxInt(170)], arraydescr) + r = self.cpu.do_getarrayitem_gc([a_box, BoxInt(311)], arraydescr) + assert r.value == 170 + # r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r.value == 342 @@ -410,11 +417,6 @@ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)], 'int', descr=arraydescr) assert r.value == 7441 - r = self.cpu.do_getarrayitem_gc([a_box, BoxInt(310)], arraydescr) - assert r.value == 7441 - self.cpu.do_setarrayitem_gc([a_box, BoxInt(3), BoxInt(170)], arraydescr) - r = self.cpu.do_getarrayitem_gc([a_box, BoxInt(3)], arraydescr) - assert r.value == 170 # a_box, A = self.alloc_array_of(lltype.Char, 11) arraydescr = self.cpu.arraydescrof(A) @@ -513,6 +515,11 @@ assert r.value == 153 def test_unicode_basic(self): + u_box = self.cpu.do_newunicode([ConstInt(5)]) + self.cpu.do_unicodesetitem([u_box, BoxInt(4), BoxInt(123)]) + r = self.cpu.do_unicodegetitem([u_box, BoxInt(4)]) + assert r.value == 123 + # u_box = self.alloc_unicode(u"hello\u1234") r = self.execute_operation(rop.UNICODELEN, [u_box], 'int') assert r.value == 6 @@ -528,10 +535,6 @@ r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(4)], 'int') assert r.value == 31313 - u_box = self.cpu.do_newunicode([ConstInt(5)]) - self.cpu.do_unicodesetitem([u_box, BoxInt(4), BoxInt(123)]) - r = self.cpu.do_unicodegetitem([u_box, BoxInt(4)]) - assert r.value == 123 def test_same_as(self): r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int') Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sat Aug 29 18:23:36 2009 @@ -12,7 +12,7 @@ from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.x86.jump import remap_stack_layout from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport.descr import BaseFieldDescr +from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import BaseCallDescr REGS = [eax, ecx, edx, ebx, esi, edi] @@ -768,14 +768,14 @@ else: assert False, itemsize - def _malloc_varsize(self, ofs_items, ofs_length, size, v, res_v): + def _malloc_varsize(self, ofs_items, ofs_length, scale, v, res_v): # XXX kill this function at some point if isinstance(v, Box): loc = self.make_sure_var_in_reg(v, [v]) other_loc = self.force_allocate_reg(TempBox(), [v]) - self.assembler.load_effective_addr(loc, ofs_items, size, other_loc) + self.assembler.load_effective_addr(loc, ofs_items,scale, other_loc) else: - other_loc = imm(ofs_items + (v.getint() << size)) + other_loc = imm(ofs_items + (v.getint() << scale)) self._call(ResOperation(rop.NEW, [v], res_v), [other_loc], [v]) loc = self.make_sure_var_in_reg(v, [res_v]) @@ -794,13 +794,20 @@ arglocs.append(self.loc(op.args[0])) return self._call(op, arglocs) # boehm GC (XXX kill the following code at some point) - size_of_field, basesize, _ = self._unpack_arraydescr(op.descr) - return self._malloc_varsize(basesize, 0, size_of_field, op.args[0], + scale_of_field, basesize, _ = self._unpack_arraydescr(op.descr) + return self._malloc_varsize(basesize, 0, scale_of_field, op.args[0], op.result) def _unpack_arraydescr(self, arraydescr): - xxx - return CPU386.unpack_arraydescr(arraydescr) + assert isinstance(arraydescr, BaseArrayDescr) + ofs = arraydescr.get_base_size(self.translate_support_code) + size = arraydescr.get_item_size(self.translate_support_code) + ptr = arraydescr.is_array_of_pointers() + scale = 0 + while (1 << scale) < size: + scale += 1 + assert (1 << scale) == size + return scale, ofs, ptr def _unpack_fielddescr(self, fielddescr): assert isinstance(fielddescr, BaseFieldDescr) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_symbolic.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_symbolic.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_symbolic.py Sat Aug 29 18:23:36 2009 @@ -1,8 +1,10 @@ import py -from pypy.jit.backend.x86.symbolic import * -from pypy.jit.backend.x86.runner import CPU386 +from pypy.jit.backend.llsupport.symbolic import * from pypy.rpython.lltypesystem import lltype, rffi +# This test file is here and not in llsupport/test/ because it checks +# that we get correct numbers for a 32-bit machine. + class FakeStats(object): pass @@ -44,15 +46,6 @@ assert itemsize == 4 assert ofs_length == basesize - 4 -def test_array_token_2(): - cpu = CPU386(None, None) - A = lltype.GcArray(lltype.Ptr(lltype.Array(lltype.Signed))) - descr = cpu.arraydescrof(A) - assert not descr.flag2 - A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) - descr = cpu.arraydescrof(A) - assert descr.flag2 - def test_varsized_struct_size(): S1 = lltype.GcStruct('S1', ('parent', S), ('extra', lltype.Signed), @@ -66,16 +59,6 @@ assert basesize == ofs_length + 4 assert itemsize == 1 -def test_methods_of_cpu(): - py.test.skip("A bit pointless") - cpu = CPU386(rtyper=None, stats=FakeStats()) - assert cpu.sizeof(S) == get_size(S, False) - assert cpu.fielddescrof(S, 'y') & 0xffff == get_field_token(S, 'y')[0] - assert cpu.fielddescrof(S, 'y') >> 16 == get_field_token(S, 'y')[1] - A = lltype.GcArray(lltype.Char) - #assert cpu.itemoffsetof(A) == get_array_token(A)[0] - #assert cpu.arraylengthoffset(A) == get_array_token(A)[2] - def test_string(): STR = lltype.GcStruct('String', ('hash', lltype.Signed), ('chars', lltype.Array(lltype.Char))) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/executor.py Sat Aug 29 18:23:36 2009 @@ -234,6 +234,18 @@ def make_execute_list(cpuclass): from pypy.jit.backend.model import AbstractCPU + if 0: # enable this to trace calls to do_xxx + def wrap(fn): + def myfn(*args): + print '<<<', fn.__name__ + try: + return fn(*args) + finally: + print fn.__name__, '>>>' + return myfn + else: + def wrap(fn): + return fn execute = [None] * (rop._LAST+1) for key, value in rop.__dict__.items(): if not key.startswith('_'): @@ -246,9 +258,9 @@ key = key[:-5] name = 'do_' + key.lower() if hasattr(cpuclass, name): - execute[value] = getattr(cpuclass, name) + execute[value] = wrap(getattr(cpuclass, name)) elif name in globals(): - execute[value] = globals()[name] + execute[value] = wrap(globals()[name]) else: assert hasattr(AbstractCPU, name), name cpuclass._execute_list = execute From arigo at codespeak.net Sat Aug 29 18:25:57 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:25:57 +0200 (CEST) Subject: [pypy-svn] r67327 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86 Message-ID: <20090829162557.E51D5168016@codespeak.net> Author: arigo Date: Sat Aug 29 18:25:57 2009 New Revision: 67327 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Log: Fix. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sat Aug 29 18:25:57 2009 @@ -721,7 +721,8 @@ calldescr = op.descr assert isinstance(calldescr, BaseCallDescr) assert len(calldescr.arg_classes) == len(op.args) - 1 - return self._call(op, [imm(calldescr.result_size)] + + size = calldescr.get_result_size(self.translate_support_code) + return self._call(op, [imm(size)] + [self.loc(arg) for arg in op.args]) consider_call_pure = consider_call From arigo at codespeak.net Sat Aug 29 18:29:36 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:29:36 +0200 (CEST) Subject: [pypy-svn] r67328 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090829162936.A7E03168016@codespeak.net> Author: arigo Date: Sat Aug 29 18:29:36 2009 New Revision: 67328 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Log: get_overflow_error(), get_zero_division_error(). Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 18:29:36 2009 @@ -33,10 +33,28 @@ self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, 'typeptr', translate_support_code) + self._setup_prebuilt_error('ovf', OverflowError) + self._setup_prebuilt_error('zer', ZeroDivisionError) def set_class_sizes(self, class_sizes): self.class_sizes = class_sizes + def _setup_prebuilt_error(self, prefix, Class): + if self.rtyper is not None: # normal case + bk = self.rtyper.annotator.bookkeeper + clsdef = bk.getuniqueclassdef(Class) + ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance( + self.rtyper, clsdef) + else: + # for tests, a random emulated ll_inst will do + ll_inst = lltype.malloc(rclass.OBJECT) + ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, + immortal=True) + setattr(self, '_%s_error_vtable' % prefix, + llmemory.cast_ptr_to_adr(ll_inst.typeptr)) + setattr(self, '_%s_error_inst' % prefix, + llmemory.cast_ptr_to_adr(ll_inst)) + # ------------------- helpers and descriptions -------------------- @staticmethod @@ -89,6 +107,18 @@ return get_call_descr(ARGS, RESULT, self.translate_support_code, self._call_cache) + def get_overflow_error(self): + ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable) + ovf_inst = self.cast_int_to_gcref( + self.cast_adr_to_int(self._ovf_error_inst)) + return ovf_vtable, ovf_inst + + def get_zero_division_error(self): + zer_vtable = self.cast_adr_to_int(self._zer_error_vtable) + zer_inst = self.cast_int_to_gcref( + self.cast_adr_to_int(self._zer_error_inst)) + return zer_vtable, zer_inst + # ____________________________________________________________ def do_arraylen_gc(self, args, arraydescr): From arigo at codespeak.net Sat Aug 29 18:42:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:42:09 +0200 (CEST) Subject: [pypy-svn] r67329 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86 Message-ID: <20090829164209.3EE90168016@codespeak.net> Author: arigo Date: Sat Aug 29 18:42:08 2009 New Revision: 67329 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Log: Skip tests running on a moving GC. The rest of the tests pass (at least the non-translation ones). Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sat Aug 29 18:42:08 2009 @@ -126,8 +126,6 @@ zero=True, flavor='raw') self._exception_bck_addr = self.cpu.cast_ptr_to_int( self._exception_bck) - self.mc = self.mcstack.next_mc() - self.mc2 = self.mcstack.next_mc() # the address of the function called by 'new' gc_ll_descr = self.cpu.gc_ll_descr ll_new = gc_ll_descr.get_funcptr_for_new() @@ -147,6 +145,7 @@ # for moving GCs, the array used to hold the address of GC objects # that appear as ConstPtr. if gc_ll_descr.moving_gc: + import py; py.test.skip("in-progress: non-Boehm GC") self.gcrefs = gc_ll_descr.GcRefList() self.single_gcref_descr = ConstDescr3(0, WORD, True) else: @@ -154,6 +153,9 @@ self.gcrootmap = gc_ll_descr.gcrootmap if self.gcrootmap: self.gcrootmap.initialize() + # done + self.mc2 = self.mcstack.next_mc() + self.mc = self.mcstack.next_mc() def _compute_longest_fail_op(self, ops): From arigo at codespeak.net Sat Aug 29 18:58:55 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 18:58:55 +0200 (CEST) Subject: [pypy-svn] r67330 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86 Message-ID: <20090829165855.67467168016@codespeak.net> Author: arigo Date: Sat Aug 29 18:58:55 2009 New Revision: 67330 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Log: Fix. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sat Aug 29 18:58:55 2009 @@ -145,9 +145,9 @@ # for moving GCs, the array used to hold the address of GC objects # that appear as ConstPtr. if gc_ll_descr.moving_gc: - import py; py.test.skip("in-progress: non-Boehm GC") + from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr self.gcrefs = gc_ll_descr.GcRefList() - self.single_gcref_descr = ConstDescr3(0, WORD, True) + self.single_gcref_descr = GcPtrFieldDescr(0) else: self.gcrefs = None self.gcrootmap = gc_ll_descr.gcrootmap From arigo at codespeak.net Sat Aug 29 23:00:30 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 23:00:30 +0200 (CEST) Subject: [pypy-svn] r67331 - in pypy/branch/pyjitpl5-llmodel/pypy: jit/backend jit/backend/llsupport jit/backend/llsupport/test jit/backend/x86 jit/backend/x86/test jit/metainterp rpython/memory/gctransform Message-ID: <20090829210030.1CCD316801D@codespeak.net> Author: arigo Date: Sat Aug 29 23:00:29 2009 New Revision: 67331 Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (contents, props changed) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py Log: In-progress. We can now at least test directly the code in gc.py. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 23:00:29 2009 @@ -1,4 +1,3 @@ -import weakref from pypy.rpython.lltypesystem import lltype from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr @@ -11,6 +10,21 @@ # (in methods actually) using a few classes instead of just one. +class GcCache(object): + def __init__(self, translate_support_code): + self.translate_support_code = translate_support_code + self._cache_size = {} + self._cache_field = {} + self._cache_array = {} + self._cache_call = {} + + def init_size_descr(self, STRUCT, sizedescr): + pass + + def init_array_descr(self, ARRAY, arraydescr): + pass + + # ____________________________________________________________ # SizeDescrs @@ -23,15 +37,15 @@ BaseSizeDescr = SizeDescr -def get_size_descr(STRUCT, translate_support_code, - _cache=weakref.WeakKeyDictionary()): +def get_size_descr(gccache, STRUCT): + cache = gccache._cache_size try: - return _cache[STRUCT][translate_support_code] + return cache[STRUCT] except KeyError: - size = symbolic.get_size(STRUCT, translate_support_code) + size = symbolic.get_size(STRUCT, gccache.translate_support_code) sizedescr = SizeDescr(size) - cachedict = _cache.setdefault(STRUCT, {}) - cachedict[translate_support_code] = sizedescr + gccache.init_size_descr(STRUCT, sizedescr) + cache[STRUCT] = sizedescr return sizedescr @@ -70,17 +84,17 @@ return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr, NonGcPtrFieldDescr, 'Field') -def get_field_descr(STRUCT, fieldname, translate_support_code, - _cache=weakref.WeakKeyDictionary()): +def get_field_descr(gccache, STRUCT, fieldname): + cache = gccache._cache_field try: - return _cache[STRUCT][fieldname, translate_support_code] + return cache[STRUCT][fieldname] except KeyError: offset, _ = symbolic.get_field_token(STRUCT, fieldname, - translate_support_code) + gccache.translate_support_code) FIELDTYPE = getattr(STRUCT, fieldname) fielddescr = getFieldDescrClass(FIELDTYPE)(offset) - cachedict = _cache.setdefault(STRUCT, {}) - cachedict[fieldname, translate_support_code] = fielddescr + cachedict = cache.setdefault(STRUCT, {}) + cachedict[fieldname] = fielddescr return fielddescr @@ -91,6 +105,7 @@ class BaseArrayDescr(AbstractDescr): + _clsname = '' def get_base_size(self, translate_support_code): basesize, _, _ = symbolic.get_array_token(_A, translate_support_code) @@ -124,9 +139,10 @@ return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr, NonGcPtrArrayDescr, 'Array') -def get_array_descr(ARRAY, _cache=weakref.WeakKeyDictionary()): +def get_array_descr(gccache, ARRAY): + cache = gccache._cache_array try: - return _cache[ARRAY] + return cache[ARRAY] except KeyError: arraydescr = getArrayDescrClass(ARRAY)() # verify basic assumption that all arrays' basesize and ofslength @@ -135,7 +151,8 @@ assert basesize == arraydescr.get_base_size(False) assert itemsize == arraydescr.get_item_size(False) assert ofslength == arraydescr.get_ofs_length(False) - _cache[ARRAY] = arraydescr + gccache.init_array_descr(ARRAY, arraydescr) + cache[ARRAY] = arraydescr return arraydescr @@ -144,6 +161,7 @@ class BaseCallDescr(AbstractDescr): call_loop = None + arg_classes = [] # <-- annotation hack def __init__(self, arg_classes): self.arg_classes = arg_classes # list of BoxInt/BoxPtr classes @@ -196,7 +214,7 @@ return self.result_size -def get_call_descr(ARGS, RESULT, translate_support_code, cache): +def get_call_descr(gccache, ARGS, RESULT): arg_classes = [] for ARG in ARGS: kind = getkind(ARG) @@ -207,9 +225,10 @@ if RESULT is lltype.Void: result_size = 0 else: - result_size = symbolic.get_size(RESULT, translate_support_code) + result_size = symbolic.get_size(RESULT, gccache.translate_support_code) ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc' - key = (translate_support_code, tuple(arg_classes), result_size, ptr) + key = (tuple(arg_classes), result_size, ptr) + cache = gccache._cache_call try: return cache[key] except KeyError: Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 23:00:29 2009 @@ -1,4 +1,5 @@ from pypy.rlib import rgc +from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper @@ -6,11 +7,13 @@ from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr +from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr # ____________________________________________________________ -class GcLLDescription: - def __init__(self, gcdescr, cpu): +class GcLLDescription(GcCache): + def __init__(self, gcdescr, translator=None): + GcCache.__init__(self, translator is not None) self.gcdescr = gcdescr def _freeze_(self): return True @@ -24,11 +27,10 @@ class GcLLDescr_boehm(GcLLDescription): moving_gc = False gcrootmap = None - array_length_ofs = 0 - def __init__(self, gcdescr, cpu): + def __init__(self, gcdescr, translator): + GcLLDescription.__init__(self, gcdescr, translator) # grab a pointer to the Boehm 'malloc' function - self.translate_support_code = cpu.translate_support_code compilation_info = ExternalCompilationInfo(libraries=['gc']) malloc_fn_ptr = rffi.llexternal("GC_local_malloc", [lltype.Signed], # size_t, but good enough @@ -90,7 +92,10 @@ get_funcptr_for_newstr = None get_funcptr_for_newunicode = None + # ____________________________________________________________ +# All code below is for the hybrid GC + class GcRefList: """Handles all references from the generated assembler to GC objects. @@ -104,7 +109,9 @@ HASHTABLE_SIZE = 1 << HASHTABLE_BITS def __init__(self): - self.list = self.alloc_gcref_list(2000) + if we_are_translated(): n = 2000 + else: n = 10 # tests only + self.list = self.alloc_gcref_list(n) self.nextindex = 0 self.oldlists = [] # A pseudo dictionary: it is fixed size, and it may contain @@ -122,8 +129,11 @@ def alloc_gcref_list(self, n): # Important: the GRREF_LISTs allocated are *non-movable*. This # requires support in the gc (only the hybrid GC supports it so far). - list = rgc.malloc_nonmovable(self.GCREF_LIST, n) - assert list, "malloc_nonmovable failed!" + if we_are_translated(): + list = rgc.malloc_nonmovable(self.GCREF_LIST, n) + assert list, "malloc_nonmovable failed!" + else: + list = lltype.malloc(self.GCREF_LIST, n) # for tests only return list def get_address_of_gcref(self, gcref): @@ -136,7 +146,9 @@ hash &= self.HASHTABLE_SIZE - 1 addr_ref = self.hashtable[hash] # the following test is safe anyway, because the addresses found - # in the hashtable are always the addresses of nonmovable stuff: + # in the hashtable are always the addresses of nonmovable stuff + # ('addr_ref' is an address inside self.list, not directly the + # address of a real moving GC object -- that's 'addr_ref.address[0]'.) if addr_ref.address[0] == addr: return addr_ref # if it fails, add an entry to the list @@ -198,7 +210,7 @@ self._gcmap_curlength = index + 2 def _enlarge_gcmap(self): - newlength = 128 + self._gcmap_maxlength * 5 // 4 + newlength = 250 + self._gcmap_maxlength * 2 newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw') oldgcmap = self._gcmap for i in range(self._gcmap_curlength): @@ -210,7 +222,7 @@ def encode_callshape(self, gclocs): """Encode a callshape from the list of locations containing GC - pointers.""" + pointers. 'gclocs' is a list of offsets relative to EBP.""" shape = self._get_callshape(gclocs) return self._compress_callshape(shape) @@ -222,9 +234,7 @@ self.LOC_EBP_BASED | 0, # saved %ebp: at (%ebp) 0] for loc in gclocs: - assert isinstance(loc, MODRM) - assert loc.is_relative_to_ebp() - shape.append(self.LOC_EBP_BASED | (-4 * (4 + loc.position))) + shape.append(self.LOC_EBP_BASED | loc) return shape def _compress_callshape(self, shape): @@ -254,11 +264,13 @@ class GcLLDescr_framework(GcLLDescription): GcRefList = GcRefList - def __init__(self, gcdescr, cpu): + def __init__(self, gcdescr, translator, llop1=llop): from pypy.rpython.memory.gc.base import choose_gc_from_config from pypy.rpython.memory.gctransform import framework - self.cpu = cpu - self.translator = cpu.mixlevelann.rtyper.annotator.translator + GcLLDescription.__init__(self, gcdescr, translator) + assert self.translate_support_code, "required with the framework GC" + self.translator = translator + self.llop1 = llop1 # we need the hybrid GC for GcRefList.alloc_gcref_list() to work if gcdescr.config.translation.gc != 'hybrid': @@ -287,15 +299,15 @@ self.GCClass, _ = choose_gc_from_config(gcdescr.config) self.moving_gc = self.GCClass.moving_gc self.HDRPTR = lltype.Ptr(self.GCClass.HDR) - self.fielddescr_tid = cpu.fielddescrof(self.GCClass.HDR, 'tid') - _, _, self.array_length_ofs = symbolic.get_array_token( - lltype.GcArray(lltype.Signed), True) + self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid') + (self.array_basesize, _, self.array_length_ofs) = \ + symbolic.get_array_token(lltype.GcArray(lltype.Signed), True) # make a malloc function, with three arguments def malloc_basic(size, type_id, has_finalizer): - res = llop.do_malloc_fixedsize_clear(llmemory.GCREF, - type_id, size, True, - has_finalizer, False) + res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, + type_id, size, True, + has_finalizer, False) #llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id, # "-->", res) return res @@ -305,10 +317,10 @@ self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType( [llmemory.Address, llmemory.Address], lltype.Void)) # - def malloc_array(basesize, itemsize, type_id, num_elem): - return llop.do_malloc_varsize_clear( + def malloc_array(itemsize, type_id, num_elem): + return llop1.do_malloc_varsize_clear( llmemory.GCREF, - type_id, num_elem, basesize, itemsize, + type_id, num_elem, self.array_basesize, itemsize, self.array_length_ofs, True, False) self.malloc_array = malloc_array self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType( @@ -322,12 +334,12 @@ unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE) # def malloc_str(length): - return llop.do_malloc_varsize_clear( + return llop1.do_malloc_varsize_clear( llmemory.GCREF, str_type_id, length, str_basesize, str_itemsize, str_ofs_length, True, False) def malloc_unicode(length): - return llop.do_malloc_varsize_clear( + return llop1.do_malloc_varsize_clear( llmemory.GCREF, unicode_type_id, length, unicode_basesize, unicode_itemsize, unicode_ofs_length, True, False) @@ -336,57 +348,41 @@ self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType( [lltype.Signed], llmemory.GCREF)) - def sizeof(self, S, translate_support_code): + def init_size_descr(self, S, descr): from pypy.rpython.memory.gctypelayout import weakpointer_offset - assert translate_support_code, "required with the framework GC" - size = symbolic.get_size(S, True) type_id = self.layoutbuilder.get_type_id(S) has_finalizer = bool(self.layoutbuilder.has_finalizer(S)) assert weakpointer_offset(S) == -1 # XXX - descr = ConstDescr3(size, 0, has_finalizer) descr.type_id = type_id - return descr + descr.has_finalizer = has_finalizer - def arraydescrof(self, A, translate_support_code): - assert translate_support_code, "required with the framework GC" - basesize, itemsize, ofs_length = symbolic.get_array_token(A, True) - assert rffi.sizeof(A.OF) in [1, 2, WORD] - # assert ofs_length == self.array_length_ofs --- but it's symbolics... - if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc': - ptr = True - else: - ptr = False + def init_array_descr(self, A, descr): type_id = self.layoutbuilder.get_type_id(A) - descr = ConstDescr3(basesize, itemsize, ptr) descr.type_id = type_id - return descr - def gc_malloc(self, descrsize): - assert isinstance(descrsize, ConstDescr3) - size = descrsize.v0 - type_id = descrsize.type_id - has_finalizer = descrsize.flag2 + def gc_malloc(self, sizedescr): + assert isinstance(sizedescr, BaseSizeDescr) + size = sizedescr.size + type_id = sizedescr.type_id + has_finalizer = sizedescr.has_finalizer assert type_id > 0 return self.malloc_basic(size, type_id, has_finalizer) def gc_malloc_array(self, arraydescr, num_elem): - assert isinstance(arraydescr, ConstDescr3) - basesize = arraydescr.v0 - itemsize = arraydescr.v1 + assert isinstance(arraydescr, BaseArrayDescr) + itemsize = arraydescr.get_item_size(self.translate_support_code) type_id = arraydescr.type_id assert type_id > 0 - return self.malloc_array(basesize, itemsize, type_id, num_elem) + return self.malloc_array(itemsize, type_id, num_elem) - def gc_malloc_str(self, num_elem, translate_support_code): - assert translate_support_code, "required with the framework GC" + def gc_malloc_str(self, num_elem): return self.malloc_str(num_elem) - def gc_malloc_unicode(self, num_elem, translate_support_code): - assert translate_support_code, "required with the framework GC" + def gc_malloc_unicode(self, num_elem): return self.malloc_unicode(num_elem) - def args_for_new(self, descrsize): - assert isinstance(descrsize, ConstDescr3) + def args_for_new(self, sizedescr): + assert isinstance(sizedescr, BaseSizeDescr) size = descrsize.v0 type_id = descrsize.type_id has_finalizer = descrsize.flag2 @@ -417,7 +413,8 @@ if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: # get a pointer to the 'remember_young_pointer' function from # the GC, and call it immediately - funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR) + llop1 = self.llop1 + funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) funcptr(llmemory.cast_ptr_to_adr(gcref_struct), llmemory.cast_ptr_to_adr(gcref_newptr)) @@ -449,7 +446,7 @@ mc.PUSHA() # 1 byte mc.PUSH(value_reg) # 1 or 5 bytes mc.PUSH(base_reg) # 1 or 5 bytes - funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR) + funcptr = self.llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) funcaddr = rffi.cast(lltype.Signed, funcptr) mc.CALL(rel32(funcaddr)) # 5 bytes mc.POP(eax) # 1 byte @@ -460,7 +457,8 @@ # ____________________________________________________________ -def get_ll_description(gcdescr, cpu): +def get_ll_description(gcdescr, translator=None): + # translator is None if translate_support_code is False. if gcdescr is not None: name = gcdescr.config.translation.gctransformer else: @@ -469,5 +467,5 @@ cls = globals()['GcLLDescr_' + name] except KeyError: raise NotImplementedError("GC transformer %r not supported by " - "the x86 backend" % (name,)) - return cls(gcdescr, cpu) + "the JIT backend" % (name,)) + return cls(gcdescr, translator) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 23:00:29 2009 @@ -28,8 +28,11 @@ self.rtyper = rtyper self.stats = stats self.translate_support_code = translate_support_code - self._call_cache = {} - self.gc_ll_descr = get_ll_description(gcdescr, self) + if translate_support_code: + translator = rtyper.annotator.translator + else: + translator = None + self.gc_ll_descr = get_ll_description(gcdescr, translator) self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, 'typeptr', translate_support_code) @@ -58,11 +61,6 @@ # ------------------- helpers and descriptions -------------------- @staticmethod - def cast_adr_to_int(x): - res = rffi.cast(lltype.Signed, x) - return res - - @staticmethod def cast_int_to_gcref(x): if not we_are_translated(): _check_addr_range(x) @@ -78,11 +76,15 @@ _check_addr_range(x) return rffi.cast(llmemory.Address, x) + @staticmethod + def cast_adr_to_int(x): + return rffi.cast(lltype.Signed, x) + def sizeof(self, S): - return get_size_descr(S, self.translate_support_code) + return get_size_descr(self.gc_ll_descr, S) def fielddescrof(self, STRUCT, fieldname): - return get_field_descr(STRUCT, fieldname, self.translate_support_code) + return get_field_descr(self.gc_ll_descr, STRUCT, fieldname) def unpack_fielddescr(self, fielddescr): assert isinstance(fielddescr, BaseFieldDescr) @@ -93,7 +95,7 @@ unpack_fielddescr._always_inline_ = True def arraydescrof(self, A): - return get_array_descr(A) + return get_array_descr(self.gc_ll_descr, A) def unpack_arraydescr(self, arraydescr): assert isinstance(arraydescr, BaseArrayDescr) @@ -104,8 +106,7 @@ unpack_arraydescr._always_inline_ = True def calldescrof(self, FUNC, ARGS, RESULT): - return get_call_descr(ARGS, RESULT, self.translate_support_code, - self._call_cache) + return get_call_descr(self.gc_ll_descr, ARGS, RESULT) def get_overflow_error(self): ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 23:00:29 2009 @@ -5,17 +5,19 @@ def test_get_size_descr(): + c0 = GcCache(False) + c1 = GcCache(True) T = lltype.GcStruct('T') S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Ptr(T))) - descr_s = get_size_descr(S, False) - descr_t = get_size_descr(T, False) + descr_s = get_size_descr(c0, S) + descr_t = get_size_descr(c0, T) assert descr_s.size == symbolic.get_size(S, False) assert descr_t.size == symbolic.get_size(T, False) - assert descr_s == get_size_descr(S, False) - assert descr_s != get_size_descr(S, True) + assert descr_s == get_size_descr(c0, S) + assert descr_s != get_size_descr(c1, S) # - descr_s = get_size_descr(S, True) + descr_s = get_size_descr(c1, S) assert isinstance(descr_s.size, Symbolic) @@ -31,12 +33,15 @@ assert cls != getFieldDescrClass(lltype.Signed) assert cls == getFieldDescrClass(lltype.Char) # - assert get_field_descr(S, 'y', False) == get_field_descr(S, 'y', False) - assert get_field_descr(S, 'y', False) != get_field_descr(S, 'y', True) + c0 = GcCache(False) + c1 = GcCache(True) + assert get_field_descr(c0, S, 'y') == get_field_descr(c0, S, 'y') + assert get_field_descr(c0, S, 'y') != get_field_descr(c1, S, 'y') for tsc in [False, True]: - descr_x = get_field_descr(S, 'x', tsc) - descr_y = get_field_descr(S, 'y', tsc) - descr_z = get_field_descr(S, 'z', tsc) + c2 = GcCache(tsc) + descr_x = get_field_descr(c2, S, 'x') + descr_y = get_field_descr(c2, S, 'y') + descr_z = get_field_descr(c2, S, 'z') assert descr_x.__class__ is cls assert descr_y.__class__ is GcPtrFieldDescr assert descr_z.__class__ is NonGcPtrFieldDescr @@ -70,13 +75,14 @@ assert cls != getArrayDescrClass(lltype.GcArray(lltype.Signed)) assert cls == getArrayDescrClass(lltype.GcArray(lltype.Char)) # - descr1 = get_array_descr(A1) - descr2 = get_array_descr(A2) - descr3 = get_array_descr(A3) + c0 = GcCache(False) + descr1 = get_array_descr(c0, A1) + descr2 = get_array_descr(c0, A2) + descr3 = get_array_descr(c0, A3) assert descr1.__class__ is cls assert descr2.__class__ is GcPtrArrayDescr assert descr3.__class__ is NonGcPtrArrayDescr - assert descr1 == get_array_descr(lltype.GcArray(lltype.Char)) + assert descr1 == get_array_descr(c0, lltype.GcArray(lltype.Char)) assert not descr1.is_array_of_pointers() assert descr2.is_array_of_pointers() assert not descr3.is_array_of_pointers() @@ -104,52 +110,49 @@ def test_get_call_descr(): - cache = {} - descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False, - cache) + c0 = GcCache(False) + descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char) assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char) assert not descr1.returns_a_pointer() assert descr1.arg_classes == [BoxInt, BoxInt] # T = lltype.GcStruct('T') - descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False, cache) + descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T)) assert descr2.returns_a_pointer() assert descr2.arg_classes == [BoxPtr] # U = lltype.GcStruct('U', ('x', lltype.Signed)) - assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False, - cache) + assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) def test_repr_of_descr(): + c0 = GcCache(False) T = lltype.GcStruct('T') S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Ptr(T)), ('z', lltype.Ptr(T))) - descr1 = get_size_descr(S, False) + descr1 = get_size_descr(c0, S) s = symbolic.get_size(S, False) assert descr1.repr_of_descr() == '' % s # - descr2 = get_field_descr(S, 'y', False) + descr2 = get_field_descr(c0, S, 'y') o, _ = symbolic.get_field_token(S, 'y', False) assert descr2.repr_of_descr() == '' % o # - descr2i = get_field_descr(S, 'x', False) + descr2i = get_field_descr(c0, S, 'x') o, _ = symbolic.get_field_token(S, 'x', False) assert descr2i.repr_of_descr() == '' % o # - descr3 = get_array_descr(lltype.GcArray(lltype.Ptr(S))) + descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S))) assert descr3.repr_of_descr() == '' # - descr3i = get_array_descr(lltype.GcArray(lltype.Char)) + descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char)) assert descr3i.repr_of_descr() == '' # cache = {} - descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S), - False, cache) + descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S)) assert 'GcPtrCallDescr' in descr4.repr_of_descr() # - descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char, - False, cache) + descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char) assert 'IntCallDescr' in descr4i.repr_of_descr() Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Sat Aug 29 23:00:29 2009 @@ -0,0 +1,170 @@ +import random +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr +from pypy.jit.backend.llsupport.descr import * +from pypy.jit.backend.llsupport.gc import * +from pypy.jit.backend.llsupport import symbolic +from pypy.jit.metainterp.gc import get_description + + +def test_boehm(): + gc_ll_descr = GcLLDescr_boehm(None, None) + # + record = [] + prev_funcptr_for_new = gc_ll_descr.funcptr_for_new + def my_funcptr_for_new(size): + p = prev_funcptr_for_new(size) + record.append((size, p)) + return p + gc_ll_descr.funcptr_for_new = my_funcptr_for_new + # + # ---------- gc_malloc ---------- + S = lltype.GcStruct('S', ('x', lltype.Signed)) + sizedescr = get_size_descr(gc_ll_descr, S) + p = gc_ll_descr.gc_malloc(sizedescr) + assert record == [(sizedescr.size, p)] + del record[:] + # ---------- gc_malloc_array ---------- + A = lltype.GcArray(lltype.Signed) + arraydescr = get_array_descr(gc_ll_descr, A) + p = gc_ll_descr.gc_malloc_array(arraydescr, 10) + assert record == [(arraydescr.get_base_size(False) + + 10 * arraydescr.get_item_size(False), p)] + del record[:] + # ---------- gc_malloc_str ---------- + p = gc_ll_descr.gc_malloc_str(10) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, False) + assert record == [(basesize + 10 * itemsize, p)] + del record[:] + # ---------- gc_malloc_unicode ---------- + p = gc_ll_descr.gc_malloc_unicode(10) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, + False) + assert record == [(basesize + 10 * itemsize, p)] + del record[:] + +# ____________________________________________________________ + +def test_GcRefList(): + S = lltype.GcStruct('S') + order = range(50) * 4 + random.shuffle(order) + allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) + for i in range(50)] + allocs = [allocs[i] for i in order] + # + gcrefs = GcRefList() + addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs] + for i in range(len(allocs)): + assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i]) + +def test_GcRootMap_asmgcc(): + def stack_pos(n): + return -4*(4+n) + gcrootmap = GcRootMap_asmgcc() + num1 = stack_pos(1) + num2 = stack_pos(55) + shape = gcrootmap._get_callshape([num1, num2]) + assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2] + # + shapeaddr = gcrootmap.encode_callshape([num1, num2]) + PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) + p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) + num1a = -2*(num1|2)-1 + num2a = ((-2*(num2|2)-1) >> 7) | 128 + num2b = (-2*(num2|2)-1) & 127 + for i, expected in enumerate([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]): + assert p[i] == expected + # + retaddr = rffi.cast(llmemory.Address, 1234567890) + gcrootmap.put(retaddr, shapeaddr) + assert gcrootmap._gcmap[0] == retaddr + assert gcrootmap._gcmap[1] == shapeaddr + assert gcrootmap.gcmapstart().address[0] == retaddr + # + # the same as before, but enough times to trigger a few resizes + expected_shapeaddr = {} + for i in range(1, 600): + shapeaddr = gcrootmap.encode_callshape([stack_pos(i)]) + expected_shapeaddr[i] = shapeaddr + retaddr = rffi.cast(llmemory.Address, 123456789 + i) + gcrootmap.put(retaddr, shapeaddr) + for i in range(1, 600): + expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i) + assert gcrootmap._gcmap[i*2+0] == expected_retaddr + assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i] + + +class FakeLLOp: + def __init__(self): + self.record = [] + + def do_malloc_fixedsize_clear(self, RESTYPE, type_id, size, can_collect, + has_finalizer, contains_weakptr): + assert can_collect + assert not contains_weakptr + p = llmemory.raw_malloc(size) + p = llmemory.cast_adr_to_ptr(p, RESTYPE) + self.record.append(("fixedsize", type_id, repr(size), + has_finalizer, p)) + return p + + def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size, + itemsize, offset_to_length, can_collect, + has_finalizer): + assert can_collect + assert not has_finalizer + p = llmemory.raw_malloc(size + itemsize * length) + (p + offset_to_length).signed[0] = length + p = llmemory.cast_adr_to_ptr(p, RESTYPE) + self.record.append(("varsize", type_id, length, + repr(size), repr(itemsize), + repr(offset_to_length), p)) + return p + + +def test_framework_malloc(): + class FakeTranslator: + pass + class config: + class translation: + gc = 'hybrid' + gcrootfinder = 'asmgcc' + gctransformer = 'framework' + gcdescr = get_description(config) + translator = FakeTranslator() + llop1 = FakeLLOp() + gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + # + # ---------- gc_malloc ---------- + S = lltype.GcStruct('S', ('x', lltype.Signed)) + sizedescr = get_size_descr(gc_ll_descr, S) + p = gc_ll_descr.gc_malloc(sizedescr) + assert llop1.record == [("fixedsize", sizedescr.type_id, + repr(sizedescr.size), False, p)] + del llop1.record[:] + # ---------- gc_malloc_array ---------- + A = lltype.GcArray(lltype.Signed) + arraydescr = get_array_descr(gc_ll_descr, A) + p = gc_ll_descr.gc_malloc_array(arraydescr, 10) + assert llop1.record == [("varsize", arraydescr.type_id, 10, + repr(arraydescr.get_base_size(True)), + repr(arraydescr.get_item_size(True)), + repr(arraydescr.get_ofs_length(True)), p)] + del llop1.record[:] + # ---------- gc_malloc_str ---------- + p = gc_ll_descr.gc_malloc_str(10) + type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.STR) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, True) + assert llop1.record == [("varsize", type_id, 10, + repr(basesize), repr(itemsize), repr(ofs_length), + p)] + del llop1.record[:] + # ---------- gc_malloc_unicode ---------- + p = gc_ll_descr.gc_malloc_unicode(10) + type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, + True) + assert llop1.record == [("varsize", type_id, 10, + repr(basesize), repr(itemsize), repr(ofs_length), + p)] + del llop1.record[:] Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Sat Aug 29 23:00:29 2009 @@ -92,11 +92,11 @@ def typedescrof(TYPE): raise NotImplementedError - def cast_adr_to_int(self, adr): - raise NotImplementedError + #def cast_adr_to_int(self, adr): + # raise NotImplementedError - def cast_int_to_adr(self, int): - raise NotImplementedError + #def cast_int_to_adr(self, int): + # raise NotImplementedError # ---------- the backend-dependent operations ---------- Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py Sat Aug 29 23:00:29 2009 @@ -18,13 +18,10 @@ BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) def __init__(self, rtyper, stats, translate_support_code=False, - mixlevelann=None, gcdescr=None): + gcdescr=None): AbstractLLCPU.__init__(self, rtyper, stats, translate_support_code, gcdescr) - if translate_support_code: - assert mixlevelann - self.mixlevelann = mixlevelann - else: + if not translate_support_code: self.current_interpreter = LLInterpreter(self.rtyper) def _store_exception(lle): Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py Sat Aug 29 23:00:29 2009 @@ -11,7 +11,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.jit import JitDriver from pypy.jit.backend.x86.runner import CPU386 -from pypy.jit.backend.x86.gc import GcRefList, GcRootMap_asmgcc +from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc from pypy.jit.backend.x86.regalloc import stack_pos @@ -82,22 +82,6 @@ res = compile_and_run(get_test(main), "boehm", jit=True) assert int(res) >= 16 -def test_GcRefList(): - S = lltype.GcStruct('S') - order = range(20000) * 4 - random.shuffle(order) - def fn(args): - allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) - for i in range(20000)] - allocs = [allocs[i] for i in order] - # - gcrefs = GcRefList() - addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs] - for i in range(len(allocs)): - assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i]) - return 0 - compile_and_run(fn, "hybrid", gcrootfinder="asmgcc", jit=False) - def test_compile_hybrid_1(): # a moving GC. Supports malloc_varsize_nonmovable. Simple test, works # without write_barriers and root stack enumeration. @@ -113,39 +97,8 @@ jit=True) assert int(res) == 20 -def test_GcRootMap_asmgcc(): - gcrootmap = GcRootMap_asmgcc() - shape = gcrootmap._get_callshape([stack_pos(1), stack_pos(55)]) - num1 = stack_pos(1).ofs_relative_to_ebp() - num2 = stack_pos(55).ofs_relative_to_ebp() - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2] - # - shapeaddr = gcrootmap.encode_callshape([stack_pos(1), stack_pos(55)]) - PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) - p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) - num1a = -2*(num1|2)-1 - num2a = ((-2*(num2|2)-1) >> 7) | 128 - num2b = (-2*(num2|2)-1) & 127 - for i, expected in enumerate([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]): - assert p[i] == expected - # - retaddr = rffi.cast(llmemory.Address, 1234567890) - gcrootmap.put(retaddr, shapeaddr) - assert gcrootmap._gcmap[0] == retaddr - assert gcrootmap._gcmap[1] == shapeaddr - assert gcrootmap.gcmapstart().address[0] == retaddr - # - # the same as before, but enough times to trigger a few resizes - expected_shapeaddr = {} - for i in range(1, 600): - shapeaddr = gcrootmap.encode_callshape([stack_pos(i)]) - expected_shapeaddr[i] = shapeaddr - retaddr = rffi.cast(llmemory.Address, 123456789 + i) - gcrootmap.put(retaddr, shapeaddr) - for i in range(1, 600): - expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i) - assert gcrootmap._gcmap[i*2+0] == expected_retaddr - assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i] +def test_get_callshape(): + xxx #test that _get_callshape() is called with the right arguments def test_compile_hybrid_2(): # More complex test, requires root stack enumeration but Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py Sat Aug 29 23:00:29 2009 @@ -222,7 +222,7 @@ else: annhelper = None cpu = CPUClass(self.translator.rtyper, self.stats, - translate_support_code, annhelper, self.gcdescr) + translate_support_code, gcdescr=self.gcdescr) self.cpu = cpu self.metainterp_sd = MetaInterpStaticData(self.portal_graph, self.translator.graphs, cpu, Modified: pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py Sat Aug 29 23:00:29 2009 @@ -607,7 +607,7 @@ resultvar=op.result) def gct_do_malloc_fixedsize_clear(self, hop): - # used by the JIT (see the x86 backend) + # used by the JIT (see pypy.jit.backend.llsupport.gc) op = hop.spaceop [v_typeid, v_size, v_can_collect, v_has_finalizer, v_contains_weakptr] = op.args @@ -620,7 +620,7 @@ self.pop_roots(hop, livevars) def gct_do_malloc_varsize_clear(self, hop): - # used by the JIT (see the x86 backend) + # used by the JIT (see pypy.jit.backend.llsupport.gc) op = hop.spaceop [v_typeid, v_length, v_size, v_itemsize, v_offset_to_length, v_can_collect, v_has_finalizer] = op.args From arigo at codespeak.net Sat Aug 29 23:21:09 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 29 Aug 2009 23:21:09 +0200 (CEST) Subject: [pypy-svn] r67332 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport: . test Message-ID: <20090829212109.043FB16801E@codespeak.net> Author: arigo Date: Sat Aug 29 23:21:08 2009 New Revision: 67332 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Log: Test for do_write_barrier. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 23:21:08 2009 @@ -266,6 +266,7 @@ def __init__(self, gcdescr, translator, llop1=llop): from pypy.rpython.memory.gc.base import choose_gc_from_config + from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.gctransform import framework GcLLDescription.__init__(self, gcdescr, translator) assert self.translate_support_code, "required with the framework GC" @@ -299,6 +300,7 @@ self.GCClass, _ = choose_gc_from_config(gcdescr.config) self.moving_gc = self.GCClass.moving_gc self.HDRPTR = lltype.Ptr(self.GCClass.HDR) + self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO) self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid') (self.array_basesize, _, self.array_length_ofs) = \ symbolic.get_array_token(lltype.GcArray(lltype.Signed), True) @@ -383,17 +385,16 @@ def args_for_new(self, sizedescr): assert isinstance(sizedescr, BaseSizeDescr) - size = descrsize.v0 - type_id = descrsize.type_id - has_finalizer = descrsize.flag2 + size = sizedescr.size + type_id = sizedescr.type_id + has_finalizer = sizedescr.has_finalizer return [size, type_id, has_finalizer] def args_for_new_array(self, arraydescr): - assert isinstance(arraydescr, ConstDescr3) - basesize = arraydescr.v0 - itemsize = arraydescr.v1 + assert isinstance(arraydescr, BaseArrayDescr) + itemsize = arraydescr.get_item_size(self.translate_support_code) type_id = arraydescr.type_id - return [basesize, itemsize, type_id] + return [itemsize, type_id] def get_funcptr_for_new(self): return llhelper(self.GC_MALLOC_BASIC, self.malloc_basic) @@ -409,6 +410,7 @@ def do_write_barrier(self, gcref_struct, gcref_newptr): hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct) + hdr_addr -= self.gcheaderbuilder.size_gc_header hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: # get a pointer to the 'remember_young_pointer' function from Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Sat Aug 29 23:21:08 2009 @@ -121,50 +121,84 @@ repr(offset_to_length), p)) return p + def _write_barrier_failing_case(self, adr_struct, adr_newptr): + self.record.append(('barrier', adr_struct, adr_newptr)) -def test_framework_malloc(): - class FakeTranslator: - pass - class config: - class translation: - gc = 'hybrid' - gcrootfinder = 'asmgcc' - gctransformer = 'framework' - gcdescr = get_description(config) - translator = FakeTranslator() - llop1 = FakeLLOp() - gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) - # - # ---------- gc_malloc ---------- - S = lltype.GcStruct('S', ('x', lltype.Signed)) - sizedescr = get_size_descr(gc_ll_descr, S) - p = gc_ll_descr.gc_malloc(sizedescr) - assert llop1.record == [("fixedsize", sizedescr.type_id, - repr(sizedescr.size), False, p)] - del llop1.record[:] - # ---------- gc_malloc_array ---------- - A = lltype.GcArray(lltype.Signed) - arraydescr = get_array_descr(gc_ll_descr, A) - p = gc_ll_descr.gc_malloc_array(arraydescr, 10) - assert llop1.record == [("varsize", arraydescr.type_id, 10, - repr(arraydescr.get_base_size(True)), - repr(arraydescr.get_item_size(True)), - repr(arraydescr.get_ofs_length(True)), p)] - del llop1.record[:] - # ---------- gc_malloc_str ---------- - p = gc_ll_descr.gc_malloc_str(10) - type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.STR) - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, True) - assert llop1.record == [("varsize", type_id, 10, - repr(basesize), repr(itemsize), repr(ofs_length), - p)] - del llop1.record[:] - # ---------- gc_malloc_unicode ---------- - p = gc_ll_descr.gc_malloc_unicode(10) - type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE) - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, - True) - assert llop1.record == [("varsize", type_id, 10, - repr(basesize), repr(itemsize), repr(ofs_length), - p)] - del llop1.record[:] + def get_write_barrier_failing_case(self, FUNCTYPE): + return self._write_barrier_failing_case + + +class TestFramework: + + def setup_method(self, meth): + class FakeTranslator: + pass + class config: + class translation: + gc = 'hybrid' + gcrootfinder = 'asmgcc' + gctransformer = 'framework' + gcdescr = get_description(config) + translator = FakeTranslator() + self.llop1 = FakeLLOp() + self.gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), + self.llop1) + + def test_gc_malloc(self): + S = lltype.GcStruct('S', ('x', lltype.Signed)) + sizedescr = get_size_descr(self.gc_ll_descr, S) + p = self.gc_ll_descr.gc_malloc(sizedescr) + assert self.llop1.record == [("fixedsize", sizedescr.type_id, + repr(sizedescr.size), False, p)] + assert repr(self.gc_ll_descr.args_for_new(sizedescr)) == repr( + [sizedescr.size, sizedescr.type_id, False]) + + def test_gc_malloc_array(self): + A = lltype.GcArray(lltype.Signed) + arraydescr = get_array_descr(self.gc_ll_descr, A) + p = self.gc_ll_descr.gc_malloc_array(arraydescr, 10) + assert self.llop1.record == [("varsize", arraydescr.type_id, 10, + repr(arraydescr.get_base_size(True)), + repr(arraydescr.get_item_size(True)), + repr(arraydescr.get_ofs_length(True)), + p)] + assert repr(self.gc_ll_descr.args_for_new_array(arraydescr)) == repr( + [arraydescr.get_item_size(True), arraydescr.type_id]) + + def test_gc_malloc_str(self): + p = self.gc_ll_descr.gc_malloc_str(10) + type_id = self.gc_ll_descr.layoutbuilder.get_type_id(rstr.STR) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, + True) + assert self.llop1.record == [("varsize", type_id, 10, + repr(basesize), repr(itemsize), + repr(ofs_length), p)] + + def test_gc_malloc_unicode(self): + p = self.gc_ll_descr.gc_malloc_unicode(10) + type_id = self.gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE) + basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, + True) + assert self.llop1.record == [("varsize", type_id, 10, + repr(basesize), repr(itemsize), + repr(ofs_length), p)] + + def test_do_write_barrier(self): + gc_ll_descr = self.gc_ll_descr + R = lltype.GcStruct('R') + S = lltype.GcStruct('S', ('r', lltype.Ptr(R))) + s = lltype.malloc(S) + r = lltype.malloc(R) + s_hdr = gc_ll_descr.gcheaderbuilder.new_header(s) + s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) + r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r) + s_adr = llmemory.cast_ptr_to_adr(s) + r_adr = llmemory.cast_ptr_to_adr(r) + # + s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG + gc_ll_descr.do_write_barrier(s_gcref, r_gcref) + assert self.llop1.record == [] # not called + # + s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG + gc_ll_descr.do_write_barrier(s_gcref, r_gcref) + assert self.llop1.record == [('barrier', s_adr, r_adr)] From benjamin at codespeak.net Sun Aug 30 01:26:43 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 30 Aug 2009 01:26:43 +0200 (CEST) Subject: [pypy-svn] r67333 - pypy/trunk/pypy/doc Message-ID: <20090829232643.EF0ED16801B@codespeak.net> Author: benjamin Date: Sun Aug 30 01:26:41 2009 New Revision: 67333 Modified: pypy/trunk/pypy/doc/_ref.txt pypy/trunk/pypy/doc/parser.txt Log: write some docs about the new parser/compiler Modified: pypy/trunk/pypy/doc/_ref.txt ============================================================================== --- pypy/trunk/pypy/doc/_ref.txt (original) +++ pypy/trunk/pypy/doc/_ref.txt Sun Aug 30 01:26:41 2009 @@ -30,6 +30,20 @@ .. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py .. _`interpreter/pyparser/`: .. _`pypy/interpreter/pyparser`: ../../pypy/interpreter/pyparser +.. _`pypy/interpreter/pyparser/pytokenizer.py`: ../../pypy/interpreter/pyparser/pytokenizer.py +.. _`pypy/interpreter/pyparser/parser.py`: ../../pypy/interpreter/pyparser/parser.py +.. _`pypy/interpreter/pyparser/pyparse.py`: ../../pypy/interpreter/pyparser/pyparse.py +.. _`pypy/interpreter/pyparser/future.py`: ../../pypy/interpreter/pyparser/future.py +.. _`pypy/interpreter/pyparser/metaparser.py`: ../../pypy/interpreter/pyparser/metaparser.py +.. _`pypy/interpreter/astcompiler/astbuilder.py`: ../../pypy/interpreter/astcompiler/astbuilder.py +.. _`pypy/interpreter/astcompiler/optimize.py`: ../../pypy/interpreter/astcompiler/optimize.py +.. _`pypy/interpreter/astcompiler/codegen.py`: ../../pypy/interpreter/astcompiler/codegen.py +.. _`pypy/interpreter/astcompiler/tools/asdl_py.py`: ../../pypy/interpreter/astcompiler/tools/asdl_py.py +.. _`pypy/interpreter/astcompiler/tools/Python.asdl`: ../../pypy/interpreter/astcompiler/tools/Python.asdl +.. _`pypy/interpreter/astcompiler/assemble.py`: ../../pypy/interpreter/astcompiler/assemble.py +.. _`pypy/interpreter/astcompiler/symtable.py`: ../../pypy/interpreter/astcompiler/symtable.py +.. _`pypy/interpreter/astcompiler/asthelpers.py`: ../../pypy/interpreter/astcompiler/asthelpers.py +.. _`pypy/interpreter/astcompiler/ast.py`: ../../pypy/interpreter/astcompiler/ast.py .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py .. _`lang/`: ../../pypy/lang .. _`lang/js/`: ../../pypy/lang/js Modified: pypy/trunk/pypy/doc/parser.txt ============================================================================== --- pypy/trunk/pypy/doc/parser.txt (original) +++ pypy/trunk/pypy/doc/parser.txt Sun Aug 30 01:26:41 2009 @@ -1,11 +1,7 @@ -================== -PyPy Parser -================== - -WARNING: this document is out-of-date and unfinished. Our compiler -is done by now, unlike explained below. - +=========== +PyPy Parser +=========== Overview ======== @@ -15,196 +11,93 @@ Tokenizer --------- -The tokenizer accepts as string as input and provides tokens through -a ``next()`` and a ``peek()`` method. The tokenizer is implemented as a finite -automata like lex. +At the moment, the tokenizer is implemented as a single function +(``generate_tokens`` in `pypy/interpreter/pyparser/pytokenizer.py`_) that builds +a list of tokens. The tokens are then fed to the parser. Parser ------ -The parser is a tree of grammar rules. EBNF grammar rules are decomposed -as a tree of objects. -Looking at a grammar rule one can see it is composed of a set of four basic -subrules. In the following exemple we have all four of them: - -S <- A '+' (C | D) + - - -The previous line says S is a sequence of symbol A, token '+', a subrule + which -matches one or more of an alternative between symbol C and symbol D. -Thus the four basic grammar rule types are : -* sequence -* alternative -* multiplicity (called kleen star after the * multiplicity type) -* token - -The four types are represented by a class in pyparser/grammar.py -( Sequence, Alternative, KleeneStar, Token) all classes have a ``match()`` method -accepting a source (the tokenizer) and a builder (an object responsible for -building something out of the grammar). - -Here's a basic exemple and how the grammar is represented:: - - S <- A ('+'|'-') A - A <- V ( ('*'|'/') V )* - V <- 'x' | 'y' - - In python: - V = Alternative( Token('x'), Token('y') ) - A = Sequence( V, - KleeneStar( - Sequence( - Alternative( Token('*'), Token('/') ), V - ) - ) - ) - S = Sequence( A, Alternative( Token('+'), Token('-') ), A ) - - -Status -====== - -See README.compiling on the status of the parser(s) implementation of PyPy - - -Detailed design -=============== +The parser is a simple LL(1) parser that is similar to CPython's. Building the Python grammar ---------------------------- - -The python grammar is built at startup from the pristine CPython grammar file. -The grammar framework is first used to build a simple grammar to parse the -grammar itself. -The builder provided to the parser generates another grammar which is the Python -grammar itself. -The grammar file should represent an LL(1) grammar. LL(k) should still work since -the parser supports backtracking through the use of source and builder contexts -(The memento patterns for those who like Design Patterns) - -The match function for a sequence is pretty simple:: - - for each rule in the sequence: - save the source and builder context - if the rule doesn't match: - restore the source and builder context - return false - call the builder method to build the sequence - return true - -Now this really is an LL(0) grammar since it explores the whole tree of rule -possibilities. -In fact there is another member of the rule objects which is built once the -grammar is complete. -This member is a set of the tokens that match the begining of each rule. Like -the grammar it is precomputed at startup. -Then each rule starts by the following test:: - - if source.peek() not in self.firstset: return false - - -Efficiency should be similar (not too worse) to an automata based grammar since it is -basicly building an automata but it uses the execution stack to store its parsing state. -This also means that recursion in the grammar are directly translated as recursive calls. - - -Redisigning the parser to remove recursion shouldn't be difficult but would make the code -less obvious. (patches welcome). The basic idea - - -Parsing -------- - -This grammar is then used to parse Python input and transform it into a syntax tree. - -As of now the syntax tree is built as a tuple to match the output of the parser module -and feed it to the compiler package - -the compiler package uses the Transformer class to transform this tuple tree into an -abstract syntax tree. - -sticking to our previous example, the syntax tree for x+x*y would be:: - - Rule('S', nodes=[ - Rule('A',nodes=[Rule('V', nodes=[Token('x')])]), - Token('+'), - Rule('A',nodes=[ - Rule('V', nodes=[Token('x')]), - Token('*'), - Rule('V', nodes=[Token('y')]) - ]) - ]) - - -The abstract syntax tree for the same expression would look like:: - - Add(Var('x'),Mul(Var('x'),Var('y'))) - - - -Examples using the parser within PyPy -------------------------------------- - -The four parser variants are used from within interpreter/pycompiler.py - -API Quickref ------------- - -Modules -~~~~~~~ - -* interpreter/pyparser contains the tokenizer and grammar parser -* interpreter/astcompiler contains the soon to be rpythonic compiler -* interpreter/stablecompiler contains the compiler used by default -* lib/_stablecompiler contains a modified version of stablecompiler capable - of running at application level (that is not recursively calling itself - while compiling) - - -Main facade functions -~~~~~~~~~~~~~~~~~~~~~ - -still empty, but non-empty for ReST - -Grammar -~~~~~~~ - -still empty, but non-empty for ReST - -Long term goals -=============== - -having enough flexibility in the design that allows us to change the -grammar at runtime. Such modification needs to be able to: -* modify the grammar representation -* modify the ast builder so it produces existing or new AST nodes -* add new AST nodes -* modify the compiler so that it knows how to deal with new AST nodes - - -parser implementation ---------------------- - -We can now build AST trees directly from the parser. -Still missing is the ability to easily provide/change building functions -easily. The functions are referenced at interpreter level through a dictionnary -mapping that has rule names as keys. - - -compiler implementation ------------------------ - -For now we are working at translating the existing compiler module without -changing its design too much. That means we won't have enough flexibility -to be able to handle new AST nodes at runtime. - -parser module -------------- - -enhance the parser module interface so that it allows acces to the internal grammar -representation, and allows to modify it too. +*************************** -compiler module ---------------- +The python grammar is built at startup from the pristine CPython grammar file +(see `pypy/interpreter/pyparser/metaparser.py`_). The grammar builder first +represents the grammar as rules corresponding to a set of Nondeterministic +Finite Automatons (NFAs). It then converts them to a set of Deterministic +Finite Automatons (DFAs). The difference between a NFA and a DFA is that a NFA +may have several possible next states for any given input while a DFA may only +have one. DFAs are therefore more limiting, but far more efficient to use in +parsing. Finally, the assigns the grammar builder assigns each DFA state a +number and packs them into a list for the parser to use. The final product is +an instance of the ``Grammar`` class in `pypy/interpreter/pyparser/parser.py`_. + +Parser implementation +********************* + +The workhorse of the parser is the ``add_token`` method of the ``Parser`` class. +It tries to find a transition from the current state to another state based on +the token it receives as a argument. If it can't find a transition, it checks +if the current state is accepting. If it's not, a ``ParseError`` is +raised. When parsing is done without error, the parser has built a tree of +``Node``. + +Parsing Python +************** + +The glue code between the tokenizer and the parser as well as extra Python +specific code is in `pypy/interpreter/pyparser/pyparse.py`_. The +``parse_source`` method takes a string of Python code and returns the parse +tree. It also detects the coding cookie if there is one and decodes the source. +Note that __future__ imports are handled before the parser is invoked by +manually parsing the source in `pypy/interpreter/pyparser/future.py`_. + +Compiler +-------- + +The next step in generating Python bytecode is converting the parse tree into an +Abstract Syntax Tree (AST). + +Building AST +************ + +Python's AST is described in `pypy/interpreter/astcompiler/tools/Python.asdl`_. +From this definition, `pypy/interpreter/astcompiler/tools/asdl_py.py`_ generates +`pypy/interpreter/astcompiler/ast.py`_, which RPython classes for the compiler +as well as bindings to application level code for the AST. Some custom +extensions to the AST classes are in +`pypy/interpreter/astcompiler/asthelpers.py`_. + +`pypy/interpreter/astcompiler/astbuilder.py`_ is responsible for converting +parse trees into AST. It walks down the parse tree building nodes as it goes. +The result is a toplevel ``mod`` node. + +AST Optimization +**************** + +`pypy/interpreter/astcompiler/optimize.py`_ contains the AST optimizer. It does +constant folding of expressions, and other simple transformations like making a +load of the name "None" into a constant. + +Symbol analysis +*************** + +Before writing bytecode, a symbol table is built in +`pypy/interpreter/astcompiler/symtable.py`_. It determines if every name in the +source is local, implicitly global (no global declaration), explicity global +(there's a global declaration of the name in the scope), a cell (the name in +used in nested scopes), or free (it's used in a nested function). + +Bytecode generation +******************* + +Bytecode is emitted in `pypy/interpreter/astcompiler/codegen.py`_. Each +bytecode is represented temporarily by the ``Instruction`` class in +`pypy/interpreter/astcompiler/assemble.py`_. After all bytecodes have been +emitted, it's time to build the code object. Jump offsets and bytecode +information like the line number table and stack depth are computed. Finally, +everything is passed to a brand new ``PyCode`` object. -same as above +.. include:: _ref.txt From benjamin at codespeak.net Sun Aug 30 03:07:28 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 30 Aug 2009 03:07:28 +0200 (CEST) Subject: [pypy-svn] r67334 - pypy/trunk/pypy/interpreter/pyparser Message-ID: <20090830010728.58B2A16800A@codespeak.net> Author: benjamin Date: Sun Aug 30 03:07:27 2009 New Revision: 67334 Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py Log: remove pointless enumerate Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/metaparser.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/metaparser.py Sun Aug 30 03:07:27 2009 @@ -135,7 +135,7 @@ for name in names: dfa = self.dfas[name] states = [] - for state_index, state in enumerate(dfa): + for state in dfa: arcs = [] for label, next in state.arcs.iteritems(): arcs.append((self.make_label(gram, label), dfa.index(next))) From benjamin at codespeak.net Sun Aug 30 03:13:10 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 30 Aug 2009 03:13:10 +0200 (CEST) Subject: [pypy-svn] r67335 - pypy/trunk/pypy/interpreter/pyparser Message-ID: <20090830011310.A448016801B@codespeak.net> Author: benjamin Date: Sun Aug 30 03:13:10 2009 New Revision: 67335 Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py Log: fix spelling Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/metaparser.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/metaparser.py Sun Aug 30 03:13:10 2009 @@ -223,7 +223,7 @@ for label, their_first in overlap_check.iteritems(): for sub_label in their_first: if sub_label in inverse: - raise PgenError("ambiguas symbol %s" % (symbol,)) + raise PgenError("ambiguous symbol %s" % (symbol,)) inverse[sub_label] = label self.first[name] = all_labels return all_labels From benjamin at codespeak.net Sun Aug 30 03:39:30 2009 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 30 Aug 2009 03:39:30 +0200 (CEST) Subject: [pypy-svn] r67336 - pypy/trunk/pypy/interpreter/pyparser Message-ID: <20090830013930.40B2016801B@codespeak.net> Author: benjamin Date: Sun Aug 30 03:39:28 2009 New Revision: 67336 Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py Log: describe algorithm Modified: pypy/trunk/pypy/interpreter/pyparser/metaparser.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/metaparser.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/metaparser.py Sun Aug 30 03:39:28 2009 @@ -73,7 +73,13 @@ def nfa_to_dfa(start, end): - """Convert an NFA to a DFA(s)""" + """Convert an NFA to a DFA(s) + + Each DFA is initially a set of NFA states without labels. We start with the + DFA for the start NFA. Then we add labeled arcs to it pointing to another + set of NFAs (the next state). Finally, we do the same thing to every DFA + that is found and return the list of states. + """ base_nfas = set() start.find_unlabeled_states(base_nfas) state_stack = [DFA(base_nfas, end)] From antocuni at codespeak.net Sun Aug 30 10:54:51 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 30 Aug 2009 10:54:51 +0200 (CEST) Subject: [pypy-svn] r67337 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090830085451.CB38716801B@codespeak.net> Author: antocuni Date: Sun Aug 30 10:54:49 2009 New Revision: 67337 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Log: fix typo introduced by mistake by the less-is_oo branch Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_ll_random.py Sun Aug 30 10:54:49 2009 @@ -426,7 +426,7 @@ """ % funcargs).compile() vtableptr = v._hints['vtable']._as_ptr() d = { - 'ref': S.value, + 'ptr': S.value, 'vtable' : vtableptr, 'LLException' : LLException, } From antocuni at codespeak.net Sun Aug 30 13:47:53 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 30 Aug 2009 13:47:53 +0200 (CEST) Subject: [pypy-svn] r67339 - pypy/branch/pyjitpl5/pypy/jit/metainterp Message-ID: <20090830114753.C4CE216801D@codespeak.net> Author: antocuni Date: Sun Aug 30 13:47:52 2009 New Revision: 67339 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Log: don't store null keys in the dictionary, as it's not supported on cli Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizeopt.py Sun Aug 30 13:47:52 2009 @@ -344,6 +344,8 @@ return box if box.type == REF: value = box.getref_base() + if not value: + return box key = self.cpu.ts.cast_ref_to_hashable(self.cpu, value) try: return self.interned_refs[key] From antocuni at codespeak.net Sun Aug 30 13:58:39 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 30 Aug 2009 13:58:39 +0200 (CEST) Subject: [pypy-svn] r67340 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test Message-ID: <20090830115839.414F3168014@codespeak.net> Author: antocuni Date: Sun Aug 30 13:58:38 2009 New Revision: 67340 Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_exception.py (contents, props changed) Log: add this new test file, as some of its tests can be run also before translation Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_exception.py ============================================================================== --- (empty file) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_exception.py Sun Aug 30 13:58:38 2009 @@ -0,0 +1,28 @@ +import py +from pypy.jit.metainterp.test import test_exception +from pypy.jit.backend.cli.test.test_basic import CliJitMixin + + +class TestException(CliJitMixin, test_exception.TestOOtype): + # for the individual tests see + # ====> ../../../metainterp/test/test_exception.py + + def skip(self): + py.test.skip("works only after translation") + + test_simple = skip + test_bridge_from_guard_exception = skip + test_bridge_from_guard_no_exception = skip + test_four_levels_checks = skip + test_exception_from_outside = skip + test_exception_from_outside_2 = skip + test_exception_two_cases = skip + test_exception_two_cases_2 = skip + test_exception_four_cases = skip + test_exception_later = skip + test_exception_and_then_no_exception = skip + test_raise_through = skip + test_raise_through_wrong_exc = skip + test_raise_through_wrong_exc_2 = skip + test_bridge_from_interpreter_exc = skip + test_bridge_from_interpreter_exc_2 = skip From antocuni at codespeak.net Sun Aug 30 16:16:34 2009 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 30 Aug 2009 16:16:34 +0200 (CEST) Subject: [pypy-svn] r67341 - pypy/branch/pyjitpl5/pypy/jit/backend/cli Message-ID: <20090830141634.74C5A168015@codespeak.net> Author: antocuni Date: Sun Aug 30 16:16:33 2009 New Revision: 67341 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Log: optimize *_ovf operations followed by guard_no_overflow: instead of setting a flag in the catch block to be checked outside, handle the guard failure directly in the catch block. According to my benchmarks, this should be ~30% faster (at least on mono) Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Sun Aug 30 16:16:33 2009 @@ -315,12 +315,17 @@ self.il_loop_start = self.il.DefineLabel() self.il.MarkLabel(self.il_loop_start) - def emit_operations(self, operations): - for op in operations: + def emit_operations(self, oplist): + self.i = 0 + self.oplist = oplist + N = len(oplist) + while self.i < N: + op = oplist[self.i] self.emit_debug(op.repr()) func = self.operations[op.opnum] assert func is not None func(self, op) + self.i += 1 def emit_branches(self): while self.branches: @@ -382,6 +387,11 @@ self.il.EndExceptionBlock() def emit_ovf_op(self, op, emit_op): + next_op = self.oplist[self.i+1] + if next_op.opnum == rop.GUARD_NO_OVERFLOW: + self.i += 1 + self.emit_ovf_op_and_guard(op, next_op, emit_op) + return # clear the overflow flag self.il.Emit(OpCodes.Ldc_I4_0) self.av_ovf_flag.store(self) @@ -393,6 +403,19 @@ self.av_ovf_flag.store(self) self.il.EndExceptionBlock() + def emit_ovf_op_and_guard(self, op, opguard, emit_op): + # emit the checked operation + lbl = self.il.BeginExceptionBlock() + emit_op(self, op) + self.il.Emit(OpCodes.Leave, lbl) + self.il.BeginCatchBlock(dotnet.typeof(System.OverflowException)) + # emit the guard + assert opguard.suboperations + assert len(opguard.args) == 0 + il_label = self.newbranch(opguard) + self.il.Emit(OpCodes.Leave, il_label) + self.il.EndExceptionBlock() + def mark(self, msg): self.il.Emit(OpCodes.Ldstr, msg) self.il.Emit(OpCodes.Pop) From arigo at codespeak.net Sun Aug 30 17:33:26 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Aug 2009 17:33:26 +0200 (CEST) Subject: [pypy-svn] r67343 - in pypy/branch/pyjitpl5-llmodel/pypy/jit: backend backend/test backend/x86 metainterp Message-ID: <20090830153326.D0B79168015@codespeak.net> Author: arigo Date: Sun Aug 30 17:33:25 2009 New Revision: 67343 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/codebuf.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py Log: Add COND_CALL and implement it in the backend. Meant to be used only for calls to helpers like malloc. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Sun Aug 30 17:33:25 2009 @@ -160,6 +160,12 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_cond_call(self, args, calldescr): + if not args[0].getint(): + return args[1] + else: + return self.do_call(args[2:], calldescr) + def do_cast_int_to_ptr(self, args, descr=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Sun Aug 30 17:33:25 2009 @@ -109,12 +109,29 @@ func_ptr = llhelper(FPTR, func) FUNC = deref(FPTR) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) + funcbox = self.get_funcbox(cpu, func_ptr) res = self.execute_operation(rop.CALL, - [self.get_funcbox(cpu, func_ptr), - BoxInt(num), BoxInt(num)], + [funcbox, BoxInt(num), BoxInt(num)], 'int', descr=calldescr) assert res.value == 2 * num + # also test COND_CALL: + for cond in [False, True]: + value = random.randrange(-sys.maxint, sys.maxint) + if cond: + value |= 4096 + else: + value &= ~4096 + res = self.execute_operation(rop.COND_CALL, + [BoxInt(value), ConstInt(4096), + BoxInt(321123), + funcbox, BoxInt(num), BoxInt(num)], + 'int', descr=calldescr) + if cond: + assert res.value == 2 * num + else: + assert res.value == 321123 + def test_executor(self): cpu = self.cpu x = execute(cpu, rop.INT_ADD, [BoxInt(100), ConstInt(42)]) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sun Aug 30 17:33:25 2009 @@ -755,17 +755,14 @@ sizeloc = arglocs[0] assert isinstance(sizeloc, IMM32) size = sizeloc.value - arglocs = arglocs[1:] nargs = len(op.args)-1 extra_on_stack = self.align_stack_for_call(nargs) - for i in range(nargs, 0, -1): - v = op.args[i] - loc = arglocs[i] - self.mc.PUSH(loc) + for i in range(nargs+1, 1, -1): + self.mc.PUSH(arglocs[i]) if isinstance(op.args[0], Const): x = rel32(op.args[0].getint()) else: - x = arglocs[0] + x = arglocs[1] self.mc.CALL(x) self.mark_gc_roots() self.mc.ADD(esp, imm(WORD * extra_on_stack)) @@ -776,6 +773,41 @@ genop_call_pure = genop_call + def genop_cond_call(self, op, arglocs, resloc): + sizeloc = arglocs[0] + assert isinstance(sizeloc, IMM32) + size = sizeloc.value + # use 'mc._mc' directly instead of 'mc', to avoid + # bad surprizes if the code buffer is mostly full + loc_cond = arglocs[1] + loc_mask = arglocs[2] + loc_value_if_false = arglocs[3] + mc = self.mc._mc + mc.TEST(loc_cond, loc_mask) + mc.write('\x74\x00') # JZ after_the_call + jz_location = mc.get_relative_pos() + for i in range(len(arglocs)-1, 4, -1): + mc.PUSH(arglocs[i]) + mc.CALL(rel32(op.args[3].getint())) + if size == 1: + mc.MOVZX(resloc, al) + elif size == 2: + mc.MOVZX(resloc, eax) # actually reads the AX part only + elif resloc is not None and resloc is not eax: + mc.XCHG(eax, resloc) + pop_count = 0 + for i in range(5, len(arglocs)): + loc = arglocs[i] + pop_count += 1 + if loc is not resloc and isinstance(loc, REG): + while pop_count > 0: + mc.POP(loc) + pop_count -= 1 + if pop_count: + mc.ADD(esp, imm(WORD * pop_count)) + # patch the JZ above + mc.overwrite(jz_location-1, chr(mc.get_relative_pos() - jz_location)) + def not_implemented_op_discard(self, op, arglocs): print "not implemented operation: %s" % op.getopname() raise NotImplementedError Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/codebuf.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/codebuf.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/codebuf.py Sun Aug 30 17:33:25 2009 @@ -18,13 +18,18 @@ self._size = map_size self._pos = 0 - def write(self, data): - p = self._pos - assert p + len(data) <= self._size + def overwrite(self, pos, data): + assert pos + len(data) <= self._size for c in data: - self._data[p] = c - p += 1 - self._pos = p + self._data[pos] = c + pos += 1 + return pos + + def write(self, data): + self._pos = self.overwrite(self._pos, data) + + def get_relative_pos(self): + return self._pos def tell(self): baseaddr = rffi.cast(lltype.Signed, self._data) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Sun Aug 30 17:33:25 2009 @@ -717,16 +717,40 @@ self.Perform(op, arglocs, eax) def consider_call(self, op, ignored): - from pypy.jit.backend.x86.runner import CPU386 calldescr = op.descr assert isinstance(calldescr, BaseCallDescr) assert len(calldescr.arg_classes) == len(op.args) - 1 size = calldescr.get_result_size(self.translate_support_code) - return self._call(op, [imm(size)] + - [self.loc(arg) for arg in op.args]) + self._call(op, [imm(size)] + [self.loc(arg) for arg in op.args]) consider_call_pure = consider_call + def consider_cond_call(self, op, ignored): + calldescr = op.descr + assert isinstance(calldescr, BaseCallDescr) + v_cond = op.args[0] + v_mask = op.args[1] + v_value_if_false = op.args[2] + if op.result is not None: + resloc = self.force_result_in_reg(op.result, v_value_if_false, []) + else: + resloc = None + condloc = self.loc(v_cond) + arglocs = [resloc] + [self.loc(arg) for arg in op.args[3:]] + # add eax, ecx and edx as extra "arguments" to ensure they are + # saved and restored. Don't add them if they are equal to resloc! + for v, reg in self.reg_bindings.items(): + if ((reg is eax or reg is ecx or reg is edx) + and self.longevity[v][1] > self.position + and reg not in arglocs): + arglocs.append(reg) + size = calldescr.get_result_size(self.translate_support_code) + self.Perform(op, + [imm(size), condloc, convert_to_imm(v_mask)] + arglocs, + resloc) + self.eventually_free_var(v_cond) + self.eventually_free_vars(op.args[3:]) + def consider_new(self, op, ignored): args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr) arglocs = [imm(x) for x in args] Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py Sun Aug 30 17:33:25 2009 @@ -197,6 +197,8 @@ 'UNICODESETITEM', 'NEWUNICODE', 'RUNTIMENEW', # ootype operation + 'COND_CALL', # [cond, imm_and, if_false_value, + # if_true_call, args_for_call...] 'DEBUG_MERGE_POINT', # debugging only '_CANRAISE_FIRST', # ----- start of can_raise operations ----- From arigo at codespeak.net Sun Aug 30 17:34:28 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Aug 2009 17:34:28 +0200 (CEST) Subject: [pypy-svn] r67344 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86 Message-ID: <20090830153428.752BC168015@codespeak.net> Author: arigo Date: Sun Aug 30 17:34:28 2009 New Revision: 67344 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Log: Add a comment. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Sun Aug 30 17:34:28 2009 @@ -786,6 +786,8 @@ mc.TEST(loc_cond, loc_mask) mc.write('\x74\x00') # JZ after_the_call jz_location = mc.get_relative_pos() + # the following is supposed to be the slow path, so whenever possible + # we choose the most compact encoding over the most efficient one. for i in range(len(arglocs)-1, 4, -1): mc.PUSH(arglocs[i]) mc.CALL(rel32(op.args[3].getint())) From cfbolz at codespeak.net Mon Aug 31 10:38:21 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 10:38:21 +0200 (CEST) Subject: [pypy-svn] r67346 - pypy/extradoc/planning Message-ID: <20090831083821.19EF416801B@codespeak.net> Author: cfbolz Date: Mon Aug 31 10:38:18 2009 New Revision: 67346 Modified: pypy/extradoc/planning/jit.txt Log: - kill some duplicate lines - some things I discovered during the weekend Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Mon Aug 31 10:38:18 2009 @@ -27,6 +27,12 @@ - update things in metainterp/doc +Python interpreter: +- make shared dicts support shadowtracking +- make shared dicts revert to string dicts less often +- don't look for the global-lookup-cache when a function contains no + LOAD_GLOBAL + inlining discussion -------------------- @@ -37,6 +43,9 @@ - tracing aggressively will put pressure on the speed of tracing - what should we do about recursive calls? - connecting compiled loops accross a call? +- problem: when we inline one function, and then hit something non-inlinable, + how do we make the inlined function's frame not escape via the + non-inlinable's f_back? things we know are missing --------------------------- @@ -51,15 +60,13 @@ - save space on all the guard operations (see resume.py) backend: -- recompilation after every bridge is bad -- memory management for the code (free unused code) - speed of backend? - support threads again! Python interpreter: - lookups of various kinds -- calls??? +- calls tests: - find a test for r64742 (JitException capture) From cfbolz at codespeak.net Mon Aug 31 11:04:30 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 11:04:30 +0200 (CEST) Subject: [pypy-svn] r67347 - pypy/branch/pyjitpl5/pypy/module/pypyjit Message-ID: <20090831090430.E9E6216801B@codespeak.net> Author: cfbolz Date: Mon Aug 31 11:04:29 2009 New Revision: 67347 Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Log: Also show the name of the bytecode in the debug_merge_point of the Python interpreter. Modified: pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py Mon Aug 31 11:04:29 2009 @@ -45,9 +45,11 @@ return True def get_printable_location(next_instr, bytecode): + from pypy.tool.stdlib_opcode import opcode_method_names if we_are_translated(): bytecode = cast_base_ptr_to_instance(PyCode, bytecode) - return '%s #%d' % (bytecode.get_repr(), next_instr) + name = opcode_method_names[ord(bytecode.co_code[next_instr])] + return '%s #%d %s' % (bytecode.get_repr(), next_instr, name) class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] From cfbolz at codespeak.net Mon Aug 31 11:07:11 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 11:07:11 +0200 (CEST) Subject: [pypy-svn] r67348 - pypy/branch/pyjitpl5/pypy/objspace/std Message-ID: <20090831090711.755B2168015@codespeak.net> Author: cfbolz Date: Mon Aug 31 11:07:10 2009 New Revision: 67348 Modified: pypy/branch/pyjitpl5/pypy/objspace/std/celldict.py Log: Refactor things a bit in the cell dict. This makes it a lot more JIT friendly. When enabling the cell dict with the JIT, global lookups look kind of good. Modified: pypy/branch/pyjitpl5/pypy/objspace/std/celldict.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/objspace/std/celldict.py (original) +++ pypy/branch/pyjitpl5/pypy/objspace/std/celldict.py Mon Aug 31 11:07:10 2009 @@ -1,6 +1,7 @@ from pypy.objspace.std.dictmultiobject import DictImplementation from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash +from pypy.rlib import jit class ModuleCell(object): def __init__(self, w_value=None): @@ -21,13 +22,13 @@ self.unshadowed_builtins = {} def getcell(self, key, make_new=True): - try: - return self.content[key] - except KeyError: - if not make_new: - raise - result = self.content[key] = ModuleCell() - return result + res = self.content.get(key, None) + if res is not None: + return res + if not make_new: + return None + result = self.content[key] = ModuleCell() + return result def add_unshadowed_builtin(self, name, builtin_impl): assert isinstance(builtin_impl, ModuleDictImplementation) @@ -66,6 +67,8 @@ if space.is_w(w_key_type, space.w_str): key = space.str_w(w_key) cell = self.getcell(key, False) + if cell is None: + raise KeyError cell.invalidate() del self.content[key] return self @@ -81,10 +84,10 @@ space = self.space w_lookup_type = space.type(w_lookup) if space.is_w(w_lookup_type, space.w_str): - try: - return self.getcell(space.str_w(w_lookup), False).w_value - except KeyError: + res = self.getcell(space.str_w(w_lookup), False) + if res is None: return None + return res.w_value elif _is_sane_hash(space, w_lookup_type): return None else: @@ -186,9 +189,10 @@ def getcache_slow(self, space, code, w_globals, implementation): state = space.fromcache(State) if not isinstance(implementation, ModuleDictImplementation): - missing_length = max(len(code.co_names_w) - len(state.always_invalid_cache), 0) - state.always_invalid_cache.extend([state.invalidcell] * missing_length) cache = state.always_invalid_cache + if len(code.co_names_w) > len(cache): + cache = [state.invalidcell] * len(code.co_names_w) + state.always_invalid_cache = cache else: cache = [state.invalidcell] * len(code.co_names_w) self.cache = cache @@ -202,8 +206,7 @@ def get_global_cache(space, code, w_globals): from pypy.interpreter.pycode import PyCode - if not isinstance(code, PyCode): - return [] + assert isinstance(code, PyCode) holder = code.globalcacheholder return holder.getcache(space, code, w_globals) @@ -224,12 +227,10 @@ def find_cell_from_dict(implementation, name): if isinstance(implementation, ModuleDictImplementation): - try: - return implementation.getcell(name, False) - except KeyError: - return None + return implementation.getcell(name, False) return None + at jit.dont_look_inside def load_global_fill_cache(f, nameindex): name = f.space.str_w(f.getname_w(nameindex)) implementation = getimplementation(f.w_globals) From arigo at codespeak.net Mon Aug 31 11:08:13 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 11:08:13 +0200 (CEST) Subject: [pypy-svn] r67349 - pypy/branch/pyjitpl5/pypy/jit/backend/test Message-ID: <20090831090813.8E895168015@codespeak.net> Author: arigo Date: Mon Aug 31 11:08:13 2009 New Revision: 67349 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Log: (micke, arigo) Fix a failing test, by forbidding passing several times the same box. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py Mon Aug 31 11:08:13 2009 @@ -64,7 +64,8 @@ loop.operations = operations loop.inputargs = [] for box in valueboxes: - if isinstance(box, Box) and box not in loop.inputargs: + if isinstance(box, Box): + assert box not in loop.inputargs, "repeated box!" loop.inputargs.append(box) self.cpu.compile_operations(loop) return loop @@ -354,9 +355,11 @@ def test_ooops(self): u1_box, U_box = self.alloc_instance(self.U) u2_box, U_box = self.alloc_instance(self.U) - r = self.execute_operation(rop.OOIS, [u1_box, u1_box], 'int') + r = self.execute_operation(rop.OOIS, [u1_box, + u1_box.clonebox()], 'int') assert r.value == 1 - r = self.execute_operation(rop.OOISNOT, [u2_box, u2_box], 'int') + r = self.execute_operation(rop.OOISNOT, [u2_box, + u2_box.clonebox()], 'int') assert r.value == 0 r = self.execute_operation(rop.OOIS, [u1_box, u2_box], 'int') assert r.value == 0 @@ -368,13 +371,15 @@ assert r.value == 1 # null_box = self.null_instance() - r = self.execute_operation(rop.OOIS, [null_box, null_box], 'int') + r = self.execute_operation(rop.OOIS, [null_box, + null_box.clonebox()], 'int') assert r.value == 1 r = self.execute_operation(rop.OOIS, [u1_box, null_box], 'int') assert r.value == 0 r = self.execute_operation(rop.OOIS, [null_box, u2_box], 'int') assert r.value == 0 - r = self.execute_operation(rop.OOISNOT, [null_box, null_box], 'int') + r = self.execute_operation(rop.OOISNOT, [null_box, + null_box.clonebox()], 'int') assert r.value == 0 r = self.execute_operation(rop.OOISNOT, [u2_box, null_box], 'int') assert r.value == 1 From cfbolz at codespeak.net Mon Aug 31 11:35:57 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 11:35:57 +0200 (CEST) Subject: [pypy-svn] r67350 - in pypy/branch/pyjitpl5/pypy/jit: backend metainterp Message-ID: <20090831093557.8A888168015@codespeak.net> Author: cfbolz Date: Mon Aug 31 11:35:55 2009 New Revision: 67350 Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py Log: don't show the "boring" fail blocks by default. makes graphs a lot smaller in the common case. Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py Mon Aug 31 11:35:55 2009 @@ -5,6 +5,7 @@ import autopath import sys, py, re +from pypy.jit.metainterp.resoperation import rop def count_indent(s): indent = 0 @@ -60,6 +61,7 @@ return "Comment: %r" % (self.text,) class ByteCodeRef(Comment): + opnum = rop.DEBUG_MERGE_POINT def __init__(self, text): Comment.__init__(self, text) self.address = int(text.rsplit('#')[1]) @@ -67,6 +69,7 @@ class Operation(BaseOperation): def __init__(self, opname, args, result=None, descr=None): self.opname = opname + self.opnum = getattr(rop, opname.upper(), -41) self.args = args self.result = result self.descr = descr Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py Mon Aug 31 11:35:55 2009 @@ -4,6 +4,8 @@ from pypy.jit.metainterp.history import Box from pypy.jit.metainterp.resoperation import rop +SHOW_FAILS = False + class SubGraph: def __init__(self, suboperations): self.suboperations = suboperations @@ -16,11 +18,22 @@ graphs = [(loop, loop in highlight_loops) for loop in loops] for graph, highlight in graphs: for op in graph.get_operations(): - if op.is_guard(): + if is_interesting_guard(op): graphs.append((SubGraph(op.suboperations), highlight)) graphpage = ResOpGraphPage(graphs, errmsg) graphpage.display() +def is_interesting_guard(op): + if not op.is_guard(): + return False + if SHOW_FAILS: + return True + if len(op.suboperations) > 1: + return True + if op.suboperations[0].opnum == rop.FAIL: + return False + return True + class ResOpGraphPage(GraphPage): @@ -63,9 +76,16 @@ for graphindex in range(len(self.graphs)): self.block_starters[graphindex] = {0: True} for graphindex, graph in enumerate(self.graphs): + last_was_mergepoint = False for i, op in enumerate(graph.get_operations()): - if op.is_guard(): + if is_interesting_guard(op): self.mark_starter(graphindex, i+1) + if op.opnum == rop.DEBUG_MERGE_POINT: + if not last_was_mergepoint: + last_was_mergepoint = True + self.mark_starter(graphindex, i) + else: + last_was_mergepoint = False def set_errmsg(self, errmsg): self.errmsg = errmsg @@ -138,7 +158,7 @@ while True: op = operations[opindex] lines.append(repr(op)) - if op.is_guard(): + if is_interesting_guard(op): tgt = op.suboperations[0] tgt_g, tgt_i = self.all_operations[tgt] self.genedge((graphindex, opstartindex), From arigo at codespeak.net Mon Aug 31 12:44:24 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 12:44:24 +0200 (CEST) Subject: [pypy-svn] r67352 - in pypy/branch/pyjitpl5-llmodel/pypy/jit: backend/llsupport backend/llsupport/test metainterp Message-ID: <20090831104424.DAAB4168015@codespeak.net> Author: arigo Date: Mon Aug 31 12:44:22 2009 New Revision: 67352 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py Log: (micke, arigo) Finish the refactoring at least in backend.llsupport: add a way to rewrite the list of operations in order to insert write barrier calls and handle ConstPtrs. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Mon Aug 31 12:44:22 2009 @@ -4,10 +4,14 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, ConstPtr +from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr +from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr +from pypy.jit.backend.llsupport.descr import get_call_descr # ____________________________________________________________ @@ -19,7 +23,7 @@ return True def do_write_barrier(self, gcref_struct, gcref_newptr): pass - def gen_write_barrier(self, regalloc, base_reg, value_reg): + def rewrite_assembler(self, cpu, gcrefs, operations): pass # ____________________________________________________________ @@ -287,6 +291,7 @@ " with the JIT" % (name,)) gcrootmap = cls() self.gcrootmap = gcrootmap + self.single_gcref_descr = GcPtrFieldDescr(0) # make a TransformerLayoutBuilder and save it on the translator # where it can be fished and reused by the FrameworkGCTransformer @@ -302,6 +307,10 @@ self.HDRPTR = lltype.Ptr(self.GCClass.HDR) self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO) self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid') + self.c_jit_wb_if_flag = ConstInt(self.GCClass.JIT_WB_IF_FLAG) + self.calldescr_jit_wb = get_call_descr(self, [llmemory.GCREF, + llmemory.GCREF], + lltype.Void) (self.array_basesize, _, self.array_length_ofs) = \ symbolic.get_array_token(lltype.GcArray(lltype.Signed), True) @@ -420,42 +429,71 @@ funcptr(llmemory.cast_ptr_to_adr(gcref_struct), llmemory.cast_ptr_to_adr(gcref_newptr)) - def gen_write_barrier(self, assembler, base_reg, value_reg): - from pypy.jit.backend.x86.regalloc import REGS - bytes_count = 11 + def rewrite_assembler(self, cpu, gcrefs, operations): + # Perform two kinds of rewrites in parallel: # - if isinstance(value_reg, IMM32): - if value_reg.value == 0: - return # writing NULL: don't need the write barrier at all - bytes_count += 4 - else: - assert isinstance(value_reg, REG) + # - Add COND_CALLs to the write barrier before SETFIELD_GC and + # SETARRAYITEM_GC operations. # - if isinstance(base_reg, IMM32): - bytes_count += 4 - tidaddr = heap(base_reg.value + 0) - else: - assert isinstance(base_reg, REG) - tidaddr = mem(base_reg, 0) + # - Remove all uses of ConstPtrs away from the assembler. + # Idea: when running on a moving GC, we can't (easily) encode + # the ConstPtrs in the assembler, because they can move at any + # point in time. Instead, we store them in 'gcrefs.list', a GC + # but nonmovable list; and here, we modify 'operations' to + # replace direct usage of ConstPtr with a BoxPtr loaded by a + # GETFIELD_RAW from the array 'gcrefs.list'. # - assembler.mc.TEST(tidaddr, imm32(self.GCClass.JIT_WB_IF_FLAG)) - # do the rest using 'mc._mc' directly instead of 'mc', to avoid - # bad surprizes if the code buffer is mostly full - mc = assembler.mc._mc - mc.write('\x74') # JZ label_end - mc.write(chr(bytes_count)) - start = mc.tell() - mc.PUSHA() # 1 byte - mc.PUSH(value_reg) # 1 or 5 bytes - mc.PUSH(base_reg) # 1 or 5 bytes - funcptr = self.llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcaddr = rffi.cast(lltype.Signed, funcptr) - mc.CALL(rel32(funcaddr)) # 5 bytes - mc.POP(eax) # 1 byte - mc.POP(eax) # 1 byte - mc.POPA() # 1 byte - # total: 11+(4?)+(4?) bytes - assert mc.tell() == start + bytes_count + newops = [] + for op in operations: + if op.opnum == rop.DEBUG_MERGE_POINT: + continue + # ---------- replace ConstPtrs with GETFIELD_RAW ---------- + # xxx some performance issue here + for i in range(len(op.args)): + v = op.args[i] + if (isinstance(v, ConstPtr) and bool(v.value) + and rgc.can_move(v.value)): + box = BoxPtr(v.value) + addr = gcrefs.get_address_of_gcref(v.value) + addr = cpu.cast_adr_to_int(addr) + newops.append(ResOperation(rop.GETFIELD_RAW, + [ConstInt(addr)], box, + self.single_gcref_descr)) + op.args[i] = box + # ---------- write barrier for SETFIELD_GC ---------- + if op.opnum == rop.SETFIELD_GC: + v = op.args[1] + if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and + bool(v.value)): # store a non-NULL + self._gen_write_barrier(cpu, newops, op.args[0], v) + op = ResOperation(rop.SETFIELD_RAW, op.args, None, + descr=op.descr) + # ---------- write barrier for SETARRAYITEM_GC ---------- + if op.opnum == rop.SETARRAYITEM_GC: + v = op.args[2] + if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and + bool(v.value)): # store a non-NULL + self._gen_write_barrier(cpu, newops, op.args[0], v) + op = ResOperation(rop.SETARRAYITEM_RAW, op.args, None, + descr=op.descr) + # ---------- + if op.is_guard(): + self.rewrite_assembler(cpu, gcrefs, op.suboperations) + newops.append(op) + del operations[:] + operations.extend(newops) + + def _gen_write_barrier(self, cpu, newops, v_base, v_value): + v_tid = BoxInt() + newops.append(ResOperation(rop.GETFIELD_RAW, [v_base], v_tid, + descr=self.fielddescr_tid)) + llop1 = self.llop1 + funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) + funcaddr = llmemory.cast_ptr_to_adr(funcptr) + c_func = ConstInt(cpu.cast_adr_to_int(funcaddr)) + args = [v_tid, self.c_jit_wb_if_flag, c_func, v_base, v_value] + newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None, + descr=self.calldescr_jit_wb)) # ____________________________________________________________ Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Mon Aug 31 12:44:22 2009 @@ -1,5 +1,6 @@ import random from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr +from pypy.rpython.annlowlevel import llhelper from pypy.jit.backend.llsupport.descr import * from pypy.jit.backend.llsupport.gc import * from pypy.jit.backend.llsupport import symbolic @@ -124,8 +125,8 @@ def _write_barrier_failing_case(self, adr_struct, adr_newptr): self.record.append(('barrier', adr_struct, adr_newptr)) - def get_write_barrier_failing_case(self, FUNCTYPE): - return self._write_barrier_failing_case + def get_write_barrier_failing_case(self, FPTRTYPE): + return llhelper(FPTRTYPE, self._write_barrier_failing_case) class TestFramework: @@ -138,11 +139,18 @@ gc = 'hybrid' gcrootfinder = 'asmgcc' gctransformer = 'framework' + class FakeCPU: + def cast_adr_to_int(self, adr): + ptr = llmemory.cast_adr_to_ptr(adr, gc_ll_descr.WB_FUNCPTR) + assert ptr._obj._callable == llop1._write_barrier_failing_case + return 42 gcdescr = get_description(config) translator = FakeTranslator() - self.llop1 = FakeLLOp() - self.gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), - self.llop1) + llop1 = FakeLLOp() + gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + self.llop1 = llop1 + self.gc_ll_descr = gc_ll_descr + self.fake_cpu = FakeCPU() def test_gc_malloc(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) @@ -202,3 +210,120 @@ s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG gc_ll_descr.do_write_barrier(s_gcref, r_gcref) assert self.llop1.record == [('barrier', s_adr, r_adr)] + + def test_gen_write_barrier(self): + gc_ll_descr = self.gc_ll_descr + llop1 = self.llop1 + # + newops = [] + v_base = BoxPtr() + v_value = BoxPtr() + gc_ll_descr._gen_write_barrier(self.fake_cpu, newops, v_base, v_value) + assert llop1.record == [] + assert len(newops) == 2 + assert newops[0].opnum == rop.GETFIELD_RAW + assert newops[0].args == [v_base] + assert newops[0].descr == gc_ll_descr.fielddescr_tid + v_tid = newops[0].result + assert newops[1].opnum == rop.COND_CALL_GC_WB + assert newops[1].args[0] == v_tid + assert newops[1].args[1] ==ConstInt(gc_ll_descr.GCClass.JIT_WB_IF_FLAG) + assert newops[1].args[2] == ConstInt(42) # func ptr + assert newops[1].args[3] == v_base + assert newops[1].args[4] == v_value + assert newops[1].descr == gc_ll_descr.calldescr_jit_wb + assert newops[1].result is None + + def test_rewrite_assembler_1(self): + # check rewriting of ConstPtrs + class MyFakeCPU: + def cast_adr_to_int(self, adr): + stored_addr = adr.address[0] + assert stored_addr == llmemory.cast_ptr_to_adr(s_gcref) + return 43 + S = lltype.GcStruct('S') + s = lltype.malloc(S) + s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) + v_random_box = BoxPtr() + v_result = BoxInt() + operations = [ + ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)], + v_result), + ] + gcrefs = GcRefList() + gc_ll_descr = self.gc_ll_descr + gc_ll_descr.rewrite_assembler(MyFakeCPU(), gcrefs, operations) + assert len(operations) == 2 + assert operations[0].opnum == rop.GETFIELD_RAW + assert operations[0].args == [ConstInt(43)] + assert operations[0].descr == gc_ll_descr.single_gcref_descr + v_box = operations[0].result + assert isinstance(v_box, BoxPtr) + assert operations[1].opnum == rop.OOIS + assert operations[1].args == [v_random_box, v_box] + assert operations[1].result == v_result + + def test_rewrite_assembler_2(self): + # check write barriers before SETFIELD_GC + v_base = BoxPtr() + v_value = BoxPtr() + field_descr = AbstractDescr() + operations = [ + ResOperation(rop.SETFIELD_GC, [v_base, v_value], None, + descr=field_descr), + ] + gc_ll_descr = self.gc_ll_descr + gc_ll_descr.rewrite_assembler(self.fake_cpu, None, operations) + assert len(operations) == 3 + # + assert operations[0].opnum == rop.GETFIELD_RAW + assert operations[0].args == [v_base] + assert operations[0].descr == gc_ll_descr.fielddescr_tid + v_tid = operations[0].result + # + assert operations[1].opnum == rop.COND_CALL_GC_WB + assert operations[1].args[0] == v_tid + assert operations[1].args[1] == ConstInt( + gc_ll_descr.GCClass.JIT_WB_IF_FLAG) + assert operations[1].args[2] == ConstInt(42) # func ptr + assert operations[1].args[3] == v_base + assert operations[1].args[4] == v_value + assert operations[1].descr == gc_ll_descr.calldescr_jit_wb + assert operations[1].result is None + # + assert operations[2].opnum == rop.SETFIELD_RAW + assert operations[2].args == [v_base, v_value] + assert operations[2].descr == field_descr + + def test_rewrite_assembler_3(self): + # check write barriers before SETARRAYITEM_GC + v_base = BoxPtr() + v_index = BoxInt() + v_value = BoxPtr() + array_descr = AbstractDescr() + operations = [ + ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value], None, + descr=array_descr), + ] + gc_ll_descr = self.gc_ll_descr + gc_ll_descr.rewrite_assembler(self.fake_cpu, None, operations) + assert len(operations) == 3 + # + assert operations[0].opnum == rop.GETFIELD_RAW + assert operations[0].args == [v_base] + assert operations[0].descr == gc_ll_descr.fielddescr_tid + v_tid = operations[0].result + # + assert operations[1].opnum == rop.COND_CALL_GC_WB + assert operations[1].args[0] == v_tid + assert operations[1].args[1] == ConstInt( + gc_ll_descr.GCClass.JIT_WB_IF_FLAG) + assert operations[1].args[2] == ConstInt(42) # func ptr + assert operations[1].args[3] == v_base + assert operations[1].args[4] == v_value + assert operations[1].descr == gc_ll_descr.calldescr_jit_wb + assert operations[1].result is None + # + assert operations[2].opnum == rop.SETARRAYITEM_RAW + assert operations[2].args == [v_base, v_index, v_value] + assert operations[2].descr == array_descr Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/resoperation.py Mon Aug 31 12:44:22 2009 @@ -190,6 +190,7 @@ '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC', + 'SETARRAYITEM_RAW', # only added by backend.llsupport.gc.rewrite_assembler 'SETFIELD_GC', 'SETFIELD_RAW', 'NEWSTR', @@ -197,8 +198,10 @@ 'UNICODESETITEM', 'NEWUNICODE', 'RUNTIMENEW', # ootype operation - 'COND_CALL', # [cond, imm_and, if_false_value, - # if_true_call, args_for_call...] + 'COND_CALL_GC_WB', # [cond, imm_and, if_true_call, args_for_call...] + # => no result (for the write barrier) + 'COND_CALL_GC_MALLOC', # [a, b, if_(a<=b)_result, if_(a>b)_call, args...] + # => result (for mallocs) 'DEBUG_MERGE_POINT', # debugging only '_CANRAISE_FIRST', # ----- start of can_raise operations ----- From arigo at codespeak.net Mon Aug 31 14:06:04 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 14:06:04 +0200 (CEST) Subject: [pypy-svn] r67353 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: . llgraph test Message-ID: <20090831120604.59710168022@codespeak.net> Author: arigo Date: Mon Aug 31 14:06:02 2009 New Revision: 67353 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llgraph/llimpl.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Log: Write test_cond_call_gc_wb and make it pass on the llgraph backend. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llgraph/llimpl.py Mon Aug 31 14:06:02 2009 @@ -104,6 +104,7 @@ 'arraylen_gc' : (('ptr',), 'int'), 'call' : (('ptr', 'varargs'), 'intorptr'), 'call_pure' : (('ptr', 'varargs'), 'intorptr'), + 'cond_call_gc_wb' : (('int', 'int', 'ptr', 'varargs'), None), 'oosend' : (('varargs',), 'intorptr'), 'oosend_pure' : (('varargs',), 'intorptr'), 'guard_true' : (('bool',), None), @@ -690,6 +691,10 @@ op_call_pure = op_call + def op_cond_call_gc_wb(self, calldescr, a, b, func, *args): + if a & b: + self.op_call(calldescr, func, *args) + def op_oosend(self, descr, obj, *args): raise NotImplementedError("oosend for lltype backend??") Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Mon Aug 31 14:06:02 2009 @@ -139,6 +139,9 @@ def do_setarrayitem_gc(self, args, arraydescr): raise NotImplementedError + def do_setarrayitem_raw(self, args, arraydescr): + raise NotImplementedError + def do_setfield_gc(self, args, fielddescr): raise NotImplementedError @@ -160,11 +163,12 @@ def do_call(self, args, calldescr): raise NotImplementedError - def do_cond_call(self, args, calldescr): - if not args[0].getint(): - return args[1] - else: - return self.do_call(args[2:], calldescr) + def do_cond_call_gc_wb(self, args, calldescr): + if args[0].getint() & args[1].getint(): + self.do_call(args[2:], calldescr) + + def do_cond_call_gc_malloc(self, args, calldescr): + xxx def do_cast_int_to_ptr(self, args, descr=None): raise NotImplementedError Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/test/runner_test.py Mon Aug 31 14:06:02 2009 @@ -115,23 +115,6 @@ 'int', descr=calldescr) assert res.value == 2 * num - # also test COND_CALL: - for cond in [False, True]: - value = random.randrange(-sys.maxint, sys.maxint) - if cond: - value |= 4096 - else: - value &= ~4096 - res = self.execute_operation(rop.COND_CALL, - [BoxInt(value), ConstInt(4096), - BoxInt(321123), - funcbox, BoxInt(num), BoxInt(num)], - 'int', descr=calldescr) - if cond: - assert res.value == 2 * num - else: - assert res.value == 321123 - def test_executor(self): cpu = self.cpu x = execute(cpu, rop.INT_ADD, [BoxInt(100), ConstInt(42)]) @@ -960,6 +943,32 @@ assert self.cpu.get_latest_value_int(0) == 0 self.cpu.clear_exception() + def test_cond_call_gc_wb(self): + def func_void(a, b): + record.append((a, b)) + record = [] + # + FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Void) + func_ptr = llhelper(lltype.Ptr(FUNC), func_void) + funcbox = self.get_funcbox(self.cpu, func_ptr) + calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) + for cond in [False, True]: + value = random.randrange(-sys.maxint, sys.maxint) + if cond: + value |= 4096 + else: + value &= ~4096 + del record[:] + self.execute_operation(rop.COND_CALL_GC_WB, + [BoxInt(value), ConstInt(4096), + funcbox, BoxInt(655360), BoxInt(-2121)], + 'void', descr=calldescr) + if cond: + assert record == [(655360, -2121)] + else: + assert record == [] + + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' From pedronis at codespeak.net Mon Aug 31 14:12:22 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 14:12:22 +0200 (CEST) Subject: [pypy-svn] r67354 - pypy/branch/newtrunk Message-ID: <20090831121222.F0D82168022@codespeak.net> Author: pedronis Date: Mon Aug 31 14:12:21 2009 New Revision: 67354 Added: pypy/branch/newtrunk/ - copied from r67353, pypy/branch/pyjitpl5/ Log: (iko, pedronis) branch to unify trunk and pyjitpl5 From arigo at codespeak.net Mon Aug 31 14:28:21 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 14:28:21 +0200 (CEST) Subject: [pypy-svn] r67355 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport: . test Message-ID: <20090831122821.24A37168022@codespeak.net> Author: arigo Date: Mon Aug 31 14:28:19 2009 New Revision: 67355 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Log: Don't need to pass the GcRefList from outside. Keep it an internal implementation detail. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Mon Aug 31 14:28:19 2009 @@ -23,7 +23,7 @@ return True def do_write_barrier(self, gcref_struct, gcref_newptr): pass - def rewrite_assembler(self, cpu, gcrefs, operations): + def rewrite_assembler(self, cpu, operations): pass # ____________________________________________________________ @@ -266,7 +266,6 @@ class GcLLDescr_framework(GcLLDescription): - GcRefList = GcRefList def __init__(self, gcdescr, translator, llop1=llop): from pypy.rpython.memory.gc.base import choose_gc_from_config @@ -276,6 +275,7 @@ assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 + self.gcrefs = None # we need the hybrid GC for GcRefList.alloc_gcref_list() to work if gcdescr.config.translation.gc != 'hybrid': @@ -429,7 +429,7 @@ funcptr(llmemory.cast_ptr_to_adr(gcref_struct), llmemory.cast_ptr_to_adr(gcref_newptr)) - def rewrite_assembler(self, cpu, gcrefs, operations): + def rewrite_assembler(self, cpu, operations): # Perform two kinds of rewrites in parallel: # # - Add COND_CALLs to the write barrier before SETFIELD_GC and @@ -443,6 +443,8 @@ # replace direct usage of ConstPtr with a BoxPtr loaded by a # GETFIELD_RAW from the array 'gcrefs.list'. # + if self.gcrefs is None: + self.gcrefs = GcRefList() newops = [] for op in operations: if op.opnum == rop.DEBUG_MERGE_POINT: @@ -454,7 +456,7 @@ if (isinstance(v, ConstPtr) and bool(v.value) and rgc.can_move(v.value)): box = BoxPtr(v.value) - addr = gcrefs.get_address_of_gcref(v.value) + addr = self.gcrefs.get_address_of_gcref(v.value) addr = cpu.cast_adr_to_int(addr) newops.append(ResOperation(rop.GETFIELD_RAW, [ConstInt(addr)], box, @@ -478,7 +480,7 @@ descr=op.descr) # ---------- if op.is_guard(): - self.rewrite_assembler(cpu, gcrefs, op.suboperations) + self.rewrite_assembler(cpu, op.suboperations) newops.append(op) del operations[:] operations.extend(newops) Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Mon Aug 31 14:28:19 2009 @@ -250,9 +250,8 @@ ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)], v_result), ] - gcrefs = GcRefList() gc_ll_descr = self.gc_ll_descr - gc_ll_descr.rewrite_assembler(MyFakeCPU(), gcrefs, operations) + gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) assert len(operations) == 2 assert operations[0].opnum == rop.GETFIELD_RAW assert operations[0].args == [ConstInt(43)] @@ -273,7 +272,7 @@ descr=field_descr), ] gc_ll_descr = self.gc_ll_descr - gc_ll_descr.rewrite_assembler(self.fake_cpu, None, operations) + gc_ll_descr.rewrite_assembler(self.fake_cpu, operations) assert len(operations) == 3 # assert operations[0].opnum == rop.GETFIELD_RAW @@ -306,7 +305,7 @@ descr=array_descr), ] gc_ll_descr = self.gc_ll_descr - gc_ll_descr.rewrite_assembler(self.fake_cpu, None, operations) + gc_ll_descr.rewrite_assembler(self.fake_cpu, operations) assert len(operations) == 3 # assert operations[0].opnum == rop.GETFIELD_RAW From arigo at codespeak.net Mon Aug 31 14:28:29 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 14:28:29 +0200 (CEST) Subject: [pypy-svn] r67356 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86 Message-ID: <20090831122829.F0199168026@codespeak.net> Author: arigo Date: Mon Aug 31 14:28:28 2009 New Revision: 67356 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Log: Fix the x86 backend. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Mon Aug 31 14:28:28 2009 @@ -142,14 +142,6 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) - # for moving GCs, the array used to hold the address of GC objects - # that appear as ConstPtr. - if gc_ll_descr.moving_gc: - from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr - self.gcrefs = gc_ll_descr.GcRefList() - self.single_gcref_descr = GcPtrFieldDescr(0) - else: - self.gcrefs = None self.gcrootmap = gc_ll_descr.gcrootmap if self.gcrootmap: self.gcrootmap.initialize() @@ -569,6 +561,7 @@ assert 0, itemsize genop_discard_setfield_raw = genop_discard_setfield_gc + genop_discard_setarrayitem_raw = genop_discard_setarrayitem_gc def genop_strlen(self, op, arglocs, resloc): base_loc = arglocs[0] @@ -583,9 +576,9 @@ self.mc.MOV(resloc, addr_add_const(base_loc, ofs_length)) def genop_arraylen_gc(self, op, arglocs, resloc): - ofs = self.cpu.gc_ll_descr.array_length_ofs base_loc, ofs_loc = arglocs - self.mc.MOV(resloc, addr_add_const(base_loc, ofs)) + assert isinstance(ofs_loc, IMM32) + self.mc.MOV(resloc, addr_add_const(base_loc, ofs_loc.value)) def genop_strgetitem(self, op, arglocs, resloc): base_loc, ofs_loc = arglocs @@ -773,42 +766,34 @@ genop_call_pure = genop_call - def genop_cond_call(self, op, arglocs, resloc): - sizeloc = arglocs[0] - assert isinstance(sizeloc, IMM32) - size = sizeloc.value + def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid # bad surprizes if the code buffer is mostly full - loc_cond = arglocs[1] - loc_mask = arglocs[2] - loc_value_if_false = arglocs[3] + loc_cond = arglocs[0] + loc_mask = arglocs[1] mc = self.mc._mc mc.TEST(loc_cond, loc_mask) mc.write('\x74\x00') # JZ after_the_call jz_location = mc.get_relative_pos() # the following is supposed to be the slow path, so whenever possible # we choose the most compact encoding over the most efficient one. - for i in range(len(arglocs)-1, 4, -1): + for i in range(len(arglocs)-1, 2, -1): mc.PUSH(arglocs[i]) - mc.CALL(rel32(op.args[3].getint())) - if size == 1: - mc.MOVZX(resloc, al) - elif size == 2: - mc.MOVZX(resloc, eax) # actually reads the AX part only - elif resloc is not None and resloc is not eax: - mc.XCHG(eax, resloc) + mc.CALL(rel32(op.args[2].getint())) pop_count = 0 - for i in range(5, len(arglocs)): + for i in range(3, len(arglocs)): loc = arglocs[i] pop_count += 1 - if loc is not resloc and isinstance(loc, REG): + if isinstance(loc, REG): while pop_count > 0: mc.POP(loc) pop_count -= 1 if pop_count: mc.ADD(esp, imm(WORD * pop_count)) # patch the JZ above - mc.overwrite(jz_location-1, chr(mc.get_relative_pos() - jz_location)) + offset = mc.get_relative_pos() - jz_location + assert 0 < offset <= 127 + mc.overwrite(jz_location-1, chr(offset)) def not_implemented_op_discard(self, op, arglocs): print "not implemented operation: %s" % op.getopname() Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Mon Aug 31 14:28:28 2009 @@ -59,7 +59,8 @@ self.assembler = assembler self.translate_support_code = translate_support_code if regalloc is None: - self._rewrite_const_ptrs(tree.operations) + gc_ll_descr = self.assembler.cpu.gc_ll_descr + gc_ll_descr.rewrite_assembler(self, tree.operations) self.tree = tree self.reg_bindings = newcheckdict() self.stack_bindings = newcheckdict() @@ -215,38 +216,6 @@ self.max_stack_depth = max(self.max_stack_depth, self.current_stack_depth + 1) - def _rewrite_const_ptrs(self, operations): - # Idea: when running on a moving GC, we can't (easily) encode - # the ConstPtrs in the assembler, because they can move at any - # point in time. Instead, we store them in 'gcrefs.list', a GC - # but nonmovable list; and here, we modify 'operations' to - # replace direct usage of ConstPtr with a BoxPtr loaded by a - # GETFIELD_RAW from the array 'gcrefs.list'. - gcrefs = self.assembler.gcrefs - if gcrefs is None: - return - single_gcref_descr = self.assembler.single_gcref_descr - newops = [] - for op in operations: - if op.opnum == rop.DEBUG_MERGE_POINT: - continue - for i in range(len(op.args)): - v = op.args[i] - if (isinstance(v, ConstPtr) and v.value - and rgc.can_move(v.value)): - box = BoxPtr(v.value) - addr = gcrefs.get_address_of_gcref(v.value) - addr = rffi.cast(lltype.Signed, addr) - newops.append(ResOperation(rop.GETFIELD_RAW, - [ConstInt(addr)], box, - single_gcref_descr)) - op.args[i] = box - if op.is_guard(): - self._rewrite_const_ptrs(op.suboperations) - newops.append(op) - del operations[:] - operations.extend(newops) - def _compute_vars_longevity(self, inputargs, operations): # compute a dictionary that maps variables to index in # operations that is a "last-time-seen" @@ -725,31 +694,18 @@ consider_call_pure = consider_call - def consider_cond_call(self, op, ignored): - calldescr = op.descr - assert isinstance(calldescr, BaseCallDescr) - v_cond = op.args[0] - v_mask = op.args[1] - v_value_if_false = op.args[2] - if op.result is not None: - resloc = self.force_result_in_reg(op.result, v_value_if_false, []) - else: - resloc = None - condloc = self.loc(v_cond) - arglocs = [resloc] + [self.loc(arg) for arg in op.args[3:]] + def consider_cond_call_gc_wb(self, op, ignored): + assert op.result is None + arglocs = [self.loc(arg) for arg in op.args] # add eax, ecx and edx as extra "arguments" to ensure they are - # saved and restored. Don't add them if they are equal to resloc! + # saved and restored. for v, reg in self.reg_bindings.items(): if ((reg is eax or reg is ecx or reg is edx) and self.longevity[v][1] > self.position - and reg not in arglocs): + and reg not in arglocs[3:]): arglocs.append(reg) - size = calldescr.get_result_size(self.translate_support_code) - self.Perform(op, - [imm(size), condloc, convert_to_imm(v_mask)] + arglocs, - resloc) - self.eventually_free_var(v_cond) - self.eventually_free_vars(op.args[3:]) + self.PerformDiscard(op, arglocs) + self.eventually_free_vars(op.args) def consider_new(self, op, ignored): args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr) @@ -841,7 +797,7 @@ ptr = fielddescr.is_pointer_field() return imm(ofs), imm(size), ptr - def _common_consider_setfield(self, op, ignored, raw): + def consider_setfield_gc(self, op, ignored): ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) assert isinstance(size_loc, IMM32) if size_loc.value == 1: @@ -851,20 +807,10 @@ base_loc = self.make_sure_var_in_reg(op.args[0], op.args) value_loc = self.make_sure_var_in_reg(op.args[1], op.args, need_lower_byte=need_lower_byte) - if ptr: - if raw: - print "Setfield of raw structure with gc pointer" - assert False - gc_ll_descr = self.assembler.cpu.gc_ll_descr - gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) self.eventually_free_vars(op.args) self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc]) - def consider_setfield_gc(self, op, ignored): - self._common_consider_setfield(op, ignored, raw=False) - - def consider_setfield_raw(self, op, ignored): - self._common_consider_setfield(op, ignored, raw=True) + consider_setfield_raw = consider_setfield_gc def consider_strsetitem(self, op, ignored): base_loc = self.make_sure_var_in_reg(op.args[0], op.args) @@ -886,13 +832,12 @@ value_loc = self.make_sure_var_in_reg(op.args[2], op.args, need_lower_byte=need_lower_byte) ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args) - if ptr: - gc_ll_descr = self.assembler.cpu.gc_ll_descr - gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc) self.eventually_free_vars(op.args) self.PerformDiscard(op, [base_loc, ofs_loc, value_loc, imm(scale), imm(ofs)]) + consider_setarrayitem_raw = consider_setarrayitem_gc + def consider_getfield_gc(self, op, ignored): ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) @@ -952,7 +897,9 @@ consider_unicodelen = consider_strlen def consider_arraylen_gc(self, op, ignored): - _, ofs, _ = self._unpack_arraydescr(op.descr) + arraydescr = op.descr + assert isinstance(arraydescr, BaseArrayDescr) + ofs = arraydescr.get_ofs_length(self.translate_support_code) base_loc = self.make_sure_var_in_reg(op.args[0], op.args) self.eventually_free_vars(op.args) result_loc = self.force_allocate_reg(op.result, []) From arigo at codespeak.net Mon Aug 31 14:49:25 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 14:49:25 +0200 (CEST) Subject: [pypy-svn] r67357 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport llsupport/test x86 x86/test Message-ID: <20090831124925.A311C168022@codespeak.net> Author: arigo Date: Mon Aug 31 14:49:25 2009 New Revision: 67357 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_regalloc.py Log: Small changes. The x86 tests pass up to 'y'; now trying the 'z' tests... Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Mon Aug 31 14:49:25 2009 @@ -21,6 +21,8 @@ self.gcdescr = gcdescr def _freeze_(self): return True + def initialize(self): + pass def do_write_barrier(self, gcref_struct, gcref_newptr): pass def rewrite_assembler(self, cpu, operations): @@ -275,7 +277,6 @@ assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 - self.gcrefs = None # we need the hybrid GC for GcRefList.alloc_gcref_list() to work if gcdescr.config.translation.gc != 'hybrid': @@ -359,6 +360,9 @@ self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType( [lltype.Signed], llmemory.GCREF)) + def initialize(self): + self.gcrefs = GcRefList() + def init_size_descr(self, S, descr): from pypy.rpython.memory.gctypelayout import weakpointer_offset type_id = self.layoutbuilder.get_type_id(S) @@ -443,8 +447,6 @@ # replace direct usage of ConstPtr with a BoxPtr loaded by a # GETFIELD_RAW from the array 'gcrefs.list'. # - if self.gcrefs is None: - self.gcrefs = GcRefList() newops = [] for op in operations: if op.opnum == rop.DEBUG_MERGE_POINT: Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Mon Aug 31 14:49:25 2009 @@ -148,6 +148,7 @@ translator = FakeTranslator() llop1 = FakeLLOp() gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + gc_ll_descr.initialize() self.llop1 = llop1 self.gc_ll_descr = gc_ll_descr self.fake_cpu = FakeCPU() @@ -234,6 +235,14 @@ assert newops[1].descr == gc_ll_descr.calldescr_jit_wb assert newops[1].result is None + def test_get_rid_of_debug_merge_point(self): + operations = [ + ResOperation(rop.DEBUG_MERGE_POINT, [], None), + ] + gc_ll_descr = self.gc_ll_descr + gc_ll_descr.rewrite_assembler(None, operations) + assert len(operations) == 0 + def test_rewrite_assembler_1(self): # check rewriting of ConstPtrs class MyFakeCPU: Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Mon Aug 31 14:49:25 2009 @@ -128,6 +128,7 @@ self._exception_bck) # the address of the function called by 'new' gc_ll_descr = self.cpu.gc_ll_descr + gc_ll_descr.initialize() ll_new = gc_ll_descr.get_funcptr_for_new() self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new) if gc_ll_descr.get_funcptr_for_newarray is not None: @@ -143,8 +144,6 @@ self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) self.gcrootmap = gc_ll_descr.gcrootmap - if self.gcrootmap: - self.gcrootmap.initialize() # done self.mc2 = self.mcstack.next_mc() self.mc = self.mcstack.next_mc() Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Mon Aug 31 14:49:25 2009 @@ -59,8 +59,8 @@ self.assembler = assembler self.translate_support_code = translate_support_code if regalloc is None: - gc_ll_descr = self.assembler.cpu.gc_ll_descr - gc_ll_descr.rewrite_assembler(self, tree.operations) + cpu = self.assembler.cpu + cpu.gc_ll_descr.rewrite_assembler(cpu, tree.operations) self.tree = tree self.reg_bindings = newcheckdict() self.stack_bindings = newcheckdict() Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_regalloc.py Mon Aug 31 14:49:25 2009 @@ -5,6 +5,7 @@ from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ BoxPtr, ConstPtr, TreeLoop from pypy.jit.metainterp.resoperation import rop, ResOperation +from pypy.jit.backend.llsupport.descr import GcCache from pypy.jit.backend.x86.runner import CPU from pypy.jit.backend.x86.regalloc import RegAlloc, REGS, WORD from pypy.jit.metainterp.test.oparser import parse @@ -20,11 +21,14 @@ class MockAssembler(object): gcrefs = None - def __init__(self): + def __init__(self, cpu=None): self.loads = [] self.stores = [] self.performs = [] self.lea = [] + self.cpu = cpu or CPU(None, None) + if not hasattr(self.cpu, 'gc_ll_descr'): + self.cpu.gc_ll_descr = MockGcDescr(False) def dump(self, *args): pass @@ -44,6 +48,26 @@ def load_effective_addr(self, *args): self.lea.append(args) +class GcRootMap(object): + def initialize(self): + pass + +class MockGcDescr(GcCache): + def get_funcptr_for_new(self): + return 123 + get_funcptr_for_newarray = get_funcptr_for_new + get_funcptr_for_newstr = get_funcptr_for_new + get_funcptr_for_newunicode = get_funcptr_for_new + + moving_gc = True + gcrootmap = GcRootMap() + + def initialize(self): + pass + def rewrite_assembler(self, cpu, operations): + pass + + class RegAllocForTests(RegAlloc): position = 0 def _compute_next_usage(self, v, _): @@ -101,7 +125,7 @@ def test_registers_around_call(self): cpu = CPU(None, None) - regalloc = RegAlloc(MockAssembler(), DummyTree()) + regalloc = RegAlloc(MockAssembler(cpu), DummyTree()) boxes = self.fill_regs(regalloc) TP = lltype.FuncType([], lltype.Void) calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT) @@ -117,8 +141,7 @@ def test_registers_around_newstr(self): cpu = CPU(None, None) - regalloc = RegAllocForTests(MockAssembler(), DummyTree()) - regalloc.assembler.cpu = cpu + regalloc = RegAllocForTests(MockAssembler(cpu), DummyTree()) boxes = self.fill_regs(regalloc) regalloc._check_invariants() for box in boxes: @@ -522,42 +545,10 @@ assert s[1] == 'a' -class GcRootMap(object): - def initialize(self): - pass - -class MockGcDescr(object): - def get_funcptr_for_new(self): - return 123 - get_funcptr_for_newarray = get_funcptr_for_new - get_funcptr_for_newstr = get_funcptr_for_new - get_funcptr_for_newunicode = get_funcptr_for_new - - moving_gc = True - class GcRefList(object): - MAXLEN = 1000 - - def __init__(self): - TP = rffi.CArray(llmemory.GCREF) - self.l = lltype.malloc(TP, self.MAXLEN, flavor='raw') - self.size = 0 - - def get_address_of_gcref(self, addr): - baseaddr = rffi.cast(lltype.Signed, self.l) - for i in range(self.size): - if self.l[i] == addr: - return baseaddr + i * WORD - self.l[self.size] = addr - self.size += 1 - return baseaddr + (self.size - 1) * WORD - - gcrootmap = GcRootMap() - class TestRegallocGc(BaseTestRegalloc): cpu = CPU(None, None) - cpu.gc_ll_descr = MockGcDescr() - cpu.gcrefs = cpu.gc_ll_descr.GcRefList() - + cpu.gc_ll_descr = MockGcDescr(False) + S = lltype.GcForwardReference() S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), ('int', lltype.Signed))) @@ -604,15 +595,6 @@ self.interpret(ops, [0]) assert not self.getptr(0, lltype.Ptr(self.S)) - def test_get_rid_of_debug_merge_point(self): - ops = ''' - [] - debug_merge_point() - fail() - ''' - loop = self.interpret(ops, [], run=False) - assert len(loop.operations) == 1 - def test_bug_0(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8] From pedronis at codespeak.net Mon Aug 31 15:15:53 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 15:15:53 +0200 (CEST) Subject: [pypy-svn] r67358 - in pypy/branch/newtrunk/pypy: . config/test doc/jit interpreter interpreter/test lib module/__builtin__ module/__builtin__/test module/_weakref/test module/mmap/test module/posix module/sys objspace/std objspace/std/test rlib rlib/rsre rlib/rsre/test rpython/lltypesystem rpython/lltypesystem/test rpython/memory/gc rpython/test rpython/tool/test tool/test translator translator/c translator/c/test translator/cli/src translator/goal translator/jvm translator/platform translator/platform/test translator/test Message-ID: <20090831131553.27923168022@codespeak.net> Author: pedronis Date: Mon Aug 31 15:15:51 2009 New Revision: 67358 Added: pypy/branch/newtrunk/pypy/tool/test/test_license.py - copied unchanged from r66700, pypy/trunk/pypy/tool/test/test_license.py Modified: pypy/branch/newtrunk/pypy/ (props changed) pypy/branch/newtrunk/pypy/config/test/test_makerestdoc.py pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt pypy/branch/newtrunk/pypy/interpreter/generator.py pypy/branch/newtrunk/pypy/interpreter/pyframe.py pypy/branch/newtrunk/pypy/interpreter/test/test_objspace.py pypy/branch/newtrunk/pypy/lib/_marshal.py pypy/branch/newtrunk/pypy/module/__builtin__/functional.py pypy/branch/newtrunk/pypy/module/__builtin__/test/test_classobj.py pypy/branch/newtrunk/pypy/module/__builtin__/test/test_functional.py pypy/branch/newtrunk/pypy/module/__builtin__/test/test_range.py pypy/branch/newtrunk/pypy/module/_weakref/test/test_weakref.py pypy/branch/newtrunk/pypy/module/mmap/test/test_mmap.py pypy/branch/newtrunk/pypy/module/posix/__init__.py pypy/branch/newtrunk/pypy/module/sys/version.py pypy/branch/newtrunk/pypy/objspace/std/dictmultiobject.py pypy/branch/newtrunk/pypy/objspace/std/dictobject.py pypy/branch/newtrunk/pypy/objspace/std/test/test_dictmultiobject.py pypy/branch/newtrunk/pypy/objspace/std/test/test_dictobject.py pypy/branch/newtrunk/pypy/objspace/std/test/test_shadowtracking.py pypy/branch/newtrunk/pypy/objspace/std/test/test_stringobject.py pypy/branch/newtrunk/pypy/objspace/std/test/test_typeobject.py pypy/branch/newtrunk/pypy/objspace/std/typeobject.py pypy/branch/newtrunk/pypy/rlib/rarithmetic.py pypy/branch/newtrunk/pypy/rlib/rsre/rsre.py pypy/branch/newtrunk/pypy/rlib/rsre/test/test_rsre.py pypy/branch/newtrunk/pypy/rlib/streamio.py pypy/branch/newtrunk/pypy/rpython/lltypesystem/ll2ctypes.py pypy/branch/newtrunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py pypy/branch/newtrunk/pypy/rpython/memory/gc/semispace.py pypy/branch/newtrunk/pypy/rpython/test/test_rfloat.py pypy/branch/newtrunk/pypy/rpython/tool/test/test_rffi_platform.py pypy/branch/newtrunk/pypy/translator/c/dlltool.py pypy/branch/newtrunk/pypy/translator/c/genc.py pypy/branch/newtrunk/pypy/translator/c/node.py pypy/branch/newtrunk/pypy/translator/c/test/test_dlltool.py pypy/branch/newtrunk/pypy/translator/c/test/test_genc.py pypy/branch/newtrunk/pypy/translator/c/test/test_standalone.py pypy/branch/newtrunk/pypy/translator/cli/src/ll_os.cs pypy/branch/newtrunk/pypy/translator/geninterplevel.py pypy/branch/newtrunk/pypy/translator/goal/sharedpypy.py pypy/branch/newtrunk/pypy/translator/goal/targetpypystandalone.py pypy/branch/newtrunk/pypy/translator/jvm/genjvm.py pypy/branch/newtrunk/pypy/translator/platform/__init__.py pypy/branch/newtrunk/pypy/translator/platform/darwin.py pypy/branch/newtrunk/pypy/translator/platform/linux.py pypy/branch/newtrunk/pypy/translator/platform/test/test_maemo.py pypy/branch/newtrunk/pypy/translator/platform/test/test_platform.py pypy/branch/newtrunk/pypy/translator/platform/windows.py pypy/branch/newtrunk/pypy/translator/test/snippet.py pypy/branch/newtrunk/pypy/translator/test/test_geninterp.py Log: (iko, pedronis) wip: state before new compiler merge Modified: pypy/branch/newtrunk/pypy/config/test/test_makerestdoc.py ============================================================================== --- pypy/branch/newtrunk/pypy/config/test/test_makerestdoc.py (original) +++ pypy/branch/newtrunk/pypy/config/test/test_makerestdoc.py Mon Aug 31 15:15:51 2009 @@ -5,6 +5,11 @@ tempdir = py.test.ensuretemp('config') +try: + import docutils +except ImportError: + py.test.skip("don't have docutils") + def checkrest(rest, filename): tempfile = tempdir.join(filename) tempfile.write(rest) Modified: pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt Mon Aug 31 15:15:51 2009 @@ -19,3 +19,5 @@ * http://morepypy.blogspot.com/2009/04/roadmap-for-jit.html * http://morepypy.blogspot.com/2009/04/4-weeks-of-gdb.html * http://morepypy.blogspot.com/2009/05/icooolps-submissions.html +* http://morepypy.blogspot.com/2009/06/news-from-jit-front.html +* http://morepypy.blogspot.com/2009/06/jit-progress.html Modified: pypy/branch/newtrunk/pypy/interpreter/generator.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/generator.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/generator.py Mon Aug 31 15:15:51 2009 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import NoneNotWrapped from pypy.rlib.rarithmetic import intmask +from pypy.interpreter.pyopcode import LoopBlock class GeneratorIterator(Wrappable): @@ -122,8 +123,12 @@ applevel __del__, which is called at a safe point after the interp-level __del__ enqueued the object for destruction """ - self.descr_close() + # Only bother raising an exception if the frame is still not + # finished and finally or except blocks are present. + if not self.frame.frame_finished_execution: + for block in self.frame.blockstack: + if not isinstance(block, LoopBlock): + self.descr_close() def __del__(self): - if not self.frame.frame_finished_execution: - self._enqueue_for_destruction(self.space) + self._enqueue_for_destruction(self.space) Modified: pypy/branch/newtrunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyframe.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyframe.py Mon Aug 31 15:15:51 2009 @@ -23,7 +23,7 @@ """Represents a frame for a regular Python function that needs to be interpreted. - See also pyopcode.PyStandardFrame and pynestedscope.PyNestedScopeFrame. + See also pyopcode.PyStandardFrame and nestedscope.PyNestedScopeFrame. Public fields: * 'space' is the object space this frame is running in Modified: pypy/branch/newtrunk/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/test/test_objspace.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/test/test_objspace.py Mon Aug 31 15:15:51 2009 @@ -8,6 +8,10 @@ # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* + +INT32_MAX = 2147483648 + + class TestObjSpace: def test_newlist(self): w = self.space.wrap @@ -154,9 +158,9 @@ res = space.r_longlong_w(w_value) assert res == 12 assert type(res) is r_longlong - w_value = space.wrap(r_longlong(-sys.maxint * 42)) + w_value = space.wrap(r_longlong(-INT32_MAX * 42)) res = space.r_longlong_w(w_value) - assert res == -sys.maxint * 42 + assert res == -INT32_MAX * 42 assert type(res) is r_longlong w_obj = space.wrap("hello world") space.raises_w(space.w_TypeError, space.r_longlong_w, w_obj) @@ -169,9 +173,9 @@ res = space.r_ulonglong_w(w_value) assert res == 12 assert type(res) is r_ulonglong - w_value = space.wrap(r_ulonglong(sys.maxint * 42)) + w_value = space.wrap(r_ulonglong(INT32_MAX * 42)) res = space.r_ulonglong_w(w_value) - assert res == sys.maxint * 42 + assert res == INT32_MAX * 42 assert type(res) is r_ulonglong w_obj = space.wrap("hello world") space.raises_w(space.w_TypeError, space.r_ulonglong_w, w_obj) Modified: pypy/branch/newtrunk/pypy/lib/_marshal.py ============================================================================== --- pypy/branch/newtrunk/pypy/lib/_marshal.py (original) +++ pypy/branch/newtrunk/pypy/lib/_marshal.py Mon Aug 31 15:15:51 2009 @@ -6,11 +6,6 @@ import types from _codecs import utf_8_decode, utf_8_encode -try: - import new -except ImportError: - new = None - TYPE_NULL = '0' TYPE_NONE = 'N' TYPE_FALSE = 'F' @@ -409,11 +404,9 @@ name = self.load() firstlineno = self.r_long() lnotab = self.load() - if not new: - raise RuntimeError, "can't unmarshal code objects; no 'new' module" - return new.code(argcount, nlocals, stacksize, flags, code, consts, - names, varnames, filename, name, firstlineno, lnotab, - freevars, cellvars) + return types.CodeType(argcount, nlocals, stacksize, flags, code, consts, + names, varnames, filename, name, firstlineno, + lnotab, freevars, cellvars) dispatch[TYPE_CODE] = load_code def load_set(self): @@ -627,11 +620,9 @@ name = self.load() firstlineno = _r_long(self) lnotab = self.load() - if not new: - raise RuntimeError, "can't unmarshal code objects; no 'new' module" - return new.code(argcount, nlocals, stacksize, flags, code, consts, - names, varnames, filename, name, firstlineno, lnotab, - freevars, cellvars) + return types.CodeType(argcount, nlocals, stacksize, flags, code, consts, + names, varnames, filename, name, firstlineno, + lnotab, freevars, cellvars) dispatch[TYPE_CODE] = load_code def load_set(self): @@ -650,17 +641,6 @@ # _________________________________________________________________ # -# compatibility - -try: - set -except NameError: - def set(x): - raise ValueError("cannot unmarshal set objects on Python < 2.4") - frozenset = set - -# _________________________________________________________________ -# # user interface version = 1 Modified: pypy/branch/newtrunk/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/functional.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/functional.py Mon Aug 31 15:15:51 2009 @@ -61,33 +61,27 @@ get a list in decending order.""" try: - # save duplication by redirecting every error to applevel - x = space.int_w(w_x) + x = space.int_w(space.int(w_x)) if space.is_w(w_y, space.w_None): start, stop = 0, x else: - start, stop = x, space.int_w(w_y) - step = space.int_w(w_step) + start, stop = x, space.int_w(space.int(w_y)) + step = space.int_w(space.int(w_step)) howmany = get_len_of_range(start, stop, step) - except OperationError, e: - if not e.match(space, space.w_TypeError): - pass - else: - raise - except (ValueError, OverflowError): - pass - else: - if (space.config.objspace.std.withmultilist or - space.config.objspace.std.withrangelist): - return range_withspecialized_implementation(space, start, - step, howmany) - res_w = [None] * howmany - v = start - for idx in range(howmany): - res_w[idx] = space.wrap(v) - v += step - return space.newlist(res_w) - return range_fallback(space, w_x, w_y, w_step) + except (ValueError, OverflowError, OperationError): + # save duplication by redirecting every error to applevel + return range_fallback(space, w_x, w_y, w_step) + + if (space.config.objspace.std.withmultilist or + space.config.objspace.std.withrangelist): + return range_withspecialized_implementation(space, start, + step, howmany) + res_w = [None] * howmany + v = start + for idx in range(howmany): + res_w[idx] = space.wrap(v) + v += step + return space.newlist(res_w) range_int = range range_int.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] del range # don't hide the builtin one @@ -207,7 +201,7 @@ def _toint(space, w_obj): # trying to support float arguments, just because CPython still does try: - return space.int_w(w_obj) + return space.int_w(space.int(w_obj)) except OperationError, e: if space.is_true(space.isinstance(w_obj, space.w_float)): return space.int_w(space.int(w_obj)) Modified: pypy/branch/newtrunk/pypy/module/__builtin__/test/test_classobj.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/test/test_classobj.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/test/test_classobj.py Mon Aug 31 15:15:51 2009 @@ -505,6 +505,7 @@ raises(TypeError, cmp, a, b) def test_hash(self): + import sys class A: pass hash(A()) # does not crash @@ -528,11 +529,12 @@ return 1 a = A() raises(TypeError, hash, a) + bigint = sys.maxint + 1 class A: # can return long def __hash__(self): - return long(2**31) + return long(bigint) a = A() - assert hash(a) == -2147483648 + assert hash(a) == -bigint def test_index(self): import sys Modified: pypy/branch/newtrunk/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/test/test_functional.py Mon Aug 31 15:15:51 2009 @@ -117,6 +117,25 @@ # test again, to make sure that xrange() is not its own iterator assert iter(x).next() == 2 + def test_xrange_object_with___int__(self): + class A(object): + def __int__(self): + return 5 + + assert list(xrange(A())) == [0, 1, 2, 3, 4] + assert list(xrange(0, A())) == [0, 1, 2, 3, 4] + assert list(xrange(0, 10, A())) == [0, 5] + + def test_xrange_float(self): + assert list(xrange(0.1, 2.0, 1.1)) == [0, 1] + + def test_xrange_long(self): + import sys + a = long(10 * sys.maxint) + raises(OverflowError, xrange, a) + raises(OverflowError, xrange, 0, a) + raises(OverflowError, xrange, 0, 1, a) + class AppTestReversed: def test_reversed(self): r = reversed("hello") Modified: pypy/branch/newtrunk/pypy/module/__builtin__/test/test_range.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/test/test_range.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/test/test_range.py Mon Aug 31 15:15:51 2009 @@ -17,7 +17,6 @@ def test_range_negstartisstop(self): assert range(-1, -1) == [] - def test_range_zero(self): assert range(0) == [] @@ -60,10 +59,34 @@ def test_range_zerostep(self): raises(ValueError, range, 1, 5, 0) - def DONT_test_range_float(self): - "How CPython does it - UGLY, ignored for now." + def test_range_float(self): + "How CPython does it - UGLY." assert range(0.1, 2.0, 1.1) == [0, 1] def test_range_wrong_type(self): raises(TypeError, range, "42") + def test_range_object_with___int__(self): + class A(object): + def __int__(self): + return 5 + + assert range(A()) == [0, 1, 2, 3, 4] + assert range(0, A()) == [0, 1, 2, 3, 4] + assert range(0, 10, A()) == [0, 5] + + def test_range_long(self): + import sys + assert range(-2**100) == [] + assert range(0, -2**100) == [] + assert range(0, 2**100, -1) == [] + assert range(0, 2**100, -1) == [] + + a = long(10 * sys.maxint) + b = long(100 * sys.maxint) + c = long(50 * sys.maxint) + + assert range(a, a+2) == [a, a+1] + assert range(a+2, a, -1L) == [a+2, a+1] + assert range(a+4, a, -2) == [a+4, a+2] + Modified: pypy/branch/newtrunk/pypy/module/_weakref/test/test_weakref.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/_weakref/test/test_weakref.py (original) +++ pypy/branch/newtrunk/pypy/module/_weakref/test/test_weakref.py Mon Aug 31 15:15:51 2009 @@ -231,6 +231,12 @@ del g gc.collect() assert w() is None + g = f(10) + w = _weakref.ref(g) + assert list(g) == range(10) + del g + gc.collect() + assert w() is None def test_weakref_subclass_with_del(self): import _weakref, gc Modified: pypy/branch/newtrunk/pypy/module/mmap/test/test_mmap.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/mmap/test/test_mmap.py (original) +++ pypy/branch/newtrunk/pypy/module/mmap/test/test_mmap.py Mon Aug 31 15:15:51 2009 @@ -42,7 +42,7 @@ raises(TypeError, mmap, 0, 1, 2, 3, 4, 5) raises(TypeError, mmap, 0, 1, 2, 3, "foo", 5) raises(TypeError, mmap, 0, 1, foo="foo") - raises(TypeError, mmap, 0, -1) + raises((TypeError, OverflowError), mmap, 0, -1) raises(OverflowError, mmap, 0, sys.maxint ** 3) raises(ValueError, mmap, 0, 1, flags=2, access=3) raises(ValueError, mmap, 0, 1, access=123) @@ -410,7 +410,7 @@ def fn(m): m *= 1 # but it raises((SystemError, TypeError), fn, m) # doesn't def fn(): 1 * m # make much sense - raises(TypeError, fn) + raises((SystemError, TypeError), fn) m.close() f.close() # Modified: pypy/branch/newtrunk/pypy/module/posix/__init__.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/posix/__init__.py (original) +++ pypy/branch/newtrunk/pypy/module/posix/__init__.py Mon Aug 31 15:15:51 2009 @@ -120,6 +120,14 @@ if hasattr(os, name): interpleveldefs[name] = 'interp_posix.' + name + def __init__(self, space, w_name): + backend = space.config.translation.backend + # the Win32 urandom implementation isn't going to translate on JVM or CLI + # so we have to remove it + if backend == 'cli' or backend == 'jvm': + del self.interpleveldefs['urandom'] + MixedModule.__init__(self, space, w_name) + def startup(self, space): from pypy.module.posix import interp_posix interp_posix.get(space).startup(space) Modified: pypy/branch/newtrunk/pypy/module/sys/version.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/sys/version.py (original) +++ pypy/branch/newtrunk/pypy/module/sys/version.py Mon Aug 31 15:15:51 2009 @@ -11,9 +11,9 @@ # the last item is replaced by the svn revision ^^^ TRIM_URL_UP_TO = 'svn/pypy/' -SVN_URL = "$HeadURL$"[10:-28] +SVN_URL = """$HeadURL$"""[10:-28] -REV = "$LastChangedRevision$"[22:-2] +REV = """$LastChangedRevision$"""[22:-2] import pypy Modified: pypy/branch/newtrunk/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/dictmultiobject.py Mon Aug 31 15:15:51 2009 @@ -1052,6 +1052,7 @@ w_self.implementation = SharedDictImplementation(space) else: w_self.implementation = space.emptydictimpl + w_self.space = space def initialize_content(w_self, list_pairs_w): impl = w_self.implementation @@ -1059,6 +1060,11 @@ impl = impl.setitem(w_k, w_v) w_self.implementation = impl + def initialize_from_strdict_shared(w_self, strdict): + impl = StrDictImplementation(w_self.space) + impl.content = strdict + w_self.implementation = impl + def __repr__(w_self): """ representation for debugging purposes """ return "%s(%s)" % (w_self.__class__.__name__, w_self.implementation) Modified: pypy/branch/newtrunk/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/dictobject.py Mon Aug 31 15:15:51 2009 @@ -13,11 +13,18 @@ w_self.content = r_dict(space.eq_w, space.hash_w) else: w_self.content = w_otherdict.content.copy() + w_self.space = space def initialize_content(w_self, list_pairs_w): for w_k, w_v in list_pairs_w: w_self.content[w_k] = w_v + def initialize_from_strdict_shared(w_self, strdict): + # XXX the stuff below is slightly broken, as the dict is not really shared + # this would be very very annoying to fix with non-multidicts + for key, w_value in strdict.items(): + w_self.content[w_self.space.wrap(key)] = w_value + def __repr__(w_self): """ representation for debugging purposes """ return "%s(%s)" % (w_self.__class__.__name__, w_self.content) Modified: pypy/branch/newtrunk/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/test/test_dictmultiobject.py Mon Aug 31 15:15:51 2009 @@ -12,6 +12,17 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withmultidict": True}) + def test_initialize_from_strdict_really_shared(self): + space = self.space + w = space.wrap + d = {"a": w(1), "b": w(2)} + w_d = space.DictObjectCls(space) + w_d.initialize_from_strdict_shared(d) + assert self.space.eq_w(space.getitem(w_d, w("a")), w(1)) + assert self.space.eq_w(space.getitem(w_d, w("b")), w(2)) + d["c"] = w(41) + assert self.space.eq_w(space.getitem(w_d, w("c")), w(41)) + class AppTest_DictMultiObject(test_dictobject.AppTest_DictObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withmultidict": True}) Modified: pypy/branch/newtrunk/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/test/test_dictobject.py Mon Aug 31 15:15:51 2009 @@ -123,6 +123,16 @@ assert self.space.eq_w(space.call_function(get, w("33")), w(None)) assert self.space.eq_w(space.call_function(get, w("33"), w(44)), w(44)) + def test_initialize_from_strdict_shared(self): + space = self.space + w = space.wrap + d = {"a": w(1), "b": w(2)} + w_d = space.DictObjectCls(space) + w_d.initialize_from_strdict_shared(d) + assert self.space.eq_w(space.getitem(w_d, w("a")), w(1)) + assert self.space.eq_w(space.getitem(w_d, w("b")), w(2)) + + class AppTest_DictObject: Modified: pypy/branch/newtrunk/pypy/objspace/std/test/test_shadowtracking.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/test/test_shadowtracking.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/test/test_shadowtracking.py Mon Aug 31 15:15:51 2009 @@ -210,7 +210,7 @@ for name in names] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): - assert count[0] >= 5 + assert count[0] >= 5, str((name, count)) def test_mutating_bases(self): class C(object): Modified: pypy/branch/newtrunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/test/test_stringobject.py Mon Aug 31 15:15:51 2009 @@ -723,6 +723,9 @@ raises(TypeError, len, iter(iterable)) def test_overflow_replace(self): + import sys + if sys.maxint > 2**31-1: + skip("Wrong platform") x = "A" * (2**16) raises(OverflowError, x.replace, '', x) Modified: pypy/branch/newtrunk/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/test/test_typeobject.py Mon Aug 31 15:15:51 2009 @@ -915,14 +915,19 @@ return 0 raises(TypeError, X) +class AppTestWithMultidictTypes: + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withmultidict": True}) + def test_dictproxy_is_updated(self): - skip("fix me") class A(object): x = 1 d = A.__dict__ assert d["x"] == 1 A.y = 2 assert d["y"] == 2 + assert ("x", 1) in d.items() + assert ("y", 2) in d.items() class AppTestMutableBuiltintypes: Modified: pypy/branch/newtrunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/newtrunk/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/newtrunk/pypy/objspace/std/typeobject.py Mon Aug 31 15:15:51 2009 @@ -256,14 +256,8 @@ if w_self.lazyloaders: w_self._freeze_() # force un-lazification space = w_self.space - dictspec = [] - for key, w_value in w_self.dict_w.items(): - dictspec.append((space.wrap(key), w_value)) - # speed hack: instantiate a dict object cls directly - # NB: cannot use newdict, because that could return something else - # than an instance of DictObjectCls newdic = space.DictObjectCls(space) - newdic.initialize_content(dictspec) + newdic.initialize_from_strdict_shared(w_self.dict_w) return W_DictProxyObject(newdic) def unwrap(w_self, space): Modified: pypy/branch/newtrunk/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/branch/newtrunk/pypy/rlib/rarithmetic.py (original) +++ pypy/branch/newtrunk/pypy/rlib/rarithmetic.py Mon Aug 31 15:15:51 2009 @@ -5,7 +5,7 @@ such that before and after translation semantics are consistent -r_uint an unsigned integer which has not overflow +r_uint an unsigned integer which has no overflow checking. It is always positive and always truncated to the internal machine word size. intmask mask a possibly long value when running on CPython Modified: pypy/branch/newtrunk/pypy/rlib/rsre/rsre.py ============================================================================== --- pypy/branch/newtrunk/pypy/rlib/rsre/rsre.py (original) +++ pypy/branch/newtrunk/pypy/rlib/rsre/rsre.py Mon Aug 31 15:15:51 2009 @@ -12,6 +12,7 @@ rsre_core_filename = rsre_core_filename[:-1] rsre_core_filename = os.path.abspath(rsre_core_filename) del rsre_core +from pypy.rlib.rsre.rsre_char import getlower def insert_sre_methods(locals, name): """A hack that inserts the SRE entry point methods into the 'locals' @@ -58,3 +59,6 @@ def get_char_ord(self, p): return ord(self.string[p]) + + def lower(self, char_ord): + return getlower(char_ord, 0) Modified: pypy/branch/newtrunk/pypy/rlib/rsre/test/test_rsre.py ============================================================================== --- pypy/branch/newtrunk/pypy/rlib/rsre/test/test_rsre.py (original) +++ pypy/branch/newtrunk/pypy/rlib/rsre/test/test_rsre.py Mon Aug 31 15:15:51 2009 @@ -80,6 +80,11 @@ def test_getlower(): assert rsre_char.getlower(ord("A"), 0) == ord("a") +def test_SimpleStringState(): + state = SimpleStringState("A", 0, -1) + assert state.get_char_ord(0) == ord("A") + assert state.lower(state.get_char_ord(0)) == ord("a") + def test_get_byte_array(): if sys.byteorder == "big": if rsre_char.CODESIZE == 2: Modified: pypy/branch/newtrunk/pypy/rlib/streamio.py ============================================================================== --- pypy/branch/newtrunk/pypy/rlib/streamio.py (original) +++ pypy/branch/newtrunk/pypy/rlib/streamio.py Mon Aug 31 15:15:51 2009 @@ -176,6 +176,10 @@ compilation_info=_eci) SetEndOfFile = rffi.llexternal('SetEndOfFile', [rffi.LONG], rwin32.BOOL, compilation_info=_eci) + + # HACK: These implementations are specific to MSVCRT and the C backend. + # When generating on CLI or JVM, these are patched out. + # See PyPyTarget.target() in targetpypystandalone.py def _setfd_binary(fd): _setmode(fd, os.O_BINARY) Modified: pypy/branch/newtrunk/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/newtrunk/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/newtrunk/pypy/rpython/lltypesystem/ll2ctypes.py Mon Aug 31 15:15:51 2009 @@ -19,6 +19,7 @@ from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.annlowlevel import base_ptr_lltype from pypy.rpython import raddress +from pypy.translator.platform import platform def uaddressof(obj): return fixid(ctypes.addressof(obj)) @@ -871,17 +872,16 @@ not_found = [] for libname in libraries: libpath = None + ext = platform.so_ext + prefixes = platform.so_prefixes for dir in eci.library_dirs: - # xxx untested directly, what about 'lib' prefix - if sys.platform == "win32": - tryfile = os.path.join(dir, libname + '.dll') - elif sys.platform == "darwin": - tryfile = os.path.join(dir, libname + '.dylib') - else: - tryfile = os.path.join(dir, libname + '.so') - if os.path.isfile(tryfile): - libpath = tryfile + if libpath: break + for prefix in prefixes: + tryfile = os.path.join(dir, prefix + libname + '.' + ext) + if os.path.isfile(tryfile): + libpath = tryfile + break if not libpath: libpath = ctypes.util.find_library(libname) if not libpath: @@ -890,8 +890,10 @@ libpath = libname if libpath: dllclass = getattr(ctypes, calling_conv + 'dll') - # urgh, cannot pass the flag to dllclass.LoadLibrary - clib = dllclass._dlltype(libpath, ctypes.RTLD_GLOBAL) + # on ie slackware there was need for RTLD_GLOBAL here. + # this breaks a lot of things, since passing RTLD_GLOBAL + # creates symbol conflicts on C level. + clib = dllclass.LoadLibrary(libpath) cfunc = get_on_lib(clib, funcname) if cfunc is not None: break Modified: pypy/branch/newtrunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/branch/newtrunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/branch/newtrunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Mon Aug 31 15:15:51 2009 @@ -15,6 +15,7 @@ from pypy.rpython.test.test_llinterp import interpret from pypy.annotation.annrpython import RPythonAnnotator from pypy.rpython.rtyper import RPythonTyper +from pypy.tool.udir import udir class TestLL2Ctypes(object): @@ -1093,4 +1094,45 @@ assert not (ref2 != ref1) - +class TestPlatform(object): + def test_lib_on_libpaths(self): + from pypy.translator.platform import platform + from pypy.translator.tool.cbuild import ExternalCompilationInfo + + tmpdir = udir.join('lib_on_libppaths') + tmpdir.ensure(dir=1) + c_file = tmpdir.join('c_file.c') + c_file.write('int f(int a, int b) { return (a + b); }') + eci = ExternalCompilationInfo(export_symbols=['f']) + so = platform.compile([c_file], eci, standalone=False) + eci = ExternalCompilationInfo( + libraries = ['c_file'], + library_dirs = [str(so.dirpath())] + ) + f = rffi.llexternal('f', [rffi.INT, rffi.INT], rffi.INT, + compilation_info=eci) + assert f(3, 4) == 7 + + def test_prefix(self): + + if sys.platform != 'linux2': + py.test.skip("Not supported") + + from pypy.translator.platform import platform + from pypy.translator.tool.cbuild import ExternalCompilationInfo + + tmpdir = udir.join('lib_on_libppaths_prefix') + tmpdir.ensure(dir=1) + c_file = tmpdir.join('c_file.c') + c_file.write('int f(int a, int b) { return (a + b); }') + eci = ExternalCompilationInfo() + so = platform.compile([c_file], eci, standalone=False) + sopath = py.path.local(so) + sopath.move(sopath.dirpath().join('libc_file.so')) + eci = ExternalCompilationInfo( + libraries = ['c_file'], + library_dirs = [str(so.dirpath())] + ) + f = rffi.llexternal('f', [rffi.INT, rffi.INT], rffi.INT, + compilation_info=eci) + assert f(3, 4) == 7 Modified: pypy/branch/newtrunk/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/newtrunk/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/newtrunk/pypy/rpython/memory/gc/semispace.py Mon Aug 31 15:15:51 2009 @@ -212,6 +212,11 @@ start_time = 0 # Help the flow space start_usage = 0 # Help the flow space #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing)) + + # Switch the spaces. We copy everything over to the empty space + # (self.fromspace at the beginning of the collection), and clear the old + # one (self.tospace at the beginning). Their purposes will be reversed + # for the next collection. tospace = self.fromspace fromspace = self.tospace self.fromspace = fromspace Modified: pypy/branch/newtrunk/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/branch/newtrunk/pypy/rpython/test/test_rfloat.py (original) +++ pypy/branch/newtrunk/pypy/rpython/test/test_rfloat.py Mon Aug 31 15:15:51 2009 @@ -2,7 +2,7 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.test import snippet from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_singlefloat,\ +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_singlefloat,\ isnan, isinf class TestSnippet(object): @@ -76,12 +76,17 @@ assert res == fn(2.34) def test_longlong_conversion(self): + import sys def fn(f): return r_longlong(f) res = self.interpret(fn, [1.0]) assert res == 1 - assert self.is_of_type(res, r_longlong) + # r_longlong is int on a 64 bit system + if sys.maxint == 2**63 - 1: + assert self.is_of_type(res, int) + else: + assert self.is_of_type(res, r_longlong) res = self.interpret(fn, [2.34]) assert res == fn(2.34) big = float(0x7fffffffffffffff) Modified: pypy/branch/newtrunk/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/branch/newtrunk/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/branch/newtrunk/pypy/rpython/tool/test/test_rffi_platform.py Mon Aug 31 15:15:51 2009 @@ -4,6 +4,7 @@ from pypy.rpython.lltypesystem import rffi from pypy.tool.udir import udir from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.translator.platform import platform def import_ctypes(): try: @@ -234,3 +235,24 @@ a = rffi_platform.memory_alignment() print a assert a % struct.calcsize("P") == 0 + +def test_external_lib(): + # XXX this one seems to be a bit too platform-specific. Check + # how to test it on windows correctly (using so_prefix?) + # and what are alternatives to LD_LIBRARY_PATH + eci = ExternalCompilationInfo() + c_source = """ + int f(int a, int b) + { + return (a + b); + } + """ + tmpdir = udir.join('external_lib').ensure(dir=1) + c_file = tmpdir.join('libc_lib.c') + c_file.write(c_source) + l = platform.compile([c_file], eci, standalone=False) + eci = ExternalCompilationInfo( + libraries = ['c_lib'], + library_dirs = [str(tmpdir)] + ) + rffi_platform.verify_eci(eci) Modified: pypy/branch/newtrunk/pypy/translator/c/dlltool.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/dlltool.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/dlltool.py Mon Aug 31 15:15:51 2009 @@ -6,6 +6,7 @@ class CLibraryBuilder(CBuilder): standalone = False + split = True def __init__(self, *args, **kwds): self.functions = kwds.pop('functions') @@ -35,10 +36,10 @@ return self.so_name class DLLDef(object): - def __init__(self, name, functions=[], policy=None): + def __init__(self, name, functions=[], policy=None, config=None): self.name = name self.functions = functions # [(function, annotation), ...] - self.driver = TranslationDriver() + self.driver = TranslationDriver(config=config) self.driver.setup_library(self, policy=policy) def compile(self): Modified: pypy/branch/newtrunk/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/genc.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/genc.py Mon Aug 31 15:15:51 2009 @@ -101,6 +101,7 @@ c_source_filename = None _compiled = False modulename = None + split = False def __init__(self, translator, entrypoint, config, gcpolicy=None): self.translator = translator @@ -231,7 +232,8 @@ assert not self.config.translation.instrument self.eci, cfile, extra = gen_source(db, modulename, targetdir, self.eci, - defines = defines) + defines = defines, + split=self.split) else: pfname = db.get(pf) if self.config.translation.instrument: @@ -428,9 +430,10 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args=''): + def cmdexec(self, args='', env=None): assert self._compiled - res = self.translator.platform.execute(self.executable_name, args) + res = self.translator.platform.execute(self.executable_name, args, + env=env) if res.returncode != 0: raise Exception("Returned %d" % (res.returncode,)) return res.out @@ -515,7 +518,7 @@ self.path = None self.namespace = NameManager() - def set_strategy(self, path): + def set_strategy(self, path, split=True): all_nodes = list(self.database.globalcontainers()) # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] @@ -526,7 +529,8 @@ else: othernodes.append(node) # for now, only split for stand-alone programs. - if self.database.standalone: + #if self.database.standalone: + if split: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes @@ -817,7 +821,7 @@ files, eci = eci.get_module_files() return eci, filename, sg.getextrafiles() + list(files) -def gen_source(database, modulename, targetdir, eci, defines={}): +def gen_source(database, modulename, targetdir, eci, defines={}, split=False): assert not database.standalone if isinstance(targetdir, str): targetdir = py.path.local(targetdir) @@ -852,7 +856,9 @@ # 2) Implementation of functions and global structures and arrays # sg = SourceGenerator(database, preimplementationlines) - sg.set_strategy(targetdir) + sg.set_strategy(targetdir, split) + if split: + database.prepare_inline_helpers() sg.gen_readable_parts_of_source(f) gen_startupcode(f, database) Modified: pypy/branch/newtrunk/pypy/translator/c/node.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/node.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/node.py Mon Aug 31 15:15:51 2009 @@ -13,6 +13,7 @@ from pypy.rlib.rarithmetic import isinf, isnan from pypy.translator.c import extfunc from pypy.translator.tool.cbuild import ExternalCompilationInfo +from py.builtin import BaseException def needs_gcheader(T): if not isinstance(T, ContainerType): @@ -892,7 +893,7 @@ return 'Py_None' import types, py if isinstance(value, (type, types.ClassType)): - if (issubclass(value, Exception) and + if (issubclass(value, BaseException) and (value.__module__ == 'exceptions' or value is py.magic.AssertionError)): return 'PyExc_' + value.__name__ Modified: pypy/branch/newtrunk/pypy/translator/c/test/test_dlltool.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/test/test_dlltool.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/test/test_dlltool.py Mon Aug 31 15:15:51 2009 @@ -1,6 +1,7 @@ from pypy.translator.c.dlltool import DLLDef from ctypes import CDLL +import py class TestDLLTool(object): def test_basic(self): @@ -15,3 +16,14 @@ dll = CDLL(str(so)) assert dll.f(3) == 3 assert dll.b(10) == 12 + + def test_split_criteria(self): + def f(x): + return x + + def b(x): + return x + 2 + + d = DLLDef('lib', [(f, [int]), (b, [int])]) + so = d.compile() + assert py.path.local(so).dirpath().join('implement.c').check() Modified: pypy/branch/newtrunk/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/test/test_genc.py Mon Aug 31 15:15:51 2009 @@ -12,7 +12,6 @@ from pypy.translator.gensupp import uniquemodulename from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation -from pypy import conftest def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): @@ -24,7 +23,7 @@ # XXX fish t.driver.config.translation.countmallocs = True compiled_fn = t.compile_c() - if conftest.option.view: + if py.test.config.option.view: t.view() malloc_counters = t.driver.cbuilder.get_malloc_counters() def checking_fn(*args, **kwds): @@ -403,6 +402,6 @@ t = Translation(f, [], backend="c") t.annotate() compiled_fn = t.compile_c() - if conftest.option.view: + if py.test.config.option.view: t.view() assert 'pypy_xyz_f' in t.driver.cbuilder.c_source_filename.read() Modified: pypy/branch/newtrunk/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/newtrunk/pypy/translator/c/test/test_standalone.py Mon Aug 31 15:15:51 2009 @@ -77,11 +77,11 @@ cbuilder.compile() counters_fname = udir.join("_counters_") - os.putenv('_INSTRUMENT_COUNTERS', str(counters_fname)) + os.environ['_INSTRUMENT_COUNTERS'] = str(counters_fname) try: data = cbuilder.cmdexec() finally: - os.unsetenv('_INSTRUMENT_COUNTERS') + del os.environ['_INSTRUMENT_COUNTERS'] f = counters_fname.open('rb') counters_data = f.read() Modified: pypy/branch/newtrunk/pypy/translator/cli/src/ll_os.cs ============================================================================== --- pypy/branch/newtrunk/pypy/translator/cli/src/ll_os.cs (original) +++ pypy/branch/newtrunk/pypy/translator/cli/src/ll_os.cs Mon Aug 31 15:15:51 2009 @@ -261,7 +261,8 @@ public static void ll_os_close(int fd) { FileStream stream = getfd(fd).GetStream(); - stream.Close(); + if (stream != null) // stdin/stdout/stderr files don't have a stream + stream.Close(); FileDescriptors.Remove(fd); } Modified: pypy/branch/newtrunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/geninterplevel.py (original) +++ pypy/branch/newtrunk/pypy/translator/geninterplevel.py Mon Aug 31 15:15:51 2009 @@ -982,7 +982,7 @@ globname = self.nameof(self.moddict) self.initcode.append('space.setitem(%s, space.new_interned_str("__builtins__"), ' 'space.builtin.w_dict)' % globname) - self.initcode.append('%s = space.eval("property(%s)", %s, %s. hidden_applevel=True)' %( + self.initcode.append('%s = space.eval("property(%s)", %s, %s, hidden_applevel=True)' %( name, origin, globname, globname) ) self.initcode.append('space.delitem(%s, space.new_interned_str("__builtins__"))' % globname) Modified: pypy/branch/newtrunk/pypy/translator/goal/sharedpypy.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/goal/sharedpypy.py (original) +++ pypy/branch/newtrunk/pypy/translator/goal/sharedpypy.py Mon Aug 31 15:15:51 2009 @@ -1,14 +1,15 @@ -import sys +import sys, pdb, traceback from pypy.translator.c.dlltool import DLLDef from pypy.config.translationoption import get_combined_translation_config -from pypy.rpython.lltypesystem.rffi import charp2str, CCHARP +from pypy.rpython.lltypesystem.rffi import charp2str, CCHARP, VOIDP from pypy.tool.option import make_objspace from pypy.interpreter.error import OperationError from pypy.config.pypyoption import pypy_optiondescription, set_pypy_opt_level from pypy.interpreter.pyopcode import prepare_exec from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy from pypy.config.translationoption import set_opt_level +from pypy.config.pypyoption import enable_allworkingmodules OVERRIDES = { 'translation.debug': False, @@ -22,12 +23,13 @@ config.translating = True set_opt_level(config, '1') set_pypy_opt_level(config, '1') - print config + enable_allworkingmodules(config) space = make_objspace(config) policy = PyPyAnnotatorPolicy(single_space = space) + policy.allow_someobjects = False - def interpret(source): + def interpret(source, context): source = charp2str(source) w_dict = space.newdict() try: @@ -41,8 +43,18 @@ return 1 return 0 - dll = DLLDef('pypylib', [(interpret, [CCHARP])], policy=policy) + dll = DLLDef('pypylib', [(interpret, [CCHARP, VOIDP])], policy=policy, + config=config) exe_name = dll.compile() if __name__ == '__main__': - main(sys.argv) + try: + main(sys.argv) + except KeyboardInterrupt: + raise + except: + e, v, tb = sys.exc_info() + traceback.print_tb(tb) + print e, v + pdb.post_mortem(tb) + Modified: pypy/branch/newtrunk/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/newtrunk/pypy/translator/goal/targetpypystandalone.py Mon Aug 31 15:15:51 2009 @@ -199,6 +199,16 @@ wrapstr = 'space.wrap(%r)' % (options) pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr + if config.translation.backend in ["cli", "jvm"] and sys.platform == "win32": + # HACK: The ftruncate implementation in streamio.py which is used for the Win32 platform + # is specific for the C backend and can't be generated on CLI or JVM. Because of that, + # we have to patch it out. + from pypy.rlib import streamio + def ftruncate_win32_dummy(fd, size): pass + def _setfd_binary_dummy(fd): pass + streamio.ftruncate_win32 = ftruncate_win32_dummy + streamio._setfd_binary = _setfd_binary_dummy + return self.get_entry_point(config) def jitpolicy(self, driver): Modified: pypy/branch/newtrunk/pypy/translator/jvm/genjvm.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/jvm/genjvm.py (original) +++ pypy/branch/newtrunk/pypy/translator/jvm/genjvm.py Mon Aug 31 15:15:51 2009 @@ -3,6 +3,7 @@ """ import sys +import os import py from py.compat import subprocess @@ -197,7 +198,7 @@ cmd = [getoption('java'), '-Xmx256M', # increase the heapsize so the microbenchmarks run '-cp', - str(self.javadir)+":"+str(self.jnajar), + str(self.javadir)+os.pathsep+str(self.jnajar), self.package+".Main"] + strargs print "Invoking java to run the code" stdout, stderr, retval = self._invoke(cmd, True) Modified: pypy/branch/newtrunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/__init__.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/__init__.py Mon Aug 31 15:15:51 2009 @@ -52,6 +52,8 @@ name = "abstract platform" c_environ = None + so_prefixes = [''] + def __init__(self, cc): if self.__class__ is Platform: raise TypeError("You should not instantiate Platform class directly") @@ -70,7 +72,12 @@ ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) return ofiles - def execute(self, executable, args=None, env=None): + def execute(self, executable, args=None, env=None, compilation_info=None): + if env is None: + env = os.environ.copy() + if compilation_info is not None: + env['LD_LIBRARY_PATH'] = ':'.join( + [str(i) for i in compilation_info.library_dirs]) returncode, stdout, stderr = _run_subprocess(str(executable), args, env) return ExecutionResult(returncode, stdout, stderr) @@ -120,7 +127,7 @@ cflags = self.cflags + extra return (cflags + list(eci.compile_extra) + args) - def _link_args_from_eci(self, eci): + def _link_args_from_eci(self, eci, standalone): library_dirs = self._libdirs(eci.library_dirs) libraries = self._libs(eci.libraries) link_files = self._linkfiles(eci.link_files) @@ -141,8 +148,8 @@ cc_link = 'g++' # XXX hard-coded so far else: cc_link = self.cc - return self._link(cc_link, ofiles, self._link_args_from_eci(eci), - standalone, exe_name) + largs = self._link_args_from_eci(eci, standalone) + return self._link(cc_link, ofiles, largs, standalone, exe_name) # below are some detailed informations for platforms Modified: pypy/branch/newtrunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/darwin.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/darwin.py Mon Aug 31 15:15:51 2009 @@ -38,8 +38,8 @@ args.append(f) return args - def _link_args_from_eci(self, eci): - args = super(Darwin, self)._link_args_from_eci(eci) + def _link_args_from_eci(self, eci, standalone): + args = super(Darwin, self)._link_args_from_eci(eci, standalone) frameworks = self._frameworks(eci.frameworks) include_dirs = self._includedirs(eci.include_dirs) return (args + frameworks + include_dirs) Modified: pypy/branch/newtrunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/linux.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/linux.py Mon Aug 31 15:15:51 2009 @@ -13,6 +13,7 @@ standalone_only = [] shared_only = [] so_ext = 'so' + so_prefixes = ['lib', ''] def _args_for_shared(self, args): return ['-shared'] + args Modified: pypy/branch/newtrunk/pypy/translator/platform/test/test_maemo.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/test/test_maemo.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/test/test_maemo.py Mon Aug 31 15:15:51 2009 @@ -31,3 +31,6 @@ executable = self.platform.compile([cfile], eci) res = self.platform.execute(executable) self.check_res(res) + + def test_environment_inheritance(self): + py.test.skip("FIXME") Modified: pypy/branch/newtrunk/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/test/test_platform.py Mon Aug 31 15:15:51 2009 @@ -1,5 +1,5 @@ -import py, sys +import py, sys, ctypes, os from pypy.tool.udir import udir from pypy.translator.platform import CompilationError, Platform from pypy.translator.platform import host @@ -102,6 +102,18 @@ res = self.platform.execute(executable) assert res.out.startswith('4.0') + def test_environment_inheritance(self): + # make sure that environment is inherited + cmd = 'import os; print os.environ["_SOME_VARIABLE_%d"]' + res = self.platform.execute('python', ['-c', cmd % 1], + env={'_SOME_VARIABLE_1':'xyz'}) + assert 'xyz' in res.out + os.environ['_SOME_VARIABLE_2'] = 'zyz' + try: + res = self.platform.execute('python', ['-c', cmd % 2]) + assert 'zyz' in res.out + finally: + del os.environ['_SOME_VARIABLE_2'] def test_equality(): class X(Platform): Modified: pypy/branch/newtrunk/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/platform/windows.py (original) +++ pypy/branch/newtrunk/pypy/translator/platform/windows.py Mon Aug 31 15:15:51 2009 @@ -133,8 +133,9 @@ def _args_for_shared(self, args): return ['/dll'] + args - def _link_args_from_eci(self, eci): - args = super(MsvcPlatform, self)._link_args_from_eci(eci) + def _link_args_from_eci(self, eci, standalone): + # Windows needs to resolve all symbols even for DLLs + args = super(MsvcPlatform, self)._link_args_from_eci(eci, standalone=True) return args + ['/EXPORT:%s' % symbol for symbol in eci.export_symbols] def _compile_c_file(self, cc, cfile, compile_args): Modified: pypy/branch/newtrunk/pypy/translator/test/snippet.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/test/snippet.py (original) +++ pypy/branch/newtrunk/pypy/translator/test/snippet.py Mon Aug 31 15:15:51 2009 @@ -675,7 +675,20 @@ raise Exc(x) except Exception, e: return e.args[0] - + + +class HaveProp(object): + + def __init__(self, v): + self.v = v + + def _hi(self): + return self.v + hi = property(_hi, doc="HaveProp._hi") + + +def run_prop(v): + return HaveProp(v).hi # --------------------(Currently) Non runnable Functions --------------------- Modified: pypy/branch/newtrunk/pypy/translator/test/test_geninterp.py ============================================================================== --- pypy/branch/newtrunk/pypy/translator/test/test_geninterp.py (original) +++ pypy/branch/newtrunk/pypy/translator/test/test_geninterp.py Mon Aug 31 15:15:51 2009 @@ -304,3 +304,7 @@ fn = self.build_interpfunc(snippet.exception_subclass_sanity) result = fn(7) assert result == 7 + + def test_property(self): + fn = self.build_interpfunc(snippet.run_prop) + assert fn(23) == 23 From pedronis at codespeak.net Mon Aug 31 15:16:26 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 15:16:26 +0200 (CEST) Subject: [pypy-svn] r67359 - pypy/branch/newtrunk Message-ID: <20090831131626.2997C168025@codespeak.net> Author: pedronis Date: Mon Aug 31 15:16:25 2009 New Revision: 67359 Modified: pypy/branch/newtrunk/LICENSE Log: (iko, pedronis) this too Modified: pypy/branch/newtrunk/LICENSE ============================================================================== --- pypy/branch/newtrunk/LICENSE (original) +++ pypy/branch/newtrunk/LICENSE Mon Aug 31 15:16:25 2009 @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2007 +PyPy Copyright holders 2003-2009 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at @@ -116,12 +116,12 @@ Change Maker, Sweden -License for 'lib-python/2.4.1' and 'lib-python/2.4.1-modified' +License for 'lib-python/2.5.2' and 'lib-python/2.5.2-modified' ============================================================== Except when otherwise stated (look for LICENSE files or copyright/license information at the beginning of each file) the files -in the 'lib-python/2.4.1' and 'lib-python/2.4.1-modified' directories +in the 'lib-python/2.5.2' and 'lib-python/2.5.2-modified' directories are all copyrighted by the Python Software Foundation and licensed under the Python Software License of which you can find a copy here: http://www.python.org/doc/Copyright.html @@ -134,7 +134,7 @@ http://www.gnu.org/licenses/lgpl.html License for 'pypy/translator/jvm/src/jasmin.jar' -============================================= +================================================ The file 'pypy/translator/jvm/src/jasmin.jar' is copyright (c) 1996-2004 Jon Meyer and distributed with permission. The use of Jasmin by PyPy does not imply From arigo at codespeak.net Mon Aug 31 15:17:20 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 15:17:20 +0200 (CEST) Subject: [pypy-svn] r67360 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport: . test Message-ID: <20090831131720.8EB74168023@codespeak.net> Author: arigo Date: Mon Aug 31 15:17:20 2009 New Revision: 67360 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Log: Fix calldescrs. get_call_descr() failed if we_are_translated. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Mon Aug 31 15:17:20 2009 @@ -82,7 +82,7 @@ def getFieldDescrClass(TYPE): return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr, - NonGcPtrFieldDescr, 'Field') + NonGcPtrFieldDescr, 'Field', 'get_field_size') def get_field_descr(gccache, STRUCT, fieldname): cache = gccache._cache_field @@ -137,7 +137,7 @@ def getArrayDescrClass(ARRAY): return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr, - NonGcPtrArrayDescr, 'Array') + NonGcPtrArrayDescr, 'Array', 'get_item_size') def get_array_descr(gccache, ARRAY): cache = gccache._cache_array @@ -160,6 +160,7 @@ # CallDescrs class BaseCallDescr(AbstractDescr): + _clsname = '' call_loop = None arg_classes = [] # <-- annotation hack @@ -197,22 +198,30 @@ self.call_loop = loop return loop + def repr_of_descr(self): + return '<%s>' % self._clsname -class GcPtrCallDescr(BaseCallDescr): - def returns_a_pointer(self): - return True +class NonGcPtrCallDescr(BaseCallDescr): + _clsname = 'NonGcPtrCallDescr' def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) -class IntCallDescr(BaseCallDescr): - def __init__(self, arg_classes, result_size): - BaseCallDescr.__init__(self, arg_classes) - self.result_size = result_size +class GcPtrCallDescr(NonGcPtrCallDescr): + _clsname = 'GcPtrCallDescr' + def returns_a_pointer(self): + return True +class VoidCallDescr(NonGcPtrCallDescr): + _clsname = 'VoidCallDescr' def get_result_size(self, translate_support_code): - return self.result_size + return 0 +def getCallDescrClass(RESULT): + if RESULT is lltype.Void: + return VoidCallDescr + return getDescrClass(RESULT, BaseCallDescr, GcPtrCallDescr, + NonGcPtrCallDescr, 'Call', 'get_result_size') def get_call_descr(gccache, ARGS, RESULT): arg_classes = [] @@ -222,20 +231,13 @@ elif kind == 'ptr': arg_classes.append(BoxPtr) else: raise NotImplementedError('ARG = %r' % (ARG,)) - if RESULT is lltype.Void: - result_size = 0 - else: - result_size = symbolic.get_size(RESULT, gccache.translate_support_code) - ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc' - key = (tuple(arg_classes), result_size, ptr) + cls = getCallDescrClass(RESULT) + key = (cls, tuple(arg_classes)) cache = gccache._cache_call try: return cache[key] except KeyError: - if ptr: - calldescr = GcPtrCallDescr(arg_classes) - else: - calldescr = IntCallDescr(arg_classes, result_size) + calldescr = cls(arg_classes) cache[key] = calldescr return calldescr @@ -243,7 +245,7 @@ # ____________________________________________________________ def getDescrClass(TYPE, BaseDescr, GcPtrDescr, NonGcPtrDescr, - nameprefix, _cache={}): + nameprefix, methodname, _cache={}): if isinstance(TYPE, lltype.Ptr): if TYPE.TO._gckind == 'gc': return GcPtrDescr @@ -255,10 +257,11 @@ # class Descr(BaseDescr): _clsname = '%s%sDescr' % (TYPE._name, nameprefix) - def get_field_size(self, translate_support_code): - return symbolic.get_size(TYPE, translate_support_code) - get_item_size = get_field_size - # Descr.__name__ = Descr._clsname + # + def method(self, translate_support_code): + return symbolic.get_size(TYPE, translate_support_code) + setattr(Descr, methodname, method) + # _cache[nameprefix, TYPE] = Descr return Descr Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Mon Aug 31 15:17:20 2009 @@ -124,6 +124,12 @@ # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) + # + c1 = GcCache(True) + descr3 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U)) + assert isinstance(descr3.get_result_size(True), Symbolic) + assert descr3.returns_a_pointer() + assert descr3.arg_classes == [BoxPtr] def test_repr_of_descr(): @@ -155,4 +161,4 @@ assert 'GcPtrCallDescr' in descr4.repr_of_descr() # descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char) - assert 'IntCallDescr' in descr4i.repr_of_descr() + assert 'CharCallDescr' in descr4i.repr_of_descr() From pedronis at codespeak.net Mon Aug 31 15:37:21 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 15:37:21 +0200 (CEST) Subject: [pypy-svn] r67361 - in pypy/branch/newtrunk: lib-python lib-python/modified-2.5.2/test pypy pypy/config pypy/doc pypy/doc/config pypy/doc/jit pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/astcompiler/test pypy/interpreter/astcompiler/tools pypy/interpreter/pyparser pypy/interpreter/pyparser/data pypy/interpreter/pyparser/test pypy/interpreter/test pypy/lib pypy/lib/test2 pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/_ast pypy/module/_ast/test pypy/module/dyngram pypy/module/parser pypy/module/parser/test pypy/module/recparser pypy/module/symbol pypy/module/token pypy/module/token/test pypy/objspace/std pypy/objspace/std/test pypy/tool pypy/tool/pytest pypy/tool/pytest/test pypy/translator/goal Message-ID: <20090831133721.4A07A168023@codespeak.net> Author: pedronis Date: Mon Aug 31 15:37:16 2009 New Revision: 67361 Added: pypy/branch/newtrunk/pypy/doc/config/objspace.usemodules._ast.txt - copied unchanged from r67336, pypy/trunk/pypy/doc/config/objspace.usemodules._ast.txt pypy/branch/newtrunk/pypy/doc/config/objspace.usemodules.parser.txt - copied unchanged from r67336, pypy/trunk/pypy/doc/config/objspace.usemodules.parser.txt pypy/branch/newtrunk/pypy/doc/config/objspace.usemodules.token.txt - copied unchanged from r67336, pypy/trunk/pypy/doc/config/objspace.usemodules.token.txt pypy/branch/newtrunk/pypy/interpreter/astcompiler/assemble.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/assemble.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/ast.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/astcompiler/ast.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/astbuilder.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/astbuilder.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/asthelpers.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/codegen.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/codegen.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/optimize.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/optimize.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/symtable.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/symtable.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_astbuilder.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_symtable.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/test/test_symtable.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/ - copied from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/ pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/Python.asdl - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/Python.asdl pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/asdl.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/asdl.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/asdl_py.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/spark.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/spark.py pypy/branch/newtrunk/pypy/interpreter/pyparser/data/Grammar2.5 - copied unchanged from r67336, pypy/trunk/pypy/interpreter/pyparser/data/Grammar2.5 pypy/branch/newtrunk/pypy/interpreter/pyparser/data/Grammar2.5_2 (props changed) - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/data/Grammar2.5_2 pypy/branch/newtrunk/pypy/interpreter/pyparser/metaparser.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/pyparser/metaparser.py pypy/branch/newtrunk/pypy/interpreter/pyparser/parser.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/parser.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pygram.py - copied, changed from r67184, pypy/trunk/pypy/interpreter/pyparser/pygram.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pyparse.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/pyparse.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pytokenizer.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/pytokenizer.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_metaparser.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/test/test_metaparser.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_pyparse.py - copied unchanged from r67184, pypy/trunk/pypy/interpreter/pyparser/test/test_pyparse.py pypy/branch/newtrunk/pypy/module/_ast/ - copied from r67184, pypy/trunk/pypy/module/_ast/ pypy/branch/newtrunk/pypy/module/_ast/__init__.py - copied unchanged from r67184, pypy/trunk/pypy/module/_ast/__init__.py pypy/branch/newtrunk/pypy/module/_ast/test/ - copied from r67184, pypy/trunk/pypy/module/_ast/test/ pypy/branch/newtrunk/pypy/module/_ast/test/__init__.py - copied unchanged from r67184, pypy/trunk/pypy/module/_ast/test/__init__.py pypy/branch/newtrunk/pypy/module/_ast/test/test_ast.py - copied, changed from r67184, pypy/trunk/pypy/module/_ast/test/test_ast.py pypy/branch/newtrunk/pypy/module/parser/ - copied from r67184, pypy/trunk/pypy/module/parser/ pypy/branch/newtrunk/pypy/module/parser/__init__.py - copied unchanged from r67184, pypy/trunk/pypy/module/parser/__init__.py pypy/branch/newtrunk/pypy/module/parser/app_helpers.py - copied unchanged from r67184, pypy/trunk/pypy/module/parser/app_helpers.py pypy/branch/newtrunk/pypy/module/parser/pyparser.py - copied unchanged from r67184, pypy/trunk/pypy/module/parser/pyparser.py pypy/branch/newtrunk/pypy/module/parser/test/ - copied from r67184, pypy/trunk/pypy/module/parser/test/ pypy/branch/newtrunk/pypy/module/parser/test/__init__.py - copied unchanged from r67184, pypy/trunk/pypy/module/parser/test/__init__.py pypy/branch/newtrunk/pypy/module/parser/test/test_parser.py - copied unchanged from r67184, pypy/trunk/pypy/module/parser/test/test_parser.py pypy/branch/newtrunk/pypy/module/token/ - copied from r67184, pypy/trunk/pypy/module/token/ pypy/branch/newtrunk/pypy/module/token/__init__.py - copied unchanged from r67184, pypy/trunk/pypy/module/token/__init__.py pypy/branch/newtrunk/pypy/module/token/test/ - copied from r67184, pypy/trunk/pypy/module/token/test/ pypy/branch/newtrunk/pypy/module/token/test/test_token.py - copied unchanged from r67184, pypy/trunk/pypy/module/token/test/test_token.py pypy/branch/newtrunk/pypy/objspace/std/test/test_viewlist.py (props changed) - copied unchanged from r67184, pypy/trunk/pypy/objspace/std/test/test_viewlist.py pypy/branch/newtrunk/pypy/objspace/std/viewlist.py (props changed) - copied unchanged from r67184, pypy/trunk/pypy/objspace/std/viewlist.py pypy/branch/newtrunk/pypy/tool/pytest/test/test_appsupport.py - copied, changed from r67184, pypy/trunk/pypy/tool/pytest/test/test_appsupport.py Removed: pypy/branch/newtrunk/pypy/doc/config/objspace.usemodules.dyngram.txt pypy/branch/newtrunk/pypy/doc/config/objspace.usemodules.recparser.txt pypy/branch/newtrunk/pypy/interpreter/astcompiler/ast.txt pypy/branch/newtrunk/pypy/interpreter/astcompiler/astgen.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/future.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/opt.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/pyassem.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/pycodegen.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/symbols.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_ast.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/visitor.py pypy/branch/newtrunk/pypy/interpreter/pyparser/astbuilder.py pypy/branch/newtrunk/pypy/interpreter/pyparser/asthelper.py pypy/branch/newtrunk/pypy/interpreter/pyparser/ebnfgrammar.py pypy/branch/newtrunk/pypy/interpreter/pyparser/ebnflexer.py pypy/branch/newtrunk/pypy/interpreter/pyparser/ebnfparse.py pypy/branch/newtrunk/pypy/interpreter/pyparser/grammar.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pythonlexer.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pythonparse.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pythonutil.py pypy/branch/newtrunk/pypy/interpreter/pyparser/symbol.py pypy/branch/newtrunk/pypy/interpreter/pyparser/syntaxtree.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/support.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_lookahead.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_pytokenizer.py pypy/branch/newtrunk/pypy/interpreter/pyparser/tuplebuilder.py pypy/branch/newtrunk/pypy/lib/optimizers.py pypy/branch/newtrunk/pypy/lib/test2/test_optimizers.py pypy/branch/newtrunk/pypy/module/dyngram/ pypy/branch/newtrunk/pypy/module/recparser/ Modified: pypy/branch/newtrunk/lib-python/ (props changed) pypy/branch/newtrunk/lib-python/conftest.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_generators.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_genexps.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_grammar.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_peepholer.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_syntax.py pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_trace.py pypy/branch/newtrunk/pypy/ (props changed) pypy/branch/newtrunk/pypy/config/pypyoption.py pypy/branch/newtrunk/pypy/conftest.py pypy/branch/newtrunk/pypy/doc/_ref.txt pypy/branch/newtrunk/pypy/doc/cpython_differences.txt pypy/branch/newtrunk/pypy/doc/extradoc.txt pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt pypy/branch/newtrunk/pypy/doc/parser.txt pypy/branch/newtrunk/pypy/interpreter/astcompiler/consts.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/misc.py pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_compiler.py pypy/branch/newtrunk/pypy/interpreter/pycompiler.py pypy/branch/newtrunk/pypy/interpreter/pyparser/automata.py pypy/branch/newtrunk/pypy/interpreter/pyparser/error.py pypy/branch/newtrunk/pypy/interpreter/pyparser/future.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pytoken.py pypy/branch/newtrunk/pypy/interpreter/pyparser/pytokenize.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_futureautomaton.py pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_parser.py pypy/branch/newtrunk/pypy/interpreter/test/test_compiler.py pypy/branch/newtrunk/pypy/interpreter/test/test_syntax.py pypy/branch/newtrunk/pypy/module/__builtin__/compiling.py pypy/branch/newtrunk/pypy/module/__builtin__/test/test_builtin.py pypy/branch/newtrunk/pypy/module/symbol/__init__.py pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py pypy/branch/newtrunk/pypy/tool/stdlib_opcode.py pypy/branch/newtrunk/pypy/translator/goal/ (props changed) Log: (iko, pedronis) finished merging 66083-67336 from trunk. Modified: pypy/branch/newtrunk/lib-python/conftest.py ============================================================================== --- pypy/branch/newtrunk/lib-python/conftest.py (original) +++ pypy/branch/newtrunk/lib-python/conftest.py Mon Aug 31 15:37:16 2009 @@ -129,7 +129,7 @@ RegrTest('test__locale.py', skip=skip_win32), RegrTest('test_aepack.py', skip=True), RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', skip="unsupported module _ast"), + RegrTest('test_ast.py', core=True), RegrTest('test_anydbm.py'), RegrTest('test_applesingle.py', skip=True), RegrTest('test_array.py', core=True, usemodules='struct'), Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_generators.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_generators.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_generators.py Mon Aug 31 15:37:16 2009 @@ -1535,17 +1535,17 @@ >>> def f(): x = yield = y Traceback (most recent call last): ... -SyntaxError: assignment to yield expression not possible (, line 1) +SyntaxError: can't assign to yield expression (, line 1) >>> def f(): (yield bar) = y Traceback (most recent call last): ... -SyntaxError: assignment to yield expression not possible (, line 1) +SyntaxError: can't assign to yield expression (, line 1) >>> def f(): (yield bar) += y Traceback (most recent call last): ... -SyntaxError: augmented assignment to yield expression not possible (, line 1) +SyntaxError: can't assign to yield expression (, line 1) Now check some throw() conditions: Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_genexps.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_genexps.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_genexps.py Mon Aug 31 15:37:16 2009 @@ -137,12 +137,12 @@ >>> (y for y in (1,2)) = 10 #doctest: +ELLIPSIS Traceback (most recent call last): ... - SyntaxError: assign to generator expression not possible... + SyntaxError: can't assign to generator expression (, line 1) >>> (y for y in (1,2)) += 10 #doctest: +ELLIPSIS Traceback (most recent call last): ... - SyntaxError: augmented assign to tuple literal or generator expression not possible... + SyntaxError: can't assign to generator expression (, line 1) Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_grammar.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_grammar.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_grammar.py Mon Aug 31 15:37:16 2009 @@ -165,12 +165,7 @@ 'list',)) vereq(f5.func_code.co_varnames, ('(compound, first)', 'two', 'compound', 'first')) -elif check_impl_detail(pypy=True): - vereq(f4.func_code.co_varnames, - ('two', '.2', 'compound', 'argument', 'list')) - vereq(f5.func_code.co_varnames, - ('.0', 'two', 'compound', 'first')) -elif check_impl_detail(cpython=True): +elif check_impl_detail(cpython=True, pypy=True): vereq(f4.func_code.co_varnames, ('two', '.1', 'compound', 'argument', 'list')) vereq(f5.func_code.co_varnames, @@ -185,9 +180,7 @@ # thus, the names nested inside tuples must appear after these names. if check_impl_detail(jython=True): verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c')) -elif check_impl_detail(pypy=True): - vereq(v3.func_code.co_varnames, ('a', '.2', 'rest', 'b', 'c')) -elif check_impl_detail(cpython=True): +elif check_impl_detail(cpython=True, pypy=True): vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) def d01(a=1): pass Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_peepholer.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_peepholer.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_peepholer.py Mon Aug 31 15:37:16 2009 @@ -43,7 +43,7 @@ def test_none_as_constant(self): # LOAD_GLOBAL None --> LOAD_CONST None def f(x): - None + x = None return x asm = disassemble(f) for elem in ('LOAD_GLOBAL',): Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_syntax.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_syntax.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_syntax.py Mon Aug 31 15:37:16 2009 @@ -164,13 +164,13 @@ >>> (x for x in x) += 1 # doctest: +ELLIPSIS Traceback (most recent call last): -SyntaxError: augmented assign...generator expression not possible (, line 1) +SyntaxError: can't assign to generator expression (, line 1) >>> None += 1 # doctest: +ELLIPSIS Traceback (most recent call last): SyntaxError: assignment to None... (, line 1) >>> f() += 1 Traceback (most recent call last): -SyntaxError: illegal expression for augmented assignment (, line 1) +SyntaxError: can't assign to function call (, line 1) Test continue in finally in weird combinations. Modified: pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_trace.py ============================================================================== --- pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_trace.py (original) +++ pypy/branch/newtrunk/lib-python/modified-2.5.2/test/test_trace.py Mon Aug 31 15:37:16 2009 @@ -336,10 +336,11 @@ for_example, [(0, 'call'), (1, 'line'), - (1, 'line'), + (2, 'line'), (1, 'line'), (2, 'line'), - (2, 'return')]) + (1, 'line'), + (1, 'return')]) def while_example(): # While expression should be traced on every loop Modified: pypy/branch/newtrunk/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/newtrunk/pypy/config/pypyoption.py (original) +++ pypy/branch/newtrunk/pypy/config/pypyoption.py Mon Aug 31 15:37:16 2009 @@ -18,7 +18,7 @@ default_modules.update(dict.fromkeys( ["_codecs", "gc", "_weakref", "marshal", "errno", "math", "_sre", "_pickle_support", "operator", - "recparser", "symbol", "_random", "__pypy__"])) + "parser", "symbol", "token", "_ast", "_random", "__pypy__"])) # --allworkingmodules @@ -26,7 +26,7 @@ working_modules.update(dict.fromkeys( ["_socket", "unicodedata", "mmap", "fcntl", "rctime" , "select", "zipimport", "_lsprof", - "crypt", "signal", "dyngram", "_rawffi", "termios", "zlib", + "crypt", "signal", "_rawffi", "termios", "zlib", "struct", "md5", "sha", "bz2", "_minimal_curses", "cStringIO", "thread", "itertools", "pyexpat", "_ssl"] )) Modified: pypy/branch/newtrunk/pypy/conftest.py ============================================================================== --- pypy/branch/newtrunk/pypy/conftest.py (original) +++ pypy/branch/newtrunk/pypy/conftest.py Mon Aug 31 15:37:16 2009 @@ -188,6 +188,7 @@ # Interfacing/Integrating with py.test's collection process # # + def ensure_pytest_builtin_helpers(helpers='skip raises'.split()): """ hack (py.test.) raises and skip into builtins, needed for applevel tests to run directly on cpython but Modified: pypy/branch/newtrunk/pypy/doc/_ref.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/_ref.txt (original) +++ pypy/branch/newtrunk/pypy/doc/_ref.txt Mon Aug 31 15:37:16 2009 @@ -30,6 +30,20 @@ .. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py .. _`interpreter/pyparser/`: .. _`pypy/interpreter/pyparser`: ../../pypy/interpreter/pyparser +.. _`pypy/interpreter/pyparser/pytokenizer.py`: ../../pypy/interpreter/pyparser/pytokenizer.py +.. _`pypy/interpreter/pyparser/parser.py`: ../../pypy/interpreter/pyparser/parser.py +.. _`pypy/interpreter/pyparser/pyparse.py`: ../../pypy/interpreter/pyparser/pyparse.py +.. _`pypy/interpreter/pyparser/future.py`: ../../pypy/interpreter/pyparser/future.py +.. _`pypy/interpreter/pyparser/metaparser.py`: ../../pypy/interpreter/pyparser/metaparser.py +.. _`pypy/interpreter/astcompiler/astbuilder.py`: ../../pypy/interpreter/astcompiler/astbuilder.py +.. _`pypy/interpreter/astcompiler/optimize.py`: ../../pypy/interpreter/astcompiler/optimize.py +.. _`pypy/interpreter/astcompiler/codegen.py`: ../../pypy/interpreter/astcompiler/codegen.py +.. _`pypy/interpreter/astcompiler/tools/asdl_py.py`: ../../pypy/interpreter/astcompiler/tools/asdl_py.py +.. _`pypy/interpreter/astcompiler/tools/Python.asdl`: ../../pypy/interpreter/astcompiler/tools/Python.asdl +.. _`pypy/interpreter/astcompiler/assemble.py`: ../../pypy/interpreter/astcompiler/assemble.py +.. _`pypy/interpreter/astcompiler/symtable.py`: ../../pypy/interpreter/astcompiler/symtable.py +.. _`pypy/interpreter/astcompiler/asthelpers.py`: ../../pypy/interpreter/astcompiler/asthelpers.py +.. _`pypy/interpreter/astcompiler/ast.py`: ../../pypy/interpreter/astcompiler/ast.py .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py .. _`lang/`: ../../pypy/lang .. _`lang/js/`: ../../pypy/lang/js Modified: pypy/branch/newtrunk/pypy/doc/cpython_differences.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/cpython_differences.txt (original) +++ pypy/branch/newtrunk/pypy/doc/cpython_differences.txt Mon Aug 31 15:37:16 2009 @@ -31,7 +31,6 @@ bz2 cStringIO crypt - `dyngram`_ errno exceptions fcntl @@ -42,9 +41,9 @@ md5 mmap operator + parser posix pyexpat - recparser select sha signal @@ -54,6 +53,7 @@ termios thread time + token unicodedata zipimport zlib @@ -85,7 +85,6 @@ .. _`__pypy__`: __pypy__-module.html .. _`_rawffi`: ctypes-implementation.html .. _`_minimal_curses`: config/objspace.usemodules._minimal_curses.html -.. _`dyngram`: config/objspace.usemodules.dyngram.html .. _Stackless: stackless.html Modified: pypy/branch/newtrunk/pypy/doc/extradoc.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/extradoc.txt (original) +++ pypy/branch/newtrunk/pypy/doc/extradoc.txt Mon Aug 31 15:37:16 2009 @@ -7,6 +7,12 @@ *Articles about PyPy published so far, most recent first:* (bibtex_ file) +* `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, + C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo + +* `Faster than C#: Efficient Implementation of Dynamic Languages on .NET`_, + A. Cuni, D. Ancona and A. Rigo + * `Automatic JIT Compiler Generation with Runtime Partial Evaluation`_ (Master Thesis), C.F. Bolz @@ -21,12 +27,6 @@ *Non-published articles (only submitted so far, or technical reports):* -* `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, - C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo - -* `Faster than C#: Efficient Implementation of Dynamic Languages on .NET`_, - A. Cuni, D. Ancona and A. Rigo - * `Automatic generation of JIT compilers for dynamic languages in .NET`_, D. Ancona, C.F. Bolz, A. Cuni and A. Rigo Modified: pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/branch/newtrunk/pypy/doc/jit/pyjitpl5.txt Mon Aug 31 15:37:16 2009 @@ -3,21 +3,12 @@ ======================================================================== The documentation about the current JIT is available as a -first submitted article: +first published article: * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ .. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit.pdf -as well as blog posts (oldest first): +as well as the `blog posts with the JIT tag.`__ -* http://morepypy.blogspot.com/2008/06/hi-all-some-news-from-jit-front.html -* http://morepypy.blogspot.com/2008/10/prolog-jit-masters-thesis-finished.html -* http://morepypy.blogspot.com/2009/03/applying-tracing-jit-to-interpreter.html -* http://morepypy.blogspot.com/2009/03/jit-bit-of-look-inside.html -* http://morepypy.blogspot.com/2009/03/good-news-everyone.html -* http://morepypy.blogspot.com/2009/04/roadmap-for-jit.html -* http://morepypy.blogspot.com/2009/04/4-weeks-of-gdb.html -* http://morepypy.blogspot.com/2009/05/icooolps-submissions.html -* http://morepypy.blogspot.com/2009/06/news-from-jit-front.html -* http://morepypy.blogspot.com/2009/06/jit-progress.html +.. __: http://morepypy.blogspot.com/search/label/jit Modified: pypy/branch/newtrunk/pypy/doc/parser.txt ============================================================================== --- pypy/branch/newtrunk/pypy/doc/parser.txt (original) +++ pypy/branch/newtrunk/pypy/doc/parser.txt Mon Aug 31 15:37:16 2009 @@ -1,11 +1,7 @@ -================== -PyPy Parser -================== - -WARNING: this document is out-of-date and unfinished. Our compiler -is done by now, unlike explained below. - +=========== +PyPy Parser +=========== Overview ======== @@ -15,196 +11,93 @@ Tokenizer --------- -The tokenizer accepts as string as input and provides tokens through -a ``next()`` and a ``peek()`` method. The tokenizer is implemented as a finite -automata like lex. +At the moment, the tokenizer is implemented as a single function +(``generate_tokens`` in `pypy/interpreter/pyparser/pytokenizer.py`_) that builds +a list of tokens. The tokens are then fed to the parser. Parser ------ -The parser is a tree of grammar rules. EBNF grammar rules are decomposed -as a tree of objects. -Looking at a grammar rule one can see it is composed of a set of four basic -subrules. In the following exemple we have all four of them: - -S <- A '+' (C | D) + - - -The previous line says S is a sequence of symbol A, token '+', a subrule + which -matches one or more of an alternative between symbol C and symbol D. -Thus the four basic grammar rule types are : -* sequence -* alternative -* multiplicity (called kleen star after the * multiplicity type) -* token - -The four types are represented by a class in pyparser/grammar.py -( Sequence, Alternative, KleeneStar, Token) all classes have a ``match()`` method -accepting a source (the tokenizer) and a builder (an object responsible for -building something out of the grammar). - -Here's a basic exemple and how the grammar is represented:: - - S <- A ('+'|'-') A - A <- V ( ('*'|'/') V )* - V <- 'x' | 'y' - - In python: - V = Alternative( Token('x'), Token('y') ) - A = Sequence( V, - KleeneStar( - Sequence( - Alternative( Token('*'), Token('/') ), V - ) - ) - ) - S = Sequence( A, Alternative( Token('+'), Token('-') ), A ) - - -Status -====== - -See README.compiling on the status of the parser(s) implementation of PyPy - - -Detailed design -=============== +The parser is a simple LL(1) parser that is similar to CPython's. Building the Python grammar ---------------------------- - -The python grammar is built at startup from the pristine CPython grammar file. -The grammar framework is first used to build a simple grammar to parse the -grammar itself. -The builder provided to the parser generates another grammar which is the Python -grammar itself. -The grammar file should represent an LL(1) grammar. LL(k) should still work since -the parser supports backtracking through the use of source and builder contexts -(The memento patterns for those who like Design Patterns) - -The match function for a sequence is pretty simple:: - - for each rule in the sequence: - save the source and builder context - if the rule doesn't match: - restore the source and builder context - return false - call the builder method to build the sequence - return true - -Now this really is an LL(0) grammar since it explores the whole tree of rule -possibilities. -In fact there is another member of the rule objects which is built once the -grammar is complete. -This member is a set of the tokens that match the begining of each rule. Like -the grammar it is precomputed at startup. -Then each rule starts by the following test:: - - if source.peek() not in self.firstset: return false - - -Efficiency should be similar (not too worse) to an automata based grammar since it is -basicly building an automata but it uses the execution stack to store its parsing state. -This also means that recursion in the grammar are directly translated as recursive calls. - - -Redisigning the parser to remove recursion shouldn't be difficult but would make the code -less obvious. (patches welcome). The basic idea - - -Parsing -------- - -This grammar is then used to parse Python input and transform it into a syntax tree. - -As of now the syntax tree is built as a tuple to match the output of the parser module -and feed it to the compiler package - -the compiler package uses the Transformer class to transform this tuple tree into an -abstract syntax tree. - -sticking to our previous example, the syntax tree for x+x*y would be:: - - Rule('S', nodes=[ - Rule('A',nodes=[Rule('V', nodes=[Token('x')])]), - Token('+'), - Rule('A',nodes=[ - Rule('V', nodes=[Token('x')]), - Token('*'), - Rule('V', nodes=[Token('y')]) - ]) - ]) - - -The abstract syntax tree for the same expression would look like:: - - Add(Var('x'),Mul(Var('x'),Var('y'))) - - - -Examples using the parser within PyPy -------------------------------------- - -The four parser variants are used from within interpreter/pycompiler.py - -API Quickref ------------- - -Modules -~~~~~~~ - -* interpreter/pyparser contains the tokenizer and grammar parser -* interpreter/astcompiler contains the soon to be rpythonic compiler -* interpreter/stablecompiler contains the compiler used by default -* lib/_stablecompiler contains a modified version of stablecompiler capable - of running at application level (that is not recursively calling itself - while compiling) - - -Main facade functions -~~~~~~~~~~~~~~~~~~~~~ - -still empty, but non-empty for ReST - -Grammar -~~~~~~~ - -still empty, but non-empty for ReST - -Long term goals -=============== - -having enough flexibility in the design that allows us to change the -grammar at runtime. Such modification needs to be able to: -* modify the grammar representation -* modify the ast builder so it produces existing or new AST nodes -* add new AST nodes -* modify the compiler so that it knows how to deal with new AST nodes - - -parser implementation ---------------------- - -We can now build AST trees directly from the parser. -Still missing is the ability to easily provide/change building functions -easily. The functions are referenced at interpreter level through a dictionnary -mapping that has rule names as keys. - - -compiler implementation ------------------------ - -For now we are working at translating the existing compiler module without -changing its design too much. That means we won't have enough flexibility -to be able to handle new AST nodes at runtime. - -parser module -------------- - -enhance the parser module interface so that it allows acces to the internal grammar -representation, and allows to modify it too. +*************************** -compiler module ---------------- +The python grammar is built at startup from the pristine CPython grammar file +(see `pypy/interpreter/pyparser/metaparser.py`_). The grammar builder first +represents the grammar as rules corresponding to a set of Nondeterministic +Finite Automatons (NFAs). It then converts them to a set of Deterministic +Finite Automatons (DFAs). The difference between a NFA and a DFA is that a NFA +may have several possible next states for any given input while a DFA may only +have one. DFAs are therefore more limiting, but far more efficient to use in +parsing. Finally, the assigns the grammar builder assigns each DFA state a +number and packs them into a list for the parser to use. The final product is +an instance of the ``Grammar`` class in `pypy/interpreter/pyparser/parser.py`_. + +Parser implementation +********************* + +The workhorse of the parser is the ``add_token`` method of the ``Parser`` class. +It tries to find a transition from the current state to another state based on +the token it receives as a argument. If it can't find a transition, it checks +if the current state is accepting. If it's not, a ``ParseError`` is +raised. When parsing is done without error, the parser has built a tree of +``Node``. + +Parsing Python +************** + +The glue code between the tokenizer and the parser as well as extra Python +specific code is in `pypy/interpreter/pyparser/pyparse.py`_. The +``parse_source`` method takes a string of Python code and returns the parse +tree. It also detects the coding cookie if there is one and decodes the source. +Note that __future__ imports are handled before the parser is invoked by +manually parsing the source in `pypy/interpreter/pyparser/future.py`_. + +Compiler +-------- + +The next step in generating Python bytecode is converting the parse tree into an +Abstract Syntax Tree (AST). + +Building AST +************ + +Python's AST is described in `pypy/interpreter/astcompiler/tools/Python.asdl`_. +From this definition, `pypy/interpreter/astcompiler/tools/asdl_py.py`_ generates +`pypy/interpreter/astcompiler/ast.py`_, which RPython classes for the compiler +as well as bindings to application level code for the AST. Some custom +extensions to the AST classes are in +`pypy/interpreter/astcompiler/asthelpers.py`_. + +`pypy/interpreter/astcompiler/astbuilder.py`_ is responsible for converting +parse trees into AST. It walks down the parse tree building nodes as it goes. +The result is a toplevel ``mod`` node. + +AST Optimization +**************** + +`pypy/interpreter/astcompiler/optimize.py`_ contains the AST optimizer. It does +constant folding of expressions, and other simple transformations like making a +load of the name "None" into a constant. + +Symbol analysis +*************** + +Before writing bytecode, a symbol table is built in +`pypy/interpreter/astcompiler/symtable.py`_. It determines if every name in the +source is local, implicitly global (no global declaration), explicity global +(there's a global declaration of the name in the scope), a cell (the name in +used in nested scopes), or free (it's used in a nested function). + +Bytecode generation +******************* + +Bytecode is emitted in `pypy/interpreter/astcompiler/codegen.py`_. Each +bytecode is represented temporarily by the ``Instruction`` class in +`pypy/interpreter/astcompiler/assemble.py`_. After all bytecodes have been +emitted, it's time to build the code object. Jump offsets and bytecode +information like the line number table and stack depth are computed. Finally, +everything is passed to a brand new ``PyCode`` object. -same as above +.. include:: _ref.txt Copied: pypy/branch/newtrunk/pypy/interpreter/astcompiler/ast.py (from r67184, pypy/trunk/pypy/interpreter/astcompiler/ast.py) ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/ast.py Mon Aug 31 15:37:16 2009 @@ -343,7 +343,8 @@ else: if not self.initialization_state & 1: self.value = None - self.value.sync_app_attrs(space) + if self.value: + self.value.sync_app_attrs(space) class Delete(stmt): @@ -487,7 +488,8 @@ else: if not self.initialization_state & 1: self.dest = None - self.dest.sync_app_attrs(space) + if self.dest: + self.dest.sync_app_attrs(space) w_list = self.w_values if w_list is not None: list_w = space.viewiterable(w_list) @@ -701,7 +703,8 @@ if not self.initialization_state & 2: self.optional_vars = None self.context_expr.sync_app_attrs(space) - self.optional_vars.sync_app_attrs(space) + if self.optional_vars: + self.optional_vars.sync_app_attrs(space) w_list = self.w_body if w_list is not None: list_w = space.viewiterable(w_list) @@ -750,9 +753,12 @@ self.inst = None if not self.initialization_state & 4: self.tback = None - self.type.sync_app_attrs(space) - self.inst.sync_app_attrs(space) - self.tback.sync_app_attrs(space) + if self.type: + self.type.sync_app_attrs(space) + if self.inst: + self.inst.sync_app_attrs(space) + if self.tback: + self.tback.sync_app_attrs(space) class TryExcept(stmt): @@ -900,7 +906,8 @@ if not self.initialization_state & 2: self.msg = None self.test.sync_app_attrs(space) - self.msg.sync_app_attrs(space) + if self.msg: + self.msg.sync_app_attrs(space) class Import(stmt): @@ -1014,8 +1021,10 @@ if not self.initialization_state & 4: self.locals = None self.body.sync_app_attrs(space) - self.globals.sync_app_attrs(space) - self.locals.sync_app_attrs(space) + if self.globals: + self.globals.sync_app_attrs(space) + if self.locals: + self.locals.sync_app_attrs(space) class Global(stmt): @@ -1474,7 +1483,8 @@ else: if not self.initialization_state & 1: self.value = None - self.value.sync_app_attrs(space) + if self.value: + self.value.sync_app_attrs(space) class Compare(expr): @@ -1587,8 +1597,10 @@ if self.keywords is not None: for node in self.keywords: node.sync_app_attrs(space) - self.starargs.sync_app_attrs(space) - self.kwargs.sync_app_attrs(space) + if self.starargs: + self.starargs.sync_app_attrs(space) + if self.kwargs: + self.kwargs.sync_app_attrs(space) class Repr(expr): @@ -1967,9 +1979,12 @@ self.upper = None if not self.initialization_state & 4: self.step = None - self.lower.sync_app_attrs(space) - self.upper.sync_app_attrs(space) - self.step.sync_app_attrs(space) + if self.lower: + self.lower.sync_app_attrs(space) + if self.upper: + self.upper.sync_app_attrs(space) + if self.step: + self.step.sync_app_attrs(space) class ExtSlice(slice): @@ -2323,8 +2338,10 @@ self.type = None if not self.initialization_state & 2: self.name = None - self.type.sync_app_attrs(space) - self.name.sync_app_attrs(space) + if self.type: + self.type.sync_app_attrs(space) + if self.name: + self.name.sync_app_attrs(space) w_list = self.w_body if w_list is not None: list_w = space.viewiterable(w_list) Copied: pypy/branch/newtrunk/pypy/interpreter/astcompiler/asthelpers.py (from r67184, pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py) ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/asthelpers.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/asthelpers.py Mon Aug 31 15:37:16 2009 @@ -10,6 +10,15 @@ setattr(ast, "UnacceptableExpressionContext", UnacceptableExpressionContext) +class __extend__(ast.AST): + + def as_node_list(self, space): + raise AssertionError("only for expressions") + + def set_context(self, ctx): + raise AssertionError("should only be on expressions") + + class __extend__(ast.expr): constant = False Modified: pypy/branch/newtrunk/pypy/interpreter/astcompiler/consts.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/astcompiler/consts.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/consts.py Mon Aug 31 15:37:16 2009 @@ -22,3 +22,7 @@ CO_FUTURE_DIVISION = 0x2000 CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 CO_FUTURE_WITH_STATEMENT = 0x8000 + +PyCF_SOURCE_IS_UTF8 = 0x0100 +PyCF_DONT_IMPLY_DEDENT = 0x0200 +PyCF_AST_ONLY = 0x0400 Modified: pypy/branch/newtrunk/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/misc.py Mon Aug 31 15:37:16 2009 @@ -1,22 +1,88 @@ +from pypy.interpreter import gateway from pypy.interpreter.astcompiler import ast +from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.unroll import unrolling_iterable -def flatten(tup): - elts = [] - for elt in tup: - if type(elt) == tuple: - elts = elts + flatten(elt) + +app = gateway.applevel(""" +def syntax_warning(msg, fn, lineno, offset): + import warnings + try: + warnings.warn_explicit(msg, SyntaxWarning, fn, lineno) + except SyntaxWarning: + raise SyntaxError(msg, fn, lineno, offset) +""", filename=__file__) +_emit_syntax_warning = app.interphook("syntax_warning") +del app + +def syntax_warning(space, msg, fn, lineno, offset): + """Raise an applevel SyntaxWarning. + + If the user has set this warning to raise an error, a SyntaxError will be + raised.""" + w_msg = space.wrap(msg) + w_filename = space.wrap(fn) + w_lineno = space.wrap(lineno) + w_offset = space.wrap(offset) + _emit_syntax_warning(space, w_msg, w_filename, w_lineno, w_offset) + + +def parse_future(tree): + future_lineno = 0 + future_column = 0 + have_docstring = False + if isinstance(tree, ast.Module): + body = tree.body + elif isinstance(tree, ast.Interactive): + body = tree.body + else: + return 0, 0 + for stmt in body: + if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Str): + if have_docstring: + break + else: + have_docstring = True + elif isinstance(stmt, ast.ImportFrom): + if stmt.module == "__future__": + future_lineno = stmt.lineno + future_column = stmt.col_offset + else: + break + else: + break + return future_lineno, future_column + + +class ForbiddenNameAssignment(Exception): + + def __init__(self, name, node): + self.name = name + self.node = node + + +def check_forbidden_name(name, node=None): + """Raise an error if the name cannot be assigned to.""" + if name in ("None", "__debug__"): + raise ForbiddenNameAssignment(name, node) + # XXX Warn about using True and False + + +def dict_to_switch(d): + """Convert of dictionary with integer keys to a switch statement.""" + def lookup(query): + if we_are_translated(): + for key, value in unrolling_iteritems: + if key == query: + return value + else: + raise KeyError else: - elts.append(elt) - return elts + return d[query] + lookup._always_inline_ = True + unrolling_iteritems = unrolling_iterable(d.iteritems()) + return lookup -class Counter: - def __init__(self, initial): - self.count = initial - - def next(self): - i = self.count - self.count += 1 - return i MANGLE_LEN = 256 # magic constant from compile.c @@ -44,32 +110,3 @@ klass = klass[:end] return "_%s%s" % (klass, name) - -class Queue(object): - def __init__(self, item): - self.head = [item] - self.tail = [] - - def pop(self): - if self.head: - return self.head.pop() - else: - for i in range(len(self.tail)-1, -1, -1): - self.head.append(self.tail[i]) - self.tail = [] - return self.head.pop() - - def extend(self, items): - self.tail.extend(items) - - def nonempty(self): - return self.tail or self.head - -def set_filename(filename, tree): - """Set the filename attribute to filename on every node in tree""" - worklist = Queue(tree) - while worklist.nonempty(): - node = worklist.pop() - assert isinstance(node, ast.Node) - node.filename = filename - worklist.extend(node.getChildNodes()) Copied: pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_astbuilder.py (from r67184, pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py) ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/test/test_astbuilder.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_astbuilder.py Mon Aug 31 15:37:16 2009 @@ -10,6 +10,16 @@ from pypy.interpreter.astcompiler import ast, consts +try: + all +except NameError: + def all(iterable): + for x in iterable: + if not x: + return False + return True + + class TestAstBuilder: def setup_class(cls): Modified: pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_compiler.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_compiler.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/test/test_compiler.py Mon Aug 31 15:37:16 2009 @@ -1,25 +1,16 @@ import py -from pypy.interpreter.astcompiler import misc, pycodegen, opt -from pypy.interpreter.pyparser.test.support import source2ast +from pypy.interpreter.astcompiler import codegen, astbuilder +from pypy.interpreter.pyparser import pyparse from pypy.interpreter.pyparser.test import expressions from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyparser.error import SyntaxError, IndentationError def compile_with_astcompiler(expr, mode, space): - ast = source2ast(expr, mode, space) - misc.set_filename('', ast) - ast = opt.optimize_ast_tree(space, ast) - if mode == 'exec': - Generator = pycodegen.ModuleCodeGenerator - elif mode == 'single': - Generator = pycodegen.InteractiveCodeGenerator - elif mode == 'eval': - Generator = pycodegen.ExpressionCodeGenerator - codegen = Generator(space, ast) - rcode = codegen.getCode() - assert isinstance(rcode, PyCode) - assert rcode.co_filename == '' - return rcode + p = pyparse.PythonParser(space) + info = pyparse.CompileInfo("", mode) + cst = p.parse_source(expr, info) + ast = astbuilder.ast_from_node(space, cst, info) + return codegen.compile_ast(space, ast, info) class TestCompiler: @@ -56,6 +47,16 @@ st = simple_test + def test_long_jump(self): + func = """def f(x): + y = 0 + if x: +%s return 1 + else: + return 0""" % (" y += 1\n" * 9000,) + yield self.st, func, "f(1)", 1 + yield self.st, func, "f(0)", 0 + def test_argtuple(self): yield (self.simple_test, "def f( x, (y,z) ): return x,y,z", "f((1,2),(3,4))", ((1,2),3,4)) @@ -409,6 +410,14 @@ decl = str(decl) + "\n" yield self.st, decl, 'x', (1, 2, 3, 4) + source = """def f(a): + del a + def x(): + a +""" + exc = py.test.raises(SyntaxError, self.run, source).value + assert exc.msg == "Can't delete variable used in nested scopes: 'a'" + def test_try_except_finally(self): yield self.simple_test, """ try: @@ -430,6 +439,12 @@ comments[:0] = [comment] comment = '' """, 'comments', ['# foo', 42] + yield self.simple_test, """ + while 0: + pass + else: + x = 1 + """, "x", 1 def test_return_lineno(self): # the point of this test is to check that there is no code associated @@ -690,3 +705,33 @@ l.append(x) """ self.simple_test(source, 'l', [1, 2]) + + def test_lambda(self): + yield self.st, "y = lambda x: x", "y(4)", 4 + + def test_backquote_repr(self): + yield self.st, "x = None; y = `x`", "y", "None" + + def test_deleting_attributes(self): + test = """class X(): + x = 3 +del X.x +try: + X.x +except AttributeError: + pass +else: + raise AssertionError("attribute not removed")""" + yield self.st, test, "X.__name__", "X" + + +class AppTestPrint: + + def test_print_to(self): + exec """from StringIO import StringIO +s = StringIO() +print >> s, "hi", "lovely!" +assert s.getvalue() == "hi lovely!\\n" +s = StringIO() +print >> s, "hi", "lovely!", +assert s.getvalue() == "hi lovely!\"""" in {} Copied: pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/asdl_py.py (from r67184, pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py) ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/tools/asdl_py.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/astcompiler/tools/asdl_py.py Mon Aug 31 15:37:16 2009 @@ -161,7 +161,11 @@ elif attr.type.value not in asdl.builtin_types and \ attr.type.value not in self.data.simple_types: doing_something = True - self.emit("self.%s.sync_app_attrs(space)" % (attr.name,), 2) + level = 2 + if attr.opt: + self.emit("if self.%s:" % (attr.name,), 2) + level += 1 + self.emit("self.%s.sync_app_attrs(space)" % (attr.name,), level) self.emit("") def make_constructor(self, fields, node, extras=None, base=None): Modified: pypy/branch/newtrunk/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pycompiler.py Mon Aug 31 15:37:16 2009 @@ -4,7 +4,7 @@ """ import sys -from codeop import PyCF_DONT_IMPLY_DEDENT +from pypy.interpreter.astcompiler.consts import PyCF_DONT_IMPLY_DEDENT from pypy.interpreter.error import OperationError class AbstractCompiler(object): @@ -205,6 +205,7 @@ ######## + class PythonAstCompiler(PyCodeCompiler): """Uses the stdlib's python implementation of compiler @@ -215,122 +216,63 @@ """ def __init__(self, space, override_version=None): - from pyparser.pythonparse import make_pyparser + from pypy.interpreter.pyparser.pyparse import PythonParser PyCodeCompiler.__init__(self, space) - self.grammar_version = override_version or "2.5" - self.parser = make_pyparser(self.grammar_version) + self.parser = PythonParser(space) self.additional_rules = {} - if self.grammar_version >= '2.5': - self.futureFlags = future.futureFlags_2_5 - else: - self.futureFlags = future.futureFlags_2_4 + self.futureFlags = future.futureFlags_2_5 self.compiler_flags = self.futureFlags.allowed_flags - def compile(self, source, filename, mode, flags): - from pypy.interpreter.pyparser.error import SyntaxError, IndentationError - from pypy.interpreter import astcompiler - from pypy.interpreter.astcompiler.pycodegen import ModuleCodeGenerator - from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator - from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator - from pypy.interpreter.astcompiler.ast import Node - from pypy.interpreter.astcompiler import opt - from pyparser.astbuilder import AstBuilder - from pypy.interpreter.pycode import PyCode - from pypy.interpreter.function import Function + def compile_ast(self, node, filename, mode, flags): + from pypy.interpreter.pyparser.pyparse import CompileInfo + from pypy.interpreter.astcompiler.misc import parse_future + info = CompileInfo(filename, mode, flags, parse_future(node)) + return self._compile_ast(node, info) + + def _compile_ast(self, node, info): + from pypy.interpreter.astcompiler import optimize + from pypy.interpreter.astcompiler.codegen import compile_ast + from pypy.interpreter.pyparser.error import SyntaxError + space = self.space + try: + mod = optimize.optimize_ast(space, node, info) + code = compile_ast(space, mod, info) + except SyntaxError, e: + raise OperationError(space.w_SyntaxError, + e.wrap_info(space)) + return code - from pypy.interpreter.pyparser.future import getFutures - from pypy.interpreter.pyparser.pythonlexer import TokenIndentationError + def compile_to_ast(self, source, filename, mode, flags): + from pypy.interpreter.pyparser.pyparse import CompileInfo + info = CompileInfo(filename, mode, flags) + return self._compile_to_ast(source, info) -## flags |= stdlib___future__.generators.compiler_flag # always on (2.2 compat) + def _compile_to_ast(self, source, info): + from pypy.interpreter.pyparser.future import getFutures + from pypy.interpreter.pyparser.error import (SyntaxError, + IndentationError, + TokenIndentationError) + from pypy.interpreter.astcompiler.astbuilder import ast_from_node space = self.space - space.timer.start("PythonAST compile") try: - builder = AstBuilder(self.parser, self.grammar_version, space=space) - for rulename, buildfunc in self.additional_rules.iteritems(): - assert isinstance(buildfunc, Function) - builder.user_build_rules[rulename] = buildfunc - flags |= getFutures(self.futureFlags, source) - self.parser.parse_source(source, mode, builder, flags) - ast_tree = builder.rule_stack[-1] - encoding = builder.source_encoding + f_flags, future_info = getFutures(self.futureFlags, source) + info.last_future_import = future_info + info.flags |= f_flags + parse_tree = self.parser.parse_source(source, info) + mod = ast_from_node(space, parse_tree, info) except IndentationError, e: raise OperationError(space.w_IndentationError, - e.wrap_info(space, filename)) + e.wrap_info(space)) except TokenIndentationError, e: raise OperationError(space.w_IndentationError, - e.wrap_info(space, filename)) + e.wrap_info(space)) except SyntaxError, e: raise OperationError(space.w_SyntaxError, - e.wrap_info(space, filename)) - ast_tree = opt.optimize_ast_tree(space, ast_tree) + e.wrap_info(space)) + return mod - if not space.is_w(self.w_compile_hook, space.w_None): - try: - w_ast_tree = space.call_function(self.w_compile_hook, - space.wrap(ast_tree), - space.wrap(encoding), - space.wrap(filename)) - ast_tree = space.interp_w(Node, w_ast_tree) - except OperationError: - self.w_compile_hook = space.w_None - raise - try: - astcompiler.misc.set_filename(filename, ast_tree) - flag_names = self.futureFlags.get_flag_names(space, flags) - if mode == 'exec': - codegenerator = ModuleCodeGenerator(space, ast_tree, flag_names) - elif mode == 'single': - codegenerator = InteractiveCodeGenerator(space, ast_tree, flag_names) - else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(space, ast_tree, flag_names) - c = codegenerator.getCode() - except SyntaxError, e: - raise OperationError(space.w_SyntaxError, - e.wrap_info(space, filename)) - except (ValueError, TypeError), e: - raise OperationError(space.w_SystemError, space.wrap(str(e))) - assert isinstance(c, PyCode) - space.timer.stop("PythonAST compile") - return c - - # interface for pypy.module.recparser - def get_parser(self): - return self.parser - - def source2ast(self, source, mode='exec'): - from pypy.interpreter.pyparser.astbuilder import AstBuilder - builder = AstBuilder(self.parser, self.grammar_version, - space=self.space) - self.parser.parse_source(source, mode, builder) - return builder.rule_stack[-1] - - -def install_compiler_hook(space, w_callable): -# if not space.get( w_callable ): -# raise OperationError( space.w_TypeError( space.wrap( "must have a callable" ) ) - space.default_compiler.w_compile_hook = w_callable - -def insert_grammar_rule(space, w_rule, w_buildfuncs): - """inserts new grammar rules to the default compiler""" - from pypy.interpreter import function - rule = space.str_w(w_rule) - #buildfuncs_w = w_buildfuncs.content - buildfuncs = {} - #for w_name, w_func in buildfuncs_w.iteritems(): - # buildfuncs[space.str_w(w_name)] = space.unwrap(w_func) - w_iter = space.iter(w_buildfuncs) - while 1: - try: - w_key = space.next(w_iter) - w_func = space.getitem(w_buildfuncs, w_key) - buildfuncs[space.str_w(w_key)] = space.interp_w(function.Function, w_func) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - space.default_compiler.additional_rules = buildfuncs - space.default_compiler.parser.insert_rule(rule) - -# XXX cyclic import -#from pypy.interpreter.baseobjspace import ObjSpace -#insert_grammar_rule.unwrap_spec = [ObjSpace, str, dict] + def compile(self, source, filename, mode, flags): + from pypy.interpreter.pyparser.pyparse import CompileInfo + info = CompileInfo(filename, mode, flags) + mod = self._compile_to_ast(source, info) + return self._compile_ast(mod, info) Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/automata.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/automata.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/automata.py Mon Aug 31 15:37:16 2009 @@ -1,4 +1,3 @@ -#! /usr/bin/env python # ______________________________________________________________________ """Module automata Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/error.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/error.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/error.py Mon Aug 31 15:37:16 2009 @@ -10,9 +10,9 @@ self.filename = filename self.print_file_and_line = False - def wrap_info(self, space, filename): + def wrap_info(self, space): return space.newtuple([space.wrap(self.msg), - space.newtuple([space.wrap(filename), + space.newtuple([space.wrap(self.filename), space.wrap(self.lineno), space.wrap(self.offset), space.wrap(self.text)])]) @@ -32,8 +32,14 @@ self.ast_node = ast_node -class TokenError(Exception): - def __init__(self, msg, tokens): - self.msg = msg +class TokenError(SyntaxError): + + def __init__(self, msg, line, lineno, column, tokens): + SyntaxError.__init__(self, msg, lineno, column, line) + self.tokens = tokens + +class TokenIndentationError(IndentationError): + + def __init__(self, msg, line, lineno, column, tokens): + SyntaxError.__init__(self, msg, lineno, column, line) self.tokens = tokens - Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/future.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/future.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/future.py Mon Aug 31 15:37:16 2009 @@ -33,7 +33,7 @@ futures.start() except DoneException, e: pass - return futures.flags + return futures.flags, (futures.lineno, futures.col_offset) class DoneException(Exception): pass @@ -67,8 +67,13 @@ self.futureFlags = futureFlags self.s = string self.pos = 0 + self.current_lineno = 1 + self.lineno = -1 + self.line_start_pos = 0 + self.col_offset = 0 self.docstringConsumed = False self.flags = 0 + self.got_features = 0 def getc(self, offset=0): try: @@ -89,6 +94,10 @@ else: return + def atbol(self): + self.current_lineno += 1 + self.line_start_pos = self.pos + def consumeDocstring(self): self.docstringConsumed = True endchar = self.getc() @@ -98,15 +107,23 @@ while 1: # Deal with a triple quoted docstring if self.getc() == '\\': self.pos += 2 - elif self.getc() != endchar: - self.pos += 1 else: - self.pos += 1 - if (self.getc() == endchar and - self.getc(+1) == endchar): - self.pos += 2 - self.consumeEmptyLine() - break + c = self.getc() + if c != endchar: + self.pos += 1 + if c == '\n': + self.atbol() + elif c == '\r': + if self.getc() == '\n': + self.pos += 1 + self.atbol() + else: + self.pos += 1 + if (self.getc() == endchar and + self.getc(+1) == endchar): + self.pos += 2 + self.consumeEmptyLine() + break else: # Deal with a single quoted docstring self.pos += 1 @@ -142,11 +159,16 @@ self.consumeWhitespace() self.start() elif self.getc() in '\r\n': + c = self.getc() self.pos += 1 - if self.getc() == '\n': - self.pos += 1 + if c == '\r': + if self.getc() == '\n': + self.pos += 1 + self.atbol() + else: + self.atbol() self.start() - + def consumeComment(self): self.pos += 1 while self.getc() not in '\r\n': @@ -154,6 +176,8 @@ self.consumeEmptyLine() def consumeFrom(self): + col_offset = self.pos - self.line_start_pos + line = self.current_lineno self.pos += 1 if self.getc() == 'r' and self.getc(+1) == 'o' and self.getc(+2) == 'm': self.docstringConsumed = True @@ -167,15 +191,21 @@ raise DoneException self.pos += 6 self.consumeWhitespace() - if self.getc() == '(': - self.pos += 1 - self.consumeWhitespace() - self.setFlag(self.getName()) - # Set flag corresponding to name - self.getMore(parenList=True) - else: - self.setFlag(self.getName()) - self.getMore() + old_got = self.got_features + try: + if self.getc() == '(': + self.pos += 1 + self.consumeWhitespace() + self.setFlag(self.getName()) + # Set flag corresponding to name + self.getMore(parenList=True) + else: + self.setFlag(self.getName()) + self.getMore() + finally: + if self.got_features > old_got: + self.col_offset = col_offset + self.lineno = line self.consumeEmptyLine() else: return @@ -196,11 +226,13 @@ c = self.getc() if c == '\n': self.pos += 1 + self.atbol() continue elif c == '\r': self.pos += 1 if self.getc() == '\n': self.pos += 1 + self.atbol() else: raise DoneException else: @@ -242,6 +274,7 @@ self.getMore(parenList=parenList) def setFlag(self, feature): + self.got_features += 1 try: self.flags |= self.futureFlags.compiler_features[feature] except KeyError: @@ -265,12 +298,9 @@ self.compiler_features[fname] = flag if version >= feature.getMandatoryRelease(): self.mandatory_flags |= feature.compiler_flag - self.allowed_flags = compiler_flags | PyCF_DONT_IMPLY_DEDENT + self.allowed_flags = compiler_flags def get_flag_names(self, space, flags): - if flags & ~self.allowed_flags: - raise OperationError(space.w_ValueError, - space.wrap("compile(): unrecognized flags")) flag_names = [] for name, value in self.compiler_features.items(): if flags & value: Copied: pypy/branch/newtrunk/pypy/interpreter/pyparser/metaparser.py (from r67184, pypy/trunk/pypy/interpreter/pyparser/metaparser.py) ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/metaparser.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/metaparser.py Mon Aug 31 15:37:16 2009 @@ -14,7 +14,7 @@ class PgenError(Exception): def __init__(self, msg, location=None): - super(PgenError, self).__init__(msg) + Exception.__init__(self, msg) self.location = location @@ -73,7 +73,13 @@ def nfa_to_dfa(start, end): - """Convert an NFA to a DFA(s)""" + """Convert an NFA to a DFA(s) + + Each DFA is initially a set of NFA states without labels. We start with the + DFA for the start NFA. Then we add labeled arcs to it pointing to another + set of NFAs (the next state). Finally, we do the same thing to every DFA + that is found and return the list of states. + """ base_nfas = set() start.find_unlabeled_states(base_nfas) state_stack = [DFA(base_nfas, end)] @@ -135,7 +141,7 @@ for name in names: dfa = self.dfas[name] states = [] - for state_index, state in enumerate(dfa): + for state in dfa: arcs = [] for label, next in state.arcs.iteritems(): arcs.append((self.make_label(gram, label), dfa.index(next))) @@ -223,7 +229,7 @@ for label, their_first in overlap_check.iteritems(): for sub_label in their_first: if sub_label in inverse: - raise PgenError("ambiguas symbol %s" % (symbol,)) + raise PgenError("ambiguous symbol %s" % (symbol,)) inverse[sub_label] = label self.first[name] = all_labels return all_labels Copied: pypy/branch/newtrunk/pypy/interpreter/pyparser/pygram.py (from r67184, pypy/trunk/pypy/interpreter/pyparser/pygram.py) ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pygram.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/pygram.py Mon Aug 31 15:37:16 2009 @@ -9,7 +9,7 @@ def _get_python_grammar(): here = os.path.dirname(__file__) - fp = open(os.path.join(here, "data", "Grammar2.5_2")) + fp = open(os.path.join(here, "data", "Grammar2.5")) try: gram_source = fp.read() finally: Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/pytoken.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/pytoken.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/pytoken.py Mon Aug 31 15:37:16 2009 @@ -1,81 +1,71 @@ -# A replacement for the token module -# -# adds a new map token_values to avoid doing getattr on the module -# from PyPy RPython +"""Python token definitions.""" -N_TOKENS = 0 +python_tokens = {} +python_opmap = {} -# This is used to replace None -NULLTOKEN = -1 - -tok_name = {-1 : 'NULLTOKEN'} -tok_values = {'NULLTOKEN' : -1} - -# tok_rpunct = {} - -def setup_tokens( parser ): - # global tok_rpunct -# For compatibility, this produces the same constant values as Python 2.4. - parser.add_token( 'ENDMARKER' ) - parser.add_token( 'NAME' ) - parser.add_token( 'NUMBER' ) - parser.add_token( 'STRING' ) - parser.add_token( 'NEWLINE' ) - parser.add_token( 'INDENT' ) - parser.add_token( 'DEDENT' ) - parser.add_token( 'LPAR', "(" ) - parser.add_token( 'RPAR', ")" ) - parser.add_token( 'LSQB', "[" ) - parser.add_token( 'RSQB', "]" ) - parser.add_token( 'COLON', ":" ) - parser.add_token( 'COMMA', "," ) - parser.add_token( 'SEMI', ";" ) - parser.add_token( 'PLUS', "+" ) - parser.add_token( 'MINUS', "-" ) - parser.add_token( 'STAR', "*" ) - parser.add_token( 'SLASH', "/" ) - parser.add_token( 'VBAR', "|" ) - parser.add_token( 'AMPER', "&" ) - parser.add_token( 'LESS', "<" ) - parser.add_token( 'GREATER', ">" ) - parser.add_token( 'EQUAL', "=" ) - parser.add_token( 'DOT', "." ) - parser.add_token( 'PERCENT', "%" ) - parser.add_token( 'BACKQUOTE', "`" ) - parser.add_token( 'LBRACE', "{" ) - parser.add_token( 'RBRACE', "}" ) - parser.add_token( 'EQEQUAL', "==" ) - ne = parser.add_token( 'NOTEQUAL', "!=" ) - parser.tok_values["<>"] = ne - parser.add_token( 'LESSEQUAL', "<=" ) - parser.add_token( 'GREATEREQUAL', ">=" ) - parser.add_token( 'TILDE', "~" ) - parser.add_token( 'CIRCUMFLEX', "^" ) - parser.add_token( 'LEFTSHIFT', "<<" ) - parser.add_token( 'RIGHTSHIFT', ">>" ) - parser.add_token( 'DOUBLESTAR', "**" ) - parser.add_token( 'PLUSEQUAL', "+=" ) - parser.add_token( 'MINEQUAL', "-=" ) - parser.add_token( 'STAREQUAL', "*=" ) - parser.add_token( 'SLASHEQUAL', "/=" ) - parser.add_token( 'PERCENTEQUAL', "%=" ) - parser.add_token( 'AMPEREQUAL', "&=" ) - parser.add_token( 'VBAREQUAL', "|=" ) - parser.add_token( 'CIRCUMFLEXEQUAL', "^=" ) - parser.add_token( 'LEFTSHIFTEQUAL', "<<=" ) - parser.add_token( 'RIGHTSHIFTEQUAL', ">>=" ) - parser.add_token( 'DOUBLESTAREQUAL', "**=" ) - parser.add_token( 'DOUBLESLASH', "//" ) - parser.add_token( 'DOUBLESLASHEQUAL',"//=" ) - parser.add_token( 'AT', "@" ) - parser.add_token( 'OP' ) - parser.add_token( 'ERRORTOKEN' ) +def _add_tok(name, *values): + index = len(python_tokens) + assert index < 256 + python_tokens[name] = index + for value in values: + python_opmap[value] = index + +_add_tok('ENDMARKER') +_add_tok('NAME') +_add_tok('NUMBER') +_add_tok('STRING') +_add_tok('NEWLINE') +_add_tok('INDENT') +_add_tok('DEDENT') +_add_tok('LPAR', "(") +_add_tok('RPAR', ")") +_add_tok('LSQB', "[") +_add_tok('RSQB', "]") +_add_tok('COLON', ":") +_add_tok('COMMA', "," ) +_add_tok('SEMI', ";" ) +_add_tok('PLUS', "+" ) +_add_tok('MINUS', "-" ) +_add_tok('STAR', "*" ) +_add_tok('SLASH', "/" ) +_add_tok('VBAR', "|" ) +_add_tok('AMPER', "&" ) +_add_tok('LESS', "<" ) +_add_tok('GREATER', ">" ) +_add_tok('EQUAL', "=" ) +_add_tok('DOT', "." ) +_add_tok('PERCENT', "%" ) +_add_tok('BACKQUOTE', "`" ) +_add_tok('LBRACE', "{" ) +_add_tok('RBRACE', "}" ) +_add_tok('EQEQUAL', "==" ) +_add_tok('NOTEQUAL', "!=", "<>" ) +_add_tok('LESSEQUAL', "<=" ) +_add_tok('GREATEREQUAL', ">=" ) +_add_tok('TILDE', "~" ) +_add_tok('CIRCUMFLEX', "^" ) +_add_tok('LEFTSHIFT', "<<" ) +_add_tok('RIGHTSHIFT', ">>" ) +_add_tok('DOUBLESTAR', "**" ) +_add_tok('PLUSEQUAL', "+=" ) +_add_tok('MINEQUAL', "-=" ) +_add_tok('STAREQUAL', "*=" ) +_add_tok('SLASHEQUAL', "/=" ) +_add_tok('PERCENTEQUAL', "%=" ) +_add_tok('AMPEREQUAL', "&=" ) +_add_tok('VBAREQUAL', "|=" ) +_add_tok('CIRCUMFLEXEQUAL', "^=" ) +_add_tok('LEFTSHIFTEQUAL', "<<=" ) +_add_tok('RIGHTSHIFTEQUAL', ">>=" ) +_add_tok('DOUBLESTAREQUAL', "**=" ) +_add_tok('DOUBLESLASH', "//" ) +_add_tok('DOUBLESLASHEQUAL',"//=" ) +_add_tok('AT', "@" ) +_add_tok('OP') +_add_tok('ERRORTOKEN') # extra PyPy-specific tokens - parser.add_token( "COMMENT" ) - parser.add_token( "NL" ) +_add_tok("COMMENT") +_add_tok("NL") - # tok_rpunct = parser.tok_values.copy() - # for _name, _value in parser.tokens.items(): - # globals()[_name] = _value - # setattr(parser, _name, _value) +del _add_tok Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/pytokenize.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/pytokenize.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/pytokenize.py Mon Aug 31 15:37:16 2009 @@ -1,4 +1,3 @@ -#! /usr/bin/env python # ______________________________________________________________________ """Module pytokenize Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_futureautomaton.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_futureautomaton.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_futureautomaton.py Mon Aug 31 15:37:16 2009 @@ -124,15 +124,17 @@ def test_full_chain(): s = '"abc" #def\n #ghi\nfrom __future__ import (division as b, generators,); from __future__ import with_statement\n' - flags = future.getFutures(future.futureFlags_2_5, s) + flags, pos = future.getFutures(future.futureFlags_2_5, s) assert flags == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) + assert pos == (3, 55) def test_intervening_code(): s = 'from __future__ import (division as b, generators,)\nfrom sys import modules\nfrom __future__ import with_statement\n' - flags = future.getFutures(future.futureFlags_2_5, s) + flags, pos = future.getFutures(future.futureFlags_2_5, s) assert flags & fut.CO_FUTURE_WITH_STATEMENT == 0 + assert pos == (1, 0) def test_nonexisting(): Modified: pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_parser.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_parser.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/pyparser/test/test_parser.py Mon Aug 31 15:37:16 2009 @@ -1,47 +1,294 @@ -from pypy.interpreter.pyparser.asthelper import get_atoms -from pypy.interpreter.pyparser.grammar import Parser -from pypy.interpreter.pyparser import error - - -def test_symbols(): - p = Parser() - x1 = p.add_symbol('sym') - x2 = p.add_token('tok') - x3 = p.add_anon_symbol(':sym') - x4 = p.add_anon_symbol(':sym1') - # test basic numbering assumption - # symbols and tokens are attributed sequentially - # using the same counter - assert x2 == x1 + 1 - # anon symbols have negative value - assert x3 != x2 + 1 - assert x4 == x3 - 1 - assert x3 < 0 - y1 = p.add_symbol('sym') - assert y1 == x1 - y2 = p.add_token('tok') - assert y2 == x2 - y3 = p.add_symbol(':sym') - assert y3 == x3 - y4 = p.add_symbol(':sym1') - assert y4 == x4 - - -def test_load(): - d = { 5 : 'sym1', - 6 : 'sym2', - 9 : 'sym3', - } - p = Parser() - p.load_symbols( d ) - v = p.add_symbol('sym4') - # check that we avoid numbering conflicts - assert v>9 - v = p.add_symbol( 'sym1' ) - assert v == 5 - v = p.add_symbol( 'sym2' ) - assert v == 6 - v = p.add_symbol( 'sym3' ) - assert v == 9 +# New parser tests. +import py +import tokenize +import token +import StringIO +from pypy.interpreter.pyparser import parser, metaparser, pygram +from pypy.interpreter.pyparser.test.test_metaparser import MyGrammar +class SimpleParser(parser.Parser): + + def parse(self, input): + self.prepare() + rl = StringIO.StringIO(input + "\n").readline + gen = tokenize.generate_tokens(rl) + for tp, value, begin, end, line in gen: + if self.add_token(tp, value, begin[0], begin[1], line): + py.test.raises(StopIteration, gen.next) + return self.root + + +def tree_from_string(expected, gram): + def count_indent(s): + indent = 0 + for char in s: + if char != " ": + break + indent += 1 + return indent + last_newline_index = 0 + for i, char in enumerate(expected): + if char == "\n": + last_newline_index = i + elif char != " ": + break + if last_newline_index: + expected = expected[last_newline_index + 1:] + base_indent = count_indent(expected) + assert not divmod(base_indent, 4)[1], "not using 4 space indentation" + lines = [line[base_indent:] for line in expected.splitlines()] + last_indent = 0 + node_stack = [] + for line in lines: + if not line.strip(): + continue + data = line.split() + if data[0].isupper(): + tp = getattr(token, data[0]) + if len(data) == 2: + value = data[1].strip("\"") + elif tp == token.NEWLINE: + value = "\n" + else: + value = "" + children = None + else: + tp = gram.symbol_ids[data[0]] + value = None + children = [] + n = parser.Node(tp, value, children, 0, 0) + new_indent = count_indent(line) + if new_indent >= last_indent: + if new_indent == last_indent and node_stack: + node_stack.pop() + if node_stack: + node_stack[-1].children.append(n) + node_stack.append(n) + else: + diff = last_indent - new_indent + pop_nodes = diff // 4 + 1 + del node_stack[-pop_nodes:] + node_stack[-1].children.append(n) + node_stack.append(n) + last_indent = new_indent + return node_stack[0] + + +class TestParser: + + def parser_for(self, gram, add_endmarker=True): + if add_endmarker: + gram += " NEWLINE ENDMARKER\n" + pgen = metaparser.ParserGenerator(gram) + g = pgen.build_grammar(MyGrammar) + return SimpleParser(g), g + + def test_multiple_rules(self): + gram = """foo: 'next_rule' bar 'end' NEWLINE ENDMARKER +bar: NAME NUMBER\n""" + p, gram = self.parser_for(gram, False) + expected = """ + foo + NAME "next_rule" + bar + NAME "a_name" + NUMBER "42" + NAME "end" + NEWLINE + ENDMARKER""" + input = "next_rule a_name 42 end" + assert tree_from_string(expected, gram) == p.parse(input) + + def test_recursive_rule(self): + gram = """foo: NAME bar STRING NEWLINE ENDMARKER +bar: NAME [bar] NUMBER\n""" + p, gram = self.parser_for(gram, False) + expected = """ + foo + NAME "hi" + bar + NAME "hello" + bar + NAME "a_name" + NUMBER "32" + NUMBER "42" + STRING "'string'" + NEWLINE + ENDMARKER""" + input = "hi hello a_name 32 42 'string'" + assert tree_from_string(expected, gram) == p.parse(input) + + def test_symbol(self): + gram = """parent: first_child second_child NEWLINE ENDMARKER +first_child: NAME age +second_child: STRING +age: NUMBER\n""" + p, gram = self.parser_for(gram, False) + expected = """ + parent + first_child + NAME "harry" + age + NUMBER "13" + second_child + STRING "'fred'" + NEWLINE + ENDMARKER""" + input = "harry 13 'fred'" + assert tree_from_string(expected, gram) == p.parse(input) + + def test_token(self): + p, gram = self.parser_for("foo: NAME") + expected = """ + foo + NAME "hi" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi") + py.test.raises(parser.ParseError, p.parse, "567") + p, gram = self.parser_for("foo: NUMBER NAME STRING") + expected = """ + foo + NUMBER "42" + NAME "hi" + STRING "'bar'" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("42 hi 'bar'") + + def test_optional(self): + p, gram = self.parser_for("foo: [NAME] 'end'") + expected = """ + foo + NAME "hi" + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi end") + expected = """ + foo + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("end") + + def test_grouping(self): + p, gram = self.parser_for( + "foo: ((NUMBER NAME | STRING) | 'second_option')") + expected = """ + foo + NUMBER "42" + NAME "hi" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("42 hi") + expected = """ + foo + STRING "'hi'" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("'hi'") + expected = """ + foo + NAME "second_option" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("second_option") + py.test.raises(parser.ParseError, p.parse, "42 a_name 'hi'") + py.test.raises(parser.ParseError, p.parse, "42 second_option") + + def test_alternative(self): + p, gram = self.parser_for("foo: (NAME | NUMBER)") + expected = """ + foo + NAME "hi" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi") + expected = """ + foo + NUMBER "42" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("42") + py.test.raises(parser.ParseError, p.parse, "hi 23") + py.test.raises(parser.ParseError, p.parse, "23 hi") + py.test.raises(parser.ParseError, p.parse, "'some string'") + + def test_keyword(self): + p, gram = self.parser_for("foo: 'key'") + expected = """ + foo + NAME "key" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("key") + py.test.raises(parser.ParseError, p.parse, "") + p, gram = self.parser_for("foo: NAME 'key'") + expected = """ + foo + NAME "some_name" + NAME "key" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("some_name key") + py.test.raises(parser.ParseError, p.parse, "some_name") + + def test_repeaters(self): + p, gram = self.parser_for("foo: NAME+ 'end'") + expected = """ + foo + NAME "hi" + NAME "bye" + NAME "nothing" + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi bye nothing end") + py.test.raises(parser.ParseError, p.parse, "end") + py.test.raises(parser.ParseError, p.parse, "hi bye") + p, gram = self.parser_for("foo: NAME* 'end'") + expected = """ + foo + NAME "hi" + NAME "bye" + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi bye end") + py.test.raises(parser.ParseError, p.parse, "hi bye") + expected = """ + foo + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("end") + + p, gram = self.parser_for("foo: (NAME | NUMBER)+ 'end'") + expected = """ + foo + NAME "a_name" + NAME "name_two" + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("a_name name_two end") + expected = """ + foo + NUMBER "42" + NAME "name" + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("42 name end") + py.test.raises(parser.ParseError, p.parse, "end") + p, gram = self.parser_for("foo: (NAME | NUMBER)* 'end'") + expected = """ + foo + NAME "hi" + NUMBER 42 + NAME "end" + NEWLINE + ENDMARKER""" + assert tree_from_string(expected, gram) == p.parse("hi 42 end") Modified: pypy/branch/newtrunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/test/test_compiler.py Mon Aug 31 15:37:16 2009 @@ -197,21 +197,25 @@ assert not space.eq_w(w_const, space.wrap("b")) assert not space.eq_w(w_const, space.wrap("c")) + _unicode_error_kind = "w_UnicodeError" + def test_unicodeliterals(self): + w_error = getattr(self.space, self._unicode_error_kind) + e = py.test.raises(OperationError, self.eval_string, "u'\\Ufffffffe'") ex = e.value ex.normalize_exception(self.space) - assert ex.match(self.space, self.space.w_UnicodeError) + assert ex.match(self.space, w_error) e = py.test.raises(OperationError, self.eval_string, "u'\\Uffffffff'") ex = e.value ex.normalize_exception(self.space) - assert ex.match(self.space, self.space.w_UnicodeError) + assert ex.match(self.space, w_error) e = py.test.raises(OperationError, self.eval_string, "u'\\U%08x'" % 0x110000) ex = e.value ex.normalize_exception(self.space) - assert ex.match(self.space, self.space.w_UnicodeError) + assert ex.match(self.space, w_error) def test_unicode_docstring(self): space = self.space @@ -637,6 +641,8 @@ def setup_method(self, method): self.compiler = CPythonCompiler(self.space) + _unicode_error_kind = "w_SyntaxError" + if sys.version_info < (2, 4): def skip_on_2_3(self): py.test.skip("syntax not supported by the CPython 2.3 compiler") @@ -646,6 +652,7 @@ elif sys.version_info < (2, 5): def skip_on_2_4(self): py.test.skip("syntax not supported by the CPython 2.4 compiler") + _unicode_error_kind = "w_UnicodeError" test_continue_in_nested_finally = skip_on_2_4 test_try_except_finally = skip_on_2_4 test_yield_in_finally = skip_on_2_4 @@ -717,42 +724,6 @@ ## py.test.skip("unsupported") class AppTestOptimizer: - def test_constant_fold_add(self): - import parser - class Folder(object): - def defaultvisit(self, node): - return node - - def __getattr__(self, attrname): - if attrname.startswith('visit'): - return self.defaultvisit - raise AttributeError(attrname) - - def visitAdd(self, node): - left = node.left - right = node.right - if isinstance(left, parser.ASTConst) and \ - isinstance(right, parser.ASTConst): - if type(left.value) == type(right.value): - return parser.ASTConst(left.value + right.value) - return node - - def hook(ast, enc, filename): - return ast.mutate(Folder()) - - parser.install_compiler_hook(hook) - code = compile("1+2", "", "eval") - parser.install_compiler_hook(None) - import dis, sys, StringIO - s = StringIO.StringIO() - so = sys.stdout - sys.stdout = s - try: - dis.dis(code) - finally: - sys.stdout = so - output = s.getvalue() - assert 'BINARY_ADD' not in output def test_remove_ending(self): source = """def f(): @@ -771,7 +742,48 @@ output = s.getvalue() assert output.count('LOAD_CONST') == 1 - + def test_none_constant(self): + import opcode + co = compile("def f(): return None", "", "exec").co_consts[0] + assert "None" not in co.co_names + co = co.co_code + op = ord(co[0]) + (ord(co[1]) << 8) + assert op == opcode.opmap["LOAD_CONST"] + + def test_tuple_constants(self): + ns = {} + exec "x = (1, 0); y = (1L, 0L)" in ns + assert isinstance(ns["x"][0], int) + assert isinstance(ns["y"][0], long) + + def test_division_folding(self): + def code(source): + return compile(source, "", "exec") + co = code("x = 10//4") + assert len(co.co_consts) == 2 + assert co.co_consts[0] == 2 + co = code("x = 10/4") + assert len(co.co_consts) == 3 + assert co.co_consts[:2] == (10, 4) + co = code("from __future__ import division\nx = 10/4") + assert co.co_consts[2] == 2.5 + + def test_tuple_folding(self): + co = compile("x = (1, 2, 3)", "", "exec") + assert co.co_consts == ((1, 2, 3), None) + co = compile("x = ()", "", "exec") + assert co.co_consts == ((), None) + + def test_unary_folding(self): + co = compile("x = -(3)", "", "exec") + assert co.co_consts[0] == -3 + co = compile("x = ~3", "", "exec") + assert co.co_consts[0] == ~3 + co = compile("x = +(-3)", "", "exec") + assert co.co_consts[0] == -3 + co = compile("x = not None", "", "exec") + assert co.co_consts[0] is True + def test_folding_of_binops_on_constants(self): def disassemble(func): from StringIO import StringIO Modified: pypy/branch/newtrunk/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/newtrunk/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/newtrunk/pypy/interpreter/test/test_syntax.py Mon Aug 31 15:37:16 2009 @@ -155,6 +155,7 @@ def f(): from a import * + x def g(): x @@ -169,23 +170,27 @@ def f(): from a import * + x class g: x def f(): exec "hi" + x = 5 class g: def h(): x def f(): from a import * + x = 4 class g: def h(): x def f(x): exec "hi" + x = 4 class g: x @@ -196,12 +201,14 @@ def f(x): exec "hi" + x = 5 class g: def h(): x def f(x): from a import * + x = 5 class g: def h(): x @@ -277,6 +284,37 @@ exec s + +class AppTestDecorators: + + def test_function_decorators(self): + def other(): + return 4 + def dec(f): + return other + ns = {} + ns["dec"] = dec + exec """@dec +def g(): + pass""" in ns + assert ns["g"] is other + assert ns["g"]() == 4 + + def test_application_order(self): + def dec1(f): + record.append(1) + return f + def dec2(f): + record.append(2) + return f + record = [] + ns = {"dec1" : dec1, "dec2" : dec2} + exec """@dec1 + at dec2 +def g(): pass""" in ns + assert record == [2, 1] + + class AppTestWith: def test_with_simple(self): @@ -602,7 +640,7 @@ except SyntaxError, e: assert e.lineno == 4 assert e.text.endswith('a b c d e\n') - assert e.offset == e.text.index('b') + 1 + assert e.offset == e.text.index('b') else: raise Exception("no SyntaxError??") Modified: pypy/branch/newtrunk/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/compiling.py Mon Aug 31 15:37:16 2009 @@ -4,7 +4,8 @@ from pypy.interpreter.pycode import PyCode from pypy.interpreter.baseobjspace import W_Root, ObjSpace -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError +from pypy.interpreter.astcompiler import consts, ast from pypy.interpreter.gateway import NoneNotWrapped def compile(space, w_source, filename, mode, flags=0, dont_inherit=0): @@ -20,16 +21,27 @@ compile; if absent or zero these statements do influence the compilation, in addition to any features explicitly specified. """ - if space.is_true(space.isinstance(w_source, space.w_unicode)): - # hack: encode the unicode string as UTF-8 and attach - # a BOM at the start - w_source = space.call_method(w_source, 'encode', space.wrap('utf-8')) - str_ = space.str_w(w_source) - str_ = '\xEF\xBB\xBF' + str_ + + ast_node = None + w_ast_type = space.gettypeobject(ast.AST.typedef) + str_ = None + if space.is_true(space.isinstance(w_source, w_ast_type)): + ast_node = space.interp_w(ast.mod, w_source) + ast_node.sync_app_attrs(space) + elif space.is_true(space.isinstance(w_source, space.w_unicode)): + w_utf_8_source = space.call_method(w_source, "encode", + space.wrap("utf-8")) + str_ = space.str_w(w_utf_8_source) + # This flag tells the parser to reject any coding cookies it sees. + flags |= consts.PyCF_SOURCE_IS_UTF8 else: str_ = space.str_w(w_source) ec = space.getexecutioncontext() + if flags & ~(ec.compiler.compiler_flags | consts.PyCF_AST_ONLY | + consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8): + raise OperationError(space.w_ValueError, + space.wrap("compile() unrecognized flags")) if not dont_inherit: caller = ec.gettopframe_nohidden() if caller: @@ -40,7 +52,14 @@ space.wrap("compile() arg 3 must be 'exec' " "or 'eval' or 'single'")) - code = ec.compiler.compile(str_, filename, mode, flags) + if ast_node is None: + if flags & consts.PyCF_AST_ONLY: + mod = ec.compiler.compile_to_ast(str_, filename, mode, flags) + return space.wrap(mod) + else: + code = ec.compiler.compile(str_, filename, mode, flags) + else: + code = ec.compiler.compile_ast(ast_node, filename, mode, flags) return space.wrap(code) # compile.unwrap_spec = [ObjSpace,W_Root,str,str,int,int] Modified: pypy/branch/newtrunk/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/branch/newtrunk/pypy/module/__builtin__/test/test_builtin.py Mon Aug 31 15:37:16 2009 @@ -400,6 +400,7 @@ raises(SyntaxError, compile, '-', '?', 'eval') raises(ValueError, compile, '"\\xt"', '?', 'eval') raises(ValueError, compile, '1+2', '?', 'maybenot') + raises(ValueError, compile, "\n", "", "exec", 0xff) raises(TypeError, compile, '1+2', 12, 34) def test_unicode_compile(self): Copied: pypy/branch/newtrunk/pypy/module/_ast/test/test_ast.py (from r67184, pypy/trunk/pypy/module/_ast/test/test_ast.py) ============================================================================== --- pypy/trunk/pypy/module/_ast/test/test_ast.py (original) +++ pypy/branch/newtrunk/pypy/module/_ast/test/test_ast.py Mon Aug 31 15:37:16 2009 @@ -56,13 +56,13 @@ return compile(node, "", "exec") mod = ast.Module() raises(AttributeError, getattr, mod, "body") - exc = raises(TypeError, com, mod)[1] + exc = raises(TypeError, com, mod).value assert str(exc) == "required attribute 'body' missing from Module" expr = ast.Name() expr.id = "hi" expr.ctx = ast.Load() expr.lineno = 4 - exc = raises(TypeError, com, ast.Module([ast.Expr(expr, 0, 0)]))[1] + exc = raises(TypeError, com, ast.Module([ast.Expr(expr, 0, 0)])).value assert str(exc) == "required attribute 'col_offset' missing from Name" def test_int(self): @@ -95,6 +95,15 @@ const.value = 5 assert const.value == 5 + def test_optional(self): + mod = self.get_ast("x(32)", "eval") + call = mod.body + assert call.starargs is None + assert call.kwargs is None + co = compile(mod, "", "eval") + ns = {"x" : lambda x: x} + assert eval(co, ns) == 32 + def test_list_syncing(self): ast = self.ast mod = ast.Module([ast.Lt()]) @@ -147,7 +156,7 @@ assert fr.body is body assert fr.lineno == 0 assert fr.col_offset == 1 - exc = raises(TypeError, ast.Module, 1, 2)[1] + exc = raises(TypeError, ast.Module, 1, 2).value msg = str(exc) assert msg == "Module constructor takes 0 or 1 positional arguments" raises(AttributeError, ast.Module, nothing=23) @@ -155,6 +164,9 @@ def test_future(self): mod = self.get_ast("from __future__ import with_statement") compile(mod, "", "exec") + mod = self.get_ast(""""I'm a docstring."\n +from __future__ import generators""") + compile(mod, "", "exec") mod = self.get_ast("from __future__ import with_statement; import y; " \ "from __future__ import nested_scopes") raises(SyntaxError, compile, mod, "", "exec") Modified: pypy/branch/newtrunk/pypy/module/symbol/__init__.py ============================================================================== --- pypy/branch/newtrunk/pypy/module/symbol/__init__.py (original) +++ pypy/branch/newtrunk/pypy/module/symbol/__init__.py Mon Aug 31 15:37:16 2009 @@ -5,10 +5,7 @@ """ from pypy.interpreter.mixedmodule import MixedModule - -# Forward imports so they run at startup time -import pypy.interpreter.pyparser.pythonlexer -import pypy.interpreter.pyparser.pythonparse +from pypy.interpreter.pyparser import pygram class Module(MixedModule): @@ -17,23 +14,11 @@ interpleveldefs = {} # see below -# Export the values from our custom symbol module. -# Skip negative values (the corresponding symbols are not visible in -# pure Python). -sym_name = {} - -def _init_symbols(grammar_version): - global sym_name - +def _init_symbols(): sym_name = {} - from pypy.interpreter.pyparser.pythonparse import make_pyparser - parser = make_pyparser(grammar_version) - - for name, val in parser.symbols.items(): - if val >= 0: - Module.interpleveldefs[name] = 'space.wrap(%d)' % val - sym_name[val] = name + for name, val in pygram.python_grammar.symbol_ids.iteritems(): + Module.interpleveldefs[name] = 'space.wrap(%d)' % val + sym_name[val] = name Module.interpleveldefs['sym_name'] = 'space.wrap(%r)' % (sym_name,) -# This is very evil -_init_symbols('2.5') +_init_symbols() Modified: pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py Mon Aug 31 15:37:16 2009 @@ -180,6 +180,27 @@ space.newtuple([w_BuiltinAssertionError]), w_dict) +def _exc_info(space, err): + """Hack the fact that exc_info() isn't set until a app except + block catches it.""" + err.normalize_exception(space) + frame = space.getexecutioncontext().framestack.top() + old = frame.last_exception + frame.last_exception = err + if not hasattr(space, '_w_ExceptionInfo'): + space._w_ExceptionInfo = space.appexec([], """(): + class _ExceptionInfo(object): + def __init__(self): + import sys + self.type, self.value, _ = sys.exc_info() + + return _ExceptionInfo +""") + try: + return space.call_function(space._w_ExceptionInfo) + finally: + frame.last_exception = old + def pypyraises(space, w_ExpectedException, w_expr, __args__): """A built-in function providing the equivalent of py.test.raises().""" args_w, kwds_w = __args__.unpack() @@ -199,14 +220,14 @@ space.exec_(source.compile(), frame.w_globals, w_locals) except OperationError, e: if e.match(space, w_ExpectedException): - return space.sys.call('exc_info') + return _exc_info(space, e) raise else: try: space.call_args(w_expr, __args__) except OperationError, e: if e.match(space, w_ExpectedException): - return space.sys.call('exc_info') + return _exc_info(space, e) raise raise OperationError(space.w_AssertionError, space.wrap("DID NOT RAISE")) Copied: pypy/branch/newtrunk/pypy/tool/pytest/test/test_appsupport.py (from r67184, pypy/trunk/pypy/tool/pytest/test/test_appsupport.py) ============================================================================== --- pypy/trunk/pypy/tool/pytest/test/test_appsupport.py (original) +++ pypy/branch/newtrunk/pypy/tool/pytest/test/test_appsupport.py Mon Aug 31 15:37:16 2009 @@ -2,5 +2,10 @@ def app_test_raises(): info = raises(TypeError, id) - assert info[0] is TypeError - assert isinstance(info[1], TypeError) + assert info.type is TypeError + assert isinstance(info.value, TypeError) + + x = 43 + info = raises(ZeroDivisionError, "x/0") + assert info.type is ZeroDivisionError + assert isinstance(info.value, ZeroDivisionError) Modified: pypy/branch/newtrunk/pypy/tool/stdlib_opcode.py ============================================================================== --- pypy/branch/newtrunk/pypy/tool/stdlib_opcode.py (original) +++ pypy/branch/newtrunk/pypy/tool/stdlib_opcode.py Mon Aug 31 15:37:16 2009 @@ -18,6 +18,10 @@ for name in __all__: if name in opcode_dict: globals()[name] = opcode_dict[name] +globals().update(opmap) +SLICE = opmap["SLICE+0"] +STORE_SLICE = opmap["STORE_SLICE+0"] +DELETE_SLICE = opmap["DELETE_SLICE+0"] opcode_method_names = ['MISSING_OPCODE'] * 256 for name, index in opmap.items(): From pedronis at codespeak.net Mon Aug 31 16:00:14 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 16:00:14 +0200 (CEST) Subject: [pypy-svn] r67362 - in pypy/branch/newtrunk/pypy: interpreter/pyparser/data objspace/std objspace/std/test Message-ID: <20090831140014.B2023168023@codespeak.net> Author: pedronis Date: Mon Aug 31 16:00:13 2009 New Revision: 67362 Removed: pypy/branch/newtrunk/pypy/interpreter/pyparser/data/Grammar2.5_2 pypy/branch/newtrunk/pypy/objspace/std/test/test_viewlist.py pypy/branch/newtrunk/pypy/objspace/std/viewlist.py Log: (iko, pedronis) remove files that should have gone away From pedronis at codespeak.net Mon Aug 31 16:20:42 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 16:20:42 +0200 (CEST) Subject: [pypy-svn] r67363 - pypy/branch/newtrunk/pypy/tool/pytest Message-ID: <20090831142042.91EEB168014@codespeak.net> Author: pedronis Date: Mon Aug 31 16:20:41 2009 New Revision: 67363 Modified: pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py Log: (iko, pedronis) framestack is no more, use the new interface Modified: pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/newtrunk/pypy/tool/pytest/appsupport.py Mon Aug 31 16:20:41 2009 @@ -184,7 +184,7 @@ """Hack the fact that exc_info() isn't set until a app except block catches it.""" err.normalize_exception(space) - frame = space.getexecutioncontext().framestack.top() + frame = space.getexecutioncontext().gettopframe() old = frame.last_exception frame.last_exception = err if not hasattr(space, '_w_ExceptionInfo'): From arigo at codespeak.net Mon Aug 31 16:36:49 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 16:36:49 +0200 (CEST) Subject: [pypy-svn] r67364 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport Message-ID: <20090831143649.E3ED9168026@codespeak.net> Author: arigo Date: Mon Aug 31 16:36:46 2009 New Revision: 67364 Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Log: Translation fixes. Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Mon Aug 31 16:36:46 2009 @@ -29,6 +29,8 @@ # SizeDescrs class SizeDescr(AbstractDescr): + size = 0 # help translation + def __init__(self, size): self.size = size @@ -53,6 +55,8 @@ # FieldDescrs class BaseFieldDescr(AbstractDescr): + offset = 0 # help translation + _clsname = '' def __init__(self, offset): self.offset = offset From pedronis at codespeak.net Mon Aug 31 17:07:22 2009 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Aug 2009 17:07:22 +0200 (CEST) Subject: [pypy-svn] r67365 - pypy/branch/newtrunk/lib-python Message-ID: <20090831150722.616E2168026@codespeak.net> Author: pedronis Date: Mon Aug 31 17:07:21 2009 New Revision: 67365 Modified: pypy/branch/newtrunk/lib-python/conftest.py Log: substitute hack with proper module availability check Modified: pypy/branch/newtrunk/lib-python/conftest.py ============================================================================== --- pypy/branch/newtrunk/lib-python/conftest.py (original) +++ pypy/branch/newtrunk/lib-python/conftest.py Mon Aug 31 17:07:21 2009 @@ -573,10 +573,6 @@ regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') - pypy_options = [] - pypy_options.extend( - ['--withmod-%s' % mod for mod in regrtest.usemodules]) - sopt = " ".join(pypy_options) # we use the regrverbose script to run the test, but don't get # confused: it still doesn't set verbose to True by default if # regrtest.outputpath() is true, because output tests get confused @@ -595,7 +591,16 @@ if not execpath.check(): execpath = py.path.local.sysfind(option.pypy) if not execpath: - raise LookupError("could not find executable %r" %(option.pypy,)) + raise LookupError("could not find executable %r" % + (option.pypy,)) + + # check modules + info = py.process.cmdexec("%s --info" % execpath) + for mod in regrtest.usemodules: + if "objspace.usemodules.%s: False" % mod in info: + py.test.skip("%s module not included in %s" % (mod, + execpath)) + cmd = "%s %s %s %s" %( execpath, regrrun, regrrun_verbosity, fspath.purebasename) @@ -605,6 +610,11 @@ python, watchdog_script, TIMEOUT, cmd) else: + pypy_options = [] + pypy_options.extend( + ['--withmod-%s' % mod for mod in regrtest.usemodules]) + sopt = " ".join(pypy_options) + cmd = "%s %s %d %s %s %s %s %s" %( python, alarm_script, TIMEOUT, pypy_script, sopt, @@ -626,9 +636,6 @@ else: msg = regrtest.skip py.test.skip(msg) - # XXX evil hack - if 'thread' in regrtest.usemodules: - py.test.skip("uses thread") (skipped, exit_status, test_stdout, test_stderr) = self.getresult(regrtest) if skipped: From arigo at codespeak.net Mon Aug 31 17:23:40 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 17:23:40 +0200 (CEST) Subject: [pypy-svn] r67366 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090831152340.E322B168025@codespeak.net> Author: arigo Date: Mon Aug 31 17:23:36 2009 New Revision: 67366 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: A failing test derived from this code in pypy-c-jit: while a < N: t = (a+1,) (a,) = t Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/oparser.py Mon Aug 31 17:23:36 2009 @@ -186,8 +186,10 @@ ops = [] newlines = [] for line in lines: - if not line.strip() or line.strip().startswith("#"): - continue # a comment + if '#' in line: + line = line[:line.index('#')] # remove comment + if not line.strip(): + continue # a comment or empty line newlines.append(line) base_indent, inpargs = self.parse_inpargs(newlines[0]) newlines = newlines[1:] Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 31 17:23:36 2009 @@ -74,8 +74,25 @@ sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S))) + T = lltype.GcStruct('TUPLE', + ('c', lltype.Signed), + ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) + tsize = cpu.sizeof(T) + cdescr = cpu.fielddescrof(T, 'c') + ddescr = cpu.fielddescrof(T, 'd') + arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE))) + + U = lltype.GcStruct('U', + ('parent', OBJECT), + ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) + u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable) + usize = cpu.sizeof(U) + onedescr = cpu.fielddescrof(U, 'one') + cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), - cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2)} + cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), + cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U)} namespace = locals() class OOtypeMixin(object): @@ -117,6 +134,19 @@ sbox = BoxObj(ootype.cast_to_object(ootype.new(S))) arraydescr2 = cpu.arraydescrof(ootype.Array(S)) + T = ootype.Record({'c': ootype.Signed, + 'd': ootype.Array(NODE)}) + tsize = cpu.typedescrof(T) + cdescr = cpu.fielddescrof(T, 'c') + ddescr = cpu.fielddescrof(T, 'd') + arraydescr3 = cpu.arraydescrof(ootype.Array(NODE)) + + U = ootype.Instance('U', ootype.ROOT, {'one': ootype.Array(NODE)}) + usize = cpu.typedescrof(U) + onedescr = cpu.fielddescrof(U, 'one') + u_vtable = ootype.runtimeClass(U) + u_vtable_adr = ootype.cast_to_object(u_vtable) + # force a consistent order valuedescr.sort_key() nextdescr.sort_key() @@ -124,7 +154,8 @@ bdescr.sort_key() cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE), - node_vtable_adr2: cpu.typedescrof(NODE2)} + node_vtable_adr2: cpu.typedescrof(NODE2), + u_vtable_adr: cpu.typedescrof(U)} namespace = locals() class BaseTest(object): @@ -739,6 +770,74 @@ """ self.find_nodes(ops, 'Not, Not') + def test_find_nodes_bug_1(self): + py.test.skip("fails!") + ops = """ + [p12] + i16 = ooisnull(p12) + guard_false(i16) + fail() + guard_class(p12, ConstClass(node_vtable)) + fail() + guard_class(p12, ConstClass(node_vtable)) + fail() + i22 = getfield_gc_pure(p12, descr=valuedescr) + escape(i22) + i25 = ooisnull(p12) + guard_false(i25) + fail() + guard_class(p12, ConstClass(node_vtable)) + fail() + guard_class(p12, ConstClass(node_vtable)) + fail() + i29 = getfield_gc_pure(p12, descr=valuedescr) + i31 = int_add_ovf(i29, 1) + guard_no_overflow() + fail() + p33 = new_with_vtable(ConstClass(node_vtable)) # NODE + setfield_gc(p33, i31, descr=valuedescr) + # + p35 = new_array(1, descr=arraydescr3) # Array(NODE) + setarrayitem_gc(p35, 0, p33, descr=arraydescr3) + p38 = new_with_vtable(ConstClass(u_vtable)) # U + setfield_gc(p38, p35, descr=onedescr) + i39 = ooisnull(p38) + guard_false(i39) + fail() + i40 = oononnull(p38) + guard_true(i40) + fail() + guard_class(p38, ConstClass(u_vtable)) + fail() + p42 = getfield_gc(p38, descr=onedescr) # Array(NODE) + i43 = arraylen_gc(p42, descr=arraydescr3) + i45 = int_sub(i43, 0) + p46 = new(descr=tsize) # T + setfield_gc(p46, i45, descr=cdescr) + p47 = new_array(i45, descr=arraydescr3) # Array(NODE) + setfield_gc(p46, p47, descr=ddescr) + i48 = int_lt(0, i43) + guard_true(i48) + fail() + p49 = getarrayitem_gc(p42, 0, descr=arraydescr3) # NODE + p50 = getfield_gc(p46, descr=ddescr) # Array(NODE) + setarrayitem_gc(p50, 0, p49, descr=arraydescr3) + i52 = int_lt(1, i43) + guard_false(i52) + fail() + i53 = getfield_gc(p46, descr=cdescr) + i55 = int_ne(i53, 1) + guard_false(i55) + fail() + p56 = getfield_gc(p46, descr=ddescr) # Array(NODE) + p58 = getarrayitem_gc(p56, 0, descr=arraydescr3) # NODE + i59 = ooisnull(p38) + guard_false(i59) + fail() + jump(p58) + """ + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') + # ------------------------------ # Bridge tests From arigo at codespeak.net Mon Aug 31 17:50:07 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 17:50:07 +0200 (CEST) Subject: [pypy-svn] r67367 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090831155007.02713168025@codespeak.net> Author: arigo Date: Mon Aug 31 17:50:07 2009 New Revision: 67367 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: More tests and a fix in optimizefindnode.py. The original test still fails... Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Mon Aug 31 17:50:07 2009 @@ -127,6 +127,16 @@ self.nodes[box] = node return node + def is_constant_box(self, box): + if isinstance(box, Const): + return True + try: + node = self.nodes[box] + except KeyError: + return False + else: + return node.is_constant() + def find_nodes(self, operations): for op in operations: opnum = op.opnum @@ -171,10 +181,10 @@ def find_nodes_NEW_ARRAY(self, op): lengthbox = op.args[0] - if not isinstance(lengthbox, ConstInt): + if not self.is_constant_box(lengthbox): return # var-sized arrays are not virtual arraynode = InstanceNode() - arraynode.arraysize = lengthbox.value + arraynode.arraysize = lengthbox.getint() arraynode.arraydescr = op.descr self.nodes[op.result] = arraynode @@ -225,7 +235,7 @@ def find_nodes_SETARRAYITEM_GC(self, op): indexbox = op.args[1] - if not isinstance(indexbox, ConstInt): + if not self.is_constant_box(indexbox): self.find_nodes_default(op) # not a Const index return arraynode = self.getnode(op.args[0]) @@ -235,18 +245,18 @@ return # nothing to be gained from tracking the item if arraynode.curitems is None: arraynode.curitems = {} - arraynode.curitems[indexbox.value] = itemnode + arraynode.curitems[indexbox.getint()] = itemnode arraynode.add_escape_dependency(itemnode) def find_nodes_GETARRAYITEM_GC(self, op): indexbox = op.args[1] - if not isinstance(indexbox, ConstInt): + if not self.is_constant_box(indexbox): self.find_nodes_default(op) # not a Const index return arraynode = self.getnode(op.args[0]) if arraynode.escaped: return # nothing to be gained from tracking the item - index = indexbox.value + index = indexbox.getint() if arraynode.curitems is not None and index in arraynode.curitems: itemnode = arraynode.curitems[index] elif arraynode.origitems is not None and index in arraynode.origitems: Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 31 17:50:07 2009 @@ -770,8 +770,47 @@ """ self.find_nodes(ops, 'Not, Not') + def test_find_nodes_arithmetic_propagation_bug_0(self): + ops = """ + [p1] + i1 = getarrayitem_gc(p1, 0, descr=arraydescr) + escape(i1) + i2 = int_add(0, 1) + p2 = new_array(i2, descr=arraydescr) + i3 = escape() + setarrayitem_gc(p2, 0, i3, descr=arraydescr) + jump(p2) + """ + self.find_nodes(ops, 'VArray(arraydescr, Not)', i2=1) + + def test_find_nodes_arithmetic_propagation_bug_1(self): + ops = """ + [p1] + i1 = getarrayitem_gc(p1, 0, descr=arraydescr) + escape(i1) + i2 = same_as(1) + p2 = new_array(i2, descr=arraydescr) + setarrayitem_gc(p2, 0, 5) + jump(p2) + """ + self.find_nodes(ops, 'VArray(arraydescr, Not)', i2=1) + + def test_find_nodes_arithmetic_propagation_bug_2(self): + ops = """ + [p1] + i0 = int_sub(17, 17) + i1 = getarrayitem_gc(p1, i0, descr=arraydescr) + escape(i1) + i2 = int_add(0, 1) + p2 = new_array(i2, descr=arraydescr) + i3 = escape() + setarrayitem_gc(p2, i0, i3, descr=arraydescr) + jump(p2) + """ + self.find_nodes(ops, 'VArray(arraydescr, Not)', i2=1, i0=0) + def test_find_nodes_bug_1(self): - py.test.skip("fails!") + py.test.skip("still a bug") ops = """ [p12] i16 = ooisnull(p12) @@ -836,7 +875,9 @@ fail() jump(p58) """ - self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)') + self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)', + i16=0, i25=0, i39=0, i52=0, i55=0, i59=0, + i43=1, i45=1, i48=1, i40=1) # ------------------------------ # Bridge tests From cfbolz at codespeak.net Mon Aug 31 17:52:22 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 17:52:22 +0200 (CEST) Subject: [pypy-svn] r67368 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test Message-ID: <20090831155222.74154168026@codespeak.net> Author: cfbolz Date: Mon Aug 31 17:52:21 2009 New Revision: 67368 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py Log: the test expects the wrong exception, could be fixed. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_recursive.py Mon Aug 31 17:52:21 2009 @@ -14,6 +14,5 @@ # ==========> test_recursive.py - @py.test.mark.xfail def test_inline_faulty_can_inline(self): - test_recursive.RecursiveTests.test_inline_faulty_can_inline(self) + py.test.skip("XXX does not work with LLException") From cfbolz at codespeak.net Mon Aug 31 17:55:02 2009 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 31 Aug 2009 17:55:02 +0200 (CEST) Subject: [pypy-svn] r67369 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090831155502.60FA9168026@codespeak.net> Author: cfbolz Date: Mon Aug 31 17:55:01 2009 New Revision: 67369 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py Log: test and fix for inlining: if a guard fails in a recursive portal call, strange things could happen so far. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Mon Aug 31 17:55:01 2009 @@ -809,7 +809,8 @@ pass # xxx? def generate_merge_point(self, pc, varargs): - if self.metainterp.is_blackholing(): + # XXX could be sped up by calling the portal if in_recursion is non-zero + if self.metainterp.is_blackholing() and not self.metainterp.in_recursion: raise self.metainterp.staticdata.ContinueRunningNormally(varargs) num_green_args = self.metainterp.staticdata.num_green_args for i in range(num_green_args): @@ -1246,7 +1247,6 @@ debug_print('~~~ LEAVE', self.history.extratext) def interpret(self): - self.in_recursion = 0 if we_are_translated(): self._interpret() else: @@ -1476,6 +1476,7 @@ *args[1:]) def initialize_state_from_start(self, *args): + self.in_recursion = 0 self.staticdata._setup_once() self.staticdata.profiler.start_tracing() self.create_empty_history() @@ -1492,6 +1493,7 @@ def initialize_state_from_guard_failure(self, guard_failure): # guard failure: rebuild a complete MIFrame stack + self.in_recursion = 0 resumedescr = guard_failure.descr assert isinstance(resumedescr, compile.ResumeGuardDescr) warmrunnerstate = self.staticdata.state @@ -1617,7 +1619,10 @@ jitcode, pc, exception_target = resumereader.consume_frame_info() env = resumereader.consume_boxes() f = self.newframe(jitcode) + if jitcode is self.staticdata.portal_code: + self.in_recursion += 1 f.setup_resume_at_op(pc, exception_target, env) + self.in_recursion -= 1 # always one portal around def check_synchronized_virtualizable(self): if not we_are_translated(): Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py Mon Aug 31 17:55:01 2009 @@ -176,6 +176,41 @@ else: py.test.fail("DID NOT RAISE") + def test_inner_failure(self): + from pypy.rpython.annlowlevel import hlstr + def p(code, pc): + code = hlstr(code) + return "%s %d %s" % (code, pc, code[pc]) + myjitdriver = JitDriver(greens=['code', 'pc'], reds=['n'], get_printable_location=p) + def f(code, n): + pc = 0 + while pc < len(code): + + myjitdriver.jit_merge_point(n=n, code=code, pc=pc) + op = code[pc] + if op == "-": + n -= 1 + elif op == "c": + n = f("---i---", n) + elif op == "i": + if n % 5 == 1: + return n + elif op == "l": + if n > 0: + myjitdriver.can_enter_jit(n=n, code=code, pc=0) + pc = 0 + continue + else: + assert 0 + pc += 1 + return n + def main(n): + return f("c-l", n) + print main(100) + res = self.meta_interp(main, [100], optimizer=simple_optimize) + assert res == 0 + + class TestLLtype(RecursiveTests, LLJitMixin): pass From arigo at codespeak.net Mon Aug 31 17:56:00 2009 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Aug 2009 17:56:00 +0200 (CEST) Subject: [pypy-svn] r67370 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test Message-ID: <20090831155600.694FD168025@codespeak.net> Author: arigo Date: Mon Aug 31 17:55:59 2009 New Revision: 67370 Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Log: Finish off test_find_nodes_bug_1: arraylen_gc returns a *constant* result if applied to a virtual array. Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Mon Aug 31 17:55:59 2009 @@ -166,7 +166,6 @@ find_nodes_OOISNULL = find_nodes_no_escape find_nodes_OOIS = find_nodes_no_escape find_nodes_OOISNOT = find_nodes_no_escape - find_nodes_ARRAYLEN_GC = find_nodes_no_escape find_nodes_INSTANCEOF = find_nodes_no_escape def find_nodes_NEW_WITH_VTABLE(self, op): @@ -188,6 +187,12 @@ arraynode.arraydescr = op.descr self.nodes[op.result] = arraynode + def find_nodes_ARRAYLEN_GC(self, op): + arraynode = self.getnode(op.args[0]) + if arraynode.arraydescr is not None: + assert op.result.getint() == arraynode.arraysize + self.set_constant_node(op.result) + def find_nodes_GUARD_CLASS(self, op): instnode = self.getnode(op.args[0]) if instnode.fromstart: # only useful (and safe) in this case Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Aug 31 17:55:59 2009 @@ -809,8 +809,21 @@ """ self.find_nodes(ops, 'VArray(arraydescr, Not)', i2=1, i0=0) + def test_find_nodes_arithmetic_propagation_bug_3(self): + ops = """ + [p1] + i1 = getarrayitem_gc(p1, 0, descr=arraydescr) + escape(i1) + p3 = new_array(1, descr=arraydescr) + i2 = arraylen_gc(p3, descr=arraydescr) + p2 = new_array(i2, descr=arraydescr) + i3 = escape() + setarrayitem_gc(p2, 0, i3, descr=arraydescr) + jump(p2) + """ + self.find_nodes(ops, 'VArray(arraydescr, Not)', i2=1) + def test_find_nodes_bug_1(self): - py.test.skip("still a bug") ops = """ [p12] i16 = ooisnull(p12)