]> Nishi Git Mirror - gwion.git/commitdiff
:art: pre_ctor is now a function
authorfennecdjay <fennecdjay@gmail.com>
Mon, 9 Jan 2023 13:53:47 +0000 (14:53 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Mon, 9 Jan 2023 13:53:47 +0000 (14:53 +0100)
20 files changed:
compile_flags.txt [new file with mode: 0644]
include/env/func.h
include/env/type.h
include/instr.h
include/parse.h
include/vm.h
src/emit/emit.c
src/env/func.c
src/env/type.c
src/gwion.c
src/import/import_cdef.c
src/lib/closure.c
src/lib/dict.c
src/lib/instr.c
src/lib/object.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c
src/vm/vm.c
util

diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644 (file)
index 0000000..9998e44
--- /dev/null
@@ -0,0 +1,4 @@
+-Iutil/include
+-Iast/include
+-Iinclude
+-Ifmt/include
index d0fa07248e704662a053a8f8c5db10202426fbc6..4c45038ebb16fe440b86a5ade67f12b6a86c1c93 100644 (file)
@@ -17,12 +17,11 @@ struct Func_ {
   Value            value_ref;
   Func             next;
   m_str            name;
-  uint32_t         wait;
+  MP_Vector       *_wait;
   float            inline_mult;
   uint16_t         weight;  // used to mark gack use in scan1
   uint16_t         memoize; // used to mark return in scan1
   uint16_t         ref;
-//  uint16_t         vt_index;
   ae_flag          flag;
   enum fflag       fflag;
 };
@@ -45,7 +44,11 @@ ANN static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol s
 }
 
 ANN static inline m_uint captures_sz(const Capture_List captures) {
-  const Capture *cap = mp_vector_at(captures, Capture, (captures->len - 1));
+  const Capture *cap = mp_vector_back(captures, Capture);
   return cap->temp->from->offset + cap->temp->type->size;
 }
+
+ANN static inline bool is_ctor(const Func_Def fdef) {
+  return !strcmp(s_name(fdef->base->xid), "@ctor");
+}
 #endif
index 85165b2fe247ddc0d49438515553dce83c5601c9..6a1a6bba2c9397c889a225cc047d07fc0565f46e 100644 (file)
@@ -50,9 +50,7 @@ struct Type_ {
   struct TypeInfo_ *info;
   uint64_t          size;
   uint64_t          actual_size;
-  struct Vector_    effects; // pre-ctor effects
-//  struct MP_Vector  *wait;
-  uint32_t wait;
+//  struct Vector_    effects; // pre-ctor effects
   uint32_t          array_depth;
   uint16_t          ref;
   uint16_t          weight;
index 4217a4b611ab360ff836e9402f3d3356fa75d948..72e733b5251431ede00d298506c86104a3bc9024 100644 (file)
@@ -69,6 +69,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const Func_Def fdef, const Valu
 
 INSTR(SetFunc);
 INSTR(SetCtor);
+INSTR(FuncWait);
 #include "opcode.h"
 
 INSTR(dict_ctor_alt);
index f2c96926e00d66b6cbf5d66e22b39a6a81518b14..b0b75621a34170791708f6c66ca676b9d1ce1401 100644 (file)
@@ -117,6 +117,7 @@ static inline bool exp_is_zero(const Exp exp) {
 }
 
 ANN static inline bool not_upvalue(const Env env, const Value v) {
+  if (unlikely(is_class(env->gwion, v->type))) return true;
   return GET_FLAG(v, global) || vflag(v, vflag_fglobal) ||
       (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) ||
       nspc_lookup_value1(env->curr, insert_symbol(v->name));
index 395c737806e78525f028da08ad329690cc4ad83a..c1a7597ab2bb015020c9d45820387bd3101dd96a 100644 (file)
@@ -18,7 +18,6 @@ struct VM_Code_ {
   m_str            name;
   struct Map_      handlers;
   struct M_Vector_ live_values;
-  uint32_t wait;
   uint16_t         stack_depth;
   uint16_t         ref;
 //  bool             is_prepared;
@@ -136,7 +135,7 @@ ANN m_str code_name_set(MemPool p, const m_str, const m_str);
 ANN m_str code_name(const m_str, const bool);
 ANN uint32_t gw_rand(uint32_t s[2]);
 ANN void     gw_seed(uint32_t s[2], const uint64_t);
-ANN void     handle(VM_Shred shred, const m_str effect);
+ANN bool     handle(VM_Shred shred, const m_str effect);
 #define xfun_handle(shred, effect) {\
   shred->mem -= ((Instr)vector_at(&shred->code->instr, shred->pc-1))->m_val2; \
   handle(shred, effect); \
index 406ab71b08c07a6662d55dc944fb363a3a41de88..9ec0bad74285c9066506bceffca963ac182319db 100644 (file)
@@ -122,7 +122,7 @@ ANN /*static */ m_bool emit_cdef(const Emitter, const Type);
 ANN /*static inline*/ m_bool ensure_emit(const Emitter emit, const Type t) {
   if (tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK; // clean callers
-if(!tflag(t, tflag_tmpl))return GW_OK;
+  if(!tflag(t, tflag_tmpl))return GW_OK;
   struct EnvSet es = {.env   = emit->env,
                       .data  = emit,
                       .func  = (_exp_func)emit_cdef,
@@ -416,7 +416,7 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) {
   }
   const m_uint offset = emit_code_offset(emit);
   emit_setimm(emit, offset, SZ_INT*2);
-  emit_regmove(emit, SZ_INT * 2);
+  emit_regmove(emit, SZ_INT*2);
   const Instr prelude = emit_add_instr(emit, SetCode);
   prelude->m_val      = -SZ_INT * 2;
   prelude->udata.one  = 2;
@@ -531,11 +531,6 @@ ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) {
   return code;
 }
 
-ANN static VM_Code finalyze_func(const Emitter emit, const f_instr exec, const Func f) {
-  const VM_Code code = finalyze(emit, exec);
-  return code;
-}
-
 ANN static inline m_uint exp_size(const Exp e) {
   if (exp_getvar(e)) return SZ_INT;
   const Type type = e->cast_to ?: e->type;
@@ -928,8 +923,7 @@ ANN static m_bool decl_static(const Emitter emit, const Exp_Decl *decl,
 }
 
 ANN static inline int struct_ctor(const Value v) {
-  return tflag(v->type, tflag_struct) && v->type->nspc && v->type->nspc->pre_ctor;
-//  return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor;
+  return tflag(v->type, tflag_struct) && tflag(v->type, tflag_ctor);
 }
 
 ANN static void decl_expand(const Emitter emit, const Type t) {
@@ -952,7 +946,7 @@ ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) {
     CHECK_BB(emit_exp(emit, decl->args));
     if (emit_addr) {
       emit_regmove(emit, -t->size);
-      emit_regpushmem4(emit, 0, 0);
+      emit_regpushmem4(emit, decl->vd.value->from->offset, 0);
     }
     return GW_OK;
   }
@@ -1008,10 +1002,24 @@ static INSTR(UsedBy) {
   const MP_Vector *v =(MP_Vector*)instr->m_val;
   for(uint32_t i = 0; i < v->len; i++) {
     const Func f = *mp_vector_at(v, Func, i);
-    f->code->wait--;
+    const Instr instr = (Instr)vector_front(&f->code->instr);
+    instr->m_val2++;
   }
 }
 
+ANN static void used_by(const Emitter emit, const Value v) {
+  MP_Vector *vec = new_mp_vector(emit->gwion->mp, Func, 0);
+  for(uint32_t i = 0; i < v->used_by->len; i++) {
+    const Func f = *mp_vector_at(v->used_by, Func, i);
+    if(f->_wait) mp_vector_add(emit->gwion->mp, &vec, Func, f);
+  }
+  free_mp_vector(emit->gwion->mp, Func, v->used_by);
+  v->used_by = vec;
+  if(vec->len) {
+    const Instr instr = emit_add_instr(emit, UsedBy);
+    instr->m_val = (m_uint)vec;
+  }
+}
 ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
                                            const Exp_Decl *decl,
                                            const Var_Decl *var_decl,
@@ -1022,17 +1030,13 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
   const bool      is_obj   = isa(type, emit->gwion->type[et_object]) > 0;
   const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
   if (is_obj && !is_ref && !exp_self(decl)->ref) {
-//  if (is_obj && ((is_array && !exp_self(decl)->ref) || !is_ref))
     if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
     else CHECK_BB(emit_exp(emit, decl->args));
   }
   f_instr *exec = (f_instr *)allocmember;
   if (!emit->env->scope->depth) emit_debug(emit, v);
   if (!vflag(v, vflag_member)) {
-if(v->used_by) { // maybe later
-  const Instr instr = emit_add_instr(emit, UsedBy);
-  instr->m_val = (m_uint)v->used_by;
-}
+    if(v->used_by) used_by(emit, v);
     v->from->offset = decl_non_static_offset(emit, decl, type);
     exec            = (f_instr *)(allocword);
     if (GET_FLAG(v, late)) { // ref or emit_var ?
@@ -1052,8 +1056,8 @@ if(v->used_by) { // maybe later
       const Instr instr = emit_add_instr(emit, Reg2Reg);
       instr->m_val      = -SZ_INT;
     }
-    if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global))
-      emit_object_addref(emit, 0, emit_addr);
+//    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))
     CHECK_BB(struct_finish(emit, decl));
   return GW_OK;
@@ -1074,6 +1078,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
     v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
   emit_dotstatic(emit, (m_uint)&v->d.ptr, v->type->size, !struct_ctor(v) ? emit_addr : 1);
 //  set_vflag(v, vflag_direct); // mpalloc // set in check.c
+  if(v->used_by) used_by(emit, v);
   if (is_obj && !is_ref) {
     const Instr assign = emit_add_instr(emit, Assign);
     assign->m_val      = emit_var;
@@ -1144,8 +1149,6 @@ ANN /*static */ m_bool emit_exp_decl(const Emitter emit, Exp_Decl *const decl) {
   const Type t = decl->type;
   if(decl->args && !strncmp(decl->args->type->name, "partial:", 8))
     ERR_B(decl->args->pos, "unresolved partial");
-//  if(t->wait) exit(3);
-  if(t->wait) { puts(t->name); puts(decl->vd.value->name); /*exit(3); */}
   CHECK_BB(ensure_emit(emit, t));
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope =
@@ -1320,7 +1323,7 @@ ANN static m_bool emit_new_struct(const Emitter emit,const Exp_Call *call)  {
   else if(tflag(t, tflag_ctor))
     emit_regpushmem4(emit, offset, 0);
   if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
-  else if(!back)  {
+  else if(!back) {
     emit_regmove(emit, -SZ_INT + t->size);
     emit_regpushmem4(emit, offset, 0);
   }
@@ -2672,6 +2675,10 @@ ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot *member) {
 
 ANN static inline void emit_func_def_init(const Emitter emit, const Func func) {
   emit_push_code(emit, func->name);
+  if(mp_vector_len(func->_wait)) {
+    const Instr instr = emit_add_instr(emit, FuncWait);
+    instr->m_val = (m_uint) func;
+  }
 }
 
 ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
@@ -2699,19 +2706,16 @@ ANN static m_bool emit_func_def_return(const Emitter emit) {
 }
 
 ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
-// use wait everywhere
-  if (f->def->base->xid == insert_symbol("@dtor")) {
-    emit->env->class_def->nspc->dtor = f->code = finalyze_func(emit, DTOR_EOC, f);
-    vmcode_addref(f->code);
-    return f->code;
-  } else if (f->def->base->xid == insert_symbol("@gack")) {
+  if (f->def->base->xid == insert_symbol("@dtor"))
+    return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC);
+  else if (f->def->base->xid == insert_symbol("@gack")) {
     emit_regmove(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_func(emit, FuncReturn, f);
+    f->code                                 = finalyze(emit, FuncReturn);
     return emit->env->class_def->info->gack = f->code;
   }
-  return finalyze_func(emit, FuncReturn, f);
+  return finalyze(emit, FuncReturn);
 }
 
 ANN static inline VM_Code _emit_func_def_code(const Emitter emit,
@@ -2725,11 +2729,10 @@ ANN static inline VM_Code _emit_func_def_code(const Emitter emit,
       instr->m_val2 = t->size;
     }
   }
-//  return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
-//                                                   : emit_internal(emit, func);
-  const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze_func(emit, FuncReturn, func)
+  const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
                                                    : emit_internal(emit, func);
-  code->wait = func->wait;
+  if(is_ctor(func->def) && !emit->env->class_def->nspc->pre_ctor)
+    emit->env->class_def->nspc->pre_ctor = code;
   return code;
 }
 
@@ -2745,9 +2748,12 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
   if (fdef->base->args) emit_func_def_args(emit, fdef->base->args);
   if (fdef->d.code) {
     if(!fdef->builtin) {
-      scoped_ini(emit);
+      const bool ctor = is_ctor(fdef);
+      if(!ctor)
+        scoped_ini(emit);
       const m_bool ret = emit_stmt_list(emit, fdef->d.code);
-      scoped_end(emit);
+      if(!ctor)
+        scoped_end(emit);
       CHECK_BB(ret);
     }
     else fdef->base->func->code = (VM_Code)vector_at(&fdef->base->func->value_ref->from->owner_class->nspc->vtable, fdef->vt_index);
@@ -2850,6 +2856,8 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
   if(fdef->builtin)  {
     fdef->base->func->code = new_vmcode(emit->gwion->mp, NULL, NULL, func->name, fdef->stack_depth, true, false);
     fdef->base->func->code->native_func = (m_uint)fdef->d.dl_func_ptr;
+    if(is_ctor(fdef))
+      emit->env->class_def->nspc->pre_ctor = fdef->base->func->code;
     return GW_OK;
   }
   if ((vflag(func->value_ref, vflag_builtin) &&
@@ -2941,17 +2949,8 @@ ANN static m_bool _emit_class_def(const Emitter emit, const Class_Def cdef) {
   if (c->base.ext && t->info->parent->info->cdef &&
       !tflag(t->info->parent, tflag_emit)) // ?????
     CHECK_BB(cdef_parent(emit, c));
-  if (c->body) {
-    emit_class_code(emit, t->name);
-    const m_bool ret = scanx_body(emit->env, c, (_exp_func)emit_section, emit);
-    if (ret > 0 && tflag(t, tflag_ctor))
-      t->nspc->pre_ctor = finalyze(emit, FuncReturn);
-    else{
-      free_code(emit->gwion->mp, emit->code);
-      emit_pop_code(emit);
-    }
-    return ret;
-  }
+  if (c->body)
+    return scanx_body(emit->env, c, (_exp_func)emit_section, emit);
   return GW_OK;
 }
 
index 6e550e9d5c7d2c2b56be17f6448f227da8f3b18c..4a17896e4b1340e663e46e824c8e193a411d9c09 100644 (file)
@@ -8,6 +8,7 @@
 ANN void free_func(Func a, Gwion gwion) {
   if (fflag(a, fflag_tmpl)) func_def_cleaner(gwion, a->def);
   if (a->code) vmcode_remref(a->code, gwion);
+  if (a->_wait) free_mp_vector(gwion->mp, Value, a->_wait);
   mp_free(gwion->mp, Func, a);
 }
 
index fd1d8922263872fb0656f509da38970b806d7960..575e32a28f461b1abb372e2d152981e393a33673 100644 (file)
@@ -24,7 +24,6 @@ ANN void free_type(const Type a, struct Gwion_ *const gwion) {
   }
 //  if (tflag(a, tflag_cdef) && a->info->parent)
 //    type_remref(a->info->parent, gwion);
-  if (a->effects.ptr) vector_release(&a->effects);
   if (a->nspc) nspc_remref(a->nspc, gwion);
   if (a->info->tuple) free_tupleform(a->info->tuple, gwion);
   mp_free(gwion->mp, TypeInfo, a->info);
index f01ae9c7156f9a2dfaeecb4df705d06cc5f69861..30db071fca0d505fc4defc431284eea82e3f2ff7 100644 (file)
@@ -175,10 +175,17 @@ ANN void gwion_end(const Gwion gwion) {
 }
 
 ANN void env_error_footer(const Env env) {
-  if (env->class_def && tflag(env->class_def, tflag_cdef))
+  bool ctor = false;
+  if (env->func && env->func->def) {
+     if(!is_ctor(env->func->def))
+      gwerr_secondary("in function", env->name, env->func->def->base->pos);
+    else {
+      gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos);
+      ctor = true;
+    }
+  }
+  if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef))
     gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos);
-  if (env->func && env->func->def)
-    gwerr_secondary("in function", env->name, env->func->def->base->pos);
 }
 
 ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt,
index 47c680b78d8836cabf2d88ccf51b153440c345f1..61140ef6ee2442a3b127a8f8e9464e7d878a65b1 100644 (file)
 #include "specialid.h"
 #include "template.h"
 
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d,
-                          const enum tflag e) {
-  VM_Code *code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
-  const m_str name     = type->name;
-  *code                = new_vmcode(p, NULL, NULL, name, SZ_INT, true, false);
-  (*code)->native_func = (m_uint)d;
-  type->tflag |= e;
+ANN static m_bool mk_dtor(MemPool p, const Type t, const m_uint d) {
+  VM_Code code = t->nspc->dtor = new_vmcode(p, NULL, NULL, t->name, SZ_INT, true, false);
+  code->native_func = (m_uint)d;
+  set_tflag(t, tflag_dtor);
   return GW_OK;
 }
 
@@ -46,8 +43,16 @@ ANN2(1) void add_template(const Env env, const Type t) {
 ANN2(1)
 void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
   const Type t = gwi->gwion->env->class_def;
-  if (ctor) mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
-  if (dtor) mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
+  if (dtor) mk_dtor(gwi->gwion->mp, t, (m_uint)dtor);
+  if (ctor) {
+    gwi_func_ini(gwi, "void", "@ctor");
+    gwi_func_end(gwi, ctor, ae_flag_none);
+    if(t->nspc->vtable.ptr) {
+      set_tflag(t, tflag_ctor);
+      const Func f = (Func)vector_front(&t->nspc->vtable);
+      t->nspc->pre_ctor = f->code;
+    }
+  }
 }
 
 ANN static inline void gwi_type_flag(const Type t) {
@@ -141,11 +146,14 @@ ANN m_int gwi_class_end(const Gwi gwi) {
     --gwi->tmpls;
     nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
   }
+/*
+// we need to use @ctor
   if (gwi->effects.ptr) {
     vector_init(&t->effects);
     vector_copy2(&gwi->effects, &t->effects);
     vector_release(&gwi->effects);
   }
+*/
   env_pop(gwi->gwion->env, 0);
   return GW_OK;
 }
index ed4b4e98feb7ee3fa166aeef57f0663d2320af55..bf880f0d0b55f118cd018f368040f7dff12b52e3 100644 (file)
@@ -687,7 +687,7 @@ static OP_CHECK(opck_closure_scan) {
 }
 
 static CTOR(fptr_ctor) {
-  *(VM_Code*)o->data = ((Func)vector_front(&o->type_ref->nspc->vtable))->code;
+  *(VM_Code*)o->data = ((Func)vector_at(&o->type_ref->nspc->vtable, 1))->code;
 }
 
 ANN m_bool tmpl_fptr(const Env env, const Fptr_Def fptr, const Func_Def fdef) {
index 8418def87302c6a76326aecc6245b404168b2e99..b92a8fb24d68bea89f5214671a9ab43ef46613d9 100644 (file)
@@ -357,7 +357,7 @@ static OP_CHECK(opck_dict_remove_toop) {
   HMapInfo *const hinfo = (HMapInfo*)t->nspc->class_data;
   if(isa(args->type, hinfo->key) < 0 || args->next)
     ERR_N(e->pos, "dict.remove must be called with one Key argument");
-  return e->type = hinfo->val;
+  return e->type = env->gwion->type[et_void];
 }
 
 ANN static m_bool emit_dict_iter(const Emitter emit, const HMapInfo *hinfo,
@@ -640,6 +640,7 @@ static OP_CHECK(opck_dict_scan) {
   const Type   t   = cdef->base.type;
   t->nspc->class_data_size = sizeof(struct HMapInfo);
   const m_bool ret = traverse_cdef(env, t);
+    set_tflag(t, tflag_cdef);
   if(is_global) {
     env_pop(env, scope);
     type_addref(t);
@@ -659,7 +660,7 @@ static OP_CHECK(opck_dict_scan) {
   add_op(env->gwion, &opi);
 
   {
-  const Func             f      = (Func)vector_front(&t->nspc->vtable);
+  const Func             f      = (Func)vector_at(&t->nspc->vtable, 1);
   const struct Op_Func   opfunc = {.ck = opck_dict_remove_toop};
   const struct Op_Import opi    = {
       .rhs  = f->value_ref->type,
@@ -669,7 +670,6 @@ static OP_CHECK(opck_dict_scan) {
   CHECK_BN(add_op(env->gwion, &opi));
 
   }
-
   return ret > 0 ? t : NULL;
 }
 
@@ -679,7 +679,7 @@ GWION_IMPORT(dict) {
   t_dict->nspc->offset += sizeof(struct HMap);
   gwi->gwion->type[et_dict] = t_dict;
   set_tflag(t_dict, tflag_infer);
-  GWI_BB(gwi_func_ini(gwi, "bool",   "remove"));
+  GWI_BB(gwi_func_ini(gwi, "void",   "remove"));
   GWI_BB(gwi_func_arg(gwi, "Key",    "key"));
   GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none));
 
index 2cea5b4b366844ea47b764d129d499199c331b4b..97162dd95a7283be8699cbfebce5a758be3406e0 100644 (file)
@@ -141,6 +141,21 @@ INSTR(SetCtor) {
   VAL2 = SZ_INT;
 }
 
+INSTR(FuncWait) {
+  const Func f = (Func)instr->m_val;
+  if(f->_wait->len - instr->m_val2) {
+    if(!handle(shred, "UninitValue")) {
+      gw_err("{-}some values are not instantiated yet{0}\n");
+      for(uint32_t i = instr->m_val2; i < f->_wait->len; i++) {
+        Value v = *mp_vector_at(f->_wait, Value, i);
+        defined_here(v);
+      }
+    }
+  } else {
+    BYTE(eNoOp);
+  }
+}
+
 INSTR(fast_except) {
   struct FastExceptInfo *info = (struct FastExceptInfo *)instr->m_val2;
   if(*(m_uint*)REG(-SZ_INT)) {
index 0570dd83e1e97666d10874d91e654eaa1473ab23..77cb458e888d6e5cdaaace0a9bc56b97dbb3b99f 100644 (file)
@@ -121,7 +121,7 @@ static ID_EMIT(opem_this) {
 
 static ID_CHECK(opck_super) {
   const Exp self = exp_self(prim);
-  if(!env->func)
+  if(!env->func || is_ctor(env->func->def))
     ERR_O(self->pos, "can't use 'super' outside of constructor");
   const Type parent = env->class_def->info->parent;
   DECL_OO(const Value, v, = find_value(parent, insert_symbol("new")));
index 90c76eda6d17b828cedf558bfa8183152be3d318..e34c31ecf3d9bdb798de0bb043a0e9ac5cd9d4f0 100644 (file)
@@ -83,14 +83,22 @@ ANN static m_uint get_decl_size(const Env env, const Value v) {
 describe_check_decl(member, offset, v->vflag |= vflag_member);
 describe_check_decl(static, class_data_size, SET_FLAG(v, static));
 
+ANN static void var_effects(const Env env, const Type t, const Symbol sym, const loc_t loc) {
+  if (t->info->parent) var_effects(env, t->info->parent, sym, loc);
+  if(!tflag(t, tflag_ctor)) return;
+  const Value ctor = nspc_lookup_value0(t->nspc, sym);
+  if(!ctor) return; // bit sus
+  const Func f = ctor->d.func_ref;
+  const Vector v = &f->def->base->effects;
+  if(!v->ptr) return;
+  for (m_uint i = 0; i < vector_size(v); i++)
+    env_add_effect(env, (Symbol)vector_at(v, i), loc);
+}
+
 ANN static m_bool check_var(const Env env, const Var_Decl *var) {
   if (env->class_def && !env->scope->depth && env->class_def->info->parent)
     CHECK_BB(check_exp_decl_parent(env, var));
-  if (var->value->type->effects.ptr) {
-    const Vector v = &var->value->type->effects;
-    for (m_uint i = 0; i < vector_size(v); i++)
-      env_add_effect(env, (Symbol)vector_at(v, i), var->pos);
-  }
+  var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos);
   return GW_OK;
 }
 
@@ -308,8 +316,6 @@ ANN static Value check_non_res_value(const Env env, const Symbol *data) {
       if(value->from->owner_class)
       CHECK_BO(not_from_owner_class(env,
         env->class_def, value, prim_pos(data)));
-      else if(safe_vflag(value, vflag_fglobal) && !env->scope->depth)
-        env->class_def->wait++;
     }
     const Value v = value ?: find_value(env->class_def, var);
     if (v) {
@@ -394,11 +400,14 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1);
 
   if (env->func && strcmp(env->func->name, "in spork")) {
-    if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
+//    if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
+    if((GET_FLAG(v, global) || vflag(v, vflag_fglobal)) && !vflag(v, vflag_builtin) && !is_func(env->gwion, v->type)) {
+      if(!env->func->_wait)
+        env->func->_wait = new_mp_vector(env->gwion->mp, Value, 0);
       if (!v->used_by) {
         v->used_by = new_mp_vector(env->gwion->mp, Func, 1);
         mp_vector_set(v->used_by, Func, 0, env->func);
-        env->func->wait++;
+        mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
       } else {
         bool found = false;
         for(uint32_t i = 0; i < v->used_by->len; i++) {
@@ -409,8 +418,8 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
           }
         }
         if(!found) {
-          env->func->wait++;
           mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func);
+          mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
         }
       }
     }
@@ -1812,14 +1821,6 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef,
   return GW_OK;
 }
 
-ANN static bool effect_find(const MP_Vector *v, const Symbol sym) {
-  for(m_uint i = 0; i < v->len; i++) {
-    struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
-    if(eff->sym == sym) return true;
-  }
-  return false;
-}
-
 ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
   MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
   if (v) {
@@ -1829,7 +1830,7 @@ ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
     if (!base->ptr) vector_init(base);
     for (uint32_t i = 0; i < v->len; i++) {
       struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
-      if(!effect_find(v, eff->sym))
+      if(vector_find(base, (m_uint)eff->sym) == -1)
         vector_add(base, (m_uint)eff->sym);
     }
     free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
@@ -1841,11 +1842,16 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
   if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args));
   if(fdef->builtin) return GW_OK;
   if (fdef->d.code && fdef->d.code) {
-    env->scope->depth++;
-    nspc_push_value(env->gwion->mp, env->curr);
+    const bool ctor = is_ctor(fdef);
+    if(!ctor) {
+      env->scope->depth++;
+      nspc_push_value(env->gwion->mp, env->curr);
+    }
     const m_bool ret = check_stmt_list(env, fdef->d.code);
-    nspc_pop_value(env->gwion->mp, env->curr);
-    env->scope->depth--;
+    if(!ctor) {
+      nspc_pop_value(env->gwion->mp, env->curr);
+      env->scope->depth--;
+    }
     CHECK_BB(check_fdef_effects(env, fdef));
     return ret;
   }
@@ -2033,7 +2039,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
   }
   return !err ? GW_OK : GW_ERROR;
 }
-
+/*
 ANN static inline void ctor_effects(const Env env) {
   const Vector v  = &env->scope->effects;
   MP_Vector *const w = (MP_Vector*)vector_back(v);
@@ -2046,33 +2052,32 @@ ANN static inline void ctor_effects(const Env env) {
   free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
   vector_pop(v);
 }
-
+*/
 ANN static m_bool check_body(const Env env, Section *const section) {
   const m_bool ret = check_section(env, section);
-  ctor_effects(env);
+//  ctor_effects(env);
   return ret;
 }
 
 ANN static bool class_def_has_body(Ast ast) {
-  for(m_uint i = 0; i < ast->len; i++) {
-    const Section *section = mp_vector_at(ast, Section, i);
-    if (section->section_type == ae_section_stmt) {
-      Stmt_List l = section->d.stmt_list;
-      for(m_uint i = 0; i < l->len; i++) {
-        const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
-        if (stmt->stmt_type == ae_stmt_pp) continue;
-        if (stmt->stmt_type == ae_stmt_exp) {
-          const Exp exp = stmt->d.stmt_exp.val;
-          if (!exp) continue;
-          if (exp->exp_type != ae_exp_decl) return true;
-          if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
-          Var_Decl vd = exp->d.exp_decl.vd;
-          if (GET_FLAG(vd.value, late)) continue;
-          if (tflag(vd.value->type, tflag_compound))
-              return true;
-        } else return true;
-      }
-    }
+  const Section *section = mp_vector_at(ast, Section, 0);
+  if(section->section_type != ae_section_func) return false;
+  Func_Def f = section->d.func_def;
+  if(strcmp(s_name(f->base->xid), "@ctor"))return false;
+  Stmt_List l = f->d.code;
+  for(m_uint i = 0; i < l->len; i++) {
+    const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
+    if (stmt->stmt_type == ae_stmt_pp) continue;
+    if (stmt->stmt_type == ae_stmt_exp) {
+      const Exp exp = stmt->d.stmt_exp.val;
+      if (!exp) continue;
+      if (exp->exp_type != ae_exp_decl) return true;
+      if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
+      Var_Decl vd = exp->d.exp_decl.vd;
+      if (GET_FLAG(vd.value, late)) continue;
+      if (tflag(vd.value->type, tflag_compound))
+        return true;
+    } else return true;
   }
   return false;
 }
@@ -2160,6 +2165,7 @@ ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
   if (cdef->body) {
     CHECK_BB(env_body(env, cdef, check_body));
     if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body))
+//    if (class_def_has_body(cdef->body))
       set_tflag(t, tflag_ctor);
   }
   if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
index 4f6602ffd83f99b6733158c441cd17a2b509c9a5..c871bbd41aca1bfbbdae6a59187a5f2a783b9f7b 100644 (file)
@@ -5,6 +5,10 @@
 #include "traverse.h"
 #include "template.h"
 #include "parse.h"
+#include "object.h"
+#include "operator.h"
+#include "instr.h"
+#include "import.h"
 
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
@@ -133,7 +137,9 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
           env->class_def->size += t->size;
         }
       }
-    } else if(env->context)
+    } else if (GET_FLAG(decl->td, global))
+      SET_FLAG(v, global);
+    else if(env->context)
       set_vflag(v, vflag_fglobal); // file global
   } else if (GET_FLAG(decl->td, global))
     SET_FLAG(v, global);
@@ -317,7 +323,12 @@ ANN static inline m_bool shadow_arg(const Env env, const Symbol sym,
   Nspc nspc = env->curr;
   do {
     const Value v = nspc_lookup_value0(nspc, sym);
-    if (v && !env->func->def->builtin) return shadow_err(env, v, loc);
+    if (v && !env->func->def->builtin) {
+      const Type owner = v->from->owner_class;
+      if (owner && env->class_def && isa(env->class_def, owner) < 0)
+        continue;
+      return shadow_err(env, v, loc);
+    }
   } while ((nspc = nspc->parent));
   return GW_OK;
 }
@@ -644,7 +655,10 @@ ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
     CHECK_BB(scan_internal(env, fdef->base));
   else if (fbflag(fdef->base, fbflag_op) && env->class_def)
     SET_FLAG(fdef->base, static);
-  RET_NSPC(scan1_fbody(env, fdef))
+  if(!is_ctor(fdef)) {
+    RET_NSPC(scan1_fbody(env, fdef))
+  } else if(!fdef->builtin)
+      CHECK_BB(scan1_stmt_list(env, fdef->d.code));
   return GW_OK;
 }
 
@@ -742,6 +756,34 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
+ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
+  if(!tmpl_base(cdef->base.tmpl) && isa(cdef->base.type, env->gwion->type[et_closure]) < 0 &&
+   isa(cdef->base.type, env->gwion->type[et_dict]) < 0) {
+    MemPool mp = env->gwion->mp;
+    Ast base = cdef->body;
+    Stmt_List ctor = new_mp_vector(mp, struct Stmt_, 0);
+    Ast body = new_mp_vector(mp, Section, 1); // room for ctor
+    for(uint32_t i = 0; i < base->len; i++) {
+      Section section = *mp_vector_at(base, Section, i);
+      if(section.section_type == ae_section_stmt) {
+        Stmt_List list = section.d.stmt_list;
+        for(uint32_t j = 0; j < list->len; j++) {
+          Stmt stmt = mp_vector_at(list, struct Stmt_, j);
+          mp_vector_add(mp, &ctor, struct Stmt_, *stmt);
+        }
+      } else mp_vector_add(mp, &body, Section, section);
+    }
+    Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos);
+    Symbol sym = insert_symbol("@ctor");
+    Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos);
+    Func_Def  fdef = new_func_def(mp, fb, ctor);
+    mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
+    free_mp_vector(mp, Section, base);
+    cdef->body = body;
+  }
+  return env_body(env, cdef, scan1_section);
+}
+
 ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
   const Type      t = cdef->base.type;
@@ -749,7 +791,7 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   set_tflag(t, tflag_scan1);
   const Class_Def c = t->info->cdef;
   if (c->base.ext) CHECK_BB(cdef_parent(env, c));
-  if (c->body) CHECK_BB(env_body(env, c, scan1_section));
+  if (c->body) CHECK_BB(scan1_class_def_body(env, c));
   return GW_OK;
 }
 
index c6ea9a051fd2f003054b11dfa2e7f3ad08036383..057bb9f2f5b1a66ab1d0be545fad33c4364438b6 100644 (file)
@@ -414,11 +414,16 @@ ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
 ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
   const Func former = env->func;
   env->func         = f->base->func;
-  env->scope->depth++;
-  nspc_push_value(env->gwion->mp, env->curr);
+  const bool ctor = is_ctor(f);
+  if(!ctor) {
+    env->scope->depth++;
+    nspc_push_value(env->gwion->mp, env->curr);
+  }
   const m_bool ret = scan2_stmt_list(env, f->d.code); // scope depth?
-  nspc_pop_value(env->gwion->mp, env->curr);
-  env->scope->depth--;
+  if(!ctor) {
+    nspc_pop_value(env->gwion->mp, env->curr);
+    env->scope->depth--;
+  }
   env->func = former;
   return ret;
 }
index 4433b4131bfd15621501579dcaea20ff77cef07a..df8c917a2ee6e689dba57114dbc47df7c1340768 100644 (file)
@@ -156,7 +156,7 @@ ANN static inline void handle_fail(VM_Shred shred, const m_str effect, const str
   shreduler_remove(shred->tick->shreduler, shred, true);
 }
 
-ANN void handle(VM_Shred shred, const m_str effect) {
+ANN bool handle(VM_Shred shred, const m_str effect) {
   shreduler_remove(shred->tick->shreduler, shred, false);
   // store trace info
   struct TraceStart ts = {
@@ -167,8 +167,11 @@ ANN void handle(VM_Shred shred, const m_str effect) {
   const m_uint size =
       shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0;
   // maybe we should use a string to avoid the insert_symbol call
-  if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size))
+  if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size)) {
     handle_fail(shred, effect, &ts);
+    return false;
+  }
+  return true;
 }
 
 ANN bool vm_remove(const VM *vm, const m_uint index) {
@@ -1567,7 +1570,7 @@ _other:
   const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2);
   if(exec == DTOR_EOC)return;
   const Instr instr = *(Instr*)(prepare_code + SZ_INT);
-  if(exec == fast_except)
+  if(exec == fast_except || exec == FuncWait)
     instr->opcode = (m_uint)&&noop;
   else if(exec == SetFunc)
     instr->opcode = (m_uint)&&regpushimm;
diff --git a/util b/util
index 8b2644578a7489ef9c8d87cd19a6326fb775fd3f..4588df17c998d18e8db40ce1391a714cd893b469 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 8b2644578a7489ef9c8d87cd19a6326fb775fd3f
+Subproject commit 4588df17c998d18e8db40ce1391a714cd893b469