mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
make box decrement its contents when free'ing
This commit is contained in:
parent
2ea69f07ef
commit
25d2d090e8
2 changed files with 51 additions and 5 deletions
|
@ -878,7 +878,14 @@ fn modify_refcount_boxed<'a, 'ctx, 'env>(
|
|||
let basic_type = basic_type_from_layout(env, layout_interner, boxed_layout);
|
||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||
|
||||
modify_refcount_box_help(env, layout_interner, mode, inner_layout, function_value);
|
||||
modify_refcount_box_help(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
mode,
|
||||
inner_layout,
|
||||
function_value,
|
||||
);
|
||||
|
||||
function_value
|
||||
}
|
||||
|
@ -893,6 +900,7 @@ fn modify_refcount_boxed<'a, 'ctx, 'env>(
|
|||
fn modify_refcount_box_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
inner_layout: InLayout<'a>,
|
||||
fn_val: FunctionValue<'ctx>,
|
||||
|
@ -916,10 +924,49 @@ fn modify_refcount_box_help<'a, 'ctx, 'env>(
|
|||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, boxed);
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
let boxed_layout = layout_interner.insert(Layout::Boxed(inner_layout));
|
||||
refcount_ptr.modify(call_mode, boxed_layout, env, layout_interner);
|
||||
|
||||
// this function returns void
|
||||
builder.build_return(None);
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
refcount_ptr.modify(call_mode, boxed_layout, env, layout_interner);
|
||||
builder.build_return(None);
|
||||
}
|
||||
Mode::Dec => {
|
||||
// if the box is unique, also decrement its inner value
|
||||
let do_recurse_block = env.context.append_basic_block(fn_val, "do_recurse");
|
||||
let no_recurse_block = env.context.append_basic_block(fn_val, "no_recurse");
|
||||
|
||||
builder.build_conditional_branch(
|
||||
refcount_ptr.is_1(env),
|
||||
do_recurse_block,
|
||||
no_recurse_block,
|
||||
);
|
||||
|
||||
{
|
||||
env.builder.position_at_end(do_recurse_block);
|
||||
|
||||
let inner = load_roc_value(env, layout_interner, inner_layout, boxed, "inner");
|
||||
|
||||
modify_refcount_layout(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
call_mode,
|
||||
inner,
|
||||
inner_layout,
|
||||
);
|
||||
|
||||
refcount_ptr.modify(call_mode, boxed_layout, env, layout_interner);
|
||||
env.builder.build_return(None);
|
||||
}
|
||||
|
||||
{
|
||||
env.builder.position_at_end(no_recurse_block);
|
||||
|
||||
refcount_ptr.modify(call_mode, boxed_layout, env, layout_interner);
|
||||
env.builder.build_return(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build an increment or decrement function for a specific layout
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue