From: yu.dongliang <18588496441@163.com> Date: Sat, 27 Jun 2026 02:42:01 +0000 (+0800) Subject: js: support const function array with const index X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=abc.git js: support const function array with const index --- diff --git a/examples/js_array_func.html b/examples/js_array_func.html new file mode 100644 index 0000000..a255ccf --- /dev/null +++ b/examples/js_array_func.html @@ -0,0 +1,21 @@ + + + + +

含有javascript的页面

+ +

含有js的页面

+ + + + + diff --git a/js/abc_libjs.so b/js/abc_libjs.so index 41cb042..b48ed9e 100755 Binary files a/js/abc_libjs.so and b/js/abc_libjs.so differ diff --git a/js/core/scf_variable.c b/js/core/scf_variable.c index cc8935f..39ba592 100644 --- a/js/core/scf_variable.c +++ b/js/core/scf_variable.c @@ -379,10 +379,13 @@ int scf_variable_same_type(scf_variable_t* v0, scf_variable_t* v1) } if (SCF_FUNCTION_PTR == v0->type) { - assert(v0->func_ptr); - assert(v1->func_ptr); + if (!v0->func_ptr) + assert(v0->arg_flag); - if (!scf_function_same_type(v0->func_ptr, v1->func_ptr)) + else if (!v1->func_ptr) + assert(v1->arg_flag); + + else if (!scf_function_same_type(v0->func_ptr, v1->func_ptr)) return 0; } } else { diff --git a/js/core/scf_variable.h b/js/core/scf_variable.h index b6a57eb..1197f94 100644 --- a/js/core/scf_variable.h +++ b/js/core/scf_variable.h @@ -7,6 +7,8 @@ typedef struct { scf_expr_t* vla; // variable length array int num; // const length array + + scf_vector_t* vars; } scf_dimention_t; struct scf_variable_s { @@ -67,6 +69,9 @@ struct scf_variable_s { scf_string_t* signature; + scf_dimention_t* js_dimentions; // this var point to a js array + int js_nb_dimentions; + uint32_t const_literal_flag:1; uint32_t const_flag :1; uint32_t static_flag :1; diff --git a/js/doc.c b/js/doc.c index f8ea145..2f46d82 100644 --- a/js/doc.c +++ b/js/doc.c @@ -132,6 +132,12 @@ struct Object return 0; } + int __init(Object* this, const char* name, int length, const funcptr* f) + { + printf("this: %p, f: %p\n", this, f); + return 0; + } + int __init(Object* this, const char* name, int length, const char* s) { printf("this: %p, name: %s\n", this, name); diff --git a/js/parse/scf_dfa_call.c b/js/parse/scf_dfa_call.c index 47b0754..4779ac0 100644 --- a/js/parse/scf_dfa_call.c +++ b/js/parse/scf_dfa_call.c @@ -125,10 +125,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_logw("\n"); -// return SCF_DFA_ERROR; } node_call = scf_node_alloc(w1, SCF_OP_CALL, NULL); @@ -383,6 +379,74 @@ int _call_add_obj(scf_ast_t* ast, scf_lex_word_t* w, scf_node_t* call, scf_expr_ return 0; } +static int _call_get_func(scf_function_t** pf, scf_node_t* array, scf_vector_t* indexes) +{ + scf_variable_t* base = _scf_operand_get(array); + scf_variable_t* v; + int i; + int j; + + if (indexes) { + for (i = indexes->size - 1; i >= 0; i--) { + v = indexes->data[i]; + j = v->data.i64; + + if (!base->js_dimentions + || base->js_nb_dimentions <= 0 + || base->js_dimentions[0].num <= j) + return -EINVAL; + + if (!base->js_dimentions[0].vars || j >= base->js_dimentions[0].vars->size) + return -EINVAL; + + base = base->js_dimentions[0].vars->data[j]; + if (!base) + return -EINVAL; + } + } + + if (SCF_FUNCTION_PTR == base->type) { + + if (!base->const_literal_flag || !base->func_ptr) { + scf_loge("function obj '%s' is not const\n", base->w->text->data); + return -EINVAL; + } + + *pf = base->func_ptr; + } + + return 0; +} + +static int _call_use_func(scf_ast_t* ast, scf_node_t* call, scf_function_t* f) +{ + scf_variable_t* v; + scf_node_t* pf; + scf_expr_t* e; + scf_type_t* t = NULL; + + int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR); + if (ret < 0) + return ret; + + v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f); + if (!v) + return -ENOMEM; + v->const_literal_flag = 1; + + pf = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!pf) + return -ENOMEM; + + scf_node_free(call->nodes[0]); + call->nodes[0] = pf; + + pf->parent = call; + return 0; +} + static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { if (words->size < 2) { @@ -425,37 +489,84 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } - scf_variable_t* r; - scf_function_t* f = NULL; - scf_type_t* Object = NULL; - scf_node_t* pf = cd->call->nodes[0]; + scf_variable_t* base; + scf_variable_t* index; + scf_function_t* f; + scf_vector_t* indexes = NULL; + scf_type_t* Object = NULL; + scf_node_t* pf = cd->call->nodes[0]; scf_expr_t* e; + scf_type_t* t; - while (SCF_OP_EXPR == pf->type) - pf = pf->nodes[0]; + int ret; - if (SCF_OP_POINTER == pf->type) - pf = pf->nodes[1]; + while (1) { + if (SCF_OP_EXPR == pf->type) + pf = pf->nodes[0]; - int ret = scf_ast_find_type(&Object, ast, "Object"); + else if (SCF_OP_POINTER == pf->type) { + pf = pf->nodes[1]; + break; + + } else if (SCF_OP_ARRAY_INDEX == pf->type) { + index = NULL; + + ret = scf_expr_calculate(ast, pf->nodes[1], &index); + if (ret < 0) + goto error; + + if (!scf_variable_const_integer(index)) { + scf_loge("\n"); + + scf_variable_free(index); + ret = -EINVAL; + goto error; + } + + if (!indexes) { + indexes = scf_vector_alloc(); + + if (!indexes) { + scf_variable_free(index); + ret = -ENOMEM; + goto error; + } + } + + ret = scf_vector_add(indexes, index); + if (ret < 0) { + scf_variable_free(index); + goto error; + } + + pf = pf->nodes[0]; + } else + break; + } + + f = NULL; + ret = _call_get_func(&f, pf, indexes); if (ret < 0) - return ret; + goto error; + + ret = scf_ast_find_type(&Object, ast, "Object"); + if (ret < 0) + goto error; int js_flag = 1; int timer_flag = 0; - if (SCF_FUNCTION_PTR == pf->type) { - f = pf->var->func_ptr; - + if (f) { js_flag = f->js_flag; if (!strcmp(f->node.w->text->data, "setTimeout")) timer_flag = 1; - scf_logd("f: %s, f->js_flag: %d, timer_flag: %d\n", f->node.w->text->data, f->js_flag, timer_flag); + scf_logi("f: %s, f->js_flag: %d, timer_flag: %d\n", f->node.w->text->data, f->js_flag, timer_flag); } else assert(Object->node.type == pf->type); @@ -468,7 +579,7 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { ret = _call_add_obj(ast, w, cd->call, e, Object); if (ret < 0) - return ret; + goto error; } scf_node_add_child(cd->call, e); @@ -484,7 +595,7 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { ret = _call_add_obj(ast, w, cd->call, d->expr, Object); if (ret < 0) - return ret; + goto error; } scf_node_add_child(cd->call, d->expr); @@ -493,8 +604,10 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (js_flag || timer_flag) { e = scf_expr_alloc(); - if (!e) - return -ENOMEM; + if (!e) { + ret = -ENOMEM; + goto error; + } if (js_flag) ret = _call_add_arguments(ast, w, cd->call->nb_nodes - 1, e, Object); @@ -502,13 +615,13 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) ret = scf_ast_add_const_var(ast, e, SCF_VAR_INT, cd->call->nb_nodes - 3); if (ret < 0) { scf_expr_free(e); - return ret; + goto error; } ret = scf_node_add_child(cd->call, e); if (ret < 0) { scf_expr_free(e); - return ret; + goto error; } int i; @@ -519,6 +632,12 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) e = NULL; } + if (indexes) { + ret = _call_use_func(ast, cd->call, f); + if (ret < 0) + goto error; + } + if (cd->parent_expr) d->expr = cd->parent_expr; else @@ -526,10 +645,16 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) assert(--d->expr_local_flag >= 0); - free(cd); - cd = NULL; + ret = SCF_DFA_NEXT_WORD; - return SCF_DFA_NEXT_WORD; +error: + if (indexes) { + scf_vector_clear(indexes, ( void (*)(void*) ) scf_variable_free); + scf_vector_free (indexes); + } + + free(cd); + return ret; } static int _call_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) diff --git a/js/parse/scf_dfa_expr.c b/js/parse/scf_dfa_expr.c index 5b4d206..083c160 100644 --- a/js/parse/scf_dfa_expr.c +++ b/js/parse/scf_dfa_expr.c @@ -182,7 +182,8 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) d->current_function->vargs_flag = 1; } - scf_logi("var: %s, member_flag: %d, js_type: %d, line: %d, pos: %d\n", var->w->text->data, var->member_flag, var->js_type, var->w->line, var->w->pos); + scf_logi("var: %s: %p, var->dimentions: %p, nb_dimentions: %d, member_flag: %d, js_type: %d, line: %d, pos: %d\n", + var->w->text->data, var, var->dimentions, var->nb_dimentions, var->member_flag, var->js_type, var->w->line, var->w->pos); if (md->current_var && md->current_var->js_type >= 0 @@ -736,6 +737,8 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (scf_ast_find_type(&t, parse->ast, "Object") < 0) return SCF_DFA_ERROR; + scf_logi("-------- md->current_var: %s\n", md->current_var->w->text->data); + v = scf_scope_find_variable(t->scope, "members"); if (!v) { scf_logw("var 'members' not found in struct '%s'\n", t->name->data); @@ -1191,8 +1194,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); diff --git a/js/parse/scf_dfa_init_data.c b/js/parse/scf_dfa_init_data.c index 8d61fbe..5021949 100644 --- a/js/parse/scf_dfa_init_data.c +++ b/js/parse/scf_dfa_init_data.c @@ -39,8 +39,12 @@ static int _do_data_init(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* obj) init_module_data_t* md = d->module_datas[dfa_module_init_data.index]; dfa_init_expr_t* ie; int i; + int ret = 0; - int ret = scf_object_init(ast, md->assign, d->current_var, obj, md->init_exprs); + if (SCF_FUNCTION_PTR != obj->type) { + + ret = scf_object_init(ast, md->assign, d->current_var, obj, md->init_exprs); + } for (i = 0; i < md->init_exprs->size; i++) { ie = md->init_exprs->data[i]; @@ -50,6 +54,12 @@ static int _do_data_init(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* obj) ie = NULL; } + d->current_var->js_dimentions = obj->dimentions; + d->current_var->js_nb_dimentions = obj->nb_dimentions; + + obj->dimentions = NULL; + obj->nb_dimentions = 0; + md->assign = NULL; scf_vector_free(md->init_exprs); @@ -125,7 +135,10 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) scf_variable_free(r); return -ENOMEM; } - v->member_flag = 1; + + v->member_flag = 1; + v->const_flag = r->const_flag; + v->const_literal_flag = r->const_literal_flag; if (r->nb_dimentions > 0) { v->nb_dimentions = r->nb_dimentions; @@ -159,6 +172,7 @@ static int _add_array_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) init_module_data_t* md = d->module_datas[dfa_module_init_data.index]; scf_lex_word_t* w; scf_variable_t* obj = scf_stack_top(md->init_objs); + scf_variable_t* v; if (!r) { int ret = scf_expr_calculate(ast, d->expr, &r); @@ -180,6 +194,12 @@ static int _add_array_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) return -ENOMEM; } + obj->dimentions[0].vars = scf_vector_alloc(); + if (!obj->dimentions[0].vars) { + scf_variable_free(r); + return -ENOMEM; + } + obj->dimentions[0].num = 1; } else obj->dimentions[0].num++; @@ -191,11 +211,30 @@ static int _add_array_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) if (obj->dimentions[i + 1].num < r->dimentions[i].num) obj->dimentions[i + 1].num = r->dimentions[i].num; - scf_logi("obj: %p, obj->dimentions[%d].num: %d\n", obj, i + 1, obj->dimentions[i + 1].num); + scf_logi("obj: %p, obj->dimentions[%d].num: %d, r->dimentions[%d].num: %d\n", + obj, i + 1, obj->dimentions[i + 1].num, + i, r->dimentions[i].num); } + v = scf_variable_clone(r); + scf_variable_free(r); r = NULL; + if (!v) + return -ENOMEM; + + int ret = scf_vector_add(obj->dimentions[0].vars, v); + if (ret < 0) { + scf_variable_free(v); + return ret; + } + + if (v && SCF_FUNCTION_PTR == v->type && v->func_ptr) { + scf_function_t* f = v->func_ptr; + + scf_loge("%s()\n", f->node.w->text->data); + } + #if 0 if (d->current_var->nb_dimentions < md->current_n) { @@ -626,9 +665,11 @@ static int _data_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (md->init_objs->size <= 0) { d->expr_local_flag = 0; - scf_logi("----------- type: %d, nb_pointers: %d\n\n", d->current_var->type, d->current_var->nb_pointers); + if (obj->type >= SCF_STRUCT) + d->current_var->js_type = obj->type; - d->current_var->js_type = obj->type; + scf_logi("----------- type: %d, js_type: %d, SCF_FUNCTION_PTR: %d, nb_pointers: %d\n\n", + d->current_var->type, d->current_var->js_type, SCF_FUNCTION_PTR, d->current_var->nb_pointers); ret = _do_data_init(parse->ast, d, obj); if (ret < 0) diff --git a/js/parse/scf_operator_handler_expr.c b/js/parse/scf_operator_handler_expr.c index d5f6437..db0ef5a 100644 --- a/js/parse/scf_operator_handler_expr.c +++ b/js/parse/scf_operator_handler_expr.c @@ -706,24 +706,33 @@ scf_operator_handler_pt scf_find_expr_operator_handler(const int type) int scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, scf_variable_t** pret) { - if (!e || !e->nodes || e->nb_nodes <= 0) - return -1; + if (!e) + return -EINVAL; - if (scf_expr_semantic_analysis(ast, e) < 0) - return -1; + scf_handler_data_t d = {0}; + scf_variable_t* v; + + int ret = scf_expr_semantic_analysis(ast, e); + if (ret < 0) + return ret; - scf_handler_data_t d = {0}; - scf_variable_t* v; + scf_node_t* node = e; - if (!scf_type_is_var(e->nodes[0]->type)) { + if (SCF_OP_EXPR == e->type) { - if (_scf_expr_calculate_internal(ast, e->nodes[0], &d) < 0) { + if (!e->nodes || e->nb_nodes != 1) { scf_loge("\n"); - return -1; + return -EINVAL; } + + node = e->nodes[0]; } - v = _scf_operand_get(e->nodes[0]); + ret = _scf_expr_calculate_internal(ast, node, &d); + if (ret < 0) + return ret; + + v = _scf_operand_get(node); if (pret) *pret = scf_variable_ref(v); diff --git a/js/parse/scf_operator_handler_semantic.c b/js/parse/scf_operator_handler_semantic.c index 5742ece..a9d32a2 100644 --- a/js/parse/scf_operator_handler_semantic.c +++ b/js/parse/scf_operator_handler_semantic.c @@ -2873,7 +2873,7 @@ static int _semantic_multi_rets_assign(scf_ast_t* ast, scf_node_t** nodes, int n scf_variable_t* v1 = _scf_operand_get(call->result_nodes->data[i]); if (!scf_variable_same_type(v0, v1)) { - scf_loge("\n"); + scf_loge("i: %d\n", i); return -1; } @@ -3565,17 +3565,22 @@ int scf_expr_semantic_analysis(scf_ast_t* ast, scf_expr_t* e) { scf_handler_data_t d = {0}; - if (!e->nodes || e->nb_nodes != 1) { - scf_loge("\n"); - return -1; - } + scf_node_t* node = e; - int ret = _scf_expr_calculate_internal(ast, e->nodes[0], &d); - if (ret < 0) { - scf_loge("\n"); - return -1; + if (SCF_OP_EXPR == e->type) { + + if (!e->nodes || e->nb_nodes != 1) { + scf_loge("\n"); + return -EINVAL; + } + + node = e->nodes[0]; } + int ret = _scf_expr_calculate_internal(ast, node, &d); + if (ret < 0) + return ret; + return 0; } diff --git a/js/parse/scf_operator_handler_semantic.h b/js/parse/scf_operator_handler_semantic.h index 92ab2e8..25f1710 100644 --- a/js/parse/scf_operator_handler_semantic.h +++ b/js/parse/scf_operator_handler_semantic.h @@ -12,4 +12,3 @@ int scf_expr_semantic_analysis(scf_ast_t* ast, scf_expr_t* e); int scf_semantic_analysis(scf_ast_t* ast); #endif -