struct VM_Object_ {
uint16_t ref_count; // could be an unsigned short
- void (*free)(void*);
+ void (*free)(void*,void*);
};
#define HAS_OBJ struct VM_Object_ obj;
-#define INIT_OO(a, b) { (a)->obj.ref_count = 1; (a)->obj.free= (void(*)(void*))b; }
-ANN static inline void rem_ref(struct VM_Object_* a, void* ptr) {
+#define INIT_OO(a, b) { (a)->obj.ref_count = 1; (a)->obj.free= (void(*)(void*,void*))b; }
+ANN static inline void rem_ref(struct VM_Object_* a, void* ptr, void *gwion) {
if(--a->ref_count)
return;
- a->free(ptr);
+ a->free(ptr, gwion);
}
#define ADD_REF(a) { ++(a)->obj.ref_count; }
-#define REM_REF(a) { rem_ref(&(a)->obj, (a)); }
+#define REM_REF(a, b) { rem_ref(&(a)->obj, (a), (b)); }
#endif
ANN Type op_check(const Env, struct Op_Import*);
ANN m_bool op_emit(const Emitter, const struct Op_Import*);
ANN m_bool operator_set_func(const struct Op_Import*);
-ANN void free_op_map(Map map);
+ANN void free_op_map(Map map, void *gwion);
ANN m_bool env_add_op(const Env, const struct Op_Import*);
#endif
m_uint* ptr;
Func func_ref;
} d;
- struct Gwion_ *gwion;
size_t offset;
ae_flag flag;
HAS_OBJ
};
-ANEW ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name);
+ANEW ANN Value new_value(const Type type, const m_str name);
#endif
typedef struct Shreduler_* Shreduler;
typedef struct Emitter_ * Emitter;
+typedef struct VM_Shred_* VM_Shred;
+
typedef struct VM_ {
Shreduler shreduler;
struct Vector_ ugen;
struct BBQ_* bbq;
struct Gwion_* gwion;
uint32_t rand[2];
+ VM_Shred cleaner_shred;
} VM;
-typedef struct VM_Shred_* VM_Shred;
struct ShredInfo_ {
VM* vm;
}
ANN void gwion_end(const Gwion gwion) {
+ const VM_Code code = new_vm_code(NULL, 0, ae_flag_builtin, "in code dtor");
+ gwion->vm->cleaner_shred = new_vm_shred(code);
+ gwion->vm->cleaner_shred->info->vm = gwion->vm;
free_env(gwion->env);
+ free_vm_shred(gwion->vm->cleaner_shred);
free_emitter(gwion->emit);
free_vm(gwion->vm);
free_plug(gwion);
for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred);
free_m_vector(a);
- REM_REF(t)
+ REM_REF(t, shred->info->vm->gwion)
}
ANN M_Object new_array(const Type t, const m_uint length) {
#include "nspc.h"
#include "context.h"
-ANN static void free_context(const Context a) {
- REM_REF(a->nspc)
+ANN static void free_context(const Context a, void *gwion) {
+ REM_REF(a->nspc, gwion)
mp_free(Context, a);
}
free_map((Map)map_at(&context->lbls, i));
map_release(&context->lbls);
}
- REM_REF(context);
+ REM_REF(context, env->gwion);
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
}
switch_reset(env);
}
-ANN static void free_env_scope(struct Env_Scope_ *a) {
+ANN static void free_env_scope(struct Env_Scope_ *a, void *gwion) {
const m_uint size = vector_size(&a->known_ctx);
for(m_uint i = size + 1; --i;)
- REM_REF((Context)vector_at(&a->known_ctx, i - 1));
+ REM_REF((Context)vector_at(&a->known_ctx, i - 1), gwion);
vector_release(&a->known_ctx);
vector_release(&a->nspc_stack);
vector_release(&a->class_stack);
ANN void free_env(const Env a) {
switch_reset(a);
- free_env_scope(a->scope);
- REM_REF(a->global_nspc);
+ free_env_scope(a->scope, a->gwion);
+ REM_REF(a->global_nspc, a->gwion);
free(a);
}
v_type->d.base_type = type;
SET_FLAG(type, builtin);
nspc_add_type(env->curr, insert_symbol(type->name), type);
- const Value v = new_value(env->gwion, v_type, type->name);
+ const Value v = new_value(v_type, type->name);
SET_FLAG(v, checked | ae_flag_const | ae_flag_global | ae_flag_builtin);
nspc_add_value(env->curr, insert_symbol(type->name), v);
type->owner = env->curr;
nspc_commit(env->curr);
vector_add(&env->scope->known_ctx, (vtype)ctx);
} else //nspc_rollback(env->global_nspc);
- REM_REF(ctx);
+ REM_REF(ctx, env->gwion);
unload_context(ctx, env);
return ret;
}
scope_commit(&nspc->info->type);
}
-ANN static void nspc_release_object(const Nspc a, Value value) {
-// if(value->d.ptr || (GET_FLAG(value, static) && a->info->class_data) ||
+ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwion) {
if((GET_FLAG(value, static) && a->info->class_data) ||
(value->d.ptr && GET_FLAG(value, builtin))) {
- const VM_Code code = new_vm_code(NULL, 0, ae_flag_builtin, "in code dtor");
- const VM_Shred s = new_vm_shred(code);
const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
*(M_Object*)(a->info->class_data + value->offset);
- s->info->vm = value->gwion->vm;
- release(obj, s);
- free_vm_shred(s);
+ release(obj, gwion->vm->cleaner_shred);
}
}
-ANN static void free_nspc_value(const Nspc a) {
+ANN static void free_nspc_value(const Nspc a, void *gwion) {
struct scope_iter iter = { &a->info->value, 0, 0 };
Value v;
while(scope_iter(&iter, &v) > 0) {
if(isa(v->type, t_object) > 0 ||
(isa(v->type, t_union) > 0 &&
(GET_FLAG(v, static) || GET_FLAG(v, global)))) {
- nspc_release_object(a, v);
+ nspc_release_object(a, v, gwion);
}
- REM_REF(v);
+ REM_REF(v, gwion);
}
scope_release(&a->info->value);
}
#define describe_nspc_free(A, b) \
-ANN static void nspc_free_##b(Nspc n) {\
+ANN static void nspc_free_##b(Nspc n, void *gwion) {\
struct scope_iter iter = { &n->info->b, 0, 0 };\
A a;\
while(scope_iter(&iter, &a) > 0) \
- REM_REF(a);\
+ REM_REF(a, gwion);\
scope_release(&n->info->b);\
}
describe_nspc_free(Func, func)
describe_nspc_free(Type, type)
-ANN static void free_nspc(Nspc a) {
- nspc_free_func(a);
- nspc_free_type(a);
- free_nspc_value(a);
+ANN static void free_nspc(Nspc a, void *gwion) {
+ nspc_free_func(a, gwion);
+ nspc_free_type(a, gwion);
+ free_nspc_value(a, gwion);
if(a->info->class_data)
free(a->info->class_data);
if(a->info->vtable.ptr)
vector_release(&a->info->vtable);
if(a->info->op_map.ptr)
- free_op_map(&a->info->op_map);
+ free_op_map(&a->info->op_map, gwion);
mp_free(NspcInfo, a->info);
if(a->pre_ctor)
- REM_REF(a->pre_ctor);
+ REM_REF(a->pre_ctor, gwion);
if(a->dtor)
- REM_REF(a->dtor);
+ REM_REF(a->dtor, gwion);
mp_free(Nspc, a);
}
#include "type.h"
#include "nspc.h"
-ANN static void free_type(Type a) {
+ANN static void free_type(Type a, void *gwion) {
if(GET_FLAG(a, template))
free_class_def(a->def);
if(a->nspc)
- REM_REF(a->nspc);
+ REM_REF(a->nspc, gwion);
mp_free(Type, a);
}
#include "value.h"
#include "type.h"
-ANN static void free_value(Value a) {
+ANN static void free_value(Value a, void *gwion) {
if(!GET_FLAG(a, func) && a->d.ptr &&
!(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class)
&& isa(a->type, t_object) < 0)
_mp_free(a->type->size, a->d.ptr);
if(isa(a->type, t_class) > 0 || isa(a->type, t_function) > 0 || GET_FLAG(a->type, op))
- REM_REF(a->type)
+ REM_REF(a->type, gwion)
mp_free(Value, a);
}
-ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name) {
+ANN Value new_value(const Type type, const m_str name) {
const Value a = mp_alloc(Value);
a->type = type;
a->name = name;
- a->gwion = gwion;
INIT_OO(a, free_value);
return a;
}
check_class_def(env, ptr->def);
}
t = depth ? array_type(ptr, depth) : ptr;
- stmt->v = new_value(env->gwion, t, s_name(stmt->sym));
+ stmt->v = new_value(t, s_name(stmt->sym));
SET_FLAG(stmt->v, checked);
nspc_add_value(env->curr, stmt->sym, stmt->v);
return check_conts(env, stmt->self, stmt->body);
}
ANN static Value set_variadic(const Env env) {
- const Value variadic = new_value(env->gwion, t_vararg, "vararg");
+ const Value variadic = new_value(t_vararg, "vararg");
SET_FLAG(variadic, checked);
nspc_add_value(env->curr, insert_symbol("vararg"), variadic);
return variadic;
ret = err_msg(f->td ? f->td->xid->pos : 0, "...in function '%s'",
s_name(f->name));
if(variadic)
- REM_REF(variadic)
+ REM_REF(variadic, env->gwion)
if(GET_FLAG(f, builtin))
func->code->stack_depth = f->stack_depth;
else if(GET_FLAG(f, op))
if(class_def->ext->array) {
CHECK_BB(check_exp_array_subscripts(env, class_def->ext->array->exp))
if(!GET_FLAG(class_def->type, check) && class_def->tmpl)
- REM_REF(class_def->type->parent->nspc);
+ REM_REF(class_def->type->parent->nspc, env->gwion);
}
if(class_def->ext->types) {
const Type t = class_def->type->parent->array_depth ?
#include "nspc.h"
#include "func.h"
-ANN static void free_func(Func a) {
+ANN static void free_func(Func a, void *gwion) {
if(GET_FLAG(a, template)) {
free_tmpl_list(a->def->tmpl);
mp_free(Func_Def, a->def);
}
if(a->code)
- REM_REF(a->code);
+ REM_REF(a->code, gwion);
mp_free(Func, a);
}
m_bool mut;
} M_Operator;
-ANN static void free_op(M_Operator* a) {
+ANN static void free_op(M_Operator* a, void *gwion) {
if(a->lhs && a->lhs != OP_ANY_TYPE)
- REM_REF(a->lhs)
+ REM_REF(a->lhs, gwion)
if(a->rhs && a->rhs != OP_ANY_TYPE)
- REM_REF(a->rhs)
+ REM_REF(a->rhs, gwion)
if(a->ret)
- REM_REF(a->ret)
+ REM_REF(a->ret, gwion)
mp_free(M_Operator, a);
}
-ANN void free_op_map(Map map) {
+ANN void free_op_map(Map map, void *gwion) {
LOOP_OPTIM
for(m_uint i = map_size(map) + 1; --i;) {
const restrict Vector v = (Vector)map_at(map, (vtype)i - 1);
LOOP_OPTIM
for(m_uint j = vector_size(v) + 1; --j;)
- free_op((M_Operator*)vector_at(v, j - 1));
+ free_op((M_Operator*)vector_at(v, j - 1), gwion);
free_vector(v);
}
map_release(map);
ANN static Value mk_class(const Env env, const Type base) {
const Type t = type_copy(t_class);
- const Value v = new_value(env->gwion, t, base->name);
+ const Value v = new_value(t, base->name);
t->d.base_type = base;
v->owner = base->owner;
SET_FLAG(v, const | ae_flag_checked);
env->curr : env->global_nspc;
const Type t = union_type(env, nspc, stmt->type_xid ?: stmt->xid,
!!stmt->type_xid);
- stmt->value = new_value(env->gwion, t, s_name(stmt->xid));
+ stmt->value = new_value(t, s_name(stmt->xid));
stmt->value->owner_class = env->class_def;
stmt->value->owner = nspc;
nspc_add_value(nspc, stmt->xid, stmt->value);
CHECK_BB(scan1_exp(env, var->array->exp))
t = array_type(decl->type, var->array->depth);
}
- const Value v = var->value = former ? former : new_value(env->gwion, t, s_name(var->xid));
+ const Value v = var->value = former ? former : new_value(t, s_name(var->xid));
nspc_add_value(nspc, var->xid, v);
v->flag = decl->td->flag;
if(var->array && !var->array->exp)
ID_List list = stmt->list;
do {
CHECK_BB(already_defined(env, list->xid, stmt->self->pos))
- const Value v = new_value(env->gwion, stmt->t, s_name(list->xid));
+ const Value v = new_value(stmt->t, s_name(list->xid));
if(env->class_def) {
v->owner_class = env->class_def;
v->owner = env->curr;
ANN static Value arg_value(const Env env, const Arg_List list) {
const Var_Decl var = list->var_decl;
if(!var->value) {
- const Value v = new_value(env->gwion, list->type,
+ const Value v = new_value(list->type,
var->xid ? s_name(var->xid) : s_name(insert_symbol((m_str)var)));
if(list->td)
v->flag = list->td->flag | ae_flag_arg;
ANN2(1,2) static Value func_value(const Env env, const Func f,
const Value overload) {
const Type t = func_type(env, f);
- const Value v = new_value(env->gwion, t, t->name);
+ const Value v = new_value(t, t->name);
CHECK_OO(scan2_func_assign(env, f->def, f, v))
if(!overload) {
ADD_REF(v);
CHECK_BB(env_add_op(env, &opi))
if(env->class_def) {
if(env->class_def == l)
- REM_REF(l)
+ REM_REF(l, env->gwion)
if(env->class_def == r)
- REM_REF(r)
+ REM_REF(r, env->gwion)
if(env->class_def == f->ret_type)
- REM_REF(f->ret_type)
+ REM_REF(f->ret_type, env->gwion)
}
return GW_OK;
}
const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
if(exec == eFuncReturn) {
code = *(VM_Code*)(shred->mem - SZ_INT*3);
- REM_REF(code);
+ REM_REF(code, shred->info->vm->gwion);
shred->mem -= *(m_uint*)(shred->mem - SZ_INT);
} else break;
}
#include "array.h"
#include "memoize.h"
-ANN static void free_code_instr_gack(const Instr instr) {
+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)));
+ REM_REF(((Type)vector_at(v, i - 1)), gwion);
free_vector(v);
}
-ANN static void free_array_info(ArrayInfo* info) {
- REM_REF((Type)vector_back(&info->type));
+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) {
+ANN static void free_code_instr(const Vector v, void *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)
+ REM_REF((VM_Code)instr->m_val, gwion)
else if(instr->execute == ArrayAlloc)
- free_array_info((ArrayInfo*)instr->m_val);
+ free_array_info((ArrayInfo*)instr->m_val, gwion);
else if(instr->opcode == (m_uint)Gack)
- free_code_instr_gack(instr);
+ free_code_instr_gack(instr, gwion);
else if(instr->execute == BranchSwitch)
free_map((Map)instr->m_val2);
else if(instr->execute == DotTmpl) {
free_vector(v);
}
-ANN static void free_vm_code(VM_Code a) {
+ANN static void free_vm_code(VM_Code a, void *gwion) {
#ifndef NOMEMOIZE
if(a->memoize)
memoize_end(a->memoize);
#endif
if(!GET_FLAG(a, builtin))
- free_code_instr(a->instr);
+ free_code_instr(a->instr, gwion);
free(a->name);
mp_free(VM_Code, a);
}
for(m_uint i = vector_size(&shred->gc) + 1; --i;)
release((M_Object)vector_at(&shred->gc, i - 1), shred);
vector_release(&shred->gc);
- REM_REF(shred->code);
+ REM_REF(shred->code, shred->info->vm->gwion);
mp_free(ShredTick, shred->tick);
free_shredinfo(shred->info);
mp_free(Stack, shred);