From f685cefb071fc2bed2bfcd5c477895c28a2a146d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sat, 12 Sep 2020 15:06:14 +0200 Subject: [PATCH] :bug: Empty vararg does not go through varloop anymore --- include/instr.h | 1 + src/emit/emit.c | 4 ++-- src/lib/object.c | 2 +- src/lib/vararg.c | 12 +++++++++--- tests/error/variadic_miss_end.gw | 3 --- tests/new/typedef_func_class_variadic.gw | 6 +++--- tests/tree/vararg_empty.gw | 4 ++-- tests/tree/variadic_offset.gw | 5 ++++- tests/tree/varobject_assign.gw | 6 +++--- 9 files changed, 25 insertions(+), 18 deletions(-) delete mode 100644 tests/error/variadic_miss_end.gw diff --git a/include/instr.h b/include/instr.h index 782ea2e4..fa9b4852 100644 --- a/include/instr.h +++ b/include/instr.h @@ -48,6 +48,7 @@ INSTR(ArrayAlloc); /* vararg */ INSTR(VarargIni); +INSTR(VarargCheck); INSTR(PopArrayClass); diff --git a/src/emit/emit.c b/src/emit/emit.c index dc582028..daa5cf1c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1485,6 +1485,7 @@ 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) { CHECK_BB(variadic_state(emit, stmt, 1)) CHECK_BB(emit_exp(emit, stmt->exp)) + const Instr check = emit_add_instr(emit, VarargCheck); const Instr member = emit_add_instr(emit, DotMember4); member->m_val = SZ_INT*2; const Instr instr = emit_add_instr(emit, BranchEqInt); @@ -1492,9 +1493,8 @@ ANN static m_bool emit_stmt_varloop(const Emitter emit, const Stmt_VarLoop stmt) emit_stmt(emit, stmt->body, 1); CHECK_BB(emit_exp(emit, stmt->exp)) emit_vararg_end(emit, pc); - instr->m_val = emit_code_size(emit); CHECK_BB(variadic_state(emit, stmt, 0)) - instr->m_val = emit_code_size(emit); + check->m_val = instr->m_val = emit_code_size(emit); return GW_OK; } diff --git a/src/lib/object.c b/src/lib/object.c index 4127707a..b8a2bf32 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -74,7 +74,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) { isa(v->type, shred->info->vm->gwion->type[et_object]) > 0) release(*(M_Object*)(o->data + v->from->offset), shred); else if(GET_FLAG(v->type, struct) && - !GET_FLAG(v, static) && !GET_FLAG(v, pure)) { + !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) { const TupleForm tf = v->type->e->tuple; for(m_uint i = 0; i < vector_size(&tf->types); ++i) { const m_bit *data = o->data + v->from->offset; diff --git a/src/lib/vararg.c b/src/lib/vararg.c index ecb19db7..6054adb6 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -66,7 +66,6 @@ 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)) { 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; @@ -87,6 +86,15 @@ INSTR(VarargIni) { *(M_Object*)REG(-SZ_INT) = o; } +INSTR(VarargCheck) { + const M_Object o = *(M_Object*)(shred->reg-SZ_INT); + struct Vararg_ *arg = *(struct Vararg_**)o->data; + if(arg->s) + return; + shred->reg -= SZ_INT; + shred->pc = instr->m_val; +} + static INSTR(VarargEnd) { const M_Object o = *(M_Object*)REG(0); struct Vararg_* arg = *(struct Vararg_**)o->data; @@ -106,8 +114,6 @@ 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) diff --git a/tests/error/variadic_miss_end.gw b/tests/error/variadic_miss_end.gw deleted file mode 100644 index 7ff8ee1d..00000000 --- a/tests/error/variadic_miss_end.gw +++ /dev/null @@ -1,3 +0,0 @@ -fun void test(...) { - vararg.start; -} diff --git a/tests/new/typedef_func_class_variadic.gw b/tests/new/typedef_func_class_variadic.gw index f4e2a3bc..acd1abf9 100644 --- a/tests/new/typedef_func_class_variadic.gw +++ b/tests/new/typedef_func_class_variadic.gw @@ -5,9 +5,9 @@ class C { fun void test(...) { <<< this, " ", __func__ >>>; - vararg.start; - <<< vararg $ int >>>; - vararg.end; + varloop vararg { + <<< vararg $ int >>>; + } } test @=> iptr; diff --git a/tests/tree/vararg_empty.gw b/tests/tree/vararg_empty.gw index 4b56af2b..1cbb938c 100644 --- a/tests/tree/vararg_empty.gw +++ b/tests/tree/vararg_empty.gw @@ -1,5 +1,5 @@ fun void test(...){ - vararg.start; - vararg.end; + varloop vararg { + } } test(); diff --git a/tests/tree/variadic_offset.gw b/tests/tree/variadic_offset.gw index 8f8efbcf..3757d981 100644 --- a/tests/tree/variadic_offset.gw +++ b/tests/tree/variadic_offset.gw @@ -1,2 +1,5 @@ -fun void test(int i, float f, ...){ vararg.start; vararg.end; } +fun void test(int i, float f, ...){ + varloop vararg { + } +} test(1, 2.3, 1); diff --git a/tests/tree/varobject_assign.gw b/tests/tree/varobject_assign.gw index 824f2c4c..27012d54 100644 --- a/tests/tree/varobject_assign.gw +++ b/tests/tree/varobject_assign.gw @@ -1,6 +1,6 @@ fun void test(...) { var Object o; - vararg.start; - vararg $ Object @=> o; - vararg.end; + varloop vararg { + vararg $ Object @=> o; + } } -- 2.43.0