From: Jérémie Astor Date: Sun, 31 May 2020 18:06:13 +0000 (+0200) Subject: :art: Improve vararg X-Git-Tag: nightly~1500 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=8a6ba212e30f4603576a677c680e5a7cfb4422a0;p=gwion.git :art: Improve vararg --- diff --git a/src/emit/emit.c b/src/emit/emit.c index 1341f71a..330c636d 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1422,11 +1422,6 @@ ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) { return ret; } -ANN static Instr variadic_state0(const Emitter emit, const Stmt_VarLoop stmt) { - CHECK_BO(emit_exp(emit, stmt->exp)) - return emit_add_instr(emit, BranchEqInt); -} - ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, const m_uint status) { regpushi(emit, status); CHECK_BB(emit_exp(emit, stmt->exp)) @@ -1439,9 +1434,10 @@ ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, co } ANN static m_bool emit_stmt_varloop(const Emitter emit, const Stmt_VarLoop stmt) { - DECL_OB(const Instr,state, = variadic_state0(emit, stmt)) CHECK_BB(variadic_state(emit, stmt, 1)) CHECK_BB(emit_exp(emit, stmt->exp)) + const Instr member = emit_add_instr(emit, DotMember4); + member->m_val = SZ_INT*2; const Instr instr = emit_add_instr(emit, BranchEqInt); const m_uint pc = emit_code_size(emit); emit_stmt(emit, stmt->body, 1); @@ -1449,7 +1445,7 @@ ANN static m_bool emit_stmt_varloop(const Emitter emit, const Stmt_VarLoop stmt) emit_vararg_end(emit, pc); instr->m_val = emit_code_size(emit); CHECK_BB(variadic_state(emit, stmt, 0)) - state->m_val = instr->m_val = emit_code_size(emit); + instr->m_val = emit_code_size(emit); return GW_OK; } diff --git a/src/lib/vararg.c b/src/lib/vararg.c index 0ff22289..aa1db9f9 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -16,7 +16,7 @@ #include "gack.h" void free_vararg(MemPool p, struct Vararg_* arg) { - if(arg->l) { + if(arg->t.ptr) { xfree(arg->d); vector_release(&arg->t); } @@ -25,7 +25,7 @@ void free_vararg(MemPool p, struct Vararg_* arg) { static DTOR(vararg_dtor) { struct Vararg_ *arg = *(struct Vararg_**)o->data; - if(arg->l) { + if(*(m_uint*)(o->data + SZ_INT*2)) { m_uint offset = 0; for(m_uint i = 0; i < vector_size(&arg->t); ++i) { const Type t = (Type)vector_at(&arg->t, i); @@ -41,8 +41,7 @@ static MFUN(mfun_vararg_cpy) { struct Vararg_ *src = *(struct Vararg_**)o->data; struct Vararg_* arg = mp_calloc(shred->info->mp, Vararg); vector_copy2(&src->t, &arg->t); - arg->l = src->l; - arg->d = (m_bit*)xmalloc(round2szint(arg->l)); + arg->d = (m_bit*)xmalloc(round2szint(*(m_uint*)(o->data + SZ_INT*2))); m_uint offset = 0; for(m_uint i = 0; i < vector_size(&arg->t); ++i) { const Type t = (Type)vector_at(&arg->t, arg->i); @@ -56,6 +55,7 @@ static MFUN(mfun_vararg_cpy) { arg->o = src->o; const M_Object obj = new_object(shred->info->mp, shred, o->type_ref); *(struct Vararg_**)obj->data = arg; + *(m_uint*)(obj->data + SZ_INT*2) = *(m_uint*)(o->data + SZ_INT*2); *(M_Object*)RETURN = obj; } @@ -64,8 +64,9 @@ INSTR(VarargIni) { struct Vararg_* arg = mp_calloc(shred->info->mp, Vararg); *(struct Vararg_**)o->data = arg; POP_REG(shred, instr->m_val - SZ_INT) - if((arg->l = instr->m_val)) { - arg->d = (m_bit*)xmalloc(round2szint(arg->l)); +// if((arg->l = instr->m_val)) { + if((*(m_uint*)(o->data + SZ_INT * 2) = instr->m_val)) { + arg->d = (m_bit*)xmalloc(round2szint(instr->m_val)); const Vector kinds = (Vector)instr->m_val2; vector_copy2(kinds, &arg->t); m_uint offset = 0; @@ -80,15 +81,14 @@ INSTR(VarargIni) { offset += t->size; } arg->s = vector_size(kinds); - *(M_Object*)REG(-SZ_INT) = o; - } else - *(M_Object*)REG(-SZ_INT) = NULL; + } + *(M_Object*)REG(-SZ_INT) = o; } static INSTR(VarargEnd) { const M_Object o = *(M_Object*)REG(0); struct Vararg_* arg = *(struct Vararg_**)o->data; - arg->o += ((Type)vector_at(&arg->t, arg->i))->size; + arg->o += arg->t.ptr ? ((Type)vector_at(&arg->t, arg->i))->size : 0; if(++arg->i < arg->s) shred->pc = instr->m_val; else @@ -104,6 +104,8 @@ static INSTR(VarargCast) { const M_Object o = *(M_Object*)REG(-SZ_INT); if(!*(m_uint*)(o->data + SZ_INT)) Except(shred, "Using Vararg outside varloop"); + if(!*(m_uint*)(o->data + SZ_INT*2)) + Except(shred, "Using Vararg cast on empty vararg"); struct Vararg_* arg = *(struct Vararg_**)o->data; const Type t = (Type)instr->m_val; if(isa((Type)vector_at(&arg->t, arg->i), t) < 0) @@ -157,6 +159,8 @@ GWION_IMPORT(vararg) { CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL)) CHECK_BB(gwi_item_ini(gwi, "int", "@inLoop")) CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL)) + CHECK_BB(gwi_item_ini(gwi, "int", "@len")) + CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL)) CHECK_BB(gwi_func_ini(gwi, "Vararg", "cpy")) CHECK_BB(gwi_func_end(gwi, mfun_vararg_cpy, ae_flag_none)) GWI_BB(gwi_class_end(gwi))