1, css: support counter,
authoryu.dongliang <18588496441@163.com>
Thu, 18 Jun 2026 12:02:24 +0000 (20:02 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 18 Jun 2026 12:02:33 +0000 (20:02 +0800)
2, js: support setTimeout() with variable args,
3, fix: some BUGS in native/x64.

81 files changed:
examples/js_func.html [moved from examples/js2.html with 100% similarity]
examples/js_obj_func.html [new file with mode: 0644]
examples/js_setTimeout.html [new file with mode: 0644]
examples/js_switch.html [moved from examples/js.html with 100% similarity]
html/Makefile
html/abc_css.c
html/abc_css_counter.c
html/abc_html.c
html/abc_html.h
html/abc_obj.c
html/abc_obj.h
html/main.c
js/Makefile
js/abc_libjs.c
js/abc_libjs.so
js/abc_libjs_asm.S [new file with mode: 0644]
js/core/scf_3ac.c
js/core/scf_3ac.h
js/core/scf_ast.c
js/core/scf_basic_block.c
js/core/scf_block.h
js/core/scf_calculate.c
js/core/scf_calculate.h
js/core/scf_calculate_i32.c
js/core/scf_calculate_i64.c
js/core/scf_calculate_u32.c
js/core/scf_calculate_u64.c [new file with mode: 0644]
js/core/scf_expr.c
js/core/scf_function.c
js/core/scf_function.h
js/core/scf_label.c
js/core/scf_node.c
js/core/scf_node.h
js/core/scf_operator_handler_3ac.c
js/core/scf_optimizer_inline.c
js/core/scf_optimizer_js_array.c
js/core/scf_optimizer_js_array2.c
js/core/scf_optimizer_js_teq.c
js/core/scf_optimizer_js_unary_op.c
js/core/scf_scope.c
js/core/scf_scope.h
js/core/scf_type.c
js/core/scf_type.h
js/core/scf_variable.c
js/doc.c
js/elf/scf_dwarf.c
js/elf/scf_dwarf.h
js/lex/scf_lex_util.c
js/lib/scf_rbtree.c
js/native/x64/scf_x64.c
js/native/x64/scf_x64_inst.c
js/native/x64/scf_x64_inst_common.c
js/native/x64/scf_x64_peephole.c
js/native/x64/scf_x64_reg.c
js/native/x64/scf_x64_reg.h
js/parse/scf_dfa_call.c
js/parse/scf_dfa_class.c
js/parse/scf_dfa_container.c
js/parse/scf_dfa_expr.c
js/parse/scf_dfa_function.c
js/parse/scf_dfa_function_js.c
js/parse/scf_dfa_goto.c
js/parse/scf_dfa_include.c
js/parse/scf_dfa_init_data.c
js/parse/scf_dfa_label.c
js/parse/scf_dfa_new.c
js/parse/scf_dfa_type.c
js/parse/scf_dfa_va_arg.c
js/parse/scf_dfa_var.c
js/parse/scf_operator_handler_const.c
js/parse/scf_operator_handler_semantic.c
js/parse/scf_parse.c
js/parse/scf_struct_array.c
js/parse/scf_symtab.c [new file with mode: 0644]
js/parse/scf_symtab.h [new file with mode: 0644]
js/util/scf_string.c
js/util/scf_string.h
ui/Makefile
ui/abc_layout.c
ui/abc_layout_text.c
ui/main.c

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 (file)
index 0000000..0c3cb9b
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<h1>含有javascript的页面</h1>
+
+<p>含有js的页面</p>
+
+<script>
+var obj =
+{
+       f: function (a, b) {return a + b; },
+};
+
+var c = obj.f(1, 2);
+
+document.write(c);
+
+</script>
+
+</body>
+</html>
diff --git a/examples/js_setTimeout.html b/examples/js_setTimeout.html
new file mode 100644 (file)
index 0000000..83b1ea6
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>菜鸟教程(runoob.com)</title>
+</head>
+<body>
+
+<p>回调函数等待 3 秒后执行。</p>
+<p id="demo"></p>
+
+<script>
+function print(a) {
+    document.getElementById("demo").innerHTML="RUNOOB!";
+}
+
+setTimeout(print, 3000, 1);
+</script>
+
+</body>
+</html>
similarity index 100%
rename from examples/js.html
rename to examples/js_switch.html
index bbb8c73c506c9c9aa671b253a0e09dbaee77db47..b11e664b1e3f501981d4efd64491f17f2db69586 100644 (file)
@@ -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
index 16112df9f4864c6282cfaefceb0bbcb4c1590507..8e25c921676e380993ce7071ee9b634b0ca7eec4 100644 (file)
@@ -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;
 }
index a91985a91c7deef421a2bd5e6d9bb8f348343dd3..67431a05c6edcd74d968c9268dc1d3a2da4d1a1f 100644 (file)
@@ -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)
index 37946b06805732b417890eabfb33c9456762108d..47ed2d11b2de9c88079d90c96fd7dd09f24883e7 100644 (file)
@@ -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;
        };
index ff5a67540e52e1e5984f9018fd83bbbfe3f1213e..e41dae9f0d3f9709943a34afc36dde38087f88ea 100644 (file)
@@ -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
index 60ca2e1066eea17afab7b3d543a5eb4958e43ec4..e93a1113273a3b4ed6b703739248658969a9bdbd 100644 (file)
@@ -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)
index a49329578a7b82a427fd50a39ddefb3ac7a5003a..e947a408c2e53bdcb3c4c38780cddb354584f655 100644 (file)
@@ -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;
index 561c8057f4d0bba04896d5c44291ae1f7d0fbe9b..35e3788f4da092108e27bcd635b9445bc9efbcfe 100644 (file)
@@ -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);
        }
 
index b4d00fba0f7de60200a93487eabf9414398f503d..b8c56f8dcdb516f9abe7693d3e4b6ce49c10f20a 100644 (file)
@@ -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
index f8a1312c68c78780a1089d659c84343bf958aa60..3e28fdc41560ac9c40a9ee41dd73dd0b22f99f0f 100644 (file)
@@ -2,6 +2,9 @@
 #define PCRE2_CODE_UNIT_WIDTH 8
 #include<pcre2.h>
 
+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);
+}
index b5d7e51efae8bd855a2bd95d04bf4c0060ff4aea..e9b31a886e3576a056b32783adc71d35b296fc91 100755 (executable)
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 (file)
index 0000000..a0d86ce
--- /dev/null
@@ -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
index 0e28716b56d28eec98fe9e640439eeb1e0f856bb..07401bb2ecee415f176f56ed80ed5e19e429805d 100644 (file)
@@ -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;
index 947bff2878729112ba5ded2ba159c5b09311a85f..7f45cb67c46a2e56547773a3681f44e663f02873 100644 (file)
@@ -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);
 
index aa22dff14d60c402ca19b02eda8c4723efe7f002..daf19fd3e4a76a767ae5707e403c9127edd199c3 100644 (file)
@@ -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++;
index 55a642619edc8e1b1fb22205ff72943da1c32345..0fc2e60ef295c69f846496c1efb712e163862802 100644 (file)
@@ -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;
index f405d24727c1d7d55fe495f7396c7319d87cc68d..30d3fd0415df6fd6c38813a8eda837d9ad61a048 100644 (file)
@@ -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
-
index 2e429c1b69105e966805cf0f74e1253dd27e0422..6f068ad7f8b220fc799074d00a8bf2b11b1cdd3c 100644 (file)
@@ -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;
 }
-
index 145e252bdef1513e5fa4dc7d2c5a9633499e21af..4d2b19ab904e974fae79b22b1ea5d0cdac020180 100644 (file)
@@ -19,4 +19,3 @@ typedef struct {
 scf_calculate_t* scf_find_base_calculate(int op_type, int src0_type, int src1_type);
 
 #endif
-
index 50fc79c38c73733c414e9704b2b6e1e9d0aa9aab..c01ad957fbd8287f30c87106f10c53942755bf62 100644 (file)
@@ -63,4 +63,3 @@ SCF_I32_BINARY_OP(eq, ==)
 SCF_I32_BINARY_OP(ne, !=)
 SCF_I32_BINARY_OP(ge, >=)
 SCF_I32_BINARY_OP(le, <=)
-
index 06aa716fe3e51e138af388c4d81c0903c7eefa69..ed2eee953f31f0dc00fd328c76a9651c7625dd09 100644 (file)
@@ -63,4 +63,3 @@ SCF_I64_BINARY_OP(eq, ==)
 SCF_I64_BINARY_OP(ne, !=)
 SCF_I64_BINARY_OP(ge, >=)
 SCF_I64_BINARY_OP(le, <=)
-
index 7ecb10f32bc87e0a5ca769a8a45a48e008bb6939..fa982d232222eb53177ddbc4a0d86683cafec802 100644 (file)
@@ -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 (file)
index 0000000..36aaebd
--- /dev/null
@@ -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, <=)
index 8a8b081bc795992a5fb97747cd657322eeeeac5f..bb7b5daad5e099df16e5e534d22d2fcbfe95dd2b 100644 (file)
@@ -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;
index a8d5e31ecc5645d259c376c7b3f0463f79e5e1d5..de7c2fe3bcce3213741e72de8a5002621baa4a79 100644 (file)
@@ -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;
        }
 
index 9b0afd4a896c9a000db5bb125f8998673e1f5b2e..d4231989d819ec3341692ccdd8fc21df43301fa6 100644 (file)
@@ -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
index 63bdb9e33bbe74d18a05480fdd60c4ebc2daf996..7bb478b7ca1c12db5db6d006fbfb68c3a33a6109 100644 (file)
@@ -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;
index 89d68ad11d18027c388a8aed617bfd8f2c34840e..4027d4064b64b8e9473f6e53c2aba7d8b84ed1b9 100644 (file)
@@ -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);
 
index 946298cec875d51b08f35bcfc7df8416c4cdfb69..b6f23c0f2b89e3f828536b03e24d96b6fd063d8a 100644 (file)
@@ -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);
index 02b34adf2f6eefb99a2adc2e371067fe71166420..5bbf4106c4f329dbe19bac2f7580f3bf6b530e2f 100644 (file)
@@ -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; \
        \
index 6900ea9143ddca4243a752f6741e00534b055eb0..32fbb9e28f7557815b3d435fe5453f339b9d5689 100644 (file)
@@ -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;
index 27996374b86937ab56d0565a26dafc930a3ed6df..f39e0a5e1000f9d185116766c52bba8f1d30ec53 100644 (file)
@@ -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;
index 007b09bbd8745b7cbf2645a4b984f6f18bb54d73..b78138b715fae8ba833ce923d1909580e3916a7e 100644 (file)
@@ -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)) {
index 2d64d15ca9d50b3614d4346576008b1d726995ac..c48e2a5e64ac30a39f1de93408cc615f66aa408c 100644 (file)
@@ -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) {
index baad7495e0173498e6e26fa30274fdc1035027b6..86ec2ad566858710ab02b7fef57a67a913e24477 100644 (file)
@@ -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) {
index 424fb0f5b1a0e9e77be8cbb805fdfa3320ccb734..7bc08ba0dea09991338188aae086cec7396ddb76 100644 (file)
@@ -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);
index 53ef96ad5a3902223a572ca87c2c6f6d874f0fb6..ac823f19b2db20c1c63259ec80b5063d2b2df3d4 100644 (file)
@@ -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);
 
index a9640189e567ffeb28fea9f3921d4ecaa441f785..94455a5a29f8824d69634c5b7492f495439386dd 100644 (file)
@@ -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);
        }
 }
 
index 82aa8a9d9d4424fc555f58da1d0ba7f81e97f2f1..3ece46b06df740767f10f0fe32d66eb4c7a00878 100644 (file)
@@ -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
-
index 469e89640ae017384822ff7fcfe6adc24cff670c..cc8935f3b7619adbd35c90919547c83559a6e8a2 100644 (file)
@@ -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;
index ceeda44e1fe16478a6f4e70389b8736ed06a34f8..f8ea1455ea79b6edac9cc24e3071cfe2bfaaa8d1 100644 (file)
--- 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;
index c7d8771860b93e404d554923d3b848750662951f..a34bce1b162c04c7a95df484e3ff5c60657a49fc 100644 (file)
@@ -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) {
index 08675bc50f4182b1c7acdf3d28483fb7cb0c349f..c68066320fc5305094c9cc01d9d75a09bf5b87a6 100644 (file)
@@ -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
index 2fda3c05ac3817d13e609236cb8e6353b3ae76c8..b4d6c9ca6a231c554c59c1578aae99399d3edb14 100644 (file)
@@ -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;
index ff08fcb9a66bfdb889f56a20c09494f39703c89e..0723dffdb7c96766494737a6799559790ca51580 100644 (file)
@@ -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;
index 7ec69c31bb135c8e628d4e96946559daf9352a76..300b9dc0dee77d8f620a48dfdae35d99a05fc380 100644 (file)
@@ -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);
index 51c6b9b49ddd0c6681883d9276c34ec6145f31e9..992181401b3f18617dc06634a8bcc1b274aad5c4 100644 (file)
@@ -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];
 
index cdd4fbd48e4251742527a7d4e5b70a79291959b6..1d9eba7693dd8edbc046d200259ebb9fa79cb4f3 100644 (file)
@@ -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);
index 57f906cf9a10d8217b217dae11d1e4b4fc81970c..147a303d3095392709c09c452179a84aa446f7e9 100644 (file)
@@ -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;
 }
index efcc9aa06277a27d56075ea79863fedebe8c6a87..9374eed7964c8c140d0aeed09d40073eb5b9cadd 100644 (file)
@@ -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;
index 0e595799571f20c156eb1269a936748fc0be807b..9be5f653b37278a98477915c77601ccc5344809f 100644 (file)
@@ -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);
index 7197a1b5aee7c74e8b0e75c53a41a21682f098e6..47b0754358d072ab2278f7384e907f457c29d33c 100644 (file)
@@ -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--)
index 5429e61bd18b4434cd395cb0badbdde475a87e14..dc9fb5c16fa01f18f5ab22f5c658bcb88ce87d4b 100644 (file)
@@ -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;
 }
index 5a2ac2b7ba69a21f245488acc5fb2409fc28062b..03d1bbbd5bba19e2f915eeb610dc54a4a5fb852d 100644 (file)
@@ -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;
index 75337c17c407af9bf6e0835f340f38f02b5c9a1c..5b4d20634c462ea3775e93bcbe483e799b14bb39 100644 (file)
@@ -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;
index fe0748ee1f7e25395c7107792b2a9f77ead901fc..3a14de622e26b8002f912a5f8eefdba5ac6dc716 100644 (file)
@@ -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;
                }
index 97ff26b34144a2c557f3af2a397c30293a023b17..61e733f5238128a68fa4b907238b83794af809fd 100644 (file)
@@ -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);
 
index b3ea503d033040e30bfb5c99946e0e99d62319f7..2c035d5f65de93027138b4b85b3cf550148b1ac3 100644 (file)
@@ -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;
 }
index cd0c33305baeddcf5efde32729097ad7e6ae9763..fb4bb608998adfbb1325fef264d0ba161845ac25 100644 (file)
@@ -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);
index 2eb780848c257e8401de8e1370ea972630ccbd88..8d61fbe2f6617dda48310d56fe04316847574ac6 100644 (file)
@@ -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);
 
index a017cf7a961016ba770939914c09a22921c4f692..f8679fa453fff4bbfb9403b655a7705edc84120c 100644 (file)
@@ -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;
index 45987740c5e4cb6dfd07b81765270b9fa9befaf3..cab7bcf2bcf478e0571e2288f58f6f6dab0ff06f 100644 (file)
@@ -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)
index 5ef9055a4eefdcf09eab8cab3c25c3df5eaeab7e..7e72383bd701c3d5dc59d0b974571003d93bba14 100644 (file)
@@ -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);
 
index 0a4dc98a2279dfb654300499a3009b84c552ac9c..918690cb96637129b2667adcc66a1991dea0aa69 100644 (file)
@@ -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;
        }
index 33506f79cc1724c4682f479cd105f75050e7915c..5dd42490eb47b13249984ed8f94caefd27dd9e31 100644 (file)
@@ -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)
index 35ebbaeacb52ef7acd1deeacefe7980af6dd0507..656b792d8641c2b8e81b6a458bbf12df78f77e2d 100644 (file)
@@ -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;
                }
 
index f3eacb679501fec7054547cd31008af24c4266a7..5742ecef4a13647bbabd5349b864e5b736a838d5 100644 (file)
@@ -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);
index 852afbda05ecb41538ab912b7c81ca522c625b18..1d08abb66a6ba268f1a0f6a4e4d3c48346034c80 100644 (file)
@@ -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:
index b27d10d571680b0034947945fe575b32d1a4f3b1..b204298a375d005fbba5ad411cfc0529c346a0d6 100644 (file)
@@ -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 (file)
index 0000000..76f9a93
--- /dev/null
@@ -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 (file)
index 0000000..dcab871
--- /dev/null
@@ -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
index c73f9a24471c81f3215cbb6c841e5c697353734f..83c81977b95f251f574a50c66c7b1aeeb9764d4c 100644 (file)
@@ -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;
index 082d2b5adf77ecbf58525bb0606516a53b43aa0d..16b07a8384198f67506f5219bdde3aa5becc179e 100644 (file)
@@ -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);
 
index 36893bd873f9236223797832c5955901e70eda83..a56faece778c16be8718e2b63d465bdd43255328 100644 (file)
@@ -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
index 28689e0cf5b8e64053d22e104ae55b068d2f49be..f7773e0a8b02d627c86c2ed5f3faa08dc1f1ad56 100644 (file)
@@ -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;
index 1a4e29954bb4b160d1e08efea843f4ebe353edb9..540e5c0a17cb85e556d396889cd942af5a0683f1 100644 (file)
@@ -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;
index 50a81fa19a2803b55e3ba7d1cf1742f19983d318..0c49f4c4dc2910f76854a0f2f7c666d919a83a3d 100644 (file)
--- 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);
        }