2, scf: support ++, -- for float & double in native/x64.
<script>
+var a = [1, 2];
var i;
-for (i = 0; i < 2; i++) {
- document.write(i);
-}
+for (i = 0; i < 2; )
+ document.write(a[i++]);
</script>
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
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;
}
-
+#if 1
assert(!html->tmp_list_js);
void* so = dlopen(obj->js_so->data, RTLD_LAZY);
f(html);
dlclose(so);
so = NULL;
-
+#endif
abc_char_t* c;
while ( html->tmp_list_js) {
c = html->tmp_list_js;
c->next = html->tmp_list;
html->tmp_list = c;
}
-#endif
}
return 0;
|| 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 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;
}
}
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;
}
}
}
- 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;
}
#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_unary_op;
extern scf_optimizer_t scf_optimizer_js_call;
extern scf_optimizer_t scf_optimizer_split_call;
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_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;
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_unary_op,
&scf_optimizer_js_call,
&scf_optimizer_split_call,
&scf_optimizer_dominators,
&scf_optimizer_auto_gc,
+ &scf_optimizer_js_array2,
+
&scf_optimizer_active_vars,
&scf_optimizer_loads_saves,
#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_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;
- 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;
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;
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;
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);
}
}
}
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;
--- /dev/null
+#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,
+};
#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;
- 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;
- 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;
+ }
+ 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;
+ }
- 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;
+
+ 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;
+
+ 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;
}
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;
- 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;
- 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;
+ };
}
}
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) {
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)
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)
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;
+ 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;
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);
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_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;
- }
- } 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++;
}
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;
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