From: Jérémie Astor Date: Tue, 26 Nov 2019 19:56:40 +0000 (+0100) Subject: :shirt: Improve emit_spork readability X-Git-Tag: nightly~2076^2~1 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=f24ae03d18cb11812346097de3109f28cf301114;p=gwion.git :shirt: Improve emit_spork readability --- diff --git a/include/opcode.h b/include/opcode.h index 55eac482..d8d57041 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -130,7 +130,6 @@ enum { eFuncUsrEnd, eFuncMemberEnd, eSporkIni, - eForkIni, eSporkFunc, eSporkMemberFptr, eSporkExp, @@ -306,7 +305,6 @@ enum { #define FuncUsrEnd (f_instr)eFuncUsrEnd #define FuncMemberEnd (f_instr)eFuncMemberEnd #define SporkIni (f_instr)eSporkIni -#define ForkIni (f_instr)eForkIni #define SporkFunc (f_instr)eSporkFunc #define SporkMemberFptr (f_instr)eSporkMemberFptr #define SporkExp (f_instr)eSporkExp diff --git a/opcode.txt b/opcode.txt index 3924a322..d3dea2a6 100644 --- a/opcode.txt +++ b/opcode.txt @@ -127,7 +127,6 @@ Next FuncUsrEnd FuncMemberEnd SporkIni -ForkIni SporkFunc SporkMemberFptr SporkExp diff --git a/src/emit/emit.c b/src/emit/emit.c index 20b1f078..83c5a9ee 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1113,49 +1113,75 @@ static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t emit_push_code(emit, c); } -ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { +ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) { if(GET_FLAG(exp->m_func, member)) SET_FLAG(emit->code, member); return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR; } -ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) { - const m_bool is_spork = unary->op == insert_symbol("spork"); - const Func f = !unary->code ? unary->exp->d.exp_call.m_func : NULL; - if(unary->code) { +struct Sporker { + const m_bool is_spork; + const Stmt code; + const Exp exp; + VM_Code vm_code; + const m_bool emit_var; +}; + +ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) { + if(sp->code) { emit_add_instr(emit, RegPushImm); - push_spork_code(emit, is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, unary->code->pos); + push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos); if(!SAFE_FLAG(emit->env->func, member)) stack_alloc_this(emit); - CHECK_BO(scoped_stmt(emit, unary->code, 0)) + CHECK_BO(scoped_stmt(emit, sp->code, 0)) } else { - CHECK_BO(prepare_call(emit, &unary->exp->d.exp_call)) - 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)) + CHECK_BO(prepare_call(emit, &sp->exp->d.exp_call)) + push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, sp->exp->pos); + CHECK_BO(call_spork_func(emit, &sp->exp->d.exp_call)) } - 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; - if(!f) { - if(is_spork) { - const Instr spork = emit_add_instr(emit, SporkExp); - spork->m_val = emit->code->stack_depth; - } else { - const Instr spork = emit_add_instr(emit, ForkEnd); - spork->m_val = exp_self(unary)->emit_var; - } + return finalyze(emit, EOC); +} + +ANN void spork_code(const Emitter emit, const struct Sporker *sp) { + if(sp->is_spork) { + const Instr instr = emit_add_instr(emit, SporkExp); + instr->m_val = emit->code->stack_depth; } else { - if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) { - const m_uint depth = f->def->stack_depth; - regpop(emit, depth -SZ_INT); - const Instr spork = emit_add_instr(emit, SporkMemberFptr); - spork->m_val = depth; - } else - emit_exp_spork_finish(emit, f->def->stack_depth); - const Instr end = emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd); - end->m_val2 = f->def->base->ret_type->size; + const Instr instr = emit_add_instr(emit, ForkEnd); + instr->m_val = sp->emit_var; } +} + +ANN void spork_func(const Emitter emit, const struct Sporker *sp) { + const Func f = sp->exp->d.exp_call.m_func; + if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) { + const m_uint depth = f->def->stack_depth; + regpop(emit, depth -SZ_INT); + const Instr spork = emit_add_instr(emit, SporkMemberFptr); + spork->m_val = depth; + } else + emit_exp_spork_finish(emit, f->def->stack_depth); + const Instr end = emit_add_instr(emit, sp->is_spork ? SporkEnd : ForkEnd); + end->m_val2 = f->def->base->ret_type->size; +} + +ANN static Instr spork_ini(const Emitter emit, const struct Sporker *sp) { + const Instr instr = emit_add_instr(emit, SporkIni); + instr->m_val = (m_uint)sp->vm_code; + instr->m_val2 = sp->is_spork; + return instr; +} + +ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) { + struct Sporker sporker = { + .is_spork=(unary->op == insert_symbol("spork")), + .exp=unary->exp, + .code=unary->code, + .emit_var=exp_self(unary)->emit_var + }; + CHECK_OO((sporker.vm_code = spork_prepare(emit, &sporker))) + const Instr ini = spork_ini(emit, &sporker); + (unary->code ? spork_code : spork_func)(emit, &sporker); return ini; } diff --git a/src/lib/func.c b/src/lib/func.c index 52a1debc..e424626b 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -317,7 +317,6 @@ GWION_IMPORT(func) { GWI_BB(gwi_oper_emi(gwi, opem_spork)) GWI_BB(gwi_oper_end(gwi, "fork", NULL)) gwi_register_freearg(gwi, SporkIni, freearg_xork); - gwi_register_freearg(gwi, ForkIni, freearg_xork); gwi_register_freearg(gwi, DotTmpl, freearg_dottmpl); return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index e7feefbe..0c2fc5b8 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -296,7 +296,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&timeadv, &&setcode, &&funcptr, &&funcmember, &&funcusr, &®pop, &®push, &®tomem, &®tomemother, &&overflow, &&next, &&funcusrend, &&funcmemberend, - &&sporkini, &&sporkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&forkend, &&sporkend, + &&sporkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid, &&newobj, &&addref, &&objassign, &&assign, &&remref,