]> Nishi Git Mirror - gwion.git/commitdiff
:bomb: Improve struct releasing
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Wed, 22 Jul 2020 15:16:15 +0000 (17:16 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Wed, 22 Jul 2020 15:16:15 +0000 (17:16 +0200)
15 files changed:
include/object.h
src/emit/emit.c
src/env/type.c
src/import/cdef.c
src/lib/array.c
src/lib/engine.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/vararg.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/vm/gack.c
src/vm/vm.c

index e199b54beec130c72d297b4101eb609c75ea8cb9..c065c9fdefb09c046308ff2a8c2fe557fc656182 100644 (file)
@@ -36,4 +36,9 @@ static inline void _release(const restrict M_Object obj, const restrict VM_Shred
 static inline void release(const restrict M_Object obj, const restrict VM_Shred shred) {
   if(obj)_release(obj, shred);
 }
+typedef void (f_release)(const VM_Shred shred, const Type t NUSED, const m_bit* ptr);
+#define RELEASE_FUNC(a) void (a)(const VM_Shred shred, const Type t NUSED, const m_bit* ptr)
+static inline RELEASE_FUNC(object_release) { release(*(M_Object*)ptr, shred); }
+RELEASE_FUNC(struct_release);
+
 #endif
index 8c2d3fd6701dbc5e9c4d0594d3f205b67eb6a642..7a55d21c88a78996ec5e638da1dc698ddb3c1a12 100644 (file)
@@ -187,17 +187,33 @@ regxxx(push, Push)
 regxxx(pushi, PushImm)
 regxxx(seti, SetImm)
 
+ANN static void struct_expand(const Emitter emit, const Type t) {
+  const Instr instr = emit_add_instr(emit, Reg2RegDeref);
+  instr->m_val = -SZ_INT;
+  instr->m_val2 = t->size;
+//  regpush(emit, t->size - SZ_INT);
+}
+
+
+INSTR(ArrayStruct);
+
 ANN static void emit_pre_constructor_array(const Emitter emit, const Type type) {
   const m_uint start_index = emit_code_size(emit);
   const Instr top = emit_add_instr(emit, ArrayTop);
   top->m_val2 = (m_uint)type;
+  if(GET_FLAG(type, struct)) {
+    const Instr instr = emit_add_instr(emit, ArrayStruct);
+    instr->m_val = type->size;
+  }
   emit_pre_ctor(emit, type);
-  const Instr bottom = emit_add_instr(emit, ArrayBottom);
+  if(!GET_FLAG(type, struct))
+    emit_add_instr(emit, ArrayBottom);
+  else
+    regpop(emit, SZ_INT);
   regpop(emit, SZ_INT);
   const Instr pc = emit_add_instr(emit, Goto);
   pc->m_val = start_index;
   top->m_val = emit_code_size(emit);
-  bottom->m_val = start_index;
   regpop(emit, SZ_INT*3);
   emit_add_instr(emit, ArrayPost);
 }
@@ -229,9 +245,9 @@ ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) {
 
 ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) {
   const Type base = info->base;
-// TODO: needed for coumpund?
-  if(isa(base, emit->gwion->type[et_object]) > 0 && !GET_FLAG(base, abstract)) {
+  if(isa(base, emit->gwion->type[et_compound]) > 0 && !GET_FLAG(base, abstract)) {
     emit_pre_constructor_array(emit, base);
+//  if(isa(base, emit->gwion->type[et_object]) > 0)
     info->is_obj = 1;
   }
 }
@@ -514,11 +530,8 @@ ANN static void interp_multi(const Emitter emit, const Exp e) {
     regpop(emit, offset);
 }
 
-ANN static void interp_size(const Emitter emit, const Type t) {
-  const m_uint sz = (isa(t, emit->gwion->type[et_object]) < 0 ||
-    (!GET_FLAG(t, builtin) && isa(t, emit->gwion->type[et_compound]) > 0))?
-      t->size : SZ_INT;
-  const Instr instr = regseti(emit, sz);
+ANN static inline void interp_size(const Emitter emit, const Type t) {
+  const Instr instr = regseti(emit, t->size);
   instr->m_val2 = SZ_INT;
 }
 
@@ -537,10 +550,8 @@ ANN static m_bool emit_interp(const Emitter emit, const Exp exp) {
     regseti(emit, (m_uint)e->info->type);
     interp_size(emit, e->info->type);
     const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
-    if(isobj) {
-      if(!GET_FLAG(e->info->type, force))
-        emit_add_instr(emit, GackType);
-    }
+    if(isobj && !GET_FLAG(e->info->type, force))
+      emit_add_instr(emit, GackType);
     const Instr instr = emit_add_instr(emit, Gack);
     instr->m_val = emit_code_offset(emit);
   } while((e = e->next = next));
@@ -594,13 +605,11 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const
 }
 
 ANN static inline int struct_ctor(const Value v) {
-  return GET_FLAG(v->type, struct) && !GET_FLAG(v->type, builtin);
+  return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor;
 }
 
 ANN static void decl_expand(const Emitter emit, const Type t) {
-  const Instr instr = emit_add_instr(emit, Reg2RegDeref);
-  instr->m_val = -SZ_INT;
-  instr->m_val2 = t->size;
+  struct_expand(emit, t);
   regpush(emit, t->size - SZ_INT);
 }
 
@@ -653,7 +662,13 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
     emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
   instr->m_val = v->from->offset;
   if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
-    emit_add_instr(emit, Assign);
+    if(!emit_var)
+      emit_add_instr(emit, Assign);
+    else {
+      regpop(emit, SZ_INT);
+      const Instr instr = emit_add_instr(emit, Reg2Reg);
+      instr->m_val = -SZ_INT;
+    }
     const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
     if(missing_depth && !GET_FLAG(decl->td, force)) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
@@ -793,6 +808,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
   }
   const Exp e = exp_self(exp_call);
   if(exp_getvar(e)) {
+puts("here");
     regpop(emit, exp_self(exp_call)->info->type->size - SZ_INT);
     const Instr instr = emit_add_instr(emit, Reg2RegAddr);
     instr->m_val = -SZ_INT;
@@ -1810,8 +1826,9 @@ DECL_STMT_FUNC(emit, m_bool , Emitter)
 
 ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
   CHECK_BB(emit_stmt_func[stmt->stmt_type](emit, &stmt->d))
-  if(pop && stmt->stmt_type == ae_stmt_exp && stmt->d.stmt_exp.val)
+  if(pop && stmt->stmt_type == ae_stmt_exp && stmt->d.stmt_exp.val) {
     pop_exp(emit, stmt->d.stmt_exp.val);
+  }
   return GW_OK;
 }
 
@@ -1877,7 +1894,7 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
     ADD_REF(f->code)
     return f->code;
   } else if(f->def->base->xid == insert_symbol("@gack")) {
-    regpop(emit, SZ_INT*2);
+    regpop(emit, SZ_INT + f->value_ref->from->owner_class->size);
     const Instr instr = emit_add_instr(emit, RegPushMem);
     instr->m_val = SZ_INT;
     f->code = finalyze(emit, FuncReturn);
@@ -2026,7 +2043,7 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) {
 
 ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  return !GET_FLAG(parent, emit) ? scanx_parent(parent, emit_cdef, emit) : GW_OK;
+  return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
 }
 
 ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
@@ -2042,7 +2059,7 @@ ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
 ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
-  const m_bool ret = scanx_parent(cdef->base.type, emit_parent, emit);
+  const m_bool ret = emit_parent(emit, cdef);
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     nspc_pop_type(emit->gwion->mp, emit->env->curr);
   return ret;
@@ -2055,6 +2072,8 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if(GET_FLAG(t, emit))
     return GW_OK;
   SET_FLAG(t, emit);
+  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
+    CHECK_BB(ensure_emit(emit, t->e->owner_class))
   if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
     CHECK_BB(cdef_parent(emit, cdef))
   nspc_allocdata(emit->gwion->mp, t->nspc);
index a8eede9111179ad059ca57c5a8073904a6d2efcf..6cefe46f12e178092c35e9c166fc2955c902ed61 100644 (file)
@@ -6,6 +6,7 @@
 #include "parse.h"
 #include "gwion.h"
 #include "clean.h"
+#include "object.h"
 
 ANN static inline m_bool freeable(const Type a) {
   return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
@@ -110,6 +111,14 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) {
   t->array_depth = depth + src->array_depth;
   t->e->d.base_type = array_base(src) ?: src;
   t->e->owner = src->e->owner;
+  if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) {
+    t->nspc = new_nspc(env->gwion->mp, s_name(sym));
+    inherit(t);
+    t->nspc->info->class_data_size = SZ_INT;
+    nspc_allocdata(env->gwion->mp, t->nspc);
+    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ?
+      object_release : struct_release;
+  } else
   ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
   SET_FLAG(t, valid);
   mk_class(env, t);
index 6a96d2e9ee4b7d1e61bca00a8f615e660ac834e4..814ffa5bbb937a8b351d7d895e7d986aae056229 100644 (file)
@@ -26,12 +26,11 @@ ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_f
   return GW_OK;
 }
 
-ANN2(1,2) static inline m_bool class_parent(const Env env, const Type t) {
-  Type parent = t->e->parent;
-  while(parent && !GET_FLAG(parent, valid)) {
+ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
+  while(t && !GET_FLAG(t, valid)) {
     if(t->e->def)
       CHECK_BB(traverse_class_def(env, t->e->def))
-    parent = parent->e->parent;
+    t = t->e->parent;
   }
   return GW_OK;
 }
@@ -70,11 +69,16 @@ ANN static inline void gwi_type_flag(const Type t) {
 
 ANN static Type type_finish(const Gwi gwi, const Type t) {
   gwi_add_type(gwi, t);
-  CHECK_BO(class_parent(gwi->gwion->env, t))
   import_class_ini(gwi->gwion->env, t);
   return t;
 }
 
+ANN2(1,2) Type handle_class(const Gwi gwi, Type_Decl *td) {
+  DECL_OO(const Type, p, = known_type(gwi->gwion->env, td))
+  CHECK_BO(class_parent(gwi->gwion->env, p))
+  return p;
+}
+
 ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent) {
   struct ImportCK ck = { .name=name };
   CHECK_BO(check_typename_def(gwi, &ck))
@@ -82,13 +86,15 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
   Tmpl* tmpl = ck.tmpl ? new_tmpl_base(gwi->gwion->mp, ck.tmpl) : NULL;
   if(tmpl)
     CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
-  const Type p = known_type(gwi->gwion->env, td); // check
-  if(!p) {
-    env_pop(gwi->gwion->env, 0);
-    return NULL;
-  }
+  const Type base = find_type(gwi->gwion->env, td);
+  const Type_List tl = td->types;
+  if(GET_FLAG(base, unary))
+    td->types = NULL;
+  const Type p = !td->types ? handle_class(gwi, td) : NULL;
+  td->types = tl;
   if(tmpl)
     nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
+  CHECK_OO(p)
   const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
   t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
   t->e->def->base.tmpl = tmpl;
index d9bd19a90228f2dcaf4abc5f1a8c88ff2192d632..57f55ed6a9b2b539bd7d1c0b2f184181d782f21f 100644 (file)
@@ -53,16 +53,16 @@ ANN static inline int is_array(const Type *types, const Type type) {
 }
 
 static DTOR(array_dtor) {
-  const Type t = !GET_FLAG(o->type_ref, nonnull) ?
-    o->type_ref : o->type_ref->e->parent;
+  const Type t = unflag_type(o->type_ref);
   if(*(void**)(o->data + SZ_INT))
     xfree(*(void**)(o->data + SZ_INT));
   struct M_Vector_* a = ARRAY(o);
   if(!a)
     return;
-  if(t->array_depth > 1 || is_array(shred->info->vm->gwion->type, t))
+  if(t->nspc->info->class_data_size) {
     for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
-      release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred);
+      (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(a) + i * ARRAY_SIZE(a));
+  }
   free_m_vector(shred->info->mp, a);
 }
 
@@ -95,8 +95,9 @@ ANN void m_vector_set(const M_Vector v, const m_uint i, const void* data) {
 
 ANN void m_vector_rem(const M_Vector v, m_uint index) {
   const m_uint size = ARRAY_SIZE(v);
-  memmove(ARRAY_PTR(v) + index * size, ARRAY_PTR(v) + (index + 1) * size,
-    (ARRAY_SIZE(v) - index - 1) *size);
+  if(index < ARRAY_LEN(v) - 1)
+    memmove(ARRAY_PTR(v) + index * size, ARRAY_PTR(v) + (index + 1) * size,
+      (ARRAY_SIZE(v) - index - 1) *size);
   --ARRAY_LEN(v);
   if(ARRAY_LEN(v) < ARRAY_CAP(v) / 2) {
     const m_uint cap = ARRAY_CAP(v) /= 2;
@@ -109,11 +110,9 @@ static MFUN(vm_vector_rem) {
   const M_Vector v = ARRAY(o);
   if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
     return;
-  if(isa(o->type_ref, shred->info->vm->gwion->type[et_object]) > 0) {
-    M_Object obj;
-    m_vector_get(v, (vtype)index, &obj);
-    release(obj,shred);
-  }
+  const Type t = unflag_type(o->type_ref);
+  if(t->nspc->info->class_data_size)
+    (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
   m_vector_rem(v, (vtype)index);
 }
 
@@ -371,6 +370,13 @@ GWION_IMPORT(array) {
   return GW_OK;
 }
 
+INSTR(ArrayStruct) {
+  const M_Object ref = *(M_Object*)(REG(-SZ_INT * 5));
+  const m_int idx = (*(m_int*)((shred->reg -SZ_INT * 3)))++;
+  *(m_bit**)(shred->reg) = m_vector_addr(ARRAY(ref), idx);
+  shred->reg += SZ_INT; // regpush
+}
+
 INSTR(ArrayBottom) {
   *(M_Object*)(*(m_uint**)REG(-SZ_INT * 4))[(*(m_int*)REG(-SZ_INT * 3))++] = *(M_Object*)REG(-SZ_INT);
 }
@@ -439,7 +445,7 @@ ANN static M_Object* init_array(const VM_Shred shred, const ArrayInfo* info, m_u
     *num_obj *= *(m_uint*)REG(SZ_INT * curr);
     ++curr;
   }
-  return *num_obj > 0 ? (M_Object*)xcalloc(*num_obj, SZ_INT) : NULL;
+  return *num_obj > 0 ? (M_Object*)xcalloc(*num_obj, info->base->size) : NULL;
 }
 
 INSTR(ArrayAlloc) {
@@ -470,3 +476,4 @@ INSTR(ArrayAlloc) {
     *(m_uint*) REG(-SZ_INT) = num_obj;
   }
 }
+
index 35d3b45466e6eb29540d867de8425cab0644635d..efc508038377ba6009006ecfb0ca91e709e6fc70 100644 (file)
@@ -56,7 +56,7 @@ static GACK(gack_float) {
 }
 
 static GACK(gack_compound) {
-  INTERP_PRINTF("%p", *(void**)VALUE);
+  INTERP_PRINTF("%p", VALUE);
 }
 #define mk_class_instr(op, arg0, arg1, ...)                          \
 static INSTR(instr_class_##op) {                                     \
index 8cf1352a891f0e17316d62fecc911e186b807b36..e12894caff0a1ee59fb31e3de7c6b4beac647cf0 100644 (file)
@@ -113,7 +113,7 @@ static OP_EMIT(opem_implicit_null2obj) {
   return (Instr)GW_OK;
 }
 
-ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td);
+ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl* td);
 
 static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
   if(ts->td->types)
@@ -384,7 +384,7 @@ ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) {
   return GW_OK;
 }
 
-ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) {
+ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
   if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
    ERR_O(td->pos, _("invalid template types number"))
   DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
@@ -422,6 +422,21 @@ ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data) {
   return dot;
 }
 
+ANN void struct_release(const VM_Shred shred, const Type base, const m_bit *ptr) {
+  const Vector types   = &base->e->tuple->types;
+  const Vector offsets = &base->e->tuple->offset;
+  for(m_uint i = 0; i < vector_size(types); ++i) {
+    const Type t = (Type)vector_at(types, i);
+    if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0)
+      continue;
+    const m_uint offset = vector_at(offsets, i);
+    if(!GET_FLAG(t, struct))
+      release(*(M_Object*)(ptr + offset), shred);
+    else
+      struct_release(shred, t, *(m_bit**)(ptr + offset));
+  }
+}
+
 GWION_IMPORT(object_op) {
   const Type t_null  = gwi_mk_type(gwi, "@null",  SZ_INT, "Object");
   gwi->gwion->type[et_null] = t_null;
index fc931530b20b408f26caf7aeacd801c1b90ee241..84158e10dd19fa8476a01fa76559b6a1abb26ba3 100644 (file)
@@ -28,11 +28,13 @@ static OP_CHECK(opck_ptr_assign) {
   exp_setvar(bin->lhs, 1);
   Type t = bin->lhs->info->type;
   do {
+//    t = unflag_type(t);
     Type u = bin->rhs->info->type;
     do {
+//      u = unflag_type(u);
       const m_str str = get_type_name(env, u, 1);
       if(str && !strcmp(t->name, str))
-        return bin->lhs->info->type;
+        return bin->lhs->info->type; // use rhs?
     } while((u = u->e->parent));
   } while((t = t->e->parent));
   return env->gwion->type[et_null];
@@ -42,6 +44,7 @@ static INSTR(instr_ptr_assign) {
   POP_REG(shred, SZ_INT)
   const M_Object o = *(M_Object*)REG(0);
   *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT);
+  _release(o, shred);
 }
 
 static OP_CHECK(opck_ptr_deref) {
@@ -122,8 +125,41 @@ static OP_EMIT(opem_ptr_deref) {
   return instr;
 }
 
+ANN Type scan_class(const Env env, const Type t, const Type_Decl* td);
+
+static DTOR(ptr_object_dtor) {
+  release(*(M_Object*)o->data, shred);
+}
+
+static DTOR(ptr_struct_dtor) {
+  const Type t = (Type)vector_front(&o->type_ref->e->tuple->types);
+  struct_release(shred, t, *(m_bit**)o->data);
+}
+
+static OP_CHECK(opck_ptr_scan) {
+  struct TemplateScan *ts = (struct TemplateScan*)data;
+  const Type t = (Type)scan_class(env, ts->t, ts->td);
+  const Type base = known_type(env, t->e->def->base.tmpl->call->td);
+  if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
+    t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor");
+    if(!GET_FLAG(t, struct))
+      t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
+    else
+      t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
+    SET_FLAG(t, dtor);
+  }
+  return t;
+}
+
 GWION_IMPORT(ptr) {
-  const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", NULL);
+  const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
+  GWI_BB(gwi_class_end(gwi))
+  SET_FLAG(_t_ptr, unary);
+  GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
+  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
+  const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", "@Ptr");
+//  const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", NULL);
   gwi->gwion->type[et_ptr] = t_ptr;
   GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
   GWI_BB(gwi_item_end(gwi, 0, NULL))
index aa1db9f9ab87d247850a9e19b53c895e4ddb40a7..ecb19db77e7385c214568bd58f62c5aeaffe7a26 100644 (file)
@@ -31,6 +31,8 @@ static DTOR(vararg_dtor) {
       const Type t = (Type)vector_at(&arg->t, i);
       if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
         release(*(M_Object*)(arg->d + offset), shred);
+      else if(GET_FLAG(t, struct))
+        struct_release(shred, t, *(m_bit**)(arg->d + offset));
       offset += t->size;
     }
   }
index e904d781f4bf816a3733d847c5517c6518138207..bbeee4600f2940a019be8e2a79228ca781b25164 100644 (file)
@@ -357,10 +357,6 @@ ANN static Type check_prim_typeof(const Env env, const Exp *exp) {
 
 ANN static Type check_prim_interp(const Env env, const Exp* exp) {
   CHECK_OO(check_exp(env, *exp))
-  Exp e = *exp;
-  do if(GET_FLAG(e->info->type, struct) && !GET_FLAG(e->info->type, builtin))
-    exp_setvar(e, 1);
-  while((e = e->next));
   return env->gwion->type[et_string];
 }
 
@@ -1416,7 +1412,7 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
   if(td->array)
     CHECK_BB(check_subscripts(env, td->array, 1))
   if(parent->e->def && !GET_FLAG(parent, check))
-    CHECK_BB(scanx_parent(parent, check_cdef, env))
+    CHECK_BB(ensure_check(env, parent))
   if(GET_FLAG(parent, typedef))
     SET_FLAG(cdef->base.type, typedef);
   return GW_OK;
@@ -1425,7 +1421,7 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(env, cdef->base.tmpl))
-  const m_bool ret = scanx_parent(cdef->base.type, check_parent, env);
+  const m_bool ret = check_parent(env, cdef);
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
@@ -1436,7 +1432,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
     return GW_OK;
   const Type t = cdef->base.type;
   if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
-    CHECK_BB(check_class_def(env, t->e->owner_class->e->def))
+    CHECK_BB(ensure_check(env, t->e->owner_class))
   if(GET_FLAG(t, check))return GW_OK;
   SET_FLAG(t, check);
   if(cdef->base.ext)
index c4e6e919b3ab1d54313fe002a978971530375413..16da242570f360b7ac2c70de89f015db66ed59a9 100644 (file)
@@ -547,7 +547,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   if(isa(parent, env->gwion->type[et_object]) < 0)
     ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
   if(parent->e->def && !GET_FLAG(parent, scan1))
-    CHECK_BB(scanx_parent(parent, scan1_cdef, env))
+    CHECK_BB(ensure_scan1(env, parent))
   if(type_ref(parent))
     ERR_B(pos, _("can't use ref type in class extend"))
   if(GET_FLAG(parent, nonnull))
@@ -558,7 +558,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(env, cdef->base.tmpl))
-  const m_bool ret = scanx_parent(cdef->base.type, scan1_parent, env);
+  const m_bool ret = scan1_parent(env, cdef);
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
index 3bb0c31e5cd10b3ddaa8209926d7d27db84b1772..e927843c5bc61e1ebe1346adc241f6b491cfeafe 100644 (file)
@@ -550,9 +550,8 @@ HANDLE_SECTION_FUNC(scan2, m_bool, Env)
 
 ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-//  if(parent->e->def && !GET_FLAG(parent, scan2))
   if(parent->e->def && !GET_FLAG(parent, scan2))
-    CHECK_BB(scanx_parent(parent, scan2_cdef, env))
+    CHECK_BB(ensure_scan2(env, parent))
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
   return GW_OK;
@@ -561,7 +560,8 @@ ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(env, cdef->base.tmpl))
-  const m_bool ret = scanx_parent(cdef->base.type, scan2_parent, env);
+//  const m_bool ret = scanx_parent(cdef->base.type, scan2_parent, env);
+  const m_bool ret = scan2_parent(env, cdef);
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
@@ -573,7 +573,7 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   const Type t = cdef->base.type;
   if(GET_FLAG(t, scan2))return GW_OK;
   if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
-    CHECK_BB(scan2_class_def(env, t->e->owner_class->e->def))
+    CHECK_BB(ensure_scan2(env, t->e->owner_class))
   SET_FLAG(t, scan2);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
index 932c63a14e7cc39445073f1427744f10b711fbf6..ec8b81802d6f101155f4d2d157dfbf36a6507f04 100644 (file)
@@ -116,7 +116,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {
     struct EnvSet es = { .env=env, .data=env,
       .scope=env->scope->depth, .flag=ae_flag_none };
     envset_push(&es, owner, owner->nspc);
-    (void)env_push(env, owner, owner->nspc);
+    (void)env_push(env, owner, owner->nspc);// TODO: is this needed?
     const Type ret = scan_type(env, t, td->next);
     env_pop(env, es.scope);
     if(es.run)
index 4a63cd07f174e1026e0b6ae91cdf6469f957cddb..203dbee3e4a5eec719355d09976ba1f1a38874f0 100644 (file)
@@ -53,7 +53,6 @@ ANN static void prepare_call(const VM_Shred shred, const m_uint offset) {
   *(m_uint*)(shred->mem  + SZ_INT*3) = shred->pc;
   *(m_uint*)(shred->mem  + SZ_INT*4) = SZ_INT;
   shred->mem += SZ_INT*5;
-  *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
   shred->pc = 0;
 }
 
@@ -66,6 +65,10 @@ ANN void gack(const VM_Shred shred, const m_uint offset) {
     POP_REG(shred, sz);
   } else {
     prepare_call(shred, offset);
+    if(GET_FLAG(t, struct))
+      *(void**)(shred->mem) = (void*)(shred->reg - t->size);
+    else
+      *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
     shred->code = code;
   }
   return;
index b4582fcfff8f0b3c4bfe72d59d7f1acd5848f9c8..887e6d048f249c454055e110e2f6deff7ecaae50 100644 (file)
@@ -429,6 +429,7 @@ structmember:
   *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
   DISPATCH()
 structmemberfloat:
+printf("struct: %p\n", *(m_bit**)(reg-SZ_INT));
   *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
   DISPATCH()
 structmemberother:
@@ -466,6 +467,7 @@ allocfloat:
   reg += SZ_FLOAT;
   DISPATCH()
 allocother:
+puts("here!!!");
 //  LOOP_OPTIM
   for(m_uint i = 0; i <= VAL2; i += SZ_INT)
     *(m_uint*)(reg+i) = (*(m_uint*)(mem+VAL+i) = 0);