From 6b8c82c8d5018a3bda411ef2dbbe0ef3160c98de Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 3 Dec 2022 18:50:32 +0100 Subject: [PATCH] :bug: Fix struct_addref in vm --- include/env/envset.h | 7 ++++++- src/lib/closure.c | 10 ++++++++++ src/lib/event.c | 2 +- src/lib/object_op.c | 13 ++++++++++++- src/parse/check.c | 9 +++++++-- src/parse/func_resolve_tmpl.c | 16 ++++++++++------ src/parse/scan0.c | 8 ++++++-- src/parse/scan2.c | 3 +++ src/parse/template.c | 2 +- src/vm/vm.c | 4 ++-- 10 files changed, 58 insertions(+), 16 deletions(-) diff --git a/include/env/envset.h b/include/env/envset.h index 3bec88e0..ab754b21 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -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 diff --git a/src/lib/closure.c b/src/lib/closure.c index 70f65ec0..53b4d124 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -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); diff --git a/src/lib/event.c b/src/lib/event.c index c21d3b9d..2dbab34b 100644 --- a/src/lib/event.c +++ b/src/lib/event.c @@ -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); diff --git a/src/lib/object_op.c b/src/lib/object_op.c index e46d8a23..ef918974 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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) diff --git a/src/parse/check.c b/src/parse/check.c index 82e43087..9c043805 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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; } diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index 21ecaa49..97daeab2 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -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}; diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 26f94601..4b0f45ae 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 302a0625..00bb17d1 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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; } diff --git a/src/parse/template.c b/src/parse/template.c index def9181e..fbca7972 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -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); diff --git a/src/vm/vm.c b/src/vm/vm.c index 7f79eb7b..773c852e 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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); -- 2.43.0