Exemple #1
0
def _build_flow_warp(state, addr, instruction):
    warp = nodes.UnconditionalWarp()
    warp.type = nodes.UnconditionalWarp.T_FLOW
    warp.target = state._warp_in_block(addr + 1)

    opcode = instruction.opcode
    shift = 1 if opcode in (ins.FORI.opcode, ins.UCLO.opcode) else 0

    return warp, shift
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
def _build_unconditional_warp(state, addr, instruction):
    warp = nodes.UnconditionalWarp()
    warp.type = nodes.UnconditionalWarp.T_JUMP

    opcode = instruction.opcode

    warp.is_uclo = opcode == ins.UCLO.opcode

    if warp.is_uclo and instruction.CD == 0:
        # Not a jump
        return _build_flow_warp(state, addr, instruction)
    else:
        destination = get_jump_destination(addr, instruction)
        warp.target = state._warp_in_block(destination)

    return warp, 1
Exemple #4
0
def _unwarp_loops(blocks, repeat_until):
	loops = _find_all_loops(blocks, repeat_until)

	if len(loops) == 0:
		return blocks

	fixed = _cleanup_breaks_and_if_ends(loops, blocks)

	for start, end in fixed:
		start_index = blocks.index(start)
		end_index = blocks.index(end)

		if repeat_until:
			body = blocks[start_index:end_index]
		else:
			body = blocks[start_index + 1:end_index]

		loop = _unwarp_loop(start, end, body)
		body = loop.statements.contents

		block = nodes.Block()
		block.first_address = body[0].first_address
		block.last_address = body[-1].last_address
		block.index = start.index + 1
		block.contents.append(loop)

		block.warp = nodes.UnconditionalWarp()
		block.warp.type = nodes.UnconditionalWarp.T_FLOW
		block.warp.target = end

		_replace_targets(blocks, body[0], block)

		_set_end(body[-1])
		_unwarp_breaks(start, body, end)

		blocks = blocks[:start_index + 1] + [block] + blocks[end_index:]

	return blocks
Exemple #5
0
def _set_flow_to(block, target):
	block.warp = nodes.UnconditionalWarp()
	block.warp.type = nodes.UnconditionalWarp.T_FLOW
	block.warp.target = target