mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
fix RC
This commit is contained in:
parent
345ecd434b
commit
ef3bda40c6
3 changed files with 58 additions and 53 deletions
|
@ -1103,7 +1103,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
field_vals.push(ptr);
|
field_vals.push(ptr);
|
||||||
} else {
|
} else {
|
||||||
// this check fails for recursive tag unions, but can be helpful while debugging
|
// this check fails for recursive tag unions, but can be helpful while debugging
|
||||||
debug_assert_eq!(tag_field_layout, val_layout);
|
// debug_assert_eq!(tag_field_layout, val_layout);
|
||||||
|
|
||||||
field_vals.push(val);
|
field_vals.push(val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,31 +345,12 @@ pub fn decrement_refcount_layout<'a, 'ctx, 'env>(
|
||||||
NullableUnion { foo: tags, .. } => {
|
NullableUnion { foo: tags, .. } => {
|
||||||
debug_assert!(value.is_pointer_value());
|
debug_assert!(value.is_pointer_value());
|
||||||
|
|
||||||
let ptr = value.into_pointer_value();
|
build_dec_rec_union(env, layout_ids, tags, value.into_pointer_value(), true);
|
||||||
let is_null = env.builder.build_is_null(ptr, "is_null");
|
|
||||||
|
|
||||||
let ctx = env.context;
|
|
||||||
let then_block = ctx.append_basic_block(parent, "then");
|
|
||||||
let cont_block = ctx.append_basic_block(parent, "cont");
|
|
||||||
|
|
||||||
env.builder.build_switch(
|
|
||||||
is_null,
|
|
||||||
cont_block,
|
|
||||||
&[(ctx.bool_type().const_int(1, false), then_block)],
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
|
||||||
env.builder.position_at_end(then_block);
|
|
||||||
build_dec_rec_union(env, layout_ids, tags, ptr);
|
|
||||||
env.builder.build_unconditional_branch(cont_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
env.builder.position_at_end(cont_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveUnion(tags) => {
|
RecursiveUnion(tags) => {
|
||||||
debug_assert!(value.is_pointer_value());
|
debug_assert!(value.is_pointer_value());
|
||||||
build_dec_rec_union(env, layout_ids, tags, value.into_pointer_value());
|
build_dec_rec_union(env, layout_ids, tags, value.into_pointer_value(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPointer(_, _) | Pointer(_) => {}
|
FunctionPointer(_, _) | Pointer(_) => {}
|
||||||
|
@ -455,31 +436,12 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>(
|
||||||
NullableUnion { foo: tags, .. } => {
|
NullableUnion { foo: tags, .. } => {
|
||||||
debug_assert!(value.is_pointer_value());
|
debug_assert!(value.is_pointer_value());
|
||||||
|
|
||||||
let ptr = value.into_pointer_value();
|
build_inc_rec_union(env, layout_ids, tags, value.into_pointer_value(), true);
|
||||||
let is_null = env.builder.build_is_null(ptr, "is_null");
|
|
||||||
|
|
||||||
let ctx = env.context;
|
|
||||||
let then_block = ctx.append_basic_block(parent, "then");
|
|
||||||
let cont_block = ctx.append_basic_block(parent, "cont");
|
|
||||||
|
|
||||||
env.builder.build_switch(
|
|
||||||
is_null,
|
|
||||||
cont_block,
|
|
||||||
&[(ctx.bool_type().const_int(1, false), then_block)],
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
|
||||||
env.builder.position_at_end(then_block);
|
|
||||||
build_inc_rec_union(env, layout_ids, tags, ptr);
|
|
||||||
env.builder.build_unconditional_branch(cont_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
env.builder.position_at_end(cont_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveUnion(tags) => {
|
RecursiveUnion(tags) => {
|
||||||
debug_assert!(value.is_pointer_value());
|
debug_assert!(value.is_pointer_value());
|
||||||
build_inc_rec_union(env, layout_ids, tags, value.into_pointer_value());
|
build_inc_rec_union(env, layout_ids, tags, value.into_pointer_value(), false);
|
||||||
}
|
}
|
||||||
Closure(_, closure_layout, _) => {
|
Closure(_, closure_layout, _) => {
|
||||||
if closure_layout.contains_refcounted() {
|
if closure_layout.contains_refcounted() {
|
||||||
|
@ -1089,6 +1051,7 @@ pub fn build_dec_rec_union<'a, 'ctx, 'env>(
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
fields: &'a [&'a [Layout<'a>]],
|
fields: &'a [&'a [Layout<'a>]],
|
||||||
value: PointerValue<'ctx>,
|
value: PointerValue<'ctx>,
|
||||||
|
is_nullable: bool,
|
||||||
) {
|
) {
|
||||||
let layout = Layout::RecursiveUnion(fields);
|
let layout = Layout::RecursiveUnion(fields);
|
||||||
|
|
||||||
|
@ -1105,7 +1068,7 @@ pub fn build_dec_rec_union<'a, 'ctx, 'env>(
|
||||||
None => {
|
None => {
|
||||||
let function_value = build_header(env, &layout, &fn_name);
|
let function_value = build_header(env, &layout, &fn_name);
|
||||||
|
|
||||||
build_dec_rec_union_help(env, layout_ids, fields, function_value);
|
build_dec_rec_union_help(env, layout_ids, fields, function_value, is_nullable);
|
||||||
|
|
||||||
function_value
|
function_value
|
||||||
}
|
}
|
||||||
|
@ -1127,6 +1090,7 @@ pub fn build_dec_rec_union_help<'a, 'ctx, 'env>(
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
tags: &[&[Layout<'a>]],
|
tags: &[&[Layout<'a>]],
|
||||||
fn_val: FunctionValue<'ctx>,
|
fn_val: FunctionValue<'ctx>,
|
||||||
|
is_nullable: bool,
|
||||||
) {
|
) {
|
||||||
debug_assert!(!tags.is_empty());
|
debug_assert!(!tags.is_empty());
|
||||||
|
|
||||||
|
@ -1167,11 +1131,31 @@ pub fn build_dec_rec_union_help<'a, 'ctx, 'env>(
|
||||||
let parent = fn_val;
|
let parent = fn_val;
|
||||||
|
|
||||||
let layout = Layout::RecursiveUnion(tags);
|
let layout = Layout::RecursiveUnion(tags);
|
||||||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
|
||||||
|
|
||||||
debug_assert!(arg_val.is_pointer_value());
|
debug_assert!(arg_val.is_pointer_value());
|
||||||
let value_ptr = arg_val.into_pointer_value();
|
let value_ptr = arg_val.into_pointer_value();
|
||||||
|
|
||||||
|
let ctx = env.context;
|
||||||
|
let cont_block = ctx.append_basic_block(parent, "cont");
|
||||||
|
if is_nullable {
|
||||||
|
let is_null = env.builder.build_is_null(value_ptr, "is_null");
|
||||||
|
|
||||||
|
let then_block = ctx.append_basic_block(parent, "then");
|
||||||
|
|
||||||
|
env.builder.build_switch(
|
||||||
|
is_null,
|
||||||
|
cont_block,
|
||||||
|
&[(ctx.bool_type().const_int(1, false), then_block)],
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
env.builder.position_at_end(then_block);
|
||||||
|
env.builder.build_return(None);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
env.builder.build_unconditional_branch(cont_block);
|
||||||
|
}
|
||||||
|
|
||||||
// next, make a jump table for all possible values of the tag_id
|
// next, make a jump table for all possible values of the tag_id
|
||||||
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
|
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
|
||||||
|
|
||||||
|
@ -1261,7 +1245,7 @@ pub fn build_dec_rec_union_help<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
cases.reverse();
|
cases.reverse();
|
||||||
|
|
||||||
env.builder.position_at_end(before_block);
|
env.builder.position_at_end(cont_block);
|
||||||
|
|
||||||
// read the tag_id
|
// read the tag_id
|
||||||
let current_tag_id = rec_union_read_tag(env, value_ptr);
|
let current_tag_id = rec_union_read_tag(env, value_ptr);
|
||||||
|
@ -1449,6 +1433,7 @@ pub fn build_inc_rec_union<'a, 'ctx, 'env>(
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
fields: &'a [&'a [Layout<'a>]],
|
fields: &'a [&'a [Layout<'a>]],
|
||||||
value: PointerValue<'ctx>,
|
value: PointerValue<'ctx>,
|
||||||
|
is_nullable: bool,
|
||||||
) {
|
) {
|
||||||
let layout = Layout::RecursiveUnion(fields);
|
let layout = Layout::RecursiveUnion(fields);
|
||||||
|
|
||||||
|
@ -1465,7 +1450,7 @@ pub fn build_inc_rec_union<'a, 'ctx, 'env>(
|
||||||
None => {
|
None => {
|
||||||
let function_value = build_header(env, &layout, &fn_name);
|
let function_value = build_header(env, &layout, &fn_name);
|
||||||
|
|
||||||
build_inc_rec_union_help(env, layout_ids, fields, function_value);
|
build_inc_rec_union_help(env, layout_ids, fields, function_value, is_nullable);
|
||||||
|
|
||||||
function_value
|
function_value
|
||||||
}
|
}
|
||||||
|
@ -1507,6 +1492,7 @@ pub fn build_inc_rec_union_help<'a, 'ctx, 'env>(
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
tags: &[&[Layout<'a>]],
|
tags: &[&[Layout<'a>]],
|
||||||
fn_val: FunctionValue<'ctx>,
|
fn_val: FunctionValue<'ctx>,
|
||||||
|
is_nullable: bool,
|
||||||
) {
|
) {
|
||||||
debug_assert!(!tags.is_empty());
|
debug_assert!(!tags.is_empty());
|
||||||
|
|
||||||
|
@ -1546,15 +1532,30 @@ pub fn build_inc_rec_union_help<'a, 'ctx, 'env>(
|
||||||
let parent = fn_val;
|
let parent = fn_val;
|
||||||
|
|
||||||
let layout = Layout::RecursiveUnion(tags);
|
let layout = Layout::RecursiveUnion(tags);
|
||||||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
|
||||||
|
|
||||||
debug_assert!(arg_val.is_pointer_value());
|
debug_assert!(arg_val.is_pointer_value());
|
||||||
let value_ptr = arg_val.into_pointer_value();
|
let value_ptr = arg_val.into_pointer_value();
|
||||||
|
|
||||||
// read the tag_id
|
let ctx = env.context;
|
||||||
let tag_id = rec_union_read_tag(env, value_ptr);
|
let cont_block = ctx.append_basic_block(parent, "cont");
|
||||||
|
if is_nullable {
|
||||||
|
let is_null = env.builder.build_is_null(value_ptr, "is_null");
|
||||||
|
|
||||||
let tag_id_u8 = cast_basic_basic(env.builder, tag_id.into(), env.context.i8_type().into());
|
let then_block = ctx.append_basic_block(parent, "then");
|
||||||
|
|
||||||
|
env.builder.build_switch(
|
||||||
|
is_null,
|
||||||
|
cont_block,
|
||||||
|
&[(ctx.bool_type().const_int(1, false), then_block)],
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
env.builder.position_at_end(then_block);
|
||||||
|
env.builder.build_return(None);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
env.builder.build_unconditional_branch(cont_block);
|
||||||
|
}
|
||||||
|
|
||||||
// next, make a jump table for all possible values of the tag_id
|
// next, make a jump table for all possible values of the tag_id
|
||||||
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
|
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
|
||||||
|
@ -1636,7 +1637,12 @@ pub fn build_inc_rec_union_help<'a, 'ctx, 'env>(
|
||||||
cases.push((env.context.i8_type().const_int(tag_id as u64, false), block));
|
cases.push((env.context.i8_type().const_int(tag_id as u64, false), block));
|
||||||
}
|
}
|
||||||
|
|
||||||
env.builder.position_at_end(before_block);
|
env.builder.position_at_end(cont_block);
|
||||||
|
|
||||||
|
// read the tag_id
|
||||||
|
let tag_id = rec_union_read_tag(env, value_ptr);
|
||||||
|
|
||||||
|
let tag_id_u8 = cast_basic_basic(env.builder, tag_id.into(), env.context.i8_type().into());
|
||||||
|
|
||||||
env.builder
|
env.builder
|
||||||
.build_switch(tag_id_u8.into_int_value(), merge_block, &cases);
|
.build_switch(tag_id_u8.into_int_value(), merge_block, &cases);
|
||||||
|
|
|
@ -891,7 +891,6 @@ pub fn optimize_when<'a>(
|
||||||
ret_layout: Layout<'a>,
|
ret_layout: Layout<'a>,
|
||||||
opt_branches: bumpalo::collections::Vec<'a, (Pattern<'a>, Guard<'a>, Stmt<'a>)>,
|
opt_branches: bumpalo::collections::Vec<'a, (Pattern<'a>, Guard<'a>, Stmt<'a>)>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
dbg!(&opt_branches);
|
|
||||||
let (patterns, _indexed_branches) = opt_branches
|
let (patterns, _indexed_branches) = opt_branches
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue