def test_wrong_result(self): # generated by: # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10 --random-seed=7389 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() tmp16 = BoxInt() tmp17 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_IS_TRUE, [v3], tmp16), ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr1), ResOperation(rop.INT_AND, [v7, ConstInt(31)], tmp17), ResOperation(rop.INT_RSHIFT, [v5, tmp17], v11), ResOperation(rop.INT_OR, [v6, v8], v12), ResOperation(rop.GUARD_VALUE, [v11, ConstInt(-2)], None, descr=faildescr2), ResOperation(rop.INT_LE, [ConstInt(1789569706), v10], v13), ResOperation(rop.INT_IS_TRUE, [v4], v14), ResOperation(rop.INT_XOR, [v14, v3], v15), ResOperation(rop.GUARD_VALUE, [v8, ConstInt(-8)], None, descr=faildescr3), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] operations[1].setfailargs([v9, v1]) operations[5].setfailargs([v10, v2, v11, v3]) operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [0, -2, 24, 1, -4, 13, -95, 33, 2, -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == -4 assert cpu.get_int_value(deadframe, 1) == -95 assert cpu.get_int_value(deadframe, 2) == 45 assert cpu.get_int_value(deadframe, 3) == 1 assert cpu.get_int_value(deadframe, 4) == -2 assert cpu.get_int_value(deadframe, 5) == 0 assert cpu.get_int_value(deadframe, 6) == 33
class CustomBaseTestRegalloc(BaseTestRegalloc): cpu = CPU(None, None) cpu.setup_once() 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) def f(a): return 23 FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) f_fptr = llhelper(FPTR, f) f_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, EffectInfo.MOST_GENERAL) zero_division_tp, zero_division_value = get_zero_division_error(cpu) 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, EffectInfo.MOST_GENERAL) targettoken = TargetToken() targettoken2 = TargetToken() fdescr1 = BasicFailDescr(1) fdescr2 = BasicFailDescr(2) fdescr3 = BasicFailDescr(3) def setup_method(self, meth): self.targettoken._ll_loop_code = 0 self.targettoken2._ll_loop_code = 0 def f1(x): return x + 1 def f2(x, y): return x * y def f10(*args): assert len(args) == 10 return sum(args) F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 2, lltype.Signed)) F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 10, lltype.Signed)) f1ptr = llhelper(F1PTR, f1) f2ptr = llhelper(F2PTR, f2) f10ptr = llhelper(F10PTR, f10) f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) namespace = locals().copy()
def test_wrong_guard3(self): # random seed: 8029 # block length: 10 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.UINT_LT, [ConstInt(-11), v7], v11), ResOperation(rop.INT_GE, [v3, v5], v12), ResOperation(rop.INT_INVERT, [v9], v13), ResOperation(rop.GUARD_VALUE, [v13, ConstInt(14)], None, descr=faildescr3), ResOperation(rop.INT_IS_ZERO, [v12], v14), ResOperation(rop.INT_SUB, [v2, v13], v15), ResOperation(rop.GUARD_VALUE, [v15, ConstInt(-32)], None, descr=faildescr4), ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(805306366)], v16), ResOperation(rop.GUARD_VALUE, [v15, ConstInt(0)], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[3].setfailargs([]) operations[-4].setfailargs([v15]) operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 assert cpu.get_int_value(deadframe, 0) == -15 assert cpu.get_int_value(deadframe, 1) == -9 assert cpu.get_int_value(deadframe, 2) == 536870912 assert cpu.get_int_value(deadframe, 3) == 0 assert cpu.get_int_value(deadframe, 4) == 0
def test_overflow(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() v17 = BoxInt() v18 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_SUB, [ConstInt(21), v5], v11), ResOperation(rop.INT_MUL_OVF, [v8, v4], v12), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.UINT_LT, [v10, v3], v13), ResOperation(rop.INT_IS_TRUE, [v3], v14), ResOperation(rop.INT_XOR, [v9, v8], v15), ResOperation(rop.INT_LE, [v12, v6], v16), ResOperation(rop.UINT_GT, [v15, v5], v17), ResOperation(rop.UINT_LE, [ConstInt(-9), v13], v18), ResOperation(rop.GUARD_FALSE, [v13], None, descr=faildescr2), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3), ] operations[2].setfailargs([v10, v6]) operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 assert cpu.get_int_value(deadframe, 1) == 63 assert cpu.get_int_value(deadframe, 2) == 0 assert cpu.get_int_value(deadframe, 3) == 0 assert cpu.get_int_value(deadframe, 4) == 16 assert cpu.get_int_value(deadframe, 5) == 1 assert cpu.get_int_value(deadframe, 6) == 16
def test_wrong_guard(self): # generated by: # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10 --random-seed=4338 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt(32) v2 = BoxInt(41) v3 = BoxInt(-9) v4 = BoxInt(12) v5 = BoxInt(-18) v6 = BoxInt(46) v7 = BoxInt(15) v8 = BoxInt(17) v9 = BoxInt(10) v10 = BoxInt(12) v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() tmp15 = BoxInt() tmp16 = BoxInt() tmp17 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_IS_TRUE, [v1], tmp15), ResOperation(rop.GUARD_TRUE, [tmp15], None, descr=faildescr1), ResOperation(rop.INT_GT, [v4, v5], v11), ResOperation(rop.INT_XOR, [ConstInt(-4), v7], v12), ResOperation(rop.INT_MUL, [ConstInt(23), v11], v13), ResOperation(rop.UINT_GE, [ConstInt(1), v13], v14), ResOperation(rop.INT_IS_ZERO, [v14], tmp16), ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr2), ResOperation(rop.INT_IS_TRUE, [v12], tmp17), ResOperation(rop.GUARD_FALSE, [tmp17], None, descr=faildescr3), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] looptoken = JitCellToken() operations[1].setfailargs([v8, v6, v1]) operations[7].setfailargs([v4]) operations[9].setfailargs([v10, v13]) operations[-1].setfailargs([v8, v10, v6, v3, v2, v9]) args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12] cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 assert cpu.get_int_value(deadframe, 1) == 23
def test_wrong_guard2(self): # random seed: 8029 # block length: 10 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() tmp17 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_ADD_OVF, [v8, ConstInt(-30)], v11), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.UINT_LE, [v11, v1], v12), ResOperation(rop.INT_AND, [v11, ConstInt(31)], tmp17), ResOperation(rop.UINT_RSHIFT, [v12, tmp17], v13), ResOperation(rop.INT_NE, [v3, v2], v14), ResOperation(rop.INT_NE, [ConstInt(1), v11], v15), ResOperation(rop.INT_NE, [ConstInt(23), v15], v16), ResOperation(rop.GUARD_FALSE, [v15], None, descr=faildescr2), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3), ] operations[1].setfailargs([v6, v8, v1, v4]) operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 assert cpu.get_int_value(deadframe, 0) == 16 assert cpu.get_int_value(deadframe, 1) == -1
def test_wrong_result2(self): # block length 10 # random seed 1 f1 = BasicFailDescr(1) f2 = BasicFailDescr(2) f3 = BasicFailDescr(3) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_LE, [v6, v1], v11), ResOperation(rop.SAME_AS, [ConstInt(-14)], v12), ResOperation(rop.INT_ADD, [ConstInt(24), v4], v13), ResOperation(rop.UINT_RSHIFT, [v6, ConstInt(0)], v14), ResOperation(rop.GUARD_VALUE, [v14, ConstInt(1)], None, descr=f3), ResOperation(rop.INT_MUL, [v13, ConstInt(12)], v15), ResOperation(rop.GUARD_FALSE, [v11], None, descr=f1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=f2), ] operations[-2].setfailargs([v4, v10, v3, v9, v14, v2]) operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 assert cpu.get_int_value(deadframe, 0) == -2058005163 assert cpu.get_int_value(deadframe, 1) == 19 assert cpu.get_int_value(deadframe, 2) == 18 assert cpu.get_int_value(deadframe, 3) == 0 assert cpu.get_int_value(deadframe, 4) == 1 assert cpu.get_int_value(deadframe, 5) == -20
def getfaildescr(self, is_finish=False): if is_finish: descr = BasicFinalDescr() else: descr = BasicFailDescr() self.cpu._faildescr_keepalive.append(descr) return descr
def test_bug_int_is_true_1(): v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() zero = BoxInt() tmp5 = BoxInt() inputargs = [v1] operations = [ ResOperation(rop.INT_MUL, [v1, v1], v2), ResOperation(rop.INT_MUL, [v2, v1], v3), ResOperation(rop.INT_IS_TRUE, [v2], tmp5), ResOperation(rop.INT_IS_ZERO, [tmp5], v4), ResOperation(rop.SAME_AS, [ConstInt(0)], zero), ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr()) ] operations[-2].setfailargs([v4, v3, tmp5]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 assert cpu.get_int_value(deadframe, 2) == 1
def test_shadowstack_cond_call(self): cpu = self.cpu cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() def check(i, frame): frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) assert frame.jf_gcmap[0] # is not empty is good enough CHECK = lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Void) checkptr = llhelper(lltype.Ptr(CHECK), check) checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" [i0, p0] p = force_token() cond_call(i0, ConstClass(funcptr), i0, p, descr=calldescr) guard_false(i0, descr=faildescr) [p0] """, namespace={ 'faildescr': BasicFailDescr(), 'funcptr': checkptr, 'calldescr': checkdescr, }) token = JitCellToken() cpu.compile_loop(loop.inputargs, loop.operations, token) S = self.S s = lltype.malloc(S) cpu.execute_token(token, 1, s)
def test_malloc_1(self): cpu = self.cpu sizeof = cpu.sizeof(self.S, None) sizeof.tid = 0 size = sizeof.size loop = self.parse(""" [] p0 = call_malloc_nursery(%d) p1 = call_malloc_nursery(%d) p2 = call_malloc_nursery(%d) # this overflows guard_nonnull(p2, descr=faildescr) [p0, p1, p2] finish(p2, descr=finaldescr) """ % (size, size, size), namespace={'sizedescr': sizeof, 'finaldescr': BasicFinalDescr(), 'faildescr': BasicFailDescr()}) token = JitCellToken() cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) thing = frame.jf_frame[unpack_gcmap(frame)[0]] assert thing == rffi.cast(lltype.Signed, cpu.gc_ll_descr.nursery) assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame
def test_result_is_spilled(self): cpu = self.cpu inp = [InputArgInt(i) for i in range(1, 15)] looptoken = JitCellToken() targettoken = TargetToken() operations = [ ResOperation(rop.LABEL, inp, descr=targettoken), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.GUARD_FALSE, [inp[1]], descr=BasicFailDescr(1)), ResOperation(rop.FINISH, [inp[1]], descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(operations[1:15]) cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [ self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15) ] expected = [3, 7, 11, 15, 19, 23, 27, 3, 7, 11, 15, 19, 23, 27] assert output == expected
def test_nullity_with_guard(self): allops = [rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) nullptr = lltype.nullptr(llmemory.GCREF.TO) f = InputArgInt() for op in allops: for guard in guards: if op == rop.INT_IS_TRUE: bp = InputArgInt(1) n = InputArgInt(0) else: bp = InputArgRef(p) n = InputArgRef(nullptr) for b in (bp, n): i1 = ResOperation(rop.SAME_AS_I, [ConstInt(1)]) f = ResOperation(op, [b]) ops = [ i1, f, ResOperation(guard, [f], descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], descr=BasicFinalDescr()), ] ops[-2].setfailargs([i1]) looptoken = JitCellToken() self.cpu.compile_loop([b], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, b.getint()) result = self.cpu.get_int_value(deadframe, 0) if guard == rop.GUARD_FALSE: assert result == execute(self.cpu, None, op, None, b) else: assert result != execute(self.cpu, None, op, None, b)
def test_bug_heap_cache_is_cleared_but_not_is_unescaped_2(self): h = HeapCache() box1 = RefFrontendOp(1) box2 = RefFrontendOp(2) h.new(box1) h.new(box2) h.setfield(box1, box2, descr1) h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2]) assert h.getfield(box1, descr1) is box2 descr = BasicFailDescr() class XTra: oopspecindex = 0 OS_ARRAYCOPY = 42 OS_ARRAYMOVE = 49 extraeffect = 5 EF_LOOPINVARIANT = 1 EF_ELIDABLE_CANNOT_RAISE = 2 EF_ELIDABLE_OR_MEMORYERROR = 3 EF_ELIDABLE_CAN_RAISE = 4 descr.get_extra_info = XTra h.invalidate_caches(rop.CALL_N, descr, []) assert h.is_unescaped(box1) assert h.is_unescaped(box2) assert h.getfield(box1, descr1) is box2
def test_compile_more_than_32k(self): # the guard_true needs a "b.cond" jumping forward more than 32 kb looptoken = JitCellToken() targettoken = TargetToken() ops = [ '[i0]', 'label(i0, descr=targettoken)', 'i1 = int_le(i0, 9)', 'guard_true(i1, descr=faildescr) [i0]', ] NUM = 8193 iprevious = 'i0' for i in range(NUM): inext = 'i%d' % (i + 2, ) ops.append('%s = int_add(%s, 1)' % (inext, iprevious)) iprevious = inext ops.append('jump(%s, descr=targettoken)' % (iprevious, )) loop = parse('\n'.join(ops), namespace={ 'targettoken': targettoken, 'faildescr': BasicFailDescr(5) }) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, -42) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 5 res = self.cpu.get_int_value(deadframe, 0) assert res == -42 + NUM
def test_tempbox_spilling_in_sub(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_LT, [v9, v9], v11), ResOperation(rop.INT_ADD, [ConstInt(715827882), v4], v12), ResOperation(rop.INT_NEG, [v11], v13), ResOperation(rop.INT_IS_TRUE, [v3], v14), ResOperation(rop.INT_SUB_OVF, [v3, ConstInt(-95)], v15), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 assert cpu.get_int_value(deadframe, 1) == -3 assert cpu.get_int_value(deadframe, 2) == 22 assert cpu.get_int_value(deadframe, 3) == 12 assert cpu.get_int_value(deadframe, 4) == -54 assert cpu.get_int_value(deadframe, 5) == 19 assert cpu.get_int_value(deadframe, 6) == -64
def test_call_release_gil(self): py.test.skip("xxx fix this test: the code is now assuming that " "'before' is just rgil.release_gil(), and 'after' is " "only needed if 'rpy_fastgil' was not changed.") # note that we can't test floats here because when untranslated # people actually wreck xmm registers cpu = self.cpu l = [] copied_stack = [None] def before(): # put nonsense on the top of shadowstack frame = rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.gcrootmap.stack[0]) assert getmap(frame).count('1') == 7 # copied_stack[0] = cpu.gc_ll_descr.gcrootmap.stack[0] cpu.gc_ll_descr.gcrootmap.stack[0] = -42 l.append("before") def after(): cpu.gc_ll_descr.gcrootmap.stack[0] = copied_stack[0] l.append("after") invoke_around_extcall(before, after) def f(frame, x): # all the gc pointers are alive p1 -> p7 (but not p0) assert x == 1 return 2 FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" [i0, p1, p2, p3, p4, p5, p6, p7] p0 = force_token() i1 = call_release_gil(ConstClass(fptr), p0, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, p4, p5, p6, p7] finish(i1, descr=finaldescr) """, namespace={ 'fptr': fptr, 'calldescr': calldescr, 'faildescr': BasicFailDescr(), 'finaldescr': BasicFinalDescr() }) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) assert frame.jf_frame[0] == 2 assert l == ['before', 'after']
def test_sub_with_neg_const_first_arg(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() tmp13 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_EQ, [ConstInt(17), v9], v11), ResOperation(rop.INT_SUB_OVF, [ConstInt(-32), v7], v12), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.INT_IS_ZERO, [v12], tmp13), ResOperation(rop.GUARD_TRUE, [tmp13], None, descr=faildescr2), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3) ] operations[2].setfailargs([v8, v3]) operations[4].setfailargs([v2, v12, v1, v3, v4]) operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 assert cpu.get_int_value(deadframe, 0) == 24 assert cpu.get_int_value(deadframe, 1) == -32 assert cpu.get_int_value(deadframe, 2) == -5 assert cpu.get_int_value(deadframe, 3) == 46 assert cpu.get_int_value(deadframe, 4) == -15
def test_tempbox2(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_LT, [v5, ConstInt(-67)], v11), ResOperation(rop.INT_INVERT, [v2], v12), ResOperation(rop.INT_SUB, [ConstInt(-45), v2], v13), ResOperation(rop.INT_SUB, [ConstInt(99), v6], v14), ResOperation(rop.INT_MUL_OVF, [v6, v9], v15), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 assert cpu.get_int_value(deadframe, 1) == 5 assert cpu.get_int_value(deadframe, 2) == -63 assert cpu.get_int_value(deadframe, 3) == 17 assert cpu.get_int_value(deadframe, 4) == 32 assert cpu.get_int_value(deadframe, 5) == -16
def test_int_add(self): # random seed: 1202 # block length: 4 # AssertionError: Got 1431655764, expected 357913940 for value #3 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() tmp12 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_ADD, [ConstInt(-1073741825), v3], v11), ResOperation(rop.INT_IS_TRUE, [v1], tmp12), ResOperation(rop.GUARD_FALSE, [tmp12], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[2].setfailargs([v10, v3, v6, v11, v9, v2]) operations[-1].setfailargs([v8, v2, v10, v6, v7, v9, v5, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 assert cpu.get_int_value(deadframe, 0) == -43 assert cpu.get_int_value(deadframe, 1) == 1431655765 assert cpu.get_int_value(deadframe, 2) == 1789569706 assert cpu.get_int_value(deadframe, 3) == 357913940 assert cpu.get_int_value(deadframe, 4) == 16 assert cpu.get_int_value(deadframe, 5) == -5
def test_call_may_force_gcmap(self): cpu = self.cpu def f(frame, arg, x): assert not arg if self.cpu.backend_name != 'asmjs': assert frame.jf_gcmap[0] & 31 == 0 assert getmap(frame).count('1') == 3 # p1, p2, p3, but # not in registers frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) FUNC = lltype.FuncType([JITFRAMEPTR, llmemory.GCREF, lltype.Signed], llmemory.GCREF) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) a = lltype.malloc(A, 3, zero=True) loop = self.parse(""" [i0, p0] pf = force_token() p1 = getarrayitem_gc(p0, 0, descr=arraydescr) p2 = getarrayitem_gc(p0, 1, descr=arraydescr) p3 = getarrayitem_gc(p0, 2, descr=arraydescr) pdying = getarrayitem_gc(p0, 0, descr=arraydescr) px = call_may_force(ConstClass(fptr), pf, pdying, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, px] finish(px, descr=finaldescr) """, namespace={ 'fptr': fptr, 'calldescr': calldescr, 'arraydescr': cpu.arraydescrof(A), 'faildescr': BasicFailDescr(1), 'finaldescr': BasicFinalDescr(2) }) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4
def test0(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_SUB, [ConstInt(-1073741824), v7], v11), ResOperation(rop.INT_GE, [v3, ConstInt(23)], v12), ResOperation(rop.GUARD_TRUE, [v12], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] looptoken = JitCellToken() operations[2].setfailargs([v12, v8, v3, v2, v1, v11]) operations[3].setfailargs([v9, v6, v10, v2, v8, v5, v1, v4]) cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == 62 assert cpu.get_int_value(deadframe, 2) == -19 assert cpu.get_int_value(deadframe, 3) == -26 assert cpu.get_int_value(deadframe, 4) == -12 assert cpu.get_int_value(deadframe, 5) == -1073741787
def test_guard_descr(self): namespace = {'fdescr': BasicFailDescr()} inp = ''' [i0] guard_true(i0, descr=fdescr) [i0] ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd(), guard_number=True) output = logger.log_loop(loop) assert re.match("guard_true\(i0, descr=<Guard0x[\da-f]+>\) \[i0\]", output.splitlines()[-1]) pure_parse(output) logger = Logger(self.make_metainterp_sd(), guard_number=False) output = logger.log_loop(loop) lastline = output.splitlines()[-1] assert lastline.startswith("guard_true(i0, descr=<") assert not lastline.startswith("guard_true(i0, descr=<Guard")
def test_finish_with_guard_not_forced_2_ref(self): cpu = self.cpu loop = self.parse(""" [p0, p1] guard_not_forced_2(descr=faildescr) [p1] finish(p0, descr=finaldescr) """, namespace={'faildescr': BasicFailDescr(1), 'finaldescr': BasicFinalDescr(2)}) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) n = lltype.nullptr(llmemory.GCREF.TO) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, n, n)) assert getmap(frame).count('1') == 2
def test_stuff_followed_by_guard(self): boxes = [(InputArgInt(1), InputArgInt(0)), (InputArgInt(0), InputArgInt(1)), (InputArgInt(1), InputArgInt(1)), (InputArgInt(-1), InputArgInt(1)), (InputArgInt(1), InputArgInt(-1)), (ConstInt(1), InputArgInt(0)), (ConstInt(0), InputArgInt(1)), (ConstInt(1), InputArgInt(1)), (ConstInt(-1), InputArgInt(1)), (ConstInt(1), InputArgInt(-1)), (InputArgInt(1), ConstInt(0)), (InputArgInt(0), ConstInt(1)), (InputArgInt(1), ConstInt(1)), (InputArgInt(-1), ConstInt(1)), (InputArgInt(1), ConstInt(-1))] guards = [rop.GUARD_FALSE, rop.GUARD_TRUE] all = [rop.INT_EQ, rop.INT_NE, rop.INT_LE, rop.INT_LT, rop.INT_GT, rop.INT_GE, rop.UINT_GT, rop.UINT_LT, rop.UINT_LE, rop.UINT_GE] for a, b in boxes: for guard in guards: for op in all: i1 = ResOperation(rop.SAME_AS_I, [ConstInt(1)]) res = ResOperation(op, [a, b]) ops = [ i1, res, ResOperation(guard, [res], descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], descr=BasicFinalDescr()), ] ops[-2].setfailargs([i1]) inputargs = [i for i in (a, b) if not isinstance(i, Const)] looptoken = JitCellToken() self.cpu.compile_loop(inputargs, ops, looptoken) inputvalues = [box.getint() for box in inputargs] deadframe = self.cpu.execute_token(looptoken, *inputvalues) result = self.cpu.get_int_value(deadframe, 0) expected = execute(self.cpu, None, op, None, a, b) if guard == rop.GUARD_FALSE: assert result == expected else: assert result != expected
def test_label_float_in_reg_and_on_stack(self): targettoken = TargetToken() ops = """ [i0, f3] i2 = same_as_i(i0) # but forced to be in a register force_spill(i2) force_spill(f3) f4 = float_add(f3, 5.0) label(f3, f4, descr=targettoken) force_spill(f3) f5 = same_as_f(f3) # but forced to be in a register finish(f5) """ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as_i(i0) f2 = same_as_f(f1) f3 = float_add(f1, 10.0) force_spill(f3) force_spill(i1) f4 = float_add(f3, f1) jump(f3, f4, descr=targettoken) """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -13.5 # deadframe = self.cpu.execute_token(looptoken2, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -3.5
def test_uint_rshift(self): code = """ [i1] i11 = int_and(i1, 63) i10 = uint_rshift(18, i11) i1402 = int_is_true(i10) guard_false(i1402, descr=faildescr) [] # must NEVER exit with i1 == 0 finish(i1402, descr=finishdescr) """ finishdescr = BasicFinalDescr(1) faildescr = BasicFailDescr(2) loop = parse(code, namespace={ 'faildescr': faildescr, 'finishdescr': finishdescr }) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 19) fail = self.cpu.get_latest_descr(deadframe) assert fail == finishdescr # ensures that guard is not taken!
def test_bug_rshift(): v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() inputargs = [v1] operations = [ ResOperation(rop.INT_ADD, [v1, v1], v2), ResOperation(rop.INT_INVERT, [v2], v3), ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4), ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs([v4, v3]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18)
def test_calling_convention(self, monkeypatch): if WORD != 4: py.test.skip("32-bit only test") from rpython.jit.backend.x86.regloc import eax, edx from rpython.jit.backend.x86 import codebuf, callbuilder from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rlib.libffi import types, clibffi had_stdcall = hasattr(clibffi, 'FFI_STDCALL') if not had_stdcall: # not running on Windows, but we can still test monkeypatch.setattr(clibffi, 'FFI_STDCALL', 12345, raising=False) monkeypatch.setattr(callbuilder, 'stdcall_or_cdecl', True) else: assert callbuilder.stdcall_or_cdecl # for real_ffi, reported_ffi in [ (clibffi.FFI_DEFAULT_ABI, clibffi.FFI_DEFAULT_ABI), (clibffi.FFI_STDCALL, clibffi.FFI_DEFAULT_ABI), (clibffi.FFI_STDCALL, clibffi.FFI_STDCALL) ]: cpu = self.cpu mc = codebuf.MachineCodeBlockWrapper() mc.MOV_rs(eax.value, 4) # argument 1 mc.MOV_rs(edx.value, 40) # argument 10 mc.SUB_rr(eax.value, edx.value) # return arg1 - arg10 if real_ffi == clibffi.FFI_DEFAULT_ABI: mc.RET() else: mc.RET16_i(40) rawstart = mc.materialize(cpu, []) # calldescr = cpu._calldescr_dynamic_for_tests([types.slong] * 10, types.slong) calldescr.get_call_conv = lambda: reported_ffi # <==== hack # ^^^ we patch get_call_conv() so that the test also makes sense # on Linux, because clibffi.get_call_conv() would always # return FFI_DEFAULT_ABI on non-Windows platforms. funcbox = ConstInt(rawstart) i1 = InputArgInt() i2 = InputArgInt() c = ConstInt(-1) faildescr = BasicFailDescr(1) cz = ConstInt(0) # we must call it repeatedly: if the stack pointer gets increased # by 40 bytes by the STDCALL call, and if we don't expect it, # then we are going to get our stack emptied unexpectedly by # several repeated calls ops = [ ResOperation(rop.CALL_RELEASE_GIL_I, [cz, funcbox, i1, c, c, c, c, c, c, c, c, i2], descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL_I, [cz, funcbox, i1, c, c, c, c, c, c, c, c, i2], descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL_I, [cz, funcbox, i1, c, c, c, c, c, c, c, c, i2], descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL_I, [cz, funcbox, i1, c, c, c, c, c, c, c, c, i2], descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ] i3 = ops[0] i4 = ops[2] i5 = ops[4] i6 = ops[6] ops += [ ResOperation(rop.GUARD_FALSE, [i3], descr=BasicFailDescr(0)), ResOperation(rop.FINISH, [], descr=BasicFinalDescr(1)) ] ops[-2].setfailargs([i3, i4, i5, i6]) ops[1].setfailargs([]) ops[3].setfailargs([]) ops[5].setfailargs([]) ops[7].setfailargs([]) looptoken = JitCellToken() self.cpu.compile_loop([i1, i2], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 123450, 123408) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 assert self.cpu.get_int_value(deadframe, 0) == 42 assert self.cpu.get_int_value(deadframe, 1) == 42 assert self.cpu.get_int_value(deadframe, 2) == 42 assert self.cpu.get_int_value(deadframe, 3) == 42
def test_compile_bridge_check_profile_info(self): py.test.skip("does not work, reinvestigate") class FakeProfileAgent(object): def __init__(self): self.functions = [] def native_code_written(self, name, address, size): self.functions.append((name, address, size)) self.cpu.profile_agent = agent = FakeProfileAgent() i0 = InputArgInt() i1 = InputArgInt() i2 = InputArgInt() targettoken = TargetToken() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) looptoken = JitCellToken() looptoken.number = 17 class FakeString(object): def __init__(self, val): self.val = val def _get_str(self): return self.val operations = [ ResOperation(rop.LABEL, [i0], None, descr=targettoken), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0, 0], None), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), ResOperation(rop.JUMP, [i1], None, descr=targettoken), ] inputargs = [i0] operations[-2].setfailargs([i1]) self.cpu.compile_loop(inputargs, operations, looptoken) name, loopaddress, loopsize = agent.functions[0] assert name == "Loop # 17: hello (loop counter 0)" assert loopaddress <= looptoken._ll_loop_code assert loopsize >= 40 # randomish number i1b = InputArgInt() i3 = InputArgInt() bridge = [ ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3), ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0, 0], None), ResOperation(rop.JUMP, [i1b], None, descr=targettoken), ] bridge[1].setfailargs([i1b]) self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) name, address, size = agent.functions[1] assert name == "Bridge # 0: bye (loop counter 1)" # Would be exactly ==, but there are some guard failure recovery # stubs in-between assert address >= loopaddress + loopsize assert size >= 10 # randomish number deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 res = self.cpu.get_int_value(deadframe, 0) assert res == 20