mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
change over nullable wrapped
This commit is contained in:
parent
71857e83d0
commit
8add147dcf
5 changed files with 230 additions and 152 deletions
|
@ -4,7 +4,9 @@ use crate::llvm::build::{
|
|||
LLVM_SADD_WITH_OVERFLOW_I64, TAG_DATA_INDEX, TAG_ID_INDEX,
|
||||
};
|
||||
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
|
||||
use crate::llvm::convert::{basic_type_from_layout, block_of_memory_slices, ptr_int};
|
||||
use crate::llvm::convert::{
|
||||
basic_type_from_layout, block_of_memory_slices, ptr_int, union_data_block_of_memory,
|
||||
};
|
||||
use bumpalo::collections::Vec;
|
||||
use inkwell::basic_block::BasicBlock;
|
||||
use inkwell::context::Context;
|
||||
|
@ -651,6 +653,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
tags,
|
||||
true,
|
||||
);
|
||||
|
@ -666,6 +669,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
&*env.arena.alloc([other_fields]),
|
||||
true,
|
||||
);
|
||||
|
@ -679,6 +683,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
&*env.arena.alloc([*fields]),
|
||||
true,
|
||||
);
|
||||
|
@ -691,6 +696,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
tags,
|
||||
false,
|
||||
);
|
||||
|
@ -1203,10 +1209,11 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
fields: &'a [&'a [Layout<'a>]],
|
||||
union_layout: UnionLayout<'a>,
|
||||
tags: &'a [&'a [Layout<'a>]],
|
||||
is_nullable: bool,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let layout = Layout::Union(UnionLayout::Recursive(fields));
|
||||
let layout = Layout::Union(UnionLayout::Recursive(tags));
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -1223,9 +1230,7 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let basic_type = block_of_memory_slices(env.context, fields, env.ptr_bytes)
|
||||
.ptr_type(AddressSpace::Generic)
|
||||
.into();
|
||||
let basic_type = basic_type_from_layout(env, &Layout::Union(union_layout));
|
||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||
|
||||
build_rec_union_help(
|
||||
|
@ -1233,7 +1238,8 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
mode,
|
||||
when_recursive,
|
||||
fields,
|
||||
union_layout,
|
||||
tags,
|
||||
function_value,
|
||||
is_nullable,
|
||||
);
|
||||
|
@ -1249,11 +1255,13 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
|||
function
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
tags: &'a [&'a [roc_mono::layout::Layout<'a>]],
|
||||
fn_val: FunctionValue<'ctx>,
|
||||
is_nullable: bool,
|
||||
|
@ -1279,8 +1287,6 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
|||
|
||||
let parent = fn_val;
|
||||
|
||||
let layout = Layout::Union(UnionLayout::Recursive(tags));
|
||||
|
||||
debug_assert!(arg_val.is_pointer_value());
|
||||
let value_ptr = arg_val.into_pointer_value();
|
||||
|
||||
|
@ -1309,6 +1315,8 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(should_recurse_block);
|
||||
|
||||
let layout = Layout::Union(union_layout);
|
||||
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
// inc is cheap; we never recurse
|
||||
|
@ -1342,7 +1350,7 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
|||
when_recursive,
|
||||
parent,
|
||||
fn_val,
|
||||
layout,
|
||||
union_layout,
|
||||
tags,
|
||||
value_ptr,
|
||||
refcount_ptr,
|
||||
|
@ -1360,7 +1368,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
when_recursive: &WhenRecursive<'a>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
decrement_fn: FunctionValue<'ctx>,
|
||||
layout: Layout<'a>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
tags: &[&[Layout<'a>]],
|
||||
value_ptr: PointerValue<'ctx>,
|
||||
refcount_ptr: PointerToRefcount<'ctx>,
|
||||
|
@ -1433,7 +1441,15 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
debug_assert!(ptr_as_i64_ptr.is_pointer_value());
|
||||
|
||||
// therefore we must cast it to our desired type
|
||||
let union_type = block_of_memory_slices(env.context, tags, env.ptr_bytes);
|
||||
|
||||
let union_type = match union_layout {
|
||||
UnionLayout::Recursive(_) | UnionLayout::NullableWrapped { .. } => {
|
||||
union_data_block_of_memory(env.context, tags, env.ptr_bytes).into()
|
||||
}
|
||||
UnionLayout::NonRecursive(_) => unreachable!(),
|
||||
_ => block_of_memory_slices(env.context, tags, env.ptr_bytes),
|
||||
};
|
||||
|
||||
let recursive_field_ptr = cast_basic_basic(
|
||||
env.builder,
|
||||
ptr_as_i64_ptr,
|
||||
|
@ -1461,7 +1477,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
// lists. To achieve it, we must first load all fields that we want to inc/dec (done above)
|
||||
// and store them on the stack, then modify (and potentially free) the current cell, then
|
||||
// actually inc/dec the fields.
|
||||
refcount_ptr.modify(call_mode, &layout, env);
|
||||
refcount_ptr.modify(call_mode, &Layout::Union(union_layout), env);
|
||||
|
||||
for (field, field_layout) in deferred_nonrec {
|
||||
modify_refcount_layout_help(
|
||||
|
@ -1514,7 +1530,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
env.builder.position_at_end(merge_block);
|
||||
|
||||
// increment/decrement the cons-cell itself
|
||||
refcount_ptr.modify(call_mode, &layout, env);
|
||||
refcount_ptr.modify(call_mode, &Layout::Union(union_layout), env);
|
||||
|
||||
// this function returns void
|
||||
builder.build_return(None);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue