From: fennecdjay Date: Thu, 16 May 2019 13:40:01 +0000 (+0200) Subject: Revert ":art: Improve emit and VM" X-Git-Tag: nightly~2473 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=c04732ce6579c36d4ada75bd244038fd3d1cced2;p=gwion.git Revert ":art: Improve emit and VM" This reverts commit b10dab2e00a6920c5aa32d1d8a54445f21b417eb. --- diff --git a/include/opcode.h b/include/opcode.h index f1d678fc..aa306143 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -152,6 +152,7 @@ enum { eRegAddRef, eObjectAssign, eObjectRelease, + eGWOP_EXCEPTBASE, eGWOP_EXCEPT, eAllocMember4, eDotMember, @@ -325,6 +326,7 @@ enum { #define RegAddRef (f_instr)eRegAddRef #define ObjectAssign (f_instr)eObjectAssign #define ObjectRelease (f_instr)eObjectRelease +#define GWOP_EXCEPTBASE (f_instr)eGWOP_EXCEPTBASE #define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT #define AllocMember4 (f_instr)eAllocMember4 #define DotMember (f_instr)eDotMember diff --git a/include/vm.h b/include/vm.h index 3c10ea91..393439a3 100644 --- a/include/vm.h +++ b/include/vm.h @@ -34,7 +34,6 @@ struct ShredInfo_ { m_str name; Vector args; MemPool mp; - VM_Code orig; }; struct ShredTick_ { diff --git a/opcode.txt b/opcode.txt index 88498ce7..b090ee1f 100644 --- a/opcode.txt +++ b/opcode.txt @@ -149,6 +149,7 @@ ObjectInstantiate RegAddRef ObjectAssign ObjectRelease +GWOP_EXCEPTBASE GWOP_EXCEPT AllocMember4 DotMember diff --git a/src/emit/emit.c b/src/emit/emit.c index 2e085c5e..6f6e3e19 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -390,11 +390,10 @@ ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) { const m_uint is_var = exp_self(array)->emit_var; const m_uint depth = get_depth(array->base->type) - exp_self(array)->type->array_depth; CHECK_BB(emit_exp(emit, array->base, 0)) - emit_add_instr(emit, GcAdd); CHECK_BB(emit_exp(emit, array->array->exp, 0)) const Instr pop = emit_add_instr(emit, RegPop); pop->m_val = depth * SZ_INT; - emit_add_instr(emit, GWOP_EXCEPT); + emit_add_instr(emit, GWOP_EXCEPTBASE); for(m_uint i = 0; i < depth - 1; ++i) { const Instr access = emit_add_instr(emit, ArrayAccess); access->m_val = i; @@ -613,9 +612,14 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de ANN static m_bool emit_class_def(const Emitter, const Class_Def); -ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) { +ANN static m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) { const Type t = typedef_base(decl->type); - return !GET_FLAG(t, emit) ? emit_class_def(emit, t->e->def) : GW_OK; + if(!GET_FLAG(t, emit)) { + CHECK_BB(template_push_types(emit->env, t->e->def->tmpl->list.list, t->e->def->tmpl->base)) + CHECK_BB(emit_class_def(emit, t->e->def)) + emit_pop_type(emit); + } + return GW_OK; } ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { @@ -828,8 +832,9 @@ ANN static Instr emit_call(const Emitter emit, const Func f) { instr->m_val = (instr->m_val2 = i) + member; ++prelude->m_val2; } - } - exec = Overflow; + exec = Overflow; + } else + exec = Next; if(memoize) memoize->m_val = prelude->m_val2 + 1; return emit_add_instr(emit, exec); @@ -1392,7 +1397,7 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { (m_bit*)xcalloc(1, stmt->value->type->nspc->info->class_data_size); stmt->value->type->nspc->info->offset = stmt->s; Type_Decl *type_decl = new_type_decl(emit->gwion->mp, - new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos)), + new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos))), // emit->env->class_def ? ae_flag_member : 0); stmt->flag); //if(emit->env->class_def && !GET_FLAG(stmt, static)) @@ -1433,8 +1438,8 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum); } if(stmt->xid){ - const Instr instr = emit_add_instr(emit, RegPop); - instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2; + const Instr instr = emit_add_instr(emit, RegPop); + instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2; } emit_union_offset(stmt->l, stmt->o); if(stmt->xid || stmt->type_xid || global) diff --git a/src/parse/check.c b/src/parse/check.c index 509c6659..2e88c71a 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -110,8 +110,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { ERR_O(td_pos(decl->td), "can't infer type."); if(GET_FLAG(decl->type , template)) { const Type t = typedef_base(decl->type); - if(!GET_FLAG(t, check)) - CHECK_BO(traverse_template(env, t->e->def)) + CHECK_BO(traverse_template(env, t->e->def)) } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -413,7 +412,6 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal const Exp args = exp->args; const Type_List types = exp->tmpl->types; Func m_func = exp->m_func, former = env->func; -if(types->td->types)exit(12); const m_str tmpl_name = tl2str(env, types); const m_uint sz = vector_size((Vector)env->curr->info->type); const m_uint scope = env_push(env, v->owner_class, v->owner); @@ -1166,11 +1164,11 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def class_def) { const Type t = class_def->base.type->e->parent->array_depth ? array_base(class_def->base.type->e->parent) : class_def->base.type->e->parent; if(!GET_FLAG(t, checked)) { -// if(class_def->tmpl) -// CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base)) + if(class_def->tmpl) + CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base)) CHECK_BB(traverse_template(env, t->e->def)) -// if(class_def->tmpl) -// nspc_pop_type(env->gwion->mp, env->curr); + if(class_def->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); } } if(!GET_FLAG(class_def->base.type->e->parent, checked)) @@ -1199,7 +1197,7 @@ ANN static inline void inherit(const Type t) { ANN m_bool check_class_def(const Env env, const Class_Def class_def) { if(tmpl_class_base(class_def->tmpl)) return GW_OK; - if(class_def->base.type->e->parent == t_undefined) { + if(class_def->base.type->e->parent == t_undefined) { class_def->base.type->e->parent = check_td(env, class_def->base.ext); return traverse_class_def(env, class_def); } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index e46ea601..561577d6 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -62,14 +62,6 @@ ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { const ae_flag flag = base->e->def ? base->e->def->flag : 0; const Class_Def cdef = new_class_def(env->gwion->mp, flag, stmt->xid, stmt->ext, NULL, loc_cpy(env->gwion->mp, td_pos(stmt->ext))); -//const Type parent = known_type(env, stmt->ext); -//if(!parent->array_depth && !GET_FLAG(parent, builtin) && !GET_FLAG(parent, scan0)) { -//puts(parent->name); -//exit(9); -//} -//printf("%p\n", stmt->ext->types);exit(6); -//if(stmt->ext->types) -// cdef->tmpl = new_tmpl_class(, $2, -1); CHECK_BB(scan0_class_def(env, cdef)) stmt->type = cdef->base.type; } @@ -103,7 +95,6 @@ ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum stmt) { ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const m_bool add) { const m_str name = s_name(s); const Type t = type_copy(env->gwion->mp, t_union); -//t->e->parent = t_union; t->xid = ++env->scope->type_xid; t->name = name; t->nspc = new_nspc(env->gwion->mp, name); @@ -241,7 +232,6 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) { (void)mk_class(env, cdef->base.type); if(GET_FLAG(cdef, global)) env->curr = (Nspc)vector_pop(&env->scope->nspc_stack); - SET_FLAG(cdef->base.type, scan0); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index bd325a0b..3804d27e 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -9,7 +9,6 @@ #include "vm.h" #include "parse.h" #include "traverse.h" -#include "template.h" ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); @@ -44,7 +43,7 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { decl->base = t->e->def; return decl->type = t; } -//#include "loc.h" + ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)) Var_Decl_List list = decl->list; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 24be16a1..58a5b557 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -543,9 +543,8 @@ DECL_SECTION_FUNC(scan2) ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { const Type t = cdef->base.type->e->parent->array_depth ? array_base(cdef->base.type->e->parent) : cdef->base.type->e->parent; - if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef)) { + if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef)) CHECK_BB(scan2_class_def(env, t->e->def)) - } if(cdef->base.ext->array) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index b320346d..4b37f0ab 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -18,41 +18,57 @@ ANN Type type_decl_resolve(const Env env, const Type_Decl* td) { struct td_info { Type_List tl; - GwText text; + m_str str; + size_t len; + size_t cap; }; +ANN static inline m_bool td_add(struct td_info* info, const char c) { + return *(info->str + info->len++ - 1) = c; +} + +ANN static inline void td_check(struct td_info* info, const size_t len) { + if(info->len + len >= info->cap) { + while(info->len + len >= info->cap) + info->cap <<= 1; + info->str = (m_str)xrealloc(info->str, info->cap); + } +} + ANEW ANN static m_str td2str(const Env env, const Type_Decl* td); ANN static void td_info_run(const Env env, struct td_info* info) { Type_List tl = info->tl; do { m_str name = td2str(env, tl->td); - text_add(&info->text, name); + const size_t nlen = strlen(name); + td_check(info, nlen + !!tl->next); + strcpy(info->str + info->len -1, name); + info->len += nlen; xfree(name); - if(tl->next) - text_add(&info->text, ","); - } while((tl = tl->next)); + } while((tl = tl->next) && td_add(info, ',')); } ANEW ANN static m_str td2str(const Env env, const Type_Decl* td) { m_uint depth = td->array ? td->array->depth : 0; - const size_t len = id_list_len(td->xid) + depth * 2; - const size_t cap = round2szint(len); - struct td_info info = { td->types, { (m_str)xmalloc(cap), cap, len }}; - type_path(info.text.str, td->xid); - while(depth--) { text_add(&info.text, "[]"); } + const size_t l = id_list_len(td->xid) + depth * 2; + struct td_info info = { td->types, (m_str)xmalloc(l), l, l }; + type_path(info.str, td->xid); + while(depth--) { td_add(&info, '['); td_add(&info, ']'); } Type_List tl = td->types; if(tl) { - text_add(&info.text, "<"); + td_check(&info, 2); + td_add(&info, '<'); td_info_run(env, &info); - text_add(&info.text, ">"); + td_add(&info, '>'); } - return info.text.str; + info.str[info.len - 1] = '\0'; + return info.str; } ANEW ANN m_str tl2str(const Env env, Type_List tl) { - struct td_info info = { .tl=tl }; + struct td_info info = { tl, (m_str)xmalloc(32), 1, 32 }; td_info_run(env, &info); - return info.text.str; + return info.str; } ANN static inline void* type_unknown(const Env env, const ID_List id) { diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index a3b0c5b7..674aa4a8 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -6,6 +6,9 @@ #include "object.h" #include "driver.h" #include "shreduler_private.h" +#include "env.h" // unwind +#include "gwion.h" // unwind +#include "instr.h" // unwind ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) { s->loop = loop > 0; @@ -38,6 +41,22 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) { } } +ANN static void unwind(const VM_Shred shred) { + VM_Code code = shred->code; + while(code) { + if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG))) + break; + const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode; + if(exec == eFuncReturn) { + code = *(VM_Code*)(shred->mem - SZ_INT*3); + if(!GET_FLAG(code, op)) + REM_REF(code, shred->info->vm->gwion) + shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4; + } else break; + } + shred->code = code; +} + ANN static inline void shreduler_child(const Vector v) { for(m_uint i = vector_size(v) + 1; --i;) { const VM_Shred child = (VM_Shred)vector_at(v, i - 1); @@ -46,6 +65,7 @@ ANN static inline void shreduler_child(const Vector v) { } ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) { + unwind(tk->self); if(tk->parent) shreduler_parent(tk->self, &tk->parent->child); if(tk->child.ptr) diff --git a/src/vm/vm.c b/src/vm/vm.c index f329d510..8c42a61b 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -277,7 +277,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid, &&newobj, &&addref, &&assign, &&remref, - &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, + &&exceptbase, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&staticint, &&staticfloat, &&staticother, &&dotfunc, &&dotstaticfunc, &&staticcode, &&pushstr, &&gcini, &&gcadd, &&gcend, @@ -297,6 +297,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] VM_Code code; VM_Shred child; } a; + register M_Object array_base = NULL; MUTEX_LOCK(s->mutex); do { register Instr instr; DISPATCH(); @@ -586,9 +587,12 @@ regtomem: *(m_uint*)(mem+instr->m_val) = *(m_uint*)(reg+instr->m_val2); DISPATCH() overflow: - if(overflow_(mem + SZ_INT*8, shred)) { - exception(shred, "StackOverflow"); - continue; + if(overflow_((shred->mem = mem), shred)) { +PRAGMA_PUSH() +// shred->code = a.code; + shred->mem = mem; +PRAGMA_POP() + Except(shred, "StackOverflow"); } next: PRAGMA_PUSH() @@ -670,6 +674,8 @@ arrayaccess: { const m_int idx = *(m_int*)(reg + SZ_INT * instr->m_val); if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) { +// should we go to except ? so we can remove release array_base + _release(array_base, shred); gw_err("\t... at index [%" INT_F "]\n", idx); gw_err("\t... at dimension [%" INT_F "]\n", instr->m_val); shred->code = code; @@ -686,7 +692,7 @@ arrayaddr: *(m_bit**)(reg + (m_int)instr->m_val2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * instr->m_val)); DISPATCH() arrayvalid: - vector_pop(&shred->gc); + array_base = NULL; goto regpush; newobj: *(M_Object*)reg = new_object(vm->gwion->mp, shred, (Type)instr->m_val2); @@ -710,8 +716,13 @@ assign: remref: release(*(M_Object*)(mem + instr->m_val), shred); DISPATCH() +exceptbase: + array_base = *(M_Object*)(reg-SZ_INT); except: if(!(a.obj = *(M_Object*)(reg-SZ_INT))) { + if(array_base) _release(array_base, shred); +// shred->code = code; + shred->mem = mem; exception(shred, "NullPtrException"); continue; } diff --git a/src/vm/vm_shred.c b/src/vm/vm_shred.c index aa35302f..a67ec2b7 100644 --- a/src/vm/vm_shred.c +++ b/src/vm/vm_shred.c @@ -39,7 +39,6 @@ VM_Shred new_vm_shred(MemPool p, VM_Code c) { shred->reg = (m_bit*)shred + sizeof(struct VM_Shred_); shred->base = shred->mem = shred->reg + SIZEOF_REG; shred->info = new_shredinfo(p, c->name); - shred->info->orig = c; vector_init(&shred->gc); return shred; } @@ -48,7 +47,7 @@ void free_vm_shred(VM_Shred shred) { for(m_uint i = vector_size(&shred->gc) + 1; --i;) release((M_Object)vector_at(&shred->gc, i - 1), shred); vector_release(&shred->gc); - REM_REF(shred->info->orig, shred->info->vm->gwion); + REM_REF(shred->code, shred->info->vm->gwion); MemPool mp = shred->info->mp; mp_free(mp, ShredTick, shred->tick); free_shredinfo(mp, shred->info);