]> Nishi Git Mirror - gwion.git/commitdiff
:art: waaayyy to much for a commit
authorfennecdjay <fennecdjay@gmail.com>
Thu, 27 Oct 2022 15:37:24 +0000 (17:37 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Thu, 27 Oct 2022 15:38:32 +0000 (17:38 +0200)
15 files changed:
ast
include/emit.h
include/opcode.h
opcode.txt
src/emit/emit.c
src/lib/deep_equal.c
src/lib/lib_gack.c
src/parse/check.c
src/parse/scan0.c
src/vm/vm.c
tests/struct_ctor/struct_ctor_assign_get.gw
tests/struct_ctor/struct_ctor_assign_set.gw
tests/struct_ctor/struct_ctor_decl_get.gw
tests/struct_ctor/struct_ctor_decl_set.gw
tests/struct_ctor/struct_ctor_new_get.gw

diff --git a/ast b/ast
index ad317398e44e3b8c70b1695acc1991c0778644c6..1b4e5783de6964b23da7e02e79fd4003863437b6 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit ad317398e44e3b8c70b1695acc1991c0778644c6
+Subproject commit 1b4e5783de6964b23da7e02e79fd4003863437b6
index 89bc1ecc839f31c885ab01a402136989bdfeec67..62b5de3840f36417fecffe9cca56ded2511f9a9f 100644 (file)
@@ -137,9 +137,15 @@ ANN static inline void emit_pushimm(const Emitter emit, const m_uint value) {
   instr->m_val = value;
 }
 
-ANN static inline void emit_setimm(const Emitter emit, const m_uint value, const m_uint value2) {
-  const Instr instr = emit_add_instr(emit, RegSetImm);
-  instr->m_val  = value;
-  instr->m_val2 = value2;
-}
+#define mk_emit_instr(name, instruction)                                                           \
+ANN static inline Instr emit_##name(const Emitter emit, const m_uint value, const m_uint value2) { \
+  const Instr instr = emit_add_instr(emit, instruction);                                           \
+  instr->m_val  = value;                                                                           \
+  instr->m_val2 = value2;                                                                          \
+  return instr;                                                                                    \
+ }
+mk_emit_instr(setimm, RegSetImm);
+mk_emit_instr(regtomem, Reg2Mem);
+mk_emit_instr(regtomem4, Reg2Mem4);
+mk_emit_instr(regpushmem4, RegPushMem4);
 #endif
index 7daf9908ff2bcb0a18507137e0cea36fe484db87..69679ea3681e61342611b653a08a6a4c897cdf93 100644 (file)
@@ -18,7 +18,6 @@ enum {
   eRegPushBase4,
   eReg2Reg,
   eReg2RegOther,
-  eReg2RegOther2,
   eReg2RegAddr,
   eReg2RegDeref,
   eStructMember,
@@ -157,7 +156,6 @@ enum {
   eSporkIni,
   eForkIni,
   eSporkFunc,
-  eSporkMemberFptr,
   eSporkExp,
   eSporkCode,
   eForkEnd,
@@ -236,7 +234,6 @@ enum {
 #define  RegPushBase4         (f_instr)eRegPushBase4
 #define  Reg2Reg              (f_instr)eReg2Reg
 #define  Reg2RegOther         (f_instr)eReg2RegOther
-#define  Reg2RegOther2        (f_instr)eReg2RegOther2
 #define  Reg2RegAddr          (f_instr)eReg2RegAddr
 #define  Reg2RegDeref         (f_instr)eReg2RegDeref
 #define  StructMember         (f_instr)eStructMember
@@ -375,7 +372,6 @@ enum {
 #define  SporkIni             (f_instr)eSporkIni
 #define  ForkIni              (f_instr)eForkIni
 #define  SporkFunc            (f_instr)eSporkFunc
-#define  SporkMemberFptr      (f_instr)eSporkMemberFptr
 #define  SporkExp             (f_instr)eSporkExp
 #define  SporkCode            (f_instr)eSporkCode
 #define  ForkEnd              (f_instr)eForkEnd
@@ -539,12 +535,6 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
         gw_out("\n");
         break;
-      case eReg2RegOther2:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegOther2", j);
-        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
-        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
-        gw_out("\n");
-        break;
       case eReg2RegAddr:
         gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegAddr ", j);
         gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
@@ -1145,11 +1135,6 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out("{Y}┃{0}{-}% 4lu{0}: SporkFunc   ", j);
         gw_out("\n");
         break;
-      case eSporkMemberFptr:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkMemberFptr", j);
-        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
-        gw_out("\n");
-        break;
       case eSporkExp:
         gw_out("{Y}┃{0}{-}% 4lu{0}: SporkExp    ", j);
         gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
index 9cbb9db3bf1f9fc952d62de9953c3af649fb25ee..ddd0ebe80ec3e4b96400fc810809e8a17f7d6c8c 100644 (file)
@@ -15,7 +15,6 @@ RegPushBase3~p
 RegPushBase4~p
 Reg2Reg~u~u
 Reg2RegOther~u~u
-Reg2RegOther2~u~u
 Reg2RegAddr~u~u
 Reg2RegDeref~u~u
 StructMember~u
@@ -154,7 +153,6 @@ FuncMemberEnd~u~↓
 SporkIni~p
 ForkIni~p~i
 SporkFunc
-SporkMemberFptr~u
 SporkExp~u
 SporkCode~u
 ForkEnd
index aab4a82000d5b735c0b177ee13513ca1c70d296c..faff630ebcf61c5219cd0d73d22afe8dc7a11266 100644 (file)
@@ -130,25 +130,16 @@ if(!tflag(t, tflag_tmpl))return GW_OK;
                       .flag  = tflag_emit};
   return envset_run(&es, t);
 }
-/*
-ANN static inline m_uint emit_code_size(const Emitter emit) {
-  return vector_size(&emit->code->instr);
-}
-*/
+
 ANN static void emit_struct_dtor(const Emitter emit, const Type type,
                                  const m_uint offset) {
+  const m_uint code_offset = emit_code_offset(emit);
   emit->code->frame->curr_offset += SZ_INT;
-  const Instr instr = emit_add_instr(emit, RegPushMem4);
-  instr->m_val      = offset;
-  const Instr tomem = emit_add_instr(emit, Reg2Mem);
-  tomem->m_val      = emit->code->frame->curr_offset;
-  tomem->m_val2     = -SZ_INT;
+  emit_regpushmem4(emit, offset, 0);
+  emit_regtomem(emit, code_offset, -SZ_INT);
   emit_pushimm(emit, (m_uint)type);
-  const Instr tomem2       = emit_add_instr(emit, Reg2Mem);
-  tomem2->m_val            = emit->code->frame->curr_offset + SZ_INT;
-  tomem2->m_val2           = -SZ_INT;
+  emit_regtomem(emit, code_offset + SZ_INT, -SZ_INT);
   emit_setimm(emit, (m_uint)type->nspc->dtor, SZ_INT);
-  const m_uint code_offset = emit_code_offset(emit);
   emit_setimm(emit, code_offset, SZ_INT*2);
   emit_regmove(emit, SZ_INT * 2);
   const Instr prelude = emit_add_instr(emit, SetCode);
@@ -159,35 +150,50 @@ ANN static void emit_struct_dtor(const Emitter emit, const Type type,
   emit->code->frame->curr_offset -= SZ_INT;
 }
 
-ANN static void struct_pop(const Emitter emit, const Type type,
-                           const m_uint offset) {
+ANN void emit_object_release(const Emitter emit, const m_uint offset) {
+  const Instr instr = emit_add_instr(emit, ObjectRelease);
+  instr->m_val = offset;
+}
+
+ANN void emit_compound_release(const Emitter emit, const Type t, const m_uint offset) {
+  if(isa(t, emit->gwion->type[et_compound]) > 0)
+    return emit_object_release(emit, offset);
+  emit_struct_release(emit, t, offset);
+}
+
+ANN void emit_struct_release(const Emitter emit, const Type type,
+                             const m_uint offset) {
   if (!type->info->tuple) return;
   if (type->nspc->dtor) emit_struct_dtor(emit, type, offset);
-  for (m_uint i = 0; i < vector_size(&type->info->tuple->types); ++i) {
-    const Type t = (Type)vector_at(&type->info->tuple->types, i);
-    if (isa(t, emit->gwion->type[et_object]) > 0) {
-       const Instr instr = emit_add_instr(emit, ObjectRelease);
-       instr->m_val      = offset + vector_at(&type->info->tuple->offset, i);
-    } else if (tflag(t, tflag_struct))
-      struct_pop(emit, t, offset + vector_at(&type->info->tuple->offset, i));
+  const Vector v = &type->info->tuple->types;
+  for (m_uint i = 0; i < vector_size(v); i++) {
+    const Type t = (Type)vector_at(v, i);
+    if (isa(t, emit->gwion->type[et_compound]) > 0)
+      emit_compound_release(emit, t, offset + vector_at(&type->info->tuple->offset, i));
   }
 }
 
 ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt);
 
 ANN static m_bool emit_defers(const Emitter emit) {
-  if (!vector_size(&emit->code->frame->defer)) return GW_OK;
-  Stmt stmt;
-  while ((stmt = (Stmt)vector_pop(&emit->code->frame->defer)))
-    CHECK_BB(emit_stmt(emit, stmt));
+  const Vector v = &emit->code->frame->defer;
+  if (!vector_size(v)) return GW_OK;
+  m_uint i;
+  for(i = vector_size(v) + 1; --i;) {
+    const Stmt s = (Stmt)vector_at(v, i - 1);
+    if(s) CHECK_BB(emit_stmt(emit, s));
+  }
+  VLEN(v) = i;
+  vector_realloc(v);
   return GW_OK;
 }
 
 ANN static m_bool emit_defers2(const Emitter emit) {
-  for (m_uint i = vector_size(&emit->code->frame->defer) + 1; --i;) {
-    const Stmt stmt = (Stmt)vector_at(&emit->code->frame->defer, i - 1);
-    if (!stmt) break;
-    CHECK_BB(emit_stmt(emit, stmt));
+  const Vector v = &emit->code->frame->defer;
+  for (m_uint i = vector_size(v) + 1; --i;) {
+    const Stmt s = (Stmt)vector_at(v, i - 1);
+    if (!s) break;
+    CHECK_BB(emit_stmt(emit, s));
   }
   return GW_OK;
 }
@@ -202,7 +208,7 @@ ANN static m_int _frame_pop(const Emitter emit) {
       (VMValue *)m_vector_addr(&emit->code->live_values, --frame->value_count);
   vmval->end = emit_code_size(emit);
   if (!tflag(l->type, tflag_struct)) return (m_int)l->offset;
-  struct_pop(emit, l->type, l->offset);
+  emit_struct_release(emit, l->type, l->offset);
   return _frame_pop(emit);
 }
 
@@ -212,10 +218,7 @@ ANN static void emit_maybe_release(const Emitter emit, MP_Vector *const ms) {
     struct M_Vector_ vals = { .ptr = mv->ptr };
     for(m_uint j = 0; j < m_vector_size(&vals); j++) {
       const VMValue val = *(VMValue*)(vals.ptr + ARRAY_OFFSET + j * sizeof(VMValue));
-      if(!tflag(val.t, tflag_struct)) {
-       const Instr instr = emit_add_instr(emit, ObjectRelease);
-       instr->m_val      = val.offset;
-      } else struct_pop(emit, val.t, val.offset);
+      emit_compound_release(emit, val.t, val.offset);
     }
   }
 }
@@ -264,8 +267,7 @@ ANN void emit_pop_scope(const Emitter emit) {
   if(!vector_size(&v))
     vector_release(&v);
   else if(vector_size(&v) == 1) {
-    Instr instr  = emit_add_instr(emit, ObjectRelease);
-    instr->m_val = vector_front(&v);
+    emit_object_release(emit, vector_front(&v));
     vector_release(&v);
   } else {
     Instr instr  = emit_add_instr(emit, ObjectRelease2);
@@ -300,7 +302,10 @@ ANN m_uint emit_local(const Emitter emit, const Type t) {
   if (isa(t, emit->gwion->type[et_compound]) > 0) {
     l->is_compound = true;
     VMValue vmval  = {
-        .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+        .t = t,
+        .offset = l->offset,
+        .start = emit_code_size(emit)
+    };
     m_vector_add(&emit->code->live_values, &vmval);
     ++emit->code->frame->value_count;
   }
@@ -311,19 +316,19 @@ ANN void* emit_localx(const Emitter emit, const Type t) {
   Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t);
   l->is_compound = true;
   VMValue vmval  = {
-      .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+      .t = t,
+      .offset = l->offset,
+      .start = emit_code_size(emit)
+  };
   m_vector_add(&emit->code->live_values, &vmval);
   ++emit->code->frame->value_count;
-  l->instr = emit_add_instr(emit, Reg2Mem);
-  l->instr->m_val  = l->offset;
-  l->instr->m_val2 = -SZ_INT;
+  l->instr = emit_regtomem(emit, l->offset, -SZ_INT);
   return l;
 }
 
 ANN m_uint emit_local_exp(const Emitter emit, const Exp e) {
   Local *const l = emit_localx(emit, e->type);
-  if(e->ref)
-    e->ref->data = l;
+  if(e->ref) e->ref->data = l;
   return l->offset;
 }
 
@@ -441,7 +446,7 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) {
   const Instr prelude = emit_add_instr(emit, SetCode);
   prelude->m_val      = -SZ_INT * 2;
   prelude->udata.one  = 2;
-  emit_add_instr(emit, Reg2Mem);
+  (void)emit_regtomem(emit, 0, 0);
   const Instr next = emit_add_instr(emit, Overflow);
   next->m_val2     = offset;
 }
@@ -492,7 +497,6 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
       instr->f = v->d.fnum;
     else
       instr->m_val = v->d.num;
-    instr->m_val2 = size;
   }
   return GW_OK;
 }
@@ -589,8 +593,6 @@ ANN2(1)
 static void emit_exp_addref1(const Emitter emit, const Exp exp, m_int size) {
   const Type t = exp->cast_to ?: exp->type;
   if (isa(t, emit->gwion->type[et_compound]) > 0)
-    //    emit_object_addref(emit, size, exp_getvar(exp));
-    //  else if(tflag(t, tflag_struct))
     emit_compound_addref(emit, exp->type, size, exp_getvar(exp));
 }
 
@@ -643,14 +645,11 @@ ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e);
 
 ANN static m_bool emit_range(const Emitter emit, Range *range) {
   if (range->start)
-//    CHECK_BB(emit_exp_pop_next(emit, range->start));
     CHECK_BB(emit_exp(emit, range->start));
-  else
-    emit_pushimm(emit, 0);
+  else emit_pushimm(emit, 0);
   if (range->end)
     CHECK_BB(emit_exp(emit, range->end));
-  else
-    emit_pushimm(emit, -1);
+  else emit_pushimm(emit, -1);
   return GW_OK;
 }
 
@@ -700,7 +699,7 @@ ANN static m_bool emit_prim_dict(const Emitter emit, Exp *data) {
       instr->m_val2 = -SZ_INT - val->size;
       emit_regmove(emit, SZ_INT);
     } else {
-      const Instr instr = emit_add_instr(emit, Reg2RegOther2);
+      const Instr instr = emit_add_instr(emit, Reg2RegOther);
       instr->m_val  = -key->size;
       instr->m_val2 = key->size;
       emit_regmove(emit, key->size);
@@ -736,7 +735,7 @@ ANN m_bool emit_array_access(const Emitter                 emit,
 }
 
 ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array *array) {
-  const Exp              e    = exp_self(array);
+  const Exp e    = exp_self(array);
   exp_setvar(array->base, get_emit_var(emit, array->base->type, exp_getvar(e)));
   CHECK_BB(emit_exp(emit, array->base));
   struct ArrayAccessInfo info = {
@@ -771,7 +770,7 @@ ANN static inline Instr specialid_instr(const Emitter      emit,
 ANN static m_bool    emit_prim_id(const Emitter emit, const Symbol *data) {
   const Exp_Primary *prim = prim_self(data);
   struct SpecialId_ *spid = specialid_get(emit->gwion, *data);
-  if (spid)
+  if (unlikely(spid))
     return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR;
   if(vflag(prim->value, vflag_fglobal)) exp_self(prim)->acquire = 1;
   return emit_symbol(emit, prim_self(data));
@@ -862,11 +861,7 @@ ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) {
   if (!(emit->env->func &&
         emit->env->func->def->base->xid == insert_symbol("@gack")))
     emit_add_instr(emit, GackEnd);
-  else {
-    const Instr instr = emit_add_instr(emit, Reg2Mem);
-    instr->m_val      = SZ_INT;
-    instr->m_val2     = -SZ_INT;
-  }
+  else emit_regtomem(emit, SZ_INT, -SZ_INT);
   return GW_OK;
 }
 
@@ -975,17 +970,10 @@ ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) {
   const Type t = decl->type;
   const bool emit_addr = exp_getvar(exp_self(decl));
   if (decl->args) {
-//exp_setvar(decl->args, emit_addr);
-    const Instr instr = (Instr)vector_back(&emit->code->instr);
     CHECK_BB(emit_exp(emit, decl->args));
     if (emit_addr) {
       emit_regmove(emit, -t->size);
-//      emit_regmove(emit, SZ_INT -t->size);
-//      const Instr instr = emit_add_instr(emit, Reg2RegAddr);
-      const Instr instr = emit_add_instr(emit, RegPushMem4);
-//      emit_add_instr(emit, EOC);
-//      instr->m_val      = -SZ_INT;
-//      vector_add(&emit->code->instr, (m_uint)instr);
+      emit_regpushmem4(emit, 0, 0);
     }
     return GW_OK;
   }
@@ -1078,11 +1066,8 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
     }
     if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global))
       emit_object_addref(emit, 0, emit_addr);
-  } else if (tflag(v->type, tflag_struct)) {
-//    if (!emit_var)
-//      decl->vd.value->from->offset = decl_non_static_offset(emit, decl, type);
-    CHECK_BB(struct_finish(emit, decl));
-  }
+  } else if (tflag(v->type, tflag_struct))
+      CHECK_BB(struct_finish(emit, decl));
   return GW_OK;
 }
 
@@ -1274,9 +1259,7 @@ ANN static inline void inline_args_ini(const Emitter emit, const Func f,
     nspc_add_value(emit->env->curr, arg->var_decl.xid, value);
   }
   emit_regmove(emit, -f->code->stack_depth);
-  const Instr cpy = emit_add_instr(emit, Reg2Mem4);
-  cpy->m_val2     = f->code->stack_depth;
-  cpy->m_val      = start_offset;
+  emit_regtomem4(emit, f->code->stack_depth, start_offset);
 }
 
 ANN static inline void inline_args_end(const Func f, const Vector v) {
@@ -1345,15 +1328,12 @@ ANN static m_bool emit_new_struct(const Emitter emit,const Exp_Call *call)  {
   CHECK_BB(emit_func_args(emit, call));
   if(back)
     vector_add(&emit->code->instr, (m_uint)back);
-  else if(tflag(t, tflag_ctor)) {
-    const Instr instr = emit_add_instr(emit, RegPushMem4);
-    instr->m_val = offset;
-  }
+  else if(tflag(t, tflag_ctor))
+    emit_regpushmem4(emit, offset, 0);
   if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
   else if(!back)  {
     emit_regmove(emit, -SZ_INT + t->size);
-    const Instr instr = emit_add_instr(emit, RegPushMem4);
-    instr->m_val = offset;
+    emit_regpushmem4(emit, offset, 0);
   }
   emit_add_instr(emit, NoOp);
   return GW_OK;
@@ -1566,14 +1546,10 @@ ANN static Instr get_prelude(const Emitter emit, const Func f,
 
 ANN static void emit_args(const Emitter emit, const Func f) {
   const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
-  if ((f->def->stack_depth - member) == SZ_INT) {
-    const Instr instr = emit_add_instr(emit, Reg2Mem);
-    instr->m_val      = member;
-  } else {
-    const Instr instr = emit_add_instr(emit, Reg2Mem4);
-    instr->m_val      = member;
-    instr->m_val2     = f->def->stack_depth - member;
-  }
+  if ((f->def->stack_depth - member) == SZ_INT)
+    emit_regtomem(emit, member, 0);
+  else
+    emit_regtomem4(emit, member, f->def->stack_depth - member);
 }
 
 typedef struct {
@@ -1652,8 +1628,7 @@ ANN static Instr emit_call(const Emitter emit, const Func f,
   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);
-    instr->m_val2     = f->def->stack_depth - SZ_INT;
+    emit_regtomem(emit, 0, f->def->stack_depth - SZ_INT);
     ++prelude->m_val2;
   }
   if (f->def->stack_depth - member) {
@@ -2138,14 +2113,20 @@ ANN static inline void emit_push_stack(const Emitter emit) {
   vector_add(&emit->code->stack_break, (vtype)NULL);
 }
 
-ANN static void pop_vector(Vector v, const m_uint pc) {
-  Instr instr;
-  while ((instr = (Instr)vector_pop(v))) instr->m_val = pc;
+ANN static void set_pcs(const Vector v, const m_uint pc) {
+  m_uint i;
+  for(i = vector_size(v) + 1; --i;) {
+    Instr instr = (Instr)vector_at(v, i - 1);
+    if(!instr) break;
+    instr->m_val = pc;
+  }
+  VLEN(v) = i - 1;
+  vector_realloc(v);
 }
 
 ANN static void emit_pop_stack(const Emitter emit, const m_uint index) {
-  pop_vector(&emit->code->stack_cont, index);
-  pop_vector(&emit->code->stack_break, emit_code_size(emit));
+  set_pcs(&emit->code->stack_cont, index);
+  set_pcs(&emit->code->stack_break, emit_code_size(emit));
   emit_pop_scope(emit);
 }
 
@@ -2297,8 +2278,7 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt,
      ? */emit_local(emit, emit->gwion->type[et_int])
      /*: emit_local(emit, stmt->idx->v->type)*/;
   const m_uint val_offset = emit_localn(emit, stmt->v->type); // localn ?
-  const Instr tomem     = emit_add_instr(emit, Reg2Mem);
-  tomem->m_val          = arr_offset;
+  emit_regtomem(emit, arr_offset, 0);
   const Instr loop_idx  = emit_add_instr(emit, MemSetImm);
   loop_idx->m_val       = key_offset;
   loop_idx->m_val2      = -1;
@@ -2390,8 +2370,7 @@ ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt,
   }
   CHECK_BB(emit_exp_pop_next(emit, stmt->cond));
   emit_regmove(emit, -SZ_INT);
-  const Instr tomem  = emit_add_instr(emit, Reg2Mem);
-  tomem->m_val       = offset + (!stmt->idx ? 0 : SZ_INT);
+  emit_regtomem(emit, offset + !!stmt->idx * SZ_INT, 0);
   *index             = emit_code_size(emit);
   struct Looper loop = {.exp    = stmt->cond,
                         .stmt   = stmt->body,
@@ -2527,10 +2506,7 @@ ANN static m_bool emit_case_body(const Emitter             emit,
 ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
   const Value v   = e->d.prim.value;
   v->from->offset = emit_local(emit, base->type);
-  emit_debug(emit, v);
-  const Instr instr = emit_add_instr(emit, Reg2Mem4);
-  instr->m_val      = v->from->offset;
-  instr->m_val2     = base->type->size;
+  emit_regtomem4(emit, v->from->offset, base->type->size);
   return GW_OK;
 }
 
@@ -2816,8 +2792,7 @@ ANN static void me_end(MemoizeEmitter *me, const m_uint pc) {
 }
 
 ANN static void me_bottom(MemoizeEmitter *me, const m_uint pc) {
-  const Instr idx = emit_add_instr(me->emit, RegPushMem4);
-  idx->m_val      = me->offset;
+  emit_regpushmem4(me->emit, me->offset, 0);
   emit_add_instr(me->emit, int_pre_inc);
   emit_regmove(me->emit, -SZ_INT);
   const Instr loop = emit_add_instr(me->emit, Goto);
@@ -2879,9 +2854,8 @@ ANN static void emit_lambda_capture(const Emitter emit, const Func_Def fdef) {
   for(uint32_t i = 0; i < fdef->captures->len - 1; i++)
     (void)get_capture(emit, fdef->captures, i);
   const Capture *cap = get_capture(emit, fdef->captures, fdef->captures->len - 1);
-  const Instr instr = emit_add_instr(emit, Reg2Mem4);
-  instr->m_val = fdef->stack_depth;
-  instr->m_val2 = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth;
+  const m_uint offset = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth;
+  emit_regtomem4(emit, fdef->stack_depth, offset);
 }
 
 ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
index d5d0f293334ebdfeb72db20ddb64fe15891d05ef..e13bcde9d82921f6971062dbf3743b607c2df6ea 100644 (file)
@@ -164,9 +164,8 @@ ANN static void deep_emit_init(const Emitter emit, struct DeepEmit *d, const m_i
   d->tmp->d.prim.value = d->val;
   d->tmp->type = d->val->type;
   check_deep_equal_exp(emit->env, d->exp, &d->vec);
-  const Instr instr = emit_add_instr(emit, Reg2Mem);
-  instr->m_val2 = offset;
-  d->val->from->offset = instr->m_val = emit_localn(emit, d->val->type);
+  d->val->from->offset = emit_localn(emit, d->val->type);
+  emit_regtomem(emit, d->val->from->offset, offset);
 }
 
 ANN static void deep_emit_release(const Emitter emit, struct DeepEmit *d) {
index fc0edcd90ff75c3e65c5ceed18811aebc522dbaf..e736d4844a65f72ebb3152167aac4393fed76830 100644 (file)
@@ -22,7 +22,7 @@ static OP_EMIT(opem_gack_implicit) {
   const struct Implicit *imp  = (struct Implicit *)data;
   const Type t = imp->e->d.prim.d.exp->cast_to ?: imp->e->d.prim.d.exp->type;
   if(t == imp->t) {
-    const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind
+    const Instr cpy = emit_add_instr(emit, Reg2RegOther); // kind
     cpy->m_val2 = SZ_INT;
     emit_regmove(emit, imp->t->size - SZ_INT);
   } else {
@@ -32,7 +32,7 @@ static OP_EMIT(opem_gack_implicit) {
                           .rhs = imp->t};
     CHECK_BB(op_emit(emit, &opi));
     emit_regmove(emit, -SZ_INT);
-    const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind
+    const Instr cpy = emit_add_instr(emit, Reg2RegOther); // kind
     cpy->m_val = cpy->m_val2 = imp->t->size;
   }
   return GW_OK;
index 9d3ee8d82ac444d0b975dba82de50ebc368b0ed6..2927616e6bd5d8fe578c775512653d4cb02bedb1 100644 (file)
@@ -593,8 +593,10 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
   const m_uint scope   = env->scope->depth;
   env->scope->depth    = 0;
   vector_init(&v);
-  while (vector_size((Vector)&env->curr->info->value->ptr) > 1)
-    vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr));
+  Vector w = (Vector)&env->curr->info->value->ptr;
+  m_uint i = vector_size(w);
+  while (i-- > 1) vector_add(&v, vector_at(w, i));
+  vector_realloc(w);
   const m_bool ret = traverse_func_def(env, fdef);
   for (m_uint i = vector_size(&v) + 1; --i;)
     vector_add((Vector)&env->curr->info->value->ptr, vector_at(&v, i - 1));
@@ -893,24 +895,24 @@ ANN void call_add_effect(const Env env, const Func func, const loc_t pos) {
   }
 }
 
-ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
-  Type t = exp->func->type;
-  if (!is_func(env->gwion, t)) { // use func flag?
-    if(isa(exp->func->type, env->gwion->type[et_closure]) > 0)
-      t = closure_def(t)->base->func->value_ref->type;
-    else if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) {
-      const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new"));
-      if(v) t = exp->func->type = v->type;
-      else return NULL;
-    } else {
-      struct Op_Import opi = {.op   = insert_symbol("@ctor"),
-                              .rhs  = actual_type(env->gwion, exp->func->type),
-                              .data = (uintptr_t)exp,
-                              .pos  = exp_self(exp)->pos};
-      const Type       t   = op_check(env, &opi);
-      return t;
-    }
+ANN Type call_type(const Env env, Exp_Call *const exp) {
+  const Type t = exp->func->type;
+  if (is_func(env->gwion, t)) return t;
+  if(isa(exp->func->type, env->gwion->type[et_closure]) > 0)
+    return closure_def(t)->base->func->value_ref->type;
+  if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) {
+    const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new"));
+    if(v) return exp->func->type = v->type;
   }
+  struct Op_Import opi = {.op   = insert_symbol("@ctor"),
+                          .rhs  = actual_type(env->gwion, exp->func->type),
+                          .data = (uintptr_t)exp,
+                          .pos  = exp_self(exp)->pos};
+  return op_check(env, &opi);
+}
+
+ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
+  DECL_OO(const Type, t, = call_type(env, exp));
   if (t == env->gwion->type[et_op]) return check_op_call(env, exp);
   if (!t->info->func) // TODO: effects?
     return check_lambda_call(env, exp);
index 13fc1d60874d5418930624e6634989bd37383e93..2ecd4f2e79f01747f5a9c50279eeb1fe3da47e75 100644 (file)
@@ -514,15 +514,37 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
   return ret;
 }
 
+ANN static m_bool reemit_and_release(const Emitter emit, const Exp e) {
+  exp_setvar(e, false);
+  CHECK_BB(emit_exp(emit, e));
+  exp_setvar(e, true);
+  return GW_OK;
+}
+
 ANN Ast spread_class(const Env env, const Ast body);
 
+ANN static void exp_rewind(const Emitter emit,         const uint32_t start) {
+  const Vector v = &emit->code->instr;
+  for(m_int i = vector_size(v); --i > start && i;) {
+    const Instr instr = (Instr)vector_at(v, i-1);
+    free_instr(emit->gwion, instr);
+  }
+  VLEN(&emit->code->instr) = start;
+}
+
 static OP_EMIT(opem_struct_assign) {
   const Exp_Binary *bin = data;
   const Type t = bin->lhs->type;
   const Exp e = exp_self(bin);
+  CHECK_BB(reemit_and_release(emit, bin->rhs));
+  const Type rhs = bin->rhs->type;
+  emit_struct_release(emit, rhs, 0);
+  emit_regmove(emit, -rhs->size);
   if(unlikely(exp_getvar(e))) {
-    for(m_int i = vector_size(&emit->code->instr); --i > e->start && i;) {
-      const Instr instr = (Instr)vector_at(&emit->code->instr, i-1);
+    exp_rewind(emit, e->start);
+    const Vector v = &emit->code->instr;
+    for(m_int i = vector_size(v); --i > e->start && i;) {
+      const Instr instr = (Instr)vector_at(v, i-1);
       free_instr(emit->gwion, instr);
     }
     VLEN(&emit->code->instr) = e->start;
@@ -532,14 +554,12 @@ static OP_EMIT(opem_struct_assign) {
     emit_add_instr(emit, Assign);
     return GW_OK;
   }
-// need to add ref counting (release former)
   if(t->size == SZ_INT) emit_add_instr(emit, int_r_assign);
   else if(t->size == SZ_FLOAT) emit_add_instr(emit, float_r_assign);
   else {
     const Instr instr = (Instr)emit_add_instr(emit, Reg2RegOther);
-    instr->m_val  = -(t->size + SZ_INT);
+    instr->m_val  = -t->size * 2;
     instr->m_val2 = t->size;
-    emit_regmove(emit, -SZ_INT);
   }
   emit_struct_addref(emit, t, 0, false);
   return GW_OK;
index 5f44ab9ed222f90e0ac786c2178443d078b553fc..446e47725d2d60471fd9c4fc6118e07453e55301 100644 (file)
@@ -423,7 +423,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       &&regsetimm, &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
       &&regpushmem, &&regpushmemfloat, &&regpushmemother, &&regpushmemaddr,
       &&regpushmemderef, &&pushnow, &&baseint, &&basefloat, &&baseother,
-      &&baseaddr, &&regtoreg, &&regtoregother, &&regtoregother2, &&regtoregaddr, &&regtoregderef,
+      &&baseaddr, &&regtoreg, &&regtoregother2, &&regtoregaddr, &&regtoregderef,
       &&structmember, &&structmemberfloat, &&structmemberother,
       &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat,
       &&regpushme, &&regpushmaybe, &&funcreturn, &&_goto, &&allocint,
@@ -454,7 +454,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       &&regtomem, &&regtomemother,
       &&overflow,
       &&funcusrend, &&funcusrend2, &&funcmemberend,
-      &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkcode,
+      &&sporkini, &&forkini, &&sporkfunc, &&sporkexp, &&sporkcode,
       &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
       &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop,
       &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref,
@@ -564,9 +564,6 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
     regtoreg:
       *(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2);
       DISPATCH()
-    regtoregother:
-      memcpy(*(m_bit **)(reg - SZ_INT), reg + IVAL, VAL2);
-      DISPATCH()
     regtoregother2:
       memcpy(reg - VAL2, reg + IVAL, VAL2);
       DISPATCH()
@@ -897,7 +894,8 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       *(m_float *)(reg - SZ_FLOAT) += vm->bbq->pos;
       VM_OUT
       break;
-    recurs : {
+    recurs:
+    {
       register const uint push = SVAL2;
       mem += push;
       *(frame_t *)(mem - sizeof(frame_t)) =
@@ -962,14 +960,6 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
         *(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2);
       child->reg += VAL;
       DISPATCH()
-    sporkmemberfptr:
-      for (m_uint i = SZ_INT; i < VAL; i += SZ_INT)
-        *(m_uint *)(child->reg + i) = *(m_uint *)(reg - VAL + i);
-      *(M_Object *)(child->reg + VAL) = *(M_Object *)(reg + VAL + SZ_INT);
-      *(m_uint *)(child->reg + VAL + SZ_INT) =
-          *(m_uint *)(reg + VAL - SZ_INT * 2);
-      child->reg += VAL + SZ_INT * 2;
-      DISPATCH()
     sporkexp:
       //  LOOP_OPTIM
       for (m_uint i = 0; i < VAL; i += SZ_INT)
@@ -1106,20 +1096,20 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       reg += SZ_INT;
       DISPATCH()
     dotmembermem:
-      reg += SZ_INT;
-      *(m_uint *)(reg - SZ_INT) =
+      *(m_uint *)reg =
           *(m_uint *)((*(M_Object *)(mem + VAL2))->data + VAL);
+      reg += SZ_INT;
       DISPATCH()
     dotmembermem2:
-      reg += SZ_INT - SZ_FLOAT;
-      *(m_float *)(reg - SZ_FLOAT) =
+      *(m_float *)(reg + SZ_INT) =
           *(m_float *)((*(M_Object *)(mem + VAL2))->data + VAL);
+      reg += SZ_INT - SZ_FLOAT;
       DISPATCH()
 //    dotmembermem3:
     dotmembermem4:
-      reg += SZ_INT;
-      *(m_bit **)(reg - SZ_INT) =
+      *(m_bit **)reg =
           ((*(M_Object *)(mem + VAL2))->data + VAL);
+      reg += SZ_INT;
       DISPATCH()
     dotmember:
       *(m_uint *)(reg - SZ_INT) =
@@ -1278,7 +1268,7 @@ static void *_dispatch[] = {
       &&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr,
       &&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr,
       &&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother,
-      &&_baseaddr, &&_regtoreg, &&_regtoregother, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef,
+      &&_baseaddr, &&_regtoreg, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef,
       &&_structmember, &&_structmemberfloat, &&_structmemberother,
       &&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat,
       &&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint,
@@ -1309,7 +1299,7 @@ static void *_dispatch[] = {
       &&_regtomem, &&_regtomemother,
       &&_overflow,
       &&_funcusrend, &&_funcusrend2, &&_funcmemberend,
-      &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp, &&_sporkcode, &&_forkend,
+      &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkexp, &&_sporkcode, &&_forkend,
       &&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat,
       &&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop,
       &&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref,
@@ -1347,7 +1337,6 @@ goto *_dispatch[*(m_bit*)prepare_code];
     PREPARE(baseother);
     PREPARE(baseaddr);
     PREPARE(regtoreg);
-    PREPARE(regtoregother);
     PREPARE(regtoregother2);
     PREPARE(regtoregaddr);
     PREPARE(regtoregderef);
@@ -1512,7 +1501,6 @@ return;
     PREPARE(sporkini);
     PREPARE(forkini);
     PREPARE(sporkfunc);
-    PREPARE(sporkmemberfptr);
     PREPARE(sporkexp);
     PREPARE(sporkcode);
     PREPARE(forkend);
index 72a69801291dda0865d66afc53666f03db89a28e..2262994ae0c8d8db4e6c7df9a291f8a9098d24ca 100644 (file)
@@ -8,5 +8,4 @@ struct S {
   }
 }
 
-S(21,21) :=> var auto s;
-<<< s.i >>>;
+<<< (S(21,21) :=> var auto s).i >>>;
index e845d721cd9a30cd7ef013bbd812ef4fa072cef3..97b33f2ef35829f9b0fb3aef89a86897474078db 100644 (file)
@@ -1,4 +1,4 @@
-#! [contains] 42
+#! [contains] 13
 
 struct S {
   12 :=> var int i;
@@ -8,4 +8,4 @@ struct S {
   }
 }
 
-<<< 12 :=> (S(21,21) :=> var auto s).i >>>;
+<<< 13 :=> (S(21,21) :=> var auto s).i >>>;
index 99a01685cc3bf959b4c073840dce7baa775b1cdc..c4d5bffafc54780fe70b9b7256c0737959c59a23 100644 (file)
@@ -8,5 +8,4 @@ struct S {
   }
 }
 
-var S(21,21) w;
-<<< w.i >>>;
+<<< (var S(21,21) w).i >>>;
index 1af53acce60bb2cac8e6bf7357937ca3ec857a4e..63322a39248cb4c79a302ed456829078fe29bf0a 100644 (file)
@@ -1,4 +1,4 @@
-#! [contains] 42
+#! [contains] 13
 
 struct S {
   12 :=> var int i;
@@ -8,5 +8,4 @@ struct S {
   }
 }
 
-12 :=> (var S(21,21) w).i;
-<<< w.i >>>;
+<<< 13 :=> (var S(21,21) w).i >>>;
index ece50c879bd396880c2b7124e79d923f7886b75b..a154e7ba76c7726d5d3bbcfa1b5284d6808d4dfe 100644 (file)
@@ -8,4 +8,4 @@ struct S {
   }
 }
 
-(new S(21,21)).i;
+<<< (new S(21,21)).i >>>;