Esempio n. 1
0
def test_simple_read():
    b1, b2, b3 = [BoxInt(), BoxPtr(), BoxInt()]
    c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)]
    storage = Storage()
    storage.rd_consts = [c1, c2, c3]
    numb = Numbering(None, [tag(0, TAGBOX), tag(1, TAGBOX), tag(2, TAGBOX)])
    numb = Numbering(numb, [tag(1, TAGCONST), tag(2, TAGCONST)])
    numb = Numbering(numb, [
        tag(0, TAGBOX),
        tag(0, TAGCONST), NULLREF,
        tag(0, TAGBOX),
        tag(1, TAGBOX)
    ])
    storage.rd_numb = numb
    storage.rd_virtuals = None

    b1s, b2s, b3s = [BoxInt(), BoxPtr(), BoxInt()]
    assert b1s != b3s
    reader = ResumeDataReader(storage, [b1s, b2s, b3s], MyMetaInterp())
    lst = reader.consume_boxes()
    assert lst == [b1s, ConstInt(1), LLtypeMixin.cpu.ts.CONST_NULL, b1s, b2s]
    lst = reader.consume_boxes()
    assert lst == [ConstInt(2), ConstInt(3)]
    lst = reader.consume_boxes()
    assert lst == [b1s, b2s, b3s]
Esempio n. 2
0
 def get_token_for_call(self, cpu):
     if self.loop_token is not None:
         return self.loop_token
     args = [BoxInt()] + self.instantiate_arg_classes()
     if self.get_result_size(cpu.translate_support_code) == 0:
         result = None
         result_list = []
     else:
         if self.returns_a_pointer():
             result = BoxPtr()
         elif self.returns_a_float():
             result = BoxFloat()
         else:
             result = BoxInt()
         result_list = [result]
     operations = [
         ResOperation(rop.CALL, args[:], result, self),
         ResOperation(rop.GUARD_NO_EXCEPTION, [],
                      None,
                      descr=BasicFailDescr()),
         ResOperation(rop.FINISH, result_list, None, descr=BasicFailDescr())
     ]
     operations[1].fail_args = []
     loop_token = LoopToken()
     # note: the 'args' that we pass below is not the same object as the
     # 'args[:]' that was passed above to ResOperation, because we want
     # the argument to ResOperation to be non-resizable, but the argument
     # to compile_loop to be resizable.
     cpu.compile_loop(args, operations, loop_token)
     self.loop_token = loop_token
     return loop_token
Esempio n. 3
0
def test_rebuild_from_resumedata_with_virtualizable():
    b1, b2, b3, b4 = [BoxInt(), BoxPtr(), BoxInt(), BoxPtr()]
    c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)]
    storage = Storage()
    fs = [
        FakeFrame("code0", 0, -1, b1, c1, b2),
        FakeFrame("code1", 3, 7, b3, c2, b1),
        FakeFrame("code2", 9, -1, c3, b2)
    ]
    capture_resumedata(fs, [b4], storage)
    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
    modifier = ResumeDataVirtualAdder(storage, memo)
    liveboxes = modifier.finish({})
    metainterp = MyMetaInterp()

    b1t, b2t, b3t, b4t = [BoxInt(), BoxPtr(), BoxInt(), BoxPtr()]
    newboxes = _resume_remap(liveboxes, [b1, b2, b3, b4], b1t, b2t, b3t, b4t)

    result = rebuild_from_resumedata(metainterp, newboxes, storage, True)
    assert result == [b4t]
    fs2 = [
        FakeFrame("code0", 0, -1, b1t, c1, b2t),
        FakeFrame("code1", 3, 7, b3t, c2, b1t),
        FakeFrame("code2", 9, -1, c3, b2t)
    ]
    assert metainterp.framestack == fs2
Esempio n. 4
0
def test_ResumeDataLoopMemo_number_boxes():
    memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
    b1, b2 = [BoxInt(), BoxInt()]
    assert memo.num_cached_boxes() == 0
    boxes = []
    num = memo.assign_number_to_box(b1, boxes)
    assert num == -1
    assert boxes == [b1]
    assert memo.num_cached_boxes() == 1
    boxes = [None]
    num = memo.assign_number_to_box(b1, boxes)
    assert num == -1
    assert boxes == [b1]
    num = memo.assign_number_to_box(b2, boxes)
    assert num == -2
    assert boxes == [b1, b2]

    assert memo.num_cached_boxes() == 2
    boxes = [None, None]
    num = memo.assign_number_to_box(b2, boxes)
    assert num == -2
    assert boxes == [None, b2]
    num = memo.assign_number_to_box(b1, boxes)
    assert num == -1
    assert boxes == [b1, b2]

    memo.clear_box_virtual_numbers()
    assert memo.num_cached_boxes() == 0
Esempio n. 5
0
def test_rebuild_from_resumedata_two_guards_w_shared_virtuals():
    b1, b2, b3, b4, b5, b6 = [BoxPtr(), BoxPtr(), BoxInt(), BoxPtr(), BoxInt(), BoxInt()]
    c1, c2, c3, c4 = [ConstInt(1), ConstInt(2), ConstInt(3),
                      LLtypeMixin.nodebox.constbox()]
    storage = Storage()
    fs = [FakeFrame("code0", 0, -1, c1, b2, b3)]
    capture_resumedata(fs, None, [], storage)
    
    memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
    values = {b2: virtual_value(b2, b5, c4)}
    modifier = ResumeDataVirtualAdder(storage, memo)
    liveboxes = modifier.finish(values)
    assert len(storage.rd_virtuals) == 1
    assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
                                                tag(0, TAGCONST)]

    storage2 = Storage()
    fs = [FakeFrame("code0", 0, -1, b1, b4, b2)]
    capture_resumedata(fs, None, [], storage2)
    values[b4] = virtual_value(b4, b6, c4)
    modifier = ResumeDataVirtualAdder(storage2, memo)
    liveboxes = modifier.finish(values)
    assert len(storage2.rd_virtuals) == 2
    assert storage2.rd_virtuals[1].fieldnums == storage.rd_virtuals[0].fieldnums
    assert storage2.rd_virtuals[1] is storage.rd_virtuals[0]
Esempio n. 6
0
 def __init__(self, cpu, cliloop):
     self.setoptions()
     self.cpu = cpu
     self.name = cliloop.get_fresh_cli_name()
     self.cliloop = cliloop
     self.boxes = {}  # box --> local var
     self.branches = []
     self.branchlabels = []
     self.consts = {}  # object --> index
     self.meth_wrapper = self._get_meth_wrapper()
     self.il = self.meth_wrapper.get_il_generator()
     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))
         self.av_ZeroDivisionError = ConstObj(
             ootype.cast_to_object(cpu.ll_zero_exc))
     else:
         self.av_OverflowError = None
         self.av_ZeroDivisionError = None
     self.box2type = {}
Esempio n. 7
0
def test_execute_nonspec():
    cpu = FakeCPU()
    descr = FakeDescr()
    # cases with a descr
    # arity == -1
    argboxes = [BoxInt(321), ConstInt(123)]
    box = execute_nonspec(cpu, rop.CALL, argboxes, descr)
    assert box.args == ('call', argboxes, descr)
    # arity == 0
    box = execute_nonspec(cpu, rop.NEW, [], descr)
    assert box.args == ('new', descr)
    # arity == 1
    box1 = BoxInt(515)
    box = execute_nonspec(cpu, rop.ARRAYLEN_GC, [box1], descr)
    assert box.args == ('arraylen_gc', box1, descr)
    # arity == 2
    box2 = BoxInt(222)
    box = execute_nonspec(cpu, rop.SETFIELD_GC, [box1, box2], descr)
    assert box.args == ('setfield_gc', box1, box2, descr)
    # arity == 3
    box3 = BoxInt(-33)
    box = execute_nonspec(cpu, rop.SETARRAYITEM_GC, [box1, box2, box3], descr)
    assert box.args == ('setarrayitem_gc', box1, box2, box3, descr)
    # cases without descr
    # arity == 1
    box = execute_nonspec(cpu, rop.INT_INVERT, [box1])
    assert box.value == ~515
    # arity == 2
    box = execute_nonspec(cpu, rop.INT_LSHIFT, [box1, BoxInt(3)])
    assert box.value == 515 << 3
    # arity == 3
    box = execute_nonspec(cpu, rop.STRSETITEM, [box1, box2, box3])
    assert box.args == ('strsetitem', box1, box2, box3)
Esempio n. 8
0
def test__make_virtual():
    b1, b2 = BoxInt(), BoxInt()
    vbox = BoxPtr()
    modifier = ResumeDataVirtualAdder(None, None)
    modifier.liveboxes_from_env = {}
    modifier.liveboxes = {}
    modifier.virtuals = []
    modifier.vfieldboxes = []
    modifier.make_virtual(vbox, None, ['a', 'b'], [b1, b2])
    assert modifier.liveboxes == {
        vbox: tag(0, TAGVIRTUAL),
        b1: UNASSIGNED,
        b2: UNASSIGNED
    }
    assert len(modifier.virtuals) == 1
    assert modifier.vfieldboxes == [[b1, b2]]

    modifier = ResumeDataVirtualAdder(None, None)
    modifier.liveboxes_from_env = {vbox: tag(0, TAGVIRTUAL)}
    modifier.liveboxes = {}
    modifier.virtuals = [None]
    modifier.vfieldboxes = [None]
    modifier.make_virtual(vbox, None, ['a', 'b', 'c'], [b1, b2, vbox])
    assert modifier.liveboxes == {
        b1: UNASSIGNED,
        b2: UNASSIGNED,
        vbox: tag(0, TAGVIRTUAL)
    }
    assert len(modifier.virtuals) == 1
    assert modifier.vfieldboxes == [[b1, b2, vbox]]
Esempio n. 9
0
    def test_overflow_mc(self):
        from pypy.jit.backend.x86.assembler import MachineCodeBlockWrapper

        orig_size = MachineCodeBlockWrapper.MC_SIZE
        MachineCodeBlockWrapper.MC_SIZE = 1024
        old_mc = self.cpu.assembler.mc
        old_mc2 = self.cpu.assembler.mc2
        self.cpu.assembler.mc = None
        try:
            ops = []
            base_v = BoxInt()
            v = base_v
            for i in range(1024):
                next_v = BoxInt()
                ops.append(ResOperation(rop.INT_ADD, [v, ConstInt(1)], next_v))
                v = next_v
            ops.append(
                ResOperation(rop.FINISH, [v], None, descr=BasicFailDescr()))
            looptoken = LoopToken()
            self.cpu.compile_loop([base_v], ops, looptoken)
            assert self.cpu.assembler.mc != old_mc  # overflowed
            self.cpu.set_future_value_int(0, base_v.value)
            self.cpu.execute_token(looptoken)
            assert self.cpu.get_latest_value_int(0) == 1024
        finally:
            MachineCodeBlockWrapper.MC_SIZE = orig_size
            self.cpu.assembler.mc = old_mc
            self.cpu.assembler.mc2 = old_mc2
Esempio n. 10
0
 def test_ops_offset(self):
     from pypy.rlib import debug
     i0 = BoxInt()
     i1 = BoxInt()
     i2 = BoxInt()
     looptoken = JitCellToken()
     targettoken = TargetToken()
     operations = [
         ResOperation(rop.LABEL, [i0], None, descr=targettoken),
         ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
         ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
         ResOperation(rop.JUMP, [i1], None, descr=targettoken),
         ]
     inputargs = [i0]
     debug._log = dlog = debug.DebugLog()
     info = self.cpu.compile_loop(inputargs, operations, looptoken)
     ops_offset = info.ops_offset
     debug._log = None
     #
     assert ops_offset is looptoken._x86_ops_offset
     # 2*(getfield_raw/int_add/setfield_raw) + ops + None
     assert len(ops_offset) == 2*3 + len(operations) + 1
     assert (ops_offset[operations[0]] <=
             ops_offset[operations[1]] <=
             ops_offset[operations[2]] <=
             ops_offset[None])
Esempio n. 11
0
 def box_for_var(self, elem):
     try:
         return self._cache[self.type_system, elem]
     except KeyError:
         pass
     if elem.startswith('i'):
         # 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
         ts = getattr(self.cpu, 'ts', llhelper)
         box = ts.BoxRef()
         _box_counter_more_than(elem[1:])
     else:
         for prefix, boxclass in self.boxkinds.iteritems():
             if elem.startswith(prefix):
                 box = boxclass()
                 break
         else:
             raise ParseError("Unknown variable type: %s" % elem)
     self._cache[self.type_system, elem] = box
     box._str = elem
     return box
Esempio n. 12
0
 def box_for_var(self, elem):
     try:
         return self._cache[self.type_system, elem]
     except KeyError:
         pass
     if elem.startswith('i'):
         # 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
         ts = getattr(self.cpu, 'ts', llhelper)
         box = ts.BoxRef()
         _box_counter_more_than(elem[1:])
     else:
         for prefix, boxclass in self.boxkinds.iteritems():
             if elem.startswith(prefix):
                 box = boxclass()
                 break
         else:
             raise ParseError("Unknown variable type: %s" % elem)
     self._cache[self.type_system, elem] = box
     box._str = elem
     return box
Esempio n. 13
0
 def get_token_for_call(self, cpu):
     if self.loop_token is not None:
         return self.loop_token
     args = [BoxInt()] + self.instantiate_arg_classes()
     if self.get_result_size(cpu.translate_support_code) == 0:
         result = None
         result_list = []
     else:
         if self.returns_a_pointer():
             result = BoxPtr()
         elif self.returns_a_float():
             result = BoxFloat()
         else:
             result = BoxInt()
         result_list = [result]
     operations = [
         ResOperation(rop.CALL, args, result, self),
         ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                      descr=BasicFailDescr()),
         ResOperation(rop.FINISH, result_list, None,
                      descr=BasicFailDescr())]
     operations[1].fail_args = []
     loop_token = LoopToken()
     cpu.compile_loop(args, operations, loop_token)
     self.loop_token = loop_token
     return loop_token
Esempio n. 14
0
def test_unwrap():
    S = lltype.GcStruct('S')
    p = lltype.malloc(S)
    po = lltype.cast_opaque_ptr(llmemory.GCREF, p)
    assert unwrap(lltype.Void, BoxInt(42)) is None
    assert unwrap(lltype.Signed, BoxInt(42)) == 42
    assert unwrap(lltype.Char, BoxInt(42)) == chr(42)
    assert unwrap(lltype.Float, BoxFloat(42.5)) == 42.5
    assert unwrap(lltype.Ptr(S), BoxPtr(po)) == p
Esempio n. 15
0
    def test_call_with_singlefloats(self):
        cpu = self.cpu
        if not cpu.supports_floats or not cpu.supports_singlefloats:
            py.test.skip('requires floats and singlefloats')

        import random
        from pypy.rlib.libffi import types
        from pypy.rlib.rarithmetic import r_singlefloat

        def func(*args):
            res = 0.0
            for i, x in enumerate(args):
                res += (i + 1.1) * float(x)
            return res

        F = lltype.Float
        S = lltype.SingleFloat
        I = lltype.Signed
        floats = [random.random() - 0.5 for i in range(8)]
        singlefloats = [r_singlefloat(random.random() - 0.5) for i in range(8)]
        ints = [random.randrange(-99, 99) for i in range(8)]
        for repeat in range(100):
            args = []
            argvalues = []
            argslist = []
            local_floats = list(floats)
            local_singlefloats = list(singlefloats)
            local_ints = list(ints)
            for i in range(8):
                case = random.randrange(0, 3)
                if case == 0:
                    args.append(F)
                    arg = local_floats.pop()
                    argslist.append(boxfloat(arg))
                elif case == 1:
                    args.append(S)
                    arg = local_singlefloats.pop()
                    argslist.append(BoxInt(longlong.singlefloat2int(arg)))
                else:
                    args.append(I)
                    arg = local_ints.pop()
                    argslist.append(BoxInt(arg))
                argvalues.append(arg)
            FUNC = self.FuncType(args, F)
            FPTR = self.Ptr(FUNC)
            func_ptr = llhelper(FPTR, func)
            calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                        EffectInfo.MOST_GENERAL)
            funcbox = self.get_funcbox(cpu, func_ptr)

            res = self.execute_operation(rop.CALL, [funcbox] + argslist,
                                         'float',
                                         descr=calldescr)
            expected = func(*argvalues)
            assert abs(res.getfloat() - expected) < 0.0001
Esempio n. 16
0
    def test_allocations(self):
        from pypy.rpython.lltypesystem import rstr

        allocs = [None]
        all = []

        def f(size):
            allocs.insert(0, size)
            buf = ctypes.create_string_buffer(size)
            all.append(buf)
            return ctypes.cast(buf, ctypes.c_void_p).value

        func = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)(f)
        addr = ctypes.cast(func, ctypes.c_void_p).value

        try:
            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)], 'ref')
            assert allocs[0] == 7 + ofs + WORD
            resbuf = self._resbuf(res)
            assert resbuf[ofs / WORD] == 7

            # ------------------------------------------------------------

            res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref')
            assert allocs[0] == 7 + ofs + WORD
            resbuf = self._resbuf(res)
            assert resbuf[ofs / WORD] == 7

            # ------------------------------------------------------------

            TP = lltype.GcArray(lltype.Signed)
            ofs = symbolic.get_field_token(TP, 'length', False)[0]
            descr = self.cpu.arraydescrof(TP)

            res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref',
                                         descr)
            assert allocs[0] == 10 * WORD + ofs + WORD
            resbuf = self._resbuf(res)
            assert resbuf[ofs / WORD] == 10

            # ------------------------------------------------------------

            res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], 'ref',
                                         descr)
            assert allocs[0] == 10 * WORD + ofs + WORD
            resbuf = self._resbuf(res)
            assert resbuf[ofs / WORD] == 10

        finally:
            self.cpu.assembler.malloc_func_addr = saved_addr
Esempio n. 17
0
def test_execute_varargs():
    cpu = FakeCPU()
    descr = FakeCallDescr()
    argboxes = [BoxInt(99999), BoxInt(321), constfloat(2.25), ConstInt(123),
                BoxPtr(), boxfloat(5.5)]
    box = execute_varargs(cpu, FakeMetaInterp(), rop.CALL, argboxes, descr)
    assert box.getfloat() == 42.5
    assert cpu.fakecalled == (99999, descr, [321, 123],
                              [ConstPtr.value],
                              [longlong.getfloatstorage(2.25),
                               longlong.getfloatstorage(5.5)])
Esempio n. 18
0
def get_int_tests():
    for opnum, args, retvalue in (list(_int_binary_operations()) +
                                  list(_int_comparison_operations()) +
                                  list(_int_unary_operations())):
        yield opnum, [BoxInt(x) for x in args], retvalue
        if len(args) > 1:
            assert len(args) == 2
            yield opnum, [BoxInt(args[0]), ConstInt(args[1])], retvalue
            yield opnum, [ConstInt(args[0]), BoxInt(args[1])], retvalue
            if args[0] == args[1]:
                commonbox = BoxInt(args[0])
                yield opnum, [commonbox, commonbox], retvalue
Esempio n. 19
0
def compile_tmp_callback(cpu,
                         jitdriver_sd,
                         greenboxes,
                         redargtypes,
                         memory_manager=None):
    """Make a LoopToken that corresponds to assembler code that just
    calls back the interpreter.  Used temporarily: a fully compiled
    version of the code may end up replacing it.
    """
    jitcell_token = make_jitcell_token(jitdriver_sd)
    nb_red_args = jitdriver_sd.num_red_args
    assert len(redargtypes) == nb_red_args
    inputargs = []
    for kind in redargtypes:
        if kind == history.INT: box = BoxInt()
        elif kind == history.REF: box = BoxPtr()
        elif kind == history.FLOAT: box = BoxFloat()
        else: raise AssertionError
        inputargs.append(box)
    k = jitdriver_sd.portal_runner_adr
    funcbox = history.ConstInt(heaptracker.adr2int(k))
    callargs = [funcbox] + greenboxes + inputargs
    #
    result_type = jitdriver_sd.result_type
    if result_type == history.INT:
        result = BoxInt()
    elif result_type == history.REF:
        result = BoxPtr()
    elif result_type == history.FLOAT:
        result = BoxFloat()
    elif result_type == history.VOID:
        result = None
    else:
        assert 0, "bad result_type"
    if result is not None:
        finishargs = [result]
    else:
        finishargs = []
    #
    jd = jitdriver_sd
    faildescr = PropagateExceptionDescr()
    operations = [
        ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr),
        ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr),
        ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken)
    ]
    operations[1].setfailargs([])
    operations = get_deep_immutable_oplist(operations)
    cpu.compile_loop(inputargs, operations, jitcell_token, log=False)
    if memory_manager is not None:  # for tests
        memory_manager.keep_loop_alive(jitcell_token)
    return jitcell_token
Esempio n. 20
0
    def test_stringitems(self):
        from pypy.rpython.lltypesystem.rstr import STR
        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)], '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'
        self.execute_operation(rop.STRSETITEM, [res, BoxInt(2), ConstInt(ord('z'))], 'void')
        assert resbuf[ofs + ofs_items + 2] == 'z'
        r = self.execute_operation(rop.STRGETITEM, [res, BoxInt(2)], 'int')
        assert r.value == ord('z')
Esempio n. 21
0
 def handle_fail(self, metainterp_sd):
     if self.no == 0:
         raise metainterp_sd.warmrunnerdesc.DoneWithThisFrameInt(3)
     if self.no == 1:
         raise metainterp_sd.warmrunnerdesc.ContinueRunningNormally(
             [BoxInt(0), BoxInt(1)])
     if self.no == 3:
         exc = lltype.malloc(OBJECT)
         exc.typeptr = exc_vtable
         raise metainterp_sd.warmrunnerdesc.ExitFrameWithExceptionRef(
             metainterp_sd.cpu,
             lltype.cast_opaque_ptr(llmemory.GCREF, exc))
     return self.no
Esempio n. 22
0
def test_virtual_adder_make_varray():
    b2s, b4s = [BoxPtr(), BoxInt(4)]
    c1s = ConstInt(111)
    storage = Storage()
    memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
    modifier = ResumeDataVirtualAdder(storage, memo)
    modifier.liveboxes_from_env = {}
    modifier.liveboxes = {}
    modifier.vfieldboxes = {}

    class FakeOptimizer(object):
        class cpu:
            pass
        def new_const_item(self, descr):
            return None
    v2 = VArrayValue(FakeOptimizer(), LLtypeMixin.arraydescr, 2, b2s)
    v2._items = [b4s, c1s]
    modifier.register_virtual_fields(b2s, [b4s, c1s])
    liveboxes = []
    values = {b2s: v2}
    modifier._number_virtuals(liveboxes, values, 0)
    dump_storage(storage, liveboxes)
    storage.rd_consts = memo.consts[:]
    storage.rd_numb = None
    # resume
    b1t, b3t, b4t = [BoxInt(11), BoxInt(33), BoxInt(44)]
    newboxes = _resume_remap(liveboxes, [#b2s -- virtual
                                         b4s],
                                         b4t)
    # resume
    metainterp = MyMetaInterp()
    reader = ResumeDataReader(storage, newboxes, metainterp)
    assert len(reader.virtuals) == 1
    b2t = reader._decode_box(tag(0, TAGVIRTUAL))
    trace = metainterp.trace
    expected = [
        (rop.NEW_ARRAY, [ConstInt(2)], b2t, LLtypeMixin.arraydescr),
        (rop.SETARRAYITEM_GC, [b2t,ConstInt(0), b4t],None,
                              LLtypeMixin.arraydescr),
        (rop.SETARRAYITEM_GC, [b2t,ConstInt(1), c1s], None,
                              LLtypeMixin.arraydescr),
        ]
    for x, y in zip(expected, trace):
        assert x == y
    #
    ptr = b2t.value._obj.container._as_ptr()
    assert lltype.typeOf(ptr) == lltype.Ptr(lltype.GcArray(lltype.Signed))
    assert len(ptr) == 2
    assert ptr[0] == 44
    assert ptr[1] == 111
Esempio n. 23
0
 def make_guards(self, box, guards):
     if self.has_lower and self.lower > MININT:
         bound = self.lower
         res = BoxInt()
         op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res)
         guards.append(op)
         op = ResOperation(rop.GUARD_TRUE, [res], None)
         guards.append(op)
     if self.has_upper and self.upper < MAXINT:
         bound = self.upper
         res = BoxInt()
         op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res)
         guards.append(op)
         op = ResOperation(rop.GUARD_TRUE, [res], None)
         guards.append(op)
Esempio n. 24
0
    def test_getfield_setfield(self):
        TP = lltype.GcStruct('x', ('s', lltype.Signed),
                             ('i', rffi.INT),
                             ('f', lltype.Float),
                             ('u', rffi.USHORT),
                             ('c1', lltype.Char),
                             ('c2', lltype.Char),
                             ('c3', lltype.Char))
        res = self.execute_operation(rop.NEW, [],
                                     'ref', self.cpu.sizeof(TP))
        ofs_s = self.cpu.fielddescrof(TP, 's')
        ofs_i = self.cpu.fielddescrof(TP, 'i')
        #ofs_f = self.cpu.fielddescrof(TP, 'f')
        ofs_u = self.cpu.fielddescrof(TP, 'u')
        ofsc1 = self.cpu.fielddescrof(TP, 'c1')
        ofsc2 = self.cpu.fielddescrof(TP, 'c2')
        ofsc3 = self.cpu.fielddescrof(TP, 'c3')
        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void',
                               ofs_s)
        # XXX ConstFloat
        #self.execute_operation(rop.SETFIELD_GC, [res, ofs_f, 1e100], 'void')
        # XXX we don't support shorts (at all)
        #self.execute_operation(rop.SETFIELD_GC, [res, ofs_u, ConstInt(5)], 'void')
        s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s)
        assert s.value == 3
        self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(3)], 'void',
                               ofs_s)
        s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s)
        assert s.value == 3

        self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(1234)], 'void', ofs_i)
        i = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_i)
        assert i.value == 1234

        #u = self.execute_operation(rop.GETFIELD_GC, [res, ofs_u], 'int')
        #assert u.value == 5
        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(1)], 'void',
                               ofsc1)
        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void',
                               ofsc3)
        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(2)], 'void',
                               ofsc2)
        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc1)
        assert c.value == 1
        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc2)
        assert c.value == 2
        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc3)
        assert c.value == 3
Esempio n. 25
0
    def test_record_constptrs(self):
        class MyFakeCPU(object):
            def cast_adr_to_int(self, adr):
                assert adr == "some fake address"
                return 43

        class MyFakeGCRefList(object):
            def get_address_of_gcref(self, s_gcref1):
                assert s_gcref1 == s_gcref
                return "some fake address"

        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.PTR_EQ,
                         [v_random_box, ConstPtr(s_gcref)], v_result),
        ]
        gc_ll_descr = self.gc_ll_descr
        gc_ll_descr.gcrefs = MyFakeGCRefList()
        gcrefs = []
        operations = get_deep_immutable_oplist(operations)
        operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations,
                                                    gcrefs)
        assert operations2 == operations
        assert gcrefs == [s_gcref]
Esempio n. 26
0
 def do_strgetitem(self, stringbox, indexbox):
     basesize, itemsize, ofs_length = symbolic.get_array_token(
         rstr.STR, self.translate_support_code)
     gcref = stringbox.getref_base()
     i = indexbox.getint()
     v = rffi.cast(rffi.CArrayPtr(lltype.Char), gcref)[basesize + i]
     return BoxInt(ord(v))
Esempio n. 27
0
 def do_strlen(self, stringbox):
     basesize, itemsize, ofs_length = symbolic.get_array_token(
         TP, self.translate_support_code)
     gcref = stringbox.getref_base()
     v = rffi.cast(rffi.CArrayPtr(lltype.Signed),
                   gcref)[ofs_length / WORD]
     return BoxInt(v)
Esempio n. 28
0
 def do_getarrayitem_gc(self, arraybox, indexbox, arraydescr):
     itemindex = indexbox.getint()
     gcref = arraybox.getref_base()
     ofs, size, ptr, float = self.unpack_arraydescr(arraydescr)
     # --- start of GC unsafe code (no GC operation!) ---
     items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
     #
     if ptr:
         items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
         pval = self._cast_int_to_gcref(items[itemindex])
         # --- end of GC unsafe code ---
         return BoxPtr(pval)
     #
     if float:
         items = rffi.cast(rffi.CArrayPtr(lltype.Float), items)
         fval = items[itemindex]
         # --- end of GC unsafe code ---
         return BoxFloat(fval)
     #
     for TYPE, itemsize in unroll_basic_sizes:
         if size == itemsize:
             items = rffi.cast(rffi.CArrayPtr(TYPE), items)
             val = items[itemindex]
             # --- end of GC unsafe code ---
             return BoxInt(rffi.cast(lltype.Signed, val))
     else:
         raise NotImplementedError("size = %d" % size)
Esempio n. 29
0
def test_execute():
    cpu = FakeCPU()
    descr = FakeDescr()
    box = execute(cpu, rop.INT_ADD, None, BoxInt(40), ConstInt(2))
    assert box.value == 42
    box = execute(cpu, rop.NEW, descr)
    assert box.args == ('new', descr)
Esempio n. 30
0
 def new_box_item(self, arraydescr):
     if arraydescr.is_array_of_pointers():
         return self.new_ptr_box()
     elif arraydescr.is_array_of_floats():
         return BoxFloat()
     else:
         return BoxInt()
Esempio n. 31
0
 def new_box(self, fieldofs):
     if fieldofs.is_pointer_field():
         return self.new_ptr_box()
     elif fieldofs.is_float_field():
         return BoxFloat()
     else:
         return BoxInt()
Esempio n. 32
0
 def __init__(self, cpu, cliloop):
     self.setoptions()
     self.cpu = cpu
     self.name = cliloop.get_fresh_cli_name()
     self.cliloop = cliloop
     self.boxes = {}       # box --> local var
     self.branches = []
     self.branchlabels = []
     self.consts = {}      # object --> index
     self.meth_wrapper = self._get_meth_wrapper()
     self.il = self.meth_wrapper.get_il_generator()
     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))
         self.av_ZeroDivisionError = ConstObj(ootype.cast_to_object(cpu.ll_zero_exc))
     else:
         self.av_OverflowError = None
         self.av_ZeroDivisionError = None
     self.box2type = {}
Esempio n. 33
0
class Method(object):

    operations = [] # overwritten at the end of the module
    debug = False
    tailcall = True
    nocast = True

    def __init__(self, cpu, cliloop):
        self.setoptions()
        self.cpu = cpu
        self.name = cliloop.get_fresh_cli_name()
        self.cliloop = cliloop
        self.boxes = {}       # box --> local var
        self.branches = []
        self.branchlabels = []
        self.consts = {}      # object --> index
        self.meth_wrapper = self._get_meth_wrapper()
        self.il = self.meth_wrapper.get_il_generator()
        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))
            self.av_ZeroDivisionError = ConstObj(ootype.cast_to_object(cpu.ll_zero_exc))
        else:
            self.av_OverflowError = None
            self.av_ZeroDivisionError = None
        self.box2type = {}

    def compile(self):
        # ----
        debug_start('jit-backend-emit_ops')
        if self.nocast:
            self.compute_types()
        self.emit_load_inputargs()
        self.emit_preamble()        
        self.emit_operations(self.cliloop.operations)
        self.emit_branches()
        self.emit_end()
        debug_stop('jit-backend-emit_ops')
        # ----
        debug_start('jit-backend-finish_code')
        res = self.finish_code()
        debug_stop('jit-backend-finish_code')
        return res

    def _parseopt(self, text):
        text = text.lower()
        if text[0] == '-':
            return text[1:], False
        elif text[0] == '+':
            return text[1:], True
        else:
            return text, True

    def setoptions(self):
        opts = os.environ.get('PYPYJITOPT')
        if not opts:
            return
        parts = opts.split(' ')
        for part in parts:
            name, value = self._parseopt(part)
            if name == 'debug':
                self.debug = value
            elif name == 'tailcall':
                self.tailcall = value
            elif name == 'nocast':
                self.nocast = value
            else:
                os.write(2, 'Warning: invalid option name: %s\n' % name)

    def _collect_types(self, operations, box2classes):
        for op in operations:
            if op.opnum in (rop.GETFIELD_GC, rop.SETFIELD_GC):
                box = op.args[0]
                descr = op.descr
                assert isinstance(descr, runner.FieldDescr)
                box2classes.setdefault(box, []).append(descr.selfclass)
            if op in self.cliloop.guard2ops:
                _, suboperations = self.cliloop.guard2ops[op]
                self._collect_types(suboperations, box2classes)

    def compute_types(self):
        box2classes = {} # box --> [ootype.Class]
        self._collect_types(self.cliloop.operations, box2classes)
        for box, classes in box2classes.iteritems():
            cls = classes[0]
            for cls2 in classes[1:]:
                if ootype.subclassof(cls, cls2):
                    cls = cls2
                else:
                    assert ootype.subclassof(cls2, cls)
            self.box2type[box] = dotnet.class2type(cls)

    def finish_code(self):
        delegatetype = dotnet.typeof(LoopDelegate)
        # initialize the array of genconsts
        consts = dotnet.new_array(System.Object, len(self.consts))
        for av_const, i in self.consts.iteritems():
            consts[i] = av_const.get_cliobj()
        # build the delegate
        func = self.meth_wrapper.create_delegate(delegatetype, consts)
        return dotnet.clidowncast(func, LoopDelegate)

    def _get_meth_wrapper(self):
        restype = dotnet.class2type(cVoid)
        args = self._get_args_array([dotnet.typeof(InputArgs)])
        return get_method_wrapper(self.name, restype, args)

    def _get_args_array(self, arglist):
        array = dotnet.new_array(System.Type, len(arglist)+1)
        array[0] = System.Type.GetType("System.Object[]")
        for i in range(len(arglist)):
            array[i+1] = arglist[i]
        return array

    def var_for_box(self, box):
        try:
            return self.boxes[box]
        except KeyError:
            v = self.il.DeclareLocal(box.getCliType(self))
            self.boxes[box] = v
            return v

    def match_var_fox_boxes(self, failargs, inputargs):
        failargs = [arg for arg in failargs if arg is not None]
        assert len(failargs) == len(inputargs)
        for i in range(len(failargs)):
            v = self.boxes[failargs[i]]
            self.boxes[inputargs[i]] = v

    def get_index_for_failing_op(self, op):
        try:
            return self.cpu.failing_ops.index(op)
        except ValueError:
            self.cpu.failing_ops.append(op)
            return len(self.cpu.failing_ops)-1

    def get_index_for_constant(self, obj):
        try:
            return self.consts[obj]
        except KeyError:
            index = len(self.consts)
            self.consts[obj] = index
            return index

    def newbranch(self, op):
        # sanity check, maybe we can remove it later
        for myop in self.branches:
            assert myop is not op
        il_label = self.il.DefineLabel()
        self.branches.append(op)
        self.branchlabels.append(il_label)
        return il_label

    def get_inputarg_field(self, type):
        t = dotnet.typeof(InputArgs)
        if type == history.INT:
            fieldname = 'ints'
        elif type == history.FLOAT:
            fieldname = 'floats'
        elif type == history.REF:
            fieldname = 'objs'
        else:
            assert False, 'Unknown type %s' % type
        return t.GetField(fieldname)        

    def load_inputarg(self, i, type, clitype):
        field = self.get_inputarg_field(type)
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldfld, field)
        self.il.Emit(OpCodes.Ldc_I4, i)
        self.il.Emit(OpCodes.Ldelem, clitype)

    def store_inputarg(self, i, type, clitype, valuebox):
        field = self.get_inputarg_field(type)
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldfld, field)
        self.il.Emit(OpCodes.Ldc_I4, i)
        valuebox.load(self)
        self.il.Emit(OpCodes.Stelem, clitype)

    def emit_load_inputargs(self):
        self.emit_debug("executing: " + self.name)
        i = 0
        for box in self.cliloop.inputargs:
            self.load_inputarg(i, box.type, box.getCliType(self))
            box.store(self)
            i+=1

    def emit_preamble(self):
        self.il_loop_start = self.il.DefineLabel()
        self.il.MarkLabel(self.il_loop_start)

    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:
            branches = self.branches
            branchlabels = self.branchlabels
            self.branches = []
            self.branchlabels = []
            assert len(branches) == len(branchlabels)
            for i in range(len(branches)):
                op = branches[i]
                il_label = branchlabels[i]
                self.il.MarkLabel(il_label)
                self.emit_guard_subops(op)

    def emit_guard_subops(self, op):
        assert op.is_guard()
        if op in self.cliloop.guard2ops:
            inputargs, suboperations = self.cliloop.guard2ops[op]
            self.match_var_fox_boxes(op.fail_args, inputargs)
            self.emit_operations(suboperations)
        else:
            self.emit_return_failed_op(op, op.fail_args)

    def emit_end(self):
        assert self.branches == []
        self.il.Emit(OpCodes.Ret)

    # -----------------------------

    def push_all_args(self, op):
        for box in op.args:
            box.load(self)

    def push_arg(self, op, n):
        op.args[n].load(self)

    def store_result(self, op):
        op.result.store(self)

    def emit_debug(self, msg):
        if self.debug:
            self.il.EmitWriteLine(msg)

    def emit_clear_exception(self):
        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()
        lbl = self.il.BeginExceptionBlock()
        emit_op(self, op)
        self.il.Emit(OpCodes.Leave, lbl)
        for exctype in exctypes:
            v = self.il.DeclareLocal(exctype)
            self.il.BeginCatchBlock(exctype)
            if exctype == dotnet.typeof(System.OverflowException) and self.av_OverflowError:
                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 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)
        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 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 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)

    # --------------------------------

    def emit_return_failed_op(self, op, args):
        # store the index of the failed op
        index_op = self.get_index_for_failing_op(op)
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldc_I4, index_op)
        field = dotnet.typeof(InputArgs).GetField('failed_op')
        self.il.Emit(OpCodes.Stfld, field)
        self.emit_store_opargs(args)
        self.il.Emit(OpCodes.Ret)

    def emit_op_finish(self, op):
        self.emit_return_failed_op(op, op.args)

    def emit_store_opargs(self, args):
        # store the latest values
        i = 0
        for box in args:
            if box is not None:
                self.store_inputarg(i, box.type, box.getCliType(self), box)
            i+=1

    def emit_guard_bool(self, op, opcode):
        assert len(op.args) == 1
        il_label = self.newbranch(op)
        op.args[0].load(self)
        self.il.Emit(opcode, il_label)

    def emit_op_guard_true(self, op):
        self.emit_guard_bool(op, OpCodes.Brfalse)
        
    def emit_op_guard_false(self, op):
        self.emit_guard_bool(op, OpCodes.Brtrue)

    def emit_op_guard_nonnull(self, op):
        self.emit_guard_bool(op, OpCodes.Brfalse)
        
    def emit_op_guard_isnull(self, op):
        self.emit_guard_bool(op, OpCodes.Brtrue)

    def emit_op_guard_value(self, op):
        assert len(op.args) == 2
        il_label = self.newbranch(op)
        self.push_all_args(op)
        self.il.Emit(OpCodes.Bne_Un, il_label)

    def emit_op_guard_class(self, op):
        assert len(op.args) == 2
        il_label = self.newbranch(op)
        self.push_arg(op, 0)
        meth = dotnet.typeof(System.Object).GetMethod("GetType")
        self.il.Emit(OpCodes.Callvirt, meth)
        self.push_arg(op, 1)
        self.il.Emit(OpCodes.Bne_Un, il_label)

    def emit_op_guard_nonnull_class(self, op):
        assert len(op.args) == 2
        il_label = self.newbranch(op)
        # nonnull check
        self.push_arg(op, 0)
        self.il.Emit(OpCodes.Brfalse, il_label)
        # class check
        self.push_arg(op, 0)
        meth = dotnet.typeof(System.Object).GetMethod("GetType")
        self.il.Emit(OpCodes.Callvirt, meth)
        self.push_arg(op, 1)
        self.il.Emit(OpCodes.Bne_Un, il_label)

    def emit_op_guard_no_exception(self, op):
        il_label = self.newbranch(op)
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldfld, self.exc_value_field)
        self.il.Emit(OpCodes.Brtrue, il_label)

    def emit_op_guard_exception(self, op):
        il_label = self.newbranch(op)
        classbox = op.args[0]
        assert isinstance(classbox, ConstObj)
        oocls = classbox.getref(ootype.Class)
        clitype = dotnet.class2type(oocls)
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldfld, self.exc_value_field)
        self.il.Emit(OpCodes.Isinst, clitype)
        self.il.Emit(OpCodes.Brfalse, il_label)
        # the guard succeeded, store the result
        self.av_inputargs.load(self)
        self.il.Emit(OpCodes.Ldfld, self.exc_value_field)
        self.store_result(op)

    def emit_guard_overflow_impl(self, op, opcode):
        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):
        self.emit_guard_overflow_impl(op, OpCodes.Brtrue)

    def emit_op_guard_overflow(self, op):
        self.emit_guard_overflow_impl(op, OpCodes.Brfalse)

    def emit_op_jump(self, op):
        target_token = op.descr
        assert isinstance(target_token, LoopToken)
        if target_token.cliloop is self.cliloop:
            # jump to the beginning of the loop
            i = 0
            for i in range(len(op.args)):
                op.args[i].load(self)
                self.cliloop.inputargs[i].store(self)
            self.il.Emit(OpCodes.Br, self.il_loop_start)
        else:
            # it's a real bridge
            cliloop = target_token.cliloop
            assert len(op.args) == len(cliloop.inputargs)
            self.emit_debug('jumping to ' + cliloop.name)
            self.emit_store_opargs(op.args)
            cliloop.funcbox.load(self)
            self.av_inputargs.load(self)
            methinfo = dotnet.typeof(LoopDelegate).GetMethod('Invoke')
            if self.tailcall:
                self.il.Emit(OpCodes.Tailcall)
            self.il.Emit(OpCodes.Callvirt, methinfo)
            self.il.Emit(OpCodes.Ret)

    def emit_op_new_with_vtable(self, op):
        clsbox = op.args[0]
        assert isinstance(clsbox, ConstObj)
        cls = clsbox.getref_base()
        descr = self.cpu.class_sizes[cls]
        assert isinstance(descr, runner.TypeDescr)
        clitype = descr.get_clitype()
        ctor_info = descr.get_constructor_info()
        self.il.Emit(OpCodes.Newobj, ctor_info)
        self.store_result(op)

    def emit_op_runtimenew(self, op):
        clitype_utils = dotnet.typeof(Utils)
        methinfo = clitype_utils.GetMethod('RuntimeNew')
        op.args[0].load(self)
        self.il.Emit(OpCodes.Call, methinfo)
        self.store_result(op)

    def emit_op_instanceof(self, op):
        descr = op.descr
        assert isinstance(descr, runner.TypeDescr)
        clitype = descr.get_clitype()
        op.args[0].load(self)
        self.il.Emit(OpCodes.Isinst, clitype)
        self.il.Emit(OpCodes.Ldnull)
        self.il.Emit(OpCodes.Cgt_Un)
        self.store_result(op)

    def emit_op_subclassof(self, op):
        clitype_utils = dotnet.typeof(Utils)
        methinfo = clitype_utils.GetMethod('SubclassOf')
        op.args[0].load(self)
        op.args[1].load(self)
        self.il.Emit(OpCodes.Call, methinfo)
        self.store_result(op)

    def emit_op_call_impl(self, op):
        descr = op.descr
        assert isinstance(descr, runner.StaticMethDescr)
        delegate_type = descr.get_delegate_clitype()
        meth_invoke = descr.get_meth_info()
        self._emit_call(op, OpCodes.Callvirt, delegate_type,
                        meth_invoke, descr.has_result)

    def emit_op_call(self, op):
        emit_op = Method.emit_op_call_impl.im_func
        exctypes = [dotnet.typeof(System.Exception)]
        self.emit_raising_op(op, emit_op, exctypes)

    emit_op_call_pure = emit_op_call

    def emit_op_oosend(self, op):
        descr = op.descr
        assert isinstance(descr, runner.MethDescr)
        clitype = descr.get_self_clitype()
        methinfo = descr.get_meth_info()
        opcode = descr.get_call_opcode()
        self._emit_call(op, opcode, clitype, methinfo, descr.has_result)

    emit_op_oosend_pure = emit_op_oosend

    def _emit_call(self, op, opcode, clitype, methinfo, has_result):
        av_sm, args_av = op.args[0], op.args[1:]
        av_sm.load(self)
        self.il.Emit(OpCodes.Castclass, clitype)
        for av_arg in args_av:
            av_arg.load(self)
        self.il.Emit(opcode, methinfo)
        if has_result:
            self.store_result(op)

    def emit_op_getfield_gc(self, op):
        descr = op.descr
        assert isinstance(descr, runner.FieldDescr)
        clitype = descr.get_self_clitype()
        fieldinfo = descr.get_field_info()
        obj = op.args[0]
        obj.load(self)
        if obj.getCliType(self) is not clitype:
            self.il.Emit(OpCodes.Castclass, clitype)
        self.il.Emit(OpCodes.Ldfld, fieldinfo)
        self.store_result(op)
    
    emit_op_getfield_gc_pure = emit_op_getfield_gc

    def emit_op_setfield_gc(self, op):
        descr = op.descr
        assert isinstance(descr, runner.FieldDescr)
        clitype = descr.get_self_clitype()
        fieldinfo = descr.get_field_info()
        obj = op.args[0]
        obj.load(self)
        if obj.getCliType(self) is not clitype:
            self.il.Emit(OpCodes.Castclass, clitype)
        op.args[1].load(self)
        self.il.Emit(OpCodes.Stfld, fieldinfo)

    def emit_op_getarrayitem_gc(self, op):
        descr = op.descr
        assert isinstance(descr, runner.TypeDescr)
        clitype = descr.get_array_clitype()
        itemtype = descr.get_clitype()
        op.args[0].load(self)
        self.il.Emit(OpCodes.Castclass, clitype)
        op.args[1].load(self)
        self.il.Emit(OpCodes.Ldelem, itemtype)
        self.store_result(op)
    
    emit_op_getarrayitem_gc_pure = emit_op_getarrayitem_gc

    def emit_op_setarrayitem_gc(self, op):
        descr = op.descr
        assert isinstance(descr, runner.TypeDescr)
        clitype = descr.get_array_clitype()
        itemtype = descr.get_clitype()
        op.args[0].load(self)
        self.il.Emit(OpCodes.Castclass, clitype)
        op.args[1].load(self)
        op.args[2].load(self)
        self.il.Emit(OpCodes.Stelem, itemtype)

    def emit_op_arraylen_gc(self, op):
        descr = op.descr
        assert isinstance(descr, runner.TypeDescr)
        clitype = descr.get_array_clitype()
        op.args[0].load(self)
        self.il.Emit(OpCodes.Castclass, clitype)
        self.il.Emit(OpCodes.Ldlen)
        self.store_result(op)

    def emit_op_new_array(self, op):
        descr = op.descr
        assert isinstance(descr, runner.TypeDescr)
        item_clitype = descr.get_clitype()
        if item_clitype is None:
            return self.emit_new_arrayofvoids(op)
        op.args[0].load(self)
        self.il.Emit(OpCodes.Newarr, item_clitype)
        self.store_result(op)

    def emit_new_arrayofvoids(self, op):
        clitype = dotnet.typeof(ListOfVoid)
        ctor = clitype.GetConstructor(dotnet.new_array(System.Type, 0))
        _ll_resize = clitype.GetMethod('_ll_resize')
        self.il.Emit(OpCodes.Newobj, ctor)
        self.il.Emit(OpCodes.Dup)
        op.args[0].load(self)
        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

    emit_op_new = lltype_only
    emit_op_setfield_raw = lltype_only
    emit_op_getfield_raw = lltype_only
    emit_op_getfield_raw_pure = lltype_only
    emit_op_strsetitem = lltype_only
    emit_op_unicodesetitem = lltype_only
    emit_op_cast_int_to_ptr = lltype_only
    emit_op_cast_ptr_to_int = lltype_only
    emit_op_newstr = lltype_only
    emit_op_strlen = lltype_only
    emit_op_strgetitem = lltype_only
    emit_op_newunicode = lltype_only    
    emit_op_unicodelen = lltype_only
    emit_op_unicodegetitem = lltype_only
    emit_op_cond_call_gc_wb = lltype_only
    emit_op_setarrayitem_raw = lltype_only