This commit is contained in:
Brian Carroll 2022-03-20 11:17:34 +00:00
parent c9efeed17e
commit 9b6b81a438
6 changed files with 76 additions and 34 deletions

View file

@ -128,6 +128,40 @@ pub fn refcount_generic<'a>(
}
}
pub fn refcount_reset_proc_body<'a>(
root: &mut CodeGenHelp<'a>,
ident_ids: &mut IdentIds,
ctx: &mut Context<'a>,
layout: Layout<'a>,
structure: Symbol,
) -> Stmt<'a> {
// Reset is a fancy Decrement. When we recurse into child layouts we just want Dec.
ctx.op = HelperOp::Dec;
/*
assert layout is union
create the context, with op=Dec
load the rc value
- do I have a helper for this?
let isUnique = lowlevel Eq rc refcount_unique
switch
True => {
refcount union contents
ret structure
}
False => {
call specialized op Dec
let zero = 0
let typed_null = lowlevel PtrCast zero
ret typed_null
}
*/
todo!()
}
// Check if refcounting is implemented yet. In the long term, this will be deleted.
// In the short term, it helps us to skip refcounting and let it leak, so we can make
// progress incrementally. Kept in sync with generate_procs using assertions.
@ -786,7 +820,7 @@ fn refcount_union<'a>(
Recursive(tags) => {
let (is_tailrec, tail_idx) = root.union_tail_recursion_fields(union);
if is_tailrec && !ctx.op.is_decref() && !ctx.op.is_reset() {
if is_tailrec && !ctx.op.is_decref() {
refcount_union_tailrec(root, ident_ids, ctx, union, tags, None, tail_idx, structure)
} else {
refcount_union_rec(root, ident_ids, ctx, union, tags, None, structure)
@ -808,7 +842,7 @@ fn refcount_union<'a>(
} => {
let null_id = Some(nullable_id);
let (is_tailrec, tail_idx) = root.union_tail_recursion_fields(union);
if is_tailrec && !ctx.op.is_decref() && !ctx.op.is_reset() {
if is_tailrec && !ctx.op.is_decref() {
refcount_union_tailrec(
root, ident_ids, ctx, union, tags, null_id, tail_idx, structure,
)
@ -824,7 +858,7 @@ fn refcount_union<'a>(
let null_id = Some(nullable_id as TagIdIntType);
let tags = root.arena.alloc([other_fields]);
let (is_tailrec, tail_idx) = root.union_tail_recursion_fields(union);
if is_tailrec && !ctx.op.is_decref() && !ctx.op.is_reset() {
if is_tailrec && !ctx.op.is_decref() {
refcount_union_tailrec(
root, ident_ids, ctx, union, tags, null_id, tail_idx, structure,
)
@ -980,18 +1014,14 @@ fn refcount_union_rec<'a>(
let alignment = Layout::Union(union_layout).alignment_bytes(root.target_info);
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
let modify_structure_stmt = if ctx.op.is_reset() {
ret_stmt
} else {
modify_refcount(
root,
ident_ids,
ctx,
rc_ptr,
alignment,
root.arena.alloc(ret_stmt),
)
};
let modify_structure_stmt = modify_refcount(
root,
ident_ids,
ctx,
rc_ptr,
alignment,
root.arena.alloc(ret_stmt),
);
rc_ptr_from_data_ptr(
root,
@ -1020,13 +1050,13 @@ fn refcount_union_rec<'a>(
)
};
match ctx.op {
HelperOp::DecRef(_) if null_id.is_none() => rc_contents_then_structure,
HelperOp::Reset => rc_contents_then_structure,
_ => tag_id_stmt(root.arena.alloc(
if ctx.op.is_decref() && null_id.is_none() {
rc_contents_then_structure
} else {
tag_id_stmt(root.arena.alloc(
//
rc_contents_then_structure,
)),
))
}
}