]> Nishi Git Mirror - gwion.git/commitdiff
:art: REM_REF modifications
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 31 Mar 2019 18:56:00 +0000 (20:56 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 31 Mar 2019 18:56:00 +0000 (20:56 +0200)
20 files changed:
include/oo.h
include/operator.h
include/value.h
include/vm.h
src/gwion.c
src/lib/array.c
src/oo/context.c
src/oo/env.c
src/oo/nspc.c
src/oo/type.c
src/oo/value.c
src/parse/check.c
src/parse/func.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/vm/shreduler.c
src/vm/vm_code.c
src/vm/vm_shred.c

index ec55ede3022d0877b87f77ddfbf1e5fdb7574dba..449d8d01f2af9f1f7f5267b2677b4ef0be6e3b35 100644 (file)
@@ -8,16 +8,16 @@ typedef struct Func_      * Func;
 
 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
index 4eb66006b44e09c86148880f0906b1a5303550bc..6e03e3c34b536486f5a529abcf5d2ff8e3358b6a 100644 (file)
@@ -21,6 +21,6 @@ ANN m_bool add_op(const Nspc , const struct Op_Import*);
 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
index 403c28548525145073ed77319ba01830d1c2a1cd..7410cdee159af9f2ed6ab25bab311f6ef430a14d 100644 (file)
@@ -9,11 +9,10 @@ struct Value_ {
     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
index 4ba888eef947bde0fc21b66182da6d2923d99aec..3dad916601ff46b3ef85e42569707fd07ff3fdb4 100644 (file)
@@ -16,15 +16,17 @@ struct VM_Code_ {
 
 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;
index 473d635c83c5b6151e63e59af3364da22d4fe09c..1a357a66167f46cdce1e5370933524adbdf56b87 100644 (file)
@@ -92,7 +92,11 @@ ANN void gwion_run(const Gwion gwion) {
 }
 
 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);
index 73d70a6aa758fa7ef54e13d652c1af3803218ed5..2d09aa5d650ffbd83720a18c443c1247ec6928e7 100644 (file)
@@ -61,7 +61,7 @@ static DTOR(array_dtor) {
     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) {
index cf32a9f55284fc8d0c39da6f8058d4df4408b91a..7548425aa4f34121b54e8c6335337bf2e49ce4ce 100644 (file)
@@ -6,8 +6,8 @@
 #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);
 }
 
@@ -34,6 +34,6 @@ ANN void unload_context(const Context context, const Env env) {
       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);
 }
index 2b88b720327aca6b475bd96d387c89e7b6787ba7..80b41051352742baab9bb50271167462340aacbb 100644 (file)
@@ -48,10 +48,10 @@ ANN void env_reset(const Env env) {
   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);
@@ -63,8 +63,8 @@ ANN static void free_env_scope(struct Env_Scope_  *a) {
 
 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);
 }
 
@@ -89,7 +89,7 @@ ANN void env_add_type(const Env env, const Type type) {
   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;
@@ -105,7 +105,7 @@ ANN m_bool type_engine_check_prog(const Env env, const Ast ast) {
     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;
 }
index bfdc8f56883900b6d6de70f8c6a2377d4b352f0f..e41f5d0440f4631c1235bf6d507338b25422f45e 100644 (file)
@@ -18,62 +18,57 @@ ANN void nspc_commit(const Nspc nspc) {
   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);
 }
 
index e7e2877ca878818d6f72ea9f5d332765382856b7..257e23055ee1cb59038ce756cda6b03c7b1de741 100644 (file)
@@ -6,11 +6,11 @@
 #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);
 }
 
index 879b4d1975b86ca7f4064ae22e102af4566ca31f..df62046fd341e3c3ce73eb03ec5ec65ea5f953fe 100644 (file)
@@ -6,21 +6,20 @@
 #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;
 }
index 081b5a98040e640f6645be27414171bfce9cbd5f..30a89a5ade7d5ba2b426ed32df96a59fd78fcde9 100644 (file)
@@ -785,7 +785,7 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) { GWDEBUG_EX
       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);
@@ -1042,7 +1042,7 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def f) { GWD
 }
 
 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;
@@ -1082,7 +1082,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
       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))
@@ -1102,7 +1102,7 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def class_def) {
   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 ?
index 23fb0a9d315f5f26a3acb70a509d94335820d1ab..5451c65197c8d489da24c3465744ec5a4ddd757e 100644 (file)
@@ -8,13 +8,13 @@
 #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);
 }
 
index daf48dba83744e1c8f0d53979588aecc0ad71f2e..0ddd7d0ff3321e0fd2f15e0135796f52f2344a43 100644 (file)
@@ -24,23 +24,23 @@ typedef struct M_Operator_{
   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);
index f74d8e2c7025f92d72061ec0ca94e6b9f2b69f5a..dd4d075cfc12915cdc7bb20ff534083fc0e598e4 100644 (file)
@@ -12,7 +12,7 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def class_def);
 
 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);
@@ -114,7 +114,7 @@ ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEB
       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);
index 344f61806ce4e23da39d38d3b675c5b32b8c9685..3a0436acd291e1ee0126e56a4560b60be1b187f1 100644 (file)
@@ -73,7 +73,7 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE
         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)
@@ -179,7 +179,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE
   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;
index 572cf59ebf1987f542117364eea7b78068874661..03e2b154b283434bb6bd578a75a6a3fb1eba8af3 100644 (file)
@@ -51,7 +51,7 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
 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;
@@ -337,7 +337,7 @@ ANN static Type func_type(const Env env, const Func func) {
 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);
@@ -412,11 +412,11 @@ ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) { GWDEBUG_E
   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;
 }
index 10043559de408ff7172731dda26e7f01aedab597..68a93bf8efef0ba4c7d66954872f126864b8a12f 100644 (file)
@@ -45,7 +45,7 @@ ANN static void unwind(const VM_Shred shred) {
     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;
   }
index 5fb2ca837ee9d25bbdcd39b9fb583b0180a6ae6a..713655cabbb08813247627b03f6d2154870b9420 100644 (file)
 #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) {
@@ -53,13 +53,13 @@ ANN static void free_code_instr(const Vector v) {
   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);
 }
index a7788425613e610908940653853635b4939e785c..1ea451fd6d53acfc2b59f51a9544077b62c5eea9 100644 (file)
@@ -46,7 +46,7 @@ void free_vm_shred(VM_Shred shred) {
   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);