]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix struct_addref in vm
authorfennecdjay <fennecdjay@gmail.com>
Sat, 3 Dec 2022 17:50:32 +0000 (18:50 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Sat, 3 Dec 2022 17:50:32 +0000 (18:50 +0100)
include/env/envset.h
src/lib/closure.c
src/lib/event.c
src/lib/object_op.c
src/parse/check.c
src/parse/func_resolve_tmpl.c
src/parse/scan0.c
src/parse/scan2.c
src/parse/template.c
src/vm/vm.c

index 3bec88e014898a7bfdab389a9cb7aa2e04aba950..ab754b21b9dfe855b42113de9da49cac09fd9d46 100644 (file)
@@ -16,7 +16,12 @@ struct EnvSet {
 ANN m_bool envset_run(struct EnvSet *, const Type);
 ANN2(1, 3) m_bool envset_push(struct EnvSet *, const Type, const Nspc);
 ANN static inline m_bool envset_pushv(struct EnvSet *es, const Value v) {
-  return envset_push(es, v->from->owner_class, v->from->owner);
+//  es->_ctx         = es->env->context;
+//  es->_filename    = es->env->name;
+  CHECK_BB(envset_push(es, v->from->owner_class, v->from->owner));
+//  es->env->context = v->from->ctx;
+//  es->env->name    = v->from->filename;
+  return GW_OK;
 }
 ANN2(1) void envset_pop(struct EnvSet *, const Type);
 #endif
index 70f65ec0a2cd8281f17ef9f24fef082757f08afe..53b4d1241159ceaa715fc8a3eaf52db25cd5d4e4 100644 (file)
@@ -690,6 +690,16 @@ static CTOR(fptr_ctor) {
   *(VM_Code*)o->data = ((Func)vector_front(&o->type_ref->nspc->vtable))->code;
 }
 
+ANN m_bool tmpl_fptr(const Env env, const Fptr_Def fptr, const Func_Def fdef) {
+  fptr->cdef->base.type->nspc->offset += SZ_INT * 3;
+  env_push_type(env, fptr->cdef->base.type);
+  CHECK_BB(traverse_func_def(env, fdef));
+  builtin_func(env->gwion, fdef->base->func, fptr_ctor);
+  set_tflag(fdef->base->func->value_ref->type, tflag_ftmpl);
+  env_pop(env, 0);
+  return GW_OK;
+}
+
 static DTOR(fptr_dtor) {
   m_bit *const caps = *(m_bit**)(o->data + SZ_INT);
   if(caps) free_captures(shred, caps);
index c21d3b9d7ade819218752665f870816bbb0d2474..2dbab34b996674223e53153424c646f4cfc05983 100644 (file)
@@ -32,7 +32,7 @@ static INSTR(EventWait) {
 static MFUN(event_signal) {
   const Vector   v  = &EV_SHREDS(o);
   if(!vector_size(v)) return;
-  const VM_Shred sh = vector_front(v);
+  const VM_Shred sh = (VM_Shred)vector_front(v);
   shredule(sh->tick->shreduler, sh, GWION_EPSILON);
   vector_rem(v, 0);
   release(sh->info->me, sh);
index e46d8a23f6104c0bd95d3690f3346f980426c9c6..ef91897475d36c82d9056cd87ac66f8389dcd6e6 100644 (file)
@@ -140,7 +140,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) {
     }
   } else if (is_static_call(emit->gwion, exp_self(member))) {
     if (member->is_call && f == emit->env->func && !is_new(f->def)) return;
-    if(!member->is_call) emit_regmove(emit, SZ_INT);
+    if(!member->is_call && vflag(f->value_ref, vflag_member)) emit_regmove(emit, -SZ_INT);
     return emit_pushfunc(emit, f);
   } else {
     if (tflag(member->base->type, tflag_struct))
@@ -203,6 +203,11 @@ OP_CHECK(opck_object_dot) {
   if (member->xid == insert_symbol(env->gwion->st, "this") && base_static)
     ERR_N(exp_self(member)->pos,
           _("keyword 'this' must be associated with object instance..."));
+//  if (member->base->exp_type == ae_exp_decl) {
+//puts(env->name);
+//return env->gwion->type[et_error];
+//    exit(12);
+//  }
   const Value value = get_value(env, member, the_base);
   if (!value) {
     const Value v = nspc_lookup_value1(env->curr, member->xid);
@@ -212,6 +217,12 @@ OP_CHECK(opck_object_dot) {
           return v->type;
         if (is_class(env->gwion, v->type)) {
           DECL_OO(const Type, parent, = class_type(env, member, v->type));
+          if (the_base == parent) {
+            const Symbol sym = insert_symbol(env->gwion->st, "new");
+            const Value ret = nspc_lookup_value1(parent->nspc, sym);
+            member->xid = sym;
+            if(ret) return ret->type;
+          }
           if (the_base->info->parent == parent && parent->nspc) {
             const Symbol sym = insert_symbol(env->gwion->st, "new");
             if(!env->func || env->func->def->base->xid != sym)
index 82e43087afb27d726d437629b000beda5d277e78..9c0438050f2fe4d43c72b043546d80719fb5b0d9 100644 (file)
@@ -349,6 +349,8 @@ ANN static m_bool check_upvalue(const Env env, const Exp_Primary *prim, const Va
 ANN static Type prim_owned(const Env env, const Symbol *data) {
   const Exp   exp  = exp_self(prim_exp(data));
   const Value v    = exp->d.prim.value;
+  if(is_class(env->gwion, v->type) && env->class_def == v->type->info->base_type) // write it better
+    return v->type->info->base_type;
   const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
   const Exp   base =
       new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data));
@@ -1823,8 +1825,11 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
 }
 
 ANN static m_bool check_ctor(const Env env, const Func func) {
-  if(!GET_FLAG(func, const) && nspc_lookup_value0(env->class_def->info->parent->nspc, insert_symbol("new")) && !GET_FLAG(func, const))
-    ERR_B(func->def->base->pos, "missing call to parent constructor");
+  if(!func->def->builtin && !GET_FLAG(func, const)) {
+    const Value v = nspc_lookup_value0(env->class_def->info->parent->nspc, insert_symbol("new"));
+    if(v && !GET_FLAG(v, abstract))
+      ERR_B(func->def->base->pos, "missing call to parent constructor");
+  }
   return GW_OK;
 }
 
index 21ecaa4935765af6f28c1a89e34663af735885d8..97daeab2e91a24dbb907f7f4e375dd2cfae1d990 100644 (file)
@@ -43,31 +43,35 @@ tmpl_valid(const Env env, const Func_Def fdef, const m_str filename) {
 ANN static Func ensure_tmpl(const Env env, const Func_Def fdef,
                             Exp_Call *const exp, const m_str filename) {
   if (!tmpl_valid(env, fdef, filename)) return NULL;
+  if(env->context && env->context->error) return NULL;
   if (exp->args && !exp->args->type) return NULL;
   const Func f    = fdef->base->func;
   const Tmpl tmpl = {.list = fdef->base->tmpl->list, .call = exp->tmpl->call};
   CHECK_BO(template_push_types(env, &tmpl));
   const Func func = find_func_match(env, f, exp);
   nspc_pop_type(env->gwion->mp, env->curr);
-  if (func) {
-    set_fflag(func, fflag_tmpl | fflag_valid);
+  if (func)
     call_add_effect(env, func, exp->func->pos);
-  }
   return func;
 }
 
 ANN static inline Func ensure_fptr(const Env env, struct ResolverArgs *ra,
                                    const Fptr_Def fptr) {
   CHECK_BO(traverse_fptr_def(env, fptr));
-  return find_func_match(env, fptr->base->func, ra->e);
+  const Func_Def fdef = mp_vector_at(fptr->cdef->base.type->info->cdef->body, struct Section_ , 0)->d.func_def;
+  return find_func_match(env, fdef->base->func, ra->e);
 }
 
 ANN static Func fptr_match(const Env env, struct ResolverArgs *ra) {
   const Value  v = ra->v;
   const Symbol sym =
       func_symbol(env, v->from->owner->name, v->name, ra->tmpl_name, 0);
-  const Type exists = nspc_lookup_type0(v->from->owner, sym);
-  if (exists) return exists->info->func;
+  const Value exists = nspc_lookup_value0(v->from->owner, sym);
+  if(exists) {
+    const Type t = actual_type(env->gwion, exists->type);
+    const Func_Def fdef = mp_vector_at(t->info->cdef->body, struct Section_ , 0)->d.func_def;
+    return find_func_match(env, fdef->base->func, ra->e);
+  }
   const Func_Def base =
       v->d.func_ref ? v->d.func_ref->def : ra->e->func->type->info->func->def;
   const Tmpl tmpl = {.list = base->base->tmpl->list, .call = ra->types};
index 26f94601242b25c85c915760f534810ac06dc3b0..4b0f45aeae8920f63c7b5d9f686446a71de2c337 100644 (file)
@@ -66,10 +66,14 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
   Type_Decl* td = new_type_decl(env->gwion->mp, insert_symbol(env->gwion->type[et_closure]->name), loc);
   const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->xid, td, body, loc);
-  if(GET_FLAG(fptr->base, global)) SET_FLAG(cdef, global);
+  if(GET_FLAG(fptr->base, global)) {
+    SET_FLAG(cdef, global);
+    UNSET_FLAG(fptr->base, global);
+  }
   if(fptr->base->tmpl) {
     fbase->tmpl = cpy_tmpl(env->gwion->mp, fptr->base->tmpl);
-    cdef->base.tmpl = cpy_tmpl(env->gwion->mp, fptr->base->tmpl);
+    if(!fptr->base->tmpl->call)
+      cdef->base.tmpl = cpy_tmpl(env->gwion->mp, fptr->base->tmpl);
   }
   fptr->cdef = cdef;
   return scan0_class_def(env, cdef);
index 302a06250fd26b5bfe2864167d084419cf08d549..00bb17d131ecba89b98060cdd5c3937039f305e2 100644 (file)
@@ -12,6 +12,7 @@
 #include "import.h"
 #include "default_args.h"
 #include "spread.h"
+#include "closure.h"
 
 ANN static m_bool scan2_stmt(const Env, const Stmt);
 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
@@ -80,6 +81,7 @@ ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
   const m_bool ret = scan2_class_def(env, fptr->cdef);
   const Func_Def fdef = mp_vector_at(fptr->cdef->base.type->info->cdef->body, struct Section_ , 0)->d.func_def;
   if(fdef->base->func) set_fflag(fdef->base->func, fflag_fptr);
+  else CHECK_BB(tmpl_fptr(env, fptr, fdef));
   if(GET_FLAG(fptr->cdef, global)) env_pop(env, 0);
   return ret;
 }
@@ -513,6 +515,7 @@ m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
     if (fbflag(f->base, fbflag_op)) CHECK_BB(scan2_func_def_op(env, f));
     set_vflag(f->base->func->value_ref, vflag_valid);
   }
+  if (f->base->tmpl) set_fflag(f->base->func, fflag_tmpl);
   return GW_OK;
 }
 
index def9181e773e16f9d8395a06ca0bbe7e94bf1bcd..fbca7972bf8921339f3db85a4ada99272519c181 100644 (file)
@@ -205,7 +205,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl *td) {
                         .data  = env,
                         .scope = env->scope->depth,
                         .flag  = tflag_none};
-    envset_push(&es, owner, owner->nspc);
+    envset_pushv(&es, owner->info->value);
     (void)env_push(env, owner, owner->nspc); // TODO: is this needed?
     const Type ret = known_type(env, td->next);
     env_pop(env, es.scope);
index 7f79eb7bb3776d2b0db8b1ec54f4831cb67ab823..773c852eaa78084b98a4ea0dfda19d856032676a 100644 (file)
@@ -1063,10 +1063,10 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
     }
       DISPATCH()
     structaddref:
-      struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + IVAL));
+      struct_addref(vm->gwion, (Type)VAL2, (reg + IVAL));
       DISPATCH()
     structaddrefaddr:
-      struct_addref(vm->gwion, (Type)VAL2, **(m_bit ***)(reg + IVAL));
+      struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + IVAL));
       DISPATCH()
     objassign : {
       const M_Object o = **(M_Object **)(reg - SZ_INT);