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);
}