From: yu.dongliang <18588496441@163.com> Date: Wed, 13 Aug 2025 05:15:46 +0000 (+0800) Subject: js: simple Object Model ok X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=6cab491a9cd7bde00b359774360bb22ac8992de7;p=abc.git js: simple Object Model ok --- diff --git a/examples/js.html b/examples/js.html index a37709d..1c701f0 100644 --- a/examples/js.html +++ b/examples/js.html @@ -7,10 +7,16 @@

含有js的页面

diff --git a/html/Makefile b/html/Makefile index 59b84ac..1d21c36 100644 --- a/html/Makefile +++ b/html/Makefile @@ -147,6 +147,7 @@ CFILES += ../js/parse/scf_dfa_type.c CFILES += ../js/parse/scf_dfa_identity.c CFILES += ../js/parse/scf_dfa_function.c +CFILES += ../js/parse/scf_dfa_function_js.c CFILES += ../js/parse/scf_dfa_operator.c CFILES += ../js/parse/scf_dfa_var.c diff --git a/js/abc_libjs.so b/js/abc_libjs.so index 11e0760..cb2894b 100755 Binary files a/js/abc_libjs.so and b/js/abc_libjs.so differ diff --git a/js/core/scf_ast.c b/js/core/scf_ast.c index a85bc7f..2e815bb 100644 --- a/js/core/scf_ast.c +++ b/js/core/scf_ast.c @@ -410,3 +410,75 @@ int scf_ast_find_type_type(scf_type_t** pt, scf_ast_t* ast, int type) return scf_ast_find_global_type_type(pt, ast, type); } +int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w) +{ + scf_variable_t* v; + scf_lex_word_t* w2; + scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR); + scf_node_t* node; + + w2 = scf_lex_word_clone(w); + if (!w2) + return -ENOMEM; + + int ret = scf_string_cat_cstr(w2->text, "__cstr"); + if (ret < 0) { + scf_lex_word_free(w2); + return ret; + } + + v = SCF_VAR_ALLOC_BY_TYPE(w2, t, 1, 1, NULL); + scf_lex_word_free(w2); + w2 = NULL; + if (!v) + return -ENOMEM; + v->const_literal_flag = 1; + + scf_logi("w->text: %s\n", w->text->data); + v->data.s = scf_string_clone(w->text); + if (!v->data.s) { + scf_variable_free(v); + return -ENOMEM; + } + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) + return -ENOMEM; + + ret = scf_node_add_child(parent, node); + if (ret < 0) { + scf_node_free(node); + return ret; + } + + return 0; +} + +int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64) +{ + scf_variable_t* v; + scf_type_t* t = scf_block_find_type_type(ast->current_block, type); + scf_node_t* node; + + v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL); + if (!v) + return -ENOMEM; + v->data.u64 = u64; + v->const_literal_flag = 1; + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) + return -ENOMEM; + + int ret = scf_node_add_child(parent, node); + if (ret < 0) { + scf_node_free(node); + return ret; + } + + return 0; +} diff --git a/js/core/scf_ast.h b/js/core/scf_ast.h index 404c778..f05e72e 100644 --- a/js/core/scf_ast.h +++ b/js/core/scf_ast.h @@ -101,5 +101,7 @@ int scf_ast_add_base_type(scf_ast_t* ast, scf_base_type_t* base_type); int scf_ast_add_file_block(scf_ast_t* ast, const char* path); -#endif +int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w); +int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64); +#endif diff --git a/js/core/scf_dag.c b/js/core/scf_dag.c index 6290c18..fb92226 100644 --- a/js/core/scf_dag.c +++ b/js/core/scf_dag.c @@ -280,7 +280,11 @@ void scf_dn_status_print(scf_dn_status_t* ds) if (ds->dag_node) { v = ds->dag_node->var; - printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data); + + if (v->w) + printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data); + else + printf("dn: v_%#lx ", (uintptr_t)v & 0xffff); if (ds->dn_indexes) { for (i = ds->dn_indexes->size - 1; i >= 0; i--) { @@ -296,7 +300,10 @@ void scf_dn_status_print(scf_dn_status_t* ds) if (ds->alias) { v = ds->alias->var; - printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data); + if (v->w) + printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data); + else + printf(" alias: v_%#lx ", (uintptr_t)v & 0xffff); if (ds->alias_indexes) { for (i = ds->alias_indexes->size - 1; i >= 0; i--) { diff --git a/js/core/scf_lex_word.h b/js/core/scf_lex_word.h index b9addb6..7b2c10a 100644 --- a/js/core/scf_lex_word.h +++ b/js/core/scf_lex_word.h @@ -148,6 +148,7 @@ enum scf_lex_words // class SCF_LEX_WORD_KEY_CLASS, // class + SCF_LEX_WORD_KEY_FUNC, // function SCF_LEX_WORD_KEY_CONST, // const SCF_LEX_WORD_KEY_STATIC, // static diff --git a/js/core/scf_optimizer_auto_gc.c b/js/core/scf_optimizer_auto_gc.c index 822c25a..2b1ab06 100644 --- a/js/core/scf_optimizer_auto_gc.c +++ b/js/core/scf_optimizer_auto_gc.c @@ -22,23 +22,50 @@ static int _find_ds_malloced(scf_basic_block_t* bb, void* data) return 0; } -static int _find_dn_active(scf_basic_block_t* bb, void* data) +static int __find_dn_active(scf_vector_t* dn_vec, scf_dag_node_t* dn) { - scf_dag_node_t* dn = data; + scf_dn_status_t* ds = NULL; + scf_dag_node_t* dn2; + int i; - if (scf_vector_find(bb->dn_loads, data)) - return 1; + for (i = 0; i < dn_vec->size; i++) { + dn2 = dn_vec->data[i]; - if (scf_vector_find(bb->dn_reloads, data)) - return 1; + if (dn2 == dn) + return 1; - if (scf_vector_find(bb->entry_dn_actives, data)) - return 1; + int ret = scf_ds_for_dn(&ds, dn2); + if (ret < 0) + return ret; + + if (ds->dag_node == dn) { + scf_dn_status_free(ds); + return 1; + } + + scf_dn_status_free(ds); + ds = NULL; + } - scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data); return 0; } +static int _find_dn_active(scf_basic_block_t* bb, void* data) +{ + scf_dag_node_t* dn = data; + + int ret = __find_dn_active(bb->dn_loads, dn); + if (0 == ret) { + ret = __find_dn_active(bb->dn_reloads, dn); + + if (0 == ret) + ret = __find_dn_active(bb->entry_dn_actives, dn); + } + + scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data); + return ret; +} + static int _bb_find_ds_malloced(scf_basic_block_t* root, scf_list_t* bb_list_head, scf_dn_status_t* ds, scf_vector_t* results) { scf_basic_block_visit_flag(bb_list_head, 0); @@ -1014,7 +1041,6 @@ static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* fu } } -// scf_basic_block_print_list(bb_list_head); return 0; } diff --git a/js/core/scf_pointer_alias.c b/js/core/scf_pointer_alias.c index 2232ac7..811de5d 100644 --- a/js/core/scf_pointer_alias.c +++ b/js/core/scf_pointer_alias.c @@ -1557,7 +1557,7 @@ int scf_pointer_alias(scf_vector_t* aliases, scf_dag_node_t* dn_alias, scf_3ac_c default: if (dn_alias->var && dn_alias->var->w) { v = dn_alias->var; - scf_loge("type: %d, v_%d_%d/%s\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data); + scf_loge("type: %d, v_%d_%d/%s/%#lx\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn_alias->var); } else scf_loge("type: %d, v_%#lx\n", dn_alias->type, 0xffff & (uintptr_t)dn_alias->var); return -1; diff --git a/js/core/scf_scope.c b/js/core/scf_scope.c index 8790ebe..9e7612f 100644 --- a/js/core/scf_scope.c +++ b/js/core/scf_scope.c @@ -42,6 +42,9 @@ void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var) { assert(scope); assert(var); + + var->js_index = scope->vars->size; + scf_vector_add(scope->vars, var); } diff --git a/js/core/scf_type.h b/js/core/scf_type.h index efb3a15..82aa8a9 100644 --- a/js/core/scf_type.h +++ b/js/core/scf_type.h @@ -36,6 +36,7 @@ struct scf_type_s { int size; int offset; // only used for member var of struct or class + scf_type_t* super; // pointed to super type extended by this scf_type_t* parent; // pointed to parent type includes this }; diff --git a/js/core/scf_variable.c b/js/core/scf_variable.c index 96197d2..3c2fde5 100644 --- a/js/core/scf_variable.c +++ b/js/core/scf_variable.c @@ -100,6 +100,9 @@ scf_variable_t* scf_variable_alloc(scf_lex_word_t* w, scf_type_t* t) v->refs = 1; v->type = t->type; + v->js_type = -1; + v->js_index = -1; + v->const_flag = t->node.const_flag; v->nb_pointers = t->nb_pointers; v->func_ptr = t->func_ptr; diff --git a/js/core/scf_variable.h b/js/core/scf_variable.h index 89e8b19..1e4ae3d 100644 --- a/js/core/scf_variable.h +++ b/js/core/scf_variable.h @@ -16,6 +16,9 @@ struct scf_variable_s { int type; // type scf_lex_word_t* w; // lex word + int js_type; + int js_index; + int nb_lbs; // number of '{}' when parse js object int nb_rbs; diff --git a/js/doc.c b/js/doc.c index a575256..849a9db 100644 --- a/js/doc.c +++ b/js/doc.c @@ -1,4 +1,107 @@ -int printf(const char* fmt, ...); +#include"../js/lib/scf_capi.c" + +struct Object +{ + int type; + int n_members; + Object** members; + char* name; +// p.x --> p.members[x] + char* str; + double d; + + int __init(Object* this, double d) + { + this->d = d; + return 0; + } + + int __init(Object* this, const char* name, int n_members) + { + printf("this: %p, name: %s\n", this, name); + int len = strlen(name); + + this->name = scf__auto_malloc(len + 1); + if (!this->name) + return -1; + memcpy(this->name, name, len + 1); + + this->n_members = n_members; + + if (n_members > 0) { + this->members = scf__auto_malloc(sizeof(Object*) * n_members); + if (!this->members) + return -1; + } + + printf("\n"); + return 0; + } + + int __init(Object* this, const char* name, int n_members, double d) + { + printf("this: %p, name: %s\n", this, name); + int len = strlen(name); + + this->name = scf__auto_malloc(len + 1); + if (!this->name) + return -1; + memcpy(this->name, name, len + 1); + + this->n_members = n_members; + + if (n_members > 0) { + this->members = scf__auto_malloc(sizeof(Object*) * n_members); + if (!this->members) + return -1; + } + + this->d = d; + + printf("this: %p, this->d: %lg, d: %lg\n", this, this->d, d); + return 0; + } + + const char* toString(Object* this) + { + char* s = scf__auto_malloc(128); + if (!s) + return NULL; + + snprintf(s, 127, "%lg", this->d); + return s; + } + + Object* operator+(Object* this, Object* that) + { + Object* res = create Object(this->d + that->d); + return res; + } + + void __release(Object* this) + { + if (this->members) { + int i; + for (i = 0; i < this->n_members; i++) { + if (this->members[i]) { + this->members[i].__release(); + + scf__auto_freep(&this->members[i], NULL); + } + } + + scf__auto_freep(&this->members, NULL); + } + + if (this->name) + scf__auto_freep(&this->name, NULL); + + if (this->str) + scf__auto_freep(&this->str, NULL); + +// printf("\n"); + } +}; struct HTML; @@ -6,8 +109,9 @@ int abc_html_write(HTML* html, const char* s); struct HTML { - void write(HTML* this, const char* s) + void write(HTML* this, Object* obj) { + char* s = obj.toString(); abc_html_write(this, s); } }; diff --git a/js/elf/scf_elf_x64_so.c b/js/elf/scf_elf_x64_so.c index 236e9a4..46b1df7 100644 --- a/js/elf/scf_elf_x64_so.c +++ b/js/elf/scf_elf_x64_so.c @@ -170,10 +170,7 @@ static int _x64_elf_add_gnu_hash(elf_native_t* x64, elf_section_t** ps) #define HASH_BUCKETS 3 #define HASH_BLOOMS 1 - int n_syms = x64->dynsyms->size; - - if (x64->dyn_relas) - n_syms -= x64->dyn_relas->size; + int n_syms = x64->dynsyms->size - x64->n_plts; int len = sizeof(uint32_t) * 4 + sizeof(uint64_t) * HASH_BLOOMS + sizeof(uint32_t) * HASH_BUCKETS @@ -833,12 +830,9 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot) scf_string_t* str = scf_string_alloc(); char c = '\0'; - int j = 0; + int j = x64->n_plts; int i; - if (x64->dyn_relas) - j = x64->dyn_relas->size; - scf_string_cat_cstr_len(str, &c, 1); for (i = 0; i < x64->dynsyms->size; i++) { @@ -919,7 +913,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot) dyns[i + 8].d_tag = DT_JMPREL; dyns[i + 5].d_un.d_ptr = (uintptr_t)x64->got_plt; - dyns[i + 6].d_un.d_ptr = sizeof(Elf64_Rela); + dyns[i + 6].d_un.d_ptr = x64->rela_plt->data_len; dyns[i + 7].d_un.d_ptr = DT_RELA; dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->rela_plt; diff --git a/js/lex/scf_lex.c b/js/lex/scf_lex.c index a62e8a8..a9b9e56 100644 --- a/js/lex/scf_lex.c +++ b/js/lex/scf_lex.c @@ -80,6 +80,7 @@ static scf_key_word_t key_words[] = {"union", SCF_LEX_WORD_KEY_UNION}, {"struct", SCF_LEX_WORD_KEY_STRUCT}, {"var", SCF_LEX_WORD_KEY_VAR}, + {"function", SCF_LEX_WORD_KEY_FUNC}, }; static scf_escape_char_t escape_chars[] = diff --git a/js/lib/scf_capi.c b/js/lib/scf_capi.c index 384b957..759b34d 100644 --- a/js/lib/scf_capi.c +++ b/js/lib/scf_capi.c @@ -1,5 +1,6 @@ int printf(const char* fmt, ...); +int snprintf(char* buf, uintptr_t size, const char* fmt, ...); int rand(); void srand(uint32_t seed); diff --git a/js/lib/x64/scf_object.o b/js/lib/x64/scf_object.o index 00fd525..86e2a9f 100644 Binary files a/js/lib/x64/scf_object.o and b/js/lib/x64/scf_object.o differ diff --git a/js/native/x64/scf_x64_bb_color.c b/js/native/x64/scf_x64_bb_color.c index af9d946..2f9eefa 100644 --- a/js/native/x64/scf_x64_bb_color.c +++ b/js/native/x64/scf_x64_bb_color.c @@ -428,8 +428,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function for (j = 0; j < bb->prevs->size; j++) { prev = bb->prevs->data[j]; - if (!scf_vector_find(bbg->body, prev)) - continue; +// if (!scf_vector_find(bbg->body, prev)) +// continue; for (k = 0; k < prev->dn_colors_exit->size; k++) { ds2 = prev->dn_colors_exit->data[k]; @@ -438,7 +438,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function break; } - assert(k < prev->dn_colors_exit->size); + if (k >= prev->dn_colors_exit->size) + break; if (0 == first) { first = 1; @@ -452,12 +453,11 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function } if (j < bb->prevs->size) { - for (j = 0; j < bb->prevs->size; j++) { prev = bb->prevs->data[j]; - if (!scf_vector_find(bbg->body, prev)) - continue; + // if (!scf_vector_find(bbg->body, prev)) + // continue; for (k = 0; k < prev->dn_colors_exit->size; k++) { ds2 = prev->dn_colors_exit->data[k]; @@ -466,7 +466,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function break; } - assert(k < prev->dn_colors_exit->size); + if (k >= prev->dn_colors_exit->size) + continue; if (x64_bb_save_dn2(ds2->color, dn, prev, f) < 0) { scf_loge("\n"); diff --git a/js/native/x64/scf_x64_inst.c b/js/native/x64/scf_x64_inst.c index baad56d..9854380 100644 --- a/js/native/x64/scf_x64_inst.c +++ b/js/native/x64/scf_x64_inst.c @@ -1049,7 +1049,7 @@ static int _x64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_f return ret; } - if (vb->nb_dimentions > 1 || vb->type >= SCF_STRUCT || lea_flag) { + if (vb->nb_dimentions > 1 || (vb->type >= SCF_STRUCT && 0 == vb->nb_pointers) || lea_flag) { OpCode = x64_find_OpCode(SCF_X64_LEA, rd->bytes, rd->bytes, SCF_X64_E2G); } else { diff --git a/js/native/x64/scf_x64_reg.c b/js/native/x64/scf_x64_reg.c index 331d25d..b21cb3a 100644 --- a/js/native/x64/scf_x64_reg.c +++ b/js/native/x64/scf_x64_reg.c @@ -207,18 +207,21 @@ void x64_registers_print() } } -int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs) +int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs) { scf_basic_block_t* bb = c->basic_block; scf_dag_node_t* dn; scf_instruction_t* inst; - scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); - scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E); - scf_register_t* rsp = x64_find_register("rsp"); + scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); + scf_x64_OpCode_t* movsd = x64_find_OpCode(SCF_X64_MOVSD, 8,8, SCF_X64_G2E); + scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E); + scf_x64_OpCode_t* sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E); + scf_register_t* rsp = x64_find_register("rsp"); scf_register_t* r; scf_register_t* r2; + uint32_t imm = 8; int i; int j; int k; @@ -226,7 +229,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta int n = 0; for (j = 0; j < nb_regs; j++) { - r2 = x64_find_register_type_id_bytes(0, regs[j], 8); + r2 = x64_find_register(regs[j]); for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) { r = &(x64_registers[i]); @@ -263,10 +266,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta if (i == sizeof(x64_registers) / sizeof(x64_registers[0])) continue; - if (stack_size > 0) - inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2); - else - inst = x64_make_inst_G(push, r2); + if (X64_COLOR_TYPE(r2->color)) { + if (stack_size > 0) + inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2); + else { + inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_G2P(movsd, rsp, 0, r2); + } + } else { + if (stack_size > 0) + inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2); + else + inst = x64_make_inst_G(push, r2); + } X64_INST_ADD_CHECK(c->instructions, inst); saved_regs[n++] = r2; @@ -276,10 +290,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta if (size & 0xf) { r2 = saved_regs[n - 1]; - if (stack_size > 0) - inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2); - else - inst = x64_make_inst_G(push, r2); + if (X64_COLOR_TYPE(r2->color)) { + if (stack_size > 0) + inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2); + else { + inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_G2P(movsd, rsp, 0, r2); + } + } else { + if (stack_size > 0) + inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2); + else + inst = x64_make_inst_G(push, r2); + } X64_INST_ADD_CHECK(c->instructions, inst); saved_regs[n++] = r2; @@ -297,53 +322,19 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta return size; } -int x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs) -{ - int i; - int j; - scf_register_t* r; - scf_register_t* r2; - scf_instruction_t* inst; - scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); - - for (j = 0; j < nb_regs; j++) { - r2 = x64_find_register_type_id_bytes(0, regs[j], 8); - - for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) { - r = &(x64_registers[i]); - - if (!X64_COLOR_TYPE(r->color) && (SCF_X64_REG_RSP == r->id || SCF_X64_REG_RBP == r->id)) - continue; - - if (0 == r->dag_nodes->size) - continue; - - if (X64_COLOR_CONFLICT(r2->color, r->color)) - break; - } - - if (i == sizeof(x64_registers) / sizeof(x64_registers[0])) - continue; - - inst = x64_make_inst_G(push, r2); - X64_INST_ADD_CHECK(instructions, inst); - } - return 0; -} - int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated) { - int i; - int j; - - scf_register_t* rsp = x64_find_register("rsp"); - scf_register_t* r; - scf_register_t* r2; + scf_register_t* rsp = x64_find_register("rsp"); + scf_register_t* r; + scf_register_t* r2; scf_instruction_t* inst; - scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G); - scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E); + scf_x64_OpCode_t* movsd = x64_find_OpCode(SCF_X64_MOVSD, 8, 8, SCF_X64_E2G); + scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G); + scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E); uint32_t imm = 8; + int i; + int j; for (j = nb_regs - 1; j >= 0; j--) { r2 = regs[j]; @@ -373,7 +364,13 @@ int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs, } if (i == nb_updated) { - inst = x64_make_inst_G(pop, r2); + if (X64_COLOR_TYPE(r2->color)) { + inst = x64_make_inst_P2G(movsd, r2, rsp, 0); + X64_INST_ADD_CHECK(instructions, inst); + + inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4); + } else + inst = x64_make_inst_G(pop, r2); X64_INST_ADD_CHECK(instructions, inst); } else { inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4); @@ -679,7 +676,7 @@ int x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn) { scf_register_t* r2; - scf_dag_node_t* dn2; + scf_dag_node_t* dn2; int i; int j; @@ -695,7 +692,7 @@ int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn) continue; for (j = 0; j < r2->dag_nodes->size; j++) { - dn2 = r2->dag_nodes->data[j]; + dn2 = r2->dag_nodes->data[j]; if (dn2 != dn) return 1; @@ -745,6 +742,8 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c) int i; int j; + scf_logi("bytes: %d\n", bytes); + assert(c->rcg); ret = x64_rcg_find_node(&gn, c->rcg, dn, NULL); @@ -1358,9 +1357,7 @@ int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f) int j; for (i = 0; i < X64_ABI_CALLEE_SAVES_NB; i++) { - - j = x64_abi_callee_saves[i]; - r = x64_find_register_type_id_bytes(0, j, 8); + r = x64_find_register(x64_abi_callee_saves[i]); for (j = 0; j < N; j++) { r2 = &(x64_registers[j]); @@ -1397,9 +1394,7 @@ int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f) f->callee_saved_size = 0; for (i = X64_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) { - - j = x64_abi_callee_saves[i]; - r = x64_find_register_type_id_bytes(0, j, 8); + r = x64_find_register(x64_abi_callee_saves[i]); for (j = 0; j < N; j++) { r2 = &(x64_registers[j]); diff --git a/js/native/x64/scf_x64_reg.h b/js/native/x64/scf_x64_reg.h index 790ce54..40c5967 100644 --- a/js/native/x64/scf_x64_reg.h +++ b/js/native/x64/scf_x64_reg.h @@ -65,27 +65,36 @@ static uint32_t x64_abi_ret_regs[] = }; #define X64_ABI_RET_NB (sizeof(x64_abi_ret_regs) / sizeof(x64_abi_ret_regs[0])) -static uint32_t x64_abi_caller_saves[] = +static const char* x64_abi_caller_saves[] = { - SCF_X64_REG_RAX, - SCF_X64_REG_RCX, - SCF_X64_REG_RDX, - SCF_X64_REG_RSI, - SCF_X64_REG_RDI, - SCF_X64_REG_R8, - SCF_X64_REG_R9, - SCF_X64_REG_R10, - SCF_X64_REG_R11, + "rax", + "rcx", + "rdx", + "rsi", + "rdi", + "r8", + "r9", + "r10", + "r11", + + "xmm0", + "xmm1", + "xmm2", + "xmm3", + "xmm4", + "xmm5", + "xmm6", + "xmm7", }; #define X64_ABI_CALLER_SAVES_NB (sizeof(x64_abi_caller_saves) / sizeof(x64_abi_caller_saves[0])) -static uint32_t x64_abi_callee_saves[] = +static const char* x64_abi_callee_saves[] = { - SCF_X64_REG_RBX, - SCF_X64_REG_R12, - SCF_X64_REG_R13, - SCF_X64_REG_R14, - SCF_X64_REG_R15, + "rbx", + "r12", + "r13", + "r14", + "r15", }; #define X64_ABI_CALLEE_SAVES_NB (sizeof(x64_abi_callee_saves) / sizeof(x64_abi_callee_saves[0])) @@ -138,7 +147,7 @@ int x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac int x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs); int x64_pop_regs (scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated); -int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs); +int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs); int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f); int x64_pop_callee_regs (scf_3ac_code_t* c, scf_function_t* f); diff --git a/js/parse/main.c b/js/parse/main.c index d262425..d592dd3 100644 --- a/js/parse/main.c +++ b/js/parse/main.c @@ -5,7 +5,7 @@ static char* __objs[] = { - "_start.o", +// "_start.o", "scf_object.o", "scf_atomic.o", }; @@ -101,13 +101,11 @@ int scf_parse_link(const char* exec, const char* obj, const char* libjs, const c #define MAIN_ADD_FILES(_objs, _sofiles, _arch) \ do { \ - if (!dyn) { \ - int ret = add_sys_files(objs, sysroot, _arch, _objs, sizeof(_objs) / sizeof(_objs[0])); \ - if (ret < 0) \ - return ret; \ - } \ - \ - int ret = add_sys_files(sofiles, sysroot, _arch, _sofiles, sizeof(_sofiles) / sizeof(_sofiles[0])); \ + int ret; \ + ret = add_sys_files(objs, sysroot, _arch, _objs, sizeof(_objs) / sizeof(_objs[0])); \ + if (ret < 0) \ + return ret; \ + ret = add_sys_files(sofiles, sysroot, _arch, _sofiles, sizeof(_sofiles) / sizeof(_sofiles[0])); \ if (ret < 0) \ return ret; \ } while (0) diff --git a/js/parse/scf_dfa_expr.c b/js/parse/scf_dfa_expr.c index 6e9ea28..949880b 100644 --- a/js/parse/scf_dfa_expr.c +++ b/js/parse/scf_dfa_expr.c @@ -80,8 +80,10 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) { expr_module_data_t* md = d->module_datas[dfa_module_expr.index]; scf_variable_t* var = NULL; + scf_variable_t* v = NULL; scf_node_t* node = NULL; scf_type_t* pt = NULL; + scf_type_t* t = NULL; scf_function_t* f = NULL; dfa_identity_t* id = scf_stack_pop(d->current_identities); scf_lex_word_t* w; @@ -114,9 +116,25 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) var->const_literal_flag = 1; } - scf_logi("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line); + 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); - node = scf_node_alloc(w, var->type, var); + if (md->current_var + && md->current_var->js_type >= 0 + && var->member_flag) { + scf_loge("var: %s, member_flag: %d, line: %d, pos: %d\n", var->w->text->data, var->member_flag, var->w->line, var->w->pos); + + t = scf_block_find_type_type(parse->ast->current_block, SCF_VAR_INTPTR); + v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL); + if (!v) + return -ENOMEM; + v->const_literal_flag = 1; + v->data.i64 = var->js_index; + + node = scf_node_alloc(w, v->type, v); + scf_variable_free(v); + v = NULL; + } else + node = scf_node_alloc(w, var->type, var); if (!node) return -ENOMEM; @@ -273,12 +291,14 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int nb_operands) { - scf_parse_t* parse = dfa->priv; - dfa_data_t* d = data; - scf_lex_word_t* w = words->data[words->size - 1]; - - scf_operator_t* op; - scf_node_t* node; + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + expr_module_data_t* md = d->module_datas[dfa_module_expr.index]; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_variable_t* v; + scf_operator_t* op; + scf_node_t* node; + scf_type_t* t; op = scf_find_base_operator(w->text->data, nb_operands); if (!op) { @@ -297,6 +317,44 @@ static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int return SCF_DFA_ERROR; } + if (SCF_LEX_WORD_ARROW == w->type || SCF_LEX_WORD_DOT == w->type) { + if (md->current_var->js_type >= 0) { + t = NULL; + if (scf_ast_find_type(&t, parse->ast, "Object") < 0) + return SCF_DFA_ERROR; + + v = scf_scope_find_variable(t->scope, "members"); + if (!v) { + scf_logw("var 'members' not found in struct '%s'\n", t->name->data); + return SCF_DFA_ERROR; + } + + node = scf_node_alloc(NULL, v->type, v); + if (!node) + return SCF_DFA_ERROR; + + if (scf_expr_add_node(d->expr, node) < 0) { + scf_node_free(node); + return SCF_DFA_ERROR; + } + + node = scf_node_alloc(NULL, SCF_OP_ARRAY_INDEX, NULL); + if (!node) + return SCF_DFA_ERROR; + + if (scf_expr_add_node(d->expr, node) < 0) { + scf_node_free(node); + return SCF_DFA_ERROR; + } + + t = NULL; + if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0) + return SCF_DFA_ERROR; + + parse->ast->current_block = (scf_block_t*)t; + } + } + return SCF_DFA_NEXT_WORD; } @@ -552,6 +610,10 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa_data_t* d = data; expr_module_data_t* md = d->module_datas[dfa_module_expr.index]; dfa_identity_t* id = scf_stack_top(d->current_identities); + scf_operator_t* op; + scf_variable_t* v; + scf_type_t* t; + scf_node_t* node; if (id && id->identity) { if (_expr_add_var(parse, d) < 0) { @@ -565,28 +627,56 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) md->parent_block = NULL; } - scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX); + if (md->current_var->js_type >= 0) { + t = NULL; + if (scf_ast_find_type(&t, parse->ast, "Object") < 0) + return SCF_DFA_ERROR; + + v = scf_scope_find_variable(t->scope, "members"); + if (!v) { + scf_logw("var 'members' not found in struct '%s'\n", t->name->data); + return SCF_DFA_ERROR; + } + + node = scf_node_alloc(w, SCF_OP_POINTER, NULL); + if (!node) + return SCF_DFA_ERROR; + + if (scf_expr_add_node(d->expr, node) < 0) { + scf_node_free(node); + return SCF_DFA_ERROR; + } + + node = scf_node_alloc(NULL, v->type, v); + if (!node) + return SCF_DFA_ERROR; + + if (scf_expr_add_node(d->expr, node) < 0) { + scf_node_free(node); + return SCF_DFA_ERROR; + } + } + + op = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX); assert(op); - scf_node_t* n = scf_node_alloc(w, op->type, NULL); - if (!n) { + node = scf_node_alloc(w, op->type, NULL); + if (!node) { scf_loge("node alloc error\n"); return SCF_DFA_ERROR; } - n->op = op; + node->op = op; - scf_expr_add_node(d->expr, n); + scf_expr_add_node(d->expr, node); scf_stack_push(md->ls_exprs, d->expr); - scf_expr_t* index = scf_expr_alloc(); - if (!index) { + d->expr = scf_expr_alloc(); + if (!d->expr) { scf_loge("index expr alloc error\n"); return SCF_DFA_ERROR; } - d->expr = index; - return SCF_DFA_NEXT_WORD; } diff --git a/js/parse/scf_dfa_function_js.c b/js/parse/scf_dfa_function_js.c new file mode 100644 index 0000000..a32423d --- /dev/null +++ b/js/parse/scf_dfa_function_js.c @@ -0,0 +1,331 @@ +#include"scf_dfa.h" +#include"scf_dfa_util.h" +#include"scf_parse.h" + +extern scf_dfa_module_t dfa_module_function_js; + +typedef struct { + + scf_block_t* parent_block; + +} dfa_fun_data_t; + +int _function_js_add_function(scf_dfa_t* dfa, scf_lex_word_t* w, dfa_data_t* d) +{ + scf_parse_t* parse = dfa->priv; + scf_ast_t* ast = parse->ast; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + + scf_function_t* f; + scf_variable_t* v; + scf_block_t* b; + scf_type_t* t = NULL; + + int ret = scf_ast_find_type(&t, ast, "Object"); + if (ret < 0) + return ret; + + b = ast->current_block; + while (b) { + if (b->node.type >= SCF_STRUCT) + break; + b = (scf_block_t*)b->node.parent; + } + + f = scf_function_alloc(w); + if (!f) + return SCF_DFA_ERROR; + f->member_flag = !!b; + + scf_logi("function: %s,line:%d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag); + + v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL); + if (!v) { + scf_function_free(f); + return SCF_DFA_ERROR; + } + + if (scf_vector_add(f->rets, v) < 0) { + scf_variable_free(v); + scf_function_free(f); + return SCF_DFA_ERROR; + } + + scf_scope_push_function(ast->current_block->scope, f); + + scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)f); + + fd ->parent_block = ast->current_block; + ast->current_block = (scf_block_t*)f; + + d->current_function = f; + + return SCF_DFA_NEXT_WORD; +} + +int _function_js_add_arg(scf_ast_t* ast, scf_lex_word_t* w, dfa_data_t* d) +{ + scf_variable_t* arg = NULL; + scf_type_t* t = NULL; + + int ret = scf_ast_find_type(&t, ast, "Object"); + if (ret < 0) + return ret; + + arg = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL); + if (!arg) + return SCF_DFA_ERROR; + + scf_scope_push_var(d->current_function->scope, arg); + + scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n", + d->argc, arg->nb_pointers, arg->nb_dimentions); + + scf_vector_add(d->current_function->argv, arg); + + arg->refs++; + arg->arg_flag = 1; + arg->local_flag = 1; + + d->argc++; + + return SCF_DFA_NEXT_WORD; +} + +static int _function_js_action_vargs(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_data_t* d = data; + + d->current_function->vargs_flag = 1; + + return SCF_DFA_NEXT_WORD; +} + +static int _function_js_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + scf_lex_word_t* w; + + if (words->size < 2) + return SCF_DFA_ERROR; + w = words->data[words->size - 2]; + + if (!scf_lex_is_identity(w)) + return SCF_DFA_ERROR; + + if (_function_js_add_arg(parse->ast, w, d) < 0) { + scf_loge("function_js add arg failed\n"); + return SCF_DFA_ERROR; + } + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_comma"), SCF_DFA_HOOK_PRE); + + return SCF_DFA_NEXT_WORD; +} + +static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + scf_lex_word_t* w; + + if (words->size < 2) + return SCF_DFA_ERROR; + w = words->data[words->size - 2]; + + assert(!d->current_node); + + d->current_var = NULL; + + if (_function_js_add_function(dfa, w, d) < 0) + return SCF_DFA_ERROR; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_rp"), SCF_DFA_HOOK_PRE); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_comma"), SCF_DFA_HOOK_PRE); + + d->argc = 0; + d->nb_lps++; + + return SCF_DFA_NEXT_WORD; +} + +static int _function_js_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + scf_function_t* f = d->current_function; + scf_function_t* fprev = NULL; + scf_lex_word_t* w; + + d->nb_rps++; + + if (d->nb_rps < d->nb_lps) { + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_rp"), SCF_DFA_HOOK_PRE); + return SCF_DFA_NEXT_WORD; + } + + if (words->size < 2) + return SCF_DFA_ERROR; + w = words->data[words->size - 2]; + + if (scf_lex_is_identity(w)) { + if (_function_js_add_arg(parse->ast, w, d) < 0) { + scf_loge("function_js add arg failed\n"); + return SCF_DFA_ERROR; + } + } + + scf_list_del(&f->list); + scf_node_del_child((scf_node_t*)fd->parent_block, (scf_node_t*)f); + + scf_block_t* b = fd->parent_block; + + if (!b->node.root_flag && !b->node.file_flag) { + scf_loge("function_js should be defined in file, global\n"); + return SCF_DFA_ERROR; + } + + assert(b->scope); + + if (SCF_LEX_WORD_KEY_FUNC != f->node.w->type) { + if (f->static_flag) + fprev = scf_scope_find_function(b->scope, f->node.w->text->data); + else { + int ret = scf_ast_find_global_function(&fprev, parse->ast, f->node.w->text->data); + if (ret < 0) + return ret; + } + + if (fprev) { + scf_loge("repeated declare function '%s', first in line: %d_%d, second in line: %d_%d\n", + f->node.w->text->data, fprev->node.w->line, fprev->node.w->pos, f->node.w->line, f->node.w->pos); + return SCF_DFA_ERROR; + } + } + + scf_scope_push_function(fd->parent_block->scope, f); + + scf_node_add_child((scf_node_t*)fd->parent_block, (scf_node_t*)f); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_end"), SCF_DFA_HOOK_END); + + parse->ast->current_block = (scf_block_t*)d->current_function; + + return SCF_DFA_NEXT_WORD; +} + +static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + + parse->ast->current_block = (scf_block_t*)(fd->parent_block); + + if (d->current_function->node.nb_nodes > 0) + d->current_function->node.define_flag = 1; + + fd->parent_block = NULL; + + d->current_function = NULL; + d->argc = 0; + d->nb_lps = 0; + d->nb_rps = 0; + + return SCF_DFA_OK; +} + +static int _dfa_init_module_function_js(scf_dfa_t* dfa) +{ + SCF_DFA_MODULE_NODE(dfa, function_js, comma, scf_dfa_is_comma, _function_js_action_comma); + SCF_DFA_MODULE_NODE(dfa, function_js, vargs, scf_dfa_is_vargs, _function_js_action_vargs); + SCF_DFA_MODULE_NODE(dfa, function_js, end, scf_dfa_is_entry, _function_js_action_end); + + SCF_DFA_MODULE_NODE(dfa, function_js, lp, scf_dfa_is_lp, _function_js_action_lp); + SCF_DFA_MODULE_NODE(dfa, function_js, rp, scf_dfa_is_rp, _function_js_action_rp); + SCF_DFA_MODULE_NODE(dfa, function_js, func, scf_dfa_is_func, scf_dfa_action_next); + SCF_DFA_MODULE_NODE(dfa, function_js, fname, scf_dfa_is_identity, scf_dfa_action_next); + SCF_DFA_MODULE_NODE(dfa, function_js, arg, scf_dfa_is_identity, scf_dfa_action_next); + + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = parse->dfa_data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + + assert(!fd); + + fd = calloc(1, sizeof(dfa_fun_data_t)); + if (!fd) { + scf_loge("\n"); + return SCF_DFA_ERROR; + } + + d->module_datas[dfa_module_function_js.index] = fd; + + return SCF_DFA_OK; +} + +static int _dfa_fini_module_function_js(scf_dfa_t* dfa) +{ + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = parse->dfa_data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index]; + + if (fd) { + free(fd); + fd = NULL; + d->module_datas[dfa_module_function_js.index] = NULL; + } + + return SCF_DFA_OK; +} + +static int _dfa_init_syntax_function_js(scf_dfa_t* dfa) +{ + SCF_DFA_GET_MODULE_NODE(dfa, function_js, comma, comma); + SCF_DFA_GET_MODULE_NODE(dfa, function_js, vargs, vargs); + + SCF_DFA_GET_MODULE_NODE(dfa, function_js, lp, lp); + SCF_DFA_GET_MODULE_NODE(dfa, function_js, rp, rp); + SCF_DFA_GET_MODULE_NODE(dfa, function_js, func, func); + SCF_DFA_GET_MODULE_NODE(dfa, function_js, fname, fname); + SCF_DFA_GET_MODULE_NODE(dfa, function_js, arg, arg); + + SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + + // function_js start + scf_vector_add(dfa->syntaxes, func); + + scf_dfa_node_add_child(func, fname); + scf_dfa_node_add_child(fname, lp); + scf_dfa_node_add_child(func, lp); + + // function_js args + scf_dfa_node_add_child(lp, rp); + + scf_dfa_node_add_child(lp, arg); + scf_dfa_node_add_child(arg, comma); + scf_dfa_node_add_child(comma, arg); + scf_dfa_node_add_child(arg, rp); + + scf_dfa_node_add_child(comma, vargs); + scf_dfa_node_add_child(vargs, rp); + + // function_js body + scf_dfa_node_add_child(rp, block); + + return 0; +} + +scf_dfa_module_t dfa_module_function_js = +{ + .name = "function_js", + + .init_module = _dfa_init_module_function_js, + .init_syntax = _dfa_init_syntax_function_js, + + .fini_module = _dfa_fini_module_function_js, +}; diff --git a/js/parse/scf_dfa_init_data.c b/js/parse/scf_dfa_init_data.c index c13cda0..b3b647f 100644 --- a/js/parse/scf_dfa_init_data.c +++ b/js/parse/scf_dfa_init_data.c @@ -6,6 +6,7 @@ extern scf_dfa_module_t dfa_module_init_data; int scf_array_init (scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs); int scf_struct_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs); +int scf_object_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_vector_t* init_exprs); int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s); @@ -32,42 +33,17 @@ static inline int _data_is_entry(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_LB == w->type || SCF_LEX_WORD_LS == w->type; } -static int _do_data_init(scf_dfa_t* dfa, scf_vector_t* words, dfa_data_t* d) +static int _do_data_init(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* obj) { - scf_parse_t* parse = dfa->priv; - scf_variable_t* var = d->current_var; - scf_lex_word_t* w = words->data[words->size - 1]; - init_module_data_t* md = d->module_datas[dfa_module_init_data.index]; + init_module_data_t* md = d->module_datas[dfa_module_init_data.index]; dfa_init_expr_t* ie; + int i; - int ret = -1; - int i = 0; - - if (d->current_var->nb_dimentions > 0) - ret = scf_array_init(parse->ast, md->assign, d->current_var, md->init_exprs); - - else if (d->current_var->type >= SCF_STRUCT) - ret = scf_struct_init(parse->ast, md->assign, d->current_var, md->init_exprs); - - if (ret < 0) - goto error; + int 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]; - ret = scf_node_add_child((scf_node_t*)parse->ast->current_block, ie->expr); - if (ret < 0) - goto error; - ie->expr = NULL; - - free(ie); - ie = NULL; - } - -error: - for (; i < md->init_exprs->size; i++) { - ie = md->init_exprs->data[i]; - scf_expr_free(ie->expr); free(ie); ie = NULL; @@ -76,7 +52,9 @@ error: md->assign = NULL; scf_vector_free(md->init_exprs); + scf_vector_free(md->init_objs); md->init_exprs = NULL; + md->init_objs = NULL; free(md->current_index); md->current_index = NULL; @@ -85,6 +63,7 @@ error: md->nb_lbs = 0; md->nb_rbs = 0; + d->current_var = NULL; return ret; } @@ -111,11 +90,14 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) scf_scope_push_type(ast->current_block->scope, s); scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)s); - obj->type = s->type; + obj->type = s->type; + obj->js_type = s->type; + scf_logi("obj->w: %s\n", obj->w->text->data); } else { int ret = scf_ast_find_type_type(&s, ast, obj->type); if (ret < 0) return ret; + scf_logi("obj->w: %s\n", obj->w->text->data); } w = md->current_index[md->current_dim].w; @@ -141,6 +123,7 @@ 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; if (r->nb_dimentions > 0) { v->nb_dimentions = r->nb_dimentions; @@ -161,6 +144,9 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r) scf_variable_free(r); r = NULL; + if (v->type >= SCF_STRUCT) + v->js_type = v->type; + scf_scope_push_var(s->scope, v); return 0; } @@ -335,21 +321,16 @@ static int __data_add_obj(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->expr = NULL; md->current_dim++; - if (md->current_dim >= md->current_n) { - - void* p = realloc(md->current_index, sizeof(dfa_index_t) * (md->current_dim + 1)); - if (!p) - return -ENOMEM; - md->current_index = p; - md->current_n = md->current_dim + 1; - } + scf_logd("w: %s, md->current_dim: %d\n", w->text->data, md->current_dim); - int i; - for (i = md->current_dim; i < md->current_n; i++) { + void* p = realloc(md->current_index, sizeof(dfa_index_t) * (md->current_dim + 1)); + if (!p) + return -ENOMEM; + md->current_index = p; + md->current_n = md->current_dim + 1; - md->current_index[i].w = NULL; - md->current_index[i].i = 0; - } + md->current_index[md->current_dim].w = NULL; + md->current_index[md->current_dim].i = 0; return 0; } @@ -441,12 +422,14 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) md->nb_rbs++; md->current_dim--; + scf_logd("md->current_dim: %d, md->current_n: %d\n", md->current_dim, md->current_n); + int i; for (i = md->current_dim + 1; i < md->current_n; i++) { - md->current_index[i].w = NULL; md->current_index[i].i = 0; } + md->current_n--; obj = scf_stack_pop(md->init_objs); @@ -460,8 +443,8 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (md->nb_rbs == md->nb_lbs) { d->expr_local_flag = 0; - scf_logi("-----------\n\n"); - + scf_logi("----------- type: %d, nb_pointers: %d\n\n", d->current_var->type, d->current_var->nb_pointers); +#if 0 d->current_var->type = obj->type; d->current_var->size = obj->size; d->current_var->data_size = obj->data_size; @@ -469,7 +452,13 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (_do_data_init(dfa, words, d) < 0) return SCF_DFA_ERROR; +#else + d->current_var->js_type = obj->type; + ret = _do_data_init(parse->ast, d, obj); + if (ret < 0) + return ret; +#endif scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_comma"); } else { w = md->current_index[md->current_dim].w; @@ -527,23 +516,20 @@ static int _data_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) md->current_index[i].i = 0; } + md->current_n--; + scf_stack_pop(md->init_objs); if (md->init_objs->size <= 0) { d->expr_local_flag = 0; - d->current_var->type = obj->type; - d->current_var->size = obj->size; - d->current_var->data_size = obj->data_size; - d->current_var->nb_pointers = obj->nb_pointers; - - assert(d->current_var->nb_dimentions == obj->nb_dimentions); + scf_logi("----------- type: %d, nb_pointers: %d\n\n", d->current_var->type, d->current_var->nb_pointers); - for (i = 0; i < obj->nb_dimentions; i++) - d->current_var->dimentions[i].num = obj->dimentions[i].num; + d->current_var->js_type = obj->type; - if (_do_data_init(dfa, words, d) < 0) - return SCF_DFA_ERROR; + ret = _do_data_init(parse->ast, d, obj); + if (ret < 0) + return ret; scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_rs"); scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_comma"); diff --git a/js/parse/scf_dfa_parse.c b/js/parse/scf_dfa_parse.c index 495c411..2654cee 100644 --- a/js/parse/scf_dfa_parse.c +++ b/js/parse/scf_dfa_parse.c @@ -23,6 +23,7 @@ extern scf_dfa_module_t dfa_module_type; extern scf_dfa_module_t dfa_module_var; extern scf_dfa_module_t dfa_module_function; +extern scf_dfa_module_t dfa_module_function_js; extern scf_dfa_module_t dfa_module_operator; extern scf_dfa_module_t dfa_module_if; @@ -59,6 +60,7 @@ scf_dfa_module_t* dfa_modules[] = &dfa_module_enum, &dfa_module_union, &dfa_module_class, + &dfa_module_function_js, &dfa_module_type, diff --git a/js/parse/scf_dfa_util.h b/js/parse/scf_dfa_util.h index 46801e7..84e0733 100644 --- a/js/parse/scf_dfa_util.h +++ b/js/parse/scf_dfa_util.h @@ -326,4 +326,11 @@ static inline int scf_dfa_is_var(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_KEY_VAR == w->type; } +static inline int scf_dfa_is_func(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_FUNC == w->type; +} + #endif diff --git a/js/parse/scf_dfa_var.c b/js/parse/scf_dfa_var.c index 91b88fa..45b7608 100644 --- a/js/parse/scf_dfa_var.c +++ b/js/parse/scf_dfa_var.c @@ -120,6 +120,13 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) return SCF_DFA_ERROR; } + if (SCF_VAR_VAR == id0->type->type) { + id0->nb_pointers = 1; + + if (scf_ast_find_type(&id0->type, parse->ast, "Object") < 0) + return SCF_DFA_ERROR; + } + v = SCF_VAR_ALLOC_BY_TYPE(id->identity, id0->type, id0->const_flag, id0->nb_pointers, id0->func_ptr); if (!v) { scf_loge("alloc var failed\n"); @@ -158,7 +165,6 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, int semi_flag) { scf_parse_t* parse = dfa->priv; - scf_variable_t* r = NULL; scf_lex_word_t* w = words->data[words->size - 1]; scf_node_t* node0; scf_node_t* node1; @@ -171,21 +177,6 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, in assert(d->current_var); - if (SCF_VAR_VAR == d->current_var->type) { - if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) { - scf_loge("\n"); - goto error; - } - - d->current_var->type = r->type; - d->current_var->size = r->size; - d->current_var->data_size = r->data_size; - d->current_var->nb_pointers = r->nb_pointers; - } - - scf_variable_free(r); - r = NULL; - node0 = scf_node_alloc(w, SCF_OP_ASSIGN, NULL); if (!node0) goto error; diff --git a/js/parse/scf_parse.c b/js/parse/scf_parse.c index 6a6d0af..01f76ec 100644 --- a/js/parse/scf_parse.c +++ b/js/parse/scf_parse.c @@ -1902,7 +1902,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions) } assert(scf_list_empty(&h)); - scf_basic_block_print_list(&f->basic_block_list_head); +// scf_basic_block_print_list(&f->basic_block_list_head); } int ret = scf_optimize(parse->ast, functions); diff --git a/js/parse/scf_parse.h b/js/parse/scf_parse.h index 5b45bb4..aa89b4c 100644 --- a/js/parse/scf_parse.h +++ b/js/parse/scf_parse.h @@ -132,4 +132,15 @@ int scf_parse_link(const char* exec, const char* obj, const char* libjs, const c int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec); int _find_function (scf_node_t* node, void* arg, scf_vector_t* vec); +static inline int dfa_index_same(dfa_index_t* di, dfa_index_t* di2) +{ + if (di->w) { + if (di2->w && !strcmp(di->w->text->data, di2->w->text->data)) + return 1; + } else { + if (!di2->w && di->i >= 0 && di->i == di2->i) + return 1; + } + return 0; +} #endif diff --git a/js/parse/scf_struct_array.c b/js/parse/scf_struct_array.c index 8e8c720..4c16cdf 100644 --- a/js/parse/scf_struct_array.c +++ b/js/parse/scf_struct_array.c @@ -369,3 +369,330 @@ int scf_struct_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_ return 0; } + +static int __object_create(scf_expr_t* e, scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, int n_members, scf_type_t* Object, + scf_vector_t* init_exprs, + scf_vector_t* init_pos) +{ + scf_variable_t* v; + scf_block_t* b; + scf_type_t* pt = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR); + scf_node_t* create; + scf_node_t* assign; + scf_node_t* node; + + assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL); + if (!assign) + return -ENOMEM; + + int ret = scf_expr_add_node(e, assign); + if (ret < 0) { + scf_node_free(assign); + return ret; + } + + b = scf_block_alloc_cstr("multi_rets"); + if (!b) + return -ENOMEM; + + ret = scf_node_add_child((scf_node_t*)b, assign->nodes[0]); + if (ret < 0) + return ret; + assign->nodes[0] = (scf_node_t*)b; + b->node.parent = assign; + + create = scf_node_alloc(w, SCF_OP_CREATE, NULL); + if (!create) + return -ENOMEM; + + // add construct() for obj + v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL); + if (!v) { + scf_node_free(create); + return -ENOMEM; + } + v->const_literal_flag = 1; + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) { + scf_node_free(create); + return -ENOMEM; + } + + ret = scf_node_add_child(create, node); + if (ret < 0) { + scf_node_free(node); + scf_node_free(create); + return ret; + } + + // add obj name + ret = scf_ast_add_const_str(ast, create, var->w); + if (ret < 0) { + scf_node_free(create); + return ret; + } + + // add obj members + ret = scf_ast_add_const_var(ast, create, SCF_VAR_INT, n_members); + if (ret < 0) { + scf_node_free(create); + return ret; + } + + if (0 == n_members && init_exprs && init_pos) { + dfa_init_expr_t* ie; + dfa_index_t* di; + int i; + int j; + + for (i = 0; i < init_exprs->size; i++) { + ie = init_exprs->data[i]; + + if (ie->n != init_pos->size) { + scf_logw("var: %s, ie->n: %d, init_pos->size: %d\n", var->w->text->data, ie->n, init_pos->size); + continue; + } + + for (j = 0; j < init_pos->size; j++) { + di = init_pos->data[j]; + + if (!dfa_index_same(&ie->index[j], di)) { + scf_logw("var: %s\n", var->w->text->data); + break; + } + } + + if (j >= init_pos->size) { + assert(ie->expr); + + scf_logi("var: %s\n", var->w->text->data); + + ret = scf_node_add_child(create, ie->expr); + if (ret < 0) { + scf_node_free(create); + return ret; + } + + ie->expr = NULL; + assert(0 == scf_vector_del(init_exprs, ie)); + free(ie); + ie = NULL; + break; + } + } + } + + ret = scf_expr_add_node(e, create); + if (ret < 0) { + scf_node_free(create); + return ret; + } + return 0; +} + +#define OBJ_EXPR_ADD_NODE(_e, _node) \ + do { \ + int ret = scf_expr_add_node(_e, _node); \ + if (ret < 0) { \ + scf_node_free(_node); \ + scf_expr_free(_e); \ + return ret; \ + } \ + } while (0) + +static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_type_t* Object, + scf_variable_t* members, + int array_dim, + scf_vector_t* init_exprs, + scf_vector_t* init_pos) +{ + scf_type_t* t = NULL; + scf_expr_t* e2; + scf_expr_t* e3; + scf_node_t* node; + + int ret = scf_ast_find_type_type(&t, ast, obj->type); + if (ret < 0) + return ret; + + e2 = scf_expr_clone(e); + if (!e2) { + scf_expr_free(e); + return -ENOMEM; + } + + if (array_dim < obj->nb_dimentions) { + scf_logi("var: %s, array_dim: %d, nb_dimentions: %d, num: %d\n", + var->w->text->data, array_dim, obj->nb_dimentions, + obj->dimentions[array_dim].num); + + ret = __object_create(e, ast, w, var, obj->dimentions[array_dim].num, Object, NULL, NULL); + + } else if (t->type >= SCF_STRUCT) { + scf_logd("var: %s\n", var->w->text->data); + ret = __object_create(e, ast, w, var, t->scope->vars->size, Object, NULL, NULL); + } else { + scf_logd("var: %s\n", var->w->text->data); + ret = __object_create(e, ast, w, var, 0, Object, init_exprs, init_pos); + } + if (ret < 0) { + scf_expr_free(e); + scf_expr_free(e2); + return ret; + } + + ret = scf_node_add_child((scf_node_t*)ast->current_block, e); + if (ret < 0) { + scf_expr_free(e); + scf_expr_free(e2); + return ret; + } + e = NULL; + + if (t->type >= SCF_STRUCT || array_dim < obj->nb_dimentions) { + // add -> + node = scf_node_alloc(w, SCF_OP_POINTER, NULL); + if (!node) { + scf_expr_free(e2); + return -ENOMEM; + } + OBJ_EXPR_ADD_NODE(e2, node); + + // add members + node = scf_node_alloc(NULL, members->type, members); + if (!node) { + scf_expr_free(e2); + return -ENOMEM; + } + OBJ_EXPR_ADD_NODE(e2, node); + + int i; + int n; + if (array_dim < obj->nb_dimentions) + n = obj->dimentions[array_dim].num; + else + n = t->scope->vars->size; + + for (i = 0; i < n; i++) { + e3 = scf_expr_clone(e2); + if (!e3) { + scf_expr_free(e2); + return -ENOMEM; + } + + node = scf_node_alloc(w, SCF_OP_ARRAY_INDEX, NULL); + if (!node) { + scf_expr_free(e3); + scf_expr_free(e2); + return -ENOMEM; + } + + ret = scf_expr_add_node(e3, node); + if (ret < 0) { + scf_node_free(node); + scf_expr_free(e3); + scf_expr_free(e2); + return ret; + } + + scf_variable_t* v = NULL; + + if (array_dim < obj->nb_dimentions) + ret = scf_ast_add_const_var(ast, node, SCF_VAR_INT, i); + else { + v = t->scope->vars->data[i]; + ret = scf_ast_add_const_var(ast, node, SCF_VAR_INT, v->js_index); + } + if (ret < 0) { + scf_expr_free(e3); + scf_expr_free(e2); + return ret; + } + + dfa_index_t* di = calloc(1, sizeof(dfa_index_t)); + if (!di) { + scf_expr_free(e3); + scf_expr_free(e2); + return -ENOMEM; + } + + ret = scf_vector_add(init_pos, di); + if (ret < 0) { + free(di); + scf_expr_free(e3); + scf_expr_free(e2); + return ret; + } + + if (v) { + di->w = v->w; + di->i = -1; + scf_logi("i: %d, n: %d\n", i, n); + + ret = __object_init(ast, e3, w, v, v, Object, members, array_dim, init_exprs, init_pos); + } else { + di->w = NULL; + di->i = i; + scf_logi("i: %d, n: %d\n", i, n); + + ret = __object_init(ast, e3, w, var, obj, Object, members, array_dim + 1, init_exprs, init_pos); + } + if (ret < 0) { + scf_expr_free(e2); + return ret; + } + + assert(0 == scf_vector_del(init_pos, di)); + free(di); + di = NULL; + + scf_logi("init_pos->size: %d\n", init_pos->size); + } + } + + scf_expr_free(e2); + e2 = NULL; + return 0; +} + +int scf_object_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_vector_t* init_exprs) +{ + scf_vector_t* init_pos; + scf_variable_t* members = NULL; + scf_type_t* Object = NULL; + scf_node_t* node; + scf_expr_t* e; + + int ret = scf_ast_find_type(&Object, ast, "Object"); + if (ret < 0) + return ret; + + members = scf_scope_find_variable(Object->scope, "members"); + if (!members) + return -1; + + e = scf_expr_alloc(); + if (!e) + return -ENOMEM; + + node = scf_node_alloc(NULL, var->type, var); + if (!node) { + scf_expr_free(e); + return -ENOMEM; + } + OBJ_EXPR_ADD_NODE(e, node); + + init_pos = scf_vector_alloc(); + if (!init_pos) { + scf_expr_free(e); + return -ENOMEM; + } + + ret = __object_init(ast, e, w, var, obj, Object, members, 0, init_exprs, init_pos); + + scf_vector_free(init_pos); + return ret; +} diff --git a/ui/Makefile b/ui/Makefile index acc5835..fade274 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -198,6 +198,7 @@ CFILES += ../js/parse/scf_dfa_type.c CFILES += ../js/parse/scf_dfa_identity.c CFILES += ../js/parse/scf_dfa_function.c +CFILES += ../js/parse/scf_dfa_function_js.c CFILES += ../js/parse/scf_dfa_operator.c CFILES += ../js/parse/scf_dfa_var.c