From: yu.dongliang <18588496441@163.com> Date: Sat, 23 Aug 2025 16:17:59 +0000 (+0800) Subject: js: use function object to call() X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=9922487be98d0eb8bc8606aeef9087492d4d2c64;p=abc.git js: use function object to call() --- diff --git a/examples/js.html b/examples/js.html index 5811a56..146d3e4 100644 --- a/examples/js.html +++ b/examples/js.html @@ -10,9 +10,9 @@ var a = function(x, y) { return x + y; - }(1, 2); + }; -document.write(a); +document.write(a(1, 2)); diff --git a/js/core/scf_type_cast.c b/js/core/scf_type_cast.c index 15e0c73..7f103d9 100644 --- a/js/core/scf_type_cast.c +++ b/js/core/scf_type_cast.c @@ -176,7 +176,7 @@ failed: dst_type = scf_variable_type_name(ast, dst); src_type = scf_variable_type_name(ast, src); - scf_loge("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n", + scf_logw("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n", src->w->text->data, dst->w->text->data, src_type->data, dst_type->data, src->w->file->data, src->w->line); diff --git a/js/doc.c b/js/doc.c index 0a437d6..1711088 100644 --- a/js/doc.c +++ b/js/doc.c @@ -20,6 +20,17 @@ struct Object return 0; } + int __init(Object* this, int64_t d) + { + this->d = d; + return 0; + } + + int __init(Object* this, void* p) + { + return 0; + } + int __init(Object* this, const char* name, int n_members) { printf("this: %p, name: %s\n", this, name); diff --git a/js/parse/scf_dfa.c b/js/parse/scf_dfa.c index 7d5045d..790cbfb 100644 --- a/js/parse/scf_dfa.c +++ b/js/parse/scf_dfa.c @@ -261,7 +261,7 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i scf_dfa_node_t* child = childs[i]; scf_lex_word_t* w = words->data[words->size - 1]; - scf_logi("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data); + scf_logd("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data); int pre_hook_flag = 0; diff --git a/js/parse/scf_dfa_call.c b/js/parse/scf_dfa_call.c index 714a1ef..18a26ad 100644 --- a/js/parse/scf_dfa_call.c +++ b/js/parse/scf_dfa_call.c @@ -40,6 +40,7 @@ static int _call_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; + scf_ast_t* ast = parse->ast; dfa_data_t* d = data; scf_lex_word_t* w1 = words->data[words->size - 1]; scf_stack_t* s = d->module_datas[dfa_module_call.index]; @@ -49,11 +50,12 @@ 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_type_t* Object = NULL; scf_node_t* node_call = NULL; scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_CALL); - if (scf_ast_find_type_type(&pt, parse->ast, SCF_FUNCTION_PTR) < 0) + if (scf_ast_find_type_type(&pt, ast, SCF_FUNCTION_PTR) < 0) return SCF_DFA_ERROR; assert(pt); @@ -62,8 +64,8 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa_identity_t* id = scf_stack_top(d->current_identities); if (id && id->identity) { - scf_logi("parse->ast->current_block: %p, js_type: %d\n", parse->ast->current_block, parse->ast->current_block->node.type); - int ret = scf_ast_find_function(&f, parse->ast, id->identity->text->data); + scf_logi("ast->current_block: %p, js_type: %d\n", ast->current_block, ast->current_block->node.type); + int ret = scf_ast_find_function(&f, ast, id->identity->text->data); if (ret < 0) return SCF_DFA_ERROR; @@ -84,7 +86,7 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_variable_free(var_pf); var_pf = NULL; } else { - ret = scf_ast_find_variable(&var_pf, parse->ast, id->identity->text->data); + ret = scf_ast_find_variable(&var_pf, ast, id->identity->text->data); if (ret < 0) return SCF_DFA_ERROR; @@ -93,25 +95,23 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } - if (SCF_FUNCTION_PTR != var_pf->type || !var_pf->func_ptr) { - scf_loge("invalid function ptr\n"); - return SCF_DFA_ERROR; - } - - f = var_pf->func_ptr; - - if (f->js_flag) { - scf_variable_t* v2 = scf_variable_clone(var_pf); - if (!v2) - return -ENOMEM; + if (SCF_FUNCTION_PTR == var_pf->type) { + if (!var_pf->func_ptr) { + scf_loge("invalid function ptr\n"); + return SCF_DFA_ERROR; + } + } else { + ret = scf_ast_find_type(&Object, ast, "Object"); + if (ret < 0) + return SCF_DFA_ERROR; - scf_loge("f: %s\n", f->node.w->text->data); - node_pf = scf_node_alloc(NULL, v2->type, v2); + if (Object->type != var_pf->type) { + scf_loge("invalid function ptr\n"); + return SCF_DFA_ERROR; + } + } - scf_variable_free(v2); - v2 = NULL; - } else - node_pf = scf_node_alloc(NULL, var_pf->type, var_pf); + node_pf = scf_node_alloc(NULL, var_pf->type, var_pf); } if (!node_pf) { @@ -289,8 +289,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_variable_t* r; scf_function_t* f; scf_expr_t* e; - scf_type_t* t = NULL; - scf_node_t* pf = cd->call->nodes[0]; + scf_type_t* Object = NULL; + scf_node_t* pf = cd->call->nodes[0]; while (SCF_OP_EXPR == pf->type) pf = pf->nodes[0]; @@ -298,23 +298,24 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (SCF_OP_POINTER == pf->type) pf = pf->nodes[1]; - assert(SCF_FUNCTION_PTR == pf->type); - - f = pf->var->func_ptr; - - int ret = scf_ast_find_type(&t, parse->ast, "Object"); + int ret = scf_ast_find_type(&Object, parse->ast, "Object"); if (ret < 0) return ret; - scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag); + if (SCF_FUNCTION_PTR == pf->type) { + f = pf->var->func_ptr; + + scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag); + } else + assert(Object->type == pf->type); if (cd->argv) { int i; for (i = 0; i < cd->argv->size; i++) { e = cd->argv->data[i]; - if (f->js_flag) { - ret = _call_add_obj(parse->ast, w, cd->call, e, t); + if (pf->type == Object->type) { + ret = _call_add_obj(parse->ast, w, cd->call, e, Object); if (ret < 0) return ret; } @@ -328,8 +329,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) // the last arg if (d->expr) { - if (f->js_flag) { - ret = _call_add_obj(parse->ast, w, cd->call, d->expr, t); + if (pf->type == Object->type) { + ret = _call_add_obj(parse->ast, w, cd->call, d->expr, Object); if (ret < 0) return ret; } diff --git a/js/parse/scf_dfa_expr.c b/js/parse/scf_dfa_expr.c index e05c1bf..7f8c3b4 100644 --- a/js/parse/scf_dfa_expr.c +++ b/js/parse/scf_dfa_expr.c @@ -190,7 +190,6 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) assert(md->current_struct); } md->current_var = var; - d->js_var = var; free(id); id = NULL; diff --git a/js/parse/scf_dfa_function_js.c b/js/parse/scf_dfa_function_js.c index 5cf7336..62590a3 100644 --- a/js/parse/scf_dfa_function_js.c +++ b/js/parse/scf_dfa_function_js.c @@ -7,7 +7,6 @@ extern scf_dfa_module_t dfa_module_function_js; typedef struct { scf_block_t* parent_block; scf_expr_t* parent_expr; - scf_variable_t* parent_var; } dfa_fun_data_t; @@ -148,8 +147,6 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat assert(!d->current_node); fd->parent_expr = d->expr; - fd->parent_var = d->js_var; - d->js_var = NULL; d->expr = NULL; if (_function_js_add_function(dfa, w, d) < 0) @@ -258,66 +255,15 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da if (f->node.nb_nodes > 0) f->node.define_flag = 1; - int call_flag = 0; - while (w = dfa->ops->pop_word(dfa)) { - w->next = h; - h = w; - - if (SCF_LEX_WORD_RP != w->type) { - if (SCF_LEX_WORD_LP == w->type) - call_flag = 1; - break; - } - } - - while (h) { - w = h; - h = h->next; - dfa->ops->push_word(dfa, w); - } - - if (call_flag) { - w = scf_lex_word_clone(f->node.w); - if (!w) - return -ENOMEM; - w->type = SCF_LEX_WORD_ID; - - dfa->ops->push_word(dfa, w); - - d->expr = fd->parent_expr; - fd->parent_expr = NULL; - - } else if (fd->parent_expr) { - if (!fd->parent_var) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - if (SCF_FUNCTION_PTR != fd->parent_var->type) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - fd->parent_var->func_ptr = f; - - if (fd->parent_var->member_flag) { - f->member_flag = 1; - - scf_list_del(&f->list); - scf_node_del_child((scf_node_t*)fd->parent_block, (scf_node_t*)f); - - t = fd->parent_var->parent_type; - - scf_scope_push_function(t->scope, f); - scf_node_add_child((scf_node_t*)t, (scf_node_t*)f); - } - - scf_expr_free(fd->parent_expr); - } + w = scf_lex_word_clone(f->node.w); + if (!w) + return -ENOMEM; + w->type = SCF_LEX_WORD_ID; + dfa->ops->push_word(dfa, w); + d->expr = fd->parent_expr; + fd->parent_expr = NULL; fd->parent_block = NULL; - fd->parent_expr = NULL; - fd->parent_var = NULL; if (d->current_function->member_flag) { @@ -328,9 +274,7 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da d->nb_lps = 0; d->nb_rps = 0; - if (call_flag) - return SCF_DFA_NEXT_WORD; - + return SCF_DFA_NEXT_WORD; return SCF_DFA_OK; } diff --git a/js/parse/scf_operator_handler_semantic.c b/js/parse/scf_operator_handler_semantic.c index 03317ce..c4ce9ad 100644 --- a/js/parse/scf_operator_handler_semantic.c +++ b/js/parse/scf_operator_handler_semantic.c @@ -1573,8 +1573,10 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node scf_variable_t* v1; scf_variable_t* v; scf_function_t* f; - scf_node_t* p; + scf_type_t* t; + scf_type_t* Object = NULL; scf_node_t* parent = nodes[0]->parent; + scf_node_t* p; scf_node_t* this; d->pret = &nodes[0]->result; @@ -1587,12 +1589,22 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node } v0 = _scf_operand_get(nodes[0]); - - if (SCF_FUNCTION_PTR != v0->type || !v0->func_ptr) { + if (!v0->func_ptr) { scf_loge("\n"); return -1; } + if (SCF_FUNCTION_PTR != v0->type) { + ret = scf_ast_find_type(&Object, ast, "Object"); + if (ret < 0) + return ret; + + if (v0->type != Object->type) { + scf_loge("\n"); + return -1; + } + } + f = v0->func_ptr; if (f->member_flag) { // add 'this' pointer for member function @@ -1601,38 +1613,18 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node while (p && SCF_OP_EXPR == p->type) p = p->nodes[0]; - switch (p->type) { - case SCF_OP_POINTER: - assert(2 == p->nb_nodes); - - this = p->nodes[0]; - break; - - case SCF_FUNCTION_PTR: - ret = scf_ast_find_variable(&v, ast, "document"); - if (ret < 0) - return ret; - - this = scf_node_alloc(NULL, v->type, v); - if (!this) - return -ENOMEM; + if (SCF_OP_POINTER == p->type) { + assert(2 == p->nb_nodes); - scf_logi("this: %p\n", this); - break; - default: - scf_loge("\n"); - return -1; - break; - }; + this = p->nodes[0]; - scf_node_add_child(parent, this); + scf_node_add_child(parent, this); - int i; - for (i = parent->nb_nodes - 2; i >= 1; i--) - parent->nodes[i + 1] = parent->nodes[i]; - parent->nodes[1] = this; + int i; + for (i = parent->nb_nodes - 2; i >= 1; i--) + parent->nodes[i + 1] = parent->nodes[i]; + parent->nodes[1] = this; - if (SCF_OP_POINTER == p->type) { for (i = 0; i < p->parent->nb_nodes; i++) { if (p->parent->nodes[i] == p) { p->parent->nodes[i] = p->nodes[1]; @@ -1646,24 +1638,60 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node scf_node_free(p); p = NULL; + } else { + ret = scf_ast_find_variable(&v, ast, "document"); + if (ret < 0) + return ret; + + if (nb_nodes < 2 || _scf_operand_get(nodes[1]) != v) { + + this = scf_node_alloc(NULL, v->type, v); + if (!this) + return -ENOMEM; + + scf_node_add_child(parent, this); + + int i; + for (i = parent->nb_nodes - 2; i >= 1; i--) + parent->nodes[i + 1] = parent->nodes[i]; + parent->nodes[1] = this; + + scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type); + } } - nb_nodes++; + if (f->js_flag) { + p = parent->nodes[0]; + while (p && SCF_OP_EXPR == p->type) + p = p->nodes[0]; + + t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR); + v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f); + if (!v) + return -ENOMEM; + v->const_literal_flag = 1; + + scf_node_free_data(p); + + p->type = SCF_FUNCTION_PTR; + p->var = v; + } } if (f->vargs_flag) { - if (f->argv->size > nb_nodes - 1) { + if (f->argv->size > parent->nb_nodes - 1) { scf_loge("number of args pass to '%s()' at least needs %d, real: %d, file: %s, line: %d\n", - f->node.w->text->data, f->argv->size, nb_nodes - 1, parent->w->file->data, parent->w->line); + f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line); return -1; } - } else if (f->argv->size != nb_nodes - 1) { + } else if (f->argv->size != parent->nb_nodes - 1) { scf_loge("number of args pass to '%s()' needs %d, real: %d, file: %s, line: %d\n", - f->node.w->text->data, f->argv->size, nb_nodes - 1, parent->w->file->data, parent->w->line); + f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line); + assert(0); return -1; } - scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, nb_nodes); + scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, parent->nb_nodes); int i; for (i = 0; i < f->argv->size; i++) { @@ -2880,6 +2908,9 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no return ret; assert(t); + if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type) + v0->func_ptr = v1->func_ptr; + if (scf_scope_find_function(t->scope, "__init")) { int ret = _semantic_do_create(ast, nodes, nb_nodes, d); diff --git a/js/parse/scf_parse.h b/js/parse/scf_parse.h index 5f78ea9..aa89b4c 100644 --- a/js/parse/scf_parse.h +++ b/js/parse/scf_parse.h @@ -74,8 +74,6 @@ struct dfa_data_s { scf_variable_t* current_var; scf_lex_word_t* current_var_w; - scf_variable_t* js_var; - int nb_sizeofs; int nb_containers;