Exemplo n.º 1
0
Block* find_block_that_exit_point_will_reach(Term* term)
{
    ca_assert(is_exit_point(term));

    Block* block = term->owningBlock;

    // 'return' exits to nearest major block.
    if (term->function == FUNCS.return_func) {
        while (is_minor_block(block)) {
            Block* parent = get_parent_block(block);
            if (parent == NULL)
                return block;

            block = parent;
        }
        return block;
    }

    // 'case_condition_bool' exits the current if-block.
    if (term->function == FUNCS.case_condition_bool)
        return get_parent_block(term->owningBlock);

    // Otherwise, exit to nearest for-loop.
    while (!is_for_loop(block) && !is_while_loop(block)) {
        Block* parent = get_parent_block(block);
        if (parent == NULL)
            return block;

        block = parent;
    }
    return block;
}
Exemplo n.º 2
0
void MinorBlockIterator::advance()
{
    Block* nextNested = current()->nestedContents;
    if (nextNested != NULL && !is_minor_block(nextNested))
        it.advanceSkippingBlock();
    else
        it.advance();
}
Exemplo n.º 3
0
void create_output_from_minor_block(Block* block, Value* description)
{
    if (is_case_block(block)) {
        Block* ifBlock = get_parent_block(block);
        if_block_append_output(ifBlock, description);
    } else if (is_minor_block(block)) {
        append_output_placeholder_with_description(block, description);
    }
}
Exemplo n.º 4
0
Block* static_dispatch_block(Term* term)
{
    if (term->nestedContents != NULL && is_minor_block(term->nestedContents))
        return term->nestedContents;

    if (term->function == NULL || !is_function(term->function))
        return NULL;

    ca_assert(term->function->nestedContents != NULL);
    return term->function->nestedContents;
}
Exemplo n.º 5
0
void block_update_pack_state_calls(Block* block)
{
    if (block->stateType == NULL) {
        // No state type, make sure there's no pack_state call.
        // TODO: Handle this case properly (should search and destroy an existing pack_state call)
        return;
    }

    int stateOutputIndex = block->length() - 1 - find_state_output(block)->index;

    for (int i=0; i < block->length(); i++) {
        Term* term = block->get(i);
        if (term == NULL)
            continue;

        if (term->function == FUNCS.pack_state) {
            // Update the inputs for this pack_state call
            TermList inputs;
            list_inputs_to_pack_state(block, i, &inputs);
            set_inputs(term, inputs);
        }

        else if (should_have_preceeding_pack_state(term)) {
            // Check if we need to insert a pack_state call
            Term* existing = term->input(stateOutputIndex);

            if (existing == NULL || existing->function != FUNCS.pack_state) {
                TermList inputs;
                list_inputs_to_pack_state(block, i, &inputs);
                if (inputs.length() != 0) {
                    Term* pack_state = apply(block, FUNCS.pack_state, inputs);
                    move_before(pack_state, term);

                    // Only set as an input for a non-minor block.
                    if (term->nestedContents == NULL || !is_minor_block(term->nestedContents)) {
                        set_input(term, stateOutputIndex, pack_state);
                        set_input_hidden(term, stateOutputIndex, true);
                        set_input_implicit(term, stateOutputIndex, true);
                    }

                    // Advance i to compensate for the term just added
                    i++;
                }
            }
        }
    }
}
Exemplo n.º 6
0
void controlFlow_postCompile(Term* term)
{
    // Mark the owning block, and all parent minor blocks, as hasControlFlow.
    Block* block = term->owningBlock;

    while (true) {
        set_bool(block_insert_property(block, s_HasControlFlow), true);

        if (!is_minor_block(block))
            break;

        block = get_parent_block(block);

        if (block == NULL)
            break;
    }
}
Exemplo n.º 7
0
void update_for_control_flow(Block* block)
{
    if (!block_get_bool_prop(block, s_HasControlFlow, false))
        return;

    for (int i=0; i < block->length(); i++) {
        Term* term = block->get(i);
        if (term == NULL)
            continue;

        if (is_exit_point_that_handles_rebinding(term))
            update_derived_inputs_for_exit_point(term);

        Block* nestedBlock = term->nestedContents;
        if (nestedBlock != NULL && is_minor_block(nestedBlock))
            update_for_control_flow(nestedBlock);
    }
}