]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Empty vararg does not go through varloop anymore
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 12 Sep 2020 13:06:14 +0000 (15:06 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 12 Sep 2020 13:06:14 +0000 (15:06 +0200)
include/instr.h
src/emit/emit.c
src/lib/object.c
src/lib/vararg.c
tests/error/variadic_miss_end.gw [deleted file]
tests/new/typedef_func_class_variadic.gw
tests/tree/vararg_empty.gw
tests/tree/variadic_offset.gw
tests/tree/varobject_assign.gw

index 782ea2e464ddbf714df8fa0554d33f36d4134d25..fa9b48529c2939e612d7b1982b96ccb6a874ceec 100644 (file)
@@ -48,6 +48,7 @@ INSTR(ArrayAlloc);
 
 /* vararg */
 INSTR(VarargIni);
+INSTR(VarargCheck);
 
 INSTR(PopArrayClass);
 
index dc582028732edf2a70f7ea6175bfa37559d1f794..daa5cf1c229513b2441200d12b9ad16e002b3dd5 100644 (file)
@@ -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;
 }
 
index 4127707a71bacc3861aae72627a868b19bef0673..b8a2bf32ce7b89c6dcd287d84768c064762b46da 100644 (file)
@@ -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;
index ecb19db77e7385c214568bd58f62c5aeaffe7a26..6054adb6fb33485b18b4286b0de2fd4ff59a5cc7 100644 (file)
@@ -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 (file)
index 7ff8ee1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fun void test(...) {
-  vararg.start;
-}
index f4e2a3bcf60f76299e016e7d97ef7a377b52eaae..acd1abf9d60ae1aeac7419e64da14976804ddd35 100644 (file)
@@ -5,9 +5,9 @@ class C {
 
   fun void test(...) {
     <<< this, " ", __func__ >>>;
-    vararg.start;
-    <<< vararg $ int >>>;
-    vararg.end;
+    varloop vararg {
+      <<< vararg $ int >>>;
+    }
   }
 
   test @=> iptr;
index 4b56af2bdad4d6f0189e9f42e0bd6ae371789d32..1cbb938c0231dbac365aa655c7103b7c90ed39f1 100644 (file)
@@ -1,5 +1,5 @@
 fun void test(...){
-  vararg.start;
-  vararg.end;
+  varloop vararg {
+  }
 }
 test();
index 8f8efbcfd4cbbc922c764cf8ec0ecb7f7fd2d79d..3757d98174e48f407a67d4d57c21ab5006edfbe1 100644 (file)
@@ -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);
index 824f2c4c5989350a317b94845886cccbec6a7bae..27012d541627f857361f0a9ac2adc1d77557c40a 100644 (file)
@@ -1,6 +1,6 @@
 fun void test(...) {
        var Object o;
-       vararg.start;
-       vararg $ Object @=> o;
-       vararg.end;
+  varloop vararg {
+         vararg $ Object @=> o;
+  }
 }