Пример #1
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
Пример #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()
     cpu.compile_loop(args, operations, loop_token)
     self.loop_token = loop_token
     return loop_token
Пример #3
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
Пример #4
0
 def produce_into(self, builder, r):
     op, passing = self.gen_guard(builder, r)
     builder.loop.operations.append(op)
     op.descr = BasicFailDescr()
     op.fail_args = builder.subset_of_intvars(r)
     if not passing:
         builder.should_fail_by = op
         builder.guard_op = op
Пример #5
0
 def test_stuff_followed_by_guard(self):
     boxes = [(BoxInt(1), BoxInt(0)),
              (BoxInt(0), BoxInt(1)),
              (BoxInt(1), BoxInt(1)),
              (BoxInt(-1), BoxInt(1)),
              (BoxInt(1), BoxInt(-1)),
              (ConstInt(1), BoxInt(0)),
              (ConstInt(0), BoxInt(1)),
              (ConstInt(1), BoxInt(1)),
              (ConstInt(-1), BoxInt(1)),
              (ConstInt(1), BoxInt(-1)),
              (BoxInt(1), ConstInt(0)),
              (BoxInt(0), ConstInt(1)),
              (BoxInt(1), ConstInt(1)),
              (BoxInt(-1), ConstInt(1)),
              (BoxInt(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:
                 res = BoxInt()
                 i1 = BoxInt(1)
                 ops = [
                     ResOperation(rop.SAME_AS, [ConstInt(1)], i1),
                     ResOperation(op, [a, b], res),
                     ResOperation(guard, [res], None,
                                  descr=BasicFailDescr()),
                     ResOperation(rop.FINISH, [ConstInt(0)], None,
                                  descr=BasicFailDescr()),
                     ]
                 ops[-2].setfailargs([i1])
                 inputargs = [i for i in (a, b) if isinstance(i, Box)]
                 looptoken = JitCellToken()
                 self.cpu.compile_loop(inputargs, ops, looptoken)
                 inputvalues = [box.value for box in inputargs]
                 self.cpu.execute_token(looptoken, *inputvalues)
                 result = self.cpu.get_latest_value_int(0)
                 expected = execute(self.cpu, None, op, None, a, b).value
                 if guard == rop.GUARD_FALSE:
                     assert result == expected
                 else:
                     assert result != expected
Пример #6
0
 def exc_handling(guard_op):
     # operations need to start with correct GUARD_EXCEPTION
     if guard_op._exc_box is None:
         op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None)
     else:
         op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box],
                           BoxPtr())
     op.descr = BasicFailDescr()
     op.fail_args = []
     return op
Пример #7
0
 def test_nullity_with_guard(self):
     allops = [rop.OONONNULL, rop.OOISNULL, rop.INT_IS_TRUE]
     guards = [rop.GUARD_TRUE, rop.GUARD_FALSE]
     p = lltype.cast_opaque_ptr(llmemory.GCREF,
                                lltype.malloc(lltype.GcStruct('x')))
     nullptr = lltype.nullptr(llmemory.GCREF.TO)
     f = BoxInt()
     for op in allops:
         for guard in guards:
             if op == rop.INT_IS_TRUE:
                 bp = BoxInt(1)
                 n = BoxInt(0)
             else:
                 bp = BoxPtr(p)
                 n = BoxPtr(nullptr)
             for b in (bp, n):
                 i1 = BoxInt(1)
                 ops = [
                     ResOperation(rop.SAME_AS, [ConstInt(1)], i1),
                     ResOperation(op, [b], f),
                     ResOperation(guard, [f], None, descr=BasicFailDescr()),
                     ResOperation(rop.FINISH, [ConstInt(0)],
                                  None,
                                  descr=BasicFailDescr()),
                 ]
                 ops[-2].fail_args = [i1]
                 looptoken = LoopToken()
                 self.cpu.compile_loop([b], ops, looptoken)
                 if op == rop.INT_IS_TRUE:
                     self.cpu.set_future_value_int(0, b.value)
                 else:
                     self.cpu.set_future_value_ref(0, b.value)
                 r = self.cpu.execute_token(looptoken)
                 result = self.cpu.get_latest_value_int(0)
                 if guard == rop.GUARD_FALSE:
                     assert result == execute(self.cpu, op, None, b).value
                 else:
                     assert result != execute(self.cpu, op, None, b).value
Пример #8
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       BoxPtr(),
                       descr=BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Пример #9
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     if len(subset) == 0:
         RES = lltype.Void
     else:
         RES = lltype.Signed
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=BasicFailDescr())
     op.fail_args = fail_subset
     builder.loop.operations.append(op)
Пример #10
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp._got_exc:  # overflow detected
         assert isinstance(builder.fakemetainterp._got_exc, OverflowError)
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
     op.setdescr(BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Пример #11
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
     self.put(builder, args, descr)
     assert builder.cpu.get_exception()
     builder.cpu.clear_exception()
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], BoxPtr(),
                       descr=BasicFailDescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.fail_args = builder.subset_of_intvars(r)
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Пример #12
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.cpu._overflow_flag:  # overflow detected
         del builder.cpu._overflow_flag
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
     op.descr = BasicFailDescr()
     op.fail_args = fail_subset
     builder.loop.operations.append(op)
Пример #13
0
    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 output.splitlines()[-1] == "guard_true(i0, descr=<Guard0>) [i0]"
        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")
Пример #14
0
 def test_guard(self):
     namespace = {'fdescr': BasicFailDescr(4)}
     inp = '''
     [i0]
     guard_true(i0, descr=fdescr) [i0]
     '''
     loop = pure_parse(inp, namespace=namespace)
     logger = Logger(self.ts, guard_number=True)
     output = logger.log_loop(loop)
     assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard4>) [i0]"
     pure_parse(output)
     
     def boom():
         raise Exception
     namespace['fdescr'].get_index = boom
     logger = Logger(self.ts, guard_number=False)
     output = logger.log_loop(loop)
     assert output.splitlines()[-1].startswith("guard_true(i0, descr=<")
Пример #15
0
    def generate_ops(self, builder, r, loop, startvars, needs_a_label=False):
        block_length = pytest.config.option.block_length
        istart = 0

        for i in range(block_length):
            istart = len(loop.operations)
            try:
                op = r.choice(builder.OPERATIONS)
                op.filter(builder)
                op.produce_into(builder, r)
            except CannotProduceOperation:
                pass
            if builder.should_fail_by is not None:
                break
            if needs_a_label and r.random() < 0.2:
                self.insert_label(loop, istart, r)
                needs_a_label = False
        if needs_a_label:
            self.insert_label(loop, istart, r)

        endvars = []
        used_later = {}
        for op in loop.operations:
            for v in op.getarglist():
                used_later[v] = True
        for v in startvars:
            if v not in used_later:
                endvars.append(v)
        r.shuffle(endvars)
        loop.operations.append(
            ResOperation(rop.FINISH, endvars, None, descr=BasicFailDescr()))
        if builder.should_fail_by:
            self.should_fail_by = builder.should_fail_by
            self.guard_op = builder.guard_op
        else:
            self.should_fail_by = loop.operations[-1]
            self.guard_op = None
        self.prebuilt_ptr_consts.extend(builder.prebuilt_ptr_consts)
        endvars = self.get_fail_args()
        self.expected = {}
        for v in endvars:
            self.expected[v] = v.value
        if pytest.config.option.output:
            builder.print_loop()
Пример #16
0
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.FINISH, [v4, v3], None, descr=BasicFailDescr()),
        ]
    cpu = CPU(None, None)
    looptoken = LoopToken()
    cpu.compile_loop(inputargs, operations, looptoken)
    cpu.set_future_value_int(0, 9)
    cpu.execute_token(looptoken)
    assert cpu.get_latest_value_int(0) == (9 >> 3)
    assert cpu.get_latest_value_int(1) == (~18)
Пример #17
0
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     if len(subset) == 0:
         RES = lltype.Void
     else:
         RES = lltype.Signed
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
     self.put(builder, args, descr)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
                       descr=BasicFailDescr())
     op.fail_args = builder.subset_of_intvars(r)
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Пример #18
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box],
                       BoxPtr(),
                       descr=BasicFailDescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Пример #19
0
def test_bug_int_is_true_1():
    v1 = BoxInt()
    v2 = BoxInt()
    v3 = BoxInt()
    v4 = 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.BOOL_NOT, [tmp5], v4),
        ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()),
            ]
    cpu = CPU(None, None)
    looptoken = LoopToken()
    cpu.compile_loop(inputargs, operations, looptoken)
    cpu.set_future_value_int(0, -10)
    cpu.execute_token(looptoken)
    assert cpu.get_latest_value_int(0) == 0
    assert cpu.get_latest_value_int(1) == -1000
    assert cpu.get_latest_value_int(2) == 1
Пример #20
0
    def generate_ops(self, builder, r, loop, startvars):
        block_length = demo_conftest.option.block_length

        for i in range(block_length):
            try:
                op = r.choice(builder.OPERATIONS)
                op.filter(builder)
                op.produce_into(builder, r)
            except CannotProduceOperation:
                pass
            if builder.should_fail_by is not None:
                break
        endvars = []
        used_later = {}
        for op in loop.operations:
            for v in op.args:
                used_later[v] = True
        for v in startvars:
            if v not in used_later:
                endvars.append(v)
        r.shuffle(endvars)
        loop.operations.append(
            ResOperation(rop.FINISH, endvars, None, descr=BasicFailDescr()))
        if builder.should_fail_by:
            self.should_fail_by = builder.should_fail_by
            self.guard_op = builder.guard_op
        else:
            self.should_fail_by = loop.operations[-1]
            self.guard_op = None
        self.prebuilt_ptr_consts.extend(builder.prebuilt_ptr_consts)
        endvars = self.get_fail_args()
        self.expected = {}
        for v in endvars:
            self.expected[v] = v.value
        if demo_conftest.option.output:
            builder.print_loop()
Пример #21
0
def test_bug_1():
    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()
    v19 = BoxInt()
    v20 = BoxInt()
    v21 = BoxInt()
    v22 = BoxInt()
    v23 = BoxInt()
    v24 = BoxInt()
    v25 = BoxInt()
    v26 = BoxInt()
    v27 = BoxInt()
    v28 = BoxInt()
    v29 = BoxInt()
    v30 = BoxInt()
    v31 = BoxInt()
    v32 = BoxInt()
    v33 = BoxInt()
    v34 = BoxInt()
    v35 = BoxInt()
    v36 = BoxInt()
    v37 = BoxInt()
    v38 = BoxInt()
    v39 = BoxInt()
    v40 = BoxInt()
    tmp41 = BoxInt()
    tmp42 = BoxInt()
    tmp43 = BoxInt()
    tmp44 = BoxInt()
    tmp45 = BoxInt()
    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
    operations = [
        ResOperation(rop.UINT_LT, [v6, ConstInt(0)], v11),
        ResOperation(rop.INT_AND, [v3, ConstInt(31)], tmp41),
        ResOperation(rop.INT_RSHIFT, [v3, tmp41], v12),
        ResOperation(rop.INT_NEG, [v2], v13),
        ResOperation(rop.INT_ADD, [v11, v7], v14),
        ResOperation(rop.INT_OR, [v3, v2], v15),
        ResOperation(rop.INT_OR, [v12, v12], v16),
        ResOperation(rop.INT_NE, [v2, v5], v17),
        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp42),
        ResOperation(rop.UINT_RSHIFT, [v14, tmp42], v18),
        ResOperation(rop.INT_AND, [v14, ConstInt(31)], tmp43),
        ResOperation(rop.INT_LSHIFT, [ConstInt(7), tmp43], v19),
        ResOperation(rop.INT_NEG, [v19], v20),
        ResOperation(rop.INT_MOD, [v3, ConstInt(1)], v21),
        ResOperation(rop.UINT_GE, [v15, v1], v22),
        ResOperation(rop.INT_AND, [v16, ConstInt(31)], tmp44),
        ResOperation(rop.INT_LSHIFT, [v8, tmp44], v23),
        ResOperation(rop.INT_IS_TRUE, [v17], v24),
        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp45),
        ResOperation(rop.INT_LSHIFT, [v14, tmp45], v25),
        ResOperation(rop.INT_LSHIFT, [v5, ConstInt(17)], v26),
        ResOperation(rop.INT_EQ, [v9, v15], v27),
        ResOperation(rop.INT_GE, [ConstInt(0), v6], v28),
        ResOperation(rop.INT_NEG, [v15], v29),
        ResOperation(rop.INT_NEG, [v22], v30),
        ResOperation(rop.INT_ADD, [v7, v16], v31),
        ResOperation(rop.UINT_LT, [v19, v19], v32),
        ResOperation(rop.INT_ADD, [v2, ConstInt(1)], v33),
        ResOperation(rop.INT_NEG, [v5], v34),
        ResOperation(rop.INT_ADD, [v17, v24], v35),
        ResOperation(rop.UINT_LT, [ConstInt(2), v16], v36),
        ResOperation(rop.INT_NEG, [v9], v37),
        ResOperation(rop.INT_GT, [v4, v11], v38),
        ResOperation(rop.INT_LT, [v27, v22], v39),
        ResOperation(rop.INT_NEG, [v27], v40),
        ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()),
            ]
    cpu = CPU(None, None)
    looptoken = LoopToken()
    cpu.compile_loop(inputargs, operations, looptoken)
    cpu.set_future_value_int(0, 17)
    cpu.set_future_value_int(1, -20)
    cpu.set_future_value_int(2, -6)
    cpu.set_future_value_int(3, 6)
    cpu.set_future_value_int(4, 1)
    cpu.set_future_value_int(5, 13)
    cpu.set_future_value_int(6, 13)
    cpu.set_future_value_int(7, 9)
    cpu.set_future_value_int(8, 49)
    cpu.set_future_value_int(9, 8)
    cpu.execute_token(looptoken)
    assert cpu.get_latest_value_int(0) == 0
    assert cpu.get_latest_value_int(1) == 8
    assert cpu.get_latest_value_int(2) == 1
    assert cpu.get_latest_value_int(3) == 131072
    assert cpu.get_latest_value_int(4) == 20
    assert cpu.get_latest_value_int(5) == -1
    assert cpu.get_latest_value_int(6) == 0
    assert cpu.get_latest_value_int(7) == -19
    assert cpu.get_latest_value_int(8) == 6
    assert cpu.get_latest_value_int(9) == 26
    assert cpu.get_latest_value_int(10) == 12
    assert cpu.get_latest_value_int(11) == 0
    assert cpu.get_latest_value_int(12) == 0
    assert cpu.get_latest_value_int(13) == 2
    assert cpu.get_latest_value_int(14) == 2
    assert cpu.get_latest_value_int(15) == 1
    assert cpu.get_latest_value_int(16) == -57344
    assert cpu.get_latest_value_int(17) == 1
    assert cpu.get_latest_value_int(18) == -1
    assert cpu.get_latest_value_int(19) == -2147483648
    assert cpu.get_latest_value_int(20) == -49
Пример #22
0
def default_fail_descr(fail_args=None):
    return BasicFailDescr()
Пример #23
0
class BaseTestRegalloc(object):
    cpu = CPU(None, None)

    def raising_func(i):
        if i:
            raise LLException(zero_division_error, zero_division_value)

    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    raising_fptr = llhelper(FPTR, raising_func)
    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
    zero_division_error = llmemory.cast_adr_to_ptr(
        zd_addr, lltype.Ptr(rclass.OBJECT_VTABLE))
    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT)

    fdescr1 = BasicFailDescr(1)
    fdescr2 = BasicFailDescr(2)
    fdescr3 = BasicFailDescr(3)

    namespace = locals().copy()
    type_system = 'lltype'

    def parse(self, s, boxkinds=None):
        return parse(s,
                     self.cpu,
                     self.namespace,
                     type_system=self.type_system,
                     boxkinds=boxkinds)

    def interpret(self, ops, args, run=True):
        loop = self.parse(ops)
        self.cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
        for i, arg in enumerate(args):
            if isinstance(arg, int):
                self.cpu.set_future_value_int(i, arg)
            elif isinstance(arg, float):
                self.cpu.set_future_value_float(i, arg)
            else:
                assert isinstance(lltype.typeOf(arg), lltype.Ptr)
                llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
                self.cpu.set_future_value_ref(i, llgcref)
        if run:
            self.cpu.execute_token(loop.token)
        return loop

    def getint(self, index):
        return self.cpu.get_latest_value_int(index)

    def getfloat(self, index):
        return self.cpu.get_latest_value_float(index)

    def getints(self, end):
        return [
            self.cpu.get_latest_value_int(index) for index in range(0, end)
        ]

    def getfloats(self, end):
        return [
            self.cpu.get_latest_value_float(index) for index in range(0, end)
        ]

    def getptr(self, index, T):
        gcref = self.cpu.get_latest_value_ref(index)
        return lltype.cast_opaque_ptr(T, gcref)

    def attach_bridge(self, ops, loop, guard_op_index, looptoken=None, **kwds):
        if looptoken is not None:
            self.namespace = self.namespace.copy()
            self.namespace['looptoken'] = looptoken
        guard_op = loop.operations[guard_op_index]
        assert guard_op.is_guard()
        bridge = self.parse(ops, **kwds)
        assert ([box.type for box in bridge.inputargs
                 ] == [box.type for box in guard_op.fail_args])
        faildescr = guard_op.descr
        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations)
        return bridge

    def run(self, loop):
        return self.cpu.execute_token(loop.token)
Пример #24
0
class BaseTestRegalloc(object):
    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)
    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
    zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
                                            lltype.Ptr(rclass.OBJECT_VTABLE))
    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                        EffectInfo.MOST_GENERAL)

    targettoken = TargetToken()
    targettoken2 = TargetToken()
    fdescr1 = BasicFailDescr(1)
    fdescr2 = BasicFailDescr(2)
    fdescr3 = BasicFailDescr(3)

    def setup_method(self, meth):
        self.targettoken._x86_loop_code = 0
        self.targettoken2._x86_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()
    type_system = 'lltype'

    def parse(self, s, boxkinds=None):
        return parse(s, self.cpu, self.namespace,
                     type_system=self.type_system,
                     boxkinds=boxkinds)

    def interpret(self, ops, args, run=True):
        loop = self.parse(ops)
        looptoken = JitCellToken()
        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
        arguments = []
        for arg in args:
            if isinstance(arg, int):
                arguments.append(arg)
            elif isinstance(arg, float):
                arg = longlong.getfloatstorage(arg)
                arguments.append(arg)
            else:
                assert isinstance(lltype.typeOf(arg), lltype.Ptr)
                llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
                arguments.append(llgcref)
        loop._jitcelltoken = looptoken
        if run:
            self.cpu.execute_token(looptoken, *arguments)
        return loop

    def prepare_loop(self, ops):
        loop = self.parse(ops)
        regalloc = RegAlloc(self.cpu.assembler, False)
        regalloc.prepare_loop(loop.inputargs, loop.operations,
                              loop.original_jitcell_token, [])
        return regalloc

    def getint(self, index):
        return self.cpu.get_latest_value_int(index)

    def getfloat(self, index):
        return self.cpu.get_latest_value_float(index)

    def getints(self, end):
        return [self.cpu.get_latest_value_int(index) for
                index in range(0, end)]

    def getfloats(self, end):
        return [longlong.getrealfloat(self.cpu.get_latest_value_float(index))
                for index in range(0, end)]

    def getptr(self, index, T):
        gcref = self.cpu.get_latest_value_ref(index)
        return lltype.cast_opaque_ptr(T, gcref)

    def attach_bridge(self, ops, loop, guard_op_index, **kwds):
        guard_op = loop.operations[guard_op_index]
        assert guard_op.is_guard()
        bridge = self.parse(ops, **kwds)
        assert ([box.type for box in bridge.inputargs] ==
                [box.type for box in guard_op.getfailargs()])
        faildescr = guard_op.getdescr()
        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
                                loop._jitcelltoken)
        return bridge

    def run(self, loop, *arguments):
        return self.cpu.execute_token(loop._jitcelltoken, *arguments)
Пример #25
0
    def test_calling_convention(self, monkeypatch):
        if WORD != 4:
            py.test.skip("32-bit only test")
        from pypy.jit.backend.x86.regloc import eax, edx
        from pypy.jit.backend.x86 import codebuf
        from pypy.jit.codewriter.effectinfo import EffectInfo
        from pypy.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)
        #
        for ffi in [clibffi.FFI_DEFAULT_ABI, 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 ffi == clibffi.FFI_DEFAULT_ABI:
                mc.RET()
            else:
                mc.RET16_i(40)
            rawstart = mc.materialize(cpu.asmmemmgr, [])
            #
            calldescr = cpu.calldescrof_dynamic([types.slong] * 10,
                                                types.slong,
                                                EffectInfo.MOST_GENERAL,
                                                ffi_flags=-1)
            calldescr.get_call_conv = lambda: 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 = BoxInt()
            i2 = BoxInt()
            i3 = BoxInt()
            i4 = BoxInt()
            i5 = BoxInt()
            i6 = BoxInt()
            c = ConstInt(-1)
            faildescr = BasicFailDescr(1)
            # 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,
                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
                         i3, descr=calldescr),
            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),

            ResOperation(rop.CALL_RELEASE_GIL,
                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
                         i4, descr=calldescr),
            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),

            ResOperation(rop.CALL_RELEASE_GIL,
                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
                         i5, descr=calldescr),
            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),

            ResOperation(rop.CALL_RELEASE_GIL,
                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
                         i6, descr=calldescr),
            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),

            ResOperation(rop.FINISH, [i3, i4, i5, i6], None,
                         descr=BasicFailDescr(0))
            ]
            ops[1].setfailargs([])
            ops[3].setfailargs([])
            ops[5].setfailargs([])
            ops[7].setfailargs([])
            looptoken = JitCellToken()
            self.cpu.compile_loop([i1, i2], ops, looptoken)

            fail = self.cpu.execute_token(looptoken, 123450, 123408)
            assert fail.identifier == 0
            assert self.cpu.get_latest_value_int(0) == 42
            assert self.cpu.get_latest_value_int(1) == 42
            assert self.cpu.get_latest_value_int(2) == 42
            assert self.cpu.get_latest_value_int(3) == 42
Пример #26
0
    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 = BoxInt()
        i1 = BoxInt()
        i2 = BoxInt()
        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], 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._x86_loop_code
        assert loopsize >= 40 # randomish number

        i1b = BoxInt()
        i3 = BoxInt()
        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], 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

        fail = self.cpu.execute_token(looptoken, 2)
        assert fail.identifier == 2
        res = self.cpu.get_latest_value_int(0)
        assert res == 20
Пример #27
0
    def test_call_alignment_call_assembler(self):
        from pypy.rlib.libffi import types
        cpu = self.cpu
        if not cpu.supports_floats:
            py.test.skip('requires floats')

        fdescr3 = BasicFailDescr(3)
        fdescr4 = BasicFailDescr(4)

        def assembler_helper(failindex, virtualizable):
            assert 0, 'should not be called, but was with failindex (%d)' % failindex
            return 13

        FUNCPTR = lltype.Ptr(
            lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Signed))

        class FakeJitDriverSD:
            index_of_virtualizable = -1
            _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
            assembler_helper_adr = llmemory.cast_ptr_to_adr(
                _assembler_helper_ptr)

        floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56]
        ints = [7, 11, 23, 42, -42, 1111, 95, 1]

        for case in range(256):
            float_count = 0
            int_count = 0
            args = []
            called_ops = ''
            total_index = -1
            for i in range(8):
                if case & (1 << i):
                    args.append('f%d' % float_count)
                else:
                    args.append('i%d' % int_count)
                    called_ops += 'f%d = cast_int_to_float(i%d)\n' % (
                        float_count, int_count)
                    int_count += 1
                if total_index == -1:
                    total_index = float_count
                    float_count += 1
                else:
                    called_ops += 'f%d = float_add(f%d, f%d)\n' % (
                        float_count + 1, total_index, float_count)
                    total_index = float_count + 1
                    float_count += 2
            arguments = ', '.join(args)
            called_ops = '[%s]\n' % arguments + called_ops
            called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index
            # compile called loop
            called_loop = parse(called_ops, namespace=locals())
            called_looptoken = JitCellToken()
            called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
            done_number = self.cpu.get_fail_descr_number(
                called_loop.operations[-1].getdescr())
            self.cpu.compile_loop(called_loop.inputargs,
                                  called_loop.operations, called_looptoken)

            argvals, expected_result = self._prepare_args(args, floats, ints)
            res = cpu.execute_token(called_looptoken, *argvals)
            assert res.identifier == 3
            t = longlong.getrealfloat(cpu.get_latest_value_float(0))
            assert abs(t - expected_result) < 0.0001

            ARGS = []
            RES = lltype.Float
            for x in args:
                if x[0] == 'f':
                    ARGS.append(lltype.Float)
                else:
                    ARGS.append(lltype.Signed)
            FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
                lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
                EffectInfo.MOST_GENERAL)
            ops = '''
            [%s]
            f99 = call_assembler(%s, descr=called_looptoken)
            guard_not_forced()[]
            finish(f99, descr=fdescr4)
            ''' % (arguments, arguments)
            loop = parse(ops, namespace=locals())
            # we want to take the fast path
            self.cpu.done_with_this_frame_float_v = done_number
            try:
                othertoken = JitCellToken()
                self.cpu.compile_loop(loop.inputargs, loop.operations,
                                      othertoken)

                # prepare call to called_loop
                argvals, _ = self._prepare_args(args, floats, ints)
                res = cpu.execute_token(othertoken, *argvals)
                x = longlong.getrealfloat(cpu.get_latest_value_float(0))
                assert res.identifier == 4
                assert abs(x - expected_result) < 0.0001
            finally:
                del self.cpu.done_with_this_frame_float_v
Пример #28
0
 def make_fail_descr(cls):
     descr = BasicFailDescr(cls.failnumbering)
     cls.failnumbering += 1
     return descr
Пример #29
0
def test_bug_0():
    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()
    v19 = BoxInt()
    v20 = BoxInt()
    v21 = BoxInt()
    v22 = BoxInt()
    v23 = BoxInt()
    v24 = BoxInt()
    v25 = BoxInt()
    v26 = BoxInt()
    v27 = BoxInt()
    v28 = BoxInt()
    v29 = BoxInt()
    v30 = BoxInt()
    v31 = BoxInt()
    v32 = BoxInt()
    v33 = BoxInt()
    v34 = BoxInt()
    v35 = BoxInt()
    v36 = BoxInt()
    v37 = BoxInt()
    v38 = BoxInt()
    v39 = BoxInt()
    v40 = BoxInt()
    tmp41 = BoxInt()
    tmp42 = BoxInt()
    tmp43 = BoxInt()
    tmp44 = BoxInt()
    tmp45 = BoxInt()
    tmp46 = BoxInt()
    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
    operations = [
        ResOperation(rop.UINT_GT, [v3, ConstInt(-48)], v11),
        ResOperation(rop.INT_XOR, [v8, v1], v12),
        ResOperation(rop.INT_GT, [v6, ConstInt(-9)], v13),
        ResOperation(rop.INT_LE, [v13, v2], v14),
        ResOperation(rop.INT_LE, [v11, v5], v15),
        ResOperation(rop.UINT_GE, [v13, v13], v16),
        ResOperation(rop.INT_OR, [v9, ConstInt(-23)], v17),
        ResOperation(rop.INT_LT, [v10, v13], v18),
        ResOperation(rop.INT_OR, [v15, v5], v19),
        ResOperation(rop.INT_XOR, [v17, ConstInt(54)], v20),
        ResOperation(rop.INT_MUL, [v8, v10], v21),
        ResOperation(rop.INT_OR, [v3, v9], v22),
        ResOperation(rop.INT_AND, [v11, ConstInt(-4)], tmp41),
        ResOperation(rop.INT_OR, [tmp41, ConstInt(1)], tmp42),
        ResOperation(rop.INT_MOD, [v12, tmp42], v23),
        ResOperation(rop.INT_IS_TRUE, [v6], v24),
        ResOperation(rop.UINT_RSHIFT, [v15, ConstInt(6)], v25),
        ResOperation(rop.INT_OR, [ConstInt(-4), v25], v26),
        ResOperation(rop.INT_INVERT, [v8], v27),
        ResOperation(rop.INT_SUB, [ConstInt(-113), v11], v28),
        ResOperation(rop.INT_NEG, [v7], v29),
        ResOperation(rop.INT_NEG, [v24], v30),
        ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(53)], v31),
        ResOperation(rop.INT_MUL, [v28, v27], v32),
        ResOperation(rop.INT_AND, [v18, ConstInt(-4)], tmp43),
        ResOperation(rop.INT_OR, [tmp43, ConstInt(1)], tmp44),
        ResOperation(rop.INT_MOD, [v26, tmp44], v33),
        ResOperation(rop.INT_OR, [v27, v19], v34),
        ResOperation(rop.UINT_LT, [v13, ConstInt(1)], v35),
        ResOperation(rop.INT_AND, [v21, ConstInt(31)], tmp45),
        ResOperation(rop.INT_RSHIFT, [v21, tmp45], v36),
        ResOperation(rop.INT_AND, [v20, ConstInt(31)], tmp46),
        ResOperation(rop.UINT_RSHIFT, [v4, tmp46], v37),
        ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38),
        ResOperation(rop.INT_NEG, [v7], v39),
        ResOperation(rop.INT_GT, [v24, v32], v40),
        ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()),
            ]
    cpu = CPU(None, None)
    looptoken = LoopToken()
    cpu.compile_loop(inputargs, operations, looptoken)
    cpu.set_future_value_int(0, -13)
    cpu.set_future_value_int(1, 10)
    cpu.set_future_value_int(2, 10)
    cpu.set_future_value_int(3, 8)
    cpu.set_future_value_int(4, -8)
    cpu.set_future_value_int(5, -16)
    cpu.set_future_value_int(6, -18)
    cpu.set_future_value_int(7, 46)
    cpu.set_future_value_int(8, -12)
    cpu.set_future_value_int(9, 26)
    cpu.execute_token(looptoken)
    assert cpu.get_latest_value_int(0) == 0
    assert cpu.get_latest_value_int(1) == 0
    assert cpu.get_latest_value_int(2) == 0
    assert cpu.get_latest_value_int(3) == 0
    assert cpu.get_latest_value_int(4) == 1
    assert cpu.get_latest_value_int(5) == -7
    assert cpu.get_latest_value_int(6) == 1
    assert cpu.get_latest_value_int(7) == 0
    assert cpu.get_latest_value_int(8) == -2
    assert cpu.get_latest_value_int(9) == 18
    assert cpu.get_latest_value_int(10) == 1
    assert cpu.get_latest_value_int(11) == 18
    assert cpu.get_latest_value_int(12) == -1
    assert cpu.get_latest_value_int(13) == 0