From 4ea0b01a178b81aee9a2e3bcc68ad6b6e748d298 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 31 Mar 2019 21:38:20 +0200 Subject: [PATCH] :art: Introduce FREEARG --- include/gwi.h | 6 ++-- include/gwion.h | 2 ++ include/import.h | 4 +++ include/instr.h | 2 +- src/emit/emit.c | 2 +- src/gwion.c | 3 ++ src/lib/array.c | 10 +++++- src/lib/engine.c | 25 ++++++++++++--- src/lib/func.c | 15 ++++++++- src/lib/import.c | 83 +++++++++++++++++++++++++----------------------- src/lib/instr.c | 2 +- src/lib/vararg.c | 5 +++ src/vm/vm_code.c | 43 +++++-------------------- 13 files changed, 115 insertions(+), 87 deletions(-) diff --git a/include/gwi.h b/include/gwi.h index 70b3122f..9438c037 100644 --- a/include/gwi.h +++ b/include/gwi.h @@ -45,10 +45,8 @@ typedef struct { Decl_List list; } DL_Union; -struct Gwi_{ - VM* vm; - Emitter emit; - Env env; +struct Gwi_ { + struct Gwion_* gwion; Class_Body body; DL_Var var; DL_Func func; diff --git a/include/gwion.h b/include/gwion.h index 32f57ff5..431af256 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -12,7 +12,9 @@ struct Gwion_ { Env env; Emitter emit; VM* vm; + struct Map_ freearg; }; + ANN m_bool gwion_ini(const Gwion, struct Arg_*); ANN VM* gwion_cpy(const VM*); ANN void gwion_run(const Gwion gwion); diff --git a/include/import.h b/include/import.h index 028e8b36..5947e74e 100644 --- a/include/import.h +++ b/include/import.h @@ -74,4 +74,8 @@ OP_EMIT(opem_basic_cast); OP_EMIT(opem_new); ANN Type_List str2tl(const Env env, const m_str s, m_uint *depth); + +#define FREEARG(a) ANN void a(Instr instr, void *gwion) +typedef void (*f_freearg)(Instr, void*); +ANN void register_freearg(const Gwi, const f_instr, void(*)(const Instr,void*)); #endif diff --git a/include/instr.h b/include/instr.h index e9e4ed4f..20b7f4ba 100644 --- a/include/instr.h +++ b/include/instr.h @@ -34,7 +34,7 @@ INSTR(DTOR_EOC); INSTR(DtorReturn); /* branching */ -INSTR(BranchSwitch); +INSTR(SwitchBranch); INSTR(SwitchIni); INSTR(SwitchEnd); diff --git a/src/emit/emit.c b/src/emit/emit.c index 66e14f15..38a08328 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1266,7 +1266,7 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { CHECK_BB(emit_exp(emit, stmt->val, 0)) CHECK_BB(emit_switch_instr(emit, push)) vector_add(&emit->code->stack_break, (vtype)NULL); - const Instr instr = emit_add_instr(emit, BranchSwitch); + const Instr instr = emit_add_instr(emit, SwitchBranch); instr->m_val2 = (m_uint)switch_map(emit->env); CHECK_BB(emit_stmt(emit, stmt->stmt, 1)) instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); diff --git a/src/gwion.c b/src/gwion.c index 1a357a66..72834153 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -60,6 +60,7 @@ ANN VM* gwion_cpy(const VM* src) { gwion->vm->bbq->si = soundinfo_cpy(src->bbq->si); gwion->emit = src->gwion->emit; gwion->env = src->gwion->env; + gwion->freearg = src->gwion->freearg; return gwion->vm; } ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) { @@ -75,6 +76,7 @@ ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) { arg->si = gwion->vm->bbq->si; arg_parse(arg); gwion->plug = new_plug(&arg->lib); + map_init(&gwion->freearg); shreduler_set_loop(gwion->vm->shreduler, arg->loop); if(gwion_audio(gwion) > 0 && gwion_engine(gwion)) { gwion_compile(gwion, &arg->add); @@ -100,5 +102,6 @@ ANN void gwion_end(const Gwion gwion) { free_emitter(gwion->emit); free_vm(gwion->vm); free_plug(gwion); + map_release(&gwion->freearg); free_symbols(); } diff --git a/src/lib/array.c b/src/lib/array.c index 2d09aa5d..0c295078 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -28,7 +28,7 @@ ANN m_uint m_vector_size(const M_Vector v) { M_Vector new_m_vector(const m_uint size) { const M_Vector array = mp_alloc(M_Vector); -const size_t sz = (ARRAY_OFFSET*SZ_INT) + (2*size); + const size_t sz = (ARRAY_OFFSET*SZ_INT) + (2*size); array->ptr = (m_bit*)xcalloc(1, sz); ARRAY_CAP(array) = 2; ARRAY_SIZE(array) = size; @@ -187,6 +187,13 @@ static OP_CHECK(opck_array_cast) { return t_null; } +static FREEARG(freearg_array) { + ArrayInfo* info = (ArrayInfo*)instr->m_val; + REM_REF((Type)vector_back(&info->type), gwion); + vector_release(&info->type); + mp_free(ArrayInfo, info); +} + GWION_IMPORT(array) { t_array = gwi_mk_type(gwi, "Array", SZ_INT, t_object); SET_FLAG((t_array), abstract); @@ -218,6 +225,7 @@ GWION_IMPORT(array) { CHECK_BB(gwi_oper_add(gwi, opck_array_cast)) CHECK_BB(gwi_oper_emi(gwi, opem_basic_cast)) CHECK_BB(gwi_oper_end(gwi, op_cast, NULL)) + register_freearg(gwi, ArrayAlloc, freearg_array); return GW_OK; } diff --git a/src/lib/engine.c b/src/lib/engine.c index ddc9743f..500a93b1 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -15,6 +15,22 @@ #include "engine.h" #include "gwion.h" +static FREEARG(freearg_switchini) { + free_vector((Vector)instr->m_val); + free_map((Map)instr->m_val2); +} + +static FREEARG(freearg_switchbranch) { + free_map((Map)instr->m_val2); +} + +static FREEARG(freearg_gack) { + const Vector v = (Vector)instr->m_val2; + for(m_uint i = vector_size(v) + 1; --i;) + REM_REF(((Type)vector_at(v, i - 1)), gwion); + free_vector(v); +} + ANN static m_bool import_core_libs(const Gwi gwi) { CHECK_OB((t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL))) CHECK_OB((t_void = gwi_mk_type(gwi, "void", 0, NULL))) @@ -63,6 +79,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) { CHECK_BB(import_string(gwi)) CHECK_BB(import_shred(gwi)) CHECK_BB(import_modules(gwi)) + register_freearg(gwi, SwitchIni, freearg_switchini); + register_freearg(gwi, SwitchBranch, freearg_switchbranch); + register_freearg(gwi, Gack, freearg_gack); return GW_OK; } @@ -70,15 +89,13 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) { vm->gwion->env->name = "[builtin]"; struct Gwi_ gwi; memset(&gwi, 0, sizeof(struct Gwi_)); - gwi.vm = vm; - gwi.emit = vm->gwion->emit; - gwi.env = vm->gwion->env; + gwi.gwion = vm->gwion; CHECK_BB(import_core_libs(&gwi)) vm->gwion->env->name = "[imported]"; for(m_uint i = 0; i < vector_size(plug_dirs); ++i) { m_bool (*import)(Gwi) = (m_bool(*)(Gwi))vector_at(plug_dirs, i); if(import && import(&gwi) < 0) - env_reset(gwi.env); + env_reset(gwi.gwion->env); } return GW_OK; } diff --git a/src/lib/func.c b/src/lib/func.c index 77968a03..8d093bb7 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -167,6 +167,16 @@ static OP_EMIT(opem_spork) { return emit_exp_spork(emit, unary); } +static FREEARG(freearg_xork) { + REM_REF((VM_Code)instr->m_val, gwion) +} + +static FREEARG(freearg_dottmpl) { + struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; + free_type_list(dt->tl); + mp_free(dottmpl, dt); +} + GWION_IMPORT(func) { CHECK_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@function", NULL)) CHECK_BB(gwi_oper_add(gwi, opck_func_call)) @@ -185,5 +195,8 @@ GWION_IMPORT(func) { CHECK_BB(gwi_oper_end(gwi, op_spork, NULL)) CHECK_BB(gwi_oper_add(gwi, opck_spork)) CHECK_BB(gwi_oper_emi(gwi, opem_spork)) - return (m_bool)gwi_oper_end(gwi, op_fork, NULL); + CHECK_BB(gwi_oper_end(gwi, op_fork, NULL)) + register_freearg(gwi, SporkIni, freearg_xork); + register_freearg(gwi, ForkIni, freearg_xork); + return GW_OK; } diff --git a/src/lib/import.c b/src/lib/import.c index 96b5982b..4ae707d9 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -17,6 +17,7 @@ #include "func.h" #include "nspc.h" #include "operator.h" +#include "gwion.h" struct Path { m_str path, curr; @@ -34,7 +35,7 @@ ANN static ID_List templater_def(const Templater* templater) { } ANN VM* gwi_vm(const Gwi gwi) { - return gwi->vm; + return gwi->gwion->vm; } ANN m_int gwi_tmpl_end(const Gwi gwi) { @@ -181,7 +182,7 @@ ANN2(1,2) Type gwi_mk_type(const Gwi gwi __attribute__((unused)), const m_str na ANN m_int gwi_add_type(const Gwi gwi, const Type type) { if(type->name[0] != '@') CHECK_BB(name_valid(type->name)); - env_add_type(gwi->env, type); + env_add_type(gwi->gwion->env, type); return (m_int)type->xid; } @@ -215,39 +216,39 @@ ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_c } else SET_FLAG(type, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit); gwi_add_type(gwi, type); - import_class_ini(gwi->env, type, pre_ctor, dtor); + import_class_ini(gwi->gwion->env, type, pre_ctor, dtor); return (m_int)type->xid; } ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) { - if(!gwi->env->class_def) + if(!gwi->gwion->env->class_def) ERR_B(0, "gwi_class_ext invoked before gwi_class_ini") - const VM_Code ctor = gwi->env->class_def->nspc->pre_ctor; - if(gwi->env->class_def->parent || - (gwi->env->class_def->def && gwi->env->class_def->def->ext)) + const VM_Code ctor = gwi->gwion->env->class_def->nspc->pre_ctor; + if(gwi->gwion->env->class_def->parent || + (gwi->gwion->env->class_def->def && gwi->gwion->env->class_def->def->ext)) ERR_B(0, "class extend already set") if(td->array && !td->array->exp) ERR_B(0, "class extend array can't be empty") - if(!gwi->env->class_def->def) { - const Type t = known_type(gwi->env, td); + if(!gwi->gwion->env->class_def->def) { + const Type t = known_type(gwi->gwion->env, td); CHECK_OB(t) if(td->array) - SET_FLAG(gwi->env->class_def, typedef); - gwi->env->class_def->parent = t; - gwi->env->class_def->nspc->info->offset = t->nspc->info->offset; + SET_FLAG(gwi->gwion->env->class_def, typedef); + gwi->gwion->env->class_def->parent = t; + gwi->gwion->env->class_def->nspc->info->offset = t->nspc->info->offset; if(t->nspc->info->vtable.ptr) - vector_copy2(&t->nspc->info->vtable, &gwi->env->class_def->nspc->info->vtable); - CHECK_OB((gwi->emit->code = emit_class_code(gwi->emit, - gwi->env->class_def->name))) + vector_copy2(&t->nspc->info->vtable, &gwi->gwion->env->class_def->nspc->info->vtable); + CHECK_OB((gwi->gwion->emit->code = emit_class_code(gwi->gwion->emit, + gwi->gwion->env->class_def->name))) if(td->array) - CHECK_BB(emit_array_extend(gwi->emit, t, td->array->exp)) + CHECK_BB(emit_array_extend(gwi->gwion->emit, t, td->array->exp)) if(ctor) - emit_ext_ctor(gwi->emit, ctor); - emit_class_finish(gwi->emit, gwi->env->class_def->nspc); + emit_ext_ctor(gwi->gwion->emit, ctor); + emit_class_finish(gwi->gwion->emit, gwi->gwion->env->class_def->nspc); free_type_decl(td); } else { SET_FLAG(td, typedef); - gwi->env->class_def->def->ext = td; + gwi->gwion->env->class_def->def->ext = td; } return GW_OK; } @@ -264,11 +265,11 @@ ANN static m_int import_class_end(const Env env) { #include "mpool.h" ANN m_int gwi_class_end(const Gwi gwi) { - if(!gwi->env->class_def)return GW_ERROR; - const Type t = gwi->env->class_def; + if(!gwi->gwion->env->class_def)return GW_ERROR; + const Type t = gwi->gwion->env->class_def; if(t->nspc && t->nspc->info->offset) t->p = mp_ini((uint32_t)t->nspc->info->offset); - return import_class_end(gwi->env); + return import_class_end(gwi->gwion->env); } ANN static void dl_var_new_exp_array(DL_Var* v) { @@ -302,7 +303,7 @@ ANN m_int gwi_item_ini(const Gwi gwi, const restrict m_str type, const restrict memset(v, 0, sizeof(DL_Var)); if(!(v->t.xid = str2list(type, &v->array_depth))) ERR_B(0, "\t...\tduring var import '%s.%s'.", - gwi->env->class_def->name, name) + gwi->gwion->env->class_def->name, name) v->var.xid = insert_symbol(name); return GW_OK; } @@ -310,8 +311,8 @@ ANN m_int gwi_item_ini(const Gwi gwi, const restrict m_str type, const restrict #undef gwi_item_end static void gwi_body(const Gwi gwi, const Class_Body body) { - if(!gwi->env->class_def->def->body) - gwi->env->class_def->def->body = body; + if(!gwi->gwion->env->class_def->def->body) + gwi->gwion->env->class_def->def->body = body; else gwi->body->next = body; gwi->body = body; @@ -321,7 +322,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr DL_Var* v = &gwi->var; dl_var_set(v, flag | ae_flag_builtin); v->var.addr = (void*)addr; - if(gwi->env->class_def && GET_FLAG(gwi->env->class_def, template)) { + if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) { Type_Decl *type_decl = new_type_decl(v->t.xid, flag); const Var_Decl var_decl = new_var_decl(v->var.xid, v->var.array, 0); const Var_Decl_List var_decl_list = new_var_decl_list(var_decl, NULL); @@ -334,7 +335,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr gwi_body(gwi, body); return GW_OK; } - CHECK_BB(traverse_decl(gwi->env, &v->exp.d.exp_decl)) + CHECK_BB(traverse_decl(gwi->gwion->env, &v->exp.d.exp_decl)) SET_FLAG(v->var.value, builtin); dl_var_release(v); return (m_int)v->var.value->offset; @@ -444,7 +445,7 @@ ANN static Func_Def import_fun(const Env env, DL_Func * mfun, const ae_flag flag } ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) { - Func_Def def = import_fun(gwi->env, &gwi->func, flag); + Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag); CHECK_OB(def) if(gwi->templater.n) { def = new_func_def(NULL, NULL, NULL, NULL, 0); @@ -452,13 +453,13 @@ ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) { def->tmpl = new_tmpl_list(list, -1); SET_FLAG(def, template); } - if(gwi->env->class_def && GET_FLAG(gwi->env->class_def, template)) { + if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) { Section* section = new_section_func_def(def); Class_Body body = new_class_body(section, NULL); gwi_body(gwi, body); return GW_OK; } - if(traverse_func_def(gwi->env, def) < 0) { + if(traverse_func_def(gwi->gwion->env, def) < 0) { free_func_def(def); return GW_ERROR; } @@ -510,7 +511,7 @@ ANN void gwi_oper_mut(const Gwi gwi, const m_bool mut) { ANN m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f) { gwi->oper.op = op; - const m_bool ret = import_op(gwi->env, &gwi->oper, f); + const m_bool ret = import_op(gwi->gwion->env, &gwi->oper, f); gwi->oper.ck = NULL; gwi->oper.em = NULL; return ret; @@ -535,10 +536,10 @@ ANN static Stmt import_fptr(const Env env, DL_Func* dl_fun, ae_flag flag) { } ANN m_int gwi_fptr_end(const Gwi gwi, const ae_flag flag) { - const Stmt stmt = import_fptr(gwi->env, &gwi->func, flag); + const Stmt stmt = import_fptr(gwi->gwion->env, &gwi->func, flag); - CHECK_BB(traverse_stmt_fptr(gwi->env, &stmt->d.stmt_fptr)) - if(gwi->env->class_def) + CHECK_BB(traverse_stmt_fptr(gwi->gwion->env, &stmt->d.stmt_fptr)) + if(gwi->gwion->env->class_def) SET_FLAG(stmt->d.stmt_fptr.func->def, builtin); else SET_FLAG(stmt->d.stmt_fptr.func, builtin); @@ -572,7 +573,7 @@ ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str name) { ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) { const Exp exp = make_exp(type, name); CHECK_OB(exp); - const Type t = type_decl_resolve(gwi->env, exp->d.exp_decl.td); + const Type t = type_decl_resolve(gwi->gwion->env, exp->d.exp_decl.td); if(!t) ERR_B(0, "type '%s' unknown in union declaration.", type) if(isa(t, t_object) > 0) @@ -586,10 +587,10 @@ ANN m_int gwi_union_end(const Gwi gwi, const ae_flag flag) { ERR_B(0, "union is empty"); const Stmt stmt = new_stmt_union(gwi->union_data.list, 0); stmt->d.stmt_union.flag = flag; - CHECK_BB(traverse_stmt_union(gwi->env, &stmt->d.stmt_union)) + CHECK_BB(traverse_stmt_union(gwi->gwion->env, &stmt->d.stmt_union)) emit_union_offset(stmt->d.stmt_union.l, stmt->d.stmt_union.o); if(GET_FLAG((&stmt->d.stmt_union), member)) - gwi->env->class_def->nspc->info->offset = + gwi->gwion->env->class_def->nspc->info->offset = stmt->d.stmt_union.o + stmt->d.stmt_union.s; free_stmt(stmt); gwi->union_data.list = NULL; @@ -622,7 +623,7 @@ ANN static void import_enum_end(const Gwi gwi, const Vector v) { Value value = (Value)vector_at(v, i); const m_uint addr = vector_at(&d->addr, i); SET_FLAG(value, builtin); - if(!gwi->env->class_def) + if(!gwi->gwion->env->class_def) value->d.ptr = (m_uint*)(addr ? addr : i); else value->d.ptr = (m_uint*)(addr ? *(m_uint*)addr : i); @@ -635,7 +636,7 @@ ANN static void import_enum_end(const Gwi gwi, const Vector v) { ANN m_int gwi_enum_end(const Gwi gwi) { DL_Enum* d = &gwi->enum_data; const Stmt stmt = new_stmt_enum(d->base, d->t ? insert_symbol(d->t) : NULL); - if(traverse_stmt_enum(gwi->env, &stmt->d.stmt_enum) < 0) { + if(traverse_stmt_enum(gwi->gwion->env, &stmt->d.stmt_enum) < 0) { free_id_list(d->base); return GW_ERROR; } @@ -643,3 +644,7 @@ ANN m_int gwi_enum_end(const Gwi gwi) { free_stmt(stmt); return GW_OK; } + +ANN void register_freearg(const Gwi gwi, const f_instr _exec, void(*_free)(const Instr, void*)) { + map_set(&gwi->gwion->freearg, (vtype)_exec, (vtype)_free); +} \ No newline at end of file diff --git a/src/lib/instr.c b/src/lib/instr.c index 34e6cf86..b070d141 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -34,7 +34,7 @@ INSTR(SwitchIni) { map_set((Map)instr->m_val2, *(vtype*)REG((i) * SZ_INT), vector_at(v, i)); } -INSTR(BranchSwitch) { GWDEBUG_EXE +INSTR(SwitchBranch) { GWDEBUG_EXE POP_REG(shred, SZ_INT); const Map map = *(Map*)REG(SZ_INT); shred->pc = map_get(map, *(m_uint*)REG(0)) ?: instr->m_val; diff --git a/src/lib/vararg.c b/src/lib/vararg.c index 423e1454..32db5c3a 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -71,6 +71,10 @@ static INSTR(VarargAssign) { GWDEBUG_EXE *(M_Object**)REG(0) = &*(M_Object*)REG(-SZ_INT); } +FREEARG(freearg_vararg) { + if(instr->m_val2) + free_vector((Vector)instr->m_val2); +} GWION_IMPORT(vararg) { CHECK_OB((t_vararg = gwi_mk_type(gwi, "@Vararg", SZ_INT, t_object))) const Type t_varobj = gwi_mk_type(gwi, "VarObject", SZ_INT, t_vararg); @@ -101,5 +105,6 @@ GWION_IMPORT(vararg) { CHECK_BB(gwi_oper_ini(gwi, "Object", "VarObject", NULL)) CHECK_BB(gwi_oper_add(gwi, at_varobj)) CHECK_BB(gwi_oper_end(gwi, op_ref, VarargAssign)) + register_freearg(gwi, VarargIni, freearg_vararg); return GW_OK; } diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 713655ca..dfb72d42 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -11,43 +11,16 @@ #include "object.h" #include "array.h" #include "memoize.h" +#include "gwion.h" +#include "import.h" -ANN static void free_code_instr_gack(const Instr instr, void *gwion) { - const Vector v = (Vector)instr->m_val2; - for(m_uint i = vector_size(v) + 1; --i;) - REM_REF(((Type)vector_at(v, i - 1)), gwion); - free_vector(v); -} - -ANN static void free_array_info(ArrayInfo* info, void *gwion) { - REM_REF((Type)vector_back(&info->type), gwion); - vector_release(&info->type); - mp_free(ArrayInfo, info); -} - -ANN static void free_code_instr(const Vector v, void *gwion) { +ANN static void free_code_instr(const Vector v, const Gwion gwion) { for(m_uint i = vector_size(v) + 1; --i;) { const Instr instr = (Instr)vector_at(v, i - 1); - if(instr->opcode == eSporkIni || instr->opcode == eForkIni) - REM_REF((VM_Code)instr->m_val, gwion) - else if(instr->execute == ArrayAlloc) - free_array_info((ArrayInfo*)instr->m_val, gwion); - else if(instr->opcode == (m_uint)Gack) - free_code_instr_gack(instr, gwion); - else if(instr->execute == BranchSwitch) - free_map((Map)instr->m_val2); - else if(instr->execute == DotTmpl) { - struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; - free_type_list(dt->tl); - mp_free(dottmpl, dt); - } - else if(instr->execute == SwitchIni) { - free_vector((Vector)instr->m_val); - free_map((Map)instr->m_val2); - } else if(instr->execute == VarargIni) { - if(instr->m_val2) - free_vector((Vector)instr->m_val2); - } + const f_freearg f = (f_freearg)(map_get(&gwion->freearg, instr->opcode) ?: + map_get(&gwion->freearg, (vtype)instr->execute)); + if(f) + f(instr, gwion); mp_free(Instr, instr); } free_vector(v); @@ -60,7 +33,7 @@ ANN static void free_vm_code(VM_Code a, void *gwion) { #endif if(!GET_FLAG(a, builtin)) free_code_instr(a->instr, gwion); - free(a->name); + xfree(a->name); mp_free(VM_Code, a); } -- 2.43.0