From: yu.dongliang <18588496441@163.com> Date: Thu, 18 Jun 2026 12:02:24 +0000 (+0800) Subject: 1, css: support counter, X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=ae15dd5490fcf3e5185f5966da33dc061a1f67e7;p=abc.git 1, css: support counter, 2, js: support setTimeout() with variable args, 3, fix: some BUGS in native/x64. --- diff --git a/examples/js2.html b/examples/js_func.html similarity index 100% rename from examples/js2.html rename to examples/js_func.html diff --git a/examples/js_obj_func.html b/examples/js_obj_func.html new file mode 100644 index 0000000..0c3cb9b --- /dev/null +++ b/examples/js_obj_func.html @@ -0,0 +1,22 @@ + + + + +

含有javascript的页面

+ +

含有js的页面

+ + + + + diff --git a/examples/js_setTimeout.html b/examples/js_setTimeout.html new file mode 100644 index 0000000..83b1ea6 --- /dev/null +++ b/examples/js_setTimeout.html @@ -0,0 +1,21 @@ + + + + +菜鸟教程(runoob.com) + + + +

回调函数等待 3 秒后执行。

+

+ + + + + diff --git a/examples/js.html b/examples/js_switch.html similarity index 100% rename from examples/js.html rename to examples/js_switch.html diff --git a/html/Makefile b/html/Makefile index bbb8c73..b11e664 100644 --- a/html/Makefile +++ b/html/Makefile @@ -20,8 +20,9 @@ CFILES += ../js/lex/scf_lex.c CFILES += ../js/lex/scf_lex_util.c CFILES += ../js/parse/main.c -CFILES += ../js/parse/scf_parse_util.c CFILES += ../js/parse/scf_parse.c +CFILES += ../js/parse/scf_parse_util.c +CFILES += ../js/parse/scf_symtab.c CFILES += ../js/parse/scf_operator_handler_semantic.c CFILES += ../js/parse/scf_operator_handler_expr.c CFILES += ../js/parse/scf_operator_handler_const.c diff --git a/html/abc_css.c b/html/abc_css.c index 16112df..8e25c92 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -1683,24 +1683,30 @@ int abc_css_clear(abc_obj_t* obj, int pse_start, int pse_end) { abc_attr_t* attr; int i; + int n = 0; for (i = pse_start; i <= pse_end; i++) { attr = abc_obj_get_attr(obj, i); - if (attr) + if (!attr) + continue; + + if (attr->flags & ABC_CSS_FLAG_ON) { attr->flags &= ~ABC_CSS_FLAG_ON; + n++; + } } - return 0; + return n; } int abc_css_active(abc_obj_t* obj, int pse) { abc_attr_t* attr = abc_obj_get_attr(obj, pse); - if (attr) { - attr->flags |= ABC_CSS_FLAG_ON; - return 1; - } - return 0; + if (!attr || (attr->flags & ABC_CSS_FLAG_ON)) + return 0; + + attr->flags |= ABC_CSS_FLAG_ON; + return 1; } diff --git a/html/abc_css_counter.c b/html/abc_css_counter.c index a91985a..67431a0 100644 --- a/html/abc_css_counter.c +++ b/html/abc_css_counter.c @@ -1,11 +1,48 @@ #include"abc_html.h" +static int __cmp_ref_counter(const void* counter, const void* ref) +{ + const ref_count_t* r = ref; + + if (r->counter == counter) + return 0; + return -1; +} + +static int __sort_ref_counter(const void* v0, const void* v1) +{ + const ref_count_t* r0 = *(const ref_count_t**)v0; + const ref_count_t* r1 = *(const ref_count_t**)v1; + + if (r0->layer < r1->layer) + return -1; + + else if (r0->layer > r1->layer) + return 1; + return 0; +} + +css_count_t* css_count_alloc(const char* name, size_t len) +{ + css_count_t* cnt = calloc(1, sizeof(css_count_t)); + if (!cnt) + return NULL; + + cnt->name = scf_string_cstr_len(name, len); + if (!cnt->name) { + free(cnt); + return NULL; + } + + return cnt; +} + int abc_css_counter_reset(abc_obj_t* obj, abc_attr_t* attr) { if (!obj || !attr || !attr->value || 0 == attr->value->len) return -EINVAL; - css_count_t* cnt = obj->counter_list; + css_count_t* cnt = obj->reset_counters; while (cnt) { if (!scf_string_cmp(cnt->name, attr->value)) break; @@ -13,26 +50,100 @@ int abc_css_counter_reset(abc_obj_t* obj, abc_attr_t* attr) } if (!cnt) { - cnt = calloc(1, sizeof(css_count_t)); + cnt = css_count_alloc(attr->value->data, attr->value->len); if (!cnt) return -ENOMEM; - cnt->name = scf_string_clone(attr->value); - if (!cnt->name) { - free(cnt); - return -ENOMEM; + cnt->next = obj->reset_counters; + obj->reset_counters = cnt; + + } else if (cnt->objs) { + abc_obj_t* tmp; + int i; + + for (i = 0; i < cnt->objs->size; i++) { + tmp = cnt->objs->data[i]; + + if (tmp->content) { + scf_string_free(tmp->content); + tmp->content = NULL; + } + + ref_count_t* r = scf_vector_find_cmp(tmp->used_counters, cnt, __cmp_ref_counter); + if (r) + assert(0 == scf_vector_del(tmp->used_counters, r)); + + tmp->css_used = 0; + + scf_logw("cnt: %p, i: %d, obj: %p, css_used: %u\n", cnt, i, tmp, tmp->css_used); } - cnt->next = obj->counter_list; - obj->counter_list = cnt; + scf_vector_free(cnt->objs); + cnt->objs = NULL; } cnt->value = 0; - scf_logd("cnt->name: %s, value: %ld\n", cnt->name->data, cnt->value); + scf_logd("cnt->name: %s, value: %d\n", cnt->name->data, cnt->value); return 0; } +static int __css_ref_counter(abc_obj_t* obj, css_count_t* cnt, int layer) +{ + if (!obj->used_counters) { + obj ->used_counters = scf_vector_alloc(); + + if (!obj->used_counters) + return -ENOMEM; + } + + ref_count_t* r = scf_vector_find_cmp(obj->used_counters, cnt, __cmp_ref_counter); + + if (!r) { + r = calloc(1, sizeof(ref_count_t)); + if (!r) + return -ENOMEM; + + int ret = scf_vector_add(obj->used_counters, r); + if (ret < 0) { + free(r); + return ret; + } + + r->counter = cnt; + r->value = cnt->value; + } + + r->layer = layer; + + scf_logi("#0 r: %p, cnt: %p, value: %d, layer: %d, obj: %p\n", r, cnt, cnt->value, layer, obj); + return 0; +} + +static int __css_inc_counter(abc_obj_t* obj, css_count_t* cnt) +{ + if (!cnt->objs) { + cnt ->objs = scf_vector_alloc(); + + if (!cnt->objs) + return -ENOMEM; + } + + if (scf_vector_find(cnt->objs, obj)) + return 0; + + int ret = scf_vector_add(cnt->objs, obj); + if (ret < 0) + return ret; + + cnt->value++; + + printf("\n"); + scf_logw("## cnt: %p, value: %d, obj: %p\n", cnt, cnt->value, obj); + + return __css_ref_counter(obj, cnt, 0); +} + int abc_css_counter_inc(abc_obj_t* obj, abc_attr_t* attr) { if (!obj || !attr || !attr->value || 0 == attr->value->len) @@ -43,52 +154,44 @@ int abc_css_counter_inc(abc_obj_t* obj, abc_attr_t* attr) for (parent = obj->parent; parent; parent = parent->parent) { - for (cnt = parent->counter_list; cnt; cnt = cnt->next) + for (cnt = parent->reset_counters; cnt; cnt = cnt->next) { - if (!scf_string_cmp(cnt->name, attr->value)) { - cnt->value++; - return 0; - } + if (scf_string_cmp(cnt->name, attr->value)) + continue; + + return __css_inc_counter(obj, cnt); } } return -EINVAL; } -static int __css_recursive_counter(scf_string_t* content, abc_obj_t* parent, const char* name, int len, const char* split, int split_len, int all_flag) +static int __css_use_counter(abc_obj_t* obj, css_count_t* cnt, int layer) { - if (all_flag && parent->parent) { + if (!cnt->objs) { + cnt ->objs = scf_vector_alloc(); - int ret = __css_recursive_counter(content, parent->parent, name, len, split, split_len, all_flag); - if (ret < 0) - return ret; + if (!cnt->objs) + return -ENOMEM; } - css_count_t* cnt; + ref_count_t* r; - for (cnt = parent->counter_list; cnt; cnt = cnt->next) { + if (scf_vector_find(cnt->objs, obj)) { + r = scf_vector_find_cmp(obj->used_counters, cnt, __cmp_ref_counter); + assert(r); - if (cnt->name->len == len && !memcmp(cnt->name->data, name, len)) { - uint8_t buf[128]; + r->layer = layer; - int n = snprintf(buf, sizeof(buf) - 1, "%ld", cnt->value); - - int ret = scf_string_cat_cstr_len(content, buf, n); - if (ret < 0) - return ret; - - if (split && split_len > 0) { - - ret = scf_string_cat_cstr_len(content, split, split_len); - if (ret < 0) - return ret; - } - - break; - } + scf_logi("#1 r: %p, cnt: %p, value: %d, layer: %d, obj: %p\n", r, r->counter, r->value, r->layer, obj); + return 0; } - return 0; + int ret = scf_vector_add(cnt->objs, obj); + if (ret < 0) + return ret; + + return __css_ref_counter(obj, cnt, layer); } static int __css_counter(abc_obj_t* obj, abc_attr_t* attr, int lp, int comma, int rp, int all_flag) @@ -115,9 +218,58 @@ static int __css_counter(abc_obj_t* obj, abc_attr_t* attr, int lp, int comma, in } } - int split_len = (int)(split2 - split); + abc_obj_t* parent; + css_count_t* cnt; + ref_count_t* r; + + int layer = 0; + int ret; + + for (parent = obj->parent; parent; parent = parent->parent) { + + for (cnt = parent->reset_counters; cnt; cnt = cnt->next) { + + if (cnt->name->len == len && !memcmp(cnt->name->data, name, len)) { + + ret = __css_use_counter(obj, cnt, layer); + if (ret < 0) + return ret; + + if (!all_flag) + goto found; + + layer++; + break; + } + } + } + +found: + if (!obj->used_counters) + return 0; + + scf_vector_qsort(obj->used_counters, __sort_ref_counter); - return __css_recursive_counter(obj->content, obj->parent, name, len, split, split_len, all_flag); + for (i = obj->used_counters->size - 1; i >= 0; i--) { + r = obj->used_counters->data[i]; + + scf_logi("#2 i: %d, r: %p, cnt: %p, value: %d, layer: %d, obj: %p\n", i, r, r->counter, r->value, r->layer, obj); + + uint8_t buf[128]; + int n = snprintf(buf, sizeof(buf) - 1, "%d", r->value); + + ret = scf_string_cat_cstr_len(obj->content, buf, n); + if (ret < 0) + return ret; + + if (split && split2 > split) { + ret = scf_string_cat_cstr_len(obj->content, split, (size_t)(split2 - split)); + if (ret < 0) + return ret; + } + } + + return 0; } int abc_css_content(abc_obj_t* obj, abc_attr_t* attr) diff --git a/html/abc_html.c b/html/abc_html.c index 37946b0..47ed2d1 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -902,6 +902,8 @@ int abc_html_open(abc_html_t** pp, const char* path) if (!html) return -ENOMEM; + scf_rbtree_init(&html->timers); + html->io.proto = io->proto; html->io.priv = NULL; html->io.open = io->open; @@ -1381,10 +1383,6 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) if (ret < 0) return ret; - ret = __html_js_path(&obj->js_entry, obj, NULL, NULL, 0); - if (ret < 0) - return ret; - if (!html->js) { ret = scf_parse_open(&html->js); if (ret < 0) @@ -1422,12 +1420,13 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj) #if 1 assert(!html->io.tmp_list_js); - void* so = dlopen(obj->js_so->data, RTLD_LAZY); - void (*f)() = dlsym(so, "__js_main"); + obj->js_so_handle = dlopen(obj->js_so->data, RTLD_LAZY); + void (*f)(void*) = dlsym (obj->js_so_handle, "__js_main"); + + html->js_auto_freep = dlsym(obj->js_so_handle, "scf__auto_freep_array"); + html->js_release = dlsym(obj->js_so_handle, "Object___release_Object1"); f(html); - dlclose(so); - so = NULL; #endif abc_char_t* c; while ( html->io.tmp_list_js) { @@ -1560,11 +1559,13 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) } else ret = __html_parse_text(html, obj); + int err; switch (obj->type) { case ABC_HTML_SCRIPT: - if (__html_run_js(html, obj) < 0) - return -1; + err = __html_run_js(html, obj); + if (err < 0) + return err; break; case ABC_HTML_LINK: @@ -1576,19 +1577,22 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) break; case ABC_HTML_STYLE: - if (abc_css_parse(obj) < 0) - return -1; + err = abc_css_parse(obj); + if (err < 0) + return err; - if (abc_css_merge(html, obj) < 0) - return -1; + err = abc_css_merge(html, obj); + if (err < 0) + return err; break; case ABC_HTML_VIDEO: html->has_video = 1; case ABC_HTML_AUDIO: - if (__html_add_controls(obj) < 0) - return -1; + err = __html_add_controls(obj); + if (err < 0) + return err; default: break; }; diff --git a/html/abc_html.h b/html/abc_html.h index ff5a675..e41dae9 100644 --- a/html/abc_html.h +++ b/html/abc_html.h @@ -4,8 +4,10 @@ #include"abc_io.h" #include"abc_obj.h" #include"scf_parse.h" +#include"scf_rbtree.h" -typedef struct abc_html_s abc_html_t; +typedef struct abc_html_s abc_html_t; +typedef struct abc_timer_s abc_timer_t; typedef struct { abc_str_t* names; @@ -30,10 +32,23 @@ typedef struct { #define abc_number_of(__array) (sizeof(__array) / sizeof(__array[0])) +struct abc_timer_s +{ + scf_rbtree_node_t node; + int64_t usec; + + void (*func)(int argc, void* argv[]); + + int argc; + void* argv[0]; +}; + struct abc_html_s { scf_list_t list; + scf_rbtree_t timers; + abc_obj_t* root; abc_obj_t* current; @@ -46,6 +61,8 @@ struct abc_html_s int pos; scf_parse_t* js; + void (*js_auto_freep)(void** pp, int n_pointers, void (*js_release)(void* jobj)); + void (*js_release )(void* jobj); uint8_t has_video:1; }; @@ -90,4 +107,13 @@ int abc_css_counter_reset(abc_obj_t* obj, abc_attr_t* attr); int abc_css_counter_inc (abc_obj_t* obj, abc_attr_t* attr); int abc_css_content (abc_obj_t* obj, abc_attr_t* attr); + +static inline int abc_timer_cmp(scf_rbtree_node_t* node0, void* data) +{ + abc_timer_t* t0 = (abc_timer_t*)node0; + abc_timer_t* t1 = (abc_timer_t*)data; + + return t0->usec - t1->usec; +} + #endif diff --git a/html/abc_obj.c b/html/abc_obj.c index 60ca2e1..e93a111 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -44,8 +44,8 @@ void abc_obj_free(abc_obj_t* obj) if (obj->js_so) scf_string_free(obj->js_so); - if (obj->js_entry) - scf_string_free(obj->js_entry); + if (obj->js_so_handle) + dlclose(obj->js_so_handle); #ifndef ABC_HTML_TEST if (obj->av_filter) diff --git a/html/abc_obj.h b/html/abc_obj.h index a493295..e947a40 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -9,11 +9,12 @@ typedef struct abc_obj_s abc_obj_t; typedef struct abc_attr_s abc_attr_t; typedef struct abc_text_s abc_text_t; - typedef struct abc_css_s abc_css_t; + typedef struct css_rule_s css_rule_t; typedef struct css_hash_s css_hash_t; typedef struct css_count_s css_count_t; +typedef struct ref_count_s ref_count_t; enum abc_objs { @@ -266,7 +267,16 @@ struct css_count_s css_count_t* next; scf_string_t* name; - intptr_t value; + int value; + + scf_vector_t* objs; +}; + +struct ref_count_s +{ + css_count_t* counter; + int value; + int layer; }; #define ABC_HTML_FLAG_OPEN 0 @@ -368,7 +378,8 @@ struct abc_obj_s abc_text_t* text_splits; // for layout, split a long text to multi-lines and save every-line here abc_io_t io; - css_count_t* counter_list; + css_count_t* reset_counters; + scf_vector_t* used_counters; scf_string_t* content; int border_top; @@ -438,12 +449,12 @@ struct abc_obj_s scf_string_t* js_path; scf_string_t* js_obj; scf_string_t* js_so; - scf_string_t* js_entry; + void* js_so_handle; uint32_t clicked:1; uint32_t visited:1; - uint32_t css_use:1; + uint32_t css_used:1; uint32_t w_set:1; uint32_t h_set:1; diff --git a/html/main.c b/html/main.c index 561c805..35e3788 100644 --- a/html/main.c +++ b/html/main.c @@ -10,8 +10,8 @@ void abc_css_recursive_use(abc_html_t* html, abc_obj_t* obj) if (!obj) return; - if (!obj->css_use && ABC_CORE_TEXT != obj->type) { - obj->css_use = 1; + if (!obj->css_used && ABC_CORE_TEXT != obj->type) { + obj->css_used = 1; abc_css_use(html, obj); } diff --git a/js/Makefile b/js/Makefile index b4d00fb..b8c56f8 100644 --- a/js/Makefile +++ b/js/Makefile @@ -1,4 +1,8 @@ CFILES += abc_libjs.c +CFILES += abc_libjs_asm.S +CFILES += ../js/util/scf_string.c +CFILES += ../js/util/scf_rbtree.c +CFILES += ../js/lib/x64/scf_atomic.o CFLAGS += -g -DABC_HTML_TEST -D_GNU_SOURCE CFLAGS += -I../ffmpeg diff --git a/js/abc_libjs.c b/js/abc_libjs.c index f8a1312..3e28fdc 100644 --- a/js/abc_libjs.c +++ b/js/abc_libjs.c @@ -2,6 +2,9 @@ #define PCRE2_CODE_UNIT_WIDTH 8 #include +void asm_Object_ref(void* obj); +void asm_timer_func(int argc, void* argv[]); + static char* js_days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; @@ -415,3 +418,81 @@ int abc_pcre2_match(int** __ovector, const char* __subject, const char* __patter *__ovector = outs; return n_outs; } + +static abc_obj_t* __html_getElementById(abc_obj_t* root, const char* id) +{ + if (!root) + return NULL; + + scf_list_t* l; + abc_obj_t* child; + abc_obj_t* obj; + abc_attr_t* attr = abc_obj_get_attr(root, ABC_CSS_ID); + + if (attr && attr->value && attr->value->len > 0 && !strcmp(attr->value->data, id)) + return root; + + for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) { + child = scf_list_data(l, abc_obj_t, list); + + obj = __html_getElementById(child, id); + if (obj) + return obj; + } + + return NULL; +} + +abc_obj_t* abc_html_getElementById(abc_html_t* html, const char* id) +{ + if (!html || !html->root) + return NULL; + + return __html_getElementById(html->root, id); +} + +void abc_html_inner(abc_obj_t* obj, const char* s) +{ + printf("obj: %p, s: %s\n", obj, s); + + scf_string_t* text = scf_string_cstr(s); + if (text) { + if (obj->text) + scf_string_free(obj->text); + + obj->text = text; + } +} + +void abc_html_setTimeout(abc_html_t* html, int argc, void (*func)(abc_html_t* html), int msec, void** argv) +{ + printf("html: %p, func: %p, argc: %d, msec: %d, argv: %p\n", html, func, argc, msec, argv); + + int n = argc; + if (n < 5) + n = 5; + + n = (n + 1) & ~0x1; + + abc_timer_t* timer = calloc(1, sizeof(abc_timer_t) + sizeof(void*) * (2 + n)); + if (!timer) + return; + + timer->usec = gettime() + msec * 1000ll; + timer->func = asm_timer_func; + timer->argc = 2 + n; + timer->argv[0] = func; + timer->argv[1] = html; + + int i; + for (i = 0; i < argc; i++) { + asm_Object_ref(argv[i]); + + printf("argv[%d]: %p\n", i, argv[i]); + + timer->argv[2 + i] = argv[i]; + } + +// timer->func(timer->argc, timer->argv); + scf_rbtree_insert(&html->timers, (scf_rbtree_node_t*)timer, abc_timer_cmp); +} diff --git a/js/abc_libjs.so b/js/abc_libjs.so index b5d7e51..e9b31a8 100755 Binary files a/js/abc_libjs.so and b/js/abc_libjs.so differ diff --git a/js/abc_libjs_asm.S b/js/abc_libjs_asm.S new file mode 100644 index 0000000..a0d86ce --- /dev/null +++ b/js/abc_libjs_asm.S @@ -0,0 +1,67 @@ +.global Object_setTimeout_Object1_i_fp1_i, abc_html_setTimeout +.global asm_Object_ref, asm_timer_func + +asm_Object_ref: + lock incq -16(%rdi) + ret + +# asm for Object.setTimeout() +Object_setTimeout_Object1_i_fp1_i: +#rsp + ... +#rsp + 16, argv[3] +#rsp + 8, argv[2] +#rsp + 0, ret + +#rdi, this +#rsi, argc +#rdx, func +#rcx, msec +#r8, argv[0] +#r9, argv[1] + + pop %rax + push %r9 + push %r8 + mov %rsp, %r8 + push %rax + push %rax + + call abc_html_setTimeout + + pop %rax + pop %rax + pop %r8 + pop %r9 + + push %rax + ret + +asm_timer_func: +#rdi, argc +#rsi, argv + + push %rbp + push %rbp + mov %rsp, %rbp + + mov %rdi, %rcx + shl $3, %rdi + sub %rdi, %rsp + mov %rsp, %rdi + cld + rep movsq + + pop %rax + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %r8 + pop %r9 + + call *%rax + + mov %rbp, %rsp + pop %rbp + pop %rbp + ret diff --git a/js/core/scf_3ac.c b/js/core/scf_3ac.c index 0e28716..07401bb 100644 --- a/js/core/scf_3ac.c +++ b/js/core/scf_3ac.c @@ -384,7 +384,7 @@ scf_3ac_code_t* scf_3ac_alloc_by_dst(int op_type, scf_dag_node_t* dst) return c; } -scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err) +scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_lex_word_t* label) { scf_3ac_operand_t* dst; scf_3ac_code_t* c; @@ -394,9 +394,9 @@ scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err) return NULL; c->op = scf_3ac_find_operator(type); - c->label = l; + c->label = label; - c->dsts = scf_vector_alloc(); + c->dsts = scf_vector_alloc(); if (!c->dsts) { scf_3ac_code_free(c); return NULL; diff --git a/js/core/scf_3ac.h b/js/core/scf_3ac.h index 947bff2..7f45cb6 100644 --- a/js/core/scf_3ac.h +++ b/js/core/scf_3ac.h @@ -32,7 +32,7 @@ struct scf_3ac_code_s { scf_vector_t* dsts; // dst operands, maybe only used for function return value scf_vector_t* srcs; // src operands, usually 2 - scf_label_t* label; // only for 'goto' to find the destination to go + scf_lex_word_t* label; // only for 'goto' to find the destination scf_3ac_code_t* origin; @@ -60,7 +60,7 @@ void scf_3ac_code_print(scf_3ac_code_t* c, scf_list_t* sentinel); void scf_3ac_list_print(scf_list_t* h); -scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err); +scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_lex_word_t* label); scf_3ac_operator_t* scf_3ac_find_operator(const int type); diff --git a/js/core/scf_ast.c b/js/core/scf_ast.c index aa22dff..daf19fd 100644 --- a/js/core/scf_ast.c +++ b/js/core/scf_ast.c @@ -158,7 +158,7 @@ static int _find_type_by_type(scf_node_t* node, void* arg, scf_vector_t* vec) scf_type_t* t = (scf_type_t*)node; - if (t->type == (intptr_t)arg) { + if (t->node.type == (intptr_t)arg) { int ret = scf_vector_add(vec, t); if (ret < 0) @@ -486,9 +486,11 @@ int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const ui int scf_function_signature(scf_ast_t* ast, scf_function_t* f) { - scf_string_t* s; - scf_type_t* t = (scf_type_t*)f->node.parent; - + scf_string_t* s; + scf_type_t* t = (scf_type_t*)f->node.parent; + scf_type_t* tv; + scf_variable_t* v; + scf_operator_t* op; int ret; int i; @@ -509,8 +511,7 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) } if (f->op_type >= 0) { - scf_operator_t* op = scf_find_base_operator_by_type(f->op_type); - + op = scf_find_base_operator_by_type(f->op_type); if (!op->signature) goto error; @@ -532,12 +533,11 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) if (f->argv) { for (i = 0; i < f->argv->size; i++) { - scf_variable_t* v = f->argv->data[i]; - scf_type_t* t_v = NULL; + v = f->argv->data[i]; - t_v = scf_block_find_type_type((scf_block_t*)t, v->type); - if (!t_v) { - ret = scf_ast_find_global_type_type(&t_v, ast, v->type); + tv = scf_block_find_type_type((scf_block_t*)t, v->type); + if (!tv) { + ret = scf_ast_find_global_type_type(&tv, ast, v->type); if (ret < 0) goto error; } @@ -546,13 +546,11 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) if (ret < 0) goto error; - scf_logd("t_v: %p, v->type: %d, v->w->text->data: %s\n", t_v, v->type, v->w->text->data); - - const char* abbrev = scf_type_find_abbrev(t_v->name->data); + const char* abbrev = scf_type_find_abbrev(tv->name->data); if (abbrev) ret = scf_string_cat_cstr(s, abbrev); else - ret = scf_string_cat(s, t_v->name); + ret = scf_string_cat(s, tv->name); if (ret < 0) goto error; @@ -567,16 +565,15 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f) } } - scf_logd("f signature: %s\n", s->data); - if (f->signature) scf_string_free(f->signature); + f->signature = s; return 0; error: scf_string_free(s); - return -1; + return ret; } int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv) @@ -584,7 +581,6 @@ int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector scf_function_t* f; scf_variable_t* v0; scf_variable_t* v1; - int i; int j; @@ -593,9 +589,9 @@ int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector f->score = 0; - for (j = 0; j < argv->size; j++) { - v0 = f->argv->data[j]; - v1 = argv->data[j]; + for (j = 0; j < f->argv->size; j++) { + v0 = f->argv->data[j]; + v1 = argv->data[j]; if (scf_variable_is_struct_pointer(v0)) continue; @@ -619,7 +615,7 @@ int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector } } - if (j < argv->size) + if (j < f->argv->size) assert(0 == scf_vector_del(fvec, f)); // drop invalid function else i++; diff --git a/js/core/scf_basic_block.c b/js/core/scf_basic_block.c index 55a6426..0fc2e60 100644 --- a/js/core/scf_basic_block.c +++ b/js/core/scf_basic_block.c @@ -143,7 +143,7 @@ scf_basic_block_t* scf_basic_block_jcc(scf_basic_block_t* to, scf_function_t* f, if (!bb) return NULL; - c = scf_3ac_jmp_code(jcc, NULL, NULL); + c = scf_3ac_jmp_code(jcc, NULL); if (!c) { scf_basic_block_free(bb); return NULL; diff --git a/js/core/scf_block.h b/js/core/scf_block.h index f405d24..30d3fd0 100644 --- a/js/core/scf_block.h +++ b/js/core/scf_block.h @@ -9,6 +9,8 @@ struct scf_block_s { scf_scope_t* scope; scf_string_t* name; + + scf_lex_t* lex_list; }; @@ -29,4 +31,3 @@ scf_function_t* scf_block_find_function(scf_block_t* b, const char* name); scf_label_t* scf_block_find_label(scf_block_t* b, const char* name); #endif - diff --git a/js/core/scf_calculate.c b/js/core/scf_calculate.c index 2e429c1..6f068ad 100644 --- a/js/core/scf_calculate.c +++ b/js/core/scf_calculate.c @@ -3,6 +3,7 @@ #include"scf_calculate_i32.c" #include"scf_calculate_u32.c" #include"scf_calculate_i64.c" +#include"scf_calculate_u64.c" #include"scf_calculate_float.c" #include"scf_calculate_double.c" @@ -99,6 +100,37 @@ scf_calculate_t base_calculates[] = {"i64", SCF_OP_GE, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_ge}, {"i64", SCF_OP_LE, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_le}, + // u64 + {"u64", SCF_OP_ADD, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_add}, + {"u64", SCF_OP_SUB, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_sub}, + {"u64", SCF_OP_MUL, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_mul}, + {"u64", SCF_OP_DIV, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_div}, + {"u64", SCF_OP_MOD, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_mod}, + + {"u64", SCF_OP_SHL, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_shl}, + {"u64", SCF_OP_SHR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_shr}, + + {"u64", SCF_OP_INC, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_inc}, + {"u64", SCF_OP_DEC, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_dec}, + + {"u64", SCF_OP_NEG, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_neg}, + + {"u64", SCF_OP_BIT_AND, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_and}, + {"u64", SCF_OP_BIT_OR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_or}, + {"u64", SCF_OP_BIT_NOT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_not}, + + {"u64", SCF_OP_LOGIC_AND, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_and}, + {"u64", SCF_OP_LOGIC_OR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_or}, + {"u64", SCF_OP_LOGIC_NOT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_not}, + + {"u64", SCF_OP_GT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_gt}, + {"u64", SCF_OP_LT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_lt}, + + {"u64", SCF_OP_EQ, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_eq}, + {"u64", SCF_OP_NE, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_ne}, + {"u64", SCF_OP_GE, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_ge}, + {"u64", SCF_OP_LE, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_le}, + {"float", SCF_OP_ADD, SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_add}, {"float", SCF_OP_SUB, SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_sub}, {"float", SCF_OP_MUL, SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_mul}, @@ -136,4 +168,3 @@ scf_calculate_t* scf_find_base_calculate(int op_type, int src0_type, int src1_ty return NULL; } - diff --git a/js/core/scf_calculate.h b/js/core/scf_calculate.h index 145e252..4d2b19a 100644 --- a/js/core/scf_calculate.h +++ b/js/core/scf_calculate.h @@ -19,4 +19,3 @@ typedef struct { scf_calculate_t* scf_find_base_calculate(int op_type, int src0_type, int src1_type); #endif - diff --git a/js/core/scf_calculate_i32.c b/js/core/scf_calculate_i32.c index 50fc79c..c01ad95 100644 --- a/js/core/scf_calculate_i32.c +++ b/js/core/scf_calculate_i32.c @@ -63,4 +63,3 @@ SCF_I32_BINARY_OP(eq, ==) SCF_I32_BINARY_OP(ne, !=) SCF_I32_BINARY_OP(ge, >=) SCF_I32_BINARY_OP(le, <=) - diff --git a/js/core/scf_calculate_i64.c b/js/core/scf_calculate_i64.c index 06aa716..ed2eee9 100644 --- a/js/core/scf_calculate_i64.c +++ b/js/core/scf_calculate_i64.c @@ -63,4 +63,3 @@ SCF_I64_BINARY_OP(eq, ==) SCF_I64_BINARY_OP(ne, !=) SCF_I64_BINARY_OP(ge, >=) SCF_I64_BINARY_OP(le, <=) - diff --git a/js/core/scf_calculate_u32.c b/js/core/scf_calculate_u32.c index 7ecb10f..fa982d2 100644 --- a/js/core/scf_calculate_u32.c +++ b/js/core/scf_calculate_u32.c @@ -63,4 +63,3 @@ SCF_U32_BINARY_OP(eq, ==) SCF_U32_BINARY_OP(ne, !=) SCF_U32_BINARY_OP(ge, >=) SCF_U32_BINARY_OP(le, <=) - diff --git a/js/core/scf_calculate_u64.c b/js/core/scf_calculate_u64.c new file mode 100644 index 0000000..36aaebd --- /dev/null +++ b/js/core/scf_calculate_u64.c @@ -0,0 +1,65 @@ +#include"scf_calculate.h" + +#define SCF_U64_BINARY_OP(name, op) \ +int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \ +{ \ + scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_U64); \ + scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 0, 0, NULL); \ + if (!r) \ + return -ENOMEM; \ + r->data.u64 = src0->data.u64 op src1->data.u64; \ + if (pret) \ + *pret = r; \ + return 0; \ +} + +#define SCF_U64_UNARY_OP(name, op) \ +int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \ +{ \ + scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_U64); \ + scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 0, 0, NULL); \ + if (!r) \ + return -ENOMEM; \ + r->data.u64 = op src0->data.u64; \ + if (pret) \ + *pret = r; \ + return 0; \ +} + +#define SCF_U64_UPDATE_OP(name, op) \ +int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \ +{ \ + op src0->data.u64; \ + if (pret) \ + *pret = scf_variable_ref(src0); \ + return 0; \ +} + +SCF_U64_BINARY_OP(add, +) +SCF_U64_BINARY_OP(sub, -) +SCF_U64_BINARY_OP(mul, *) +SCF_U64_BINARY_OP(div, /) +SCF_U64_BINARY_OP(mod, %) + +SCF_U64_BINARY_OP(shl, <<) +SCF_U64_BINARY_OP(shr, >>) + +SCF_U64_UPDATE_OP(inc, ++); +SCF_U64_UPDATE_OP(dec, --); + +SCF_U64_UNARY_OP(neg, -) + +SCF_U64_BINARY_OP(bit_and, &) +SCF_U64_BINARY_OP(bit_or, |) +SCF_U64_UNARY_OP(bit_not, ~) + +SCF_U64_BINARY_OP(logic_and, &&) +SCF_U64_BINARY_OP(logic_or, ||) +SCF_U64_UNARY_OP(logic_not, !) + +SCF_U64_BINARY_OP(gt, >) +SCF_U64_BINARY_OP(lt, <) +SCF_U64_BINARY_OP(eq, ==) +SCF_U64_BINARY_OP(ne, !=) +SCF_U64_BINARY_OP(ge, >=) +SCF_U64_BINARY_OP(le, <=) diff --git a/js/core/scf_expr.c b/js/core/scf_expr.c index 8a8b081..bb7b5da 100644 --- a/js/core/scf_expr.c +++ b/js/core/scf_expr.c @@ -156,7 +156,8 @@ void scf_expr_simplify(scf_expr_t** pe) e = *pp; *pp = NULL; - e->parent = (*pe)->parent; + e->parent = (*pe)->parent; + e->_3ac_done = (*pe)->_3ac_done; scf_expr_free(*pe); *pe = e; diff --git a/js/core/scf_function.c b/js/core/scf_function.c index a8d5e31..de7c2fe 100644 --- a/js/core/scf_function.c +++ b/js/core/scf_function.c @@ -173,19 +173,24 @@ int scf_function_same_argv(scf_vector_t* argv0, scf_vector_t* argv1) return 1; } -int scf_function_like_argv(scf_vector_t* argv0, scf_vector_t* argv1) +int scf_function_like_argv(scf_function_t* f, scf_vector_t* argv) { - if (argv0) { - if (!argv1) + if (f->argv) { + if (!argv) return 0; - if (argv0->size != argv1->size) + if (f->argv->size > argv->size) + return 0; + else if (f->argv->size < argv->size && !f->vargs_flag) return 0; + scf_variable_t* v0; + scf_variable_t* v1; int i; - for (i = 0; i < argv0->size; i++) { - scf_variable_t* v0 = argv0->data[i]; - scf_variable_t* v1 = argv1->data[i]; + + for (i = 0; i < f->argv->size; i++) { + v0 = f->argv->data[i]; + v1 = argv->data[i]; if (scf_variable_type_like(v0, v1)) continue; @@ -194,7 +199,7 @@ int scf_function_like_argv(scf_vector_t* argv0, scf_vector_t* argv1) return 0; } } else { - if (argv1) + if (argv) return 0; } diff --git a/js/core/scf_function.h b/js/core/scf_function.h index 9b0afd4..d423198 100644 --- a/js/core/scf_function.h +++ b/js/core/scf_function.h @@ -72,11 +72,11 @@ struct scf_function_s { }; scf_function_t* scf_function_alloc(scf_lex_word_t* w); -void scf_function_free(scf_function_t* f); +void scf_function_free (scf_function_t* f); -int scf_function_same(scf_function_t* f0, scf_function_t* f1); -int scf_function_same_type(scf_function_t* f0, scf_function_t* f1); +int scf_function_same (scf_function_t* f0, scf_function_t* f1); +int scf_function_same_type(scf_function_t* f0, scf_function_t* f1); +int scf_function_like_argv(scf_function_t* f, scf_vector_t* argv); int scf_function_same_argv(scf_vector_t* argv0, scf_vector_t* argv1); -int scf_function_like_argv(scf_vector_t* argv0, scf_vector_t* argv1); #endif diff --git a/js/core/scf_label.c b/js/core/scf_label.c index 63bdb9e..7bb478b 100644 --- a/js/core/scf_label.c +++ b/js/core/scf_label.c @@ -12,7 +12,6 @@ scf_label_t* scf_label_alloc(scf_lex_word_t* w) return NULL; } - l->refs = 1; l->type = SCF_LABEL; return l; } @@ -20,9 +19,6 @@ scf_label_t* scf_label_alloc(scf_lex_word_t* w) void scf_label_free(scf_label_t* l) { if (l) { - if (--l->refs > 0) - return; - if (l->w) { scf_lex_word_free(l->w); l->w = NULL; diff --git a/js/core/scf_node.c b/js/core/scf_node.c index 89d68ad..4027d40 100644 --- a/js/core/scf_node.c +++ b/js/core/scf_node.c @@ -2,6 +2,9 @@ scf_variable_t* _scf_operand_get(const scf_node_t* node) { + while (SCF_OP_EXPR == node->type && node->nb_nodes > 0) + node = node->nodes[0]; + if (scf_type_is_var(node->type)) return node->var; else if (scf_type_is_operator(node->type)) @@ -76,9 +79,7 @@ scf_node_t* scf_node_clone(scf_node_t* node) if (!dst->var) goto failed; - } else if (SCF_LABEL == node->type) - dst->label = node->label; - else { + } else { if (node->w) { dst->w = scf_lex_word_clone(node->w); if (!dst->w) @@ -110,19 +111,6 @@ failed: return NULL; } -scf_node_t* scf_node_alloc_label(scf_label_t* l) -{ - scf_node_t* node = calloc(1, sizeof(scf_node_t)); - if (!node) { - scf_loge("node alloc failed\n"); - return NULL; - } - - node->type = SCF_LABEL; - node->label = l; - return node; -} - int scf_node_add_child(scf_node_t* parent, scf_node_t* child) { if (!parent) @@ -168,11 +156,6 @@ void scf_node_free_data(scf_node_t* node) scf_variable_free(node->var); node->var = NULL; } - } else if (SCF_LABEL == node->type) { - if (node->label) { - scf_label_free(node->label); - node->label = NULL; - } } else { if (node->w) { scf_lex_word_free(node->w); @@ -277,11 +260,7 @@ void scf_node_print(scf_node_t* node) if (node) { scf_logw("node: %p, type: %d", node, node->type); - if (SCF_LABEL == node->type) { - if (node->label && node->label->w) - printf(", w: %s, line: %d", node->label->w->text->data, node->label->w->line); - - } else if (scf_type_is_var(node->type)) { + if (scf_type_is_var(node->type)) { if (node->var && node->var->w) printf(", w: %s, line: %d", node->var->w->text->data, node->var->w->line); diff --git a/js/core/scf_node.h b/js/core/scf_node.h index 946298c..b6f23c0 100644 --- a/js/core/scf_node.h +++ b/js/core/scf_node.h @@ -22,9 +22,8 @@ struct scf_node_s { scf_expr_t* js_new; // the expr which created this node, only for js! union { - scf_variable_t* var; - scf_lex_word_t* w; - scf_label_t* label; + scf_variable_t* var; + scf_lex_word_t* w; }; scf_lex_word_t* debug_w; @@ -52,30 +51,26 @@ struct scf_node_s { uint32_t semi_flag :1; // set when followed by a ';' }; -struct scf_label_s { +struct scf_label_s +{ scf_list_t list; // for variable scope - int refs; // reference count - int type; - scf_lex_word_t* w; scf_node_t* node; // the labeled node }; scf_node_t* scf_node_alloc(scf_lex_word_t* w, int type, scf_variable_t* var); -scf_node_t* scf_node_alloc_label(scf_label_t* l); - -scf_node_t* scf_node_clone(scf_node_t* node); int scf_node_add_child(scf_node_t* parent, scf_node_t* child); void scf_node_del_child(scf_node_t* parent, scf_node_t* child); -void scf_node_free(scf_node_t* node); +void scf_node_free (scf_node_t* node); void scf_node_free_data(scf_node_t* node); void scf_node_move_data(scf_node_t* dst, scf_node_t* src); +scf_node_t* scf_node_clone(scf_node_t* node); void scf_node_print(scf_node_t* node); scf_variable_t* _scf_operand_get(const scf_node_t* node); diff --git a/js/core/scf_operator_handler_3ac.c b/js/core/scf_operator_handler_3ac.c index 02b34ad..5bbf410 100644 --- a/js/core/scf_operator_handler_3ac.c +++ b/js/core/scf_operator_handler_3ac.c @@ -413,7 +413,6 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* // for goto if (SCF_LABEL == node->type) { - scf_label_t* l = node->label; scf_list_t* tail = scf_list_tail(d->_3ac_list_head); scf_3ac_code_t* end = scf_list_data(tail, scf_3ac_code_t, list); scf_3ac_code_t* c; @@ -423,7 +422,7 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* scf_loge("\n"); return -1; } - end->label = l; + end->label = node->w; int j; for (j = 0; j < d->branch_ops->_gotos->size; j++) { @@ -432,10 +431,7 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* if (!c) continue; - assert(l->w); - assert(c->label->w); - - if (!strcmp(l->w->text->data, c->label->w->text->data)) { + if (!strcmp(node->w->text->data, c->label->text->data)) { dst = c->dsts->data[0]; dst->code = end; } @@ -486,7 +482,7 @@ static int _scf_op_return(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void return -1; } - scf_3ac_code_t* end = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + scf_3ac_code_t* end = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &end->list); @@ -510,7 +506,7 @@ static int _scf_op_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* return -1; } - scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp->list); @@ -534,7 +530,7 @@ static int _scf_op_continue(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo return -1; } - scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp->list); @@ -553,14 +549,12 @@ static int _scf_op_goto(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* scf_handler_data_t* d = data; scf_node_t* nl = nodes[0]; - scf_label_t* l = nl->label; assert(SCF_LABEL == nl->type); - assert(l->w); scf_3ac_operand_t* dst; scf_3ac_code_t* c; - scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, l, NULL); + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, nl->w); scf_list_add_tail(d->_3ac_list_head, &jmp->list); @@ -568,7 +562,7 @@ static int _scf_op_goto(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* for (i = 0; i < d->branch_ops->_labels->size; i++) { c = d->branch_ops->_labels->data[i]; - if (!strcmp(l->w->text->data, c->label->w->text->data)) { + if (!strcmp(nl->w->text->data, c->label->text->data)) { dst = jmp->dsts->data[0]; dst->code = c; break; @@ -734,7 +728,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da } scf_3ac_operand_t* dst; - scf_3ac_code_t* jmp_else = scf_3ac_jmp_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_else = scf_3ac_jmp_code(jmp_op, NULL); scf_3ac_code_t* jmp_endif = NULL; scf_list_t* l; @@ -751,7 +745,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da if (1 == i) { if (3 == nb_nodes) { - jmp_endif = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + jmp_endif = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_endif->list); } @@ -870,7 +864,7 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s }; // add loop when true - scf_3ac_code_t* loop = scf_3ac_jmp_code(jmp_op, NULL, NULL); + scf_3ac_code_t* loop = scf_3ac_jmp_code(jmp_op, NULL); scf_list_add_tail(d->_3ac_list_head, &loop->list); // should get the real start here, @@ -977,7 +971,7 @@ static int _scf_op_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da scf_list_t* l; scf_3ac_code_t* c; - scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); @@ -1037,7 +1031,7 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* return -1; } - scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc(); @@ -1102,7 +1096,7 @@ static int _scf_op_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, v if (!cmp) return -ENOMEM; - jgt = scf_3ac_jmp_code(SCF_OP_3AC_JGT, NULL, NULL); + jgt = scf_3ac_jmp_code(SCF_OP_3AC_JGT, NULL); if (!jgt) { scf_3ac_code_free(cmp); return -ENOMEM; @@ -1181,7 +1175,7 @@ static int _scf_op_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void if (SCF_OP_CASE == child->type || SCF_OP_DEFAULT == child->type) { if (jnot) { - jnext = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + jnext = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &jnext->list); scf_vector_add(up_branch_ops->_breaks, jnext); @@ -1218,12 +1212,12 @@ static int _scf_op_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void scf_function_t* f = v->func_ptr; if (SCF_OP_EQ == f->op_type) - jnot = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL); + jnot = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL); else - jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL); + jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL); } else { cmp = scf_3ac_code_NN (SCF_OP_3AC_CMP, NULL, 0, srcs, 2); - jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL); + jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL); } scf_list_add_tail(d->_3ac_list_head, &cmp->list); @@ -1311,7 +1305,7 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d return -1; } - jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL); + jmp_end = scf_3ac_jmp_code(jmp_op, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); } } @@ -1504,7 +1498,7 @@ static int _scf_op_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d return ret; } - jz = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL); + jz = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL); scf_list_add_tail(d->_3ac_list_head, &jz->list); for (i = 3; i < nb_nodes; i++) { @@ -1528,7 +1522,7 @@ static int _scf_op_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d return ret; } - jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp->list); scf_vector_add(d->branch_ops->_breaks, jz); @@ -2373,7 +2367,7 @@ static int _scf_op_logic_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes if (jmp_op < 0) \ return -1; \ \ - scf_3ac_code_t* jmp = scf_3ac_jmp_code(jmp_op, NULL, NULL); \ + scf_3ac_code_t* jmp = scf_3ac_jmp_code(jmp_op, NULL); \ if (!jmp) \ return -ENOMEM; \ \ diff --git a/js/core/scf_optimizer_inline.c b/js/core/scf_optimizer_inline.c index 6900ea9..32fbb9e 100644 --- a/js/core/scf_optimizer_inline.c +++ b/js/core/scf_optimizer_inline.c @@ -186,25 +186,6 @@ static int _copy_codes(scf_list_t* hbb, scf_vector_t* argv, scf_3ac_code_t* c, s return 0; } -static int _find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results) -{ - scf_block_t* b = (scf_block_t*)node; - - if ((SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type) && b->scope) { - - int i; - for (i = 0; i < b->scope->vars->size; i++) { - - scf_variable_t* var = b->scope->vars->data[i]; - - int ret = scf_vector_add(results, var); - if (ret < 0) - return ret; - } - } - return 0; -} - static int _do_inline(scf_ast_t* ast, scf_3ac_code_t* c, scf_basic_block_t** pbb, scf_function_t* f, scf_function_t* f2) { scf_basic_block_t* bb = *pbb; @@ -254,7 +235,7 @@ static int _do_inline(scf_ast_t* ast, scf_3ac_code_t* c, scf_basic_block_t** pbb scf_vector_clear(argv, NULL); - int ret = scf_node_search_bfs((scf_node_t*)f2, NULL, argv, -1, _find_local_vars); + int ret = scf_node_search_bfs((scf_node_t*)f2, NULL, argv, -1, __find_local_vars); if (ret < 0) { scf_vector_free(argv); return -ENOMEM; diff --git a/js/core/scf_optimizer_js_array.c b/js/core/scf_optimizer_js_array.c index 2799637..f39e0a5 100644 --- a/js/core/scf_optimizer_js_array.c +++ b/js/core/scf_optimizer_js_array.c @@ -11,7 +11,7 @@ static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* a int ret; - if (v->type == Object->type) + if (v->type == Object->node.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"); @@ -116,7 +116,7 @@ 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) + if (v->type != Object->node.type) continue; c2 = NULL; diff --git a/js/core/scf_optimizer_js_array2.c b/js/core/scf_optimizer_js_array2.c index 007b09b..b78138b 100644 --- a/js/core/scf_optimizer_js_array2.c +++ b/js/core/scf_optimizer_js_array2.c @@ -1,20 +1,22 @@ #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) +static int __js_array_index(scf_ast_t* ast, scf_3ac_code_t* c, scf_dag_node_t* array, 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; + scf_3ac_operand_t* pf; + scf_3ac_operand_t* src; + scf_3ac_operand_t* dst; + 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) + if (index->var->type == Object->node.type) ret = scf_ast_find_global_function(&f, ast, "Object_array_index_obj"); else if (index->var->type == SCF_VAR_DOUBLE) @@ -40,12 +42,17 @@ static int __js_array_index(scf_ast_t* ast, scf_3ac_code_t* c, scf_dag_node_t* i if (!dn) return -ENOMEM; - pf = c->srcs->data[2]; + // 2nd src operand is 'scale size' of array index (no-use after here), change it to 'const function pointer'. + pf = c->srcs->data[2]; + dst = c->dsts->data[0]; if (pf->node) scf_node_free(pf->node); if (pf->dag_node) { + scf_vector_del(dst->dag_node->childs, pf->dag_node); + scf_vector_del(pf ->dag_node->parents, dst->dag_node); + scf_list_del(&pf->dag_node->list); scf_dag_node_free(pf->dag_node); } @@ -56,11 +63,20 @@ static int __js_array_index(scf_ast_t* ast, scf_3ac_code_t* c, scf_dag_node_t* i SCF_XCHG(c->srcs->data[2], c->srcs->data[1]); SCF_XCHG(c->srcs->data[1], c->srcs->data[0]); + src = c->srcs->data[1]; + + scf_vector_del(dst->dag_node->childs, src->dag_node); + scf_vector_del(src->dag_node->parents, dst->dag_node); + assert (src->dag_node != array); + + src->dag_node = array; + src->node = array->node; + 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) +static scf_3ac_code_t* __js_array_find_pointer(scf_dag_node_t* members, 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; @@ -74,7 +90,7 @@ static scf_3ac_code_t* __js_array_find_3ac(scf_dag_node_t* member, scf_3ac_code_ if (SCF_OP_POINTER == c2->op->type) { dst = c2->dsts->data[0]; - if (dst->dag_node == member) + if (dst->dag_node == members) return c2; } } @@ -96,7 +112,7 @@ static scf_3ac_code_t* __js_array_find_3ac(scf_dag_node_t* member, scf_3ac_code_ if (SCF_OP_POINTER == c2->op->type) { dst = c2->dsts->data[0]; - if (dst->dag_node == member) + if (dst->dag_node == members) return c2; } } @@ -116,7 +132,7 @@ static int _optimize_js_array2_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_b scf_3ac_code_t* c; scf_3ac_code_t* c2; scf_dag_node_t* array; - scf_dag_node_t* member; + scf_dag_node_t* members; scf_type_t* Object = NULL; scf_list_t* l; scf_list_t* l2; @@ -140,41 +156,40 @@ static int _optimize_js_array2_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_b 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; + base = c->srcs->data[0]; + index = c->srcs->data[1]; + members = base->dag_node; - array = member; + array = members; while (SCF_OP_EXPR == array->type || SCF_OP_POINTER == array->type) array = array->childs->data[0]; - if (array->var->type != Object->type) + if (array->var->type != Object->node.type) continue; - if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type && index->dag_node->var->type != Object->type) + if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type && index->dag_node->var->type != Object->node.type) continue; int op_type = c->op->type; - ret = __js_array_index(ast, c, index->dag_node, Object); + ret = __js_array_index(ast, c, array, 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; + scf_vector_del(c->basic_block->dn_reloads, members); #if 1 - c2 = __js_array_find_3ac(member, c, cur_bb, bb, l, bb_list_head); + c2 = __js_array_find_pointer(members, 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); + if (!members->parents || members->parents->size <= 0) { - scf_list_del(&c2->list); - scf_3ac_code_free(c2); - c2 = NULL; + scf_vector_del(c2->basic_block->dn_resaves, members); + scf_vector_del(c2->basic_block->exit_dn_actives, members); + + 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)) { diff --git a/js/core/scf_optimizer_js_teq.c b/js/core/scf_optimizer_js_teq.c index 2d64d15..c48e2a5 100644 --- a/js/core/scf_optimizer_js_teq.c +++ b/js/core/scf_optimizer_js_teq.c @@ -90,7 +90,7 @@ static int _optimize_js_teq_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_bloc v = _scf_operand_get(node); - if (v->type != Object->type) + if (v->type != Object->node.type) continue; if (SCF_OP_CALL == node->type) { diff --git a/js/core/scf_optimizer_js_unary_op.c b/js/core/scf_optimizer_js_unary_op.c index baad749..86ec2ad 100644 --- a/js/core/scf_optimizer_js_unary_op.c +++ b/js/core/scf_optimizer_js_unary_op.c @@ -168,7 +168,7 @@ static int _optimize_js_unary_op_bb(scf_ast_t* ast, scf_function_t* f, scf_basic v = _scf_operand_get(node); - if (v->type != Object->type) + if (v->type != Object->node.type) continue; ret = __js_unary_op(ast, c, node, Object); @@ -182,7 +182,7 @@ static int _optimize_js_unary_op_bb(scf_ast_t* ast, scf_function_t* f, scf_basic v = _scf_operand_get(node); - if (v->type != Object->type) + if (v->type != Object->node.type) continue; switch (dst->node->type) { diff --git a/js/core/scf_scope.c b/js/core/scf_scope.c index 424fb0f..7bc08ba 100644 --- a/js/core/scf_scope.c +++ b/js/core/scf_scope.c @@ -1,48 +1,27 @@ #include"scf_ast.h" -scf_scope_t* scf_scope_alloc(scf_lex_word_t* w, const char* name) +scf_scope_t* scf_scope_alloc() { scf_scope_t* scope = calloc(1, sizeof(scf_scope_t)); if (!scope) return NULL; - scope->name = scf_string_cstr(name); - if (!scope->name) { - free(scope); - return NULL; - } - scope->vars = scf_vector_alloc(); if (!scope->vars) { - scf_string_free(scope->name); free(scope); return NULL; } - if (w) { - scope->w = scf_lex_word_clone(w); - - if (!scope->w) { - scf_vector_free(scope->vars); - scf_string_free(scope->name); - free(scope); - return NULL; - } - } - scf_list_init(&scope->list); - scf_list_init(&scope->type_list_head); - scf_list_init(&scope->operator_list_head); - scf_list_init(&scope->function_list_head); - scf_list_init(&scope->label_list_head); + scf_list_init(&scope->types); + scf_list_init(&scope->operators); + scf_list_init(&scope->functions); + scf_list_init(&scope->labels); return scope; } 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); @@ -50,47 +29,32 @@ void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var) void scf_scope_push_type(scf_scope_t* scope, scf_type_t* t) { - assert(scope); - assert(t); - scf_list_add_front(&scope->type_list_head, &t->list); + scf_list_add_front(&scope->types, &t->list); } void scf_scope_push_operator(scf_scope_t* scope, scf_function_t* op) { - assert(scope); - assert(op); - scf_list_add_front(&scope->operator_list_head, &op->list); + scf_list_add_front(&scope->operators, &op->list); } void scf_scope_push_function(scf_scope_t* scope, scf_function_t* f) { - assert(scope); - assert(f); - scf_list_add_front(&scope->function_list_head, &f->list); + scf_list_add_front(&scope->functions, &f->list); } void scf_scope_push_label(scf_scope_t* scope, scf_label_t* l) { - assert(scope); - assert(l); - scf_list_add_front(&scope->label_list_head, &l->list); + scf_list_add_front(&scope->labels, &l->list); } void scf_scope_free(scf_scope_t* scope) { if (scope) { - scf_string_free(scope->name); - scope->name = NULL; - - if (scope->w) - scf_lex_word_free(scope->w); - scf_vector_clear(scope->vars, (void (*)(void*))scf_variable_free); scf_vector_free(scope->vars); scope->vars = NULL; - scf_list_clear(&scope->type_list_head, scf_type_t, list, scf_type_free); - scf_list_clear(&scope->function_list_head, scf_function_t, list, scf_function_free); + scf_list_clear(&scope->labels, scf_label_t, list, scf_label_free); free(scope); } @@ -101,7 +65,7 @@ scf_type_t* scf_scope_find_type(scf_scope_t* scope, const char* name) scf_type_t* t; scf_list_t* l; - for (l = scf_list_head(&scope->type_list_head); l != scf_list_sentinel(&scope->type_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->types); l != scf_list_sentinel(&scope->types); l = scf_list_next(l)) { t = scf_list_data(l, scf_type_t, list); if (!strcmp(name, t->name->data)) { @@ -116,10 +80,10 @@ scf_type_t* scf_scope_find_type_type(scf_scope_t* scope, const int type) scf_type_t* t; scf_list_t* l; - for (l = scf_list_head(&scope->type_list_head); l != scf_list_sentinel(&scope->type_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->types); l != scf_list_sentinel(&scope->types); l = scf_list_next(l)) { t = scf_list_data(l, scf_type_t, list); - if (type == t->type) + if (type == t->node.type) return t; } return NULL; @@ -144,7 +108,7 @@ scf_label_t* scf_scope_find_label(scf_scope_t* scope, const char* name) scf_label_t* label; scf_list_t* l; - for (l = scf_list_head(&scope->label_list_head); l != scf_list_sentinel(&scope->label_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->labels); l != scf_list_sentinel(&scope->labels); l = scf_list_next(l)) { label = scf_list_data(l, scf_label_t, list); if (!strcmp(name, label->w->text->data)) @@ -158,7 +122,7 @@ scf_function_t* scf_scope_find_function(scf_scope_t* scope, const char* name) scf_function_t* f; scf_list_t* l; - for (l = scf_list_head(&scope->function_list_head); l != scf_list_sentinel(&scope->function_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->functions); l != scf_list_sentinel(&scope->functions); l = scf_list_next(l)) { f = scf_list_data(l, scf_function_t, list); if (!strcmp(name, f->node.w->text->data)) @@ -172,7 +136,7 @@ scf_function_t* scf_scope_find_same_function(scf_scope_t* scope, scf_function_t* scf_function_t* f1; scf_list_t* l; - for (l = scf_list_head(&scope->function_list_head); l != scf_list_sentinel(&scope->function_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->functions); l != scf_list_sentinel(&scope->functions); l = scf_list_next(l)) { f1 = scf_list_data(l, scf_function_t, list); if (scf_function_same(f0, f1)) @@ -191,13 +155,13 @@ int scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, if (!vec) return -ENOMEM; - for (l = scf_list_head(&scope->function_list_head); l != scf_list_sentinel(&scope->function_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->functions); l != scf_list_sentinel(&scope->functions); l = scf_list_next(l)) { f = scf_list_data(l, scf_function_t, list); if (strcmp(f->node.w->text->data, name)) continue; - if (!scf_function_like_argv(f->argv, argv)) + if (!scf_function_like_argv(f, argv)) continue; int ret = scf_vector_add(vec, f); @@ -226,13 +190,13 @@ int scf_scope_find_overloaded_functions(scf_vector_t** pfunctions, scf_scope_t* if (!vec) return -ENOMEM; - for (l = scf_list_head(&scope->operator_list_head); l != scf_list_sentinel(&scope->operator_list_head); l = scf_list_next(l)) { + for (l = scf_list_head(&scope->operators); l != scf_list_sentinel(&scope->operators); l = scf_list_next(l)) { f = scf_list_data(l, scf_function_t, list); if (op_type != f->op_type) continue; - if (!scf_function_like_argv(f->argv, argv)) + if (!scf_function_like_argv(f, argv)) continue; int ret = scf_vector_add(vec, f); diff --git a/js/core/scf_scope.h b/js/core/scf_scope.h index 53ef96a..ac823f1 100644 --- a/js/core/scf_scope.h +++ b/js/core/scf_scope.h @@ -6,37 +6,30 @@ #include"scf_lex_word.h" #include"scf_core_types.h" -struct scf_scope_s { - scf_list_t list; // scope list - scf_string_t* name; // scope name - - scf_lex_word_t* w; // scope name - - scf_vector_t* vars; // vars in this scope, should not have the same name - scf_list_t type_list_head; // type list in this scope, not define the same type - scf_list_t operator_list_head; // operator list in this scope - scf_list_t function_list_head; // function list in this scope - scf_list_t label_list_head; // label list in this scope +struct scf_scope_s +{ + scf_list_t list; // scope list + + scf_vector_t* vars; // vars in this scope, should not have the same name + scf_list_t types; // type list in this scope, not define the same type + scf_list_t operators; // operator list in this scope + scf_list_t functions; // function list in this scope + scf_list_t labels; // label list in this scope }; -scf_scope_t* scf_scope_alloc(scf_lex_word_t* w, const char* name); -void scf_scope_free( scf_scope_t* scope); +scf_scope_t* scf_scope_alloc(); +void scf_scope_free(scf_scope_t* scope); -void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var); - -void scf_scope_push_type(scf_scope_t* scope, scf_type_t* t); +void scf_scope_push_var (scf_scope_t* scope, scf_variable_t* var); +void scf_scope_push_type(scf_scope_t* scope, scf_type_t* t); void scf_scope_push_operator(scf_scope_t* scope, scf_function_t* op); - void scf_scope_push_function(scf_scope_t* scope, scf_function_t* f); -scf_type_t* scf_scope_find_type(scf_scope_t* scope, const char* name); - -scf_type_t* scf_scope_find_type_type(scf_scope_t* scope, const int type); - -scf_variable_t* scf_scope_find_variable(scf_scope_t* scope, const char* name); - -scf_function_t* scf_scope_find_function(scf_scope_t* scope, const char* name); +scf_type_t* scf_scope_find_type (scf_scope_t* scope, const char* name); +scf_type_t* scf_scope_find_type_type(scf_scope_t* scope, const int type); +scf_variable_t* scf_scope_find_variable (scf_scope_t* scope, const char* name); +scf_function_t* scf_scope_find_function (scf_scope_t* scope, const char* name); scf_function_t* scf_scope_find_same_function(scf_scope_t* scope, scf_function_t* f0); diff --git a/js/core/scf_type.c b/js/core/scf_type.c index a964018..94455a5 100644 --- a/js/core/scf_type.c +++ b/js/core/scf_type.c @@ -7,7 +7,6 @@ scf_type_t* scf_type_alloc(scf_lex_word_t* w, const char* name, int type, int si if (!t) return NULL; - t->type = type; t->node.type = type; t->name = scf_string_cstr(name); @@ -17,8 +16,8 @@ scf_type_t* scf_type_alloc(scf_lex_word_t* w, const char* name, int type, int si } if (w) { - t->w = scf_lex_word_clone(w); - if (!t->w) { + t->node.w = scf_lex_word_clone(w); + if (!t->node.w) { scf_string_free(t->name); free(t); return NULL; @@ -35,18 +34,12 @@ void scf_type_free(scf_type_t* t) scf_string_free(t->name); t->name = NULL; - if (t->w) { - scf_lex_word_free(t->w); - t->w = NULL; - } - if (t->scope) { scf_scope_free(t->scope); t->scope = NULL; } - free(t); - t = NULL; + scf_node_free((scf_node_t*)t); } } diff --git a/js/core/scf_type.h b/js/core/scf_type.h index 82aa8a9..3ece46b 100644 --- a/js/core/scf_type.h +++ b/js/core/scf_type.h @@ -4,8 +4,8 @@ #include"scf_node.h" typedef struct { - int type; const char* name; + int type; int size; } scf_base_type_t; @@ -14,20 +14,16 @@ typedef struct { const char* abbrev; } scf_type_abbrev_t; -struct scf_type_s { +struct scf_type_s +{ // same as block, only used for class type scf_node_t node; - scf_scope_t* scope; - scf_string_t* name; // list for scope's type_list_head scf_list_t list; - int type; - scf_lex_word_t* w; - int nb_pointers; // int array_capacity; @@ -36,7 +32,6 @@ 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 }; @@ -46,4 +41,3 @@ void scf_type_free(scf_type_t* t); const char* scf_type_find_abbrev(const char* name); #endif - diff --git a/js/core/scf_variable.c b/js/core/scf_variable.c index 469e896..cc8935f 100644 --- a/js/core/scf_variable.c +++ b/js/core/scf_variable.c @@ -98,7 +98,7 @@ scf_variable_t* scf_variable_alloc(scf_lex_word_t* w, scf_type_t* t) return NULL; v->refs = 1; - v->type = t->type; + v->type = t->node.type; v->js_type = -1; v->js_index = -1; diff --git a/js/doc.c b/js/doc.c index ceeda44..f8ea145 100644 --- a/js/doc.c +++ b/js/doc.c @@ -2,9 +2,12 @@ struct Object; -int abc_html_write (Object* html, const char* s); -int abc_html_write_i(Object* html, int64_t i); -int abc_html_write_d(Object* html, double d); +void abc_html_inner (Object* obj, const char* s); +int abc_html_write (Object* html, const char* s); +int abc_html_write_i(Object* html, int64_t i); +int abc_html_write_d(Object* html, double d); + +void* abc_html_getElementById(Object* html, const char* id); int abc_pcre2_match(int** __ovector, const char* __subject, const char* __pattern); @@ -31,6 +34,7 @@ struct Object char* str; double d; int64_t i64; + Object* innerHTML; int __init(Object* this) { @@ -128,6 +132,42 @@ struct Object return 0; } + int __init(Object* this, const char* name, int length, const char* s) + { + 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->length = length; + + if (length > 0) { + this->members = scf__auto_malloc(sizeof(Object*) * length); + if (!this->members) + return -1; + + this->type = JS_Object; + } else + this->type = JS_String; + + if (s) { + len = strlen(s); + + this->str = scf__auto_malloc(len + 1); + if (!this->str) + return -1; + + memcpy(this->str, s, len + 1); + + printf("this: %p, this->str: %s, s: %s\n\n", this, this->str, s); + } + + return 0; + } + Object* Boolean(Object* this) { Object* res = new Object(); @@ -581,6 +621,30 @@ struct Object { return this->match(pattern->str); } + + void operator=(Object* this, const char* s) + { + if (1ull & (uintptr_t)this) + abc_html_inner((uintptr_t)this & ~1ull, s); + } + + Object* getElementById(Object* this, const char* id) + { + void* html_obj = abc_html_getElementById(this, id); + if (!html_obj) + return NULL; + + Object* obj = new Object(); + if (!obj) + return NULL; + + obj->type = JS_Object; + *(uintptr_t*)&obj->innerHTML = 0x1 | (uintptr_t)html_obj; + return obj; + } + + // it's an ASM function, only declare here. + void setTimeout(Object* this, int argc, const funcptr* func, int msec, ...); }; const double Math_PI = 3.1415926; diff --git a/js/elf/scf_dwarf.c b/js/elf/scf_dwarf.c index c7d8771..a34bce1 100644 --- a/js/elf/scf_dwarf.c +++ b/js/elf/scf_dwarf.c @@ -435,6 +435,37 @@ scf_dwarf_t* scf_dwarf_debug_alloc() return debug; } +int _find_debug_file(const void* v0, const void* v1) +{ + const scf_string_t* s0 = v0; + const scf_string_t* s1 = v1; + + if (s0->len < s1->len) + return -1; + else if (s0->len > s1->len) + return 1; + + return strcmp(s0->data, s1->data); +} + +int scf_dwarf_add_file_name(scf_dwarf_t* debug, const scf_string_t* fname) +{ + if (scf_vector_find_cmp(debug->file_names, fname, _find_debug_file)) + return 0; + + scf_string_t* s = scf_string_clone(fname); + if (!s) + return -ENOMEM; + + int ret = scf_vector_add(debug->file_names, s); + if (ret < 0) { + scf_string_free(s); + return ret; + } + + return 0; +} + void scf_dwarf_debug_free (scf_dwarf_t* debug) { if (debug) { diff --git a/js/elf/scf_dwarf.h b/js/elf/scf_dwarf.h index 08675bc..c680663 100644 --- a/js/elf/scf_dwarf.h +++ b/js/elf/scf_dwarf.h @@ -441,4 +441,8 @@ const char* scf_dwarf_find_tag (const uint32_t type); const char* scf_dwarf_find_form(const uint32_t type); const char* scf_dwarf_find_attribute(const uint32_t type); +int scf_dwarf_add_file_name(scf_dwarf_t* debug, const scf_string_t* fname); + +int _find_debug_file(const void* v0, const void* v1); + #endif diff --git a/js/lex/scf_lex_util.c b/js/lex/scf_lex_util.c index 2fda3c0..b4d6c9c 100644 --- a/js/lex/scf_lex_util.c +++ b/js/lex/scf_lex_util.c @@ -1,5 +1,35 @@ #include"scf_lex.h" +int _find_key_word(const char* text); + +static scf_key_word_t number_postfix[] = +{ + {"l", SCF_LEX_WORD_CONST_INT}, + {"ll", SCF_LEX_WORD_CONST_I64}, + + {"u", SCF_LEX_WORD_CONST_U32}, + {"ul", SCF_LEX_WORD_CONST_U32}, + {"ull", SCF_LEX_WORD_CONST_U64}, + + {"f", SCF_LEX_WORD_CONST_FLOAT}, + {"lf", SCF_LEX_WORD_CONST_DOUBLE}, +}; + +static int _lex_number_postfix(const char* postfix, int n) +{ + scf_key_word_t* key; + int i; + + for (i = 0; i < sizeof(number_postfix) / sizeof(number_postfix[0]); i++) { + key = &number_postfix[i]; + + if (!strncmp(key->text, postfix, n)) + return key->type; + } + + return -EINVAL; +} + static int __lex_getc(scf_lex_t* lex) { if (lex->fp) @@ -78,7 +108,7 @@ scf_char_t* _lex_pop_char(scf_lex_t* lex) c->utf8[i] = ret; } else { - scf_loge("utf8 byte[%d] wrong %#x, file: %s, line: %d\n", i + 1, ret, lex->file->data, lex->nb_lines); + scf_loge("utf8 byte[%d] wrong %#x, file: %s, line: %d\n", i, ret, lex->file->data, lex->nb_lines); free(c); return NULL; } @@ -214,69 +244,93 @@ int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) { - scf_char_t* c2; - scf_char_t* c3; - scf_lex_word_t* w; + scf_char_t* c2; + scf_char_t* c3; + scf_lex_word_t* w; + int type = -1; int dot = 0; int exp = 0; int neg = 0; uint64_t value = 0; uint64_t num; + char postfix[8]; + int n = 0; + while (1) { c2 = _lex_pop_char(lex); - if (c2->c >= '0' && c2->c <= '9') { - num = c2->c - '0'; - value *= 10; - value += num; + int tmp = c2->c; + if ('A' <= tmp && 'Z' >= tmp) + tmp |= 0x20; - } else if ('.' == c2->c) { + if ('a' <= tmp && 'z' >= tmp) { - c3 = _lex_pop_char(lex); + if (n > 0 || 'e' != tmp) { + if (n < sizeof(postfix) - 1) + postfix[n++] = tmp; - _lex_push_char(lex, c3); + goto next; + } + + } else if (n > 0) { + _lex_push_char(lex, c2); + c2 = NULL; + + postfix[n] = '\0'; + + type = _lex_number_postfix(postfix, n); + if (type < 0) { + scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos); + goto error; + } + + break; + } - if ('.' == c3->c) { - c3 = NULL; + if (tmp >= '0' && tmp <= '9') + value = value * 10 + tmp - '0'; + else if ('.' == tmp) { + c3 = _lex_pop_char(lex); + tmp = c3->c; + + _lex_push_char(lex, c3); + c3 = NULL; + + if ('.' == tmp) { _lex_push_char(lex, c2); c2 = NULL; break; } - c3 = NULL; - if (++dot > 1) { scf_loge("\n"); - return -EINVAL; + goto error; } - } else if ('e' == c2->c || 'E' == c2->c) { - exp++; - - if (exp > 1) { + } else if ('e' == tmp) { + if (++exp > 1) { scf_loge("\n"); - return -EINVAL; + goto error; } - } else if ('-' == c2->c) { - neg++; - - if (0 == exp || neg > 1) { + } else if ('-' == tmp) { + if (0 == exp || ++neg > 1) { scf_loge("\n"); - return -EINVAL; + goto error; } } else if ('_' == c2->c) { - + // only to split every 3-4 numbers, no other use. } else { _lex_push_char(lex, c2); c2 = NULL; break; } +next: assert(1 == c2->len); scf_string_cat_cstr_len(s, c2->utf8, 1); lex->pos++; @@ -286,10 +340,18 @@ int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) } if (exp > 0 || dot > 0) { - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE); - w->data.d = atof(s->data); + if (SCF_LEX_WORD_CONST_FLOAT == type) { + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT); + w->data.f = atof(s->data); + } else { + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE); + w->data.d = atof(s->data); + } } else { - if (value & ~0xffffffffULL) + if (type > 0) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type); + + else if (value & ~0xffffffffULL) w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); else w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); @@ -302,57 +364,66 @@ int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) *pword = w; return 0; + +error: + free(c2); + return -EINVAL; } int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) { - scf_char_t* c2; - scf_lex_word_t* w; + scf_char_t* c2; + scf_lex_word_t* w; + int type = -1; uint64_t value = 0; - uint64_t value2; + + char postfix[8]; + int n = 0; while (1) { c2 = _lex_pop_char(lex); - if (c2->c >= '0' && c2->c <= '9') - value2 = c2->c - '0'; - - else if ('a' <= c2->c && 'f' >= c2->c) - value2 = c2->c - 'a' + 10; - - else if ('A' <= c2->c && 'F' >= c2->c) - value2 = c2->c - 'A' + 10; + int tmp = c2->c; + if ('A' <= tmp && 'Z' >= tmp) + tmp |= 0x20; - else if ('_' == c2->c) { - assert(1 == c2->len); - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + if ('g' <= tmp && 'z' >= tmp) { + if (n < sizeof(postfix) - 1) + postfix[n++] = tmp; - free(c2); - c2 = NULL; + goto next; - } else { + } else if (n > 0) { _lex_push_char(lex, c2); c2 = NULL; - if (value & ~0xffffffffULL) - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); - else - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); - - w->data.u64 = value; + postfix[n] = '\0'; - w->text = s; - s = NULL; + type = _lex_number_postfix(postfix, n); + if (type < 0) { + scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos); + goto error; + } - *pword = w; - return 0; + break; } - value <<= 4; - value += value2; + if (tmp >= '0' && tmp <= '9') + value = (value << 4) + tmp - '0'; + + else if ('a' <= tmp && 'f' >= tmp) + value = (value << 4) + tmp - 'a' + 10; + + else if ('_' == tmp) { + // only to split every 3-4 numbers, no other use. + } else { + _lex_push_char(lex, c2); + c2 = NULL; + break; + } +next: assert(1 == c2->len); scf_string_cat_cstr_len(s, c2->utf8, 1); lex->pos++; @@ -360,149 +431,266 @@ int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) free(c2); c2 = NULL; } + + if (type > 0) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type); + + else if (value & ~0xffffffffULL) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); + else + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); + + w->data.u64 = value; + + w->text = s; + s = NULL; + + *pword = w; + return 0; + +error: + free(c2); + return -EINVAL; } int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) { - scf_char_t* c2; - scf_lex_word_t* w; + scf_char_t* c2; + scf_lex_word_t* w; + int type = -1; uint64_t value = 0; + char postfix[8]; + int n = 0; + while (1) { c2 = _lex_pop_char(lex); - if (c2->c >= '0' && c2->c <= '7') { - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + int tmp = c2->c; + if ('A' <= tmp && 'Z' >= tmp) + tmp |= 0x20; - value = (value << 3) + c2->c - '0'; + if ('a' <= tmp && 'z' >= tmp) { + if (n < sizeof(postfix) - 1) + postfix[n++] = tmp; - free(c2); + goto next; + + } else if (n > 0) { + _lex_push_char(lex, c2); c2 = NULL; - } else if ('8' == c2->c || '9' == c2->c) { - scf_loge("number must be 0-7 when base 8"); + postfix[n] = '\0'; - free(c2); - c2 = NULL; - return -1; + type = _lex_number_postfix(postfix, n); + if (type < 0) { + scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos); + goto error; + } - } else if ('_' == c2->c) { - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + break; + } - free(c2); - c2 = NULL; + if (tmp >= '0' && tmp <= '7') + value = (value << 3) + tmp - '0'; + + else if ('8' == tmp || '9' == tmp) { + scf_loge("number must be 0-7 when base 8"); + goto error; + } else if ('_' == tmp) { + // only to split every 3-4 numbers, no other use. } else { _lex_push_char(lex, c2); c2 = NULL; + break; + } - if (value & ~0xffffffffULL) - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); - else - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); - w->data.u64 = value; - - w->text = s; - s = NULL; +next: + assert(1 == c2->len); + scf_string_cat_cstr_len(s, c2->utf8, 1); + lex->pos++; - *pword = w; - return 0; - } + free(c2); + c2 = NULL; } + + if (type > 0) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type); + + else if (value & ~0xffffffffULL) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); + else + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); + w->data.u64 = value; + + w->text = s; + s = NULL; + + *pword = w; + return 0; + +error: + free(c2); + return -EINVAL; } int _lex_number_base_2(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) { - scf_char_t* c2; - scf_lex_word_t* w; + scf_char_t* c2; + scf_lex_word_t* w; + int type = -1; uint64_t value = 0; + char postfix[8]; + int n = 0; + while (1) { c2 = _lex_pop_char(lex); - if (c2->c >= '0' && c2->c <= '1') { - assert(1 == c2->len); - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + int tmp = c2->c; + if ('A' <= tmp && 'Z' >= tmp) + tmp |= 0x20; - value = (value << 1) + c2->c - '0'; + if ('a' <= tmp && 'z' >= tmp) { + if (n < sizeof(postfix) - 1) + postfix[n++] = tmp; - free(c2); + goto next; + + } else if (n > 0) { + _lex_push_char(lex, c2); c2 = NULL; - } else if (c2->c >= '2' && c2->c <= '9') { - scf_loge("number must be 0-1 when base 2"); + postfix[n] = '\0'; - free(c2); - c2 = NULL; - return -1; + type = _lex_number_postfix(postfix, n); + if (type < 0) { + scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos); + goto error; + } - } else if ('_' == c2->c) { - assert(1 == c2->len); - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + break; + } - free(c2); - c2 = NULL; + if (tmp >= '0' && tmp <= '1') + value = (value << 1) + tmp - '0'; + + else if (tmp >= '2' && tmp <= '9') { + scf_loge("number must be 0-1 when base 2"); + goto error; + } else if ('_' == tmp) { + // only to split every 3-4 numbers, no other use. } else { _lex_push_char(lex, c2); c2 = NULL; + break; + } - if (value & ~0xffffffffULL) - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); - else - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); - w->data.u64 = value; - - w->text = s; - s = NULL; +next: + assert(1 == c2->len); + scf_string_cat_cstr_len(s, c2->utf8, 1); + lex->pos++; - *pword = w; - return 0; - } + free(c2); + c2 = NULL; } + + if (type > 0) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type); + + else if (value & ~0xffffffffULL) + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); + else + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32); + w->data.u64 = value; + + w->text = s; + s = NULL; + + *pword = w; + return 0; + +error: + free(c2); + return -EINVAL; } int _lex_double(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s) { - scf_lex_word_t* w; - scf_char_t* c2; + scf_char_t* c2; + scf_lex_word_t* w; + + int type = -1; + char postfix[8]; + int n = 0; while (1) { c2 = _lex_pop_char(lex); - if (c2->c >= '0' && c2->c <= '9') { - scf_string_cat_cstr_len(s, c2->utf8, 1); - lex->pos++; + int tmp = c2->c; + if ('A' <= tmp && 'Z' >= tmp) + tmp |= 0x20; - free(c2); - c2 = NULL; + if ('a' <= tmp && 'z' >= tmp) { + if (n < sizeof(postfix) - 1) + postfix[n++] = tmp; - } else if ('.' == c2->c) { - scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines); + goto next; - free(c2); + } else if (n > 0) { + _lex_push_char(lex, c2); c2 = NULL; - return -1; + postfix[n] = '\0'; + + type = _lex_number_postfix(postfix, n); + if (type < 0) { + scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos); + goto error; + } + + break; + } + + if (tmp >= '0' && tmp <= '9') { + + } else if ('.' == tmp) { + scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines); + goto error; } else { _lex_push_char(lex, c2); c2 = NULL; break; } + +next: + assert(1 == c2->len); + scf_string_cat_cstr_len(s, c2->utf8, 1); + lex->pos++; + + free(c2); + c2 = NULL; } - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE); - w->data.d = atof(s->data); + if (SCF_LEX_WORD_CONST_FLOAT == type) { + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT); + w->data.f = atof(s->data); + } else { + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE); + w->data.d = atof(s->data); + } w->text = s; *pword = w; return 0; + +error: + free(c2); + return -EINVAL; } int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0) @@ -510,8 +698,6 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0) scf_char_t* c1 = _lex_pop_char(lex); scf_char_t* c2 = NULL; scf_lex_word_t* w = NULL; - scf_lex_word_t* w1 = NULL; - scf_lex_word_t* w2 = NULL; scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len); lex->pos += c0->len; @@ -548,48 +734,16 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0) } } else { - w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT); - w->text = s; - s = NULL; - + int tmp = c1->c; _lex_push_char(lex, c1); c1 = NULL; - int ret = __lex_pop_word(lex, &w1); - if (ret < 0) { - scf_lex_word_free(w); - return ret; - } - - if (SCF_LEX_WORD_CONST_CHAR <= w1->type && w1->type <= SCF_LEX_WORD_CONST_U64) { + if ('0' <= tmp && '9' >= tmp) // for double / float .5, .618, etc. + return _lex_double(lex, pword, s); - ret = __lex_pop_word(lex, &w2); - if (ret < 0) { - scf_lex_word_free(w); - scf_lex_word_free(w1); - return ret; - } - - scf_lex_push_word(lex, w2); - - if (w2->type != SCF_LEX_WORD_ASSIGN && w2->type != SCF_LEX_WORD_DOT) { - w->type = SCF_LEX_WORD_CONST_DOUBLE; - - ret = scf_string_cat(w->text, w1->text); - scf_lex_word_free(w1); - w1 = NULL; - - if (ret < 0) { - scf_lex_word_free(w); - return ret; - } - - w->data.d = atof(w->text->data); - } - } - - if (w1) - scf_lex_push_word(lex, w1); + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT); + w->text = s; + s = NULL; } *pword = w; diff --git a/js/lib/scf_rbtree.c b/js/lib/scf_rbtree.c index ff08fcb..0723dff 100644 --- a/js/lib/scf_rbtree.c +++ b/js/lib/scf_rbtree.c @@ -471,9 +471,9 @@ int scf_rbtree_delete(scf_rbtree_t* tree, scf_rbtree_node_t* z) if (&tree->sentinel == y->parent) { tree->root = x; } else if (y->parent->left == y) { - y->parent->left = x; + y->parent->left = x; } else { - y->parent->right = x; + y->parent->right = x; } uint8_t color = y->color; diff --git a/js/native/x64/scf_x64.c b/js/native/x64/scf_x64.c index 7ec69c3..300b9dc 100644 --- a/js/native/x64/scf_x64.c +++ b/js/native/x64/scf_x64.c @@ -52,7 +52,6 @@ static void _x64_argv_rabi(scf_function_t* f) int size = x64_variable_size(v); if (is_float) { - if (f->args_float < X64_ABI_FLOAT_NB) { v->rabi = x64_find_register_type_id_bytes(is_float, x64_abi_float_regs[f->args_float], size); @@ -61,6 +60,7 @@ static void _x64_argv_rabi(scf_function_t* f) f->args_float++; continue; } + } else if (f->args_int < X64_ABI_NB) { v->rabi = x64_find_register_type_id_bytes(is_float, x64_abi_regs[f->args_int], size); @@ -79,12 +79,12 @@ static void _x64_argv_rabi(scf_function_t* f) static int _x64_function_init(scf_function_t* f, scf_vector_t* local_vars) { scf_variable_t* v; + int i; int ret = x64_registers_init(); if (ret < 0) return ret; - int i; for (i = 0; i < local_vars->size; i++) { v = local_vars->data[i]; @@ -109,11 +109,13 @@ static int _x64_function_init(scf_function_t* f, scf_vector_t* local_vars) local_vars_size += size; - if (local_vars_size & 0x7) - local_vars_size = (local_vars_size + 7) >> 3 << 3; + if (v->nb_dimentions > 0) + local_vars_size = (local_vars_size + 0xf) & ~0xf; + else + local_vars_size = (local_vars_size + 0x7) & ~0x7; - v->bp_offset = -local_vars_size; - v->local_flag = 1; + v->bp_offset = -local_vars_size; + v->local_flag = 1; } return local_vars_size; @@ -136,9 +138,12 @@ static int _x64_save_rabi(scf_function_t* f) scf_register_t* xmm1; scf_register_t* xmm2; scf_register_t* xmm3; + scf_register_t* xmm4; + scf_register_t* xmm5; + scf_register_t* xmm6; + scf_register_t* xmm7; if (f->vargs_flag) { - inst = NULL; mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E); @@ -171,11 +176,19 @@ static int _x64_save_rabi(scf_function_t* f) xmm1 = x64_find_register("xmm1"); xmm2 = x64_find_register("xmm2"); xmm3 = x64_find_register("xmm3"); - - X64_SAVE_RABI(-56, xmm0); - X64_SAVE_RABI(-64, xmm1); - X64_SAVE_RABI(-72, xmm2); - X64_SAVE_RABI(-80, xmm3); + xmm4 = x64_find_register("xmm4"); + xmm5 = x64_find_register("xmm5"); + xmm6 = x64_find_register("xmm6"); + xmm7 = x64_find_register("xmm7"); + + X64_SAVE_RABI(-56, xmm0); + X64_SAVE_RABI(-64, xmm1); + X64_SAVE_RABI(-72, xmm2); + X64_SAVE_RABI(-80, xmm3); + X64_SAVE_RABI(-88, xmm4); + X64_SAVE_RABI(-96, xmm5); + X64_SAVE_RABI(-104, xmm6); + X64_SAVE_RABI(-112, xmm7); } return 0; @@ -217,6 +230,10 @@ static int _x64_function_finish(scf_function_t* f) l = scf_list_tail(&bb->code_list_head); end = scf_list_data(l, scf_3ac_code_t, list); + int err = x64_pop_callee_regs(end, f); + if (err < 0) + return err; + if (f->bp_used_flag || f->vla_flag || f->call_flag) { inst = x64_make_inst_G2E(mov, rsp, rbp); @@ -230,16 +247,8 @@ static int _x64_function_finish(scf_function_t* f) bb ->code_bytes += inst->len; } - int err = x64_pop_callee_regs(end, f); - if (err < 0) - return err; - f->init_code_bytes = 0; - err = x64_push_callee_regs(f->init_code, f); - if (err < 0) - return err; - uint32_t local = f->bp_used_flag ? f->local_vars_size : 0; if (f->bp_used_flag || f->vla_flag || f->call_flag) { @@ -252,13 +261,8 @@ static int _x64_function_finish(scf_function_t* f) X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; - if (f->callee_saved_size & 0xf) { - if (!(local & 0xf)) - local += 8; - } else { - if ((local & 0xf)) - local += 8; - } + if ((f->callee_saved_size + local) & 0xf) + local += 8; scf_logd("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n", local, f->local_vars_size, f->callee_saved_size); @@ -267,11 +271,15 @@ static int _x64_function_finish(scf_function_t* f) X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; - int err = _x64_save_rabi(f); + err = _x64_save_rabi(f); if (err < 0) return err; } + err = x64_push_callee_regs(f->init_code, f); + if (err < 0) + return err; + inst = x64_make_inst(ret, 8); X64_INST_ADD_CHECK(end->instructions, inst, NULL); end->inst_bytes += inst->len; @@ -1120,11 +1128,13 @@ int scf_x64_select_inst(scf_native_t* ctx, scf_function_t* f) scf_logi("---------- %s() ------------\n", f->node.w->text->data); + scf_variable_t* v; int i; + for (i = 0; i < local_vars->size; i++) { - scf_variable_t* v = local_vars->data[i]; - assert(v->w); + v = local_vars->data[i]; + assert(v->w); scf_logd("v: %p, name: %s_%d_%d, size: %d, bp_offset: %d, arg_flag: %d\n", v, v->w->text->data, v->w->line, v->w->pos, scf_variable_size(v), v->bp_offset, v->arg_flag); diff --git a/js/native/x64/scf_x64_inst.c b/js/native/x64/scf_x64_inst.c index 51c6b9b..9921814 100644 --- a/js/native/x64/scf_x64_inst.c +++ b/js/native/x64/scf_x64_inst.c @@ -528,8 +528,10 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_INST_ADD_CHECK(c->instructions, inst, NULL); scf_register_t* saved_regs[X64_ABI_CALLER_SAVES_NB]; + scf_register_t* drop_regs [X64_ABI_CALLER_SAVES_NB]; + int n_drops = 0; - int save_size = x64_caller_save_regs(c, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs); + int save_size = x64_caller_save_regs(c, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs, drop_regs, &n_drops); if (save_size < 0) { scf_loge("\n"); return save_size; @@ -593,6 +595,8 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_INST_ADD_CHECK(c->instructions, inst, NULL); } + x64_drop_regs(drop_regs, n_drops); + int nb_updated = 0; scf_register_t* updated_regs[X64_ABI_RET_NB * 2]; diff --git a/js/native/x64/scf_x64_inst_common.c b/js/native/x64/scf_x64_inst_common.c index cdd4fbd..1d9eba7 100644 --- a/js/native/x64/scf_x64_inst_common.c +++ b/js/native/x64/scf_x64_inst_common.c @@ -86,18 +86,21 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ else X64_SELECT_REG_CHECK(&rd, dst, c, f, 1); - OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2G); - if (OpCode) { - inst = x64_make_inst_I2G(OpCode, rd, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst, NULL); - return 0; - } + if (scf_variable_const_integer(src->var)) { - OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); - if (OpCode) { - inst = x64_make_inst_I2E(OpCode, rd, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst, NULL); - return 0; + OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2G); + if (OpCode) { + inst = x64_make_inst_I2G(OpCode, rd, (uint8_t*)&src->var->data, src_size); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); + return 0; + } + + OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); + if (OpCode) { + inst = x64_make_inst_I2E(OpCode, rd, (uint8_t*)&src->var->data, src_size); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); + return 0; + } } OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_G2E); @@ -120,12 +123,15 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ return 0; } - OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); - if (OpCode) { - inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst, rela); - X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); - return 0; + if (scf_variable_const_integer(src->var)) { + + OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); + if (OpCode) { + inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size); + X64_INST_ADD_CHECK(c->instructions, inst, rela); + X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); + return 0; + } } OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_G2E); @@ -149,36 +155,6 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ return 0; } -static int _x64_inst_op2_imm_str(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f) -{ - if (SCF_X64_MOV != OpCode_type) { - scf_loge("\n"); - return -EINVAL; - } - - scf_register_t* rd = NULL; - scf_instruction_t* inst = NULL; - scf_x64_OpCode_t* lea = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G); - scf_rela_t* rela = NULL; - - int size0 = x64_variable_size(dst->var); - int size1 = x64_variable_size(src->var); - - assert(8 == size0); - assert(8 == size1); - - X64_SELECT_REG_CHECK(&rd, dst, c, f, 0); - - src->var->global_flag = 1; - src->var->local_flag = 0; - src->var->tmp_flag = 0; - - inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst, rela); - X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); - return 0; -} - int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f) { assert(0 != dst->color); @@ -190,9 +166,13 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ scf_rela_t* rela = NULL; if (0 == src->color) { + if (scf_variable_const_string(src->var)) { + if (SCF_X64_MOV != OpCode_type) + return -EINVAL; + X64_SELECT_REG_CHECK(&rd, dst, c, f, 0); - if (scf_variable_const_string(src->var)) - return _x64_inst_op2_imm_str(OpCode_type, dst, src, c, f); + return x64_load_const(rd, src, c, f); + } if (!scf_variable_float(src->var)) return _x64_inst_op2_imm(OpCode_type, dst, src, c, f); diff --git a/js/native/x64/scf_x64_peephole.c b/js/native/x64/scf_x64_peephole.c index 57f906c..147a303 100644 --- a/js/native/x64/scf_x64_peephole.c +++ b/js/native/x64/scf_x64_peephole.c @@ -3,18 +3,20 @@ #include"scf_basic_block.h" #include"scf_3ac.h" -static int _x64_peephole_mov(scf_vector_t* std_insts, scf_instruction_t* inst) +static int _x64_peephole_mov(scf_vector_t* save_insts, scf_vector_t* peep_insts, scf_instruction_t* inst) { - scf_3ac_code_t* c = inst->c; - scf_basic_block_t* bb = c->basic_block; + scf_3ac_code_t* c = inst->c; + scf_basic_block_t* bb = c->basic_block; - scf_instruction_t* inst2; - scf_instruction_t* std; - scf_x64_OpCode_t* OpCode; + scf_register_t* r0; + scf_register_t* r1; + scf_x64_OpCode_t* OpCode; + scf_instruction_t* inst2; + scf_instruction_t* std; int j; - for (j = std_insts->size - 1; j >= 0; j--) { - std = std_insts->data[j]; + for (j = peep_insts->size - 1; j >= 0; j--) { + std = peep_insts->data[j]; #if 0 scf_loge("std j: %d\n", j); scf_3ac_code_print(std->c, NULL); @@ -67,12 +69,13 @@ static int _x64_peephole_mov(scf_vector_t* std_insts, scf_instruction_t* inst) return X64_PEEPHOLE_DEL; } - assert(0 == scf_vector_del(std_insts, std)); + assert(0 == scf_vector_del(peep_insts, std)); if (std->nb_used > 0) continue; assert(0 == scf_vector_del(std->c->instructions, std)); + assert(0 == scf_vector_del(save_insts, std)); free(std); std = NULL; @@ -175,20 +178,16 @@ static int _x64_peephole_mov(scf_vector_t* std_insts, scf_instruction_t* inst) } } else if (scf_inst_data_same(&std->src, &inst->dst)) { - assert(0 == scf_vector_del(std_insts, std)); + assert(0 == scf_vector_del(peep_insts, std)); } else if (x64_inst_data_is_reg(&std->src)) { - scf_register_t* r0; - scf_register_t* r1; - if (x64_inst_data_is_reg(&inst->dst)) { - r0 = std ->src.base; r1 = inst->dst.base; if (X64_COLOR_CONFLICT(r0->color, r1->color)) - assert(0 == scf_vector_del(std_insts, std)); + assert(0 == scf_vector_del(peep_insts, std)); } } else if (x64_inst_data_is_reg(&std->dst)) { @@ -201,33 +200,41 @@ static int _x64_peephole_mov(scf_vector_t* std_insts, scf_instruction_t* inst) } } - assert(0 == scf_vector_add_unique(std_insts, inst)); + if (x64_inst_data_is_reg(&inst->dst)) { + r1 = inst->dst.base; + + for (j = peep_insts->size - 1; j >= 0; j--) { + std = peep_insts->data[j]; + + if ((std->src.flag && (std->src.base == r1 || std->src.index == r1)) + || (std->dst.flag && (std->dst.base == r1 || std->dst.index == r1))) + assert(0 == scf_vector_del(peep_insts, std)); + } + } + + assert(0 == scf_vector_add_unique(peep_insts, inst)); return 0; } -static int _x64_peephole_cmp(scf_vector_t* std_insts, scf_instruction_t* inst) +static int _x64_peephole_cmp(scf_vector_t* save_insts, scf_vector_t* peep_insts, scf_instruction_t* inst) { - scf_3ac_code_t* c = inst->c; - scf_basic_block_t* bb = c->basic_block; - - scf_instruction_t* inst2; - scf_instruction_t* std; + scf_3ac_code_t* c = inst->c; + scf_basic_block_t* bb = c->basic_block; + scf_instruction_t* inst2; + scf_instruction_t* std; int j; - for (j = std_insts->size - 1; j >= 0; j--) { - std = std_insts->data[j]; + for (j = peep_insts->size - 1; j >= 0; j--) { + std = peep_insts->data[j]; if (SCF_X64_LEA == std->OpCode->type) break; if (inst->src.flag) { - if (scf_inst_data_same(&inst->src, &std->src)) - inst->src.base = std->dst.base; else if (scf_inst_data_same(&inst->src, &std->dst)) - inst->src.base = std->src.base; else goto check; @@ -244,11 +251,9 @@ static int _x64_peephole_cmp(scf_vector_t* std_insts, scf_instruction_t* inst) } else if (inst->dst.flag) { if (scf_inst_data_same(&inst->dst, &std->src)) - inst->dst.base = std->dst.base; else if (scf_inst_data_same(&inst->dst, &std->dst)) - inst->dst.base = std->src.base; else goto check; @@ -295,42 +300,6 @@ check: return 0; } -static int _x64_peephole_movx(scf_vector_t* std_insts, scf_instruction_t* inst) -{ - if (!x64_inst_data_is_reg(&inst->src) || !x64_inst_data_is_reg(&inst->dst)) { - scf_vector_clear(std_insts, NULL); - return 0; - } - - scf_3ac_code_t* c = inst->c; - scf_basic_block_t* bb = c->basic_block; - scf_instruction_t* std; - scf_x64_OpCode_t* OpCode; - int j; - - for (j = std_insts->size - 1; j >= 0; j--) { - std = std_insts->data[j]; - - if (scf_inst_data_same(&std->dst, &inst->src)) { - std->nb_used++; - - if (std->OpCode == inst->OpCode - && scf_inst_data_same(&std->src, &inst->src) - && scf_inst_data_same(&std->dst, &inst->dst)) { - - assert(0 == scf_vector_del(inst->c->instructions, inst)); - - free(inst); - inst = NULL; - return X64_PEEPHOLE_DEL; - } - } - } - - assert(0 == scf_vector_add_unique(std_insts, inst)); - return 0; -} - static int x64_inst_is_useful(scf_instruction_t* inst, scf_instruction_t* std) { if (scf_inst_data_same(&inst->dst, &std->src)) @@ -478,15 +447,15 @@ static int __x64_inst_useful_bb_next(scf_basic_block_t* bb, void* data, scf_vect return 0; } -static int _x64_peephole_function(scf_vector_t* tmp_insts, scf_function_t* f) +static int _x64_peephole_function(scf_vector_t* save_insts, scf_function_t* f) { scf_instruction_t* inst; scf_basic_block_t* bb; scf_3ac_code_t* c; int i; - for (i = tmp_insts->size - 1; i >= 0; i--) { - inst = tmp_insts->data[i]; + for (i = save_insts->size - 1; i >= 0; i--) { + inst = save_insts->data[i]; if (SCF_X64_MOV != inst->OpCode->type) continue; @@ -510,7 +479,7 @@ static int _x64_peephole_function(scf_vector_t* tmp_insts, scf_function_t* f) continue; assert(0 == scf_vector_del(c->instructions, inst)); - assert(0 == scf_vector_del(tmp_insts, inst)); + assert(0 == scf_vector_del(save_insts, inst)); free(inst); inst = NULL; @@ -518,8 +487,8 @@ static int _x64_peephole_function(scf_vector_t* tmp_insts, scf_function_t* f) int n_locals = 0; - for (i = 0; i < tmp_insts->size; i++) { - inst = tmp_insts->data[i]; + for (i = 0; i < save_insts->size; i++) { + inst = save_insts->data[i]; if (x64_inst_data_is_local(&inst->src) || x64_inst_data_is_local(&inst->dst)) n_locals++; @@ -536,7 +505,6 @@ static int _x64_peephole_function(scf_vector_t* tmp_insts, scf_function_t* f) int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) { - scf_instruction_t* std; scf_instruction_t* inst; scf_basic_block_t* bb; scf_3ac_operand_t* dst; @@ -544,16 +512,16 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) scf_list_t* l; scf_list_t* l2; - scf_vector_t* std_insts; - scf_vector_t* tmp_insts; // instructions for register or local variable + scf_vector_t* peep_insts; + scf_vector_t* save_insts; - std_insts = scf_vector_alloc(); - if (!std_insts) + peep_insts = scf_vector_alloc(); + if (!peep_insts) return -ENOMEM; - tmp_insts = scf_vector_alloc(); - if (!tmp_insts) { - scf_vector_free(tmp_insts); + save_insts = scf_vector_alloc(); + if (!save_insts) { + scf_vector_free(save_insts); return -ENOMEM; } @@ -569,7 +537,7 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) bb = scf_list_data(l, scf_basic_block_t, list); if (bb->jmp_flag) { - scf_vector_clear(std_insts, NULL); + scf_vector_clear(peep_insts, NULL); l2 = scf_list_head(&bb->code_list_head); c = scf_list_data(l2, scf_3ac_code_t, list); @@ -582,9 +550,8 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) continue; } - if (bb->jmp_dst_flag) { - scf_vector_clear(std_insts, NULL); - } + if (bb->jmp_dst_flag) + scf_vector_clear(peep_insts, NULL); for (l2 = scf_list_head(&bb->code_list_head); l2 != scf_list_sentinel(&bb->code_list_head); l2 = scf_list_next(l2)) { @@ -603,26 +570,26 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) // scf_instruction_print(inst); ret = 0; - switch (inst->OpCode->type) { - + switch (inst->OpCode->type) + { case SCF_X64_CMP: case SCF_X64_TEST: - ret = _x64_peephole_cmp(std_insts, inst); + ret = _x64_peephole_cmp(save_insts, peep_insts, inst); break; case SCF_X64_MOV: - ret = _x64_peephole_mov(std_insts, inst); + ret = _x64_peephole_mov(save_insts, peep_insts, inst); break; case SCF_X64_LEA: - ret = scf_vector_add_unique(std_insts, inst); + ret = scf_vector_add_unique(peep_insts, inst); break; case SCF_X64_MOVSS: case SCF_X64_MOVSD: break; default: - scf_vector_clear(std_insts, NULL); + scf_vector_clear(peep_insts, NULL); break; }; @@ -632,7 +599,7 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) if (X64_PEEPHOLE_DEL == ret) continue; - ret = scf_vector_add(tmp_insts, inst); + ret = scf_vector_add(save_insts, inst); if (ret < 0) goto error; i++; @@ -640,9 +607,9 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) } } - ret = _x64_peephole_function(tmp_insts, f); + ret = _x64_peephole_function(save_insts, f); error: - scf_vector_free(tmp_insts); - scf_vector_free(std_insts); + scf_vector_free(save_insts); + scf_vector_free(peep_insts); return ret; } diff --git a/js/native/x64/scf_x64_reg.c b/js/native/x64/scf_x64_reg.c index efcc9aa..9374eed 100644 --- a/js/native/x64/scf_x64_reg.c +++ b/js/native/x64/scf_x64_reg.c @@ -95,7 +95,7 @@ void x64_registers_print() } } -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_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs, scf_register_t** drop_regs, int* n_drops) { scf_basic_block_t* bb = c->basic_block; scf_dag_node_t* dn; @@ -119,6 +119,8 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int for (j = 0; j < nb_regs; j++) { r2 = x64_find_register(regs[j]); + int drop_flag = 0; + for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) { r = &(x64_registers[i]); @@ -148,11 +150,15 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int if (k < r->dag_nodes->size) break; + drop_flag = 1; } } - if (i == sizeof(x64_registers) / sizeof(x64_registers[0])) + if (i == sizeof(x64_registers) / sizeof(x64_registers[0])) { + if (drop_flag) + drop_regs[(*n_drops)++] = r2; continue; + } if (X64_COLOR_TYPE(r2->color)) { if (stack_size > 0) @@ -693,6 +699,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf scf_instruction_t* inst; scf_x64_OpCode_t* lea; scf_x64_OpCode_t* mov; + scf_x64_OpCode_t* xor; scf_variable_t* v; v = dn->var; @@ -701,34 +708,9 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf int size = x64_variable_size(v); int is_float = scf_variable_float(v); - if (SCF_FUNCTION_PTR == v->type) { - - if (v->func_ptr) { - assert(v->const_literal_flag); - - v->global_flag = 1; - v->local_flag = 0; - v->tmp_flag = 0; - - scf_rela_t* rela = NULL; - - lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); - inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst, rela); - X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr); - - } else { - scf_x64_OpCode_t* xor; - - xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E); - inst = x64_make_inst_G2E(xor, r, r); - X64_INST_ADD_CHECK(c->instructions, inst, NULL); - } - - } else if (scf_variable_const_string(v)) { - - scf_rela_t* rela = NULL; + scf_rela_t* rela = NULL; + if (scf_variable_const_string(v)) { v->global_flag = 1; v->local_flag = 0; v->tmp_flag = 0; @@ -742,14 +724,29 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf } else if (v->nb_dimentions > 0) { assert(v->const_literal_flag); - scf_rela_t* rela = NULL; - lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); + } else if (SCF_FUNCTION_PTR == v->type) { + if (v->func_ptr) { + assert(v->const_literal_flag); + + v->global_flag = 1; + v->local_flag = 0; + v->tmp_flag = 0; + + lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); + inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); + X64_INST_ADD_CHECK(c->instructions, inst, rela); + X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr); + } else { + xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E); + inst = x64_make_inst_G2E(xor, r, r); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); + } } else { mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size); @@ -1181,6 +1178,46 @@ void x64_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c) *p_nfloats = nfloats; } +int x64_drop_regs(scf_register_t** drop_regs, int n_drops) +{ + scf_register_t* r2; + scf_register_t* r; + scf_dag_node_t* dn; + scf_variable_t* v; + + int N = sizeof(x64_registers) / sizeof(x64_registers[0]); + int i; + int j; + + for (j = 0; j < N; j++) { + r2 = &(x64_registers[j]); + + if (!r2->dag_nodes || r2->dag_nodes->size <= 0) + continue; + + for (i = 0; i < n_drops; i++) { + r = drop_regs[i]; + + if (X64_COLOR_CONFLICT(r2->color, r->color)) + break; + } + + if (i >= n_drops) + continue; + + for (i = 0; i < r2->dag_nodes->size; i++) { + dn = r2->dag_nodes->data[i]; + + dn->color = -1; + dn->loaded = 0; + } + + r2->dag_nodes->size = 0; + } + + return 0; +} + int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f) { scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); @@ -1217,7 +1254,6 @@ 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) { scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G); - scf_basic_block_t* bb = c->basic_block; scf_instruction_t* inst; diff --git a/js/native/x64/scf_x64_reg.h b/js/native/x64/scf_x64_reg.h index 0e59579..9be5f65 100644 --- a/js/native/x64/scf_x64_reg.h +++ b/js/native/x64/scf_x64_reg.h @@ -112,7 +112,9 @@ 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, const char* 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_register_t** drop_regs, int* n_drops); + +int x64_drop_regs(scf_register_t** drop_regs, int n_drops); 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/scf_dfa_call.c b/js/parse/scf_dfa_call.c index 7197a1b..47b0754 100644 --- a/js/parse/scf_dfa_call.c +++ b/js/parse/scf_dfa_call.c @@ -108,7 +108,7 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } } else { - if (Object->type != var_pf->type) { + if (Object->node.type != var_pf->type) { scf_loge("invalid function ptr\n"); return SCF_DFA_ERROR; } @@ -228,7 +228,7 @@ static int _call_add_arguments(scf_ast_t* ast, scf_lex_word_t* w, int n_members, } // add construct() for obj - v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL); + v = SCF_VAR_ALLOC_BY_TYPE(Object->node.w, pt, 1, 1, NULL); if (!v) { scf_node_free(assign); return -ENOMEM; @@ -251,7 +251,7 @@ static int _call_add_arguments(scf_ast_t* ast, scf_lex_word_t* w, int n_members, } // add obj name - ret = scf_ast_add_const_str(ast, new, Object->w); + ret = scf_ast_add_const_str(ast, new, Object->node.w); if (ret < 0) { scf_node_free(assign); return ret; @@ -293,7 +293,7 @@ static int _call_add_arguments(scf_ast_t* ast, scf_lex_word_t* w, int n_members, return ret; } - e->js_new = e2; + e->js_new = assign; return 0; } @@ -309,7 +309,7 @@ int _call_add_obj(scf_ast_t* ast, scf_lex_word_t* w, scf_node_t* call, scf_expr_ if (ret < 0) return ret; - if (v->type == Object->type) { + if (v->type == Object->node.type) { scf_variable_free(v); return 0; } @@ -444,22 +444,28 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (ret < 0) return ret; - int js_flag = 1; + int js_flag = 1; + int timer_flag = 0; + if (SCF_FUNCTION_PTR == pf->type) { f = pf->var->func_ptr; js_flag = f->js_flag; - scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag); + if (!strcmp(f->node.w->text->data, "setTimeout")) + timer_flag = 1; + + scf_logd("f: %s, f->js_flag: %d, timer_flag: %d\n", f->node.w->text->data, f->js_flag, timer_flag); } else - assert(Object->type == pf->type); + assert(Object->node.type == pf->type); + int i = 0; if (cd->argv) { - int i; - for (i = 0; i < cd->argv->size; i++) { - e = cd->argv->data[i]; + for ( ; i < cd->argv->size; i++) { + e = cd->argv->data[i]; - if (js_flag) { + if (js_flag || (timer_flag && i > 1)) + { ret = _call_add_obj(ast, w, cd->call, e, Object); if (ret < 0) return ret; @@ -474,7 +480,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) // the last arg if (d->expr) { - if (js_flag) { + if (js_flag || (timer_flag && i > 1)) + { ret = _call_add_obj(ast, w, cd->call, d->expr, Object); if (ret < 0) return ret; @@ -484,16 +491,25 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->expr = NULL; } - if (js_flag) { + if (js_flag || timer_flag) { e = scf_expr_alloc(); if (!e) return -ENOMEM; - ret = _call_add_arguments(ast, w, cd->call->nb_nodes - 1, e, Object); - if (ret < 0) + if (js_flag) + ret = _call_add_arguments(ast, w, cd->call->nb_nodes - 1, e, Object); + else + ret = scf_ast_add_const_var(ast, e, SCF_VAR_INT, cd->call->nb_nodes - 3); + if (ret < 0) { + scf_expr_free(e); return ret; + } - scf_node_add_child(cd->call, e); + ret = scf_node_add_child(cd->call, e); + if (ret < 0) { + scf_expr_free(e); + return ret; + } int i; for (i = cd->call->nb_nodes - 2; i >= 1; i--) diff --git a/js/parse/scf_dfa_class.c b/js/parse/scf_dfa_class.c index 5429e61..dc9fb5c 100644 --- a/js/parse/scf_dfa_class.c +++ b/js/parse/scf_dfa_class.c @@ -54,7 +54,7 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat md->parent_block = parse->ast->current_block; SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); - scf_logi("\033[31m t: %p, t->type: %d\033[0m\n", t, t->type); + scf_logi("\033[31m t: %p, t->type: %d\033[0m\n", t, t->node.type); return SCF_DFA_NEXT_WORD; } diff --git a/js/parse/scf_dfa_container.c b/js/parse/scf_dfa_container.c index 5a2ac2b..03d1bbb 100644 --- a/js/parse/scf_dfa_container.c +++ b/js/parse/scf_dfa_container.c @@ -120,7 +120,7 @@ static int _container_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* da return SCF_DFA_ERROR; } - if (id->type->type < SCF_STRUCT) { + if (id->type->node.type < SCF_STRUCT) { scf_loge("'%s' is not a class or struct\n", w->text->data); free(id); return SCF_DFA_ERROR; diff --git a/js/parse/scf_dfa_expr.c b/js/parse/scf_dfa_expr.c index 75337c1..5b4d206 100644 --- a/js/parse/scf_dfa_expr.c +++ b/js/parse/scf_dfa_expr.c @@ -152,9 +152,9 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) scf_scope_push_type(b->scope, t); scf_node_add_child((scf_node_t*)b, (scf_node_t*)t); - md->current_var->js_type = t->type; + md->current_var->js_type = t->node.type; - scf_logi("md->current_var->js_type: %d, %s\n", t->type, t->name->data); + scf_logi("md->current_var->js_type: %d, %s\n", t->node.type, t->name->data); } t2 = NULL; @@ -187,7 +187,8 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) if (md->current_var && md->current_var->js_type >= 0 && var->member_flag - && strcmp(var->w->text->data, "length")) { + && strcmp(var->w->text->data, "length") + && strcmp(var->w->text->data, "innerHTML")) { scf_logi("md->current_var: %s, var: %s, member_flag: %d, line: %d, pos: %d\n", md->current_var->w->text->data, var->w->text->data, var->member_flag, var->w->line, var->w->pos); @@ -850,7 +851,7 @@ int _expr_multi_rets(scf_expr_t* e) scf_variable_t* v_pf = _scf_operand_get(n_pf); scf_function_t* f = v_pf->func_ptr; - if (f->rets->size <= 1) + if (!f || f->rets->size <= 1) return 0; nb_rets = f->rets->size; diff --git a/js/parse/scf_dfa_function.c b/js/parse/scf_dfa_function.c index fe0748e..3a14de6 100644 --- a/js/parse/scf_dfa_function.c +++ b/js/parse/scf_dfa_function.c @@ -59,7 +59,7 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) return SCF_DFA_ERROR; } - if (SCF_VAR_VOID == id->type->type && 0 == id->nb_pointers) + if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers) void_flag = 1; f->extern_flag |= id->extern_flag; @@ -152,7 +152,7 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d) if (v && v->identity) w = v->identity; - if (SCF_VAR_VOID == t->type->type && 0 == t->nb_pointers) { + if (SCF_VAR_VOID == t->type->node.type && 0 == t->nb_pointers) { scf_loge("\n"); return SCF_DFA_ERROR; } diff --git a/js/parse/scf_dfa_function_js.c b/js/parse/scf_dfa_function_js.c index 97ff26b..61e733f 100644 --- a/js/parse/scf_dfa_function_js.c +++ b/js/parse/scf_dfa_function_js.c @@ -84,7 +84,7 @@ int _function_js_add_arg(scf_ast_t* ast, scf_lex_word_t* w, dfa_data_t* d) arg = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL); if (!arg) return SCF_DFA_ERROR; - arg->js_type = t->type; + arg->js_type = t->node.type; scf_scope_push_var(d->current_function->scope, arg); diff --git a/js/parse/scf_dfa_goto.c b/js/parse/scf_dfa_goto.c index b3ea503..2c035d5 100644 --- a/js/parse/scf_dfa_goto.c +++ b/js/parse/scf_dfa_goto.c @@ -31,11 +31,9 @@ static int _goto_action_identity(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]; + scf_node_t* node = scf_node_alloc(w, SCF_LABEL, NULL); - scf_label_t* l = scf_label_alloc(w); - scf_node_t* n = scf_node_alloc_label(l); - - scf_node_add_child(d->current_goto, n); + scf_node_add_child(d->current_goto, node); return SCF_DFA_NEXT_WORD; } diff --git a/js/parse/scf_dfa_include.c b/js/parse/scf_dfa_include.c index cd0c333..fb4bb60 100644 --- a/js/parse/scf_dfa_include.c +++ b/js/parse/scf_dfa_include.c @@ -25,7 +25,7 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_logd("include '%s', line %d\n", w->data.s->data, w->line); parse->lex = NULL; - parse->ast->current_block = parse->ast->root_block; +// parse->ast->current_block = parse->ast->root_block; int ret = scf_parse_file(parse, w->data.s->data, NULL); if (ret < 0) { @@ -33,7 +33,7 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data) goto error; } - if (parse->lex != lex && parse->lex->macros) { // copy macros + if (parse->lex && parse->lex != lex && parse->lex->macros) { // copy macros if (!lex->macros) { lex->macros = scf_vector_clone(parse->lex->macros); diff --git a/js/parse/scf_dfa_init_data.c b/js/parse/scf_dfa_init_data.c index 2eb7808..8d61fbe 100644 --- a/js/parse/scf_dfa_init_data.c +++ b/js/parse/scf_dfa_init_data.c @@ -92,8 +92,8 @@ 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->js_type = s->type; + obj->type = s->node.type; + obj->js_type = s->node.type; scf_logi("obj->w: %s\n", obj->w->text->data); } else { int ret = scf_ast_find_type_type(&s, ast, obj->type); @@ -437,14 +437,14 @@ static int _data_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child((scf_node_t*)md->parent_block, (scf_node_t*)s); if (ast->current_block == md->parent_block) - d->current_var->js_type = s->type; + d->current_var->js_type = s->node.type; ast->current_block = (scf_block_t*)s; - obj->type = s->type; - obj->js_type = s->type; + obj->type = s->node.type; + obj->js_type = s->node.type; - scf_loge("s: %p, js_type: %d, obj: %p, obj->w: %s, md->nb_lbs: %d\n", s, s->type, obj, obj->w->text->data, md->nb_lbs); + scf_loge("s: %p, js_type: %d, obj: %p, obj->w: %s, md->nb_lbs: %d\n", s, s->node.type, obj, obj->w->text->data, md->nb_lbs); SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "init_data_comma"), SCF_DFA_HOOK_POST); diff --git a/js/parse/scf_dfa_label.c b/js/parse/scf_dfa_label.c index a017cf7..f8679fa 100644 --- a/js/parse/scf_dfa_label.c +++ b/js/parse/scf_dfa_label.c @@ -16,7 +16,7 @@ static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) } scf_label_t* l = scf_label_alloc(id->identity); - scf_node_t* n = scf_node_alloc_label(l); + scf_node_t* n = scf_node_alloc(l->w, SCF_LABEL, NULL); scf_stack_pop(d->current_identities); free(id); @@ -24,6 +24,7 @@ static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child((scf_node_t*)parse->ast->current_block, n); + l->node = n; scf_scope_push_label(parse->ast->current_block->scope, l); return SCF_DFA_OK; diff --git a/js/parse/scf_dfa_new.c b/js/parse/scf_dfa_new.c index 4598774..cab7bcf 100644 --- a/js/parse/scf_dfa_new.c +++ b/js/parse/scf_dfa_new.c @@ -104,7 +104,7 @@ static int __js_init_func(scf_ast_t* ast, scf_function_t* f) } // add 'Object()' - pf = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL); + pf = SCF_VAR_ALLOC_BY_TYPE(Object->node.w, pt, 1, 1, NULL); if (!pf) { scf_node_free(assign); return -ENOMEM; @@ -242,9 +242,9 @@ static int _new_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) } if (d->current_var && strcmp(t->name->data, "Object")) { - d->current_var->js_type = t->type; + d->current_var->js_type = t->node.type; scf_logw("type '%s', t->type: %d, d->current_var: %s, type: %d, js_type: %d\n", - t->name->data, t->type, d->current_var->w->text->data, d->current_var->type, d->current_var->js_type); + t->name->data, t->node.type, d->current_var->w->text->data, d->current_var->type, d->current_var->js_type); } if (scf_ast_find_type_type(&pt, parse->ast, SCF_FUNCTION_PTR) < 0) diff --git a/js/parse/scf_dfa_type.c b/js/parse/scf_dfa_type.c index 5ef9055..7e72383 100644 --- a/js/parse/scf_dfa_type.c +++ b/js/parse/scf_dfa_type.c @@ -132,7 +132,7 @@ int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id) } } - if (SCF_FUNCTION_PTR == id->type->type) { + if (SCF_FUNCTION_PTR == id->type->node.type) { id->func_ptr = _type_find_function(parse->ast->current_block, id->identity->text->data); diff --git a/js/parse/scf_dfa_va_arg.c b/js/parse/scf_dfa_va_arg.c index 0a4dc98..918690c 100644 --- a/js/parse/scf_dfa_va_arg.c +++ b/js/parse/scf_dfa_va_arg.c @@ -120,7 +120,7 @@ static int _va_arg_action_ap(scf_dfa_t* dfa, scf_vector_t* words, void* data) } assert(t); - if (t->type != ap->type || 0 != ap->nb_dimentions) { + if (t->node.type != ap->type || 0 != ap->nb_dimentions) { scf_loge("variable %s is not va_list type\n", w->text->data); return SCF_DFA_ERROR; } diff --git a/js/parse/scf_dfa_var.c b/js/parse/scf_dfa_var.c index 33506f7..5dd4249 100644 --- a/js/parse/scf_dfa_var.c +++ b/js/parse/scf_dfa_var.c @@ -8,7 +8,7 @@ int _expr_multi_rets(scf_expr_t* e); int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w) { - if (child->type == parent->type) { + if (child->node.type == parent->node.type) { scf_loge("recursive define '%s' type member var '%s' in type '%s', line: %d\n", child->name->data, w->text->data, parent->name->data, w->line); @@ -17,7 +17,7 @@ int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w) } if (child->scope) { - assert(child->type >= SCF_STRUCT); + assert(child->node.type >= SCF_STRUCT); scf_variable_t* v = NULL; scf_type_t* type_v = NULL; @@ -85,7 +85,7 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) global_flag = 0; member_flag = 1; - if (0 == id0->nb_pointers && id0->type->type >= SCF_STRUCT) { + if (0 == id0->nb_pointers && id0->type->node.type >= SCF_STRUCT) { // if not pointer var, check if define recursive struct/union/class var if (_check_recursive((scf_type_t*)b, id0->type, id->identity) < 0) { @@ -97,7 +97,7 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) } } - if (SCF_FUNCTION_PTR == id0->type->type + if (SCF_FUNCTION_PTR == id0->type->node.type && (!id0->func_ptr || 0 == id0->nb_pointers)) { scf_loge("invalid func ptr\n"); return SCF_DFA_ERROR; @@ -116,12 +116,12 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) } } - if (SCF_VAR_VOID == id0->type->type && 0 == id0->nb_pointers) { + if (SCF_VAR_VOID == id0->type->node.type && 0 == id0->nb_pointers) { scf_loge("void var must be a pointer, like void*\n"); return SCF_DFA_ERROR; } - if (SCF_VAR_VAR == id0->type->type) { + if (SCF_VAR_VAR == id0->type->node.type) { id0->nb_pointers = 1; if (scf_ast_find_type(&id0->type, parse->ast, "Object") < 0) diff --git a/js/parse/scf_operator_handler_const.c b/js/parse/scf_operator_handler_const.c index 35ebbae..656b792 100644 --- a/js/parse/scf_operator_handler_const.c +++ b/js/parse/scf_operator_handler_const.c @@ -620,7 +620,7 @@ static int _scf_op_const_unary(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, scf_calculate_t* cal = scf_find_base_calculate(parent->type, v0->type, v0->type); if (!cal) { - scf_loge("type %d not support\n", v0->type); + scf_loge("type %d not support, SCF_VAR_U64: %d\n", v0->type, SCF_VAR_U64); return -EINVAL; } diff --git a/js/parse/scf_operator_handler_semantic.c b/js/parse/scf_operator_handler_semantic.c index f3eacb6..5742ece 100644 --- a/js/parse/scf_operator_handler_semantic.c +++ b/js/parse/scf_operator_handler_semantic.c @@ -150,7 +150,7 @@ static int _semantic_do_type_cast(scf_ast_t* ast, scf_node_t** nodes, int nb_nod if (!v_std) return -ENOMEM; - if (t->type != v0->type) { + if (t->node.type != v0->type) { ret = _semantic_add_type_cast(ast, &nodes[0], v_std, nodes[0]); if (ret < 0) { scf_loge("add type cast failed\n"); @@ -158,7 +158,7 @@ static int _semantic_do_type_cast(scf_ast_t* ast, scf_node_t** nodes, int nb_nod } } - if (t->type != v1->type) { + if (t->node.type != v1->type) { ret = _semantic_add_type_cast(ast, &nodes[1], v_std, nodes[1]); if (ret < 0) { scf_loge("add type cast failed\n"); @@ -467,12 +467,12 @@ static int _semantic_do_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, sc if (!new) return -ENOMEM; - v_pf = SCF_VAR_ALLOC_BY_TYPE(t->w, pt, 1, 1, NULL); + v_pf = SCF_VAR_ALLOC_BY_TYPE(t->node.w, pt, 1, 1, NULL); if (!v_pf) return -ENOMEM; v_pf->const_literal_flag = 1; - node_pf = scf_node_alloc(t->w, v_pf->type, v_pf); + node_pf = scf_node_alloc(t->node.w, v_pf->type, v_pf); if (!node_pf) return -ENOMEM; @@ -727,7 +727,7 @@ static int _scf_op_semantic_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes if (!argv) return -ENOMEM; - ret = _semantic_add_var(&nthis, ast, NULL, v0->w, class->type, 0, 1, NULL); + ret = _semantic_add_var(&nthis, ast, NULL, v0->w, class->node.type, 0, 1, NULL); if (ret < 0) { scf_vector_free(argv); return ret; @@ -1149,11 +1149,8 @@ static int _scf_op_semantic_goto(scf_ast_t* ast, scf_node_t** nodes, int nb_node scf_node_t* nl = nodes[0]; assert(SCF_LABEL == nl->type); - scf_label_t* l = nl->label; - assert(l->w); - - scf_label_t* l2 = scf_block_find_label(ast->current_block, l->w->text->data); - if (!l2) { + scf_label_t* l = scf_block_find_label(ast->current_block, nl->w->text->data); + if (!l) { scf_loge("label '%s' not found\n", l->w->text->data); return -1; } @@ -1507,7 +1504,7 @@ static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_no goto error; } - if (v0->type == Object->type) { + if (v0->type == Object->node.type) { ret = __switch_for_Object(ast, Object, parent, child, e, e1, d, v0, v1); if (ret < 0) goto error; @@ -1735,7 +1732,7 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node if (ret < 0) return ret; - if (v0->type != Object->type) { + if (v0->type != Object->node.type) { scf_loge("\n"); return -1; } @@ -2688,7 +2685,7 @@ static int _scf_op_semantic_binary(scf_ast_t* ast, scf_node_t** nodes, int nb_no if (ret < 0) return ret; - if (t->type != v0->type) + if (t->node.type != v0->type) ret = _semantic_add_type_cast(ast, &nodes[0], v1, nodes[0]); else ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]); @@ -3121,6 +3118,21 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no v1 = _scf_operand_get(nodes[1]); } + scf_expr_t* e = nodes[0]; + + while (SCF_OP_EXPR == e->type) + e = e->nodes[0]; + + if (scf_type_is_operator(e->type)) { + + ret = _semantic_do_overloaded(ast, nodes, nb_nodes, d); + if (ret < 0) + scf_loge("overloaded function NOT found for operator '%s', file: %s, line: %d\n", + parent->w->text->data, parent->w->file->data, parent->w->line); + + return ret; + } + if (scf_scope_find_function(t->scope, "__init")) { ret = _semantic_do_new(ast, nodes, nb_nodes, d); diff --git a/js/parse/scf_parse.c b/js/parse/scf_parse.c index 852afbd..1d08abb 100644 --- a/js/parse/scf_parse.c +++ b/js/parse/scf_parse.c @@ -5,43 +5,34 @@ #include"scf_dfa.h" #include"scf_basic_block.h" #include"scf_optimizer.h" +#include"scf_symtab.h" #include"scf_elf.h" #include"scf_leb128.h" -#define ADD_SECTION_SYMBOL(sh_index, sh_name) \ - do { \ - int ret = _scf_parse_add_sym(parse, sh_name, 0, 0, sh_index, ELF64_ST_INFO(STB_LOCAL, STT_SECTION)); \ - if (ret < 0) { \ - scf_loge("\n"); \ - return ret; \ - } \ - } while (0) - scf_base_type_t base_types[] = { - {SCF_VAR_CHAR, "char", 1}, - - {SCF_VAR_VOID, "void", 1}, - {SCF_VAR_VAR, "var", 1}, - {SCF_VAR_BOOL, "bool", 1}, - - {SCF_VAR_INT, "int", 4}, - {SCF_VAR_FLOAT, "float", 4}, - {SCF_VAR_DOUBLE, "double", 8}, - - {SCF_VAR_I8, "int8_t", 1}, - {SCF_VAR_I16, "int16_t", 2}, - {SCF_VAR_I32, "int32_t", 4}, - {SCF_VAR_I64, "int64_t", 8}, - - {SCF_VAR_U8, "uint8_t", 1}, - {SCF_VAR_U16, "uint16_t", 2}, - {SCF_VAR_U32, "uint32_t", 4}, - {SCF_VAR_U64, "uint64_t", 8}, - - {SCF_VAR_INTPTR, "intptr_t", sizeof(void*)}, - {SCF_VAR_UINTPTR, "uintptr_t", sizeof(void*)}, - {SCF_FUNCTION_PTR, "funcptr", sizeof(void*)}, + {"char", SCF_VAR_CHAR, 1}, + {"void", SCF_VAR_VOID, 1}, + {"var", SCF_VAR_VAR, 1}, + {"bool", SCF_VAR_BOOL, 1}, + + {"int", SCF_VAR_INT, 4}, + {"float", SCF_VAR_FLOAT, 4}, + {"double", SCF_VAR_DOUBLE, 8}, + + {"int8_t", SCF_VAR_I8, 1}, + {"int16_t", SCF_VAR_I16, 2}, + {"int32_t", SCF_VAR_I32, 4}, + {"int64_t", SCF_VAR_I64, 8}, + + {"uint8_t", SCF_VAR_U8, 1}, + {"uint16_t", SCF_VAR_U16, 2}, + {"uint32_t", SCF_VAR_U32, 4}, + {"uint64_t", SCF_VAR_U64, 8}, + + {"intptr_t", SCF_VAR_INTPTR, sizeof(void*)}, + {"uintptr_t", SCF_VAR_UINTPTR, sizeof(void*)}, + {"funcptr", SCF_FUNCTION_PTR, sizeof(void*)}, }; int scf_parse_open(scf_parse_t** pparse) @@ -100,58 +91,6 @@ int scf_parse_close(scf_parse_t* parse) return 0; } -static int _find_sym(const void* v0, const void* v1) -{ - const char* name = v0; - const scf_elf_sym_t* sym = v1; - - if (!sym->name) - return -1; - - return strcmp(name, sym->name); -} - -static int _scf_parse_add_sym(scf_parse_t* parse, const char* name, - uint64_t st_size, Elf64_Addr st_value, - uint16_t st_shndx, uint8_t st_info) -{ - scf_elf_sym_t* sym = NULL; - scf_elf_sym_t* sym2 = NULL; - - if (name) - sym = scf_vector_find_cmp(parse->symtab, name, _find_sym); - - if (!sym) { - sym = calloc(1, sizeof(scf_elf_sym_t)); - if (!sym) - return -ENOMEM; - - if (name) { - sym->name = strdup(name); - if (!sym->name) { - free(sym); - return -ENOMEM; - } - } - - sym->st_size = st_size; - sym->st_value = st_value; - sym->st_shndx = st_shndx; - sym->st_info = st_info; - - int ret = scf_vector_add(parse->symtab, sym); - if (ret < 0) { - if (sym->name) - free(sym->name); - free(sym); - scf_loge("\n"); - return ret; - } - } - - return 0; -} - int scf_parse_file(scf_parse_t* parse, const char* path, scf_string_t* text) { if (!parse || !path) @@ -247,7 +186,7 @@ static scf_dwarf_info_entry_t* _debug_find_type(scf_parse_t* parse, scf_type_t* tag = DW_TAG_pointer_type; types = parse->debug->base_types; - } else if (t->type < SCF_STRUCT) { + } else if (t->node.type < SCF_STRUCT) { tag = DW_TAG_base_type; types = parse->debug->base_types; @@ -271,7 +210,7 @@ static scf_dwarf_info_entry_t* _debug_find_type(scf_parse_t* parse, scf_type_t* assert(ie->attributes->size == d->attributes->size); - if (ie->type == t->type && ie->nb_pointers == nb_pointers) + if (ie->type == t->node.type && ie->nb_pointers == nb_pointers) return ie; #if 0 for (j = 0; j < d ->attributes->size; j++) { @@ -319,7 +258,7 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla types = parse->debug->base_types; - } else if (t->type < SCF_STRUCT) { + } else if (t->node.type < SCF_STRUCT) { d = scf_vector_find_cmp(parse->debug->abbrevs, (void*)DW_TAG_base_type, _debug_abbrev_find_by_tag); if (!d) { @@ -357,7 +296,7 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla return -ENOMEM; ie->code = d->code; - ie->type = t->type; + ie->type = t->node.type; ie->nb_pointers = nb_pointers; ret = scf_vector_add(types, ie); @@ -400,19 +339,19 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla uint8_t ate; - if (SCF_VAR_CHAR == t->type || SCF_VAR_I8 == t->type) + if (SCF_VAR_CHAR == t->node.type || SCF_VAR_I8 == t->node.type) ate = DW_ATE_signed_char; - else if (scf_type_is_signed(t->type)) + else if (scf_type_is_signed(t->node.type)) ate = DW_ATE_signed; - else if (SCF_VAR_U8 == t->type) + else if (SCF_VAR_U8 == t->node.type) ate = DW_ATE_unsigned_char; - else if (scf_type_is_unsigned(t->type)) + else if (scf_type_is_unsigned(t->node.type)) ate = DW_ATE_unsigned; - else if (scf_type_is_float(t->type)) + else if (scf_type_is_float(t->node.type)) ate = DW_ATE_float; else { scf_loge("\n"); @@ -439,7 +378,7 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla } else if (DW_AT_decl_line == iattr->name) { - ret = scf_dwarf_info_fill_attr(iattr, (uint8_t*)&t->w->line, sizeof(t->w->line)); + ret = scf_dwarf_info_fill_attr(iattr, (uint8_t*)&t->node.w->line, sizeof(t->node.w->line)); if (ret < 0) return ret; @@ -689,7 +628,7 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev v_member = t->scope->vars->data[i]; - if (v_member->type != t->type) + if (v_member->type != t->node.type) continue; if (v_member->nb_pointers != j) @@ -731,8 +670,7 @@ static int _debug_add_type(scf_dwarf_info_entry_t** pie, scf_parse_t* parse, scf ie = _debug_find_type(parse, t, 0); if (!ie) { - - if (t->type < SCF_STRUCT) { + if (t->node.type < SCF_STRUCT) { ret = __debug_add_type(&ie, &d, parse, t, 0, NULL); if (ret < 0) return ret; @@ -1376,52 +1314,6 @@ static int _fill_function_inst(scf_string_t* code, scf_function_t* f, int64_t of return 0; } -static int _scf_parse_add_rela(scf_vector_t* relas, scf_parse_t* parse, scf_rela_t* r, const char* name, uint16_t st_shndx) -{ - scf_elf_rela_t* rela; - - int ret; - int i; - - for (i = 0; i < parse->symtab->size; i++) { - scf_elf_sym_t* sym = parse->symtab->data[i]; - - if (!sym->name) - continue; - - if (!strcmp(name, sym->name)) - break; - } - - if (i == parse->symtab->size) { - ret = _scf_parse_add_sym(parse, name, 0, 0, st_shndx, ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE)); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - } - - scf_logd("rela: %s, offset: %ld\n", name, r->text_offset); - - rela = calloc(1, sizeof(scf_elf_rela_t)); - if (!rela) - return -ENOMEM; - - rela->name = (char*)name; - rela->r_offset = r->text_offset; - rela->r_info = ELF64_R_INFO(i + 1, r->type); - rela->r_addend = r->addend; - - ret = scf_vector_add(relas, rela); - if (ret < 0) { - scf_loge("\n"); - free(rela); - return ret; - } - - return 0; -} - static int _fill_data(scf_parse_t* parse, scf_variable_t* v, scf_string_t* data, uint32_t shndx) { char* name; @@ -1472,7 +1364,7 @@ static int _fill_data(scf_parse_t* parse, scf_variable_t* v, scf_string_t* data, else stb = STB_GLOBAL; - ret = _scf_parse_add_sym(parse, name, size, data->len, shndx, ELF64_ST_INFO(stb, STT_OBJECT)); + ret = scf_symtab_add_sym(parse->symtab, name, size, data->len, shndx, ELF64_ST_INFO(stb, STT_OBJECT)); if (ret < 0) return ret; @@ -1602,7 +1494,7 @@ static int _scf_parse_add_data_relas(scf_parse_t* parse, scf_elf_context_t* elf) } if (j == parse->symtab->size) { - ret = _scf_parse_add_sym(parse, name, 0, 0, 0, ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE)); + ret = scf_symtab_add_sym(parse->symtab, name, 0, 0, 0, ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE)); if (ret < 0) { scf_loge("\n"); return ret; @@ -1847,11 +1739,10 @@ static int _add_debug_sections(scf_parse_t* parse, scf_elf_context_t* elf) if (str < 0) return str; - ADD_SECTION_SYMBOL(abbrev, ".debug_abbrev"); - ADD_SECTION_SYMBOL(info, ".debug_info"); - ADD_SECTION_SYMBOL(line, ".debug_line"); - ADD_SECTION_SYMBOL(str, ".debug_str"); - + ADD_SECTION_SYMBOL(parse->symtab, abbrev, ".debug_abbrev"); + ADD_SECTION_SYMBOL(parse->symtab, info, ".debug_info"); + ADD_SECTION_SYMBOL(parse->symtab, line, ".debug_line"); + ADD_SECTION_SYMBOL(parse->symtab, str, ".debug_str"); return 0; } @@ -1939,9 +1830,9 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf, } if (r->func->node.define_flag) - ret = _scf_parse_add_rela(relas, parse, r, r->func->signature->data, SCF_SHNDX_TEXT); + ret = scf_symtab_add_rela(relas, parse->symtab, r, r->func->signature->data, SCF_SHNDX_TEXT); else - ret = _scf_parse_add_rela(relas, parse, r, r->func->signature->data, 0); + ret = scf_symtab_add_rela(relas, parse->symtab, r, r->func->signature->data, 0); if (ret < 0) { scf_loge("\n"); @@ -1958,7 +1849,7 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf, else name = r->var->signature->data; - ret = _scf_parse_add_rela(relas, parse, r, name, 2); + ret = scf_symtab_add_rela(relas, parse->symtab, r, name, 2); if (ret < 0) { scf_loge("\n"); goto error; @@ -2015,7 +1906,8 @@ static int _sym_cmp(const void* v0, const void* v1) static int _add_debug_file_names(scf_parse_t* parse) { scf_block_t* root = parse->ast->root_block; - scf_block_t* b = NULL; + scf_block_t* b; + scf_lex_t* lex; int ret; int i; @@ -2026,20 +1918,23 @@ static int _add_debug_file_names(scf_parse_t* parse) if (SCF_OP_BLOCK != b->node.type) continue; - ret = _scf_parse_add_sym(parse, b->name->data, 0, 0, SHN_ABS, ELF64_ST_INFO(STB_LOCAL, STT_FILE)); - if (ret < 0) { - scf_loge("\n"); + ret = scf_symtab_add_sym(parse->symtab, b->name->data, 0, 0, SHN_ABS, ELF64_ST_INFO(STB_LOCAL, STT_FILE)); + if (ret < 0) return ret; - } - - scf_string_t* file_str = scf_string_clone(b->name); - if (!file_str) - return -ENOMEM; - ret = scf_vector_add(parse->debug->file_names, file_str); - if (ret < 0) { - scf_string_free(file_str); + ret = scf_dwarf_add_file_name(parse->debug, b->name); + if (ret < 0) return ret; + + for (lex = b->lex_list; lex; lex = lex->next) + { + ret = scf_symtab_add_sym(parse->symtab, lex->file->data, 0, 0, SHN_ABS, ELF64_ST_INFO(STB_LOCAL, STT_FILE)); + if (ret < 0) + return ret; + + ret = scf_dwarf_add_file_name(parse->debug, lex->file); + if (ret < 0) + return ret; } } @@ -2138,16 +2033,9 @@ int scf_parse_write_elf(scf_parse_t* parse, scf_vector_t* functions, scf_vector_ goto error; } - scf_elf_sym_t* sym; - int i; - - for (i = 0; i < parse->symtab->size; i++) { - sym = parse->symtab->data[i]; - - ret = scf_elf_add_sym(elf, sym, ".symtab"); - if (ret < 0) - goto error; - } + ret = scf_elf_add_syms(elf, parse->symtab, ".symtab"); + if (ret < 0) + goto error; ret = scf_elf_write_rel(elf); error: @@ -2184,7 +2072,7 @@ int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_ve if (ret < 0) return ret; - ret = _scf_parse_add_sym(parse, f->signature->data, f->code_bytes, offset, SCF_SHNDX_TEXT, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC)); + ret = scf_symtab_add_sym(parse->symtab, f->signature->data, f->code_bytes, offset, SCF_SHNDX_TEXT, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC)); if (ret < 0) return ret; @@ -2232,9 +2120,9 @@ int scf_parse_fill_code(scf_parse_t* parse, scf_vector_t* functions, scf_vector_ scf_string_t* file_name = parse->debug->file_names->data[0]; const char* path = file_name->data; - ADD_SECTION_SYMBOL(SCF_SHNDX_TEXT, ".text"); - ADD_SECTION_SYMBOL(SCF_SHNDX_RODATA, ".rodata"); - ADD_SECTION_SYMBOL(SCF_SHNDX_DATA, ".data"); + ADD_SECTION_SYMBOL(parse->symtab, SCF_SHNDX_TEXT, ".text"); + ADD_SECTION_SYMBOL(parse->symtab, SCF_SHNDX_RODATA, ".rodata"); + ADD_SECTION_SYMBOL(parse->symtab, SCF_SHNDX_DATA, ".data"); scf_dwarf_info_entry_t* cu = NULL; scf_dwarf_line_result_t* r = NULL; @@ -2334,6 +2222,7 @@ int scf_parse_compile(scf_parse_t* parse, const char* arch) switch (e->type) { case SCF_OP_EXPR: + case SCF_OP_CALL: case SCF_OP_SWITCH: case SCF_OP_IF: case SCF_OP_FOR: diff --git a/js/parse/scf_struct_array.c b/js/parse/scf_struct_array.c index b27d10d..b204298 100644 --- a/js/parse/scf_struct_array.c +++ b/js/parse/scf_struct_array.c @@ -37,7 +37,7 @@ static int __object_new(scf_expr_t* e, scf_ast_t* ast, scf_lex_word_t* w, scf_va return -ENOMEM; // add construct() for obj - v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL); + v = SCF_VAR_ALLOC_BY_TYPE(Object->node.w, pt, 1, 1, NULL); if (!v) { scf_node_free(new); return -ENOMEM; @@ -99,7 +99,7 @@ static int __object_new(scf_expr_t* e, scf_ast_t* ast, scf_lex_word_t* w, scf_va if (j >= init_pos->size) { assert(ie->expr); - scf_logi("var: %s\n", var->w->text->data); + scf_logd("var: %s:%p, var->func_ptr: %p, ie->expr: %p\n", var->w->text->data, var, var->func_ptr, ie->expr); ret = scf_node_add_child(new, ie->expr); if (ret < 0) { @@ -156,13 +156,13 @@ static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_v } if (array_dim < obj->nb_dimentions) { - scf_logi("var: %s, array_dim: %d, nb_dimentions: %d, num: %d\n", + scf_logd("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_new(e, ast, w, var, obj->dimentions[array_dim].num, Object, NULL, NULL); - } else if (t->type >= SCF_STRUCT) { + } else if (t->node.type >= SCF_STRUCT) { scf_logd("var: %s\n", var->w->text->data); ret = __object_new(e, ast, w, var, t->scope->vars->size, Object, NULL, NULL); } else { @@ -185,7 +185,7 @@ static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_v scf_logi("-----------------\n"); - if (t->type >= SCF_STRUCT || array_dim < obj->nb_dimentions) { + if (t->node.type >= SCF_STRUCT || array_dim < obj->nb_dimentions) { // add -> node = scf_node_alloc(w, SCF_OP_POINTER, NULL); if (!node) { @@ -202,6 +202,7 @@ static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_v } OBJ_EXPR_ADD_NODE(e2, node); + scf_variable_t* v; int i; int n; if (array_dim < obj->nb_dimentions) @@ -210,6 +211,15 @@ static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_v n = t->scope->vars->size; for (i = 0; i < n; i++) { + v = NULL; + + if (array_dim >= obj->nb_dimentions) { + v = t->scope->vars->data[i]; + + if (v->const_flag && v->func_ptr) + continue; + } + e3 = scf_expr_clone(e2); if (!e3) { scf_expr_free(e2); @@ -231,14 +241,9 @@ static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_v return ret; } - scf_variable_t* v = NULL; + int js_index = v ? v->js_index : i; - 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); - } + ret = scf_ast_add_const_var(ast, node, SCF_VAR_INT, js_index); if (ret < 0) { scf_expr_free(e3); scf_expr_free(e2); diff --git a/js/parse/scf_symtab.c b/js/parse/scf_symtab.c new file mode 100644 index 0000000..76f9a93 --- /dev/null +++ b/js/parse/scf_symtab.c @@ -0,0 +1,100 @@ +#include"scf_symtab.h" + +static int _find_sym(const void* v0, const void* v1) +{ + const char* name = v0; + const scf_elf_sym_t* sym = v1; + + if (!sym->name) + return -1; + + return strcmp(name, sym->name); +} + +int scf_symtab_add_sym(scf_vector_t* symtab, const char* name, + uint64_t st_size, + Elf64_Addr st_value, + uint16_t st_shndx, + uint8_t st_info) +{ + scf_elf_sym_t* sym = NULL; + + if (name) + sym = scf_vector_find_cmp(symtab, name, _find_sym); + + if (!sym) { + sym = calloc(1, sizeof(scf_elf_sym_t)); + if (!sym) + return -ENOMEM; + + if (name) { + sym->name = strdup(name); + if (!sym->name) { + free(sym); + return -ENOMEM; + } + } + + sym->st_size = st_size; + sym->st_value = st_value; + sym->st_shndx = st_shndx; + sym->st_info = st_info; + + int ret = scf_vector_add(symtab, sym); + if (ret < 0) { + if (sym->name) + free(sym->name); + free(sym); + scf_loge("\n"); + return ret; + } + } + + return 0; +} + +int scf_symtab_add_rela(scf_vector_t* relas, scf_vector_t* symtab, scf_rela_t* r, const char* name, uint16_t st_shndx) +{ + scf_elf_rela_t* rela; + scf_elf_sym_t* sym; + + int ret; + int i; + + for (i = 0; i < symtab->size; i++) { + sym = symtab->data[i]; + + if (!sym->name) + continue; + + if (!strcmp(name, sym->name)) + break; + } + + if (i == symtab->size) { + ret = scf_symtab_add_sym(symtab, name, 0, 0, st_shndx, ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE)); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } + + scf_logd("rela: %s, offset: %ld\n", name, r->text_offset); + + rela = calloc(1, sizeof(scf_elf_rela_t)); + if (!rela) + return -ENOMEM; + + rela->name = (char*)name; + rela->r_offset = r->text_offset; + rela->r_info = ELF64_R_INFO(i + 1, r->type); + rela->r_addend = r->addend; + + ret = scf_vector_add(relas, rela); + if (ret < 0) { + free(rela); + return ret; + } + + return 0; +} diff --git a/js/parse/scf_symtab.h b/js/parse/scf_symtab.h new file mode 100644 index 0000000..dcab871 --- /dev/null +++ b/js/parse/scf_symtab.h @@ -0,0 +1,37 @@ +#ifndef SCF_SYMTAB_H +#define SCF_SYMTAB_H + +#include"scf_elf.h" +#include"scf_instruction.h" + +int scf_symtab_add_sym(scf_vector_t* symtab, const char* name, + uint64_t st_size, + Elf64_Addr st_value, + uint16_t st_shndx, + uint8_t st_info); + +int scf_symtab_add_rela(scf_vector_t* relas, scf_vector_t* symtab, scf_rela_t* r, const char* name, uint16_t st_shndx); + +#define ADD_SECTION_SYMBOL(symtab, sh_index, sh_name) \ + do { \ + int ret = scf_symtab_add_sym(symtab, sh_name, 0, 0, sh_index, ELF64_ST_INFO(STB_LOCAL, STT_SECTION)); \ + if (ret < 0) { \ + scf_loge("\n"); \ + return ret; \ + } \ + } while (0) + +static int __symtab_sort_cmp(const void* v0, const void* v1) +{ + const scf_elf_sym_t* sym0 = *(const scf_elf_sym_t**)v0; + const scf_elf_sym_t* sym1 = *(const scf_elf_sym_t**)v1; + + if (STB_LOCAL == ELF64_ST_BIND(sym0->st_info)) { + if (STB_GLOBAL == ELF64_ST_BIND(sym1->st_info)) + return -1; + } else if (STB_LOCAL == ELF64_ST_BIND(sym1->st_info)) + return 1; + return 0; +} + +#endif diff --git a/js/util/scf_string.c b/js/util/scf_string.c index c73f9a2..83c8197 100644 --- a/js/util/scf_string.c +++ b/js/util/scf_string.c @@ -20,7 +20,7 @@ scf_string_t* scf_string_alloc() return s; } -scf_string_t* scf_string_clone(scf_string_t* s) +scf_string_t* scf_string_clone(const scf_string_t* s) { if (!s) return NULL; diff --git a/js/util/scf_string.h b/js/util/scf_string.h index 082d2b5..16b07a8 100644 --- a/js/util/scf_string.h +++ b/js/util/scf_string.h @@ -12,7 +12,7 @@ typedef struct { scf_string_t* scf_string_alloc(); -scf_string_t* scf_string_clone(scf_string_t* s); +scf_string_t* scf_string_clone(const scf_string_t* s); scf_string_t* scf_string_cstr(const char* str); diff --git a/ui/Makefile b/ui/Makefile index 36893bd..a56faec 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -69,6 +69,7 @@ CFILES += ../ffmpeg/abc_avio.c CFILES += ../ffmpeg/abc_filter.c CFILES += ../js/util/scf_string.c +CFILES += ../js/util/scf_rbtree.c CFILES += ../js/util/scf_graph.c CFILES += ../js/lex/scf_lex.c CFILES += ../js/lex/scf_lex_util.c @@ -76,6 +77,7 @@ CFILES += ../js/lex/scf_lex_util.c CFILES += ../js/parse/main.c CFILES += ../js/parse/scf_parse_util.c CFILES += ../js/parse/scf_parse.c +CFILES += ../js/parse/scf_symtab.c CFILES += ../js/parse/scf_operator_handler_semantic.c CFILES += ../js/parse/scf_operator_handler_expr.c CFILES += ../js/parse/scf_operator_handler_const.c diff --git a/ui/abc_layout.c b/ui/abc_layout.c index 28689e0..f7773e0 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -249,12 +249,13 @@ int abc_layout_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height) || ABC_HTML_LINK == root->type) return 0; - if (!root->css_use && ABC_CORE_TEXT != root->type) { - root->css_use = 1; - + if (!root->css_used && ABC_CORE_TEXT != root->type) + { int ret = abc_css_use(ctx->current, root); if (ret < 0) return ret; + + root->css_used = 1; } abc_attr_t* attr; diff --git a/ui/abc_layout_text.c b/ui/abc_layout_text.c index 1a4e299..540e5c0 100644 --- a/ui/abc_layout_text.c +++ b/ui/abc_layout_text.c @@ -211,13 +211,8 @@ int abc_layout_text(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height) return 0; if (parent->content && !parent->text) { - if (obj->content) { - int ret = scf_string_cat(parent->content, obj->content); - if (ret < 0) - return ret; - + if (obj->content) scf_string_free(obj->content); - } obj->content = parent->content; parent->content = NULL; diff --git a/ui/main.c b/ui/main.c index 50a81fa..0c49f4c 100644 --- a/ui/main.c +++ b/ui/main.c @@ -99,8 +99,8 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) prev->mouse_move_x = -1; prev->mouse_move_y = -1; - prev->css_use = 0; - prev->clicked = 0; + prev->css_used = 0; + prev->clicked = 0; ret = 1; } @@ -158,7 +158,7 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) ret |= abc_css_active(obj, ABC_CSS_HOVER); ctx->current->current = obj; - obj->css_use = 0; + obj->css_used = 0; } return ret; @@ -216,7 +216,7 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y) abc_css_clear (obj, ABC_CSS_LINK, ABC_CSS_ACTIVE); abc_css_active(obj, ABC_CSS_VISITED); - obj->css_use = 0; + obj->css_used = 0; scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n", obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y); @@ -386,7 +386,7 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin abc_css_clear (obj, ABC_CSS_LINK, ABC_CSS_ACTIVE); abc_css_active(obj, ABC_CSS_ACTIVE); - obj->css_use = 0; + obj->css_used = 0; gtk_gl_area_queue_render(ctx->gl_area); } @@ -448,12 +448,13 @@ static gboolean key_press_event(GtkWidget* self, GdkEventKey* event, gpointer us static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data) { - abc_ctx_t* ctx = user_data; - abc_obj_t* obj; + abc_ctx_t* ctx = user_data; + abc_html_t* html = ctx->current; + abc_obj_t* obj; - if (ctx->current->io.download && ctx->current->root) + if (html->io.download && html->root) { - obj = abc_obj_find(ctx->current->root, event->x, event->y); + obj = abc_obj_find(html->root, event->x, event->y); if (obj) { obj->mouse_move_x = event->x; obj->mouse_move_y = event->y; @@ -469,37 +470,67 @@ static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpoint static gboolean timer_handler(gpointer user_data) { - abc_ctx_t* ctx = user_data; - abc_obj_t* obj; + abc_ctx_t* ctx = user_data; + abc_html_t* html = ctx->current; + abc_obj_t* obj; - if (ctx->current) { - if (!ctx->current->io.download) + if (html) { + if (!html->io.download) return TRUE; - if (!ctx->current->root) { - int ret = abc_html_parse(ctx->current); + int render_flag = 0; + + if (!html->root) { + int ret = abc_html_parse(html); if (ret < 0) { - abc_obj_free(ctx->current->root); - ctx->current->root = NULL; + abc_obj_free(html->root); + html->root = NULL; return TRUE; } - ctx->current->root->gtk_builder = ctx->builder; - ctx->current->current = ctx->current->root; + html->root->gtk_builder = ctx->builder; + html->current = html->root; gtk_widget_set_sensitive(GTK_WIDGET(ctx->back), TRUE); - gtk_gl_area_queue_render(ctx->gl_area); + render_flag = 1; + } + + while (1) { + abc_timer_t* timer = (abc_timer_t*) scf_rbtree_min(&html->timers, html->timers.root); + if (!timer || timer->usec > gettime()) + break; + + scf_rbtree_delete(&html->timers, (scf_rbtree_node_t*)timer); + + if (timer->func) { + timer->func(timer->argc, timer->argv); + render_flag = 1; + } + + if (html->js_auto_freep && html->js_release) { + int i; + for (i = 2; i < timer->argc; i++) { + if (timer->argv[i]) + html->js_auto_freep(&(timer->argv[i]), 1, html->js_release); + } + } + + free(timer); + timer = NULL; } - obj = ctx->current->current; + obj = html->current; if (obj) { obj->jiffies++; if (ABC_HTML_INPUT == obj->type && 0 == obj->jiffies % 64) - gtk_gl_area_queue_render(ctx->gl_area); + render_flag = 1; } - if (ctx->current->has_video) + if (html->has_video) + render_flag = 1; + + if (render_flag) gtk_gl_area_queue_render(ctx->gl_area); }