From dced4c486339bc2079e84a68da1f928a2b9b8059 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 22 Sep 2019 20:56:24 +0200 Subject: [PATCH] :art: Prepare emit --- include/emit.h | 19 +++++++++---- src/compile.c | 40 +++++++++++++++++---------- src/emit/emit.c | 69 ++++++++++++++++++++-------------------------- src/emit/emitter.c | 15 ++++++---- src/emit/escape.c | 4 +-- src/emit/memoize.c | 2 +- src/gwion.c | 2 +- src/lib/instr.c | 23 ++++++++-------- 8 files changed, 93 insertions(+), 81 deletions(-) diff --git a/include/emit.h b/include/emit.h index 57b406e7..e08bc23a 100644 --- a/include/emit.h +++ b/include/emit.h @@ -15,21 +15,28 @@ typedef struct Code_ { ae_flag flag; } Code; +struct EmitterInfo_ { + struct Vector_ pure; + struct Vector_ variadic; + char *escape; + f_instr finalyzer; + VM_Code (*emit_code)(const Emitter); + VM_Code code; + m_bool memoize; +}; + struct Emitter_ { Env env; Code* code; struct Gwion_ *gwion; - struct Vector_ stack; - struct Vector_ pure; - struct Vector_ variadic; - char *escape; - m_bool memoize; + struct EmitterInfo_ *info; + struct Vector_ stack; }; ANEW ANN Emitter new_emitter(MemPool); ANN void free_emitter(MemPool, Emitter); ANEW ANN VM_Code emit_code(const Emitter); -ANN VM_Code emit_ast(const Emitter emit, Ast ast); +ANN m_bool emit_ast(const Env env, Ast ast); ANN Instr emit_exp_call1(const Emitter, const Func); ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((returns_nonnull)); ANN Code* emit_class_code(const Emitter, const m_str); diff --git a/src/compile.c b/src/compile.c index 679ee399..fd8ad67f 100644 --- a/src/compile.c +++ b/src/compile.c @@ -80,33 +80,42 @@ static inline m_bool compiler_open(MemPool p, struct Compiler* c) { return GW_OK; } -static m_bool check(struct Gwion_* gwion, struct Compiler* c) { +static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) { struct ScannerArg_ arg = { c->name, c->file, gwion->st }; - MUTEX_LOCK(gwion->data->mutex); CHECK_OB((c->ast = parse(&arg))) gwion->env->name = c->name; - const m_bool ret = type_engine_check_prog(gwion->env, c->ast); + return type_engine_check_prog(gwion->env, c->ast); +} +/* +static m_bool check(struct Gwion_* gwion, struct Compiler* c) { + MUTEX_LOCK(gwion->data->mutex); + const m_bool ret = _check(gwion, c); MUTEX_UNLOCK(gwion->data->mutex); return ret; } +*/ +static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) { + CHECK_BB(compiler_open(gwion->mp, c)) + if(_check(gwion, c) < 0 || emit_ast(gwion->env, c->ast) < 0) { + gw_err(_("while compiling file '%s'\n"), c->base); + return 0; + } + const VM_Shred shred = new_vm_shred(gwion->mp, gwion->emit->info->code); + shred->info->args = c->args; + vm_add_shred(gwion->vm, shred); + gwion->emit->info->code = NULL; + return shred->tick->xid; +} static m_uint compile(struct Gwion_* gwion, struct Compiler* c) { - VM_Shred shred = NULL; - VM_Code code; compiler_name(gwion->mp, c); MUTEX_LOCK(gwion->data->mutex); - CHECK_BB(compiler_open(gwion->mp, c)) - if(check(gwion, c) < 0 || !(code = emit_ast(gwion->emit, c->ast))) - gw_err(_("while compiling file '%s'\n"), c->base); - else { - const VM_Shred shred = new_vm_shred(gwion->mp, code); - shred->info->args = c->args; - vm_add_shred(gwion->vm, shred); - } + const m_uint ret = _compile(gwion, c); MUTEX_UNLOCK(gwion->data->mutex); compiler_clean(gwion->mp, c); - return shred ? shred->tick->xid : 0; + return ret; } + /* m_bool check_filename(struct Gwion_* vm, const m_str filename) { struct Compiler c = { .base=filename, .type=COMPILE_NAME }; @@ -131,12 +140,13 @@ m_uint compile_filename(struct Gwion_* gwion, const m_str filename) { struct Compiler c = { .base=filename, .type=COMPILE_NAME }; return compile(gwion, &c); } -/* + m_uint compile_string(struct Gwion_* vm, const m_str filename, const m_str data) { struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .data=data }; return compile(vm, &c); } +/* m_uint compile_file(struct Gwion_* vm, const m_str filename, FILE* file) { struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .file=file }; return compile(vm, &c); diff --git a/src/emit/emit.c b/src/emit/emit.c index c7eadfec..6c126c6f 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -125,7 +125,7 @@ ANN static void emit_pop_scope(const Emitter emit) { Instr instr = emit_add_instr(emit, ObjectRelease); instr->m_val = (m_uint)offset; } - vector_pop(&emit->pure); + vector_pop(&emit->info->pure); } ANN static inline void emit_push_code(const Emitter emit, const m_str name) { @@ -133,13 +133,9 @@ ANN static inline void emit_push_code(const Emitter emit, const m_str name) { emit->code = new_code(emit, name); } -ANN static inline void emit_pop_code(const Emitter emit) { - emit->code = (Code*)vector_pop(&emit->stack); -} - ANN static inline void emit_push_scope(const Emitter emit) { frame_push(emit->code->frame); - vector_add(&emit->pure, 0); + vector_add(&emit->info->pure, 0); } ANN static inline m_uint emit_code_size(const Emitter emit) { @@ -235,7 +231,7 @@ ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) { } ANN static inline void emit_notpure(const Emitter emit) { - ++VPTR(&emit->pure, VLEN(&emit->pure) - 1); + ++VPTR(&emit->info->pure, VLEN(&emit->info->pure) - 1); } ANN static Array_Sub instantiate_typedef(MemPool p, const m_uint depth) { @@ -374,10 +370,10 @@ ANEW ANN VM_Code emit_code(const Emitter emit) { return code; } -ANN static VM_Code finalyze(const Emitter emit) { - emit_add_instr(emit, EOC); +ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) { + emit_add_instr(emit, exec); const VM_Code code = emit_code(emit); - emit_pop_code(emit); + emit->code = (Code*)vector_pop(&emit->stack); return code; } @@ -945,7 +941,7 @@ ANN static void emit_args(const Emitter emit, const Func f) { } ANN static Instr emit_call(const Emitter emit, const Func f) { - const Instr memoize = !(emit->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall); + const Instr memoize = !(emit->info->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall); const Instr prelude = get_prelude(emit, f); prelude->m_val = f->def->stack_depth; const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0; @@ -1026,7 +1022,7 @@ static inline void stack_alloc_this(const Emitter emit) { static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) { ++emit->env->scope->depth; emit_push_scope(emit); - const m_bool pure = !vector_back(&emit->pure); + const m_bool pure = !vector_back(&emit->info->pure); if(!pure) emit_add_instr(emit, GcIni); CHECK_BB(emit_stmt(emit, stmt, pop)) @@ -1068,7 +1064,7 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) { push_spork_code(emit, is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, unary->exp->pos); CHECK_BO(spork_func(emit, &unary->exp->d.exp_call)) } - const VM_Code code = finalyze(emit); + const VM_Code code = finalyze(emit, EOC); const Instr ini = emit_add_instr(emit, unary->op == insert_symbol("spork") ? SporkIni : ForkIni); ini->m_val = (m_uint)code; ini->m_val2 = is_spork; @@ -1604,11 +1600,11 @@ ANN static m_bool emit_vararg_start(const Emitter emit, const m_uint offset) { const Instr instr = emit_add_instr(emit, VarargTop); instr->m_val = offset; instr->m_val2 = emit_code_size(emit); - vector_set(&emit->variadic, vector_size(&emit->variadic) -1, (vtype)instr); + vector_set(&emit->info->variadic, vector_size(&emit->info->variadic) -1, (vtype)instr); return GW_OK; } ANN static inline Instr get_variadic(const Emitter emit) { - return (Instr)vector_back(&emit->variadic); + return (Instr)vector_back(&emit->info->variadic); } ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) { @@ -1745,19 +1741,12 @@ ANN static void emit_func_def_return(const Emitter emit) { } vector_clear(&emit->code->stack_return); emit_pop_scope(emit); - if(emit->memoize && GET_FLAG(emit->env->func, pure)) + if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) emit_add_instr(emit, MemoizeStore); - emit_add_instr(emit, FuncReturn); } ANN static void emit_func_def_code(const Emitter emit, const Func func) { - if(GET_FLAG(func->def, dtor)) { - Instr instr = (Instr)vector_back(&emit->code->instr); - instr->opcode = eOP_MAX; - instr->execute = DTOR_EOC; - instr->m_val = (m_uint)emit->gwion->mp; - } - func->code = emit_code(emit); + func->code = finalyze(emit, !GET_FLAG(func->def, dtor) ? FuncReturn : DTOR_EOC); if(GET_FLAG(func->def, dtor)) { emit->env->class_def->nspc->dtor = func->code; ADD_REF(func->code) @@ -1776,7 +1765,7 @@ ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) { } ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { - vector_add(&emit->variadic, 0); + vector_add(&emit->info->variadic, 0); CHECK_BB(_fdef_body(emit, fdef)) if(GET_FLAG(fdef, variadic)) { if(!get_variadic(emit)) @@ -1819,11 +1808,10 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { emit_func_def_code(emit, func); if(fdef->base->tmpl) emit_pop_type(emit); - emit_pop_code(emit); emit->env->func = former; if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl) emit_func_def_global(emit, func->value_ref); - if(emit->memoize && GET_FLAG(func, pure)) + if(emit->info->memoize && GET_FLAG(func, pure)) func->code->memoize = memoize_ini(emit, func, kindof(func->def->base->ret_type->size, !func->def->base->ret_type->size)); return GW_OK; @@ -1841,12 +1829,6 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) { return emit->code; } -ANN inline void emit_class_finish(const Emitter emit, const Nspc nspc) { - emit_add_instr(emit, FuncReturn); - nspc->pre_ctor = emit_code(emit); - SET_FLAG(nspc->pre_ctor, ctor); -} - ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; const Type base = parent->e->d.base_type; @@ -1860,6 +1842,11 @@ ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) { (_exp_func)emit_class_def, (_exp_func)emit_union_def); } +ANN void emit_class_finish(const Emitter emit, const Nspc nspc) { + nspc->pre_ctor = finalyze(emit, FuncReturn); + SET_FLAG(nspc->pre_ctor, ctor); +} + ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if(tmpl_base(cdef->base.tmpl)) return GW_OK; @@ -1874,13 +1861,12 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { CHECK_BB(emit_array_extend(emit, type->e->parent, cdef->base.ext->array->exp)) if(cdef->body) CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit)) - emit_class_finish(emit, nspc); - emit_pop_code(emit); + emit_class_finish(emit, type->nspc); SET_FLAG(type, emit); return GW_OK; } -ANN static void emit_free_code(const Emitter emit, Code* code) { +ANN static inline void emit_free_code(const Emitter emit, Code* code) { if(vector_size(&code->instr)) free_code_instr(&code->instr, emit->gwion); free_code(emit->gwion->mp, code); @@ -1891,7 +1877,7 @@ ANN static VM_Code emit_free_stack(const Emitter emit) { for(m_uint i = vector_size(&emit->stack) + 1; --i;) emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1)); vector_clear(&emit->stack); - vector_clear(&emit->pure); + vector_clear(&emit->info->pure); emit_free_code(emit, emit->code); return NULL; } @@ -1902,10 +1888,15 @@ ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) { return GW_OK; } -ANN VM_Code emit_ast(const Emitter emit, Ast ast) { +ANN m_bool emit_ast(const Env env, Ast ast) { + const Emitter emit = env->gwion->emit; emit->code = new_code(emit, emit->env->name); emit_push_scope(emit); const m_bool ret = emit_ast_inner(emit, ast); emit_pop_scope(emit); - return ret > 0 ? finalyze(emit) : emit_free_stack(emit); + if(ret > 0) + emit->info->code = finalyze(emit, emit->info->finalyzer); + else + emit_free_stack(emit); + return ret; } diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 3ac80be7..71c8df69 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -14,17 +14,20 @@ ANEW Emitter new_emitter(MemPool p) { Emitter emit = (Emitter)mp_calloc(p, Emitter); vector_init(&emit->stack); - vector_init(&emit->pure); - vector_init(&emit->variadic); - emit->escape = escape_table(p); + emit->info = (struct EmitterInfo_*)mp_calloc(p, EmitterInfo); + vector_init(&emit->info->pure); + vector_init(&emit->info->variadic); + emit->info->escape = escape_table(p); + emit->info->finalyzer = EOC; return emit; } ANN void free_emitter(MemPool p, Emitter a) { vector_release(&a->stack); - vector_release(&a->pure); - vector_release(&a->variadic); - mp_free2(p, 256, a->escape); + vector_release(&a->info->pure); + vector_release(&a->info->variadic); + mp_free2(p, 256, a->info->escape); + mp_free(p, EmitterInfo, a->info); mp_free(p, Emitter, a); } diff --git a/src/emit/escape.c b/src/emit/escape.c index b9d49211..c5493c09 100644 --- a/src/emit/escape.c +++ b/src/emit/escape.c @@ -24,8 +24,8 @@ char* escape_table(MemPool p) { } static int get_escape(const Emitter emit, const char c, const loc_t pos) { - if(emit->escape[(int)c]) - return emit->escape[(int)c]; + if(emit->info->escape[(int)c]) + return emit->info->escape[(int)c]; env_err(emit->env, pos, _("unrecognized escape sequence '\\%c'"), c); return GW_ERROR; } diff --git a/src/emit/memoize.c b/src/emit/memoize.c index 538af2b0..4e80f2b0 100644 --- a/src/emit/memoize.c +++ b/src/emit/memoize.c @@ -56,7 +56,7 @@ Memoize memoize_ini(const Emitter emit, const Func f, const enum Kind kind) { m->member = SZ_INT; m->arg_sz = f->def->stack_depth - SZ_INT; } - m->limit = emit->memoize; + m->limit = emit->info->memoize; m->p = new_pool((uint32_t)(m->arg_sz + m->ret_sz)); return m; } diff --git a/src/gwion.c b/src/gwion.c index 50798b07..c28493a6 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -71,7 +71,7 @@ ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) { gwion->vm->bbq->si = new_soundinfo(gwion->mp); arg->si = gwion->vm->bbq->si; arg_parse(arg); - gwion->emit->memoize = arg->memoize; + gwion->emit->info->memoize = arg->memoize; gwion->plug = new_plug(gwion->mp, &arg->lib); gwion->data = new_gwiondata(gwion->mp); shreduler_set_loop(gwion->vm->shreduler, arg->loop); diff --git a/src/lib/instr.c b/src/lib/instr.c index 0da50fc5..7c922cab 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -53,6 +53,12 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns return def; } +ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) { + DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc)) + CHECK_BO(traverse_dot_tmpl(emit, dt)) + return def; +} + INSTR(GTmpl) { struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; const Func f = *(Func*)REG(-SZ_INT); @@ -73,13 +79,10 @@ INSTR(GTmpl) { } free_mstr(emit->gwion->mp, tmpl_name); dt->def = f->def; - const Func_Def def = from_base(emit->env, dt, f->value_ref->owner); + const Func_Def def = traverse_tmpl(emit, dt, f->value_ref->owner); if(!def) Except(shred, "MissigTmplPtrException[internal]"); - if(traverse_dot_tmpl(emit, dt) > 0) - *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code; - else - Except(shred, "TemplateException"); + *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code; } INSTR(DotTmpl) { @@ -101,14 +104,12 @@ INSTR(DotTmpl) { shred->reg += SZ_INT; return; } else { - const Func_Def def = from_base(emit->env, dt, t->nspc); + const Func_Def def = traverse_tmpl(emit, dt, t->nspc); if(!def) continue; - if(traverse_dot_tmpl(emit, dt) > 0) { - *(VM_Code*)shred->reg = def->base->func->code; - shred->reg += SZ_INT; - return; - } else break; + *(VM_Code*)shred->reg = def->base->func->code; + shred->reg += SZ_INT; + return; } } while((t = t->e->parent)); Except(shred, "MissigTmplException[internal]"); //unreachable -- 2.43.0