{SCF_OP_3AC_RELOAD, "reload"},
{SCF_OP_3AC_RESAVE, "resave"},
- {SCF_OP_3AC_PUSH_RAX, "push rax"},
- {SCF_OP_3AC_POP_RAX, "pop rax"},
+ {SCF_OP_3AC_PUSH_RETS, "push rets"},
+ {SCF_OP_3AC_POP_RETS, "pop rets"},
{SCF_OP_3AC_MEMSET, "memset"},
{SCF_OP_3AC_INC, "inc3"},
scf_list_t h;
scf_list_init(&h);
- if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
+ if (scf_vector_add_unique(bb->entry_dn_actives, ds->dag_node) < 0)
return -ENOMEM;
int ret = _auto_gc_code_list_ref(&h, dag_list_head, ast, ds);
scf_list_t h;
scf_list_init(&h);
- if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
+ if (scf_vector_add_unique(bb->entry_dn_actives, ds->dag_node) < 0)
return -ENOMEM;
int ret = _auto_gc_code_list_freep(&h, dag_list_head, ast, ds);
scf_list_t h;
scf_list_init(&h);
- if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
+ if (scf_vector_add_unique(bb->entry_dn_actives, dn_array) < 0)
return -ENOMEM;
int ret = _auto_gc_code_list_memset_array(&h, dag_list_head, ast, dn_array);
scf_list_t h;
scf_list_init(&h);
- if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
+ if (scf_vector_add_unique(bb->entry_dn_actives, dn_array) < 0)
return -ENOMEM;
int ret = _auto_gc_code_list_free_array(&h, dag_list_head, ast, dn_array);
scf_logd("v: %s\n", v->w->text->data);
- if (scf_vector_add_unique(cur_bb->dn_reloads, dn) < 0)
+ if (scf_vector_add_unique(cur_bb->entry_dn_actives, dn) < 0)
return -ENOMEM;
}
ds2 = scf_vector_find_cmp(next_bb->ds_malloced, ds, scf_ds_cmp_like_indexes);
if (ds2) {
- uint32_t tmp = ds2->ret;
+ uint32_t tmp = ds2->ret_flag;
- ds2->ret |= ds->ret;
+ ds2->ret_flag |= ds->ret_flag;
+
+ if (tmp != ds2->ret_flag) {
+ scf_logd("*** ds2: %#lx, ret_index: %d, ret_flag: %d, ds: %#lx, ret_index: %d, ret_flag: %d\n",
+ 0xffff & (uintptr_t)ds2, ds2->ret_index, ds2->ret_flag,
+ 0xffff & (uintptr_t)ds, ds->ret_index, ds->ret_flag);
- if (tmp != ds2->ret)
count++;
+ ds2->ret_index = ds->ret_index;
+ }
continue;
}
if (!bb->ds_freed)
goto error_freed;
- bb->generate_flag = 1;
return bb;
error_freed:
uint32_t auto_ref_flag :1;
uint32_t auto_free_flag:1;
- uint32_t generate_flag :1;
-
uint32_t back_flag :1;
uint32_t loop_flag :1;
uint32_t group_flag :1;
SCF_OP_3AC_PUSH, // push a var to stack, only for 3ac & native
SCF_OP_3AC_POP, // pop a var from stack, only for 3ac & native
- SCF_OP_3AC_PUSH_RAX, // push rax, only for 3ac & native
- SCF_OP_3AC_POP_RAX, // pop rax, only for 3ac & native
+ SCF_OP_3AC_PUSH_RETS, // push return value registers, only for 3ac & native
+ SCF_OP_3AC_POP_RETS, // pop return value registers, only for 3ac & native
SCF_OP_3AC_MEMSET, //
ds2->active = ds->active;
ds2->inited = ds->inited;
ds2->updated = ds->updated;
- ds2->ret = ds->ret;
+
+ ds2->ret_flag = ds->ret_flag;
+ ds2->ret_index = ds->ret_index;
return ds2;
}
intptr_t color;
+ int ret_index;
+ uint32_t ret_flag:1;
+
uint32_t active :1;
uint32_t inited :1;
uint32_t updated:1;
uint32_t loaded :1;
- uint32_t ret :1;
};
scf_dn_index_t* scf_dn_index_alloc();
int scf_function_signature(scf_function_t* f)
{
+ scf_string_t* s;
+ scf_type_t* t = (scf_type_t*)f->node.parent;
+
int ret;
int i;
- if (f->signature)
- scf_string_free(f->signature);
-
- scf_string_t* s = scf_string_alloc();
+ s = scf_string_alloc();
if (!s)
return -ENOMEM;
- scf_type_t* t = (scf_type_t*)f->node.parent;
if (t->node.type >= SCF_STRUCT) {
assert(t->node.class_flag);
goto error;
}
- ret = scf_string_cat(s, f->node.w->text);
+ if (f->op_type >= 0) {
+ scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
+
+ if (!op->signature)
+ goto error;
+
+ ret = scf_string_cat_cstr(s, op->signature);
+ } else
+ ret = scf_string_cat(s, f->node.w->text);
+
if (ret < 0)
goto error;
scf_logd("f signature: %s\n", s->data);
if (t->node.type < SCF_STRUCT) {
+ if (f->signature)
+ scf_string_free(f->signature);
+
f->signature = s;
return 0;
}
scf_logd("f signature: %s\n", s->data);
+ if (f->signature)
+ scf_string_free(f->signature);
f->signature = s;
return 0;
int local_vars_size;
int code_bytes;
- uint32_t vargs_flag :1;
uint32_t visited_flag:1;
uint32_t bp_used_flag:1;
uint32_t extern_flag:1;
uint32_t inline_flag:1;
uint32_t member_flag:1;
+
+ uint32_t vargs_flag :1;
+ uint32_t void_flag :1;
};
scf_function_t* scf_function_alloc(scf_lex_word_t* w);
#include"scf_operator.h"
#include"scf_core_types.h"
-static scf_operator_t base_operators[] = {
- {SCF_OP_EXPR, "(", 0, 1, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_CALL, "(", 1, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_ARRAY_INDEX, "[", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_POINTER, "->", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_VA_START, "va_start", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_VA_ARG, "va_arg", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_VA_END, "va_end", 1, 1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_CONTAINER, "container", 1, 3, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_CREATE, "create", 2, -1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_TYPE_CAST, "(", 2, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_LOGIC_NOT, "!", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_BIT_NOT, "~", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_NEG, "-", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_POSITIVE, "+", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_SIZEOF, "sizeof", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
-
- {SCF_OP_INC, "++", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_DEC, "--", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
-
- {SCF_OP_INC_POST, "++", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_DEC_POST, "--", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
-
- {SCF_OP_DEREFERENCE, "*", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_ADDRESS_OF, "&", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
-
- {SCF_OP_MUL, "*", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_DIV, "/", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_MOD, "%", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_ADD, "+", 5, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_SUB, "-", 5, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_SHL, "<<", 6, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_SHR, ">>", 6, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_BIT_AND, "&", 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_BIT_OR, "|", 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_EQ, "==", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_NE, "!=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_GT, ">", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_LT, "<", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_GE, ">=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_LE, "<=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_LOGIC_AND, "&&", 9, 2, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_LOGIC_OR, "||", 9, 2, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_ASSIGN, "=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_ADD_ASSIGN, "+=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_SUB_ASSIGN, "-=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_MUL_ASSIGN, "*=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_DIV_ASSIGN, "/=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_MOD_ASSIGN, "%=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_SHL_ASSIGN, "<<=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_SHR_ASSIGN, ">>=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_AND_ASSIGN, "&=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {SCF_OP_OR_ASSIGN, "|=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
-
- {SCF_OP_BLOCK, "{}", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_RETURN, "return", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_BREAK, "break", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_CONTINUE, "continue", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_GOTO, "goto", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_LABEL, "label", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_IF, "if", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_WHILE, "while", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_DO, "do", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_FOR, "for", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {SCF_OP_SWITCH, "switch", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_CASE, "case", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {SCF_OP_DEFAULT, "default", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+static scf_operator_t base_operators[] =
+{
+ {"(", NULL, SCF_OP_EXPR, 0, 1, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"(", NULL, SCF_OP_CALL, 1, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"[", "i", SCF_OP_ARRAY_INDEX, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"->", "p", SCF_OP_POINTER, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"va_start", NULL, SCF_OP_VA_START, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"va_arg", NULL, SCF_OP_VA_ARG, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"va_end", NULL, SCF_OP_VA_END, 1, 1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"container", NULL, SCF_OP_CONTAINER, 1, 3, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"create", NULL, SCF_OP_CREATE, 2, -1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"(", NULL, SCF_OP_TYPE_CAST, 2, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"!", "not", SCF_OP_LOGIC_NOT, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"~", "bnot", SCF_OP_BIT_NOT, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"-", "neg", SCF_OP_NEG, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"+", "pos", SCF_OP_POSITIVE, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"sizeof", NULL, SCF_OP_SIZEOF, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+
+ {"++", "inc", SCF_OP_INC, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"--", "dec", SCF_OP_DEC, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+
+ {"++", "inc", SCF_OP_INC_POST, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"--", "dec", SCF_OP_DEC_POST, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+
+ {"*", NULL, SCF_OP_DEREFERENCE, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"&", NULL, SCF_OP_ADDRESS_OF, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT},
+
+ {"*", "mul", SCF_OP_MUL, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"/", "div", SCF_OP_DIV, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"%", "mod", SCF_OP_MOD, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"+", "add", SCF_OP_ADD, 5, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"-", "sub", SCF_OP_SUB, 5, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"<<", NULL, SCF_OP_SHL, 6, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {">>", NULL, SCF_OP_SHR, 6, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"&", "band", SCF_OP_BIT_AND, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"|", "bor", SCF_OP_BIT_OR, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"==", "eq", SCF_OP_EQ, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"!=", "ne", SCF_OP_NE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {">", "gt", SCF_OP_GT, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"<", "lt", SCF_OP_LT, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {">=", "ge", SCF_OP_GE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"<=", "le", SCF_OP_LE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"&&", NULL, SCF_OP_LOGIC_AND, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"||", NULL, SCF_OP_LOGIC_OR, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"=", "a", SCF_OP_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"+=", "add_", SCF_OP_ADD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"-=", "sub_", SCF_OP_SUB_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"*=", "mul_", SCF_OP_MUL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"/=", "div_", SCF_OP_DIV_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"%=", "mod_", SCF_OP_MOD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"<<=", NULL, SCF_OP_SHL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {">>=", NULL, SCF_OP_SHR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"&=", "and_", SCF_OP_AND_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"|=", "or_", SCF_OP_OR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+
+ {"{}", NULL, SCF_OP_BLOCK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"return", NULL, SCF_OP_RETURN, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"break", NULL, SCF_OP_BREAK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"continue", NULL, SCF_OP_CONTINUE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"goto", NULL, SCF_OP_GOTO, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"label", NULL, SCF_LABEL, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"if", NULL, SCF_OP_IF, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"while", NULL, SCF_OP_WHILE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"do", NULL, SCF_OP_DO, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"for", NULL, SCF_OP_FOR, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+
+ {"switch", NULL, SCF_OP_SWITCH, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"case", NULL, SCF_OP_CASE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"default", NULL, SCF_OP_DEFAULT, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
};
scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands)
struct scf_operator_s
{
- int type;
- char* name;
+ char* name;
+ char* signature;
+ int type;
- int priority;
- int nb_operands;
- int associativity;
+ int priority;
+ int nb_operands;
+ int associativity;
};
scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands);
scf_operator_t* scf_find_base_operator_by_type(const int type);
#endif
-
#include"scf_auto_gc_3ac.c"
+int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c);
+
static int _find_ds_malloced(scf_basic_block_t* bb, void* data)
{
scf_dn_status_t* ds = data;
if (scf_vector_find(bb->dn_reloads, data))
return 1;
+ if (scf_vector_find(bb->entry_dn_actives, data))
+ return 1;
+
scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data);
return 0;
}
if (scf_type_is_operator(dn->type))
ret = scf_vector_add(bb->dn_reloads, dn);
- else
- ret = scf_vector_add(bb->dn_loads, dn);
+// else
+// ret = scf_vector_add(bb->dn_loads, dn);
return ret;
}
return -ENOMEM;
}
+ scf_vector_free(bb1->prevs);
+ bb1->prevs = bb_split_prevs;
+ bb_split_prevs = NULL;
+
bb1->ds_auto_gc = scf_dn_status_clone(ds);
- if (!bb1->ds_auto_gc)
+ if (!bb1->ds_auto_gc) {
+ scf_basic_block_free(bb1);
return -ENOMEM;
+ }
+
+ int ret = scf_vector_add(bb1->nexts, bb);
+ if (ret < 0) {
+ scf_basic_block_free(bb1);
+ return ret;
+ }
bb1->call_flag = 1;
bb1->auto_free_flag = 1;
- scf_vector_add( bb1->nexts, bb);
- scf_vector_free(bb1->prevs);
-
- bb1->prevs = bb_split_prevs;
- bb_split_prevs = NULL;
-
scf_list_add_tail(&bb->list, &bb1->list);
scf_3ac_operand_t* dst;
if (!ds3)
return -ENOMEM;
- int ret = scf_vector_add(bb1->ds_malloced, ds3);
+ ret = scf_vector_add(bb1->ds_malloced, ds3);
if (ret < 0)
return ret;
}
}
- int ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds);
+ ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds);
if (ret < 0)
return ret;
return 0;
}
+static int _bb_add_last_free(scf_dn_status_t* ds, scf_basic_block_t* bb, scf_ast_t* ast, scf_function_t* f)
+{
+ scf_vector_t* vec = scf_vector_alloc();
+ if (!vec)
+ return -ENOMEM;
+
+ scf_basic_block_t* bb2;
+ int j;
+ int dfo = 0;
+
+ int ret = _bb_find_ds_malloced(bb, &f->basic_block_list_head, ds, vec);
+ if (ret < 0) {
+ scf_vector_free(vec);
+ return ret;
+ }
+
+#define AUTO_GC_FIND_MAX_DFO() \
+ do { \
+ for (j = 0; j < vec->size; j++) { \
+ bb2 = vec->data[j]; \
+ \
+ if (bb2->dfo > dfo) \
+ dfo = bb2->dfo; \
+ } \
+ } while (0)
+ AUTO_GC_FIND_MAX_DFO();
+ vec->size = 0;
+
+ ret = _bb_find_dn_active(bb, &f->basic_block_list_head, ds->dag_node, vec);
+ if (ret < 0) {
+ scf_vector_free(vec);
+ return ret;
+ }
+ AUTO_GC_FIND_MAX_DFO();
+ vec->size = 0;
+
+ for (j = 0; j < bb->dominators->size; j++) {
+ bb2 = bb->dominators->data[j];
+
+ if (bb2->dfo > dfo)
+ break;
+ }
+
+ ret = _bb_split_prevs(bb2, ds, vec);
+ if (ret < 0) {
+ scf_vector_free(vec);
+ return ret;
+ }
+
+ return _bb_split_prev_add_free(ast, f, bb2, ds, vec);
+}
+
static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f)
{
- scf_list_t* bb_list_head = &f->basic_block_list_head;
- scf_list_t* l;
+ scf_list_t* l = scf_list_tail(&f->basic_block_list_head);
scf_basic_block_t* bb;
scf_dn_status_t* ds;
scf_dag_node_t* dn;
scf_variable_t* v;
scf_vector_t* local_arrays;
- l = scf_list_tail(bb_list_head);
bb = scf_list_data(l, scf_basic_block_t, list);
scf_logd("bb: %p, bb->ds_malloced->size: %d\n", bb, bb->ds_malloced->size);
int ret;
int i;
- for (i = 0; i < bb->ds_malloced->size; ) {
+
+ for (i = 0; i < bb->ds_malloced->size; i++) {
ds = bb->ds_malloced->data[i];
dn = ds->dag_node;
v = dn->var;
- scf_logw("f: %s, last free: v_%d_%d/%s, ds->ret: %u\n",
- f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret);
+ scf_logw("%s(), last free: v_%d_%d/%s, ds->ret_flag: %u\n",
+ f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret_flag);
scf_dn_status_print(ds);
- if (ds->ret) {
- i++;
+ if (ds->ret_flag)
continue;
- }
if (ds->dn_indexes) {
-
- scf_dn_index_t* di;
-
- int var_index = 0;
int j;
+ scf_dn_index_t* di;
for (j = ds->dn_indexes->size - 1; j >= 0; j--) {
di = ds->dn_indexes->data[j];
break;
}
- if (-1 == di->index)
- var_index++;
- }
-
- if (var_index > 0) {
- if (v->nb_dimentions > 0 && v->local_flag) {
+ if (-1 == di->index) {
+ if (v->nb_dimentions > 0 && v->local_flag) {
- if (scf_vector_add_unique(local_arrays, dn) < 0)
- return -ENOMEM;
+ ret = scf_vector_add_unique(local_arrays, dn);
+ if (ret < 0)
+ goto error;
+ }
+ break;
}
-
- i++;
- continue;
}
- if (j >= 0) {
- i++;
+ if (j >= 0)
continue;
- }
- }
-
- scf_vector_t* vec = scf_vector_alloc();
- if (!vec)
- return -ENOMEM;
-
- scf_basic_block_t* bb1;
- scf_basic_block_t* bb_dominator;
-
- int dfo = 0;
- int j;
-
- ret = _bb_find_ds_malloced(bb, bb_list_head, ds, vec);
- if (ret < 0) {
- scf_vector_free(vec);
- return ret;
- }
-#define AUTO_GC_FIND_MAX_DFO() \
- do { \
- for (j = 0; j < vec->size; j++) { \
- bb1 = vec->data[j]; \
- \
- if (bb1->dfo > dfo) \
- dfo = bb1->dfo; \
- } \
- } while (0)
- AUTO_GC_FIND_MAX_DFO();
-
- vec->size = 0;
-
- ret = _bb_find_dn_active(bb, bb_list_head, dn, vec);
- if (ret < 0) {
- scf_vector_free(vec);
- return ret;
- }
- AUTO_GC_FIND_MAX_DFO();
-
- for (j = 0; j < bb->dominators->size; j++) {
- bb_dominator = bb->dominators->data[j];
-
- if (bb_dominator->dfo > dfo)
- break;
- }
-
- vec->size = 0;
-
- ret = _bb_split_prevs(bb_dominator, ds, vec);
- if (ret < 0) {
- scf_vector_free(vec);
- return ret;
}
- ret = _bb_split_prev_add_free(ast, f, bb_dominator, ds, vec);
+ ret = _bb_add_last_free(ds, bb, ast, f);
if (ret < 0)
- return ret;
- i++;
+ goto error;
}
for (i = 0; i < local_arrays->size; i++) {
ret = _bb_add_memset_array(ast, f, dn);
if (ret < 0)
- return ret;
+ goto error;
ret = _bb_add_free_arry(ast, f, bb, dn);
if (ret < 0)
- return ret;
+ goto error;
}
- return 0;
+ ret = 0;
+error:
+ scf_vector_free(local_arrays);
+ return ret;
}
#define AUTO_GC_BB_SPLIT(parent, child) \
scf_list_add_front(&parent->list, &child->list); \
} while (0)
-static int _optimize_auto_gc_bb_ref(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_list_t* bb_list_head, scf_dn_status_t* ds)
+static int _auto_gc_bb_split(scf_basic_block_t* parent, scf_basic_block_t** pchild)
+{
+ scf_basic_block_t* child = NULL;
+
+ AUTO_GC_BB_SPLIT(parent, child);
+
+ *pchild = child;
+ return 0;
+}
+
+static int _auto_gc_bb_ref(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb)
{
scf_basic_block_t* cur_bb = *pbb;
scf_basic_block_t* bb1 = NULL;
- scf_dag_node_t* dn = ds->dag_node;
+ scf_dag_node_t* dn = ds_obj->dag_node;
AUTO_GC_BB_SPLIT(cur_bb, bb1);
- bb1->ds_auto_gc = scf_dn_status_clone(ds);
+ bb1->ds_auto_gc = scf_dn_status_clone(ds_obj);
if (!bb1->ds_auto_gc)
return -ENOMEM;
- int ret = _bb_add_gc_code_ref(&f->dag_list_head, ast, bb1, ds);
+ int ret = _bb_add_gc_code_ref(&f->dag_list_head, ast, bb1, ds_obj);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
+ if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) {
+ ret = scf_vector_add(ds_malloced, ds_obj);
+ if (ret < 0)
+ return ret;
+
+ scf_dn_status_ref(ds_obj);
+ }
+
bb1->call_flag = 1;
bb1->dereference_flag = 0;
bb1->auto_ref_flag = 1;
return 0;
}
-static int _optimize_auto_gc_bb_free(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_dn_status_t* ds)
+static int _bb_split_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_dn_status_t* ds)
{
scf_basic_block_t* cur_bb = *pbb;
scf_basic_block_t* bb1 = NULL;
int __bb_find_ds_alias(scf_vector_t* aliases, scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head);
-static int _bb_need_ref(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced,
- scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+static int _bb_need_ref(scf_dag_node_t* dn, scf_vector_t* ds_malloced, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
{
- scf_dn_status_t* ds_alias;
+ scf_dn_status_t* ds = NULL;
scf_vector_t* aliases;
-
- int ret;
int i;
+ int ret = scf_ds_for_dn(&ds, dn);
+ if (ret < 0)
+ return ret;
+
+ if (scf_vector_find_cmp(ds_malloced, ds, scf_ds_cmp_like_indexes)) {
+ scf_dn_status_free(ds);
+ return 1;
+ }
+
aliases = scf_vector_alloc();
- if (!aliases)
+ if (!aliases) {
+ scf_dn_status_free(ds);
return -ENOMEM;
+ }
- ret = __bb_find_ds_alias(aliases, ds_obj, c, bb, bb_list_head);
- if (ret < 0)
- return ret;
+ ret = __bb_find_ds_alias(aliases, ds, c, bb, bb_list_head);
- scf_logd("aliases->size: %d\n", aliases->size);
+ scf_dn_status_free(ds);
+ ds = NULL;
+ if (ret < 0)
+ goto error;
- int need = 0;
+ ret = 0;
for (i = 0; i < aliases->size; i++) {
- ds_alias = aliases->data[i];
+ ds = aliases->data[i];
- if (!ds_alias->dag_node)
+ if (!ds->dag_node)
continue;
- if (scf_vector_find_cmp(ds_malloced, ds_alias, scf_ds_cmp_like_indexes)) {
- need = 1;
+ if (scf_vector_find_cmp(ds_malloced, ds, scf_ds_cmp_like_indexes)) {
+ ret = 1;
break;
}
}
- if (scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) {
- need = 1;
- }
-
+error:
+ scf_vector_clear(aliases, ( void (*)(void*) )scf_dn_status_free);
scf_vector_free (aliases);
- return need;
+ return ret;
}
static int _bb_split_prevs_need_free(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_vector_t* bb_split_prevs, scf_basic_block_t* bb)
return 0;
}
-static int _optimize_auto_gc_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+static int _auto_gc_bb_free(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_vector_t* ds_assigned, scf_ast_t* ast,
+ scf_function_t* f,
+ scf_basic_block_t* bb,
+ scf_basic_block_t** cur_bb)
{
- scf_list_t* l;
- scf_3ac_code_t* c;
- scf_vector_t* ds_malloced;
- scf_vector_t* ds_assigned;
-
- scf_basic_block_t* bb_prev = NULL;
- scf_basic_block_t* cur_bb = bb;
-
- ds_malloced = scf_vector_alloc();
- if (!ds_malloced)
- return -ENOMEM;
+ scf_vector_t* bb_split_prevs = scf_vector_alloc();
- ds_assigned = scf_vector_alloc();
- if (!ds_assigned)
+ if (!bb_split_prevs)
return -ENOMEM;
- // at first, the malloced vars, are ones malloced in previous blocks
-
- int ret = _bb_prevs_malloced(bb, ds_malloced);
+ int ret = _bb_split_prevs_need_free(ds_obj, ds_malloced, bb_split_prevs, bb);
if (ret < 0) {
- scf_vector_clear(ds_malloced, ( void (*)(void*) )scf_dn_status_free);
- scf_vector_free(ds_malloced);
+ scf_vector_free(bb_split_prevs);
return ret;
}
- for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
+ if (ret) {
+ if (!scf_vector_find_cmp(ds_assigned, ds_obj, scf_ds_cmp_like_indexes)
+ && bb_split_prevs->size > 0
+ && bb_split_prevs->size < bb->prevs->size) {
- c = scf_list_data(l, scf_3ac_code_t, list);
- l = scf_list_next(l);
-
- scf_3ac_operand_t* base;
- scf_3ac_operand_t* member;
- scf_3ac_operand_t* index;
- scf_3ac_operand_t* scale;
+ return _bb_split_prev_add_free(ast, f, bb, ds_obj, bb_split_prevs);
+ }
- scf_3ac_operand_t* dst;
- scf_3ac_operand_t* src;
- scf_dag_node_t* dn;
- scf_dn_status_t* ds_obj;
- scf_variable_t* v0;
+ ret = _bb_split_add_free(ast, f, cur_bb, ds_obj);
+ }
- if (SCF_OP_ASSIGN == c->op->type) {
+ scf_vector_free(bb_split_prevs);
+ bb_split_prevs = NULL;
+ return ret;
+}
- dst = c->dsts->data[0];
- v0 = dst->dag_node->var;
+static int _auto_gc_retval(scf_dn_status_t* ds_obj, scf_dag_node_t* dn, scf_vector_t* ds_malloced, scf_3ac_code_t* c, scf_function_t* f)
+{
+ scf_dag_node_t* pf;
+ scf_function_t* f2;
+ scf_variable_t* fret;
+ scf_node_t* parent;
+ scf_node_t* result;
- if (!scf_variable_may_malloced(v0))
- goto _end;
+ int i = 0;
- ds_obj = NULL;
+ if (dn->node->split_flag) {
+ parent = dn->node->split_parent;
- ret = scf_ds_for_dn(&ds_obj, dst->dag_node);
- if (!ds_obj)
- return -ENOMEM;
+ assert(SCF_OP_CALL == parent->type || SCF_OP_CREATE == parent->type);
- src = c->srcs->data[0];
- dn = src->dag_node;
+ for (i = 0; i < parent->result_nodes->size; i++) {
+ result = parent->result_nodes->data[i];
- } else if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type) {
+ if (dn->node == result)
+ break;
+ }
+ }
- assert(4 == c->srcs->size);
+ pf = dn->childs->data[0];
+ f2 = pf->var->func_ptr;
+ fret = f2->rets->data[i];
- base = c->srcs->data[0];
- index = c->srcs->data[1];
- scale = c->srcs->data[2];
- src = c->srcs->data[3];
- dn = src->dag_node;
- v0 = _scf_operand_get(base->node->parent);
+ if (!strcmp(f2->node.w->text->data, "scf__auto_malloc") || fret->auto_gc_flag) {
- if (!scf_variable_may_malloced(v0))
- goto _end;
+ assert(SCF_OP_RETURN != c->op->type);
+// fret = f->rets->data[i];
+// fret->auto_gc_flag = 1;
- ds_obj = NULL;
+ if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) {
- int ret = scf_ds_for_assign_array_member(&ds_obj, base->dag_node, index->dag_node, scale->dag_node);
+ int ret = scf_vector_add(ds_malloced, ds_obj);
if (ret < 0)
return ret;
- if (ds_obj->dag_node->var->arg_flag)
- ds_obj->ret = 1;
-
- } else if (SCF_OP_3AC_ASSIGN_POINTER == c->op->type) {
-
- assert(3 == c->srcs->size);
+ scf_dn_status_ref(ds_obj);
+ }
+ }
- base = c->srcs->data[0];
- member = c->srcs->data[1];
- src = c->srcs->data[2];
- dn = src->dag_node;
- v0 = member->dag_node->var;
+ return 0;
+}
- if (!scf_variable_may_malloced(v0))
- goto _end;
+static int _optimize_auto_gc_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_3ac_code_t* c;
+ scf_vector_t* ds_malloced;
+ scf_vector_t* ds_assigned;
+ scf_list_t* l;
- ds_obj = NULL;
+ ds_malloced = scf_vector_alloc();
+ if (!ds_malloced)
+ return -ENOMEM;
- int ret = scf_ds_for_assign_member(&ds_obj, base->dag_node, member->dag_node);
- if (ret < 0)
- return ret;
+ ds_assigned = scf_vector_alloc();
+ if (!ds_assigned) {
+ scf_vector_free(ds_malloced);
+ return -ENOMEM;
+ }
- if (ds_obj->dag_node->var->arg_flag)
- ds_obj->ret = 1;
+ // at first, the malloced vars, are ones malloced in previous blocks
- } else if (SCF_OP_3AC_ASSIGN_DEREFERENCE == c->op->type) {
+ int ret = _bb_prevs_malloced(bb, ds_malloced);
+ if (ret < 0)
+ goto error;
- assert(2 == c->srcs->size);
+ for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
- src = c->srcs->data[1];
- dn = src->dag_node;
- v0 = dn->var;
+ c = scf_list_data(l, scf_3ac_code_t, list);
+ l = scf_list_next(l);
- if (!scf_variable_may_malloced(v0))
- goto _end;
+ scf_dn_status_t* ds_obj = NULL;
+ scf_dn_status_t* ds = NULL;
+ scf_dag_node_t* dn = NULL;
- src = c->srcs->data[0];
- ds_obj = NULL;
+ if (SCF_OP_ASSIGN == c->op->type
+ || SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type
+ || SCF_OP_3AC_ASSIGN_POINTER == c->op->type
+ || SCF_OP_3AC_ASSIGN_DEREFERENCE == c->op->type) {
- int ret = scf_ds_for_assign_dereference(&ds_obj, src->dag_node);
+ ret = __auto_gc_ds_for_assign(&ds_obj, &dn, c);
if (ret < 0)
- return ret;
+ goto error;
- } else
- goto _end;
-
- scf_vector_t* bb_split_prevs = scf_vector_alloc();
- if (!bb_split_prevs)
- return -ENOMEM;
-
- ret = _bb_split_prevs_need_free(ds_obj, ds_malloced, bb_split_prevs, bb);
- if (ret < 0) {
- scf_loge("\n");
- return ret;
- }
-
- if (ret) {
- if (!scf_vector_find_cmp(ds_assigned, ds_obj, scf_ds_cmp_like_indexes)
- && bb_split_prevs->size > 0
- && bb_split_prevs->size < bb->prevs->size)
-
- ret = _bb_split_prev_add_free(ast, f, bb, ds_obj, bb_split_prevs);
- else {
- scf_vector_free(bb_split_prevs);
- bb_split_prevs = NULL;
+ if (!ds_obj)
+ goto end;
- ret = _optimize_auto_gc_bb_free(ast, f, &cur_bb, ds_obj);
+ if (SCF_OP_ASSIGN != c->op->type) {
+ if (ds_obj->dag_node->var->arg_flag)
+ ds_obj->ret_flag = 1;
}
+ } else
+ goto end;
- if (ret < 0)
- return ret;
- } else {
- scf_vector_free(bb_split_prevs);
- bb_split_prevs = NULL;
+ ret = _auto_gc_bb_free(ds_obj, ds_malloced, ds_assigned, ast, f, bb, &cur_bb);
+ if (ret < 0) {
+ scf_dn_status_free(ds_obj);
+ goto error;
}
- if (scf_vector_add(ds_assigned, ds_obj) < 0) {
+ ret = scf_vector_add(ds_assigned, ds_obj);
+ if (ret < 0) {
scf_dn_status_free(ds_obj);
- return -ENOMEM;
+ goto error;
}
-
-_ref:
+ref:
if (!dn->var->local_flag && cur_bb != bb)
dn ->var->tmp_flag = 1;
if (SCF_OP_CALL == dn->type || dn->node->split_flag) {
- if (dn->node->split_flag) {
- assert(SCF_OP_CALL == dn->node->split_parent->type
- || SCF_OP_CREATE == dn->node->split_parent->type);
- }
-
- scf_dag_node_t* dn_pf;
- scf_function_t* f2;
- scf_variable_t* ret;
-
- dn_pf = dn->childs->data[0];
- f2 = dn_pf->var->func_ptr;
- ret = f2->rets->data[0];
-
- if (!strcmp(f2->node.w->text->data, "scf__auto_malloc") || ret->auto_gc_flag) {
-
- if (SCF_OP_RETURN == c->op->type) {
- ret = f->rets->data[0];
- ret->auto_gc_flag = 1;
- }
-
- if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) {
-
- assert(0 == scf_vector_add(ds_malloced, ds_obj));
- } else {
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
- }
-
- if (cur_bb != bb) {
- scf_list_del(&c->list);
- scf_list_add_tail(&cur_bb->code_list_head, &c->list);
- }
- continue;
- }
- } else {
- scf_dn_status_t* ds = NULL;
-
- ret = scf_ds_for_dn(&ds, dn);
+ ret = _auto_gc_retval(ds_obj, dn, ds_malloced, c, f);
if (ret < 0)
- return ret;
-
- int ret = _bb_need_ref(ds, ds_malloced, c, bb, bb_list_head);
-
- scf_dn_status_free(ds);
- ds = NULL;
+ goto error;
+ } else {
+ ret = _bb_need_ref(dn, ds_malloced, c, bb, bb_list_head);
if (ret < 0)
- return ret;
+ goto error;
if (ret > 0) {
- scf_basic_block_t* bb2 = NULL;
-
- if (SCF_OP_RETURN == c->op->type) {
- scf_variable_t* ret = f->rets->data[0];
- ret->auto_gc_flag = 1;
- }
+ assert(SCF_OP_RETURN != c->op->type);
+// scf_variable_t* fret = f->rets->data[0];
+// fret->auto_gc_flag = 1;
if (cur_bb != bb) {
scf_list_del(&c->list);
scf_list_add_tail(&cur_bb->code_list_head, &c->list);
}
- int ret = _optimize_auto_gc_bb_ref(ast, f, &cur_bb, bb_list_head, ds_obj);
+ ret = _auto_gc_bb_ref(ds_obj, ds_malloced, ast, f, &cur_bb);
if (ret < 0)
- return ret;
-
- if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) {
-
- assert(0 == scf_vector_add(ds_malloced, ds_obj));
- } else {
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
- }
+ goto error;
if (l != scf_list_sentinel(&bb->code_list_head)) {
+ bb2 = NULL;
+ ret = _auto_gc_bb_split(cur_bb, &bb2);
+ if (ret < 0)
+ goto error;
- AUTO_GC_BB_SPLIT(cur_bb, bb2);
cur_bb = bb2;
}
-
continue;
}
}
-
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
-_end:
+end:
if (cur_bb != bb) {
scf_list_del(&c->list);
scf_list_add_tail(&cur_bb->code_list_head, &c->list);
}
}
- return 0;
+ ret = 0;
+error:
+ scf_vector_clear(ds_assigned, ( void (*)(void*) )scf_dn_status_free);
+ scf_vector_clear(ds_malloced, ( void (*)(void*) )scf_dn_status_free);
+ scf_vector_free (ds_assigned);
+ scf_vector_free (ds_malloced);
+ return ret;
}
static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
}
}
- ds->ret |= ds_obj->ret;
+ ds->ret_flag |= ds_obj->ret_flag;
+ ds->ret_index = ds_obj->ret_index;
return 0;
}
for (i = 0; i < bb2->ds_malloced->size; i++) {
ds2 = bb2->ds_malloced->data[i];
- if (!ds2->ret)
+ if (!ds2->ret_flag)
continue;
__bb_add_ds_append(bb, ds_obj, bb2, ds2);
return ret;
if (ds_obj->dag_node->var->arg_flag)
- ds_obj->ret = 1;
+ ds_obj->ret_flag = 1;
- ret = scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
+ ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node);
if (ret < 0) {
scf_dn_status_free(ds_obj);
return ret;
scf_3ac_operand_t* dst;
scf_3ac_operand_t* src = c->srcs->data[0];
scf_function_t* f2 = src->dag_node->var->func_ptr;
- scf_variable_t* ret = f2->rets->data[0];
+ scf_variable_t* fret;
scf_variable_t* v;
scf_dn_status_t* ds_obj;
- if (ret->auto_gc_flag) {
- dst = c->dsts->data[0];
- v = dst->dag_node->var;
+ assert(c->dsts->size <= f2->rets->size);
- if (!scf_variable_may_malloced(v))
- return 0;
+ int i;
+ for (i = 0; i < c->dsts->size; i++) {
+ dst = c->dsts->data[i];
- ds_obj = scf_dn_status_alloc(dst->dag_node);
- if (!ds_obj)
- return -ENOMEM;
+ fret = f2->rets->data[i];
+ v = dst->dag_node->var;
- _bb_add_ds(cur_bb, ds_obj);
+ scf_logd("--- f2: %s(), i: %d, auto_gc_flag: %d\n", f2->node.w->text->data, i, fret->auto_gc_flag);
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
+ if (fret->auto_gc_flag) {
+ if (!scf_variable_may_malloced(v))
+ return 0;
+
+ ds_obj = scf_dn_status_alloc(dst->dag_node);
+ if (!ds_obj)
+ return -ENOMEM;
+
+ _bb_add_ds(cur_bb, ds_obj);
+
+ scf_dn_status_free(ds_obj);
+ ds_obj = NULL;
+ }
}
return 0;
}
-static int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c)
+int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c)
{
scf_3ac_operand_t* base;
scf_3ac_operand_t* member;
return 0;
}
+static int _auto_gc_find_ref(scf_dn_status_t* ds_obj, scf_dag_node_t* dn, scf_3ac_code_t* c,
+ scf_basic_block_t* bb,
+ scf_basic_block_t* cur_bb,
+ scf_function_t* f)
+{
+ scf_dn_status_t* ds;
+ scf_dag_node_t* pf;
+ scf_function_t* f2;
+ scf_variable_t* fret;
+ scf_node_t* parent;
+ scf_node_t* result;
+
+ if (SCF_OP_CALL == dn->type || dn->node->split_flag) {
+ int i = 0;
+
+ if (dn->node->split_flag) {
+ parent = dn->node->split_parent;
+
+ assert(SCF_OP_CALL == parent->type || SCF_OP_CREATE == parent->type);
+
+ for (i = 0; i < parent->result_nodes->size; i++) {
+ result = parent->result_nodes->data[i];
+
+ if (dn->node == result)
+ break;
+ }
+ }
+
+ pf = dn->childs->data[0];
+ f2 = pf->var->func_ptr;
+ fret = f2->rets->data[i];
+
+ scf_logd("f2: %s, rets[%d], auto_gc_flag: %d\n", f2->node.w->text->data, i, fret->auto_gc_flag);
+
+ if (!strcmp(f2->node.w->text->data, "scf__auto_malloc")) {
+ _bb_add_ds(cur_bb, ds_obj);
+ return 1;
+ }
+
+ if (fret->auto_gc_flag) {
+ _bb_add_ds (cur_bb, ds_obj);
+ _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
+
+ ds = scf_dn_status_alloc(dn);
+ if (!ds)
+ return -ENOMEM;
+
+ _bb_del_ds(cur_bb, ds);
+
+ scf_dn_status_free(ds);
+ ds = NULL;
+ return 2;
+ }
+ } else {
+ ds = NULL;
+ int ret = scf_ds_for_dn(&ds, dn);
+ if (ret < 0)
+ return ret;
+
+ ret = _bb_find_ds_alias(ds, c, bb, &f->basic_block_list_head);
+
+ scf_dn_status_free(ds);
+ ds = NULL;
+ if (ret < 0)
+ return ret;
+
+ if (1 == ret) {
+ _bb_add_ds(cur_bb, ds_obj);
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+static int _auto_gc_find_return(scf_vector_t* objs, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_basic_block_t* cur_bb, scf_function_t* f)
+{
+ scf_3ac_operand_t* src;
+ scf_dn_status_t* ds_obj;
+ scf_dag_node_t* dn;
+ scf_variable_t* v;
+
+ int count = 0;
+ int i;
+
+ for (i = 0; i < c->srcs->size; i++) {
+ src = c->srcs->data[i];
+
+ dn = src->dag_node;
+ v = dn->var;
+
+ if (!scf_variable_may_malloced(dn->var))
+ continue;
+
+ if (v->w)
+ scf_logd("v: %s, line: %d\n", v->w->text->data, v->w->line);
+
+ while (dn) {
+ if (SCF_OP_TYPE_CAST == dn->type)
+ dn = dn->childs->data[0];
+
+ else if (SCF_OP_EXPR == dn->type)
+ dn = dn->childs->data[0];
+ else
+ break;
+ }
+
+ ds_obj = scf_dn_status_alloc(dn);
+ if (!ds_obj)
+ return -ENOMEM;
+
+ ds_obj->ret_flag = 1;
+ ds_obj->ret_index = i;
+
+ scf_logd("i: %d, ds: %#lx, ret_index: %d\n", i, 0xffffff &(uintptr_t)ds_obj, ds_obj->ret_index);
+// scf_dn_status_print(ds_obj);
+
+ int ret = _auto_gc_find_ref(ds_obj, dn, c, bb, cur_bb, f);
+ if (ret < 0) {
+ scf_dn_status_free(ds_obj);
+ return ret;
+ }
+
+ count += ret > 0;
+
+ if (ret > 1) {
+ ret = scf_vector_add(objs, ds_obj);
+ if (ret < 0) {
+ scf_dn_status_free(ds_obj);
+ return ret;
+ }
+ } else
+ scf_dn_status_free(ds_obj);
+ ds_obj = NULL;
+ }
+
+ return count;
+}
+
static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
{
scf_basic_block_t* cur_bb = bb;
int count = 0;
int ret;
+ int i;
for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
if (SCF_OP_ASSIGN != c->op->type) {
if (ds_obj->dag_node->var->arg_flag)
- ds_obj->ret = 1;
+ ds_obj->ret_flag = 1;
}
-#if 1
- } else if (SCF_OP_RETURN == c->op->type) {
- src = c->srcs->data[0];
- dn = src->dag_node;
- if (!scf_variable_may_malloced(dn->var))
- goto end;
+ } else if (SCF_OP_RETURN == c->op->type) {
- ds_obj = scf_dn_status_alloc(dn);
- if (!ds_obj)
+ scf_vector_t* objs = scf_vector_alloc();
+ if (!objs)
return -ENOMEM;
- ds_obj->ret = 1;
- goto ref;
-#endif
+ ret = _auto_gc_find_return(objs, c, bb, cur_bb, f);
+ if (ret < 0) {
+ scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free);
+ scf_vector_free (objs);
+ return ret;
+ }
+ count += ret;
+
+ if (cur_bb != bb) {
+ scf_list_del(&c->list);
+ scf_list_add_tail(&cur_bb->code_list_head, &c->list);
+ }
+
+ if (objs->size > 0 && l != scf_list_sentinel(&bb->code_list_head)) {
+
+ AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2);
+ cur_bb = bb2;
+
+ for (i = 0; i < objs->size; i++) {
+ ds_obj = objs->data[i];
+
+ ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node);
+ if (ret < 0) {
+ scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free);
+ scf_vector_free (objs);
+ return ret;
+ }
+ }
+ }
+
+ scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free);
+ scf_vector_free (objs);
+ continue;
+
} else if (SCF_OP_CALL == c->op->type) {
assert(c->srcs->size > 0);
_bb_del_ds(cur_bb, ds_obj);
count++;
-
ref:
while (dn) {
if (SCF_OP_TYPE_CAST == dn->type)
break;
}
- if (SCF_OP_CALL == dn->type || dn->node->split_flag) {
-
- if (dn->node->split_flag) {
- assert(SCF_OP_CALL == dn->node->split_parent->type
- || SCF_OP_CREATE == dn->node->split_parent->type);
- }
-
- scf_dag_node_t* dn_pf = dn->childs->data[0];
- scf_function_t* f2 = dn_pf->var->func_ptr;
- scf_variable_t* ret = f2->rets->data[0];
-
- scf_logd("f2: %s, ret->auto_gc_flag: %d\n", f2->node.w->text->data, ret->auto_gc_flag);
-
- if (!strcmp(f2->node.w->text->data, "scf__auto_malloc")) {
- _bb_add_ds(cur_bb, ds_obj);
- count++;
-
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
- goto end;
-
- } else if (ret->auto_gc_flag) {
-
- if (cur_bb != bb) {
- scf_list_del(&c->list);
- scf_list_add_tail(&cur_bb->code_list_head, &c->list);
- }
-
- _bb_add_ds (cur_bb, ds_obj);
- _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
-
- ds = scf_dn_status_alloc(dn);
- if (!ds) {
- scf_dn_status_free(ds_obj);
- return -ENOMEM;
- }
- _bb_del_ds(cur_bb, ds);
-
- scf_dn_status_free(ds);
- ds = NULL;
-
- if (l != scf_list_sentinel(&bb->code_list_head)) {
+ ret = _auto_gc_find_ref(ds_obj, dn, c, bb, cur_bb, f);
+ if (ret < 0) {
+ scf_dn_status_free(ds_obj);
+ return ret;
+ }
- AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2);
- cur_bb = bb2;
- scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
- }
+ count += ret > 0;
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
+ if (cur_bb != bb) {
+ scf_list_del(&c->list);
+ scf_list_add_tail(&cur_bb->code_list_head, &c->list);
+ }
- count++;
- continue;
- }
- } else {
- ds = NULL;
- ret = scf_ds_for_dn(&ds, dn);
- if (ret < 0) {
- scf_dn_status_free(ds_obj);
- return ret;
- }
+ if (ret > 1 && l != scf_list_sentinel(&bb->code_list_head)) {
- ret = _bb_find_ds_alias(ds, c, bb, &f->basic_block_list_head);
+ AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2);
+ cur_bb = bb2;
- scf_dn_status_free(ds);
- ds = NULL;
+ ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node);
if (ret < 0) {
scf_dn_status_free(ds_obj);
return ret;
}
-
- if (1 == ret) {
- if (cur_bb != bb) {
- scf_list_del(&c->list);
- scf_list_add_tail(&cur_bb->code_list_head, &c->list);
- }
-
- _bb_add_ds(cur_bb, ds_obj);
-
- if (l != scf_list_sentinel(&bb->code_list_head)) {
-
- AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2);
- cur_bb = bb2;
- scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
- }
-
- scf_dn_status_free(ds_obj);
- ds_obj = NULL;
-
- count++;
- continue;
- }
}
scf_dn_status_free(ds_obj);
ds_obj = NULL;
+ continue;
end:
if (cur_bb != bb) {
scf_list_del(&c->list);
scf_basic_block_t* bb;
scf_dn_status_t* ds;
scf_3ac_code_t* c;
+ scf_variable_t* fret;
int total = 0;
- int count;
+ int count = 0;
int ret;
- scf_logw("f: %s\n", f->node.w->text->data);
+ scf_logw("--- %s() ---\n", f->node.w->text->data);
do {
for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
int i;
for (i = 0; i < bb->ds_malloced->size; i++) {
ds = bb->ds_malloced->data[i];
+
+ if (!ds->ret_flag)
+ continue;
#if 1
- scf_logi("ds->ret: %u, ds->dag_node->var->arg_flag: %u\n", ds->ret, ds->dag_node->var->arg_flag);
+ scf_logi("ds: %#lx, ds->ret_flag: %u, ds->ret_index: %d, ds->dag_node->var->arg_flag: %u\n",
+ 0xffff & (uintptr_t)ds, ds->ret_flag, ds->ret_index, ds->dag_node->var->arg_flag);
scf_dn_status_print(ds);
- printf("\n");
#endif
- if (!ds->ret)
- continue;
if (ds->dag_node->var->arg_flag)
ds->dag_node->var->auto_gc_flag = 1;
else {
- scf_variable_t* ret = f->rets->data[0];
- ret->auto_gc_flag = 1;
+ assert(ds->ret_index < f->rets->size);
+
+ fret = f->rets->data[ds->ret_index];
+ fret->auto_gc_flag = 1;
_bb_find_ds_alias_leak(ds, c, bb, bb_list_head);
}
}
- scf_logi("f: %s *****\n\n", f->node.w->text->data);
+ scf_logi("--- %s() ---\n\n", f->node.w->text->data);
return total;
}
bb->index = f->nb_basic_blocks++;
- if (bb->generate_flag) {
- for (i = 0; i < bb->dn_loads->size; i++) {
- dn = bb->dn_loads->data[i];
+ for (i = 0; i < bb->dn_loads->size; i++) {
+ dn = bb->dn_loads->data[i];
- if (scf_vector_find(bb->dn_reloads, dn))
- continue;
+ if (scf_vector_find(bb->dn_reloads, dn))
+ continue;
- SCF_OPTIMIZER_LOAD(SCF_OP_3AC_LOAD, &bb->code_list_head);
- }
+ SCF_OPTIMIZER_LOAD(SCF_OP_3AC_LOAD, &bb->code_list_head);
+ }
- for (i = 0; i < bb->dn_saves->size; i++) {
- dn = bb->dn_saves->data[i];
+ for (i = 0; i < bb->dn_saves->size; i++) {
+ dn = bb->dn_saves->data[i];
- if (scf_vector_find(bb->dn_resaves, dn))
- continue;
+ if (scf_vector_find(bb->dn_resaves, dn))
+ continue;
- if (bb->loop_flag)
- SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->save_list_head);
- else {
- SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->code_list_head);
+ if (bb->loop_flag)
+ SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->save_list_head);
+ else {
+ SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->code_list_head);
- if (bb->cmp_flag) {
- scf_list_del(&save->list);
- scf_list_add_front(&bb->code_list_head, &save->list);
- }
+ if (bb->cmp_flag) {
+ scf_list_del(&save->list);
+ scf_list_add_front(&bb->code_list_head, &save->list);
}
}
}
}
if (bb->auto_ref_flag || bb->auto_free_flag) {
-
+#if 1
scf_3ac_code_t* c0 = scf_3ac_code_alloc();
scf_3ac_code_t* c1 = scf_3ac_code_alloc();
- c0->op = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RAX);
- c1->op = scf_3ac_find_operator(SCF_OP_3AC_POP_RAX);
+ c0->op = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RETS);
+ c1->op = scf_3ac_find_operator(SCF_OP_3AC_POP_RETS);
scf_list_add_front(&bb->code_list_head, &c0->list);
scf_list_add_tail(&bb->code_list_head, &c1->list);
+#endif
}
+
#if 1
scf_logd("bb: %p, bb->index: %d\n", bb, bb->index);
ret = scf_basic_block_active_vars(bb);
--- /dev/null
+
+#include "../lib/scf_capi.c"
+
+int*, int* f()
+{
+ int* p0 = scf__auto_malloc(sizeof(int));
+ int* p1 = scf__auto_malloc(sizeof(int));
+
+ *p0 = 1;
+ *p1 = 2;
+
+ return p0, p1;
+}
+
+int main(int argc, char* argv[])
+{
+ int* p0;
+ int* p1;
+
+ p0, p1 = f();
+
+ if (argc > 1)
+ return 1;
+
+ printf("%d, %d\n", *p0, *p1);
+ return 0;
+}
return 0;
}
-/* int operator+=(mat* this, mat* that)
- {
- if (this->depth != that->depth
- || this->width != that->width
- || this->height != that->height
- || this->count != that->count
- || this->type != that->type)
- return -1;
-
- if (MAT_TYPE_DOUBLE != this->type)
- return -1;
-
- int64_t c;
- int64_t y;
- int64_t x;
- int64_t z;
-
- double* d0 = (double*)this->data;
- double* d1 = (double*)that->data;
-
- for (c = 0; c < this->count; c++) {
-
- int64_t c0 = this->c + this->cstep * c;
- int64_t c1 = that->c + that->cstep * c;
-
- int64_t coffset0 = c0 * this->height * this->xstride;
- int64_t coffset1 = c1 * that->height * that->xstride;
-
- for (y = 0; y < this->height; y++) {
-
- int64_t y0 = this->y + this->ystep * y;
- int64_t y1 = that->y + that->ystep * y;
-
- int64_t yoffset0 = y0 * this->xstride * this->depth;
- int64_t yoffset1 = y1 * that->xstride * that->depth;
-
- for (x = 0; x < this->width; x++) {
-
- int64_t x0 = this->x + this->xstep * x;
- int64_t x1 = that->x + that->xstep * x;
-
- int64_t xoffset0 = x0 * this->depth;
- int64_t xoffset1 = x1 * that->depth;
-
- for (z = 0; z < this->depth; z++) {
-
- int64_t z0 = this->z + this->zstep * z;
- int64_t z1 = that->z + that->zstep * z;
-
- d0[coffset0 + yoffset0 + xoffset0 + z0] += d1[coffset1 + yoffset1 + xoffset1 + z1];
- }
- }
- }
- }
-
- return 0;
- }
-*/
mat*, int operator+(mat* this, mat* that)
{
-/* if (this->depth != that->depth
- || this->width != that->width
- || this->height != that->height
- || this->count != that->count
- || this->type != that->type)
- return NULL, -1;
-
- if (MAT_TYPE_DOUBLE != this->type)
- return NULL, -1;
-*/
mat* res;
res = create mat(MAT_TYPE_DOUBLE, NULL, this->depth, this->width, this->height, this->count);
m2 = create mat(MAT_TYPE_DOUBLE, (uint8_t*)c, 1, 2, 2, 1);
m3 = m0 + m1 + m2;
-// scf_printf("%s(),%d\n", __func__, __LINE__);
double* dd = (double*)m3->data;
int i;
for (i = 0; i < 4; i++)
printf("m3: %lf\n", dd[i]);
-// scf_printf("m1: %lf\n", *(double*)(m1->data + i * sizeof(double)));
return 0;
}
-
[SCF_OP_3AC_INC ] = _risc_inst_inc_handler,
[SCF_OP_3AC_DEC ] = _risc_inst_dec_handler,
- [SCF_OP_3AC_PUSH_RAX] = _risc_inst_push_rax_handler,
- [SCF_OP_3AC_POP_RAX ] = _risc_inst_pop_rax_handler,
+ [SCF_OP_3AC_PUSH_RETS] = _risc_inst_push_rax_handler,
+ [SCF_OP_3AC_POP_RETS ] = _risc_inst_pop_rax_handler,
[SCF_OP_3AC_MEMSET ] = _risc_inst_memset_handler,
[SCF_OP_3AC_INC ] = _risc_rcg_inc_handler,
[SCF_OP_3AC_DEC ] = _risc_rcg_dec_handler,
- [SCF_OP_3AC_PUSH_RAX] = _risc_rcg_push_rax_handler,
- [SCF_OP_3AC_POP_RAX ] = _risc_rcg_pop_rax_handler,
+ [SCF_OP_3AC_PUSH_RETS] = _risc_rcg_push_rax_handler,
+ [SCF_OP_3AC_POP_RETS ] = _risc_rcg_pop_rax_handler,
[SCF_OP_3AC_MEMSET ] = _risc_rcg_memset_handler,
return x64_inst_pointer(ctx, c, 1);
}
-static int _x64_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+static int _x64_inst_push_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
if (!c->instructions) {
c->instructions = scf_vector_alloc();
return -ENOMEM;
}
- scf_register_t* rax = x64_find_register("rax");
- scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+ scf_x64_context_t* x64 = ctx->priv;
+ scf_function_t* f = x64->f;
+
scf_instruction_t* inst;
+ scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+ scf_register_t* r;
- inst = x64_make_inst_G(push, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ int n = 0;
+ int i;
+
+ if (!f->void_flag) {
+ n = f->rets->size;
+
+ if (n > X64_ABI_RET_NB)
+ return -EINVAL;
+ }
+
+ for (i = 0; i < n; i++) {
+ r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8);
+
+ inst = x64_make_inst_G(push, r);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+ }
- inst = x64_make_inst_G(push, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
return 0;
}
-static int _x64_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
if (!c->instructions) {
c->instructions = scf_vector_alloc();
return -ENOMEM;
}
- scf_register_t* rax = x64_find_register("rax");
- scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G);
+ scf_x64_context_t* x64 = ctx->priv;
+ scf_function_t* f = x64->f;
+
scf_instruction_t* inst;
+ scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G);
+ scf_register_t* r;
- inst = x64_make_inst_G(pop, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ int n = 0;
+ int i;
+
+ if (!f->void_flag) {
+ n = f->rets->size;
+
+ if (n > X64_ABI_RET_NB)
+ return -EINVAL;
+ }
+
+ for (i = n - 1; i >= 0; i--) {
+ r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8);
+
+ inst = x64_make_inst_G(pop, r);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+ }
- inst = x64_make_inst_G(pop, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
return 0;
}
[SCF_OP_3AC_INC ] = _x64_inst_inc_handler,
[SCF_OP_3AC_DEC ] = _x64_inst_dec_handler,
- [SCF_OP_3AC_PUSH_RAX] = _x64_inst_push_rax_handler,
- [SCF_OP_3AC_POP_RAX ] = _x64_inst_pop_rax_handler,
+ [SCF_OP_3AC_PUSH_RETS] = _x64_inst_push_rets_handler,
+ [SCF_OP_3AC_POP_RETS] = _x64_inst_pop_rets_handler,
[SCF_OP_3AC_MEMSET ] = _x64_inst_memset_handler,
[SCF_OP_3AC_INC ] = _x64_rcg_inc_handler,
[SCF_OP_3AC_DEC ] = _x64_rcg_dec_handler,
- [SCF_OP_3AC_PUSH_RAX] = _x64_rcg_push_rax_handler,
- [SCF_OP_3AC_POP_RAX ] = _x64_rcg_pop_rax_handler,
+ [SCF_OP_3AC_PUSH_RETS] = _x64_rcg_push_rax_handler,
+ [SCF_OP_3AC_POP_RETS] = _x64_rcg_pop_rax_handler,
[SCF_OP_3AC_MEMSET ] = _x64_rcg_memset_handler,
return SCF_DFA_ERROR;
}
+ f->void_flag = void_flag;
+
if (f->rets->size > 4) {
scf_loge("function return values must NOT more than 4!\n");
return SCF_DFA_ERROR;
}
} else {
scf_operator_t* op = scf_find_base_operator(d->current_function->node.w->text->data, d->current_function->argv->size);
- if (!op) {
+
+ if (!op || !op->signature) {
scf_loge("operator: '%s', nb_operands: %d\n",
d->current_function->node.w->text->data, d->current_function->argv->size);
return SCF_DFA_ERROR;
assert(call->nb_nodes > 0);
- scf_loge("rets->nb_nodes: %d, call->result_nodes: %p\n", rets->nb_nodes, call->result_nodes);
- scf_loge("rets->nb_nodes: %d, call->result_nodes->size: %d\n", rets->nb_nodes, call->result_nodes->size);
+ scf_logd("rets->nb_nodes: %d, call->result_nodes: %p\n", rets->nb_nodes, call->result_nodes);
+ scf_logd("rets->nb_nodes: %d, call->result_nodes->size: %d\n", rets->nb_nodes, call->result_nodes->size);
assert(rets->nb_nodes <= call->result_nodes->size);