1, js : support 'for() loop' with array[] & ++, --, master
authoryu.dongliang <18588496441@163.com>
Sun, 16 Nov 2025 04:35:41 +0000 (12:35 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 16 Nov 2025 04:35:49 +0000 (12:35 +0800)
2, scf: support ++, -- for float & double in native/x64.

12 files changed:
examples/js.html
html/Makefile
html/abc_html.c
js/core/scf_dag.c
js/core/scf_optimizer.c
js/core/scf_optimizer_js_array.c
js/core/scf_optimizer_js_array2.c [new file with mode: 0644]
js/core/scf_optimizer_js_unary_op.c
js/doc.c
js/native/x64/scf_x64_inst.c
js/parse/scf_dfa_for.c
ui/Makefile

index 7419820ebf51daa2d4881eaff97e74750f8006d4..c6906acda9af96f6b5c39a032b79812f6037db5e 100644 (file)
@@ -8,10 +8,10 @@
 
 <script>
 
 
 <script>
 
+var a = [1, 2];
 var i;
 var i;
-for (i = 0; i < 2; i++) {
-       document.write(i);
-}
+for (i = 0; i < 2; )
+       document.write(a[i++]);
 
 </script>
 
 
 </script>
 
index bfdac5123dc1575d9b7b0315fbe4c244fa29f050..67b5badcda16465860cc99f5c12f0a8a86c38655 100644 (file)
@@ -108,6 +108,7 @@ CFILES += ../js/core/scf_optimizer_dag.c
 CFILES += ../js/core/scf_optimizer_inline.c
 
 CFILES += ../js/core/scf_optimizer_js_array.c
 CFILES += ../js/core/scf_optimizer_inline.c
 
 CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_array2.c
 CFILES += ../js/core/scf_optimizer_js_teq.c
 CFILES += ../js/core/scf_optimizer_js_unary_op.c
 CFILES += ../js/core/scf_optimizer_js_call.c
 CFILES += ../js/core/scf_optimizer_js_teq.c
 CFILES += ../js/core/scf_optimizer_js_unary_op.c
 CFILES += ../js/core/scf_optimizer_js_call.c
index a7d1f1f36d8d92c6368044755971e6fe02dc52bd..a9b0fe0c47719018b3bdecfe04e952c31523d03a 100644 (file)
@@ -1008,13 +1008,13 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
                        scf_loge("\n");
                        return ret;
                }
                        scf_loge("\n");
                        return ret;
                }
-#if 1
+
                ret = scf_parse_link(obj->js_so->data, obj->js_obj->data, "../js/abc_libjs.so", "x64", 1);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
                }
                ret = scf_parse_link(obj->js_so->data, obj->js_obj->data, "../js/abc_libjs.so", "x64", 1);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
                }
-
+#if 1
                assert(!html->tmp_list_js);
 
                void* so = dlopen(obj->js_so->data, RTLD_LAZY);
                assert(!html->tmp_list_js);
 
                void* so = dlopen(obj->js_so->data, RTLD_LAZY);
@@ -1023,7 +1023,7 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
                f(html);
                dlclose(so);
                so = NULL;
                f(html);
                dlclose(so);
                so = NULL;
-
+#endif
                abc_char_t* c;
                while ( html->tmp_list_js) {
                        c = html->tmp_list_js;
                abc_char_t* c;
                while ( html->tmp_list_js) {
                        c = html->tmp_list_js;
@@ -1033,7 +1033,6 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
                        c->next = html->tmp_list;
                        html->tmp_list = c;
                }
                        c->next = html->tmp_list;
                        html->tmp_list = c;
                }
-#endif
        }
 
        return 0;
        }
 
        return 0;
index 54a58cb8d225ea603d40a6b83053a863820961ef..422c74c42dc11725b801bfd20a39b4b42dc5224e 100644 (file)
@@ -575,17 +575,25 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
                        || SCF_OP_INC_POST == node->type
                        || SCF_OP_DEC_POST == node->type
                        || SCF_OP_ADDRESS_OF == node->type) {
                        || SCF_OP_INC_POST == node->type
                        || SCF_OP_DEC_POST == node->type
                        || SCF_OP_ADDRESS_OF == node->type) {
-               if (dn->var == _scf_operand_get((scf_node_t*)node))
+               if (dn->var == _scf_operand_get(node))
                        return 1;
                        return 1;
+
                return 0;
        }
 
        if (!dn->childs) {
                return 0;
        }
 
        if (!dn->childs) {
-               if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) {
-                       int ret = __dn_same_call(dn, node, split);
-                       scf_logd("ret: %d\n", ret);
-                       return ret;
-               }
+               switch (node->type) {
+                       case SCF_OP_CALL:
+                               //if (1 == node->nb_nodes)
+                               return __dn_same_call(dn, node, split);
+                               break;
+
+                       case SCF_OP_POINTER:
+                               return dn->var == _scf_operand_get(node);
+                               break;
+                       default:
+                               break;
+               };
 
                return 0;
        }
 
                return 0;
        }
@@ -640,11 +648,8 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
        }
 
        if (dn->childs->size != node->nb_nodes) {
        }
 
        if (dn->childs->size != node->nb_nodes) {
-               if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) {
-                       int ret = __dn_same_call(dn, node, split);
-                       scf_logd("ret: %d\n", ret);
-                       return ret;
-               }
+               if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/)
+                       return __dn_same_call(dn, node, split);
 
                return 0;
        }
 
                return 0;
        }
@@ -693,11 +698,8 @@ cmp_childs:
                }
        }
 
                }
        }
 
-       if (SCF_OP_CALL == dn->type) {
-               int ret = __dn_same_call(dn, node, split);
-               scf_logd("ret: %d\n", ret);
-               return ret;
-       }
+       if (SCF_OP_CALL == dn->type)
+               return __dn_same_call(dn, node, split);
 
        return 1;
 }
 
        return 1;
 }
index bf646c4f39b6cc3857771bbe94d838cb637785d1..0ffc5e28dee4684dff03c2cf5d4b036c53e04382 100644 (file)
@@ -1,9 +1,9 @@
 #include"scf_optimizer.h"
 
 extern scf_optimizer_t   scf_optimizer_inline;
 #include"scf_optimizer.h"
 
 extern scf_optimizer_t   scf_optimizer_inline;
+extern scf_optimizer_t   scf_optimizer_js_unary_op;
 extern scf_optimizer_t   scf_optimizer_js_array;
 extern scf_optimizer_t   scf_optimizer_js_teq;
 extern scf_optimizer_t   scf_optimizer_js_array;
 extern scf_optimizer_t   scf_optimizer_js_teq;
-extern scf_optimizer_t   scf_optimizer_js_unary_op;
 extern scf_optimizer_t   scf_optimizer_js_call;
 
 extern scf_optimizer_t   scf_optimizer_split_call;
 extern scf_optimizer_t   scf_optimizer_js_call;
 
 extern scf_optimizer_t   scf_optimizer_split_call;
@@ -19,15 +19,18 @@ extern scf_optimizer_t   scf_optimizer_active_vars;
 extern scf_optimizer_t   scf_optimizer_pointer_aliases;
 extern scf_optimizer_t   scf_optimizer_loads_saves;
 
 extern scf_optimizer_t   scf_optimizer_pointer_aliases;
 extern scf_optimizer_t   scf_optimizer_loads_saves;
 
+extern scf_optimizer_t   scf_optimizer_basic_block;
+extern scf_optimizer_t   scf_optimizer_const_teq;
+
+extern scf_optimizer_t   scf_optimizer_js_unary_post;
+
 extern scf_optimizer_t   scf_optimizer_dominators;
 extern scf_optimizer_t   scf_optimizer_dominators_reverse;
 
 extern scf_optimizer_t   scf_optimizer_auto_gc_find;
 extern scf_optimizer_t   scf_optimizer_auto_gc;
 
 extern scf_optimizer_t   scf_optimizer_dominators;
 extern scf_optimizer_t   scf_optimizer_dominators_reverse;
 
 extern scf_optimizer_t   scf_optimizer_auto_gc_find;
 extern scf_optimizer_t   scf_optimizer_auto_gc;
 
-extern scf_optimizer_t   scf_optimizer_basic_block;
-
-extern scf_optimizer_t   scf_optimizer_const_teq;
+extern scf_optimizer_t   scf_optimizer_js_array2;
 
 extern scf_optimizer_t   scf_optimizer_loop;
 extern scf_optimizer_t   scf_optimizer_vla;
 
 extern scf_optimizer_t   scf_optimizer_loop;
 extern scf_optimizer_t   scf_optimizer_vla;
@@ -37,9 +40,9 @@ extern scf_optimizer_t   scf_optimizer_generate_loads_saves;
 static scf_optimizer_t*  scf_optimizers[] =
 {
        &scf_optimizer_inline, // global optimizer
 static scf_optimizer_t*  scf_optimizers[] =
 {
        &scf_optimizer_inline, // global optimizer
+       &scf_optimizer_js_unary_op,
        &scf_optimizer_js_array,
        &scf_optimizer_js_teq,
        &scf_optimizer_js_array,
        &scf_optimizer_js_teq,
-       &scf_optimizer_js_unary_op,
        &scf_optimizer_js_call,
 
        &scf_optimizer_split_call,
        &scf_optimizer_js_call,
 
        &scf_optimizer_split_call,
@@ -62,6 +65,8 @@ static scf_optimizer_t*  scf_optimizers[] =
        &scf_optimizer_dominators,
        &scf_optimizer_auto_gc,
 
        &scf_optimizer_dominators,
        &scf_optimizer_auto_gc,
 
+       &scf_optimizer_js_array2,
+
        &scf_optimizer_active_vars,
        &scf_optimizer_loads_saves,
 
        &scf_optimizer_active_vars,
        &scf_optimizer_loads_saves,
 
index 3940541925ccfbe159778a69708027c5944d4299..27996374b86937ab56d0565a26dafc930a3ed6df 100644 (file)
@@ -1,15 +1,20 @@
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
-static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* array, scf_node_t* index)
+static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* array, scf_node_t* index, scf_type_t* Object)
 {
        scf_3ac_code_t*  c;
 {
        scf_3ac_code_t*  c;
-       scf_variable_t*  v;
+       scf_variable_t*  v = _scf_operand_get(index);
        scf_function_t*  f = NULL;
        scf_type_t*      t = NULL;
        scf_node_t*      pf;
 
        scf_function_t*  f = NULL;
        scf_type_t*      t = NULL;
        scf_node_t*      pf;
 
-       int ret = scf_ast_find_global_function(&f, ast, "Object_array_realloc");
+       int ret;
+
+       if (v->type == Object->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");
        if (ret < 0)
                return ret;
 
        if (ret < 0)
                return ret;
 
@@ -81,6 +86,7 @@ static int __js_ref_obj(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* obj)
 
 static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head)
 {
 
 static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head)
 {
+       scf_3ac_operand_t* dst;
        scf_3ac_operand_t* base;
        scf_3ac_operand_t* index;
        scf_3ac_code_t*    c;
        scf_3ac_operand_t* base;
        scf_3ac_operand_t* index;
        scf_3ac_code_t*    c;
@@ -100,7 +106,7 @@ static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_bl
                c  = scf_list_data(l, scf_3ac_code_t, list);
                l  = scf_list_next(l);
 
                c  = scf_list_data(l, scf_3ac_code_t, list);
                l  = scf_list_next(l);
 
-               if (SCF_OP_ARRAY_INDEX == c->op->type || scf_type_is_assign_array_index(c->op->type)) {
+               if (scf_type_is_assign_array_index(c->op->type)) {
                        base  = c->srcs->data[0];
                        index = c->srcs->data[1];
                        array = base->node;
                        base  = c->srcs->data[0];
                        index = c->srcs->data[1];
                        array = base->node;
@@ -110,39 +116,40 @@ static int _optimize_js_array_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_bl
 
                        v = _scf_operand_get(array);
 
 
                        v = _scf_operand_get(array);
 
-                       if (v->type == Object->type) {
-                               c2  = NULL;
-                               ret = __js_array_realloc(ast, &c2, array, index->node);
-                               if (ret < 0)
-                                       return ret;
+                       if (v->type != Object->type)
+                               continue;
 
 
-                               c2->basic_block            = c->basic_block;
-                               c2->basic_block->call_flag = 1;
+                       c2  = NULL;
+                       ret = __js_array_realloc(ast, &c2, array, index->node, Object);
+                       if (ret < 0)
+                               return ret;
 
 
-                               assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head));
+                       c2->basic_block            = c->basic_block;
+                       c2->basic_block->call_flag = 1;
 
 
-                               scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
+                       assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head));
 
 
-                               if (f->js_flag && scf_type_is_assign_array_index(c->op->type)) {
-                                       base = c->srcs->data[3];
-                                       node = base->node;
+                       scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
 
 
-                                       while (SCF_OP_EXPR == node->type)
-                                               node = node->nodes[0];
+                       if (f->js_flag) {
+                               base = c->srcs->data[3];
+                               node = base->node;
 
 
-                                       v = _scf_operand_get(node);
+                               while (SCF_OP_EXPR == node->type)
+                                       node = node->nodes[0];
 
 
-                                       if (v->arg_flag) {
-                                               c2  = NULL;
-                                               ret = __js_ref_obj(ast, &c2, node);
-                                               if (ret < 0)
-                                                       return ret;
+                               v = _scf_operand_get(node);
 
 
-                                               c2->basic_block            = c->basic_block;
-                                               c2->basic_block->call_flag = 1;
+                               if (v->arg_flag) {
+                                       c2  = NULL;
+                                       ret = __js_ref_obj(ast, &c2, node);
+                                       if (ret < 0)
+                                               return ret;
 
 
-                                               scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
-                                       }
+                                       c2->basic_block            = c->basic_block;
+                                       c2->basic_block->call_flag = 1;
+
+                                       scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
                                }
                        }
                }
                                }
                        }
                }
@@ -156,6 +163,16 @@ static int _optimize_js_array(scf_ast_t* ast, scf_function_t* f, scf_vector_t* f
        if (!f)
                return -EINVAL;
 
        if (!f)
                return -EINVAL;
 
+       if (strcmp(f->node.w->text->data, "__js_main")) {
+               scf_string_t* s = f->node.w->file;
+
+               if (!strncmp(s->data + s->len - 8, "js/doc.c", 8))
+                       return 0;
+       }
+
+       printf("\n");
+       scf_logi("------- %s() ------ file: %s\n", f->node.w->text->data, f->node.w->file->data);
+
        scf_list_t*        bb_list_head = &f->basic_block_list_head;
        scf_list_t*        l;
        scf_basic_block_t* bb;
        scf_list_t*        bb_list_head = &f->basic_block_list_head;
        scf_list_t*        l;
        scf_basic_block_t* bb;
diff --git a/js/core/scf_optimizer_js_array2.c b/js/core/scf_optimizer_js_array2.c
new file mode 100644 (file)
index 0000000..007b09b
--- /dev/null
@@ -0,0 +1,265 @@
+#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)
+{
+       scf_3ac_operand_t* pf;
+       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)
+                       ret = scf_ast_find_global_function(&f, ast, "Object_array_index_obj");
+
+               else if (index->var->type == SCF_VAR_DOUBLE)
+                       ret = scf_ast_find_global_function(&f, ast, "Object_array_index_d");
+               else
+                       ret = scf_ast_find_global_function(&f, ast, "Object_array_index");
+       }
+       if (ret < 0)
+               return ret;
+
+       ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+       if (ret < 0)
+               return ret;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+       if (!v)
+               return -ENOMEM;
+       v->const_literal_flag = 1;
+
+       dn = scf_dag_node_alloc(v->type, v, (scf_node_t*)f);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dn)
+               return -ENOMEM;
+
+       pf = c->srcs->data[2];
+
+       if (pf->node)
+               scf_node_free(pf->node);
+
+       if (pf->dag_node) {
+               scf_list_del(&pf->dag_node->list);
+               scf_dag_node_free(pf->dag_node);
+       }
+
+       pf->node     = (scf_node_t*)f;
+       pf->dag_node = dn;
+
+       SCF_XCHG(c->srcs->data[2], c->srcs->data[1]);
+       SCF_XCHG(c->srcs->data[1], c->srcs->data[0]);
+
+       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)
+{
+       scf_basic_block_t*  bb2;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c2;
+       scf_list_t*         l2;
+       scf_list_t*         l3;
+
+       for (l2 = scf_list_prev(&c->list); l2 != scf_list_sentinel(&cur_bb->code_list_head); l2 = scf_list_prev(l2)) {
+               c2  = scf_list_data(l2, scf_3ac_code_t, list);
+
+               if (SCF_OP_POINTER == c2->op->type) {
+                       dst = c2->dsts->data[0];
+
+                       if (dst->dag_node == member)
+                               return c2;
+               }
+       }
+
+       for (l3 = scf_list_prev(&cur_bb->list); l3 != scf_list_sentinel(bb_list_head); l3 = scf_list_prev(l3)) {
+               bb2 = scf_list_data(l3, scf_basic_block_t, list);
+
+               if (bb2 == bb) {
+                       l2  =  scf_list_prev(l);
+
+                       if (l2 == &c->list)
+                               l2 =  scf_list_prev(l2);
+               } else
+                       l2 = scf_list_tail(&bb2->code_list_head);
+
+               for ( ; l2 != scf_list_sentinel(&bb2->code_list_head); l2 = scf_list_prev(l2)) {
+                       c2      = scf_list_data(l2, scf_3ac_code_t, list);
+
+                       if (SCF_OP_POINTER == c2->op->type) {
+                               dst = c2->dsts->data[0];
+
+                               if (dst->dag_node == member)
+                                       return c2;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+static int _optimize_js_array2_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_basic_block_t* cur_bb = bb;
+       scf_basic_block_t* bb2;
+       scf_basic_block_t* bb3;
+
+       scf_3ac_operand_t* base;
+       scf_3ac_operand_t* index;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    c2;
+       scf_dag_node_t*    array;
+       scf_dag_node_t*    member;
+       scf_type_t*        Object = NULL;
+       scf_list_t*        l;
+       scf_list_t*        l2;
+
+       int ret = scf_ast_find_global_type(&Object, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               if (cur_bb != bb) {
+                       scf_list_del(&c->list);
+                       scf_list_add_tail(&cur_bb->code_list_head, &c->list);
+
+                       c->basic_block = cur_bb;
+               }
+
+               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;
+
+               array  = member;
+               while (SCF_OP_EXPR == array->type || SCF_OP_POINTER == array->type)
+                       array = array->childs->data[0];
+
+               if (array->var->type != Object->type)
+                       continue;
+
+               if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type && index->dag_node->var->type != Object->type)
+                       continue;
+
+               int op_type = c->op->type;
+
+               ret = __js_array_index(ast, c, 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;
+#if 1
+               c2 = __js_array_find_3ac(member, 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);
+
+               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)) {
+                       bb2 = NULL;
+                       ret = scf_basic_block_split(cur_bb, &bb2);
+                       if (ret < 0)
+                               return ret;
+                       scf_list_add_front(&cur_bb->list, &bb2->list);
+
+                       if (SCF_OP_ARRAY_INDEX == op_type) {
+                               base = c->dsts->data[0];
+                               scf_vector_del(cur_bb->dn_resaves,      base->dag_node);
+                               scf_vector_del(cur_bb->exit_dn_actives, base->dag_node);
+
+                               base = c->srcs->data[2];
+                               scf_vector_del(cur_bb->dn_reloads,      base->dag_node);
+                       }
+
+                       scf_list_del(&c->list);
+                       scf_list_add_tail(&bb2->code_list_head, &c->list);
+
+                       c->basic_block = bb2;
+
+                       if (l != scf_list_sentinel(&bb->code_list_head)) {
+                               bb3 = NULL;
+                               ret = scf_basic_block_split(bb2, &bb3);
+                               if (ret < 0)
+                                       return ret;
+                               scf_list_add_front(&bb2->list, &bb3->list);
+
+                               bb3->ret_flag = bb->ret_flag;
+
+                               cur_bb = bb3;
+                       }
+               }
+
+               c->basic_block->call_flag = 1;
+       }
+
+       return 0;
+}
+
+static int _optimize_js_array2(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+       if (!f)
+               return -EINVAL;
+
+       if (strcmp(f->node.w->text->data, "__js_main")) {
+               scf_string_t* s = f->node.w->file;
+
+               if (!strncmp(s->data + s->len - 8, "js/doc.c", 8))
+                       return 0;
+       }
+
+       printf("\n");
+       scf_logi("------- %s() ------ file: %s\n", f->node.w->text->data, f->node.w->file->data);
+
+       scf_list_t*        bb_list_head = &f->basic_block_list_head;
+       scf_list_t*        l;
+       scf_basic_block_t* bb;
+
+       if (scf_list_empty(bb_list_head))
+               return 0;
+
+       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
+
+               bb = scf_list_data(l, scf_basic_block_t, list);
+               l  = scf_list_next(l);
+
+               if (bb->jmp_flag || bb->end_flag || bb->cmp_flag)
+                       continue;
+
+               int ret = _optimize_js_array2_bb(ast, f, bb, bb_list_head);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+scf_optimizer_t  scf_optimizer_js_array2 =
+{
+       .name     =  "js_array2",
+
+       .optimize =  _optimize_js_array2,
+
+       .flags    = SCF_OPTIMIZER_LOCAL,
+};
index b569a2961020275c15611cd85ad7fac0a90d44c1..baad7495e0173498e6e26fa30274fdc1035027b6 100644 (file)
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
-static int __js_unary_op(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* node, int op_type)
+static int __js_unary_pointer(scf_ast_t* ast, scf_node_t** __pointer, scf_node_t** __member, scf_node_t* base, scf_type_t* Object)
 {
 {
-       scf_3ac_code_t*  c;
-       scf_variable_t*  v;
-       scf_function_t*  f = NULL;
-       scf_type_t*      t = NULL;
-       scf_node_t*      pf;
-       scf_node_t*      fret;
-
-       char* fname = NULL;
-
-       switch (op_type) {
-               case SCF_OP_3AC_INC:
-                       fname = "Object_inc";
-                       break;
-
-               case SCF_OP_3AC_DEC:
-                       fname = "Object_dec";
-                       break;
-               default:
-                       return -1;
-                       break;
-       };
-
-       int ret = scf_ast_find_global_function(&f, ast, fname);
-       if (ret < 0)
-               return ret;
-
-       ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+       scf_variable_t*     v;
+       scf_variable_t*     d = scf_scope_find_variable(Object->scope, "d");
+       scf_type_t*         t = NULL;
+       scf_node_t*         parent = base->parent;
+       scf_node_t*         pointer;
+       scf_node_t*         member;
+
+       int ret = scf_ast_find_type_type(&t, ast, SCF_VAR_DOUBLE);
        if (ret < 0)
                return ret;
 
        if (ret < 0)
                return ret;
 
-       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+       v = SCF_VAR_ALLOC_BY_TYPE(d->w, t, 0, 0, NULL);
        if (!v)
                return -ENOMEM;
        if (!v)
                return -ENOMEM;
-       v->const_literal_flag = 1;
 
 
-       pf = scf_node_alloc(NULL, v->type, v);
-       scf_variable_free(v);
-       v = NULL;
-       if (!pf)
+       pointer = scf_node_alloc(d->w, SCF_OP_POINTER, NULL);
+       if (!pointer) {
+               scf_variable_free(v);
                return -ENOMEM;
                return -ENOMEM;
+       }
+       pointer->op     = scf_find_base_operator_by_type(SCF_OP_POINTER);
+       pointer->result = v;
+       v = NULL;
 
 
-       ret = scf_ast_find_type_type(&t, ast, SCF_VAR_VOID);
-       if (ret < 0)
+       ret = scf_node_add_child(pointer, base);
+       if (ret < 0) {
+               scf_node_free(pointer);
                return ret;
                return ret;
+       }
 
 
-       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 0, 0, NULL);
-       if (!v)
-               return -ENOMEM;
-       v->tmp_flag   = 1;
-       v->const_flag = 1;
+       int i;
+       for (i = 0; i < parent->nb_nodes; i++) {
+               if (parent->nodes[i] == base)
+                       parent->nodes[i] =  pointer;
+       }
+       pointer->parent = parent;
 
 
-       fret = scf_node_alloc(f->node.w, SCF_OP_CALL, NULL);
-       if (!fret) {
-               scf_variable_free(v);
-               scf_node_free(pf);
+       member = scf_node_alloc(NULL, d->type, d);
+       if (!member)
                return -ENOMEM;
                return -ENOMEM;
+
+       ret = scf_node_add_child(pointer, member);
+       if (ret < 0) {
+               scf_node_free(member);
+               return ret;
+       }
+
+       *__pointer = pointer;
+       *__member  = member;
+       return 0;
+}
+
+static int __js_unary_op(scf_ast_t* ast, scf_3ac_code_t* c, scf_node_t* base, scf_type_t* Object)
+{
+       scf_3ac_operand_t*  src;
+       scf_3ac_code_t*     c2;
+       scf_node_t*         parent  = base->parent;
+       scf_node_t*         pointer = NULL;
+       scf_node_t*         member  = NULL;
+
+       if (parent->nb_nodes < 2) {
+               int ret = __js_unary_pointer(ast, &pointer, &member, base, Object);
+               if (ret < 0)
+                       return ret;
+       } else {
+               assert(SCF_OP_POINTER == parent->type);
+
+               pointer = parent;
+               member  = parent->nodes[1];
        }
        }
-       fret->op     = scf_find_base_operator_by_type(SCF_OP_CALL);
-       fret->result = v;
-       v = NULL;
 
 
-       scf_node_t* srcs[] = {pf, node};
+       switch (c->op->type) {
+               case SCF_OP_INC:
+               case SCF_OP_DEC:
+                       c2 = scf_3ac_code_NN(SCF_OP_POINTER, &pointer, 1, pointer->nodes, 2);
+                       if (!c2)
+                               return -ENOMEM;
 
 
-       c = scf_3ac_code_NN(SCF_OP_CALL, &fret, 1, srcs, 2);
-       if (!c) {
-               scf_node_free(pf);
-               scf_node_free(fret);
+                       scf_list_add_tail(&c->list, &c2->list);
+                       break;
+               default:
+                       break;
+       };
+
+       src = c->srcs->data[0];
+       src->node = pointer;
+
+       scf_node_t* srcs[] = {base, member, pointer};
+
+       c2 = scf_3ac_code_NN(SCF_OP_3AC_ASSIGN_POINTER, NULL, 0, srcs, 3);
+       if (!c2)
                return -ENOMEM;
                return -ENOMEM;
+
+       scf_list_add_front(&c->list, &c2->list);
+       return 0;
+}
+
+static int __js_unary_assign(scf_ast_t* ast, scf_3ac_code_t* c, scf_node_t* base, scf_type_t* Object)
+{
+       scf_3ac_operand_t*  src = c->srcs->data[0];
+       scf_3ac_operand_t*  dst = c->dsts->data[0];
+       scf_3ac_code_t*     c2;
+       scf_variable_t*     v;
+       scf_node_t*         parent  = base->parent;
+       scf_node_t*         pointer = NULL;
+       scf_node_t*         member  = NULL;
+
+       if (parent->nb_nodes < 2) {
+               int ret = __js_unary_pointer(ast, &pointer, &member, base, Object);
+               if (ret < 0)
+                       return ret;
+       } else {
+               assert(SCF_OP_POINTER == parent->type);
+
+               pointer = parent;
+               member  = parent->nodes[1];
        }
 
        }
 
-       *pc = c;
+       switch (dst->node->type) {
+               case SCF_OP_INC_POST:
+               case SCF_OP_DEC_POST:
+                       c2 = scf_3ac_code_NN(SCF_OP_POINTER, &pointer, 1, pointer->nodes, 2);
+                       if (!c2)
+                               return -ENOMEM;
+
+                       scf_list_add_tail(&c->list, &c2->list);
+                       break;
+               default:
+                       break;
+       };
+
+       src->node = pointer;
+
+       v         = _scf_operand_get(dst->node);
+       v->type   = SCF_VAR_DOUBLE;
+       v->nb_pointers = 0;
        return 0;
 }
 
        return 0;
 }
 
@@ -101,27 +166,37 @@ static int _optimize_js_unary_op_bb(scf_ast_t* ast, scf_function_t* f, scf_basic
                        src  = c->srcs->data[0];
                        node = src->node;
 
                        src  = c->srcs->data[0];
                        node = src->node;
 
-                       while (SCF_OP_EXPR == node->type)
-                               node = node->nodes[0];
-
                        v = _scf_operand_get(node);
 
                        if (v->type != Object->type)
                                continue;
 
                        v = _scf_operand_get(node);
 
                        if (v->type != Object->type)
                                continue;
 
-                       c2  = NULL;
-                       ret = __js_unary_op(ast, &c2, node, c->op->type);
+                       ret = __js_unary_op(ast, c, node, Object);
                        if (ret < 0)
                                return ret;
 
                        if (ret < 0)
                                return ret;
 
-                       c2->basic_block            = c->basic_block;
-                       c2->basic_block->call_flag = 1;
+               } else if (SCF_OP_ASSIGN == c->op->type) {
+                       src  = c->srcs->data[0];
+                       dst  = c->dsts->data[0];
+                       node = src->node;
 
 
-                       scf_list_add_tail(&c->list, &c2->list);
+                       v = _scf_operand_get(node);
+
+                       if (v->type != Object->type)
+                               continue;
 
 
-                       scf_list_del(&c->list);
-                       scf_3ac_code_free(c);
-                       c = NULL;
+                       switch (dst->node->type) {
+                               case SCF_OP_INC:
+                               case SCF_OP_INC_POST:
+                               case SCF_OP_DEC_POST:
+                               case SCF_OP_DEC:
+                                       ret = __js_unary_assign(ast, c, node, Object);
+                                       if (ret < 0)
+                                               return ret;
+                                       break;
+                               default:
+                                       break;
+                       };
                }
        }
 
                }
        }
 
index 15505b2d35d29e903dcf03f150ffde58f4cbaa27..2d320eba0f0c234883df6fd27cd8c3db8f0f906b 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -437,6 +437,19 @@ struct Object
                return 0;
        }
 
                return 0;
        }
 
+       bool operator>(Object* this, Object* that)
+       {
+               if (JS_Number == this->type && JS_Number == that->type)
+                       return this->d > that->d;
+               return 0;
+       }
+       bool operator>(Object* this, double d)
+       {
+               if (JS_Number == this->type)
+                       return this->d > d;
+               return 0;
+       }
+
        void __release(Object* this)
        {
                if (this->members) {
        void __release(Object* this)
        {
                if (this->members) {
@@ -620,6 +633,35 @@ int Object_array_realloc(Object* this, int i)
        return 0;
 }
 
        return 0;
 }
 
+int Object_array_realloc_obj(Object* this, Object* index)
+{
+       int i = index->d;
+       return Object_array_realloc(this, i);
+}
+
+Object* Object_array_index(Object* this, int i)
+{
+       if (i < this->length)
+               return this->members[i];
+       return NULL;
+}
+
+Object* Object_array_index_d(Object* this, double d)
+{
+       int i = d;
+       if (i < this->length)
+               return this->members[i];
+       return NULL;
+}
+
+Object* Object_array_index_obj(Object* this, Object* index)
+{
+       int i = index->d;
+       if (i < this->length)
+               return this->members[i];
+       return NULL;
+}
+
 Object* document = NULL;
 
 void __js_main(Object* doc)
 Object* document = NULL;
 
 void __js_main(Object* doc)
index 985438098bc5046025323f5501642a2cb8c78137..c98b96f2a01abde4599bfb9189f62cb49c827522 100644 (file)
@@ -803,6 +803,59 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        return 0;
 }
 
        return 0;
 }
 
+static int _x64_inst_inc_float(scf_function_t* f, scf_3ac_code_t* c, int INC)
+{
+       scf_3ac_operand_t*  src = c->srcs->data[0];
+       scf_variable_t*     v   = src->dag_node->var;
+       scf_variable_t*     v1;
+       scf_register_t*     rs  = NULL;
+       scf_x64_OpCode_t*   OpCode;
+       scf_instruction_t*  inst = NULL;
+       scf_rela_t*         rela = NULL;
+
+       v1 = scf_variable_clone(v);
+       if (!v1)
+               return -ENOMEM;
+
+       scf_string_free(v1->w->text);
+       v1->w->text = scf_string_cstr("1.0");
+       if (!v1->w->text) {
+               scf_variable_free(v1);
+               return -ENOMEM;
+       }
+
+       scf_scope_push_var(f->scope, v1);
+
+       v1->const_literal_flag = 1;
+       v1->const_flag  = 1;
+       v1->global_flag = 1;
+       v1->local_flag  = 0;
+       v1->tmp_flag    = 0;
+
+       if (4 == v->size) {
+               if (SCF_X64_INC == INC)
+                       OpCode = x64_find_OpCode(SCF_X64_ADDSS, 4, 4, SCF_X64_E2G);
+               else
+                       OpCode = x64_find_OpCode(SCF_X64_SUBSS, 4, 4, SCF_X64_E2G);
+
+               v1->data.f = 1.0;
+       } else {
+               v1->data.d = 1.0;
+
+               if (SCF_X64_INC == INC)
+                       OpCode = x64_find_OpCode(SCF_X64_ADDSD, 8, 8, SCF_X64_E2G);
+               else
+                       OpCode = x64_find_OpCode(SCF_X64_SUBSD, 8, 8, SCF_X64_E2G);
+       }
+
+       X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
+
+       inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1);
+       X64_INST_ADD_CHECK(c->instructions, inst);
+       X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL);
+       return 0;
+}
+
 static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
 {
        if (!c->srcs || c->srcs->size != 1)
 static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
 {
        if (!c->srcs || c->srcs->size != 1)
@@ -818,11 +871,20 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
        if (0 == src->dag_node->color)
                return -EINVAL;
 
        if (0 == src->dag_node->color)
                return -EINVAL;
 
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
+       }
+
        scf_variable_t*     v    = src->dag_node->var;
        scf_register_t*     rs   = NULL;
        scf_x64_OpCode_t*   OpCode;
        scf_instruction_t*  inst = NULL;
 
        scf_variable_t*     v    = src->dag_node->var;
        scf_register_t*     rs   = NULL;
        scf_x64_OpCode_t*   OpCode;
        scf_instruction_t*  inst = NULL;
 
+       if (scf_variable_float(v))
+               return _x64_inst_inc_float(f, c, INC);
+
        int imm_size = 1;
        if (v->data_size > 0xff)
                imm_size = 4;
        int imm_size = 1;
        if (v->data_size > 0xff)
                imm_size = 4;
@@ -837,12 +899,6 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
                return -EINVAL;
        }
 
                return -EINVAL;
        }
 
-       if (!c->instructions) {
-               c->instructions = scf_vector_alloc();
-               if (!c->instructions)
-                       return -ENOMEM;
-       }
-
        if (v->nb_pointers > 0) {
                if (src->dag_node->color > 0) {
                        X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
        if (v->nb_pointers > 0) {
                if (src->dag_node->color > 0) {
                        X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
index a83a21d228d8e5835393a2e8901967e90a6651ef..543c1169499454feb1467c2a656d438a2754baae 100644 (file)
@@ -103,27 +103,36 @@ static int _for_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
                return SCF_DFA_ERROR;
        }
 
-       if (0 == fd->nb_semicolons) {
-               if (!fd->init_exprs)
-                       fd->init_exprs = scf_vector_alloc();
-
-               scf_vector_add(fd->init_exprs, d->expr);
-               d->expr = NULL;
-
-       } else if (1 == fd->nb_semicolons) {
-               fd->cond_expr = d->expr;
-               d->expr = NULL;
-
-       } else if (2 == fd->nb_semicolons) {
-               if (!fd->update_exprs)
-                       fd->update_exprs = scf_vector_alloc();
-
-               scf_vector_add(fd->update_exprs, d->expr);
-               d->expr = NULL;
-       } else {
-               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-               return SCF_DFA_ERROR;
-       }
+       switch (fd->nb_semicolons) {
+               case 0:
+                       if (d->expr) {
+                               if (!fd->init_exprs)
+                                       fd->init_exprs = scf_vector_alloc();
+
+                               scf_vector_add(fd->init_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+
+               case 1:
+                       fd->cond_expr = d->expr;
+                       d->expr = NULL;
+                       break;
+
+               case 2:
+                       if (d->expr) {
+                               if (!fd->update_exprs)
+                                       fd->update_exprs = scf_vector_alloc();
+
+                               scf_vector_add(fd->update_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+               default:
+                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
+                       return SCF_DFA_ERROR;
+                       break;
+       };
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),   SCF_DFA_HOOK_POST);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"), SCF_DFA_HOOK_POST);
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),   SCF_DFA_HOOK_POST);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"), SCF_DFA_HOOK_POST);
@@ -142,22 +151,25 @@ static int _for_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_top(s);
 
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_top(s);
 
-       if (0 == fd->nb_semicolons) {
-               if (d->expr) {
-                       if (!fd->init_exprs)
-                               fd->init_exprs = scf_vector_alloc();
+       switch (fd->nb_semicolons) {
+               case 0:
+                       if (d->expr) {
+                               if (!fd->init_exprs)
+                                       fd->init_exprs = scf_vector_alloc();
 
 
-                       scf_vector_add(fd->init_exprs, d->expr);
-                       d->expr = NULL;
-               }
-       } else if (1 == fd->nb_semicolons) {
-               if (d->expr) {
+                               scf_vector_add(fd->init_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+
+               case 1:
                        fd->cond_expr = d->expr;
                        d->expr = NULL;
                        fd->cond_expr = d->expr;
                        d->expr = NULL;
-               }
-       } else {
-               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-               return SCF_DFA_ERROR;
+                       break;
+               default:
+                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
+                       return SCF_DFA_ERROR;
+                       break;
        }
 
        fd->nb_semicolons++;
        }
 
        fd->nb_semicolons++;
@@ -237,11 +249,13 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        }
 
        if (2 == fd->nb_semicolons) {
        }
 
        if (2 == fd->nb_semicolons) {
-               if (!fd->update_exprs)
-                       fd->update_exprs = scf_vector_alloc();
+               if (d->expr) {
+                       if (!fd->update_exprs)
+                               fd->update_exprs = scf_vector_alloc();
 
 
-               scf_vector_add(fd->update_exprs, d->expr);
-               d->expr = NULL;
+                       scf_vector_add(fd->update_exprs, d->expr);
+                       d->expr = NULL;
+               }
        } else {
                scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
                return SCF_DFA_ERROR;
        } else {
                scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
                return SCF_DFA_ERROR;
index c177fdd2b410e6ae939fe9c3b34a01f77e79c104..d6ce2b04188190af68142ee8749221fa816d05c8 100644 (file)
@@ -158,6 +158,7 @@ CFILES += ../js/core/scf_optimizer.c
 CFILES += ../js/core/scf_optimizer_dag.c
 CFILES += ../js/core/scf_optimizer_inline.c
 CFILES += ../js/core/scf_optimizer_js_array.c
 CFILES += ../js/core/scf_optimizer_dag.c
 CFILES += ../js/core/scf_optimizer_inline.c
 CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_array2.c
 CFILES += ../js/core/scf_optimizer_js_teq.c
 CFILES += ../js/core/scf_optimizer_js_unary_op.c
 CFILES += ../js/core/scf_optimizer_js_call.c
 CFILES += ../js/core/scf_optimizer_js_teq.c
 CFILES += ../js/core/scf_optimizer_js_unary_op.c
 CFILES += ../js/core/scf_optimizer_js_call.c