optimize switch-case for "const literal string"
authoryu.dongliang <18588496441@163.com>
Wed, 2 Oct 2024 09:07:57 +0000 (17:07 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 2 Oct 2024 09:08:08 +0000 (17:08 +0800)
core/scf_3ac.c
core/scf_expr.c
core/scf_node.c
core/scf_operator_handler_3ac.c
examples/switch_string.c
parse/scf_operator_handler_semantic.c

index 3a13affadd107e55a859f46cb7ffe7ba64a07e6d..4fbaf37dc4f063bcdafe8f596ec7f2c6b7a720d4 100644 (file)
@@ -437,7 +437,6 @@ scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err)
        }
 
        if (scf_vector_add(c->dsts, dst) < 0) {
-
                scf_3ac_operand_free(dst);
                scf_3ac_code_free(c);
                return NULL;
index b2377c32e266c75f9fef430537a8a48651664ed8..35c8eb1ec58be474e78febacec6e427379661ff2 100644 (file)
@@ -19,8 +19,8 @@ scf_expr_t* scf_expr_alloc()
 int scf_expr_copy(scf_node_t* e2, scf_node_t* e)
 {
        scf_node_t* node;
-
        int i;
+
        for (i = 0; i < e->nb_nodes; i++) {
 
                node = scf_node_clone(e->nodes[i]);
index 03de08deec8eeec53275f05cd99f8b5d674d7364..89d68ad11d18027c388a8aed617bfd8f2c34840e 100644 (file)
@@ -66,52 +66,47 @@ _failed:
 
 scf_node_t* scf_node_clone(scf_node_t* node)
 {
-       scf_node_t* node2 = calloc(1, sizeof(scf_node_t));
-       if (!node2)
+       scf_node_t* dst = calloc(1, sizeof(scf_node_t));
+       if (!dst)
                return NULL;
 
        if (scf_type_is_var(node->type)) {
 
-               node2->var = scf_variable_ref(node->var);
-               if (!node2->var)
-                       goto _failed;
-
-       } else if (SCF_LABEL == node->type) {
-               node2->label = node->label;
+               dst->var = scf_variable_ref(node->var);
+               if (!dst->var)
+                       goto failed;
 
-       } else {
+       } else if (SCF_LABEL == node->type)
+               dst->label = node->label;
+       else {
                if (node->w) {
-                       node2->w = scf_lex_word_clone(node->w);
-                       if (!node2->w)
-                               goto _failed;
-
-               } else
-                       node2->w = NULL;
+                       dst->w = scf_lex_word_clone(node->w);
+                       if (!dst->w)
+                               goto failed;
+               }
        }
 
        if (node->debug_w) {
-               node2->debug_w = scf_lex_word_clone(node->debug_w);
+               dst ->debug_w = scf_lex_word_clone(node->debug_w);
 
-               if (!node2->debug_w)
-                       goto _failed;
+               if (!dst->debug_w)
+                       goto failed;
        }
 
-       node2->type        = node->type;
+       dst->type        = node->type;
 
-       node2->root_flag   = node->root_flag;
-       node2->file_flag   = node->file_flag;
-       node2->class_flag  = node->class_flag;
-       node2->union_flag  = node->union_flag;
-       node2->define_flag = node->define_flag;
-       node2->const_flag  = node->const_flag;
-       node2->split_flag  = node->split_flag;
-       node2->semi_flag   = node->semi_flag;
-
-       scf_logd("node: %p, node->type: %d\n", node, node->type);
-       return node;
+       dst->root_flag   = node->root_flag;
+       dst->file_flag   = node->file_flag;
+       dst->class_flag  = node->class_flag;
+       dst->union_flag  = node->union_flag;
+       dst->define_flag = node->define_flag;
+       dst->const_flag  = node->const_flag;
+       dst->split_flag  = node->split_flag;
+       dst->semi_flag   = node->semi_flag;
+       return dst;
 
-_failed:
-       scf_node_free(node);
+failed:
+       scf_node_free(dst);
        return NULL;
 }
 
index e5c389772838c7adcc844380ff035f609dc631be..6aa7db5b0bb376e6e0174450c64a939b4ab5bdc7 100644 (file)
@@ -1135,22 +1135,26 @@ static int _scf_op_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
                                while (e2 && SCF_OP_EXPR == e2->type)
                                        e2 = e2->nodes[0];
 
+                               if (SCF_OP_CALL == e2->type) {
+                                       assert(3    == e2->nb_nodes);
+                                       e2->nodes[1]->_3ac_done = 1;
+                               }
+
                                if (_scf_expr_calculate_internal(ast, e2, d) < 0) {
                                        scf_loge("\n");
                                        return -1;
                                }
 
-                               if (SCF_OP_CALL == e2->type)
-                                       cmp = scf_3ac_code_NN(SCF_OP_3AC_TEQ, NULL, 0, &e2, 1);
-                               else {
-                                       scf_node_t* srcs[2] = {e, e2};
+                               scf_node_t* srcs[2] = {e, e2};
 
+                               if (SCF_OP_CALL != e2->type)
                                        cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
-                               }
-                               scf_list_add_tail(d->_3ac_list_head, &cmp->list);
+                               else
+                                       cmp = scf_3ac_code_NN(SCF_OP_3AC_TEQ, NULL, 0, &e2, 1);
 
                                jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
 
+                               scf_list_add_tail(d->_3ac_list_head, &cmp->list);
                                scf_list_add_tail(d->_3ac_list_head, &jnot->list);
 
                                scf_vector_add(up_branch_ops->_breaks, jnot);
index 7c5844a06f8b722e032c9bec4cf970a1c9f0c4c7..343b05cf4a1537f3d9f71de3ca9de585e88c127c 100644 (file)
@@ -3,9 +3,10 @@ int strcmp(const char* s1, const char* s2);
 
 int main()
 {
-       const char* s = "123";
+       char* argv[2] = {"hello", "123"};
+
+       switch (argv[1]) {
 
-       switch (s) {
                case "456":
                        printf("0\n");
                case "123":
index f37493c9ca231ce1c1dd90409dfb7cd0bb4d2ac8..87eb380c9017743a6fc7ca552b9e366d50b7ff99 100644 (file)
@@ -1287,6 +1287,7 @@ static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
 static int __switch_for_string(scf_ast_t* ast, scf_node_t* parent, scf_node_t* child, scf_expr_t* e, scf_expr_t* e1, scf_handler_data_t* d)
 {
        scf_function_t* f = NULL;
+       scf_variable_t* v = NULL;
        scf_expr_t*     e2;
        scf_expr_t*     e3;
        scf_expr_t*     e4;
@@ -1305,6 +1306,13 @@ static int __switch_for_string(scf_ast_t* ast, scf_node_t* parent, scf_node_t* c
        if (!e1)
                return -ENOMEM;
 
+       if (_scf_expr_calculate(ast, e2, &v) < 0) {
+               scf_expr_free(e2);
+               return -1;
+       }
+       scf_variable_free(v);
+       v = NULL;
+
        e3 = scf_expr_alloc();
        if (!e3) {
                scf_expr_free(e2);