ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary *);
ANN m_bool emit_exp(const Emitter, const Exp);
-ANN Instr emit_object_addref(const Emitter emit, const m_int size,
+ANN void emit_object_addref(const Emitter emit, const m_int size,
const bool emit_var);
-ANN Instr emit_struct_addref(const Emitter emit, const Type t, const m_int size,
+ANN void emit_struct_addref(const Emitter emit, const Type t, const m_int size,
const bool emit_var);
-ANN static inline Instr emit_compound_addref(const Emitter emit, const Type t,
+ANN static inline void emit_compound_addref(const Emitter emit, const Type t,
const m_int size,
const m_bool emit_var) {
return !tflag(t, tflag_struct) ? emit_object_addref(emit, size, emit_var)
uint64_t start;
};
-ANN Type tuple_type(const Env, const Vector, const loc_t);
ANN void tuple_contains(const Env, const Value);
ANN void tuple_info(const Env, const Value);
ANN2(1) TupleForm new_tupleform(MemPool p, const Type parent_type);
ANN void free_tupleform(const TupleForm tuple, const struct Gwion_ *gwion);
-#ifdef __INSTR
-INSTR(TupleCtor);
-INSTR(TupleMember);
-#endif
#endif
tflag_ref = 1 << 22,
tflag_packed = 1 << 23,
tflag_compound = 1 << 24,
+ tflag_release = 1 << 25, // mark structs that need release
} __attribute__((packed));
struct Type_ {
ANN void emit_compound_release(const Emitter emit, const Type t, const m_uint offset) {
if(tflag(t, tflag_compound))
return emit_object_release(emit, offset);
- emit_struct_release(emit, t, offset);
+ if(tflag(t, tflag_release))
+ emit_struct_release(emit, t, offset);
}
ANN void emit_struct_release(const Emitter emit, const Type type,
return size;
}
-ANN Instr emit_object_addref(const Emitter emit, const m_int size,
+ANN void emit_object_addref(const Emitter emit, const m_int size,
const bool emit_var) {
const f_instr exec = !emit_var ? RegAddRef : RegAddRefAddr;
const Instr instr = emit_add_instr(emit, exec);
instr->m_val = size;
- return instr;
}
-ANN Instr emit_struct_addref(const Emitter emit, const Type t, const m_int size,
+ANN void emit_struct_addref(const Emitter emit, const Type t, const m_int size,
const bool emit_var) {
+ if(!tflag(t, tflag_release)) return;
const Instr instr =
emit_add_instr(emit, !emit_var ? StructRegAddRef : StructRegAddRefAddr);
instr->m_val2 = (m_uint)t;
instr->m_val = !emit_var ? size : (m_int)-SZ_INT;
- return instr;
}
ANN2(1)
if (cflag(cdef, cflag_struct)) {
t->size = 0;
set_tflag(t, tflag_struct);
- }
+ } else set_tflag(t, tflag_release);
set_tflag(t, tflag_compound);
t->info->tuple = new_tupleform(env->gwion->mp, parent);
t->nspc = new_nspc(env->gwion->mp, t->name);
const Type t = bin->lhs->type;
const Exp e = exp_self(bin);
- const Instr release = emit_add_instr(emit, StructReleaseRegAddr);
- release->m_val = -SZ_INT;
- release->m_val2 = (m_uint)t;
+ if(tflag(t, tflag_release)) {
+ const Instr release = emit_add_instr(emit, StructReleaseRegAddr);
+ release->m_val = -SZ_INT;
+ release->m_val2 = (m_uint)t;
+ }
const Instr instr = emit_add_instr(emit, StructAssign);
instr->m_val = -t->size - SZ_INT;
if (env->class_def->info->tuple) tuple_contains(env, v);
if (!GET_FLAG(decl->td, static)) {
set_vflag(v, vflag_member);
+ if(tflag(t, tflag_release))
+ set_tflag(env->class_def, tflag_release);
if(isa(t, env->gwion->type[et_object]) > 0)
set_vflag(v, vflag_release);
if (tflag(env->class_def, tflag_struct)) {