support function pointer array.
authoryu.dongliang <18588496441@163.com>
Wed, 17 Jun 2026 14:57:54 +0000 (22:57 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 17 Jun 2026 14:57:54 +0000 (22:57 +0800)
examples/array_func_ptr.c [new file with mode: 0644]
native/x64/scf_x64_reg.c
parse/scf_dfa_call.c
parse/scf_dfa_expr.c

diff --git a/examples/array_func_ptr.c b/examples/array_func_ptr.c
new file mode 100644 (file)
index 0000000..354a229
--- /dev/null
@@ -0,0 +1,22 @@
+
+int printf(const char* fmt, ...);
+
+int op_pt(int a, int b);
+
+int add(int a, int b)
+{
+       return a + b;
+}
+
+int sub(int a, int b)
+{
+       return a - b;
+}
+
+int main()
+{
+       op_pt* ops[] = {add, sub};
+
+       printf("ops[0](1, 2): %d\n", ops[0](1, 2));
+       return 0;
+}
index a94ef7c49ffa5991e0d22fa9358d6ed6d937519f..9374eed7964c8c140d0aeed09d40073eb5b9cadd 100644 (file)
@@ -699,6 +699,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf
        scf_instruction_t*  inst;
        scf_x64_OpCode_t*   lea;
        scf_x64_OpCode_t*   mov;
+       scf_x64_OpCode_t*   xor;
        scf_variable_t*     v;
 
        v = dn->var;
@@ -707,34 +708,9 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf
        int size     = x64_variable_size(v);
        int is_float = scf_variable_float(v);
 
-       if (SCF_FUNCTION_PTR == v->type) {
-
-               if (v->func_ptr) {
-                       assert(v->const_literal_flag);
-
-                       v->global_flag = 1;
-                       v->local_flag  = 0;
-                       v->tmp_flag    = 0;
-
-                       scf_rela_t* rela = NULL;
-
-                       lea  = x64_find_OpCode(SCF_X64_LEA,  size, size, SCF_X64_E2G);
-                       inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
-                       X64_INST_ADD_CHECK(c->instructions, inst, rela);
-                       X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
-
-               } else {
-                       scf_x64_OpCode_t* xor;
-
-                       xor  = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
-                       inst = x64_make_inst_G2E(xor, r, r);
-                       X64_INST_ADD_CHECK(c->instructions, inst, NULL);
-               }
-
-       } else if (scf_variable_const_string(v)) {
-
-               scf_rela_t* rela = NULL;
+       scf_rela_t* rela = NULL;
 
+       if (scf_variable_const_string(v)) {
                v->global_flag = 1;
                v->local_flag  = 0;
                v->tmp_flag    = 0;
@@ -748,14 +724,29 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf
        } else if (v->nb_dimentions > 0) {
                assert(v->const_literal_flag);
 
-               scf_rela_t* rela = NULL;
-
                lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
 
                inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
                X64_INST_ADD_CHECK(c->instructions, inst, rela);
                X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
 
+       } else if (SCF_FUNCTION_PTR == v->type) {
+               if (v->func_ptr) {
+                       assert(v->const_literal_flag);
+
+                       v->global_flag = 1;
+                       v->local_flag  = 0;
+                       v->tmp_flag    = 0;
+
+                       lea  = x64_find_OpCode(SCF_X64_LEA,  size, size, SCF_X64_E2G);
+                       inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+                       X64_INST_ADD_CHECK(c->instructions, inst, rela);
+                       X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
+               } else {
+                       xor  = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
+                       inst = x64_make_inst_G2E(xor, r, r);
+                       X64_INST_ADD_CHECK(c->instructions, inst, NULL);
+               }
        } else {
                mov  = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
                inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size);
index 71455bbce90bc88e6fb17eeffc893eb5bcdfd833..723fff021afdfa42ad8423643fbf72e1b118fb03 100644 (file)
@@ -49,7 +49,6 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_variable_t*   var_pf    = NULL;
        scf_node_t*       node_pf   = NULL;
        scf_type_t*       pt        = NULL;
-
        scf_node_t*       node_call = NULL;
        scf_operator_t*   op        = scf_find_base_operator_by_type(SCF_OP_CALL);
 
@@ -103,10 +102,6 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_stack_pop(d->current_identities);
                free(id);
                id = NULL;
-       } else {
-               // f()(), function f should return a function pointer
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
        }
 
        node_call = scf_node_alloc(w1, SCF_OP_CALL, NULL);
@@ -177,10 +172,13 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_logi("d->expr: %p\n", d->expr);
 
        if (cd->parent_expr) {
-               scf_expr_add_node(cd->parent_expr, cd->func);
+               if (cd->func)
+                       scf_expr_add_node(cd->parent_expr, cd->func);
+
                scf_expr_add_node(cd->parent_expr, cd->call);
        } else {
-               scf_node_add_child(cd->call, cd->func);
+               if (cd->func)
+                       scf_node_add_child(cd->call, cd->func);
        }
 
        if (cd->argv) {
@@ -224,8 +222,8 @@ static int _call_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_data_t*       d     = data;
        scf_lex_word_t*   w     = words->data[words->size - 1];
        scf_stack_t*      s     = d->module_datas[dfa_module_call.index];
-
        dfa_call_data_t*  cd    = scf_stack_top(s);
+
        if (!cd) {
                scf_loge("\n");
                return SCF_DFA_ERROR;
index fde6bdf0ac2f16ae4b15b0e1060175a494e48992..8b7c8af754c3a123e7fc8472a827df1caaa64552 100644 (file)
@@ -986,8 +986,9 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        scf_dfa_node_add_child(expr,       rs);
        scf_dfa_node_add_child(ls,         rs);
        scf_dfa_node_add_child(rs,         ls);
-       scf_dfa_node_add_child(rs,         binary_op);
+       scf_dfa_node_add_child(rs,         call_lp);
 
+       scf_dfa_node_add_child(rs,         binary_op);
        scf_dfa_node_add_child(rs,         unary_post);
        scf_dfa_node_add_child(rs,         rp);
        scf_dfa_node_add_child(identity,   unary_post);