Exemple #1
0
def _build_conditional_warp(state, last_addr, instructions):
    condition = instructions[-2]
    condition_addr = last_addr - 1

    warp = nodes.ConditionalWarp()

    if condition.opcode in (ins.ISTC.opcode, ins.ISFC.opcode):
        expression = _build_unary_expression(state, condition_addr, condition)

        setattr(warp, "_slot", condition.A)
    elif condition.opcode >= ins.IST.opcode:
        expression = _build_unary_expression(state, condition_addr, condition)

        setattr(warp, "_slot", condition.CD)
    else:
        expression = _build_comparison_expression(state, condition_addr,
                                                  condition)

    warp.condition = expression

    jump = instructions[-1]
    jump_addr = last_addr

    destination = get_jump_destination(jump_addr, jump)

    # A condition is inverted during the preparation phase above
    warp.false_target = state._warp_in_block(destination)
    warp.true_target = state._warp_in_block(jump_addr + 1)

    return warp, 2
Exemple #2
0
def _build_conditional_warp(state, last_addr, instructions):
    condition = instructions[-2]
    condition_addr = last_addr - 1

    warp = nodes.ConditionalWarp()

    if condition.opcode in (ins.ISTC.opcode, ins.ISFC.opcode):
        expression = _build_unary_expression(state, condition_addr, condition)

        setattr(warp, "_slot", condition.A)
    elif condition.opcode >= ins.IST.opcode:
        expression = _build_unary_expression(state, condition_addr, condition)

        setattr(warp, "_slot", condition.CD)
    else:
        expression = _build_comparison_expression(state, condition_addr,
                                                  condition)

    warp.condition = expression

    jump = instructions[-1]
    jump_addr = last_addr

    destination = get_jump_destination(jump_addr, jump)

    # A condition is inverted during the preparation phase above
    warp.false_target = state._warp_in_block(destination)
    warp.true_target = state._warp_in_block(jump_addr + 1)

    shift = 2
    if destination == (jump_addr + 1) \
            and condition.opcode not in (ins.ISTC.opcode, ins.ISFC.opcode):
        # This is an empty 'then' or 'else'. The simplest way to handle it is
        # to insert a Block containing just a no-op statement.
        block = nodes.Block()
        block.first_address = jump_addr + 1
        block.last_address = block.first_address
        block.index = warp.true_target.index
        block.warpins_count = 1
        setattr(block, "_last_body_addr", block.last_address - shift)

        block.warp = nodes.UnconditionalWarp()
        block.warp.type = nodes.UnconditionalWarp.T_FLOW
        block.warp.target = warp.true_target
        setattr(block.warp, "_addr", block.last_address - shift + 1)

        state.blocks.insert(state.blocks.index(warp.true_target), block)
        warp.true_target = block

        _create_no_op(state, jump_addr, block)

    return warp, shift