From ec01b6ed6e57f62dc99ab4b3ebb2f7820a54d49c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Mon, 9 May 2022 14:04:37 +0200 Subject: [PATCH] :art: Improve vm cleaning and fptr type check --- include/vm.h | 1 + src/emit/emit.c | 25 ++++++++++++------------- src/gwion.c | 14 +++----------- src/parse/check.c | 14 +++++++++----- src/plug.c | 12 ++++++------ src/vm/vm.c | 15 ++++++++++++++- 6 files changed, 45 insertions(+), 36 deletions(-) diff --git a/include/vm.h b/include/vm.h index 0ce89d89..deca0f85 100644 --- a/include/vm.h +++ b/include/vm.h @@ -110,6 +110,7 @@ __attribute__((hot)) ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->tick->shreduler, shred, true); } +ANN void vm_clean(const VM* vm, const Gwion gwion); void free_vm_shred(const VM_Shred shred) __attribute__((hot, nonnull)); void vm_prepare(const VM *vm, m_bit*) __attribute__((hot)); diff --git a/src/emit/emit.c b/src/emit/emit.c index 2fa8c504..fcf0a2ad 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1277,13 +1277,13 @@ ANN static inline void inline_args_ini(const Emitter emit, const Func f, if(member) emit->this_offset = emit_local(emit, emit->gwion->type[et_int]); const m_uint start_offset = emit_code_offset(emit) - (member ? SZ_INT : 0); - Arg_List arg = f->def->base->args; - while (arg) { - const Value value = arg->var_decl->value; + Arg_List args = f->def->base->args; + for(uint32_t i = 0; i < args->len; i++) { + const Arg *arg = mp_vector_at(args, Arg, i); + const Value value = arg->var_decl.value; vector_add(v, value->from->offset); value->from->offset = emit_local(emit, value->type); - nspc_add_value(emit->env->curr, arg->var_decl->xid, value); - arg = arg->next; + nspc_add_value(emit->env->curr, arg->var_decl.xid, value); } if (fbflag(f->def->base, fbflag_variadic)) emit->vararg_offset = emit_local(emit, emit->gwion->type[et_int]) + SZ_INT; @@ -1294,12 +1294,11 @@ ANN static inline void inline_args_ini(const Emitter emit, const Func f, } ANN static inline void inline_args_end(const Func f, const Vector v) { - Arg_List arg = f->def->base->args; - m_uint i = 0; - while (arg) { - const Value value = arg->var_decl->value; + Arg_List args = f->def->base->args; + for(uint32_t i = 0; i < args->len; i++) { + const Arg *arg = mp_vector_at(args, Arg, i); + const Value value = arg->var_decl.value; value->from->offset = vector_at(v, i++); - arg = arg->next; } } @@ -1346,9 +1345,9 @@ ANN static inline m_bool emit_inline(const Emitter emit, const Func f, return ret; } #endif + ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { -/* - #ifndef GWION_NOINLINE + #ifdef GWION_INLINE const Func _f = is_inlinable(emit, exp_call); if(_f) { const Func base = emit->env->func; @@ -1360,7 +1359,7 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { return ret; } #endif -*/ + // skip when recursing const Type t = actual_type(emit->gwion, exp_call->func->type); const Func f = t->info->func; diff --git a/src/gwion.c b/src/gwion.c index 7de93762..3342f657 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -157,22 +157,14 @@ ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) { if (gwion->data->child2.ptr) fork_clean2(shred, &gwion->data->child2); } -ANN static inline void free_killed_shred(const Vector v) { - for (m_uint i = 0; i < vector_size(v); i++) { - const VM_Shred shred = (VM_Shred)vector_at(v, i); - free_vm_shred(shred); - } -} - ANN void gwion_end(const Gwion gwion) { - free_killed_shred(&gwion->vm->shreduler->killed_shreds); - gwion_end_child(gwion->vm->cleaner_shred, gwion); + VM *vm = gwion->vm; + vm_clean(vm, gwion); release_ctx(gwion->env->scope, gwion); if (gwion->data->plugs) free_plug(gwion); free_env(gwion->env); - if (gwion->vm->cleaner_shred) free_vm_shred(gwion->vm->cleaner_shred); free_emitter(gwion->mp, gwion->emit); - free_vm(gwion->vm); + free_vm(vm); pparg_end(gwion->ppa); mp_free(gwion->mp, PPArg, gwion->ppa); free_gwiondata(gwion); diff --git a/src/parse/check.c b/src/parse/check.c index 8c592cd2..788f39a7 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -813,10 +813,12 @@ ANN m_bool func_check(const Env env, Exp_Call *const exp) { ERR_B(exp->func->pos, _("Can't call late function pointer at declaration " "site. did you meant to use `@=>`?")) const Type t = actual_type(env->gwion, exp->func->type); - if (is_func(env->gwion, t) && exp->func->exp_type == ae_exp_dot && - !t->info->value->from->owner_class) { - if (exp->args) CHECK_OB(check_exp(env, exp->args)); - return call2ufcs(env, exp, t->info->func->value_ref) ? GW_OK : GW_ERROR; + if(!is_fptr(env->gwion, t)) { + if (is_func(env->gwion, t) && exp->func->exp_type == ae_exp_dot && + !t->info->value->from->owner_class) { + if (exp->args) CHECK_OB(check_exp(env, exp->args)); + return call2ufcs(env, exp, t->info->func->value_ref) ? GW_OK : GW_ERROR; + } } const Exp e = exp_self(exp); struct Op_Import opi = {.op = insert_symbol("@func_check"), @@ -850,8 +852,10 @@ ANN Type check_exp_call1(const Env env, Exp_Call *const exp) { const Type t = op_check(env, &opi); return t; } - if (_class) // need an instance + if (_class) { + // need an instance ERR_O(exp->func->pos, "can't call a function pointer type"); + } if (t == env->gwion->type[et_op]) return check_op_call(env, exp); if (t == env->gwion->type[et_lambda]) // TODO: effects? return check_lambda_call(env, exp); diff --git a/src/plug.c b/src/plug.c index 9fadddc5..96a1855e 100644 --- a/src/plug.c +++ b/src/plug.c @@ -90,6 +90,12 @@ ANN m_bool plug_ini(const struct Gwion_ *gwion, const Vector list) { } void free_plug(const Gwion gwion) { + const Vector vec = &gwion->data->plugs->vec; + for (m_uint i = vector_size(vec) + 1; --i;) { + const Nspc nspc = (Nspc)vector_at(vec, i-1); + nspc_remref(nspc, gwion); + } + vector_release(&gwion->data->plugs->vec); const Map map = &gwion->data->plugs->map; for (m_uint i = 0; i < map_size(map); ++i) { const Plug plug = (Plug)VVAL(map, i); @@ -99,12 +105,6 @@ void free_plug(const Gwion gwion) { DLCLOSE(plug->dl); } map_release(map); - const Vector vec = &gwion->data->plugs->vec; - for (m_uint i = vector_size(vec) + 1; --i;) { - const Nspc nspc = (Nspc)vector_at(vec, i-1); - nspc_remref(nspc, gwion); - } - vector_release(&gwion->data->plugs->vec); mp_free2(gwion->mp, sizeof(Plugs), gwion->data->plugs); } diff --git a/src/vm/vm.c b/src/vm/vm.c index 26bd184c..2f8e4178 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -1606,10 +1606,23 @@ VM *new_vm(MemPool p, const bool audio) { return vm; } +ANN static inline void free_killed_shred(const Vector v) { + for (m_uint i = 0; i < vector_size(v); i++) { + const VM_Shred shred = (VM_Shred)vector_at(v, i); + free_vm_shred(shred); + } +} + +ANN void vm_clean(const VM* vm, const Gwion gwion) { + free_killed_shred(&vm->shreduler->killed_shreds); + gwion_end_child(vm->cleaner_shred, gwion); + if (vm->bbq) free_driver(vm->bbq, gwion->vm); +} + ANN void free_vm(VM *vm) { const MemPool mp = vm->gwion->mp; + if (vm->cleaner_shred) free_vm_shred(vm->cleaner_shred); free_shreduler(mp, vm->shreduler); - if (vm->bbq) free_driver(vm->bbq, vm); vector_release(&vm->ugen); mp_free(mp, VM, vm); } -- 2.43.0