예제 #1
0
static void print_graph_node(NODE *node)
{
    int i;
    GRAPH *graph = CAST_TO_GRAPH(node);
    
    printf("\n");
    
    for (i = 0; i < tree_num_children(node); i++)
    {
        HASH_ENTRY *he;
        
        printf("%d ->", i);
        he = find_in_hash(graph->forward, tree_get_child(node, i), sizeof(void *));
        if (he)
        {
            HASH *subhash = he->data;
            HASH_ITERATOR iter;
            for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
            {
                NODE *n = iter.entry->key;
                HASH_ENTRY *he2 = find_in_hash(graph->labels, n, sizeof(void *));
                if (he2)
                    printf(" %d", (int) he2->data);
            }
        }
        printf("\n");
        
        tree_print(tree_get_child(node, i), 2);
    }
}
예제 #2
0
파일: graph.c 프로젝트: doniexun/compiler-3
void replace_backward(GRAPH *graph, NODE *old, NODE *vertex, EDGE_TYPE type)
{
    HASH *subhash = get_from_hash(graph->backward, old, sizeof(void *));
    HASH_ITERATOR iter;
    for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
    {
        NODE *pred = iter.entry->key;
        EDGE_TYPE type2 = (EDGE_TYPE) iter.entry->data;
        remove_edge(graph, pred, old);
        if (vertex != NULL)
            add_edge(graph, pred, vertex, type | type2);
    }
}
예제 #3
0
static NODE *get_successor(GRAPH *graph, NODE *vertex, EDGE_TYPE type)
{
    HASH *subhash = get_from_hash(graph->forward, vertex, sizeof(void *));    
    HASH_ITERATOR iter;
    for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
    {
        NODE *succ = iter.entry->key;
        EDGE_TYPE succ_type = (EDGE_TYPE) iter.entry->data;
        if (succ_type & type)
            return succ;
    }
    
    return NULL;
}
예제 #4
0
파일: graph.c 프로젝트: doniexun/compiler-3
void inject_before(GRAPH *graph, NODE *vertex, NODE *before, EDGE_TYPE type)
{
    HASH *subhash = get_from_hash(graph->backward, before, sizeof(void *));
    HASH_ITERATOR iter;
    for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
    {
        NODE *pred = iter.entry->key;
        EDGE_TYPE type = (EDGE_TYPE) iter.entry->data;
        remove_edge(graph, pred, before);
        add_edge(graph, pred, vertex, type);
    }
    
    add_edge(graph, vertex, before, EDGE_NORMAL | type);
}
예제 #5
0
파일: list.c 프로젝트: comprateur/openvpn
void
hash_remove_by_value(struct hash *hash, void *value)
{
    struct hash_iterator hi;
    struct hash_element *he;

    hash_iterator_init(hash, &hi);
    while ((he = hash_iterator_next(&hi)))
    {
        if (he->value == value)
        {
            hash_iterator_delete_element(&hi);
        }
    }
    hash_iterator_free(&hi);
}
예제 #6
0
파일: pf.c 프로젝트: benjdag/openvpn
static void
pf_cn_set_print(const struct pf_cn_set *s, const int lev)
{
    if (s)
    {
        struct hash_iterator hi;
        struct hash_element *he;

        msg(lev, "  ----- struct pf_cn_set -----");
        msg(lev, "  default_allow=%s", drop_accept(s->default_allow));

        if (s->hash_table)
        {
            hash_iterator_init(s->hash_table, &hi);
            while ((he = hash_iterator_next(&hi)))
            {
                struct pf_cn *e = (struct pf_cn *)he->value;
                msg(lev, "   %s %s",
                    e->cn,
                    drop_accept(!e->exclude));
            }

            msg(lev, "  ----------");

            {
                struct pf_cn_elem *ce;
                for (ce = s->list; ce != NULL; ce = ce->next)
                {
                    struct pf_cn *e = lookup_cn_rule(s->hash_table, ce->rule.cn, cn_hash_function(ce->rule.cn, 0));
                    if (e)
                    {
                        msg(lev, "   %s %s",
                            e->cn,
                            drop_accept(!e->exclude));
                    }
                    else
                    {
                        msg(lev, "   %s LOOKUP FAILED", ce->rule.cn);
                    }
                }
            }
        }
    }
}
예제 #7
0
파일: list.c 프로젝트: comprateur/openvpn
static void
print_nhash(struct hash *hash)
{
    struct hash_iterator hi;
    struct hash_element *he;
    int count = 0;

    hash_iterator_init(hash, &hi, true);

    while ((he = hash_iterator_next(&hi)))
    {
        printf("%d ", (int) he->value);
        ++count;
    }
    printf("\n");

    hash_iterator_free(&hi);
    ASSERT(count == hash_n_elements(hash));
}
예제 #8
0
파일: graph.c 프로젝트: doniexun/compiler-3
static void edge_printer(NODE *from, NODE *to, void *data)
{
    if (data)
    {
        DFA *dfa = data;
        LIST *output = get_from_hash(dfa->outputs, to, sizeof(void *));
        DAA_SET *set = output->size ? output->items[0] : NULL;
        if (set)
        {
            printf("{");
            HASH_ITERATOR iter;
            for (hash_iterator(set->set, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
            {
                DECLARATION *decl = CAST_TO_DECLARATION(iter.entry->data);
                printf("<font color=\"%s\">%s</font>", get_colour(decl->colour), (char *) iter.entry->key);
                printf(",");
            }
            printf("}");
        }
    }
}
예제 #9
0
static EXPRESSION *simplify_expression(MODULE *module, FUNCTION *func, BLOCK *block, EXPRESSION *expr, STATEMENT *before)
{
    int i;
    
    int source_line = CAST_TO_AST(expr)->source_line;
    
    if (!has_graph(func) && is_short_circuit(expr))
    {
        TYPE *new_temp_type = CAST_TO_EXPRESSION(tree_get_child(expr, 0))->type;
        EXPRESSION *new_temp = make_new_temp(module, func, new_temp_type, source_line);
        STATEMENT *new_assign = make_assignment(new_temp, tree_get_child(expr, 0), source_line);
        tree_add_before(CAST_TO_NODE(block), CAST_TO_NODE(new_assign), CAST_TO_NODE(before));
        STATEMENT *new_assign2 = make_assignment(new_temp, tree_get_child(expr, 1), source_line);
        EXPRESSION *new_cond = new_temp;
        if (tree_is_type(expr, EXPR_OR))
            new_cond = make_unary_expression(EXPR_NOT, new_cond, source_line);
        STATEMENT *new_if = make_if(new_cond, make_block(NULL, new_assign2, 0), NULL, 0);
        tree_add_before(CAST_TO_NODE(block), CAST_TO_NODE(new_if), CAST_TO_NODE(before));
        return new_temp;
    }
    
    if (has_graph(func) && is_short_circuit(expr))
    {
        GRAPH *graph = func->graph;
        
        EXPRESSION *sub0 = tree_get_child(expr, 0);
        EXPRESSION *sub1 = tree_get_child(expr, 1);
        
        STATEMENT *new_test = make_test(sub0, source_line);
        
        EDGE_TYPE inner_type = tree_is_type(expr, EXPR_OR) ? EDGE_NO : EDGE_YES;
        EDGE_TYPE outer_type = tree_is_type(expr, EXPR_OR) ? EDGE_YES : EDGE_NO;
        
        add_vertex(graph, CAST_TO_NODE(new_test));
        HASH *subhash = get_from_hash(graph->forward, before, sizeof(void *));
        HASH_ITERATOR iter;
        for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
        {
            EDGE_TYPE type = (EDGE_TYPE) iter.entry->data;
            if (outer_type & type)
                add_edge(graph, CAST_TO_NODE(new_test), iter.entry->key, type);
            if (inner_type & type)
                inner_type = type;
        }
        inject_before(graph, CAST_TO_NODE(new_test), CAST_TO_NODE(before), inner_type);        
        
        return sub1;
    }
    
    if (is_simple(expr))
        return expr;
    
    if (tree_is_type(expr, EXPR_CALL))
    {
        EXPRESSION *args = CAST_TO_EXPRESSION(tree_get_child(expr, 1));
        args = atomise_expression(module, func, block, args, before);
        tree_get_child(expr, 1) = args;
        return expr;
    }
    
    for (i = 0; i < tree_num_children(expr); i++)
    {
        EXPRESSION *child = tree_get_child(expr, i);
        if (!is_atomic(child))
        {
            TYPE *new_temp_type = CAST_TO_EXPRESSION(child)->type;
            EXPRESSION *new_temp = make_new_temp(module, func, new_temp_type, CAST_TO_AST(child)->source_line);
            STATEMENT *new_assign = make_assignment(new_temp, child, CAST_TO_AST(child)->source_line);
            
            if (has_graph(func))
            {
                GRAPH *graph = func->graph;
                add_vertex(graph, CAST_TO_NODE(new_assign));
                inject_before(graph, CAST_TO_NODE(new_assign), CAST_TO_NODE(before), 0);
            }
            else
                tree_add_before(CAST_TO_NODE(block), CAST_TO_NODE(new_assign), CAST_TO_NODE(before));
            
            tree_get_child(expr, i) = new_temp;
        }
    }
    
    return expr;
}
예제 #10
0
파일: list.c 프로젝트: comprateur/openvpn
void
list_test(void)
{
    openvpn_thread_init();

    {
        struct gc_arena gc = gc_new();
        struct hash *hash = hash_init(10000, get_random(), word_hash_function, word_compare_function);
        struct hash *nhash = hash_init(256, get_random(), word_hash_function, word_compare_function);

        printf("hash_init n_buckets=%d mask=0x%08x\n", hash->n_buckets, hash->mask);

        /* parse words from stdin */
        while (true)
        {
            char buf[256];
            char wordbuf[256];
            int wbi;
            int bi;
            char c;

            if (!fgets(buf, sizeof(buf), stdin))
            {
                break;
            }

            bi = wbi = 0;
            do
            {
                c = buf[bi++];
                if (isalnum(c) || c == '_')
                {
                    ASSERT(wbi < (int) sizeof(wordbuf));
                    wordbuf[wbi++] = c;
                }
                else
                {
                    if (wbi)
                    {
                        struct word *w;
                        ASSERT(wbi < (int) sizeof(wordbuf));
                        wordbuf[wbi++] = '\0';

                        /* word is parsed from stdin */

                        /* does it already exist in table? */
                        w = (struct word *) hash_lookup(hash, wordbuf);

                        if (w)
                        {
                            /* yes, increment count */
                            ++w->n;
                        }
                        else
                        {
                            /* no, make a new object */
                            ALLOC_OBJ_GC(w, struct word, &gc);
                            w->word = string_alloc(wordbuf, &gc);
                            w->n = 1;
                            ASSERT(hash_add(hash, w->word, w, false));
                            ASSERT(hash_add(nhash, w->word, (void *) ((random() & 0x0F) + 1), false));
                        }
                    }
                    wbi = 0;
                }
            } while (c);
        }

#if 1
        /* remove some words from the table */
        {
            rmhash(hash, "true");
            rmhash(hash, "false");
        }
#endif

        /* output contents of hash table */
        {
            int base;
            int inc = 0;
            int count = 0;

            for (base = 0; base < hash_n_buckets(hash); base += inc)
            {
                struct hash_iterator hi;
                struct hash_element *he;
                inc = (get_random() % 3) + 1;
                hash_iterator_init_range(hash, &hi, true, base, base + inc);

                while ((he = hash_iterator_next(&hi)))
                {
                    struct word *w = (struct word *) he->value;
                    printf("%6d '%s'\n", w->n, w->word);
                    ++count;
                }

                hash_iterator_free(&hi);
            }
            ASSERT(count == hash_n_elements(hash));
        }

#if 1
        /* test hash_remove_by_value function */
        {
            int i;
            for (i = 1; i <= 16; ++i)
            {
                printf("[%d] ***********************************\n", i);
                print_nhash(nhash);
                hash_remove_by_value(nhash, (void *) i, true);
            }
            printf("FINAL **************************\n");
            print_nhash(nhash);
        }
#endif

        hash_free(hash);
        hash_free(nhash);
        gc_free(&gc);
    }

    openvpn_thread_cleanup();
}
예제 #11
0
int emit_function(FUNCTION *func, EMIT_FUNCTIONS *functions, void *data)
{
    GRAPH *graph = func->graph;
    
    QUEUE *queue = create_queue();
    HASH *done = create_hash(10, key_type_direct);
    
    queue_push(queue, tree_get_child(graph, 0));
    
    NODE *last = NULL;
    while (!queue_is_empty(queue))
    {
        NODE *vertex = queue_pop(queue);
        
        if (find_in_hash(done, vertex, sizeof(void *)))
            continue;
        
do_next:
        add_to_hash(done, vertex, sizeof(void *), (void *) 1);
        int label = (int) get_from_hash(graph->labels, vertex, sizeof(void *));
        HASH *predecessor_hash = get_from_hash(graph->backward, vertex, sizeof(void *));
        HASH_ITERATOR iter;
        hash_iterator(predecessor_hash, &iter);
        if (predecessor_hash && (predecessor_hash->num > 1 || (predecessor_hash->num == 1 && last != iter.entry->key)))
        {
            functions->emit_label(label, data);
        }
        functions->emit_comment(vertex, data);
        
        HASH *successor_hash = get_from_hash(graph->forward, vertex, sizeof(void *));
        NODE *successor;
        int successor_label;
        if (successor_hash)
        {
            hash_iterator(successor_hash, &iter);
            successor = iter.entry->key;
            successor_label = (int) get_from_hash(graph->labels, successor, sizeof(void *));
        }
        else
            successor = NULL;
        
        if (tree_is_type(vertex, STMT_ENTER))
        {
            functions->emit_enter(vertex, data);
        }
        else if (tree_is_type(vertex, STMT_EXIT))
        {
            functions->emit_exit(vertex, data);
            last = vertex;
            continue;
        }
        else if (tree_is_type(vertex, STMT_ASSIGN))
            functions->emit_assign(vertex, data);
        else if (tree_is_type(vertex, STMT_RETURN))
            functions->emit_return(vertex, data);
        else if (tree_is_type(vertex, STMT_TEST))
        {
            hash_iterator_next(&iter);
            NODE *branch = iter.entry->key;
            EDGE_TYPE branch_type = (EDGE_TYPE) iter.entry->data;
            int branch_label = (int) get_from_hash(graph->labels, branch, sizeof(void *));
            
            functions->emit_test(vertex, branch_type, branch_label, data);
            if (!find_in_hash(done, branch, sizeof(void *)))
                queue_push(queue, branch);
            
            /* Force label on next vertex, in case we jumped to it in the test's branch.
               Fixes a bug where the label is omitted just because the test was before it,
                by neglecting to notice that the test reaches it by a jump. */
            vertex = NULL;
        }
        last = vertex;
        if (find_in_hash(done, successor, sizeof(void *)))
        {
            functions->emit_jump(successor_label, data);
            continue;
        }
        vertex = successor;
        if (vertex)
            goto do_next;
    }
    
    functions->emit_end(data);
    
    destroy_queue(queue);
    destroy_hash(done);
    
    return 1;
}
예제 #12
0
파일: graph.c 프로젝트: doniexun/compiler-3
void print_graph(GRAPH *graph, char *name, void *data)
{
    int i;
    
    graph_sequence++;
    
    printf("subgraph cluster_%s_%d {\n", name, graph_sequence);
    printf("    label=\"%s\"; labelloc=\"t\";\n", name);
    printf("    ranksep=0.1\n");
    printf("    node [shape=\"box\", style=\"filled\"];\n");
    
    /* Vertices. */
    for (i = 0; i < tree_num_children(graph); i++)
    {
        NODE *vertex = tree_get_child(graph, i);
        if (vertex == NULL)
            continue;
        
        if (combine_bb && !tree_is_type(vertex, DEF_VARIABLE) && get_bb_next(graph, vertex, 2))
            continue;
        
        printf("    %s_%d_%d [label=<<table border=\"0\">\n", name, graph_sequence, i);
        printf("<tr><td>%d. ", i);
        vertex_printer(vertex, data);
        printf("</td></tr>\n");
        
        if (combine_bb && !tree_is_type(vertex, DEF_VARIABLE))
        {
            NODE *next_vertex = get_bb_next(graph, vertex, 1);
            while (next_vertex)
            {
                vertex = next_vertex;
                int pos = (int) get_from_hash(graph->labels, vertex, sizeof(void *));
                printf("<tr><td>%d. ", pos);
                vertex_printer(vertex, data);
                printf("</td></tr>\n");
                next_vertex = get_bb_next(graph, vertex, 1);
            }
        }
        
        printf("</table>>");
        if (tree_is_type(vertex, DEF_VARIABLE))
        {
            DECLARATION *decl = CAST_TO_DECLARATION(vertex);
            printf(", fillcolor=%s", get_colour(decl->colour));
        }
        printf("];\n");
        
        HASH_ENTRY *he;
        NODE *from = vertex;
        
        he = find_in_hash(graph->forward, from, sizeof(void *));
        if (he)
        {
            HASH *subhash = he->data;
            HASH_ITERATOR iter;
            for (hash_iterator(subhash, &iter); hash_iterator_valid(&iter); hash_iterator_next(&iter))
            {
                NODE *to = iter.entry->key;
                HASH_ENTRY *he2 = find_in_hash(graph->labels, to, sizeof(void *));
                if (he2)
                {
                    EDGE_TYPE type = (EDGE_TYPE) iter.entry->data;
                    if (type == EDGE_SYMMETRICAL)
                        continue;
                    printf("    %s_%d_%d -> %s_%d_%d [label=<", name, graph_sequence, i, name, graph_sequence, (int) he2->data);
                    if (type & EDGE_YES)
                        printf("Y");
                    if (type & EDGE_NO)
                        printf("N");
                    if (type & EDGE_BACK)
                        printf("B");
                    if (type & EDGE_LOOP)
                        printf("L");
                    edge_printer(from, to, data);
                    printf(">];\n");
                }
            }
        }
    }
    printf("}\n");
}