From b5463fa017075807f9af1b11b07656e5a67faae3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sun, 6 Jun 2021 18:46:48 +0200 Subject: [PATCH] :art: small updates [skip ci] --- Makefile | 2 +- include/opcode.h | 4 ++++ include/vm.h | 5 +++++ opcode.txt | 2 ++ src/emit/emit.c | 25 ++++++++++++++++++++----- src/lib/union.c | 14 +++++++------- src/vm/gack.c | 11 +++++------ src/vm/vm.c | 41 +++++++++++++++++++++++++---------------- src/vm/vm_code.c | 3 +++ 9 files changed, 72 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 1aef8588..a72065ea 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ gwion-fuzz: clean_core: @rm -f core.* *vgcore.* -clean-all: +clean-all: clean ${MAKE} -s -C libcmdapp clean ${MAKE} -s -C fmt clean ${MAKE} -s -C ast clean diff --git a/include/opcode.h b/include/opcode.h index 7eec1cff..96d7997b 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -127,12 +127,14 @@ enum { eCastI2F, eCastF2I, eTime_Advance, + eRecurs, eSetCode, eRegMove, eReg2Mem, eReg2Mem4, eOverflow, eFuncUsrEnd, + eFuncUsrEnd2, eFuncMemberEnd, eSporkIni, eForkIni, @@ -326,12 +328,14 @@ enum { #define CastI2F (f_instr)eCastI2F #define CastF2I (f_instr)eCastF2I #define Time_Advance (f_instr)eTime_Advance +#define Recurs (f_instr)eRecurs #define SetCode (f_instr)eSetCode #define RegMove (f_instr)eRegMove #define Reg2Mem (f_instr)eReg2Mem #define Reg2Mem4 (f_instr)eReg2Mem4 #define Overflow (f_instr)eOverflow #define FuncUsrEnd (f_instr)eFuncUsrEnd +#define FuncUsrEnd2 (f_instr)eFuncUsrEnd2 #define FuncMemberEnd (f_instr)eFuncMemberEnd #define SporkIni (f_instr)eSporkIni #define ForkIni (f_instr)eForkIni diff --git a/include/vm.h b/include/vm.h index a10821d7..8d90a8cb 100644 --- a/include/vm.h +++ b/include/vm.h @@ -31,6 +31,11 @@ struct VM_Code_ { bool is_memoize; }; +struct frame_t { + uint32_t push, pc; + VM_Code code; +}; + typedef struct Shreduler_* Shreduler; typedef struct Emitter_ * Emitter; typedef struct VM_Shred_* VM_Shred; diff --git a/opcode.txt b/opcode.txt index cbb5d5d7..169fa167 100644 --- a/opcode.txt +++ b/opcode.txt @@ -124,12 +124,14 @@ float_int_r_div CastI2F CastF2I Time_Advance +Recurs SetCode RegMove Reg2Mem Reg2Mem4 Overflow FuncUsrEnd +FuncUsrEnd2 FuncMemberEnd SporkIni ForkIni diff --git a/src/emit/emit.c b/src/emit/emit.c index 8199a6e6..526e4d96 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1071,8 +1071,13 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call* exp_call) { return emit_inline(emit, f, exp_call); #endif */ - CHECK_BB(prepare_call(emit, exp_call)); + // skip when recursing const Type t = actual_type(emit->gwion, exp_call->func->type); + const Func f = t->info->func; + if(is_fptr(emit->gwion, t) || f != emit->env->func || f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) + CHECK_BB(prepare_call(emit, exp_call)); + else + CHECK_BB(emit_func_args(emit, exp_call)); if(isa(t, emit->gwion->type[et_function]) > 0) CHECK_BB(emit_exp_call1(emit, t->info->func)); else { @@ -1243,12 +1248,19 @@ ANN static void tmpl_prelude(const Emitter emit, const Func f) { ANN static Instr get_prelude(const Emitter emit, const Func f) { const Type t = actual_type(emit->gwion, f->value_ref->type); + const bool fp = is_fptr(emit->gwion, t); if(is_fptr(emit->gwion, t)) { if(f->def->base->tmpl) tmpl_prelude(emit, f); } - const Instr instr = emit_add_instr(emit, SetCode); + if(fp || f != emit->env->func || f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) { + const Instr instr = emit_add_instr(emit, SetCode); + instr->m_val2 = 1; + return instr; + } + const Instr instr = emit_add_instr(emit, Recurs); instr->m_val2 = 1; + instr->m_val = SZ_INT; return instr; } @@ -1305,7 +1317,7 @@ ANN static m_bool me_arg(MemoizeEmitter *me) { ANN static Instr emit_call(const Emitter emit, const Func f) { const Instr prelude = get_prelude(emit, f); - prelude->m_val = -f->def->stack_depth - SZ_INT; + prelude->m_val += -f->def->stack_depth - SZ_INT; const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0; if(member) { const Instr instr = emit_add_instr(emit, Reg2Mem); @@ -1313,8 +1325,11 @@ ANN static Instr emit_call(const Emitter emit, const Func f) { ++prelude->m_val2; } if(f->def->stack_depth - member) { +// if(is_fptr(emit->gwion, t) || f != emit->env->func || f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) +{ emit_args(emit, f); ++prelude->m_val2; +} } return emit_add_instr(emit, Overflow); } @@ -1329,11 +1344,11 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { if(emit->env->func != f) CHECK_BB(emit_template_code(emit, f)); else { // recursive function. (maybe should be used only for global funcs) - const Instr back = (Instr) vector_size(&emit->code->instr) ? + /* const Instr back = (Instr) vector_size(&emit->code->instr) ? (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm); back->opcode = eOP_MAX; back->execute = SetRecurs; - back->m_val = 0; + back->m_val = 0;*/ } } else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) { if(fbflag(f->def->base, fbflag_op)) { diff --git a/src/lib/union.c b/src/lib/union.c index 611a2b30..74bfef01 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -111,13 +111,13 @@ static OP_CHECK(opck_union_ctor) { if(!name || !name->next || name->next->next) ERR_N(name->pos, "Union constructor takes two arguments, " "'id' and 'value'"); - if(name->exp_type != ae_exp_primary || - name->d.prim.prim_type != ae_prim_id) - return NULL; - const Exp val = name->next; - const Type base = actual_type(env->gwion, call->func->type); - const Map map = &base->nspc->info->value->map; - for(m_uint i = 0; i < map_size(map); ++i) { + if(name->exp_type != ae_exp_primary || + name->d.prim.prim_type != ae_prim_id) + return NULL; + const Exp val = name->next; + const Type base = actual_type(env->gwion, call->func->type); + const Map map = &base->nspc->info->value->map; + for(m_uint i = 0; i < map_size(map); ++i) { if(VKEY(map, i) == (m_uint)name->d.prim.d.var) { const Value v = (Value)VVAL(map, i); name->d.prim.prim_type = ae_prim_num; diff --git a/src/vm/gack.c b/src/vm/gack.c index 932357ba..4ffa777e 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -47,12 +47,11 @@ ANN2(2) int gw_asprintf(MemPool mp, char **str, const char *fmt, ...) { } ANN static void prepare_call(const VM_Shred shred, const m_uint offset) { - shred->mem += offset; - *(m_uint*)(shred->mem + SZ_INT) = offset + SZ_INT; - *(VM_Code*)(shred->mem + SZ_INT*2) = shred->code; - *(m_uint*)(shred->mem + SZ_INT*3) = shred->pc; - *(m_uint*)(shred->mem + SZ_INT*4) = SZ_INT; - shred->mem += SZ_INT*5; + shred->mem += offset + SZ_INT + sizeof(struct frame_t); + register struct frame_t *frame = (struct frame_t*)(shred->mem - sizeof(struct frame_t)); + frame->push = offset + SZ_INT; + frame->code = shred->code; + frame->pc = shred->pc; shred->pc = 0; } diff --git a/src/vm/vm.c b/src/vm/vm.c index deaff7b4..42d67446 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -40,10 +40,11 @@ uint32_t gw_rand(uint32_t s[2]) { return ret; } -ANN static inline void shred_unwind(VM_Shred shred) { - shred->pc = *(m_uint*) (shred->mem - SZ_INT * 2); - shred->code = *(VM_Code*)(shred->mem - SZ_INT * 3); - shred->mem -= (*(m_uint*)(shred->mem - SZ_INT * 4) + SZ_INT * 4); +ANN static inline void shred_unwind(const VM_Shred shred) { + register struct frame_t *frame = &*(struct frame_t*)(shred->mem - sizeof(struct frame_t)); + shred->code = frame->code; + shred->pc = frame->pc; + shred->mem -= (frame->push + sizeof(struct frame_t)); } ANN static bool unwind(VM_Shred shred, const Symbol effect, const m_uint size) { @@ -402,8 +403,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&firassign, &&firadd, &&firsub, &&firmul, &&firdiv, &&itof, &&ftoi, &&timeadv, - &&setcode, - &®move, &®tomem, &®tomemother, &&overflow, &&funcusrend, &&funcmemberend, + &&recurs, &&setcode, &®move, &®tomem, &®tomemother, &&overflow, &&funcusrend, &&funcusrend2, &&funcmemberend, &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, @@ -547,10 +547,10 @@ regpushmaybe: DISPATCH(); funcreturn: { - register const m_uint pc = *(m_uint*)(mem-SZ_INT*2); - bytecode = (code = *(VM_Code*)(mem-SZ_INT*3))->bytecode; - mem -= (*(m_uint*)(mem-SZ_INT*4) + SZ_INT*4); - PC_DISPATCH(pc); + register struct frame_t frame = *(struct frame_t*)(mem - sizeof(struct frame_t)); + bytecode = (code = frame.code)->bytecode; + mem -= (frame.push + sizeof(struct frame_t)); + PC_DISPATCH(frame.pc); } _goto: PC_DISPATCH(VAL); @@ -709,16 +709,22 @@ timeadv: *(m_float*)(reg-SZ_FLOAT) += vm->bbq->pos; VM_OUT break; +recurs: +{ + register const uint push = *(m_uint*)reg + code->stack_depth; + mem += push + sizeof(struct frame_t); + *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=VAL2,.push=push}; + reg += (m_int)VAL; + next = eFuncUsrEnd2; +} + DISPATCH(); setcode: PRAGMA_PUSH() a.code = *(VM_Code*)(reg - SZ_INT); if(!a.code->builtin) { - register const m_uint push = *(m_uint*)reg + *(m_uint*)(mem-SZ_INT); - mem += push; - *(m_uint*) mem = push; mem += SZ_INT; - *(VM_Code*) mem = code; mem += SZ_INT; - *(m_uint*) mem = PC + VAL2; mem += SZ_INT; - *(m_uint*) mem = a.code->stack_depth; mem += SZ_INT; + register const uint push = *(m_uint*)reg + code->stack_depth; + mem += push + sizeof(struct frame_t); + *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=PC+VAL2,.push=push}; next = eFuncUsrEnd; } else { mem += *(m_uint*)reg; @@ -748,6 +754,9 @@ PRAGMA_PUSH() byte = bytecode = (code = a.code)->bytecode; PRAGMA_POP() SDISPATCH(); +funcusrend2: + byte = bytecode; + SDISPATCH(); funcmemberend: VM_OUT { diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 77418999..8deb304d 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -141,6 +141,9 @@ ANN static m_bit* tobytecode(MemPool p, const VM_Code code) { map_set(&code->handlers, j, new_pc); } *(m_uint*)(data + SZ_INT) = new_pc; + } else if(opcode == eRecurs /*|| opcode == eSetCode*/) { + *(m_uint*)(final + j * BYTECODE_SZ + SZ_INT*2) = + instr->m_val2 += j+1; } setpc(data, j); ++j; -- 2.43.0