From f16f8131c6f1bf5cf17053cc0b5174a6bee2d86f Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 30 Mar 2019 18:56:18 +0100 Subject: [PATCH] :art: Move autoloop to vm --- include/instr.h | 2 -- include/opcode.h | 6 ++++++ opcode.txt | 3 +++ src/emit/emit.c | 26 ++++++++++++++++++-------- src/lib/instr.c | 25 ------------------------- src/vm/vm.c | 11 ++++++++++- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/include/instr.h b/include/instr.h index 627c3199..87395204 100644 --- a/include/instr.h +++ b/include/instr.h @@ -62,8 +62,6 @@ INSTR(VecCpy); INSTR(VecMember); INSTR(PopArrayClass); -INSTR(AutoLoopStart); -INSTR(AutoLoopEnd); INSTR(DotTmpl); struct dottmpl_ { diff --git a/include/opcode.h b/include/opcode.h index 9fb5fff7..699aa524 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -141,6 +141,9 @@ enum { eBranchEqFloat, eBranchNeqFloat, eArrayAppend, + eAutoLoop, + eAutoLoopPtr, + eAutoLoopCount, eArrayTop, eObjectInstantiate, eRegAddRef, @@ -306,6 +309,9 @@ enum { #define BranchEqFloat (f_instr)eBranchEqFloat #define BranchNeqFloat (f_instr)eBranchNeqFloat #define ArrayAppend (f_instr)eArrayAppend +#define AutoLoop (f_instr)eAutoLoop +#define AutoLoopPtr (f_instr)eAutoLoopPtr +#define AutoLoopCount (f_instr)eAutoLoopCount #define ArrayTop (f_instr)eArrayTop #define ObjectInstantiate (f_instr)eObjectInstantiate #define RegAddRef (f_instr)eRegAddRef diff --git a/opcode.txt b/opcode.txt index d8639229..8568384a 100644 --- a/opcode.txt +++ b/opcode.txt @@ -138,6 +138,9 @@ BranchNeqInt BranchEqFloat BranchNeqFloat ArrayAppend +AutoLoop +AutoLoopPtr +AutoLoopCount ArrayTop ObjectInstantiate RegAddRef diff --git a/src/emit/emit.c b/src/emit/emit.c index c18e47aa..beb414ce 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1149,25 +1149,35 @@ ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) { GWDEB ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { GWDEBUG_EXE CHECK_BB(emit_exp(emit, stmt->exp, 0)) const Instr s1 = emit_add_instr(emit, MemSetImm); - const Instr s2 = emit_add_instr(emit, MemSetImm); + Instr cpy; + if(stmt->is_ptr) { + const Instr new_obj = emit_add_instr(emit, ObjectInstantiate); + new_obj->m_val2 = (m_uint)stmt->v->type; + const Instr pop = emit_add_instr(emit, RegPop); + pop->m_val = SZ_INT; + cpy = emit_add_instr(emit, Reg2Mem); + } const m_uint ini_pc = emit_code_size(emit); emit_push_stack(emit); - const Instr loop = emit_add_instr(emit, AutoLoopStart); + emit_add_instr(emit, GWOP_EXCEPT); + const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop); + const Instr end = emit_add_instr(emit, BranchEqInt); const m_uint offset = emit_local(emit, 2*SZ_INT, 0); - s2->m_val = stmt->v->offset = offset + SZ_INT; + stmt->v->offset = offset + SZ_INT; CHECK_BB(emit_stmt(emit, stmt->body, 1)) const m_uint end_pc = emit_code_size(emit); if(stmt->is_ptr) { + loop->m_val2 = (m_uint)stmt->v->type; + cpy->m_val = offset + SZ_INT; const Instr release = emit_add_instr(emit, ObjectRelease); release->m_val = offset + SZ_INT; } - const Instr end = emit_add_instr(emit, AutoLoopEnd); const Instr tgt = emit_add_instr(emit, Goto); - end->m_val2 = emit_code_size(emit); + end->m_val = emit_code_size(emit); tgt->m_val = ini_pc; - s1->m_val = end->m_val = loop->m_val = offset; - if(stmt->is_ptr) - loop->m_val2 = (m_uint)stmt->v->type; + s1->m_val = loop->m_val = offset; + const Instr pop = emit_add_instr(emit, RegPop); + pop->m_val = SZ_INT; emit_pop_stack(emit, end_pc); return GW_OK; } diff --git a/src/lib/instr.c b/src/lib/instr.c index 40c24d35..b4c0654e 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -43,31 +43,6 @@ INSTR(BranchSwitch) { GWDEBUG_EXE shred->pc = map_get(map, *(m_uint*)REG(0)) ?: instr->m_val; } -INSTR(AutoLoopStart) { GWDEBUG_EXE - const M_Object o = *(M_Object*)REG(-SZ_INT); - if(!o) - Except(shred, "NullPtrException"); - const m_uint idx = *(m_uint*)MEM(instr->m_val); - const Type t = (Type)instr->m_val2; - if(t) { - M_Object ptr = *(M_Object*)MEM(instr->m_val + SZ_INT); - if(!idx) { - ptr = new_object(shred, t); - *(M_Object*)MEM(instr->m_val + SZ_INT) = ptr; - } - *(m_bit**)ptr->data = m_vector_addr(ARRAY(o), idx); - } else - m_vector_get(ARRAY(o), idx, MEM(instr->m_val + SZ_INT)); -} - -INSTR(AutoLoopEnd) { GWDEBUG_EXE - const M_Object o = *(M_Object*)REG(-SZ_INT); - if(++*(m_uint*)MEM(instr->m_val) >= m_vector_size(ARRAY(o))) { - shred->pc = instr->m_val2; - POP_REG(shred, SZ_INT); - } -} - #ifdef OPTIMIZE INSTR(PutArgsInMem) { GWDEBUG_EXE POP_REG(shred, instr->m_val) diff --git a/src/vm/vm.c b/src/vm/vm.c index 6581750a..a98f685e 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -280,7 +280,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&funcusr, &®pop, &®tomem, &&overflow, &&next, &&funcusrend, &&funcmemberend, &&sporkini, &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, - &&arrayappend, &&arraytop, &&newobj, + &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&newobj, &&addref, &&assign, &&remref, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&staticint, &&staticfloat, &&staticother, @@ -669,6 +669,15 @@ arrayappend: m_vector_add(ARRAY(a.obj), reg); release(a.obj, shred); DISPATCH() +autoloop: + m_vector_get(ARRAY(a.obj), *(m_uint*)(mem + instr->m_val), mem + instr->m_val + SZ_INT); + goto autoloopcount; +autoloopptr: + *(m_bit**)(*(M_Object*)(mem + instr->m_val + SZ_INT))->data = m_vector_addr(ARRAY(a.obj), *(m_uint*)(mem + instr->m_val)); +autoloopcount: + *(m_uint*)reg = m_vector_size(ARRAY(a.obj)) - ++*(m_uint*)(mem + instr->m_val); + reg += SZ_INT; + DISPATCH() arraytop: if(*(m_uint*)(reg - SZ_INT * 2) < *(m_uint*)(reg-SZ_INT)) goto newobj; -- 2.43.0