mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
move the heap cell out of the union
This commit is contained in:
parent
92cca127b1
commit
5b8c63d292
1 changed files with 37 additions and 22 deletions
|
@ -215,7 +215,10 @@ where
|
||||||
debug_assert_eq!(variant_types.len(), 1);
|
debug_assert_eq!(variant_types.len(), 1);
|
||||||
variant_types[0]
|
variant_types[0]
|
||||||
} else {
|
} else {
|
||||||
builder.add_union_type(&variant_types)?
|
let data_type = builder.add_union_type(&variant_types)?;
|
||||||
|
let cell_type = builder.add_heap_cell_type();
|
||||||
|
|
||||||
|
builder.add_tuple_type(&[cell_type, data_type])?
|
||||||
};
|
};
|
||||||
|
|
||||||
let type_def = builder.build(root_type)?;
|
let type_def = builder.build(root_type)?;
|
||||||
|
@ -1374,10 +1377,7 @@ fn recursive_tag_variant(
|
||||||
) -> Result<TypeId> {
|
) -> Result<TypeId> {
|
||||||
let when_recursive = WhenRecursive::Loop(*union_layout);
|
let when_recursive = WhenRecursive::Loop(*union_layout);
|
||||||
|
|
||||||
let data_id = build_recursive_tuple_type(builder, fields, &when_recursive)?;
|
build_recursive_tuple_type(builder, fields, &when_recursive)
|
||||||
let cell_id = builder.add_heap_cell_type();
|
|
||||||
|
|
||||||
builder.add_tuple_type(&[cell_id, data_id])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recursive_variant_types(
|
fn recursive_variant_types(
|
||||||
|
@ -1479,7 +1479,7 @@ fn expr_spec<'a>(
|
||||||
return builder.add_make_union(block, &variant_types, *tag_id as u32, value_id);
|
return builder.add_make_union(block, &variant_types, *tag_id as u32, value_id);
|
||||||
}
|
}
|
||||||
UnionLayout::NonNullableUnwrapped(_) => {
|
UnionLayout::NonNullableUnwrapped(_) => {
|
||||||
let value_id = with_new_heap_cell(builder, block, data_id)?;
|
let value_id = data_id;
|
||||||
|
|
||||||
let type_name_bytes = recursive_tag_union_name_bytes(tag_layout).as_bytes();
|
let type_name_bytes = recursive_tag_union_name_bytes(tag_layout).as_bytes();
|
||||||
let type_name = TypeName(&type_name_bytes);
|
let type_name = TypeName(&type_name_bytes);
|
||||||
|
@ -1488,11 +1488,9 @@ fn expr_spec<'a>(
|
||||||
|
|
||||||
return builder.add_make_named(block, MOD_APP, type_name, value_id);
|
return builder.add_make_named(block, MOD_APP, type_name, value_id);
|
||||||
}
|
}
|
||||||
UnionLayout::Recursive(_) => with_new_heap_cell(builder, block, data_id)?,
|
UnionLayout::Recursive(_) => data_id,
|
||||||
UnionLayout::NullableWrapped { .. } => with_new_heap_cell(builder, block, data_id)?,
|
UnionLayout::NullableWrapped { .. } => data_id,
|
||||||
UnionLayout::NullableUnwrapped { .. } => {
|
UnionLayout::NullableUnwrapped { .. } => data_id,
|
||||||
with_new_heap_cell(builder, block, data_id)?
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_types = recursive_variant_types(builder, tag_layout)?;
|
let variant_types = recursive_variant_types(builder, tag_layout)?;
|
||||||
|
@ -1500,12 +1498,14 @@ fn expr_spec<'a>(
|
||||||
let union_id =
|
let union_id =
|
||||||
builder.add_make_union(block, &variant_types, *tag_id as u32, value_id)?;
|
builder.add_make_union(block, &variant_types, *tag_id as u32, value_id)?;
|
||||||
|
|
||||||
|
let tag_value_id = with_new_heap_cell(builder, block, union_id)?;
|
||||||
|
|
||||||
let type_name_bytes = recursive_tag_union_name_bytes(tag_layout).as_bytes();
|
let type_name_bytes = recursive_tag_union_name_bytes(tag_layout).as_bytes();
|
||||||
let type_name = TypeName(&type_name_bytes);
|
let type_name = TypeName(&type_name_bytes);
|
||||||
|
|
||||||
env.type_names.insert(*tag_layout);
|
env.type_names.insert(*tag_layout);
|
||||||
|
|
||||||
builder.add_make_named(block, MOD_APP, type_name, union_id)
|
builder.add_make_named(block, MOD_APP, type_name, tag_value_id)
|
||||||
}
|
}
|
||||||
Struct(fields) => build_tuple_value(builder, env, block, fields),
|
Struct(fields) => build_tuple_value(builder, env, block, fields),
|
||||||
UnionAtIndex {
|
UnionAtIndex {
|
||||||
|
@ -1531,16 +1531,20 @@ fn expr_spec<'a>(
|
||||||
let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
|
let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
|
||||||
let type_name = TypeName(&type_name_bytes);
|
let type_name = TypeName(&type_name_bytes);
|
||||||
|
|
||||||
|
// unwrap the named wrapper
|
||||||
let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
|
let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
|
||||||
let variant_id = builder.add_unwrap_union(block, union_id, *tag_id as u32)?;
|
|
||||||
|
// now we have a tuple (cell, union { ... }); decompose
|
||||||
|
let heap_cell = builder.add_get_tuple_field(block, union_id, TAG_CELL_INDEX)?;
|
||||||
|
let union_data = builder.add_get_tuple_field(block, union_id, TAG_DATA_INDEX)?;
|
||||||
|
|
||||||
// we're reading from this value, so touch the heap cell
|
// we're reading from this value, so touch the heap cell
|
||||||
let heap_cell = builder.add_get_tuple_field(block, variant_id, 0)?;
|
|
||||||
builder.add_touch(block, heap_cell)?;
|
builder.add_touch(block, heap_cell)?;
|
||||||
|
|
||||||
let tuple_value_id = builder.add_get_tuple_field(block, variant_id, 1)?;
|
// next, unwrap the union at the tag id that we've got
|
||||||
|
let variant_id = builder.add_unwrap_union(block, union_data, *tag_id as u32)?;
|
||||||
|
|
||||||
builder.add_get_tuple_field(block, tuple_value_id, index)
|
builder.add_get_tuple_field(block, variant_id, index)
|
||||||
}
|
}
|
||||||
UnionLayout::NonNullableUnwrapped { .. } => {
|
UnionLayout::NonNullableUnwrapped { .. } => {
|
||||||
let index = (*index) as u32;
|
let index = (*index) as u32;
|
||||||
|
@ -1551,16 +1555,20 @@ fn expr_spec<'a>(
|
||||||
let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
|
let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
|
||||||
let type_name = TypeName(&type_name_bytes);
|
let type_name = TypeName(&type_name_bytes);
|
||||||
|
|
||||||
let variant_id =
|
// a tuple ( cell, union { ... } )
|
||||||
builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
|
let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
|
||||||
|
|
||||||
|
// decompose
|
||||||
|
let heap_cell = builder.add_get_tuple_field(block, union_id, TAG_CELL_INDEX)?;
|
||||||
|
let union_data = builder.add_get_tuple_field(block, union_id, TAG_DATA_INDEX)?;
|
||||||
|
|
||||||
// we're reading from this value, so touch the heap cell
|
// we're reading from this value, so touch the heap cell
|
||||||
let heap_cell = builder.add_get_tuple_field(block, variant_id, 0)?;
|
|
||||||
builder.add_touch(block, heap_cell)?;
|
builder.add_touch(block, heap_cell)?;
|
||||||
|
|
||||||
let tuple_value_id = builder.add_get_tuple_field(block, variant_id, 1)?;
|
// next, unwrap the union at the tag id that we've got
|
||||||
|
let variant_id = builder.add_unwrap_union(block, union_data, *tag_id as u32)?;
|
||||||
|
|
||||||
builder.add_get_tuple_field(block, tuple_value_id, index)
|
builder.add_get_tuple_field(block, variant_id, index)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
StructAtIndex {
|
StructAtIndex {
|
||||||
|
@ -1613,7 +1621,11 @@ fn expr_spec<'a>(
|
||||||
|
|
||||||
builder.add_terminate(block, type_id)
|
builder.add_terminate(block, type_id)
|
||||||
}
|
}
|
||||||
GetTagId { .. } => builder.add_make_tuple(block, &[]),
|
GetTagId { .. } => {
|
||||||
|
// TODO touch heap cell in recursive cases
|
||||||
|
|
||||||
|
builder.add_make_tuple(block, &[])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1767,6 +1779,9 @@ const LIST_BAG_INDEX: u32 = 1;
|
||||||
const DICT_CELL_INDEX: u32 = LIST_CELL_INDEX;
|
const DICT_CELL_INDEX: u32 = LIST_CELL_INDEX;
|
||||||
const DICT_BAG_INDEX: u32 = LIST_BAG_INDEX;
|
const DICT_BAG_INDEX: u32 = LIST_BAG_INDEX;
|
||||||
|
|
||||||
|
const TAG_CELL_INDEX: u32 = 0;
|
||||||
|
const TAG_DATA_INDEX: u32 = 1;
|
||||||
|
|
||||||
fn with_new_heap_cell(
|
fn with_new_heap_cell(
|
||||||
builder: &mut FuncDefBuilder,
|
builder: &mut FuncDefBuilder,
|
||||||
block: BlockId,
|
block: BlockId,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue