コード例 #1
0
ファイル: vm.py プロジェクト: malchev/cairo-lang
    def get_traceback_entries(self):
        """
        Returns the values of pc of the call instructions in the traceback.
        Returns the most recent call last.
        """
        entries = []
        fp = self.fp
        for _ in range(MAX_TRACEBACK_ENTRIES):
            # Get the previous fp and the return pc.
            fp, ret_pc = self.memory.get(fp - 2), self.memory.get(fp - 1)

            # If one of them is not in memory, abort.
            if fp is None or ret_pc is None:
                break

            # Get the two memory cells before ret_pc.
            instruction0, instruction1 = self.memory.get(ret_pc - 2), self.memory.get(ret_pc - 1)

            # Try to check if the call instruction is (instruction0, instruction1) or just
            # instruction1 (with no immediate).
            # In rare cases this may be ambiguous.
            if instruction1 is not None and is_call_instruction(
                    encoded_instruction=instruction1, imm=None):
                call_pc = ret_pc - 1
            elif instruction0 is not None and instruction1 is not None and is_call_instruction(
                    encoded_instruction=instruction0, imm=instruction1):
                call_pc = ret_pc - 2
            else:
                # If none of them seems like the calling instruction, abort.
                break

            entries.append(call_pc)

        return entries[::-1]
コード例 #2
0
def test_jmp():
    encoded = [0x0129800080027fff]
    instruction = Instruction(
        off0=-1,
        off1=2,
        off2=0,
        imm=None,
        dst_register=Register.FP,
        op0_register=Register.AP,
        op1_addr=Instruction.Op1Addr.FP,
        res=Instruction.Res.ADD,
        pc_update=Instruction.PcUpdate.JUMP_REL,
        ap_update=Instruction.ApUpdate.REGULAR,
        fp_update=Instruction.FpUpdate.REGULAR,
        opcode=Instruction.Opcode.NOP,
    )
    assert build_instruction(
        parse_instruction('jmp rel [ap + 2] + [fp]')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction

    # Change to jmp abs.
    instruction = dataclasses.replace(instruction,
                                      pc_update=Instruction.PcUpdate.JUMP)
    encoded = [0x00a9800080027fff]
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(encoded[0], None) is False
コード例 #3
0
def test_assert_eq():
    encoded = [0x480680017fff8000, 1]
    instruction = Instruction(
        off0=0,
        off1=-1,
        off2=1,
        imm=1,
        dst_register=Register.AP,
        op0_register=Register.FP,
        op1_addr=Instruction.Op1Addr.IMM,
        res=Instruction.Res.OP1,
        pc_update=Instruction.PcUpdate.REGULAR,
        ap_update=Instruction.ApUpdate.ADD1,
        fp_update=Instruction.FpUpdate.REGULAR,
        opcode=Instruction.Opcode.ASSERT_EQ,
    )
    assert build_instruction(
        parse_instruction('[ap] = 1; ap++')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction

    # Remove "ap++".
    instruction = dataclasses.replace(instruction,
                                      ap_update=Instruction.ApUpdate.REGULAR)
    encoded = [0x400680017fff8000, 1]
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(*encoded) is False
コード例 #4
0
def test_addap():
    encoded = [0x40780017fff7fff, 123]
    instruction = Instruction(off0=-1,
                              off1=-1,
                              off2=1,
                              imm=123,
                              dst_register=Register.FP,
                              op0_register=Register.FP,
                              op1_addr=Instruction.Op1Addr.IMM,
                              res=Instruction.Res.OP1,
                              pc_update=Instruction.PcUpdate.REGULAR,
                              ap_update=Instruction.ApUpdate.ADD,
                              fp_update=Instruction.FpUpdate.REGULAR,
                              opcode=Instruction.Opcode.NOP)
    assert build_instruction(parse_instruction('ap += 123')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(*encoded) is False
コード例 #5
0
def test_call():
    encoded = [0x1104800180018000, 1234]
    instruction = Instruction(
        off0=0,
        off1=1,
        off2=1,
        imm=1234,
        dst_register=Register.AP,
        op0_register=Register.AP,
        op1_addr=Instruction.Op1Addr.IMM,
        res=Instruction.Res.OP1,
        pc_update=Instruction.PcUpdate.JUMP_REL,
        ap_update=Instruction.ApUpdate.ADD2,
        fp_update=Instruction.FpUpdate.AP_PLUS2,
        opcode=Instruction.Opcode.CALL,
    )
    assert build_instruction(parse_instruction('call rel 1234')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(*encoded) is True
コード例 #6
0
def test_ret():
    encoded = [0x208b7fff7fff7ffe]
    instruction = Instruction(
        off0=-2,
        off1=-1,
        off2=-1,
        imm=None,
        dst_register=Register.FP,
        op0_register=Register.FP,
        op1_addr=Instruction.Op1Addr.FP,
        res=Instruction.Res.OP1,
        pc_update=Instruction.PcUpdate.JUMP,
        ap_update=Instruction.ApUpdate.REGULAR,
        fp_update=Instruction.FpUpdate.DST,
        opcode=Instruction.Opcode.RET,
    )
    assert build_instruction(parse_instruction('ret')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(encoded[0], None) is False
コード例 #7
0
def test_jnz():
    encoded = [0x020a7ff07fff8003]
    instruction = Instruction(
        off0=3,
        off1=-1,
        off2=-16,
        imm=None,
        dst_register=Register.AP,
        op0_register=Register.FP,
        op1_addr=Instruction.Op1Addr.FP,
        res=Instruction.Res.UNCONSTRAINED,
        pc_update=Instruction.PcUpdate.JNZ,
        ap_update=Instruction.ApUpdate.REGULAR,
        fp_update=Instruction.FpUpdate.REGULAR,
        opcode=Instruction.Opcode.NOP,
    )
    assert build_instruction(
        parse_instruction('jmp rel [fp - 16] if [ap + 3] != 0')) == instruction
    assert encode_instruction(instruction, prime=PRIME) == encoded
    assert decode_instruction(*encoded) == instruction
    assert is_call_instruction(encoded[0], None) is False