예제 #1
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
예제 #2
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
예제 #3
0
def assemble(preprocessed_program: PreprocessedProgram,
             main_scope: ScopedName = ScopedName(),
             add_debug_info: bool = False,
             file_contents_for_debug_info: Dict[str, str] = {}) -> Program:
    data: List[int] = []
    hints: Dict[int, List[CairoHint]] = {}
    debug_info = DebugInfo(instruction_locations={}, file_contents=file_contents_for_debug_info) \
        if add_debug_info else None

    for inst in preprocessed_program.instructions:
        for hint, hint_flow_tracking_data in inst.hints:
            hints.setdefault(len(data), []).append(
                CairoHint(code=hint.hint_code,
                          accessible_scopes=inst.accessible_scopes,
                          flow_tracking_data=hint_flow_tracking_data))
        if debug_info is not None and inst.instruction.location is not None:
            hint_locations: List[Optional[HintLocation]] = []
            for hint, _ in inst.hints:
                if hint.location is None:
                    hint_locations.append(None)
                else:
                    hint_locations.append(
                        HintLocation(
                            location=hint.location,
                            n_prefix_newlines=hint.hint.n_prefix_newlines,
                        ))
            debug_info.instruction_locations[len(data)] = \
                InstructionLocation(
                    inst=inst.instruction.location,
                    hints=hint_locations,
                    accessible_scopes=inst.accessible_scopes,
                    flow_tracking_data=inst.flow_tracking_data)
        data += [
            word
            for word in encode_instruction(build_instruction(inst.instruction),
                                           prime=preprocessed_program.prime)
        ]

    if debug_info is not None:
        debug_info.add_autogen_file_contents()

    return Program(prime=preprocessed_program.prime,
                   data=data,
                   hints=hints,
                   main_scope=main_scope,
                   identifiers=preprocessed_program.identifiers,
                   builtins=preprocessed_program.builtins,
                   reference_manager=preprocessed_program.reference_manager,
                   debug_info=debug_info)
예제 #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 assemble(preprocessed_program: PreprocessedProgram,
             main_scope: ScopedName = ScopedName(),
             add_debug_info: bool = False,
             file_contents_for_debug_info: Dict[str, str] = {}) -> Program:
    data: List[int] = []
    hints: Dict[int, CairoHint] = {}
    debug_info = DebugInfo(instruction_locations={}, file_contents=file_contents_for_debug_info) \
        if add_debug_info else None

    for inst in preprocessed_program.instructions:
        if inst.hint:
            hints[len(data)] = CairoHint(
                code=inst.hint.hint_code,
                accessible_scopes=inst.accessible_scopes,
                flow_tracking_data=inst.flow_tracking_data)
        if debug_info is not None and inst.instruction.location is not None:
            hint_location = None
            if inst.hint is not None and inst.hint.location is not None:
                hint_location = HintLocation(
                    location=inst.hint.location,
                    n_prefix_newlines=inst.hint.n_prefix_newlines,
                )
            debug_info.instruction_locations[len(data)] = \
                InstructionLocation(
                    inst=inst.instruction.location,
                    hint=hint_location,
                    accessible_scopes=inst.accessible_scopes,
                    flow_tracking_data=inst.flow_tracking_data)
        data += [
            word
            for word in encode_instruction(build_instruction(inst.instruction),
                                           prime=preprocessed_program.prime)
        ]

    return Program(prime=preprocessed_program.prime,
                   data=data,
                   hints=hints,
                   main_scope=main_scope,
                   identifiers=preprocessed_program.identifiers,
                   builtins=preprocessed_program.builtins,
                   reference_manager=preprocessed_program.reference_manager,
                   debug_info=debug_info)
예제 #6
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
예제 #7
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
예제 #8
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