<p>含有js的页面</p>
<script>
+function f()
+{
+ document.write(arguments.length);
+}
-var a = function(x, y) {
- return x + y;
- };
+f("hello", "world");
-document.write(a(1, 2));
</script>
</body>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<body>
+
+<h1>含有javascript的页面</h1>
+
+<p>含有js的页面</p>
+
+<script>
+function f(a, b)
+{
+ return a + b;
+}
+
+var c = f(1, 2);
+
+document.write(c);
+
+</script>
+
+</body>
+</html>
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_js_call.c
+
CFILES += ../js/core/scf_optimizer_split_call.c
CFILES += ../js/core/scf_optimizer_call.c
CFILES += ../js/core/scf_optimizer_common_expr.c
abc_char_t* c = NULL;
+ int flag = 0;
while (1) {
c = __html_pop_char(html);
if (!c) {
return -1;
}
- if ('<' == c->c)
- break;
+ if ('\'' == c->c || '\"' == c->c)
+ flag = !flag;
+
+ if (!flag) {
+ if ('<' == c->c)
+ break;
+ }
if ('\n' == c->c) {
html->n_lines++;
static int __html_js_path(scf_string_t** ppath, abc_obj_t* obj, const char* prefix, const char* ext, int dir_flag)
{
- if (*ppath)
- scf_string_free(*ppath);
-
- *ppath = scf_string_alloc();
- if (!*ppath)
+ scf_string_t* path = scf_string_alloc();
+ if (!path)
return -ENOMEM;
+ int ret = 0;
+
if (dir_flag) {
char* cwd = get_current_dir_name();
- if (!cwd)
+ if (!cwd) {
+ scf_string_free(path);
return -ENOMEM;
+ }
- int ret = scf_string_cat_cstr(*ppath, cwd);
+ ret = scf_string_cat_cstr(path, cwd);
free(cwd);
cwd = NULL;
if (ret < 0)
- return ret;
+ goto error;
- ret = scf_string_cat_cstr(*ppath, "/");
+ ret = scf_string_cat_cstr(path, "/");
if (ret < 0)
- return ret;
+ goto error;
}
if (prefix) {
- int ret = scf_string_cat_cstr(*ppath, prefix);
+ ret = scf_string_cat_cstr(path, prefix);
if (ret < 0)
- return ret;
+ goto error;
}
- int len = (*ppath)->len;
+ int len = path->len;
int i;
- int ret = scf_string_cat(*ppath, obj->file);
+ ret = scf_string_cat(path, obj->file);
if (ret < 0)
- return ret;
+ goto error;
- for (i = len; i < (*ppath)->len; i++) {
- char c = (*ppath)->data[i];
+ for (i = len; i < path->len; i++) {
+ char c = path->data[i];
if ('_' == c
|| ('0' <= c && c <= '9')
|| ('A' <= c && c <= 'Z'))
continue;
- (*ppath)->data[i] = '_';
+ path->data[i] = '_';
}
char buf[256];
len = snprintf(buf, sizeof(buf) - 1, "_%d_%d", obj->line, obj->pos);
- ret = scf_string_cat_cstr_len(*ppath, buf, len);
+ ret = scf_string_cat_cstr_len(path, buf, len);
if (ret < 0)
- return ret;
+ goto error;
if (ext) {
- ret = scf_string_cat_cstr(*ppath, ext);
+ ret = scf_string_cat_cstr(path, ext);
if (ret < 0)
- return ret;
+ goto error;
}
+ if (*ppath)
+ scf_string_free(*ppath);
+
+ *ppath = path;
return 0;
+
+error:
+ scf_string_free(path);
+ return ret;
}
static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
}
if (obj->text) {
+ scf_logd("obj->text: %s\n", obj->text->data);
+
ret = scf_parse_file(html->js, obj->js_path->data, obj->text);
if (ret < 0)
return ret;
}
return -1;
}
+
+int abc_html_write_i(abc_html_t* html, int64_t i)
+{
+ char buf[128];
+ snprintf(buf, sizeof(buf) - 1, "%ld", i);
+
+ return abc_html_write(html, buf);
+}
+
+int abc_html_write_d(abc_html_t* html, double d)
+{
+ char buf[128];
+ snprintf(buf, sizeof(buf) - 1, "%lg", d);
+
+ return abc_html_write(html, buf);
+}
}
if (c->srcs) {
-
+
for (i = 0; i < c->srcs->size; i++) {
src = c->srcs->data[i];
}
#endif
- scf_vector_clear(bb->entry_dn_actives, NULL);
- scf_vector_clear(bb->dn_updateds, NULL);
+ scf_vector_clear(bb->entry_dn_actives, NULL);
+ scf_vector_clear(bb->entry_dn_inactives, NULL);
+ scf_vector_clear(bb->dn_updateds, NULL);
if (!scf_list_empty(&bb->code_list_head)) {
int ret;
int i;
+ scf_vector_clear(bb->dn_loads, NULL);
+ scf_vector_clear(bb->dn_saves, NULL);
+
for (i = 0; i < bb->entry_dn_actives->size; i++) {
dn = bb->entry_dn_actives->data[i];
f->signature = NULL;
}
+ if (f->src_code) {
+ scf_string_free(f->src_code);
+ f->src_code = NULL;
+ }
+
if (f->rets) {
scf_vector_clear(f->rets, ( void (*)(void*) ) scf_variable_free);
scf_vector_free (f->rets);
scf_scope_t* scope;
scf_string_t* signature;
+ scf_string_t* src_code;
scf_list_t list; // for scope
int nb_nodes; // children nodes count
scf_node_t** nodes; // children nodes
+ scf_expr_t* js_create; // the expr which created this node, only for js!
+
union {
scf_variable_t* var;
scf_lex_word_t* w;
uint32_t split_flag :1; // set when node is a split node of its parent
uint32_t _3ac_done :1; // set when node's 3ac code is made
+ uint32_t this_done :1; // set when node is a function call() & its 'this' pointer is set
+
uint32_t semi_flag :1; // set when followed by a ';'
};
#if 1
assert(1 == nb_nodes);
- scf_handler_data_t* d = data;
+ scf_handler_data_t* d = data;
+ scf_node_t* parent = nodes[0]->parent;
+
+ if (parent->_3ac_done)
+ return 0;
int ret = _scf_expr_calculate_internal(ast, nodes[0], d);
if (ret < 0)
#include"scf_optimizer.h"
extern scf_optimizer_t scf_optimizer_inline;
+extern scf_optimizer_t scf_optimizer_js_array;
+extern scf_optimizer_t scf_optimizer_js_call;
+
extern scf_optimizer_t scf_optimizer_split_call;
extern scf_optimizer_t scf_optimizer_dag;
static scf_optimizer_t* scf_optimizers[] =
{
&scf_optimizer_inline, // global optimizer
+ &scf_optimizer_js_array,
+ &scf_optimizer_js_call,
+
&scf_optimizer_split_call,
&scf_optimizer_dag,
&scf_optimizer_loads_saves,
&scf_optimizer_auto_gc_find, // global optimizer
-
&scf_optimizer_dominators,
-
&scf_optimizer_auto_gc,
&scf_optimizer_basic_block,
&scf_optimizer_const_teq,
+ &scf_optimizer_active_vars,
+ &scf_optimizer_loads_saves,
+
&scf_optimizer_dominators,
&scf_optimizer_loop,
&scf_optimizer_vla,
static int _auto_gc_find_ret(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
{
+ if (!c->dsts)
+ return 0;
assert(c->srcs->size > 0);
scf_3ac_operand_t* dst;
}
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;
+
+ _bb_add_ds (cur_bb, ds_obj);
+ _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
return 2;
}
} else {
0xffff & (uintptr_t)ds, ds->ret_flag, ds->ret_index, ds->dag_node->var->arg_flag);
scf_dn_status_print(ds);
#endif
-
if (ds->dag_node->var->arg_flag)
ds->dag_node->var->auto_gc_flag = 1;
else {
--- /dev/null
+#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)
+{
+ scf_3ac_code_t* c;
+ scf_variable_t* v;
+ 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");
+ 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;
+
+ pf = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!pf)
+ return -ENOMEM;
+
+ scf_node_t* srcs[3] = {pf, array, index};
+
+ c = scf_3ac_code_NN(SCF_OP_CALL, NULL, 0, srcs, 3);
+ if (!c) {
+ scf_node_free(pf);
+ return -ENOMEM;
+ }
+
+ *pc = c;
+ return 0;
+}
+
+static int _optimize_js_array_bb(scf_ast_t* ast, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+ scf_3ac_operand_t* base;
+ scf_3ac_operand_t* index;
+ scf_3ac_code_t* c;
+ scf_3ac_code_t* c2;
+ scf_variable_t* v;
+ scf_node_t* array;
+ scf_type_t* Object = NULL;
+ scf_list_t* l;
+
+ 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 (SCF_OP_ARRAY_INDEX == c->op->type || scf_type_is_assign_array_index(c->op->type)) {
+ base = c->srcs->data[0];
+ index = c->srcs->data[1];
+ array = base->node;
+
+ while (SCF_OP_EXPR == array->type || SCF_OP_POINTER == array->type)
+ array = array->nodes[0];
+
+ 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;
+
+ c2->basic_block = c->basic_block;
+
+ assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head));
+
+ scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int _optimize_js_array(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+ if (!f)
+ return -EINVAL;
+
+ 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_array_bb(ast, bb, bb_list_head);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+scf_optimizer_t scf_optimizer_js_array =
+{
+ .name = "js_array",
+
+ .optimize = _optimize_js_array,
+
+ .flags = SCF_OPTIMIZER_LOCAL,
+};
--- /dev/null
+#include"scf_optimizer.h"
+#include"scf_pointer_alias.h"
+
+static int __js_call_arguments(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* arguments, int i, scf_node_t* arg)
+{
+ 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* index;
+
+ int ret = scf_ast_find_global_function(&f, ast, "Object_func_arguments");
+ 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;
+
+ pf = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!pf)
+ return -ENOMEM;
+
+ // index
+ ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INT);
+ if (ret < 0)
+ return ret;
+
+ v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
+ if (!v)
+ return -ENOMEM;
+ v->data.u64 = i;
+ v->const_literal_flag = 1;
+
+ index = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!index)
+ return -ENOMEM;
+
+ scf_node_t* srcs[] = {pf, arguments, index, arg};
+
+ c = scf_3ac_code_NN(SCF_OP_CALL, NULL, 0, srcs, 4);
+ if (!c) {
+ scf_node_free(index);
+ scf_node_free(pf);
+ return -ENOMEM;
+ }
+
+ *pc = c;
+ return 0;
+}
+
+static int _optimize_js_call_bb(scf_ast_t* ast, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+ scf_3ac_operand_t* src;
+ scf_3ac_operand_t* args;
+ scf_3ac_code_t* c;
+ scf_3ac_code_t* c2;
+ scf_variable_t* v;
+ scf_function_t* f;
+ scf_node_t* array;
+ scf_type_t* Object = NULL;
+ scf_list_t* l;
+
+ 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 (SCF_OP_CALL != c->op->type)
+ continue;
+
+ src = c->srcs->data[0];
+ f = _scf_operand_get(src->node)->func_ptr;
+
+ if (!f->js_flag || !f->vargs_flag)
+ continue;
+ args = c->srcs->data[2];
+
+ int i;
+ for (i = 3; i < c->srcs->size; i++) {
+ src = c->srcs->data[i];
+
+ c2 = NULL;
+ ret = __js_call_arguments(ast, &c2, args->node, i - 3, src->node);
+ if (ret < 0)
+ return ret;
+
+ c2->basic_block = c->basic_block;
+
+ scf_list_add_tail(&c->list, &c2->list);
+ }
+ }
+
+ return 0;
+}
+
+static int _optimize_js_call(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+ if (!f)
+ return -EINVAL;
+
+ 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_call_bb(ast, bb, bb_list_head);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+scf_optimizer_t scf_optimizer_js_call =
+{
+ .name = "js_call",
+
+ .optimize = _optimize_js_call,
+
+ .flags = SCF_OPTIMIZER_LOCAL,
+};
int js_type;
int js_index;
+ scf_variable_t* js_var;
int nb_lbs; // number of '{}' when parse js object
int nb_rbs;
struct Object;
-int abc_html_write(Object* html, const char* s);
+int abc_html_write (Object* html, const char* s);
+int abc_html_write_i(Object* html, int64_t i);
+int abc_html_write_d(Object* html, double d);
+
+enum {
+ JS_Undef,
+ JS_Number,
+ JS_String,
+ JS_Object,
+};
struct Object
{
int type;
- int n_members;
+ int length;
Object** members;
char* name;
// p.x --> p.members[x]
int __init(Object* this, double d)
{
- this->d = d;
+ this->d = d;
+ this->type = JS_Number;
+ printf("this: %p, this->d: %lg, d: %lg\n\n", this, this->d, d);
return 0;
}
int __init(Object* this, int64_t d)
{
- this->d = d;
+ this->d = d;
+ this->type = JS_Number;
+ printf("this: %p, this->d: %lg, d: %ld\n\n", this, this->d, d);
return 0;
}
- int __init(Object* this, void* p)
+ int __init(Object* this, const char* s)
{
+ int len = strlen(s);
+
+ this->str = scf__auto_malloc(len + 1);
+ if (!this->str)
+ return -1;
+
+ memcpy(this->str, s, len + 1);
+
+ this->type = JS_String;
return 0;
}
- int __init(Object* this, const char* name, int n_members)
+ int __init(Object* this, const char* name, int length)
{
printf("this: %p, name: %s\n", this, name);
int len = strlen(name);
return -1;
memcpy(this->name, name, len + 1);
- this->n_members = n_members;
+ this->length = length;
- if (n_members > 0) {
- this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+ if (length > 0) {
+ this->members = scf__auto_malloc(sizeof(Object*) * length);
if (!this->members)
return -1;
}
printf("\n");
+
+ this->type = JS_Object;
return 0;
}
- int __init(Object* this, const char* name, int n_members, double d)
+ int __init(Object* this, const char* name, int length, double d)
{
printf("this: %p, name: %s\n", this, name);
int len = strlen(name);
return -1;
memcpy(this->name, name, len + 1);
- this->n_members = n_members;
+ this->length = length;
- if (n_members > 0) {
- this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+ if (length > 0) {
+ this->members = scf__auto_malloc(sizeof(Object*) * length);
if (!this->members)
return -1;
- }
+
+ this->type = JS_Object;
+ } else
+ this->type = JS_Number;
this->d = d;
- printf("this: %p, this->d: %lg, d: %lg\n", this, this->d, d);
+ printf("this: %p, this->d: %lg, d: %lg\n\n", this, this->d, d);
return 0;
}
const char* toString(Object* this)
{
- char* s = scf__auto_malloc(128);
- if (!s)
- return NULL;
+ char* p;
+ char* s;
+ int len;
+ int type = JS_Undef;
+
+ if (this)
+ type = this->type;
+
+ switch (type) {
+ case JS_Number:
+ s = scf__auto_malloc(128);
+ if (!s)
+ return NULL;
+
+ snprintf(s, 127, "%lg", this->d);
+ break;
+
+ case JS_String:
+ len = strlen(this->str);
+
+ s = scf__auto_malloc(len + 1);
+ if (!s)
+ return NULL;
+
+ memcpy(s, this->str, len + 1);
+ break;
+
+ case JS_Object:
+ p = "[object Object]";
+ len = strlen(p);
+
+ s = scf__auto_malloc(len + 1);
+ if (!s)
+ return NULL;
+
+ memcpy(s, p, len + 1);
+ break;
+
+ default:
+ p = "undefined";
+ len = strlen(p);
+
+ s = scf__auto_malloc(len + 1);
+ if (!s)
+ return NULL;
+
+ memcpy(s, p, len + 1);
+ break;
+ };
- snprintf(s, 127, "%lg", this->d);
return s;
}
abc_html_write(this, s);
}
+ void write(Object* this, const char* s)
+ {
+ abc_html_write(this, s);
+ }
+
+ void write(Object* this, int64_t i)
+ {
+ abc_html_write_i(this, i);
+ }
+
+ void write(Object* this, double d)
+ {
+ abc_html_write_i(this, d);
+ }
+
Object* operator+(Object* this, Object* that)
{
Object* res = create Object(this->d + that->d);
{
if (this->members) {
int i;
- for (i = 0; i < this->n_members; i++) {
+ for (i = 0; i < this->length; i++) {
if (this->members[i]) {
this->members[i].__release();
}
};
+void Object_func_arguments(Object* this, int i, Object* arg)
+{
+ if (i < this->length) {
+ scf__auto_ref(arg);
+ this->members[i] = arg;
+ }
+}
+
+int Object_array_realloc(Object* this, int i)
+{
+ if (i < this->length)
+ return 0;
+
+ int n = i + 1;
+ void* p = scf__auto_malloc(sizeof(Object*) * n);
+ if (!p)
+ return -1;
+
+ if (this->length > 0) {
+ memcpy(p, this->members, sizeof(Object*) * this->length);
+
+ scf__auto_freep(&this->members, NULL);
+ }
+
+ this->members = p;
+ this->length = n;
+ return 0;
+}
+
Object* document = NULL;
void __js_main(Object* doc)
d->expr = NULL;
d->expr_local_flag++;
+ if (d->parent_block) {
+ ast->current_block = d->parent_block;
+ d->parent_block = NULL;
+ }
+
scf_stack_push(s, cd);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "call_rp"), SCF_DFA_HOOK_POST);
return SCF_DFA_NEXT_WORD;
}
+static int _call_add_arguments(scf_ast_t* ast, scf_lex_word_t* w, int n_members, scf_expr_t* e, scf_type_t* Object)
+{
+ scf_variable_t* v;
+ scf_block_t* b;
+ scf_type_t* pt = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+ scf_node_t* create;
+ scf_node_t* assign;
+ scf_node_t* node;
+ scf_node_t* arguments;
+ scf_expr_t* e2;
+
+ // add 'arguments'
+ v = SCF_VAR_ALLOC_BY_TYPE(w, Object, 0, 1, NULL);
+ if (!v)
+ return -ENOMEM;
+
+ arguments = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!arguments)
+ return -ENOMEM;
+
+ b = scf_block_alloc_cstr("multi_rets");
+ if (!b) {
+ scf_node_free(arguments);
+ return -ENOMEM;
+ }
+
+ int ret = scf_node_add_child((scf_node_t*)b, arguments);
+ if (ret < 0) {
+ scf_node_free(arguments);
+ scf_block_free(b);
+ return ret;
+ }
+
+ assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
+ if (!assign) {
+ scf_block_free(b);
+ return -ENOMEM;
+ }
+
+ ret = scf_node_add_child(assign, (scf_node_t*)b);
+ if (ret < 0) {
+ scf_node_free(assign);
+ scf_block_free(b);
+ return ret;
+ }
+ b = NULL;
+
+ // add create()
+ create = scf_node_alloc(w, SCF_OP_CREATE, NULL);
+ if (!create) {
+ scf_node_free(assign);
+ return -ENOMEM;
+ }
+
+ ret = scf_node_add_child(assign, create);
+ if (ret < 0) {
+ scf_node_free(create);
+ scf_node_free(assign);
+ return ret;
+ }
+
+ // add construct() for obj
+ v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL);
+ if (!v) {
+ scf_node_free(assign);
+ return -ENOMEM;
+ }
+ v->const_literal_flag = 1;
+
+ node = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!node) {
+ scf_node_free(assign);
+ return -ENOMEM;
+ }
+
+ ret = scf_node_add_child(create, node);
+ if (ret < 0) {
+ scf_node_free(node);
+ scf_node_free(assign);
+ return ret;
+ }
+
+ // add obj name
+ ret = scf_ast_add_const_str(ast, create, Object->w);
+ if (ret < 0) {
+ scf_node_free(assign);
+ return ret;
+ }
+
+ // add obj members
+ ret = scf_ast_add_const_var(ast, create, SCF_VAR_INT, n_members);
+ if (ret < 0) {
+ scf_node_free(assign);
+ return ret;
+ }
+
+ e2 = scf_expr_alloc();
+ if (!e2) {
+ scf_node_free(assign);
+ return -ENOMEM;
+ }
+
+ ret = scf_node_add_child(e2, assign);
+ if (ret < 0) {
+ scf_expr_free(e2);
+ scf_node_free(assign);
+ return ret;
+ }
+
+ ret = scf_node_add_child((scf_node_t*)ast->current_block, e2);
+ if (ret < 0) {
+ scf_expr_free(e2);
+ return ret;
+ }
+
+ node = scf_node_clone(arguments);
+ if (!node)
+ return -ENOMEM;
+
+ ret = scf_node_add_child(e, node);
+ if (ret < 0) {
+ scf_node_free(node);
+ return ret;
+ }
+
+ e->js_create = e2;
+ return 0;
+}
+
static int _call_add_obj(scf_ast_t* ast, scf_lex_word_t* w, scf_node_t* call, scf_expr_t* e, scf_type_t* Object)
{
scf_variable_t* v = NULL;
}
scf_parse_t* parse = dfa->priv;
+ scf_ast_t* ast = parse->ast;
dfa_data_t* d = data;
scf_lex_word_t* w = words->data[words->size - 1];
scf_stack_t* s = d->module_datas[dfa_module_call.index];
}
scf_variable_t* r;
- scf_function_t* f;
- scf_expr_t* e;
+ scf_function_t* f = NULL;
scf_type_t* Object = NULL;
scf_node_t* pf = cd->call->nodes[0];
+ scf_expr_t* e;
while (SCF_OP_EXPR == pf->type)
pf = pf->nodes[0];
if (SCF_OP_POINTER == pf->type)
pf = pf->nodes[1];
- int ret = scf_ast_find_type(&Object, parse->ast, "Object");
+ int ret = scf_ast_find_type(&Object, ast, "Object");
if (ret < 0)
return ret;
+ int js_flag = 1;
if (SCF_FUNCTION_PTR == pf->type) {
f = pf->var->func_ptr;
+ js_flag = f->js_flag;
+
scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag);
} else
assert(Object->type == pf->type);
for (i = 0; i < cd->argv->size; i++) {
e = cd->argv->data[i];
- if (pf->type == Object->type) {
- ret = _call_add_obj(parse->ast, w, cd->call, e, Object);
+ if (js_flag) {
+ ret = _call_add_obj(ast, w, cd->call, e, Object);
if (ret < 0)
return ret;
}
// the last arg
if (d->expr) {
- if (pf->type == Object->type) {
- ret = _call_add_obj(parse->ast, w, cd->call, d->expr, Object);
+ if (js_flag) {
+ ret = _call_add_obj(ast, w, cd->call, d->expr, Object);
if (ret < 0)
return ret;
}
d->expr = NULL;
}
+ if (js_flag) {
+ e = scf_expr_alloc();
+ if (!e)
+ return -ENOMEM;
+
+ ret = _call_add_arguments(ast, w, cd->call->nb_nodes - 1, e, Object);
+ if (ret < 0)
+ return ret;
+
+ scf_node_add_child(cd->call, e);
+
+ int i;
+ for (i = cd->call->nb_nodes - 2; i >= 1; i--)
+ cd->call->nodes[i + 1] = cd->call->nodes[i];
+
+ cd->call->nodes[1] = e;
+ e = NULL;
+ }
+
if (cd->parent_expr)
d->expr = cd->parent_expr;
else
return SCF_DFA_NEXT_WORD;
}
-int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s)
+int _class_calculate_size(scf_type_t* s)
{
scf_variable_t* v;
dfa_data_t* d = data;
class_module_data_t* md = d->module_datas[dfa_module_class.index];
- if (_class_calculate_size(dfa, md->current_class) < 0) {
+ if (_class_calculate_size(md->current_class) < 0) {
scf_loge("\n");
return SCF_DFA_ERROR;
}
md->current_v = v;
- scf_logi("enum var: '%s', type: %d, size: %d\n", w->text->data, v->type, v->size);
-
return SCF_DFA_NEXT_WORD;
}
d->expr_local_flag--;
}
+ scf_logi("enum var: '%s', value: %ld\n", md->current_v->w->text->data, md->current_v->data.i64);
+
md->current_v = NULL;
return SCF_DFA_SWITCH_TO;
typedef struct {
scf_stack_t* ls_exprs;
scf_stack_t* lp_exprs;
- scf_block_t* parent_block;
+
scf_variable_t* current_var;
scf_type_t* current_struct;
int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
+int _class_calculate_size(scf_type_t* s);
+
static int _expr_is_expr(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
scf_node_t* node = NULL;
scf_type_t* pt = NULL;
scf_type_t* t = NULL;
+ scf_type_t* t2 = NULL;
scf_function_t* f = NULL;
dfa_identity_t* id = scf_stack_pop(d->current_identities);
scf_lex_word_t* w;
if (scf_ast_find_function(&f, parse->ast, w->text->data) < 0)
return SCF_DFA_ERROR;
- if (!f) {
+ if (f) {
+ var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
+ if (!var)
+ return -ENOMEM;
+
+ var->const_literal_flag = 1;
+
+ } else if (md->current_var && md->current_var->js_type >= 0) {
+ t = NULL;
+ if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0)
+ return SCF_DFA_ERROR;
+
+ t2 = NULL;
+ if (scf_ast_find_type_type(&t2, parse->ast, SCF_VAR_VAR) < 0)
+ return SCF_DFA_ERROR;
+
+ var = SCF_VAR_ALLOC_BY_TYPE(w, t2, 0, 0, NULL);
+ if (!var)
+ return -ENOMEM;
+ var->member_flag = 1;
+
+ scf_scope_push_var(t->scope, var);
+
+ if (_class_calculate_size(t) < 0)
+ return SCF_DFA_ERROR;
+
+ } else {
scf_loge("function '%s' not found\n", w->text->data);
return SCF_DFA_ERROR;
}
-
- var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
- if (!var)
- return -ENOMEM;
-
- var->const_literal_flag = 1;
+ } else {
+ if (d->current_function
+ && d->current_function->js_flag
+ && !strcmp(w->text->data, "arguments"))
+ d->current_function->vargs_flag = 1;
}
scf_logi("var: %s, member_flag: %d, js_type: %d, line: %d, pos: %d\n", var->w->text->data, var->member_flag, var->js_type, var->w->line, var->w->pos);
if (md->current_var
&& md->current_var->js_type >= 0
- && SCF_FUNCTION_PTR != var->type
- && var->member_flag) {
+ && var->member_flag
+ && strcmp(var->w->text->data, "length")) {
+
scf_logi("md->current_var: %s, var: %s, member_flag: %d, line: %d, pos: %d\n",
md->current_var->w->text->data, var->w->text->data, var->member_flag, var->w->line, var->w->pos);
return -ENOMEM;
v->const_literal_flag = 1;
v->data.i64 = var->js_index;
+ v->js_var = var;
node = scf_node_alloc(w, v->type, v);
scf_variable_free(v);
if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0)
return SCF_DFA_ERROR;
- scf_loge("t: %p, js_type: %d\n", t, t->type);
+ scf_logd("t: %p, js_type: %d\n", t, t->type);
parse->ast->current_block = (scf_block_t*)t;
}
}
scf_logd("\n");
scf_parse_t* parse = dfa->priv;
+ scf_ast_t* ast = parse->ast;
dfa_data_t* d = data;
scf_lex_word_t* w = words->data[words->size - 1];
expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
if (id && id->identity) {
- v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data);
+ v = scf_block_find_variable(ast->current_block, id->identity->text->data);
if (!v) {
scf_logw("'%s' not var\n", id->identity->text->data);
if (SCF_LEX_WORD_ARROW == w->type || SCF_LEX_WORD_DOT == w->type) {
assert(md->current_struct);
- if (!md->parent_block)
- md->parent_block = parse->ast->current_block;
+ if (!d->parent_block)
+ d->parent_block = ast->current_block;
- parse->ast->current_block = (scf_block_t*)md->current_struct;
+ ast->current_block = (scf_block_t*)md->current_struct;
- } else if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ scf_logi("ast->current_block: %p, js_type: %d\n", ast->current_block, ast->current_block->node.type);
+
+ } else if (d->parent_block) {
+ ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
return _expr_action_op(dfa, words, data, 2);
scf_stack_push(md->lp_exprs, d->expr);
d->expr = e;
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ if (d->parent_block) {
+ parse->ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
return SCF_DFA_NEXT_WORD;
}
}
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ if (d->parent_block) {
+ parse->ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
scf_expr_t* parent = scf_stack_pop(md->lp_exprs);
}
}
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ if (d->parent_block) {
+ parse->ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
if (md->current_var->js_type >= 0) {
}
}
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ if (d->parent_block) {
+ parse->ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
scf_expr_t* ls_parent = scf_stack_pop(md->ls_exprs);
return SCF_DFA_ERROR;
}
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
+ if (md->current_var)
+ md->current_var = NULL;
+
+ if (d->parent_block) {
+ parse->ast->current_block = d->parent_block;
+ d->parent_block = NULL;
}
scf_logd("d->expr: %p\n", d->expr);
d->expr = NULL;
}
- scf_logd("d->expr: %p, d->expr_local_flag: %d\n", d->expr, d->expr_local_flag);
+ scf_logi("d->expr: %p, d->expr_local_flag: %d\n", d->expr, d->expr_local_flag);
}
return SCF_DFA_OK;
assert(t->scope);
- if (!strcmp(f->node.w->text->data, "__init")) {
+ if (!strcmp(f->node.w->text->data, "__release")) {
- fprev = scf_scope_find_same_function(t->scope, f);
-
- } else {
fprev = scf_scope_find_function(t->scope, f->node.w->text->data);
-
- if (fprev && !scf_function_same(fprev, f)) {
+ if (fprev) {
scf_loge("function '%s' can't be overloaded, repeated declare first in line: %d, second in line: %d\n",
f->node.w->text->data, fprev->node.w->line, f->node.w->line);
return SCF_DFA_ERROR;
}
+ } else {
+ fprev = scf_scope_find_same_function(t->scope, f);
}
} else {
scf_block_t* b = fd->parent_block;
}
if (fprev && !scf_function_same(fprev, f)) {
-
scf_loge("repeated declare function '%s', first in line: %d, second in line: %d, function overloading only can do in class\n",
f->node.w->text->data, fprev->node.w->line, f->node.w->line);
return SCF_DFA_ERROR;
scf_block_t* parent_block;
scf_expr_t* parent_expr;
+ int start_word;
} dfa_fun_data_t;
int _function_js_add_function(scf_dfa_t* dfa, scf_lex_word_t* w, dfa_data_t* d)
arg = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL);
if (!arg)
return SCF_DFA_ERROR;
+ arg->js_type = t->type;
scf_scope_push_var(d->current_function->scope, arg);
- scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
- d->argc, arg->nb_pointers, arg->nb_dimentions);
+ scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d, %s\n",
+ d->argc, arg->nb_pointers, arg->nb_dimentions, w->text->data);
scf_vector_add(d->current_function->argv, arg);
return SCF_DFA_NEXT_WORD;
}
-static int _function_js_action_vargs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
- dfa_data_t* d = data;
-
- d->current_function->vargs_flag = 1;
-
- return SCF_DFA_NEXT_WORD;
-}
-
static int _function_js_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_parse_t* parse = dfa->priv;
return SCF_DFA_NEXT_WORD;
}
+static int _function_js_action_func(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ dfa_data_t* d = data;
+ dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index];
+
+ fd->start_word = words->size - 1;
+
+ return SCF_DFA_NEXT_WORD;
+}
+
static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_parse_t* parse = dfa->priv;
dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index];
scf_lex_word_t* w;
scf_lex_word_t* this;
+ scf_lex_word_t* arguments;
if (words->size < 2)
return SCF_DFA_ERROR;
if (ret < 0)
return SCF_DFA_ERROR;
+ // add 'arguments'
+ arguments = scf_lex_word_alloc(w->file, 0, 0, SCF_LEX_WORD_ID);
+ if (!arguments)
+ return SCF_DFA_ERROR;
+
+ arguments->text = scf_string_cstr("arguments");
+ if (!arguments->text) {
+ scf_lex_word_free(arguments);
+ return SCF_DFA_ERROR;
+ }
+
+ ret = _function_js_add_arg(parse->ast, arguments, d);
+
+ scf_lex_word_free(arguments);
+ arguments = NULL;
+ if (ret < 0)
+ return SCF_DFA_ERROR;
+
return SCF_DFA_NEXT_WORD;
}
scf_lex_word_t* h = NULL;
dfa_fun_data_t* fd = d->module_datas[dfa_module_function_js.index];
scf_function_t* f = d->current_function;
+ scf_variable_t* arg;
scf_type_t* t;
+ int i;
+
parse->ast->current_block = (scf_block_t*)(fd->parent_block);
if (f->node.nb_nodes > 0)
f->node.define_flag = 1;
- w = scf_lex_word_clone(f->node.w);
- if (!w)
- return -ENOMEM;
- w->type = SCF_LEX_WORD_ID;
+ if (!f->vargs_flag) {
+ for (i = 0; i < f->argv->size; i++) {
+ arg = f->argv->data[i];
+
+ if (!strcmp(arg->w->text->data, "arguments"))
+ break;
+ }
+
+ assert(0 == scf_vector_del(f->argv, arg));
+ assert(0 == scf_vector_del(f->scope->vars, arg));
+
+ assert(2 == arg->refs);
+ arg->refs = 1;
+
+ scf_variable_free(arg);
+ arg = NULL;
+ }
+
+ for (i = fd->start_word; i < words->size; i++) {
+ w = words->data[i];
+
+ if (!f->src_code) {
+ f->src_code = scf_string_clone(w->text);
+ if (!f->src_code)
+ return -ENOMEM;
+ } else {
+ int ret = scf_string_cat_cstr_len(f->src_code, " ", 1);
+ if (ret < 0)
+ return ret;
+
+ ret = scf_string_cat(f->src_code, w->text);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ w = dfa->ops->pop_word(dfa);
dfa->ops->push_word(dfa, w);
+ switch (w->type) {
+ case SCF_LEX_WORD_SEMICOLON:
+ case SCF_LEX_WORD_COMMA:
+ case SCF_LEX_WORD_LP:
+ w = scf_lex_word_clone(f->node.w);
+ if (!w)
+ return -ENOMEM;
+ w->type = SCF_LEX_WORD_ID;
+
+ dfa->ops->push_word(dfa, w);
+ break;
+ default:
+ break;
+ };
+
d->expr = fd->parent_expr;
fd->parent_expr = NULL;
fd->parent_block = NULL;
static int _dfa_init_module_function_js(scf_dfa_t* dfa)
{
SCF_DFA_MODULE_NODE(dfa, function_js, comma, scf_dfa_is_comma, _function_js_action_comma);
- SCF_DFA_MODULE_NODE(dfa, function_js, vargs, scf_dfa_is_vargs, _function_js_action_vargs);
SCF_DFA_MODULE_NODE(dfa, function_js, end, scf_dfa_is_entry, _function_js_action_end);
SCF_DFA_MODULE_NODE(dfa, function_js, lp, scf_dfa_is_lp, _function_js_action_lp);
SCF_DFA_MODULE_NODE(dfa, function_js, rp, scf_dfa_is_rp, _function_js_action_rp);
- SCF_DFA_MODULE_NODE(dfa, function_js, func, scf_dfa_is_func, scf_dfa_action_next);
+ SCF_DFA_MODULE_NODE(dfa, function_js, func, scf_dfa_is_func, _function_js_action_func);
SCF_DFA_MODULE_NODE(dfa, function_js, fname, scf_dfa_is_identity, scf_dfa_action_next);
SCF_DFA_MODULE_NODE(dfa, function_js, arg, scf_dfa_is_identity, scf_dfa_action_next);
static int _dfa_init_syntax_function_js(scf_dfa_t* dfa)
{
SCF_DFA_GET_MODULE_NODE(dfa, function_js, comma, comma);
- SCF_DFA_GET_MODULE_NODE(dfa, function_js, vargs, vargs);
SCF_DFA_GET_MODULE_NODE(dfa, function_js, lp, lp);
SCF_DFA_GET_MODULE_NODE(dfa, function_js, rp, rp);
scf_dfa_node_add_child(comma, arg);
scf_dfa_node_add_child(arg, rp);
- scf_dfa_node_add_child(comma, vargs);
- scf_dfa_node_add_child(vargs, rp);
-
// function_js body
scf_dfa_node_add_child(rp, block);
int scf_object_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_vector_t* init_exprs);
-int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s);
+int _class_calculate_size(scf_type_t* s);
int _expr_add_var(scf_parse_t* parse, dfa_data_t* d);
if (ret < 0)
goto error;
- ret = _class_calculate_size(dfa, t);
+ ret = _class_calculate_size(t);
if (ret < 0)
goto error;
scf_variable_free(obj);
obj = NULL;
- return SCF_DFA_NEXT_WORD;
+ return SCF_DFA_SWITCH_TO;
}
static int _dfa_init_module_init_data(scf_dfa_t* dfa)
SCF_DFA_MODULE_NODE(dfa, init_data, colon, scf_dfa_is_colon, scf_dfa_action_next);
SCF_DFA_MODULE_NODE(dfa, init_data, comma, scf_dfa_is_comma, _data_action_comma);
- SCF_DFA_MODULE_NODE(dfa, init_data, func, scf_dfa_is_func, _data_action_func);
- SCF_DFA_MODULE_NODE(dfa, init_data, func_end, scf_dfa_is_entry, _data_action_func_end);
+// SCF_DFA_MODULE_NODE(dfa, init_data, func, scf_dfa_is_func, _data_action_func);
+// SCF_DFA_MODULE_NODE(dfa, init_data, func_end, scf_dfa_is_entry, _data_action_func_end);
SCF_DFA_MODULE_NODE(dfa, init_data, lb, scf_dfa_is_lb, _data_action_lb);
SCF_DFA_MODULE_NODE(dfa, init_data, rb, scf_dfa_is_rb, _data_action_rb);
SCF_DFA_GET_MODULE_NODE(dfa, init_data, comma, comma);
SCF_DFA_GET_MODULE_NODE(dfa, init_data, colon, colon);
SCF_DFA_GET_MODULE_NODE(dfa, init_data, member, member);
- SCF_DFA_GET_MODULE_NODE(dfa, init_data, func, func);
- SCF_DFA_GET_MODULE_NODE(dfa, init_data, func_end, func_end);
+// SCF_DFA_GET_MODULE_NODE(dfa, init_data, func, func);
+// SCF_DFA_GET_MODULE_NODE(dfa, init_data, func_end, func_end);
SCF_DFA_GET_MODULE_NODE(dfa, init_data, lb, lb);
SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb, rb);
scf_dfa_node_add_child(lb, member);
scf_dfa_node_add_child(member, colon);
- // init member function()
- scf_dfa_node_add_child(colon, func);
- scf_dfa_node_add_child(func, func_js);
- scf_dfa_node_add_child(func_end, comma);
- scf_dfa_node_add_child(func_end, member);
- scf_dfa_node_add_child(func_end, rb);
+// // init member function()
+// scf_dfa_node_add_child(colon, func);
+// scf_dfa_node_add_child(func, func_js);
+// scf_dfa_node_add_child(func_end, comma);
+// scf_dfa_node_add_child(func_end, member);
+// scf_dfa_node_add_child(func_end, rb);
scf_dfa_node_add_child(colon, expr);
scf_dfa_node_add_child(expr, comma);
} dfa_switch_data_t;
+int _expr_add_var(scf_parse_t* parse, dfa_data_t* d);
+
+
static int _switch_is_end(scf_dfa_t* dfa, void* word)
{
return 1;
dfa_data_t* d = data;
assert(!d->expr);
- d->expr_local_flag = 1;
+ d->expr_local_flag++;
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"), SCF_DFA_HOOK_POST);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST);
scf_node_add_child(sd->_switch, d->expr);
d->expr = NULL;
- d->expr_local_flag = 0;
+ assert(--d->expr_local_flag >= 0);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_end"), SCF_DFA_HOOK_END);
dfa_switch_data_t* sd = scf_stack_top(s);
assert(!d->expr);
- d->expr_local_flag = 1;
+ d->expr_local_flag++;
sd->child = scf_node_alloc(w, SCF_OP_CASE, NULL);
if (!sd->child)
scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child);
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_colon"), SCF_DFA_HOOK_PRE);
+
return SCF_DFA_NEXT_WORD;
}
return SCF_DFA_ERROR;
}
+ dfa_identity_t* id = scf_stack_top(d->current_identities);
+
+ if (id && id->identity) {
+ if (_expr_add_var(parse, d) < 0)
+ return SCF_DFA_ERROR;
+ }
+
scf_node_add_child(sd->child, d->expr);
d->expr = NULL;
- d->expr_local_flag = 0;
+ assert(--d->expr_local_flag >= 0);
} else {
assert(SCF_OP_DEFAULT == sd->child->type);
return 0;
}
+static int _semantic_add_this(scf_ast_t* ast, scf_function_t* f, scf_node_t* parent)
+{
+ scf_variable_t* v;
+ scf_type_t* t;
+ scf_node_t* this;
+ scf_node_t* p = parent->nodes[0];
+
+ while (p && SCF_OP_EXPR == p->type)
+ p = p->nodes[0];
+
+ if (SCF_OP_POINTER == p->type) {
+ assert(2 == p->nb_nodes);
+
+ this = p->nodes[0];
+ } else {
+ int ret = scf_ast_find_variable(&v, ast, "document");
+ if (ret < 0)
+ return ret;
+
+ this = scf_node_alloc(NULL, v->type, v);
+ }
+
+ if (!this)
+ return -ENOMEM;
+ scf_node_add_child(parent, this);
+
+ scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type);
+
+ int i;
+ for (i = parent->nb_nodes - 2; i >= 1; i--)
+ parent->nodes[i + 1] = parent->nodes[i];
+ parent->nodes[1] = this;
+
+ if (SCF_OP_POINTER == p->type) {
+ for (i = 0; i < p->parent->nb_nodes; i++) {
+ if (p->parent->nodes[i] == p) {
+ p->parent->nodes[i] = p->nodes[1];
+ p->nodes[1]->parent = p->parent;
+ break;
+ }
+ }
+
+ p->nodes[0] = NULL;
+ p->nodes[1] = NULL;
+
+ scf_node_free(p);
+ p = NULL;
+ }
+
+ if (f->js_flag) {
+ p = parent->nodes[0];
+ while (p && SCF_OP_EXPR == p->type)
+ p = p->nodes[0];
+
+ t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+ v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+ if (!v)
+ return -ENOMEM;
+ v->const_literal_flag = 1;
+
+ scf_node_free_data(p);
+
+ p->type = SCF_FUNCTION_PTR;
+ p->var = v;
+ }
+
+ return 0;
+}
+
static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(nb_nodes > 0);
scf_variable_t** pret = d->pret;
scf_variable_t* v0;
scf_variable_t* v1;
- scf_variable_t* v;
scf_function_t* f;
scf_type_t* t;
scf_type_t* Object = NULL;
scf_node_t* parent = nodes[0]->parent;
- scf_node_t* p;
- scf_node_t* this;
+ int i;
d->pret = &nodes[0]->result;
int ret = _scf_expr_calculate_internal(ast, nodes[0], d);
f = v0->func_ptr;
- if (f->member_flag) { // add 'this' pointer for member function
- p = nodes[0];
-
- while (p && SCF_OP_EXPR == p->type)
- p = p->nodes[0];
-
- if (SCF_OP_POINTER == p->type) {
- assert(2 == p->nb_nodes);
-
- this = p->nodes[0];
-
- scf_node_add_child(parent, this);
-
- int i;
- for (i = parent->nb_nodes - 2; i >= 1; i--)
- parent->nodes[i + 1] = parent->nodes[i];
- parent->nodes[1] = this;
-
- for (i = 0; i < p->parent->nb_nodes; i++) {
- if (p->parent->nodes[i] == p) {
- p->parent->nodes[i] = p->nodes[1];
- p->nodes[1]->parent = p->parent;
- break;
- }
- }
-
- p->nodes[0] = NULL;
- p->nodes[1] = NULL;
-
- scf_node_free(p);
- p = NULL;
- } else {
- ret = scf_ast_find_variable(&v, ast, "document");
+ if (f->member_flag) {
+ if (!parent->this_done) { // add 'this' pointer for member function
+ ret = _semantic_add_this(ast, f, parent);
if (ret < 0)
return ret;
+ parent->this_done = 1;
+ }
- if (nb_nodes < 2 || _scf_operand_get(nodes[1]) != v) {
-
- this = scf_node_alloc(NULL, v->type, v);
- if (!this)
- return -ENOMEM;
+ if (!f->js_flag) {
+ t = NULL;
+ v1 = _scf_operand_get(parent->nodes[1]);
- scf_node_add_child(parent, this);
+ ret = scf_ast_find_type_type(&t, ast, v1->type);
+ if (ret < 0)
+ return ret;
- int i;
- for (i = parent->nb_nodes - 2; i >= 1; i--)
- parent->nodes[i + 1] = parent->nodes[i];
- parent->nodes[1] = this;
+ scf_vector_t* argv = scf_vector_alloc();
+ if (!argv)
+ return -ENOMEM;
- scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type);
+ for (i = 1; i < parent->nb_nodes; i++) {
+ ret = scf_vector_add(argv, _scf_operand_get(parent->nodes[i]));
+ if (ret < 0) {
+ scf_vector_free(argv);
+ return ret;
+ }
}
- }
- if (f->js_flag) {
- p = parent->nodes[0];
- while (p && SCF_OP_EXPR == p->type)
- p = p->nodes[0];
+ scf_function_t* f2 = NULL;
- t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
- v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
- if (!v)
- return -ENOMEM;
- v->const_literal_flag = 1;
+ ret = _semantic_find_proper_function(ast, t, f->node.w->text->data, argv, &f2);
- scf_node_free_data(p);
+ scf_vector_free(argv);
+ argv = NULL;
+ if (ret < 0) {
+ scf_loge("function '%s()' of class '%s' not found\n", f->node.w->text->data, t->name->data);
+ return ret;
+ }
- p->type = SCF_FUNCTION_PTR;
- p->var = v;
+ v0 = _scf_operand_get(parent->nodes[0]);
+ f = f2;
+ v0->func_ptr = f2;
}
}
f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line);
return -1;
}
+
+ } else if (f->argv->size == parent->nb_nodes - 2 && f->js_flag && !f->vargs_flag) {
+ scf_node_t* arguments = parent->nodes[2];
+
+ for (i = 3; i < parent->nb_nodes; i++)
+ parent->nodes[i - 1] = parent->nodes[i];
+ parent->nodes[i - 1] = NULL;
+ parent->nb_nodes--;
+
+ assert(arguments->js_create);
+ arguments->js_create->_3ac_done = 1;
+
+ scf_node_free(arguments);
+ arguments = NULL;
+
} else if (f->argv->size != parent->nb_nodes - 1) {
scf_loge("number of args pass to '%s()' needs %d, real: %d, file: %s, line: %d\n",
f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line);
- assert(0);
return -1;
}
scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, parent->nb_nodes);
- int i;
for (i = 0; i < f->argv->size; i++) {
v0 = f->argv->data[i];
return 0;
}
+static scf_variable_t* __object_func_ptr(scf_node_t* p)
+{
+ while (SCF_OP_EXPR == p->type)
+ p = p->nodes[0];
+
+ if (SCF_OP_ARRAY_INDEX == p->type || SCF_OP_POINTER == p->type) {
+ assert(2 == p->nb_nodes);
+
+ p = p->nodes[1];
+
+ while (SCF_OP_EXPR == p->type)
+ p = p->nodes[0];
+ }
+
+ if (!scf_type_is_var(p->type))
+ return NULL;
+
+ if (p->var->js_var)
+ return p->var->js_var;
+ return p->var;
+}
+
+static scf_node_t* __object_func_src(scf_ast_t* ast, scf_function_t* f)
+{
+ scf_node_t* node;
+ scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR);
+ scf_variable_t* v;
+ scf_lex_word_t* w = scf_lex_word_clone(f->node.w);
+
+ if (!w)
+ return NULL;
+
+ int ret = scf_string_cat_cstr(w->text, "__cstr");
+ if (ret < 0) {
+ scf_lex_word_free(w);
+ return NULL;
+ }
+
+ v = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, 1, NULL);
+ scf_lex_word_free(w);
+ w = NULL;
+ if (!v)
+ return NULL;
+
+ v->data.s = scf_string_clone(f->src_code);
+ if (!v->data.s) {
+ scf_variable_free(v);
+ return NULL;
+ }
+ v->const_literal_flag = 1;
+
+ node = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ return node;
+}
+
static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
return _semantic_multi_rets_assign(ast, nodes, nb_nodes, data);
}
- scf_variable_t* v0 = _scf_operand_get(nodes[0]);
- scf_variable_t* v1 = _scf_operand_get(nodes[1]);
+ scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+ scf_variable_t* v1 = _scf_operand_get(nodes[1]);
assert(v0);
assert(v1);
return -1;
}
+ scf_type_t* t = NULL;
+ scf_type_t* t1 = NULL;
+
+ int ret = scf_ast_find_type_type(&t, ast, v0->type);
+ if (ret < 0)
+ return ret;
+
+ if (!strcmp(t->name->data, "Object")) {
+ ret = scf_ast_find_type_type(&t1, ast, v1->type);
+ if (ret < 0)
+ return ret;
+
+ scf_variable_t* pf0 = __object_func_ptr(nodes[0]);
+ scf_variable_t* pf1;
+
+ if (!strcmp(t1->name->data, "Object"))
+ pf1 = __object_func_ptr(nodes[1]);
+ else
+ pf1 = v1;
+
+ if (pf0 && pf1 && SCF_FUNCTION_PTR == pf1->type) {
+ pf0->func_ptr = pf1->func_ptr;
+
+ scf_logd("---- pf1: %s()\n", pf1->w->text->data);
+ }
+ }
+
if (!scf_variable_same_type(v0, v1)) {
if (scf_variable_is_struct_pointer(v0) && v1->w && strcmp(v1->w->text->data, "NULL")) {
- scf_type_t* t = NULL;
- int ret = scf_ast_find_type_type(&t, ast, v0->type);
- if (ret < 0)
- return ret;
- assert(t);
+ if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type) {
+ scf_node_t* node = __object_func_src(ast, v1->func_ptr);
+ if (!node)
+ return -ENOMEM;
+
+ scf_node_free(nodes[1]);
+ nodes[1] = node;
+ node->parent = parent;
- if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type)
- v0->func_ptr = v1->func_ptr;
+ v1 = _scf_operand_get(nodes[1]);
+ }
if (scf_scope_find_function(t->scope, "__init")) {
- int ret = _semantic_do_create(ast, nodes, nb_nodes, d);
+ ret = _semantic_do_create(ast, nodes, nb_nodes, d);
if (0 == ret)
return 0;
return -1;
}
- int ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
+ ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
if (ret < 0) {
scf_loge("add type cast failed\n");
return ret;
}
}
- scf_type_t* t = NULL;
- int ret = scf_ast_find_type_type(&t, ast, v0->type);
+ t = NULL;
+ ret = scf_ast_find_type_type(&t, ast, v0->type);
if (ret < 0)
return ret;
scf_lex_word_t* current_assign_w;
scf_lex_word_t* current_async_w;
- scf_type_t* root_struct;
- scf_type_t* current_struct;
+ scf_block_t* parent_block;
scf_node_t* current_node;
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_js_call.c
CFILES += ../js/core/scf_optimizer_split_call.c
CFILES += ../js/core/scf_optimizer_call.c
CFILES += ../js/core/scf_optimizer_common_expr.c