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));
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;
}
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;
}
}
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;
return ret;
}
#endif
-*/
+
// skip when recursing
const Type t = actual_type(emit->gwion, exp_call->func->type);
const Func f = t->info->func;
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);
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"),
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);
}
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);
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);
}
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);
}