From 89bceefde101789bc3ce2c22b59cd46def652d0c Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Tue, 11 Nov 2025 19:57:52 +0800 Subject: [PATCH] js: support simple 'for() loop' --- examples/js.html | 8 +- html/Makefile | 1 + html/abc_html.c | 24 +++- js/core/scf_3ac.c | 75 ++++------ js/core/scf_function.h | 4 +- js/core/scf_operator_dag.c | 10 +- js/core/scf_optimizer.c | 8 +- js/core/scf_optimizer_js_unary_op.c | 176 +++++++++++++++++++++++ js/core/scf_pointer_alias.c | 6 +- js/core/scf_type.c | 1 + js/doc.c | 25 +++- js/native/x64/scf_x64_inst_cmp.c | 31 +++- js/native/x64/scf_x64_opcode.c | 6 + js/native/x64/scf_x64_opcode.h | 1 - js/native/x64/scf_x64_rcg.c | 59 +++----- js/native/x64/scf_x64_util.h | 8 +- js/parse/scf_dfa_for.c | 14 +- js/parse/scf_operator_handler_semantic.c | 44 ++++-- js/parse/scf_parse.c | 1 + ui/Makefile | 2 + 20 files changed, 370 insertions(+), 134 deletions(-) create mode 100644 js/core/scf_optimizer_js_unary_op.c diff --git a/examples/js.html b/examples/js.html index 322c052..7419820 100644 --- a/examples/js.html +++ b/examples/js.html @@ -8,10 +8,10 @@ diff --git a/html/Makefile b/html/Makefile index 3890934..bfdac51 100644 --- a/html/Makefile +++ b/html/Makefile @@ -109,6 +109,7 @@ CFILES += ../js/core/scf_optimizer_inline.c CFILES += ../js/core/scf_optimizer_js_array.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 CFILES += ../js/core/scf_optimizer_split_call.c diff --git a/html/abc_html.c b/html/abc_html.c index f47710a..a7d1f1f 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -606,8 +606,22 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) flag = !flag; if (!flag) { - if ('<' == c->c) - break; + if ('<' == c->c) { + if (ABC_HTML_SCRIPT != obj->type) + break; + + abc_char_t* c2 = __html_pop_char(html); + if (!c2) { + scf_loge("\n"); + scf_string_free(text); + return -1; + } + + __html_push_char(html, c2); + + if ('/' == c2->c) + break; + } } if ('\n' == c->c) { @@ -977,11 +991,11 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) } if (obj->text) { - scf_logd("obj->text: %s\n", obj->text->data); - ret = scf_parse_file(html->js, obj->js_path->data, obj->text); - if (ret < 0) + if (ret < 0) { + scf_loge("obj->text: %s\n", obj->text->data); return ret; + } ret = scf_parse_compile(html->js, "x64"); if (ret < 0) { diff --git a/js/core/scf_3ac.c b/js/core/scf_3ac.c index 45a2691..0e28716 100644 --- a/js/core/scf_3ac.c +++ b/js/core/scf_3ac.c @@ -1252,49 +1252,37 @@ void scf_3ac_list_print(scf_list_t* h) static int _3ac_find_basic_block_start(scf_list_t* h) { - int start = 0; - scf_list_t* l; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; + scf_variable_t* v; + scf_list_t* l; + scf_list_t* l2; - for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) { + int start = 0; - scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); + for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) { - scf_list_t* l2 = NULL; - scf_3ac_code_t* c2 = NULL; + c = scf_list_data(l, scf_3ac_code_t, list); if (!start) { c->basic_block_start = 1; start = 1; } -#if 0 - if (scf_type_is_assign_dereference(c->op->type)) { - - l2 = scf_list_next(&c->list); - if (l2 != scf_list_sentinel(h)) { - c2 = scf_list_data(l2, scf_3ac_code_t, list); - c2->basic_block_start = 1; - } - - c->basic_block_start = 1; - continue; - } - if (SCF_OP_DEREFERENCE == c->op->type) { - c->basic_block_start = 1; - continue; - } -#endif +#if 1 + if (SCF_OP_ASSIGN == c->op->type) { + dst = c->dsts->data[0]; + v = _scf_operand_get(dst->node); -#if 0 - if (SCF_OP_CALL == c->op->type) { + if (v->nb_pointers > 0) { + l2 = scf_list_next(&c->list); - l2 = scf_list_next(&c->list); - if (l2 != scf_list_sentinel(h)) { - c2 = scf_list_data(l2, scf_3ac_code_t, list); - c2->basic_block_start = 1; + if (l2 != scf_list_sentinel(h)) { + c2 = scf_list_data(l2, scf_3ac_code_t, list); + c2->basic_block_start = 1; + } + continue; } - -// c->basic_block_start = 1; - continue; } #endif @@ -1318,7 +1306,6 @@ static int _3ac_find_basic_block_start(scf_list_t* h) || SCF_OP_3AC_TEQ == c->op->type) { for (l2 = scf_list_next(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_next(l2)) { - c2 = scf_list_data(l2, scf_3ac_code_t, list); if (scf_type_is_setcc(c2->op->type)) @@ -1336,12 +1323,11 @@ static int _3ac_find_basic_block_start(scf_list_t* h) if (scf_type_is_jmp(c->op->type)) { - scf_3ac_operand_t* dst0 = c->dsts->data[0]; - - assert(dst0->code); + dst = c->dsts->data[0]; + assert(dst->code); // filter 1st expr of logic op, such as '&&', '||' - if (SCF_OP_3AC_TEQ == dst0->code->op->type) { + if (SCF_OP_3AC_TEQ == dst->code->op->type) { int ret = _3ac_filter_dst_teq(h, c); if (ret < 0) @@ -1349,7 +1335,6 @@ static int _3ac_find_basic_block_start(scf_list_t* h) } for (l2 = scf_list_prev(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_prev(l2)) { - c2 = scf_list_data(l2, scf_3ac_code_t, list); if (scf_type_is_setcc(c2->op->type)) @@ -1370,12 +1355,7 @@ static int _3ac_find_basic_block_start(scf_list_t* h) } #if 1 for (l = scf_list_head(h); l != scf_list_sentinel(h); ) { - - scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); - - scf_list_t* l2 = NULL; - scf_3ac_code_t* c2 = NULL; - scf_3ac_operand_t* dst0 = NULL; + c = scf_list_data(l, scf_3ac_code_t, list); if (SCF_OP_3AC_NOP == c->op->type) { assert(!c->jmp_dst_flag); @@ -1395,7 +1375,6 @@ static int _3ac_find_basic_block_start(scf_list_t* h) assert(!c->jmp_dst_flag); for (l2 = scf_list_next(&c->list); l2 != scf_list_sentinel(h); ) { - c2 = scf_list_data(l2, scf_3ac_code_t, list); if (c2->jmp_dst_flag) @@ -1408,10 +1387,10 @@ static int _3ac_find_basic_block_start(scf_list_t* h) c2 = NULL; } - l = scf_list_next(l); - dst0 = c->dsts->data[0]; + l = scf_list_next(l); + dst = c->dsts->data[0]; - if (l == &dst0->code->list) { + if (l == &dst->code->list) { scf_list_del(&c->list); scf_3ac_code_free(c); c = NULL; diff --git a/js/core/scf_function.h b/js/core/scf_function.h index 880e2ee..9b0afd4 100644 --- a/js/core/scf_function.h +++ b/js/core/scf_function.h @@ -20,7 +20,7 @@ struct scf_function_s { int args_float; int args_double; - int op_type; // overloaded operator type + int op_type; // overloaded operator type scf_vector_t* callee_functions; scf_vector_t* caller_functions; @@ -28,6 +28,8 @@ struct scf_function_s { scf_list_t basic_block_list_head; int nb_basic_blocks; + int score; // overloaded score + scf_vector_t* jmps; scf_list_t dag_list_head; diff --git a/js/core/scf_operator_dag.c b/js/core/scf_operator_dag.c index 103592e..a3142e8 100644 --- a/js/core/scf_operator_dag.c +++ b/js/core/scf_operator_dag.c @@ -373,9 +373,11 @@ static int _scf_dag_op_##name(scf_list_t* h, scf_dag_node_t* parent, scf_dag_nod } SCF_OP_CMP(eq, ==, SCF_OP_EQ) -SCF_OP_CMP(ne, ==, SCF_OP_NE) -SCF_OP_CMP(gt, >, SCF_OP_GT) -SCF_OP_CMP(lt, <, SCF_OP_LT) +SCF_OP_CMP(ne, !=, SCF_OP_NE) +SCF_OP_CMP(gt, >, SCF_OP_GT) +SCF_OP_CMP(ge, >=, SCF_OP_GE) +SCF_OP_CMP(lt, <, SCF_OP_LT) +SCF_OP_CMP(le, <=, SCF_OP_LE) scf_dag_operator_t dag_operators[] = { @@ -409,7 +411,9 @@ scf_dag_operator_t dag_operators[] = {SCF_OP_EQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_eq}, {SCF_OP_NE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ne}, {SCF_OP_GT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_gt}, + {SCF_OP_GE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ge}, {SCF_OP_LT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_lt}, + {SCF_OP_LE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_le}, {SCF_OP_VLA_ALLOC, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_vla_alloc}, {SCF_OP_RETURN, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_return}, diff --git a/js/core/scf_optimizer.c b/js/core/scf_optimizer.c index bf449f5..bf646c4 100644 --- a/js/core/scf_optimizer.c +++ b/js/core/scf_optimizer.c @@ -3,6 +3,7 @@ extern scf_optimizer_t scf_optimizer_inline; 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; @@ -38,6 +39,7 @@ static scf_optimizer_t* scf_optimizers[] = &scf_optimizer_inline, // global optimizer &scf_optimizer_js_array, &scf_optimizer_js_teq, + &scf_optimizer_js_unary_op, &scf_optimizer_js_call, &scf_optimizer_split_call, @@ -53,13 +55,13 @@ static scf_optimizer_t* scf_optimizers[] = &scf_optimizer_pointer_aliases, &scf_optimizer_loads_saves, + &scf_optimizer_basic_block, + &scf_optimizer_const_teq, + &scf_optimizer_auto_gc_find, // global optimizer &scf_optimizer_dominators, &scf_optimizer_auto_gc, - &scf_optimizer_basic_block, - &scf_optimizer_const_teq, - &scf_optimizer_active_vars, &scf_optimizer_loads_saves, diff --git a/js/core/scf_optimizer_js_unary_op.c b/js/core/scf_optimizer_js_unary_op.c new file mode 100644 index 0000000..b569a29 --- /dev/null +++ b/js/core/scf_optimizer_js_unary_op.c @@ -0,0 +1,176 @@ +#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) +{ + 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); + 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; + + ret = scf_ast_find_type_type(&t, ast, SCF_VAR_VOID); + if (ret < 0) + 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; + + fret = scf_node_alloc(f->node.w, SCF_OP_CALL, NULL); + if (!fret) { + scf_variable_free(v); + scf_node_free(pf); + return -ENOMEM; + } + fret->op = scf_find_base_operator_by_type(SCF_OP_CALL); + fret->result = v; + v = NULL; + + scf_node_t* srcs[] = {pf, node}; + + c = scf_3ac_code_NN(SCF_OP_CALL, &fret, 1, srcs, 2); + if (!c) { + scf_node_free(pf); + scf_node_free(fret); + return -ENOMEM; + } + + *pc = c; + return 0; +} + +static int _optimize_js_unary_op_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head) +{ + scf_3ac_operand_t* src; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; + scf_variable_t* v; + scf_node_t* node; + scf_type_t* Object = NULL; + scf_list_t* l; + + 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 (SCF_OP_3AC_INC == c->op->type || SCF_OP_3AC_DEC == c->op->type) { + 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); + if (ret < 0) + return ret; + + c2->basic_block = c->basic_block; + c2->basic_block->call_flag = 1; + + scf_list_add_tail(&c->list, &c2->list); + + scf_list_del(&c->list); + scf_3ac_code_free(c); + c = NULL; + } + } + + return 0; +} + +static int _optimize_js_unary_op(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_unary_op_bb(ast, f, bb, bb_list_head); + if (ret < 0) + return ret; + } + + return 0; +} + +scf_optimizer_t scf_optimizer_js_unary_op = +{ + .name = "js_unary_op", + + .optimize = _optimize_js_unary_op, + + .flags = SCF_OPTIMIZER_LOCAL, +}; diff --git a/js/core/scf_pointer_alias.c b/js/core/scf_pointer_alias.c index 9868a73..02af3c6 100644 --- a/js/core/scf_pointer_alias.c +++ b/js/core/scf_pointer_alias.c @@ -153,8 +153,10 @@ static int _bb_pointer_initeds(scf_vector_t* initeds, scf_list_t* bb_list_head, if (v->tmp_flag) return 0; - scf_loge("pointer '%s' is not inited, tmp_flag: %d, local_flag: %d, file: %s, line: %d\n", - v->w->text->data, v->tmp_flag, v->local_flag, v->w->file->data, v->w->line); + if (SCF_OP_ADDRESS_OF != dn->type) { + scf_loge("pointer '%s_%d_%d' is not inited, tmp_flag: %d, local_flag: %d, file: %s, line: %d\n", + v->w->text->data, v->w->line, v->w->pos, v->tmp_flag, v->local_flag, v->w->file->data, v->w->line); + } return SCF_POINTER_NOT_INIT; } diff --git a/js/core/scf_type.c b/js/core/scf_type.c index 5a13a3a..a964018 100644 --- a/js/core/scf_type.c +++ b/js/core/scf_type.c @@ -54,6 +54,7 @@ static scf_type_abbrev_t type_abbrevs[] = { {"int", "i"}, {"void", "v"}, + {"bool", "B"}, {"char", "c"}, {"float", "f"}, diff --git a/js/doc.c b/js/doc.c index fb4ce0c..15505b2 100644 --- a/js/doc.c +++ b/js/doc.c @@ -50,7 +50,7 @@ struct Object { this->d = d; this->type = JS_Number; - printf("this: %p, this->d: %lg, d: %ld\n\n", this, this->d, d); + printf("this: %p, this->d: %lg, i64 d: %ld\n\n", this, this->d, d); return 0; } @@ -421,7 +421,19 @@ struct Object if (JS_String == this->type && JS_String == that->type) return !strcmp(this->str, that->str); + 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; } @@ -549,6 +561,17 @@ void Object_func_arguments(Object* this, int i, Object* arg) } } +void Object_inc(Object* this) +{ + if (JS_Number == this->type) + this->d += 1.0; +} +void Object_dec(Object* this) +{ + if (JS_Number == this->type) + this->d -= 1.0; +} + bool Object_teq(Object* this) { if (!this) diff --git a/js/native/x64/scf_x64_inst_cmp.c b/js/native/x64/scf_x64_inst_cmp.c index ad09f1a..84c40f9 100644 --- a/js/native/x64/scf_x64_inst_cmp.c +++ b/js/native/x64/scf_x64_inst_cmp.c @@ -204,6 +204,35 @@ int x64_inst_cmp_set(scf_native_t* ctx, scf_3ac_code_t* c, int setcc_type) if (ret < 0) return ret; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_dag_node_t* dn = src->dag_node; + + int is_float = scf_variable_float(dn->var); + + switch (setcc_type) + { + case SCF_X64_SETG: + if (is_float) + setcc_type = SCF_X64_SETA; + break; + + case SCF_X64_SETGE: + if (is_float) + setcc_type = SCF_X64_SETAE; + break; + + case SCF_X64_SETL: + if (is_float) + setcc_type = SCF_X64_SETB; + break; + + case SCF_X64_SETLE: + if (is_float) + setcc_type = SCF_X64_SETBE; + break; + default: + break; + }; + return x64_inst_set(ctx, c, setcc_type); } - diff --git a/js/native/x64/scf_x64_opcode.c b/js/native/x64/scf_x64_opcode.c index 8254307..1b51082 100644 --- a/js/native/x64/scf_x64_opcode.c +++ b/js/native/x64/scf_x64_opcode.c @@ -241,6 +241,12 @@ scf_x64_OpCode_t x64_OpCodes[] = { {SCF_X64_SETL, "setl", 3, {0x0f, 0x9c, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, {SCF_X64_SETLE, "setle", 3, {0x0f, 0x9e, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, + {SCF_X64_SETA, "seta", 3, {0x0f, 0x97, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, + {SCF_X64_SETAE, "setae", 3, {0x0f, 0x93, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, + + {SCF_X64_SETB, "setb", 3, {0x0f, 0x92, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, + {SCF_X64_SETBE, "setbe", 3, {0x0f, 0x96, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}}, + {SCF_X64_ADDSS, "addss", 4, {0xf3, 0x0f, 0x58},3, 4,4, SCF_X64_E2G, 0,0, 0,{0,0}}, {SCF_X64_ADDSD, "addsd", 8, {0xf2, 0x0f, 0x58},3, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}}, diff --git a/js/native/x64/scf_x64_opcode.h b/js/native/x64/scf_x64_opcode.h index 92cbec4..c471e2d 100644 --- a/js/native/x64/scf_x64_opcode.h +++ b/js/native/x64/scf_x64_opcode.h @@ -34,4 +34,3 @@ scf_x64_OpCode_t* x64_find_OpCode(const int type, const int OpBytes, const int int x64_find_OpCodes(scf_vector_t* results, const int type, const int OpBytes, const int RegBytes, const int EG); #endif - diff --git a/js/native/x64/scf_x64_rcg.c b/js/native/x64/scf_x64_rcg.c index bb0d728..79059a8 100644 --- a/js/native/x64/scf_x64_rcg.c +++ b/js/native/x64/scf_x64_rcg.c @@ -805,49 +805,22 @@ X64_RCG_SET(setge) X64_RCG_SET(setlt) X64_RCG_SET(setle) -static int _x64_rcg_eq_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) -{ - scf_3ac_operand_t* dst = c->dsts->data[0]; - - int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); - if (ret < 0) - return ret; - - return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); -} - -static int _x64_rcg_ne_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) -{ - scf_3ac_operand_t* dst = c->dsts->data[0]; - - int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); - if (ret < 0) - return ret; - - return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); -} - -static int _x64_rcg_gt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) -{ - scf_3ac_operand_t* dst = c->dsts->data[0]; - - int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); - if (ret < 0) - return ret; - - return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); -} - -static int _x64_rcg_lt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) -{ - scf_3ac_operand_t* dst = c->dsts->data[0]; - - int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); - if (ret < 0) - return ret; - - return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); +#define X64_RCG_CMP(op) \ +static int _x64_rcg_##op##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ +{ \ + scf_3ac_operand_t* dst = c->dsts->data[0]; \ + \ + int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + if (ret < 0) \ + return ret; \ + return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ } +X64_RCG_CMP(eq) +X64_RCG_CMP(ne) +X64_RCG_CMP(gt) +X64_RCG_CMP(ge) +X64_RCG_CMP(lt) +X64_RCG_CMP(le) static int _x64_rcg_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { @@ -1296,7 +1269,9 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [SCF_OP_EQ ] = _x64_rcg_eq_handler, [SCF_OP_NE ] = _x64_rcg_ne_handler, [SCF_OP_GT ] = _x64_rcg_gt_handler, + [SCF_OP_GE ] = _x64_rcg_ge_handler, [SCF_OP_LT ] = _x64_rcg_lt_handler, + [SCF_OP_LE ] = _x64_rcg_le_handler, [SCF_OP_ASSIGN ] = _x64_rcg_assign_handler, [SCF_OP_ADD_ASSIGN ] = _x64_rcg_add_assign_handler, diff --git a/js/native/x64/scf_x64_util.h b/js/native/x64/scf_x64_util.h index 2458e9f..837c30a 100644 --- a/js/native/x64/scf_x64_util.h +++ b/js/native/x64/scf_x64_util.h @@ -74,6 +74,12 @@ enum scf_x64_OpCode_types { SCF_X64_SETL, SCF_X64_SETLE, + SCF_X64_SETA, + SCF_X64_SETAE, + + SCF_X64_SETB, + SCF_X64_SETBE, + SCF_X64_ADDSS, SCF_X64_ADDSD, @@ -83,7 +89,6 @@ enum scf_x64_OpCode_types { SCF_X64_MULSS, SCF_X64_MULSD, - // 41 SCF_X64_DIVSS, SCF_X64_DIVSD, @@ -93,7 +98,6 @@ enum scf_x64_OpCode_types { SCF_X64_UCOMISS, SCF_X64_UCOMISD, - // 47 SCF_X64_CVTSI2SD, SCF_X64_CVTSI2SS, diff --git a/js/parse/scf_dfa_for.c b/js/parse/scf_dfa_for.c index fa243ed..a83a21d 100644 --- a/js/parse/scf_dfa_for.c +++ b/js/parse/scf_dfa_for.c @@ -184,21 +184,17 @@ static int _for_add_expr_vector(dfa_for_data_t* fd, scf_vector_t* vec) return SCF_DFA_OK; } - scf_node_t* parent = fd->_for; - if (vec->size > 1) { - - scf_block_t* b = scf_block_alloc_cstr("for"); - - scf_node_add_child(fd->_for, (scf_node_t*)b); - parent = (scf_node_t*)b; - } + scf_block_t* b = scf_block_alloc_cstr("for"); + if (!b) + return -ENOMEM; + scf_node_add_child(fd->_for, (scf_node_t*)b); int i; for (i = 0; i < vec->size; i++) { scf_expr_t* e = vec->data[i]; - scf_node_add_child(parent, e); + scf_node_add_child((scf_node_t*)b, e); } scf_vector_free(vec); diff --git a/js/parse/scf_operator_handler_semantic.c b/js/parse/scf_operator_handler_semantic.c index 51c1cfc..8ec3f1b 100644 --- a/js/parse/scf_operator_handler_semantic.c +++ b/js/parse/scf_operator_handler_semantic.c @@ -293,20 +293,12 @@ static int _semantic_find_proper_function2(scf_ast_t* ast, scf_vector_t* fvec, s int i; int j; - for (i = 0; i < fvec->size; i++) { + for (i = 0; i < fvec->size; ) { f = fvec->data[i]; - if (scf_function_same_argv(f->argv, argv)) { - *pf = f; - return 0; - } - } - - for (i = 0; i < fvec->size; i++) { - f = fvec->data[i]; + f->score = 0; for (j = 0; j < argv->size; j++) { - v0 = f->argv->data[j]; v1 = argv->data[j]; @@ -316,12 +308,40 @@ static int _semantic_find_proper_function2(scf_ast_t* ast, scf_vector_t* fvec, s if (scf_type_cast_check(ast, v0, v1) < 0) break; + int type = scf_find_updated_type(ast, v0, v1); + if (type < 0) + break; + + if (scf_variable_nb_pointers(v0) == scf_variable_nb_pointers(v1)) { + if (type == v0->type) { + f->score += 1; + + if (type == v1->type) + f->score += 1000; + } + } + } + + if (j < argv->size) + assert(0 == scf_vector_del(fvec, f)); // drop invalid function + else + i++; + } + + if (fvec->size <= 0) + return -404; + + int max = INT_MIN; + for (i = 0; i < fvec->size; i++) { + f = fvec->data[i]; + + if (max < f->score) { + max = f->score; *pf = f; - return 0; } } - return -404; + return 0; } static int _semantic_find_proper_function(scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv, scf_function_t** pf) diff --git a/js/parse/scf_parse.c b/js/parse/scf_parse.c index 95efe61..c976598 100644 --- a/js/parse/scf_parse.c +++ b/js/parse/scf_parse.c @@ -2335,6 +2335,7 @@ int scf_parse_compile(scf_parse_t* parse, const char* arch) switch (e->type) { case SCF_OP_EXPR: case SCF_OP_IF: + case SCF_OP_FOR: ret = scf_node_add_child((scf_node_t*)f, e); if (ret < 0) return ret; diff --git a/ui/Makefile b/ui/Makefile index 229ff1d..c177fdd 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -159,7 +159,9 @@ 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_teq.c +CFILES += ../js/core/scf_optimizer_js_unary_op.c CFILES += ../js/core/scf_optimizer_js_call.c + CFILES += ../js/core/scf_optimizer_split_call.c CFILES += ../js/core/scf_optimizer_call.c CFILES += ../js/core/scf_optimizer_common_expr.c -- 2.25.1