From: yu.dongliang <18588496441@163.com> Date: Wed, 17 Jun 2026 14:57:54 +0000 (+0800) Subject: support function pointer array. X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=b0911649635f66f09dd4084005521662daeac297;p=scf.git support function pointer array. --- diff --git a/examples/array_func_ptr.c b/examples/array_func_ptr.c new file mode 100644 index 0000000..354a229 --- /dev/null +++ b/examples/array_func_ptr.c @@ -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; +} diff --git a/native/x64/scf_x64_reg.c b/native/x64/scf_x64_reg.c index a94ef7c..9374eed 100644 --- a/native/x64/scf_x64_reg.c +++ b/native/x64/scf_x64_reg.c @@ -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); diff --git a/parse/scf_dfa_call.c b/parse/scf_dfa_call.c index 71455bb..723fff0 100644 --- a/parse/scf_dfa_call.c +++ b/parse/scf_dfa_call.c @@ -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; diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index fde6bdf..8b7c8af 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -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);