From cb546ccdc63d3db032bc6d2b289161ade943d643 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 16 Nov 2025 12:35:41 +0800 Subject: [PATCH] 1, js : support 'for() loop' with array[] & ++, --, 2, scf: support ++, -- for float & double in native/x64. --- examples/js.html | 6 +- html/Makefile | 1 + html/abc_html.c | 7 +- js/core/scf_dag.c | 34 ++-- js/core/scf_optimizer.c | 15 +- js/core/scf_optimizer_js_array.c | 73 +++++--- js/core/scf_optimizer_js_array2.c | 265 ++++++++++++++++++++++++++++ js/core/scf_optimizer_js_unary_op.c | 205 ++++++++++++++------- js/doc.c | 42 +++++ js/native/x64/scf_x64_inst.c | 68 ++++++- js/parse/scf_dfa_for.c | 90 ++++++---- ui/Makefile | 1 + 12 files changed, 642 insertions(+), 165 deletions(-) create mode 100644 js/core/scf_optimizer_js_array2.c diff --git a/examples/js.html b/examples/js.html index 7419820..c6906ac 100644 --- a/examples/js.html +++ b/examples/js.html @@ -8,10 +8,10 @@ diff --git a/html/Makefile b/html/Makefile index bfdac51..67b5bad 100644 --- a/html/Makefile +++ b/html/Makefile @@ -108,6 +108,7 @@ CFILES += ../js/core/scf_optimizer_dag.c CFILES += ../js/core/scf_optimizer_inline.c CFILES += ../js/core/scf_optimizer_js_array.c +CFILES += ../js/core/scf_optimizer_js_array2.c CFILES += ../js/core/scf_optimizer_js_teq.c CFILES += ../js/core/scf_optimizer_js_unary_op.c CFILES += ../js/core/scf_optimizer_js_call.c diff --git a/html/abc_html.c b/html/abc_html.c index a7d1f1f..a9b0fe0 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -1008,13 +1008,13 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) scf_loge("\n"); return ret; } -#if 1 + ret = scf_parse_link(obj->js_so->data, obj->js_obj->data, "../js/abc_libjs.so", "x64", 1); if (ret < 0) { scf_loge("\n"); return ret; } - +#if 1 assert(!html->tmp_list_js); void* so = dlopen(obj->js_so->data, RTLD_LAZY); @@ -1023,7 +1023,7 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) f(html); dlclose(so); so = NULL; - +#endif abc_char_t* c; while ( html->tmp_list_js) { c = html->tmp_list_js; @@ -1033,7 +1033,6 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) c->next = html->tmp_list; html->tmp_list = c; } -#endif } return 0; diff --git a/js/core/scf_dag.c b/js/core/scf_dag.c index 54a58cb..422c74c 100644 --- a/js/core/scf_dag.c +++ b/js/core/scf_dag.c @@ -575,17 +575,25 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node) || SCF_OP_INC_POST == node->type || SCF_OP_DEC_POST == node->type || SCF_OP_ADDRESS_OF == node->type) { - if (dn->var == _scf_operand_get((scf_node_t*)node)) + if (dn->var == _scf_operand_get(node)) return 1; + return 0; } if (!dn->childs) { - if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) { - int ret = __dn_same_call(dn, node, split); - scf_logd("ret: %d\n", ret); - return ret; - } + switch (node->type) { + case SCF_OP_CALL: + //if (1 == node->nb_nodes) + return __dn_same_call(dn, node, split); + break; + + case SCF_OP_POINTER: + return dn->var == _scf_operand_get(node); + break; + default: + break; + }; return 0; } @@ -640,11 +648,8 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node) } if (dn->childs->size != node->nb_nodes) { - if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) { - int ret = __dn_same_call(dn, node, split); - scf_logd("ret: %d\n", ret); - return ret; - } + if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) + return __dn_same_call(dn, node, split); return 0; } @@ -693,11 +698,8 @@ cmp_childs: } } - if (SCF_OP_CALL == dn->type) { - int ret = __dn_same_call(dn, node, split); - scf_logd("ret: %d\n", ret); - return ret; - } + if (SCF_OP_CALL == dn->type) + return __dn_same_call(dn, node, split); return 1; } diff --git a/js/core/scf_optimizer.c b/js/core/scf_optimizer.c index bf646c4..0ffc5e2 100644 --- a/js/core/scf_optimizer.c +++ b/js/core/scf_optimizer.c @@ -1,9 +1,9 @@ #include"scf_optimizer.h" extern scf_optimizer_t scf_optimizer_inline; +extern scf_optimizer_t scf_optimizer_js_unary_op; extern scf_optimizer_t scf_optimizer_js_array; extern scf_optimizer_t scf_optimizer_js_teq; -extern scf_optimizer_t scf_optimizer_js_unary_op; extern scf_optimizer_t scf_optimizer_js_call; extern scf_optimizer_t scf_optimizer_split_call; @@ -19,15 +19,18 @@ extern scf_optimizer_t scf_optimizer_active_vars; extern scf_optimizer_t scf_optimizer_pointer_aliases; extern scf_optimizer_t scf_optimizer_loads_saves; +extern scf_optimizer_t scf_optimizer_basic_block; +extern scf_optimizer_t scf_optimizer_const_teq; + +extern scf_optimizer_t scf_optimizer_js_unary_post; + extern scf_optimizer_t scf_optimizer_dominators; extern scf_optimizer_t scf_optimizer_dominators_reverse; extern scf_optimizer_t scf_optimizer_auto_gc_find; extern scf_optimizer_t scf_optimizer_auto_gc; -extern scf_optimizer_t scf_optimizer_basic_block; - -extern scf_optimizer_t scf_optimizer_const_teq; +extern scf_optimizer_t scf_optimizer_js_array2; extern scf_optimizer_t scf_optimizer_loop; extern scf_optimizer_t scf_optimizer_vla; @@ -37,9 +40,9 @@ extern scf_optimizer_t scf_optimizer_generate_loads_saves; static scf_optimizer_t* scf_optimizers[] = { &scf_optimizer_inline, // global optimizer + &scf_optimizer_js_unary_op, &scf_optimizer_js_array, &scf_optimizer_js_teq, - &scf_optimizer_js_unary_op, &scf_optimizer_js_call, &scf_optimizer_split_call, @@ -62,6 +65,8 @@ static scf_optimizer_t* scf_optimizers[] = &scf_optimizer_dominators, &scf_optimizer_auto_gc, + &scf_optimizer_js_array2, + &scf_optimizer_active_vars, &scf_optimizer_loads_saves, diff --git a/js/core/scf_optimizer_js_array.c b/js/core/scf_optimizer_js_array.c index 3940541..2799637 100644 --- a/js/core/scf_optimizer_js_array.c +++ b/js/core/scf_optimizer_js_array.c @@ -1,15 +1,20 @@ #include"scf_optimizer.h" #include"scf_pointer_alias.h" -static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* array, scf_node_t* index) +static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* array, scf_node_t* index, scf_type_t* Object) { scf_3ac_code_t* c; - scf_variable_t* v; + scf_variable_t* v = _scf_operand_get(index); scf_function_t* f = NULL; scf_type_t* t = NULL; scf_node_t* pf; - int ret = scf_ast_find_global_function(&f, ast, "Object_array_realloc"); + int ret; + + if (v->type == Object->type) + ret = scf_ast_find_global_function(&f, ast, "Object_array_realloc_obj"); + else + ret = scf_ast_find_global_function(&f, ast, "Object_array_realloc"); if (ret < 0) return ret; @@ -81,6 +86,7 @@ static int __js_ref_obj(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* obj) static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head) { + scf_3ac_operand_t* dst; scf_3ac_operand_t* base; scf_3ac_operand_t* index; scf_3ac_code_t* c; @@ -100,7 +106,7 @@ static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_bl c = scf_list_data(l, scf_3ac_code_t, list); l = scf_list_next(l); - if (SCF_OP_ARRAY_INDEX == c->op->type || scf_type_is_assign_array_index(c->op->type)) { + if (scf_type_is_assign_array_index(c->op->type)) { base = c->srcs->data[0]; index = c->srcs->data[1]; array = base->node; @@ -110,39 +116,40 @@ static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_bl v = _scf_operand_get(array); - if (v->type == Object->type) { - c2 = NULL; - ret = __js_array_realloc(ast, &c2, array, index->node); - if (ret < 0) - return ret; + if (v->type != Object->type) + continue; - c2->basic_block = c->basic_block; - c2->basic_block->call_flag = 1; + c2 = NULL; + ret = __js_array_realloc(ast, &c2, array, index->node, Object); + if (ret < 0) + return ret; - assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head)); + c2->basic_block = c->basic_block; + c2->basic_block->call_flag = 1; - scf_list_add_tail(scf_list_prev(&c->list), &c2->list); + assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head)); - if (f->js_flag && scf_type_is_assign_array_index(c->op->type)) { - base = c->srcs->data[3]; - node = base->node; + scf_list_add_tail(scf_list_prev(&c->list), &c2->list); - while (SCF_OP_EXPR == node->type) - node = node->nodes[0]; + if (f->js_flag) { + base = c->srcs->data[3]; + node = base->node; - v = _scf_operand_get(node); + while (SCF_OP_EXPR == node->type) + node = node->nodes[0]; - if (v->arg_flag) { - c2 = NULL; - ret = __js_ref_obj(ast, &c2, node); - if (ret < 0) - return ret; + v = _scf_operand_get(node); - c2->basic_block = c->basic_block; - c2->basic_block->call_flag = 1; + if (v->arg_flag) { + c2 = NULL; + ret = __js_ref_obj(ast, &c2, node); + if (ret < 0) + return ret; - scf_list_add_tail(scf_list_prev(&c->list), &c2->list); - } + c2->basic_block = c->basic_block; + c2->basic_block->call_flag = 1; + + scf_list_add_tail(scf_list_prev(&c->list), &c2->list); } } } @@ -156,6 +163,16 @@ static int _optimize_js_array(scf_ast_t* ast, scf_function_t* f, scf_vector_t* f if (!f) return -EINVAL; + if (strcmp(f->node.w->text->data, "__js_main")) { + scf_string_t* s = f->node.w->file; + + if (!strncmp(s->data + s->len - 8, "js/doc.c", 8)) + return 0; + } + + printf("\n"); + scf_logi("------- %s() ------ file: %s\n", f->node.w->text->data, f->node.w->file->data); + scf_list_t* bb_list_head = &f->basic_block_list_head; scf_list_t* l; scf_basic_block_t* bb; diff --git a/js/core/scf_optimizer_js_array2.c b/js/core/scf_optimizer_js_array2.c new file mode 100644 index 0000000..007b09b --- /dev/null +++ b/js/core/scf_optimizer_js_array2.c @@ -0,0 +1,265 @@ +#include"scf_optimizer.h" +#include"scf_pointer_alias.h" + +static int __js_array_index(scf_ast_t* ast, scf_3ac_code_t* c, scf_dag_node_t* index, scf_type_t* Object) +{ + scf_3ac_operand_t* pf; + scf_variable_t* v; + scf_dag_node_t* dn; + scf_function_t* f = NULL; + scf_type_t* t = NULL; + + int ret; + + if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type) + ret = scf_ast_find_global_function(&f, ast, "Object_assign_array_index_obj"); + else { + if (index->var->type == Object->type) + ret = scf_ast_find_global_function(&f, ast, "Object_array_index_obj"); + + else if (index->var->type == SCF_VAR_DOUBLE) + ret = scf_ast_find_global_function(&f, ast, "Object_array_index_d"); + else + ret = scf_ast_find_global_function(&f, ast, "Object_array_index"); + } + if (ret < 0) + return ret; + + 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; + + dn = scf_dag_node_alloc(v->type, v, (scf_node_t*)f); + scf_variable_free(v); + v = NULL; + if (!dn) + return -ENOMEM; + + pf = c->srcs->data[2]; + + if (pf->node) + scf_node_free(pf->node); + + if (pf->dag_node) { + scf_list_del(&pf->dag_node->list); + scf_dag_node_free(pf->dag_node); + } + + pf->node = (scf_node_t*)f; + pf->dag_node = dn; + + SCF_XCHG(c->srcs->data[2], c->srcs->data[1]); + SCF_XCHG(c->srcs->data[1], c->srcs->data[0]); + + c->op = scf_3ac_find_operator(SCF_OP_CALL); + return 0; +} + +static scf_3ac_code_t* __js_array_find_3ac(scf_dag_node_t* member, scf_3ac_code_t* c, scf_basic_block_t* cur_bb, scf_basic_block_t* bb, scf_list_t* l, scf_list_t* bb_list_head) +{ + scf_basic_block_t* bb2; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c2; + scf_list_t* l2; + scf_list_t* l3; + + for (l2 = scf_list_prev(&c->list); l2 != scf_list_sentinel(&cur_bb->code_list_head); l2 = scf_list_prev(l2)) { + c2 = scf_list_data(l2, scf_3ac_code_t, list); + + if (SCF_OP_POINTER == c2->op->type) { + dst = c2->dsts->data[0]; + + if (dst->dag_node == member) + return c2; + } + } + + for (l3 = scf_list_prev(&cur_bb->list); l3 != scf_list_sentinel(bb_list_head); l3 = scf_list_prev(l3)) { + bb2 = scf_list_data(l3, scf_basic_block_t, list); + + if (bb2 == bb) { + l2 = scf_list_prev(l); + + if (l2 == &c->list) + l2 = scf_list_prev(l2); + } else + l2 = scf_list_tail(&bb2->code_list_head); + + for ( ; l2 != scf_list_sentinel(&bb2->code_list_head); l2 = scf_list_prev(l2)) { + c2 = scf_list_data(l2, scf_3ac_code_t, list); + + if (SCF_OP_POINTER == c2->op->type) { + dst = c2->dsts->data[0]; + + if (dst->dag_node == member) + return c2; + } + } + } + + return NULL; +} + +static int _optimize_js_array2_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head) +{ + scf_basic_block_t* cur_bb = bb; + scf_basic_block_t* bb2; + scf_basic_block_t* bb3; + + scf_3ac_operand_t* base; + scf_3ac_operand_t* index; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; + scf_dag_node_t* array; + scf_dag_node_t* member; + scf_type_t* Object = NULL; + scf_list_t* l; + scf_list_t* l2; + + int ret = scf_ast_find_global_type(&Object, ast, "Object"); + if (ret < 0) + return ret; + + for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) { + + c = scf_list_data(l, scf_3ac_code_t, list); + l = scf_list_next(l); + + if (cur_bb != bb) { + scf_list_del(&c->list); + scf_list_add_tail(&cur_bb->code_list_head, &c->list); + + c->basic_block = cur_bb; + } + + if (SCF_OP_ARRAY_INDEX != c->op->type && SCF_OP_3AC_ASSIGN_ARRAY_INDEX != c->op->type) + continue; + + base = c->srcs->data[0]; + index = c->srcs->data[1]; + member = base->dag_node; + + array = member; + while (SCF_OP_EXPR == array->type || SCF_OP_POINTER == array->type) + array = array->childs->data[0]; + + if (array->var->type != Object->type) + continue; + + if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type && index->dag_node->var->type != Object->type) + continue; + + int op_type = c->op->type; + + ret = __js_array_index(ast, c, index->dag_node, Object); + if (ret < 0) + return ret; + + scf_vector_del(c->basic_block->dn_reloads, member); + + base = c->srcs->data[1]; + base->dag_node = array; + base->node = array->node; +#if 1 + c2 = __js_array_find_3ac(member, c, cur_bb, bb, l, bb_list_head); + assert(c2); + + scf_vector_del(c2->basic_block->dn_resaves, member); + scf_vector_del(c2->basic_block->exit_dn_actives, member); + + scf_list_del(&c2->list); + scf_3ac_code_free(c2); + c2 = NULL; +#endif + + if (scf_list_prev(&c->list) != scf_list_sentinel(&cur_bb->code_list_head)) { + bb2 = NULL; + ret = scf_basic_block_split(cur_bb, &bb2); + if (ret < 0) + return ret; + scf_list_add_front(&cur_bb->list, &bb2->list); + + if (SCF_OP_ARRAY_INDEX == op_type) { + base = c->dsts->data[0]; + scf_vector_del(cur_bb->dn_resaves, base->dag_node); + scf_vector_del(cur_bb->exit_dn_actives, base->dag_node); + + base = c->srcs->data[2]; + scf_vector_del(cur_bb->dn_reloads, base->dag_node); + } + + scf_list_del(&c->list); + scf_list_add_tail(&bb2->code_list_head, &c->list); + + c->basic_block = bb2; + + if (l != scf_list_sentinel(&bb->code_list_head)) { + bb3 = NULL; + ret = scf_basic_block_split(bb2, &bb3); + if (ret < 0) + return ret; + scf_list_add_front(&bb2->list, &bb3->list); + + bb3->ret_flag = bb->ret_flag; + + cur_bb = bb3; + } + } + + c->basic_block->call_flag = 1; + } + + return 0; +} + +static int _optimize_js_array2(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions) +{ + if (!f) + return -EINVAL; + + if (strcmp(f->node.w->text->data, "__js_main")) { + scf_string_t* s = f->node.w->file; + + if (!strncmp(s->data + s->len - 8, "js/doc.c", 8)) + return 0; + } + + printf("\n"); + scf_logi("------- %s() ------ file: %s\n", f->node.w->text->data, f->node.w->file->data); + + scf_list_t* bb_list_head = &f->basic_block_list_head; + scf_list_t* l; + scf_basic_block_t* bb; + + if (scf_list_empty(bb_list_head)) + return 0; + + for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) { + + bb = scf_list_data(l, scf_basic_block_t, list); + l = scf_list_next(l); + + if (bb->jmp_flag || bb->end_flag || bb->cmp_flag) + continue; + + int ret = _optimize_js_array2_bb(ast, f, bb, bb_list_head); + if (ret < 0) + return ret; + } + + return 0; +} + +scf_optimizer_t scf_optimizer_js_array2 = +{ + .name = "js_array2", + + .optimize = _optimize_js_array2, + + .flags = SCF_OPTIMIZER_LOCAL, +}; diff --git a/js/core/scf_optimizer_js_unary_op.c b/js/core/scf_optimizer_js_unary_op.c index b569a29..baad749 100644 --- a/js/core/scf_optimizer_js_unary_op.c +++ b/js/core/scf_optimizer_js_unary_op.c @@ -1,79 +1,144 @@ #include"scf_optimizer.h" #include"scf_pointer_alias.h" -static int __js_unary_op(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* node, int op_type) +static int __js_unary_pointer(scf_ast_t* ast, scf_node_t** __pointer, scf_node_t** __member, scf_node_t* base, scf_type_t* Object) { - scf_3ac_code_t* c; - scf_variable_t* v; - scf_function_t* f = NULL; - scf_type_t* t = NULL; - scf_node_t* pf; - scf_node_t* fret; - - char* fname = NULL; - - switch (op_type) { - case SCF_OP_3AC_INC: - fname = "Object_inc"; - break; - - case SCF_OP_3AC_DEC: - fname = "Object_dec"; - break; - default: - return -1; - break; - }; - - int ret = scf_ast_find_global_function(&f, ast, fname); - if (ret < 0) - return ret; - - ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR); + scf_variable_t* v; + scf_variable_t* d = scf_scope_find_variable(Object->scope, "d"); + scf_type_t* t = NULL; + scf_node_t* parent = base->parent; + scf_node_t* pointer; + scf_node_t* member; + + int ret = scf_ast_find_type_type(&t, ast, SCF_VAR_DOUBLE); if (ret < 0) return ret; - v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f); + v = SCF_VAR_ALLOC_BY_TYPE(d->w, t, 0, 0, NULL); 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) + pointer = scf_node_alloc(d->w, SCF_OP_POINTER, NULL); + if (!pointer) { + scf_variable_free(v); return -ENOMEM; + } + pointer->op = scf_find_base_operator_by_type(SCF_OP_POINTER); + pointer->result = v; + v = NULL; - ret = scf_ast_find_type_type(&t, ast, SCF_VAR_VOID); - if (ret < 0) + ret = scf_node_add_child(pointer, base); + if (ret < 0) { + scf_node_free(pointer); return ret; + } - v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 0, 0, NULL); - if (!v) - return -ENOMEM; - v->tmp_flag = 1; - v->const_flag = 1; + int i; + for (i = 0; i < parent->nb_nodes; i++) { + if (parent->nodes[i] == base) + parent->nodes[i] = pointer; + } + pointer->parent = parent; - fret = scf_node_alloc(f->node.w, SCF_OP_CALL, NULL); - if (!fret) { - scf_variable_free(v); - scf_node_free(pf); + member = scf_node_alloc(NULL, d->type, d); + if (!member) return -ENOMEM; + + ret = scf_node_add_child(pointer, member); + if (ret < 0) { + scf_node_free(member); + return ret; + } + + *__pointer = pointer; + *__member = member; + return 0; +} + +static int __js_unary_op(scf_ast_t* ast, scf_3ac_code_t* c, scf_node_t* base, scf_type_t* Object) +{ + scf_3ac_operand_t* src; + scf_3ac_code_t* c2; + scf_node_t* parent = base->parent; + scf_node_t* pointer = NULL; + scf_node_t* member = NULL; + + if (parent->nb_nodes < 2) { + int ret = __js_unary_pointer(ast, &pointer, &member, base, Object); + if (ret < 0) + return ret; + } else { + assert(SCF_OP_POINTER == parent->type); + + pointer = parent; + member = parent->nodes[1]; } - fret->op = scf_find_base_operator_by_type(SCF_OP_CALL); - fret->result = v; - v = NULL; - scf_node_t* srcs[] = {pf, node}; + switch (c->op->type) { + case SCF_OP_INC: + case SCF_OP_DEC: + c2 = scf_3ac_code_NN(SCF_OP_POINTER, &pointer, 1, pointer->nodes, 2); + if (!c2) + return -ENOMEM; - c = scf_3ac_code_NN(SCF_OP_CALL, &fret, 1, srcs, 2); - if (!c) { - scf_node_free(pf); - scf_node_free(fret); + scf_list_add_tail(&c->list, &c2->list); + break; + default: + break; + }; + + src = c->srcs->data[0]; + src->node = pointer; + + scf_node_t* srcs[] = {base, member, pointer}; + + c2 = scf_3ac_code_NN(SCF_OP_3AC_ASSIGN_POINTER, NULL, 0, srcs, 3); + if (!c2) return -ENOMEM; + + scf_list_add_front(&c->list, &c2->list); + return 0; +} + +static int __js_unary_assign(scf_ast_t* ast, scf_3ac_code_t* c, scf_node_t* base, scf_type_t* Object) +{ + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_code_t* c2; + scf_variable_t* v; + scf_node_t* parent = base->parent; + scf_node_t* pointer = NULL; + scf_node_t* member = NULL; + + if (parent->nb_nodes < 2) { + int ret = __js_unary_pointer(ast, &pointer, &member, base, Object); + if (ret < 0) + return ret; + } else { + assert(SCF_OP_POINTER == parent->type); + + pointer = parent; + member = parent->nodes[1]; } - *pc = c; + switch (dst->node->type) { + case SCF_OP_INC_POST: + case SCF_OP_DEC_POST: + c2 = scf_3ac_code_NN(SCF_OP_POINTER, &pointer, 1, pointer->nodes, 2); + if (!c2) + return -ENOMEM; + + scf_list_add_tail(&c->list, &c2->list); + break; + default: + break; + }; + + src->node = pointer; + + v = _scf_operand_get(dst->node); + v->type = SCF_VAR_DOUBLE; + v->nb_pointers = 0; return 0; } @@ -101,27 +166,37 @@ static int _optimize_js_unary_op_bb(scf_ast_t* ast, scf_function_t* f, scf_basic src = c->srcs->data[0]; node = src->node; - while (SCF_OP_EXPR == node->type) - node = node->nodes[0]; - v = _scf_operand_get(node); if (v->type != Object->type) continue; - c2 = NULL; - ret = __js_unary_op(ast, &c2, node, c->op->type); + ret = __js_unary_op(ast, c, node, Object); if (ret < 0) return ret; - c2->basic_block = c->basic_block; - c2->basic_block->call_flag = 1; + } else if (SCF_OP_ASSIGN == c->op->type) { + src = c->srcs->data[0]; + dst = c->dsts->data[0]; + node = src->node; - scf_list_add_tail(&c->list, &c2->list); + v = _scf_operand_get(node); + + if (v->type != Object->type) + continue; - scf_list_del(&c->list); - scf_3ac_code_free(c); - c = NULL; + switch (dst->node->type) { + case SCF_OP_INC: + case SCF_OP_INC_POST: + case SCF_OP_DEC_POST: + case SCF_OP_DEC: + ret = __js_unary_assign(ast, c, node, Object); + if (ret < 0) + return ret; + break; + default: + break; + }; } } diff --git a/js/doc.c b/js/doc.c index 15505b2..2d320eb 100644 --- a/js/doc.c +++ b/js/doc.c @@ -437,6 +437,19 @@ struct Object return 0; } + bool operator>(Object* this, Object* that) + { + if (JS_Number == this->type && JS_Number == that->type) + return this->d > that->d; + return 0; + } + bool operator>(Object* this, double d) + { + if (JS_Number == this->type) + return this->d > d; + return 0; + } + void __release(Object* this) { if (this->members) { @@ -620,6 +633,35 @@ int Object_array_realloc(Object* this, int i) return 0; } +int Object_array_realloc_obj(Object* this, Object* index) +{ + int i = index->d; + return Object_array_realloc(this, i); +} + +Object* Object_array_index(Object* this, int i) +{ + if (i < this->length) + return this->members[i]; + return NULL; +} + +Object* Object_array_index_d(Object* this, double d) +{ + int i = d; + if (i < this->length) + return this->members[i]; + return NULL; +} + +Object* Object_array_index_obj(Object* this, Object* index) +{ + int i = index->d; + if (i < this->length) + return this->members[i]; + return NULL; +} + Object* document = NULL; void __js_main(Object* doc) diff --git a/js/native/x64/scf_x64_inst.c b/js/native/x64/scf_x64_inst.c index 9854380..c98b96f 100644 --- a/js/native/x64/scf_x64_inst.c +++ b/js/native/x64/scf_x64_inst.c @@ -803,6 +803,59 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } +static int _x64_inst_inc_float(scf_function_t* f, scf_3ac_code_t* c, int INC) +{ + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_variable_t* v = src->dag_node->var; + scf_variable_t* v1; + scf_register_t* rs = NULL; + scf_x64_OpCode_t* OpCode; + scf_instruction_t* inst = NULL; + scf_rela_t* rela = NULL; + + v1 = scf_variable_clone(v); + if (!v1) + return -ENOMEM; + + scf_string_free(v1->w->text); + v1->w->text = scf_string_cstr("1.0"); + if (!v1->w->text) { + scf_variable_free(v1); + return -ENOMEM; + } + + scf_scope_push_var(f->scope, v1); + + v1->const_literal_flag = 1; + v1->const_flag = 1; + v1->global_flag = 1; + v1->local_flag = 0; + v1->tmp_flag = 0; + + if (4 == v->size) { + if (SCF_X64_INC == INC) + OpCode = x64_find_OpCode(SCF_X64_ADDSS, 4, 4, SCF_X64_E2G); + else + OpCode = x64_find_OpCode(SCF_X64_SUBSS, 4, 4, SCF_X64_E2G); + + v1->data.f = 1.0; + } else { + v1->data.d = 1.0; + + if (SCF_X64_INC == INC) + OpCode = x64_find_OpCode(SCF_X64_ADDSD, 8, 8, SCF_X64_E2G); + else + OpCode = x64_find_OpCode(SCF_X64_SUBSD, 8, 8, SCF_X64_E2G); + } + + X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + + inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1); + X64_INST_ADD_CHECK(c->instructions, inst); + X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL); + return 0; +} + static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD) { if (!c->srcs || c->srcs->size != 1) @@ -818,11 +871,20 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD) if (0 == src->dag_node->color) return -EINVAL; + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + scf_variable_t* v = src->dag_node->var; scf_register_t* rs = NULL; scf_x64_OpCode_t* OpCode; scf_instruction_t* inst = NULL; + if (scf_variable_float(v)) + return _x64_inst_inc_float(f, c, INC); + int imm_size = 1; if (v->data_size > 0xff) imm_size = 4; @@ -837,12 +899,6 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD) return -EINVAL; } - if (!c->instructions) { - c->instructions = scf_vector_alloc(); - if (!c->instructions) - return -ENOMEM; - } - if (v->nb_pointers > 0) { if (src->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); diff --git a/js/parse/scf_dfa_for.c b/js/parse/scf_dfa_for.c index a83a21d..543c116 100644 --- a/js/parse/scf_dfa_for.c +++ b/js/parse/scf_dfa_for.c @@ -103,27 +103,36 @@ static int _for_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } - if (0 == fd->nb_semicolons) { - if (!fd->init_exprs) - fd->init_exprs = scf_vector_alloc(); - - scf_vector_add(fd->init_exprs, d->expr); - d->expr = NULL; - - } else if (1 == fd->nb_semicolons) { - fd->cond_expr = d->expr; - d->expr = NULL; - - } else if (2 == fd->nb_semicolons) { - if (!fd->update_exprs) - fd->update_exprs = scf_vector_alloc(); - - scf_vector_add(fd->update_exprs, d->expr); - d->expr = NULL; - } else { - scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line); - return SCF_DFA_ERROR; - } + switch (fd->nb_semicolons) { + case 0: + if (d->expr) { + if (!fd->init_exprs) + fd->init_exprs = scf_vector_alloc(); + + scf_vector_add(fd->init_exprs, d->expr); + d->expr = NULL; + } + break; + + case 1: + fd->cond_expr = d->expr; + d->expr = NULL; + break; + + case 2: + if (d->expr) { + if (!fd->update_exprs) + fd->update_exprs = scf_vector_alloc(); + + scf_vector_add(fd->update_exprs, d->expr); + d->expr = NULL; + } + break; + default: + scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line); + return SCF_DFA_ERROR; + break; + }; SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"), SCF_DFA_HOOK_POST); SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"), SCF_DFA_HOOK_POST); @@ -142,22 +151,25 @@ static int _for_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data scf_stack_t* s = d->module_datas[dfa_module_for.index]; dfa_for_data_t* fd = scf_stack_top(s); - if (0 == fd->nb_semicolons) { - if (d->expr) { - if (!fd->init_exprs) - fd->init_exprs = scf_vector_alloc(); + switch (fd->nb_semicolons) { + case 0: + if (d->expr) { + if (!fd->init_exprs) + fd->init_exprs = scf_vector_alloc(); - scf_vector_add(fd->init_exprs, d->expr); - d->expr = NULL; - } - } else if (1 == fd->nb_semicolons) { - if (d->expr) { + scf_vector_add(fd->init_exprs, d->expr); + d->expr = NULL; + } + break; + + case 1: fd->cond_expr = d->expr; d->expr = NULL; - } - } else { - scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line); - return SCF_DFA_ERROR; + break; + default: + scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line); + return SCF_DFA_ERROR; + break; } fd->nb_semicolons++; @@ -237,11 +249,13 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) } if (2 == fd->nb_semicolons) { - if (!fd->update_exprs) - fd->update_exprs = scf_vector_alloc(); + if (d->expr) { + if (!fd->update_exprs) + fd->update_exprs = scf_vector_alloc(); - scf_vector_add(fd->update_exprs, d->expr); - d->expr = NULL; + scf_vector_add(fd->update_exprs, d->expr); + d->expr = NULL; + } } else { scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line); return SCF_DFA_ERROR; diff --git a/ui/Makefile b/ui/Makefile index c177fdd..d6ce2b0 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -158,6 +158,7 @@ CFILES += ../js/core/scf_optimizer.c CFILES += ../js/core/scf_optimizer_dag.c CFILES += ../js/core/scf_optimizer_inline.c CFILES += ../js/core/scf_optimizer_js_array.c +CFILES += ../js/core/scf_optimizer_js_array2.c CFILES += ../js/core/scf_optimizer_js_teq.c CFILES += ../js/core/scf_optimizer_js_unary_op.c CFILES += ../js/core/scf_optimizer_js_call.c -- 2.25.1