Update dev and wasm backend to use new list bitcode args

This commit is contained in:
Brendan Hansknecht 2024-04-09 21:57:40 -07:00
parent c79febb52d
commit d5e91ed61e
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
5 changed files with 479 additions and 140 deletions

View file

@ -2278,6 +2278,25 @@ impl<
refcount_proc_name
}
fn build_indirect_inc_n(&mut self, layout: InLayout<'a>) -> Symbol {
let ident_ids = self
.interns
.all_ident_ids
.get_mut(&self.env.module_id)
.unwrap();
let (refcount_proc_name, linker_data) = self.helper_proc_gen.gen_refcount_proc(
ident_ids,
self.layout_interner,
layout,
HelperOp::IndirectIncN,
);
self.helper_proc_symbols_mut().extend(linker_data);
refcount_proc_name
}
fn build_indirect_dec(&mut self, layout: InLayout<'a>) -> Symbol {
let ident_ids = self
.interns
@ -2348,7 +2367,7 @@ impl<
// function pointer to a function that takes a pointer, and increments
let inc_n_data = if let Some(closure_env_layout) = higher_order.closure_env_layout {
self.increment_fn_pointer(closure_env_layout)
self.increment_n_fn_pointer(closure_env_layout)
} else {
// null pointer
self.load_literal_i64(&Symbol::DEV_TMP, 0);
@ -2404,6 +2423,9 @@ impl<
&Literal::Bool(data_is_owned),
);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(new_element_layout, Symbol::DEV_TMP3);
// list: RocList,
// caller: Caller1,
// data: Opaque,
@ -2412,6 +2434,7 @@ impl<
// alignment: u32,
// old_element_width: usize,
// new_element_width: usize,
// new_element_refcounted: bool,
let arguments = [
xs,
@ -2422,6 +2445,7 @@ impl<
alignment,
old_element_width,
new_element_width,
Symbol::DEV_TMP3,
];
let layouts = [
@ -2433,6 +2457,7 @@ impl<
Layout::U32,
usize_,
usize_,
Layout::BOOL,
];
self.build_fn_call_stack_return(
@ -2445,6 +2470,7 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
}
HigherOrder::ListMap2 { xs, ys } => {
let old_element_layout1 = argument_layouts[0];
@ -2488,6 +2514,9 @@ impl<
&Literal::Bool(data_is_owned),
);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(new_element_layout, Symbol::DEV_TMP3);
// list1: RocList,
// list2: RocList,
// caller: Caller1,
@ -2498,6 +2527,7 @@ impl<
// old_element_width1: usize,
// old_element_width2: usize,
// new_element_width: usize,
// new_element_refcounted: bool,
let arguments = [
xs,
@ -2512,6 +2542,7 @@ impl<
new_element_width,
dec1,
dec2,
Symbol::DEV_TMP3,
];
let layouts = [
@ -2525,8 +2556,9 @@ impl<
usize_,
usize_,
usize_,
ptr, // dec1
ptr, // dec2
ptr, // dec1
ptr, // dec2
Layout::BOOL, // new_element_refcounted
];
self.build_fn_call_stack_return(
@ -2539,6 +2571,7 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
}
HigherOrder::ListMap3 { xs, ys, zs } => {
let old_element_layout1 = argument_layouts[0];
@ -2591,6 +2624,9 @@ impl<
&Literal::Bool(data_is_owned),
);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(new_element_layout, Symbol::DEV_TMP3);
// list1: RocList,
// list2: RocList,
// caller: Caller1,
@ -2601,6 +2637,7 @@ impl<
// old_element_width1: usize,
// old_element_width2: usize,
// new_element_width: usize,
// new_element_refcounted: bool,
let arguments = [
xs,
@ -2618,6 +2655,7 @@ impl<
dec1,
dec2,
dec3,
Symbol::DEV_TMP3,
];
let layouts = [
@ -2629,13 +2667,14 @@ impl<
ptr,
Layout::BOOL,
Layout::U32,
usize_, // old_element_width_1
usize_, // old_element_width_2
usize_, // old_element_width_3
usize_, // new_element_width
ptr, // dec1
ptr, // dec2
ptr, // dec3
usize_, // old_element_width_1
usize_, // old_element_width_2
usize_, // old_element_width_3
usize_, // new_element_width
ptr, // dec1
ptr, // dec2
ptr, // dec3
Layout::BOOL, // new_element_refcounted
];
self.build_fn_call_stack_return(
@ -2648,6 +2687,7 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
}
HigherOrder::ListMap4 { xs, ys, zs, ws } => {
let old_element_layout1 = argument_layouts[0];
@ -2709,6 +2749,9 @@ impl<
&Literal::Bool(data_is_owned),
);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(new_element_layout, Symbol::DEV_TMP3);
let arguments = [
xs,
ys,
@ -2728,6 +2771,7 @@ impl<
dec2,
dec3,
dec4,
Symbol::DEV_TMP3,
];
let layouts = [
@ -2740,15 +2784,16 @@ impl<
ptr,
Layout::BOOL,
Layout::U32,
usize_, // old_element_width_1
usize_, // old_element_width_2
usize_, // old_element_width_3
usize_, // old_element_width_4
usize_, // new_element_width
ptr, // dec1
ptr, // dec2
ptr, // dec3
ptr, // dec4
usize_, // old_element_width_1
usize_, // old_element_width_2
usize_, // old_element_width_3
usize_, // old_element_width_4
usize_, // new_element_width
ptr, // dec1
ptr, // dec2
ptr, // dec3
ptr, // dec4
Layout::BOOL, // new_element_refcounted
];
self.build_fn_call_stack_return(
@ -2761,6 +2806,7 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
}
HigherOrder::ListSortWith { xs } => {
let element_layout = argument_layouts[0];
@ -2788,6 +2834,12 @@ impl<
&Literal::Bool(data_is_owned),
);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(element_layout, Symbol::DEV_TMP3);
let inc_elem_fn = self.increment_fn_pointer(element_layout);
let dec_elem_fn = self.decrement_fn_pointer(element_layout);
// input: RocList,
// caller: CompareFn,
// data: Opaque,
@ -2795,6 +2847,9 @@ impl<
// data_is_owned: bool,
// alignment: u32,
// element_width: usize,
// element_refcounted: bool,
// inc: Inc,
// dec: Dec,
let arguments = [
xs,
@ -2804,6 +2859,9 @@ impl<
Symbol::DEV_TMP2,
alignment,
element_width,
Symbol::DEV_TMP3,
inc_elem_fn,
dec_elem_fn,
];
let layouts = [
@ -2814,6 +2872,9 @@ impl<
Layout::BOOL,
Layout::U32,
usize_,
Layout::BOOL,
usize_,
usize_,
];
self.build_fn_call_stack_return(
@ -2852,6 +2913,12 @@ impl<
// Load element_width argument (usize).
self.load_layout_stack_size(elem_layout, Symbol::DEV_TMP2);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
// Setup the return location.
let base_offset =
self.storage_manager
@ -2863,11 +2930,17 @@ impl<
Symbol::DEV_TMP,
// element_width
Symbol::DEV_TMP2,
// element_refcounted
Symbol::DEV_TMP3,
// inc
inc_elem_fn,
// dec
dec_elem_fn,
];
let lowlevel_arg_layouts = [ret_layout, Layout::U32, Layout::U64];
self.build_fn_call(
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
bitcode::LIST_CLONE.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -2875,17 +2948,18 @@ impl<
);
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
// Copy from list to the output record.
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
base_offset,
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
&ret_layout,
);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
}
fn build_list_with_capacity(
@ -2902,6 +2976,11 @@ impl<
// Load element_width argument (usize).
self.load_layout_stack_size(elem_layout, Symbol::DEV_TMP2);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
// Setup the return location.
let base_offset =
self.storage_manager
@ -2913,11 +2992,15 @@ impl<
Symbol::DEV_TMP,
// element_width
Symbol::DEV_TMP2,
// element_refcounted
Symbol::DEV_TMP3,
// Inc element fn
inc_elem_fn,
];
let lowlevel_arg_layouts = [capacity_layout, Layout::U32, Layout::U64];
self.build_fn_call(
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
bitcode::LIST_WITH_CAPACITY.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -2925,17 +3008,18 @@ impl<
);
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
// Copy from list to the output record.
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
base_offset,
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
ret_layout,
);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
}
fn build_list_reserve(
@ -2959,12 +3043,15 @@ impl<
_ => unreachable!(),
};
self.load_layout_stack_size(element_layout, Symbol::DEV_TMP2);
self.load_layout_refcounted(element_layout, Symbol::DEV_TMP3);
let inc_elem_fn = self.increment_fn_pointer(element_layout);
// Load UpdateMode.Immutable argument (0u8)
let u8_layout = Layout::U8;
let update_mode = 0u8;
self.load_literal(
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
&u8_layout,
&Literal::Int((update_mode as i128).to_ne_bytes()),
);
@ -2982,9 +3069,12 @@ impl<
spare,
// element_width
Symbol::DEV_TMP2,
// update_mode
// element_refcounted
Symbol::DEV_TMP3,
// Inc element fn
inc_elem_fn,
// update_mode
Symbol::DEV_TMP4,
];
let lowlevel_arg_layouts = [
list_layout,
@ -2995,7 +3085,7 @@ impl<
];
self.build_fn_call(
&Symbol::DEV_TMP4,
&Symbol::DEV_TMP5,
bitcode::LIST_RESERVE.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -3004,17 +3094,18 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
// Return list value from fn call
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
base_offset,
&Symbol::DEV_TMP4,
&Symbol::DEV_TMP5,
ret_layout,
);
self.free_symbol(&Symbol::DEV_TMP4);
self.free_symbol(&Symbol::DEV_TMP5);
}
fn build_list_append_unsafe(
@ -3155,6 +3246,12 @@ impl<
// Load the elements size.
self.load_layout_stack_size(elem_layout, Symbol::DEV_TMP3);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP4);
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
// Setup the return location.
let base_offset =
self.storage_manager
@ -3188,7 +3285,7 @@ impl<
// Load address of output element into register.
let reg = self
.storage_manager
.claim_general_reg(&mut self.buf, &Symbol::DEV_TMP4);
.claim_general_reg(&mut self.buf, &Symbol::DEV_TMP5);
ASM::add_reg64_reg64_imm32(&mut self.buf, reg, CC::BASE_PTR_REG, out_elem_offset);
let lowlevel_args = bumpalo::vec![
@ -3199,6 +3296,9 @@ impl<
Symbol::DEV_TMP2,
Symbol::DEV_TMP3,
Symbol::DEV_TMP4,
inc_elem_fn,
dec_elem_fn,
Symbol::DEV_TMP5,
];
let lowlevel_arg_layouts = [
list_layout,
@ -3206,11 +3306,15 @@ impl<
index_layout,
u64_layout,
u64_layout,
Layout::BOOL,
u64_layout,
u64_layout,
u64_layout,
];
let out = self.debug_symbol("out");
self.build_fn_call(
&Symbol::DEV_TMP5,
&out,
bitcode::LIST_REPLACE.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -3220,17 +3324,18 @@ impl<
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
self.free_symbol(&Symbol::DEV_TMP5);
// Copy from list to the output record.
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
out_list_offset,
&Symbol::DEV_TMP5,
&out,
&list_layout,
);
self.free_symbol(&Symbol::DEV_TMP5);
self.free_symbol(&out);
}
fn build_list_concat(
@ -3252,6 +3357,12 @@ impl<
// Load element_width argument (usize).
self.load_layout_stack_size(elem_layout, Symbol::DEV_TMP2);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
// Setup the return location.
let base_offset =
self.storage_manager
@ -3265,11 +3376,23 @@ impl<
Symbol::DEV_TMP,
// element_width
Symbol::DEV_TMP2,
// element_refcounted
Symbol::DEV_TMP3,
inc_elem_fn,
dec_elem_fn,
];
let lowlevel_arg_layouts = [list_a_layout, list_b_layout, Layout::U32, Layout::U64];
let lowlevel_arg_layouts = [
list_a_layout,
list_b_layout,
Layout::U32,
Layout::U64,
Layout::BOOL,
Layout::U64,
Layout::U64,
];
self.build_fn_call(
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
bitcode::LIST_CONCAT.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -3278,17 +3401,18 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
// Return list value from fn call
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
base_offset,
&Symbol::DEV_TMP3,
&Symbol::DEV_TMP4,
ret_layout,
);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
}
fn build_list_prepend(
@ -3320,6 +3444,11 @@ impl<
// Load element_witdh argument (usize).
self.load_layout_stack_size(elem_layout, Symbol::DEV_TMP3);
// Load element_refcounted argument (bool).
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP4);
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
// Setup the return location.
let base_offset =
self.storage_manager
@ -3333,11 +3462,15 @@ impl<
Symbol::DEV_TMP2,
// element_width
Symbol::DEV_TMP3,
// element_refcounted
Symbol::DEV_TMP4,
// inc
inc_elem_fn,
];
let lowlevel_arg_layouts = [list_layout, Layout::U32, Layout::U64, Layout::U64];
self.build_fn_call(
&Symbol::DEV_TMP4,
&Symbol::DEV_TMP5,
bitcode::LIST_PREPEND.to_string(),
&lowlevel_args,
&lowlevel_arg_layouts,
@ -3346,17 +3479,18 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
self.free_symbol(&Symbol::DEV_TMP3);
self.free_symbol(&Symbol::DEV_TMP4);
// Return list value from fn call
self.storage_manager.copy_symbol_to_stack_offset(
self.layout_interner,
&mut self.buf,
base_offset,
&Symbol::DEV_TMP4,
&Symbol::DEV_TMP5,
ret_layout,
);
self.free_symbol(&Symbol::DEV_TMP4);
self.free_symbol(&Symbol::DEV_TMP5);
}
fn build_ptr_cast(&mut self, dst: &Symbol, src: &Symbol) {
@ -3403,15 +3537,20 @@ impl<
let element_alignment_symbol = self.debug_symbol("element_alignment");
self.load_layout_alignment(*element_in_layout, element_alignment_symbol);
let element_refcounted = self.debug_symbol("element_refcounted");
self.load_layout_refcounted(*element_in_layout, element_refcounted);
let allocation_symbol = self.debug_symbol("list_allocation");
self.allocate_with_refcount(
allocation_symbol,
data_bytes_symbol,
element_alignment_symbol,
element_refcounted,
);
self.free_symbol(&data_bytes_symbol);
self.free_symbol(&element_alignment_symbol);
self.free_symbol(&element_refcounted);
enum Origin {
S(Symbol),
@ -3862,11 +4001,17 @@ impl<
match reuse {
None => {
let element_refcounted = self.debug_symbol("element_refcounted");
self.load_layout_refcounted(element_layout, element_refcounted);
self.allocate_with_refcount(
allocation,
element_width_symbol,
element_alignment_symbol,
element_refcounted,
);
self.free_symbol(&element_refcounted);
}
Some(reuse) => {
self.allocate_with_refcount_if_null(allocation, reuse, element_layout);
@ -5180,11 +5325,12 @@ impl<
dst: Symbol,
data_bytes: Symbol,
element_alignment: Symbol,
element_refcounted: Symbol,
) {
self.build_fn_call(
&dst,
bitcode::UTILS_ALLOCATE_WITH_REFCOUNT.to_string(),
&[data_bytes, element_alignment],
&[data_bytes, element_alignment, element_refcounted],
&[Layout::U64, Layout::U32],
&Layout::U64,
);
@ -5217,10 +5363,14 @@ impl<
let element_alignment = self.debug_symbol("element_alignment");
self.load_layout_alignment(layout, element_alignment);
self.allocate_with_refcount(dst, data_bytes, element_alignment);
let element_refcounted = self.debug_symbol("element_refcounted");
self.load_layout_refcounted(layout, element_refcounted);
self.allocate_with_refcount(dst, data_bytes, element_alignment, element_refcounted);
self.free_symbol(&data_bytes);
self.free_symbol(&element_alignment);
self.free_symbol(&element_refcounted);
let mut tmp = bumpalo::vec![in self.env.arena];
@ -5609,6 +5759,15 @@ impl<
self.load_literal(&symbol, &u32_layout, &alignment_literal);
}
/// Loads if the layout is refcounted (recursively checking) of `layout` into the given `symbol`
fn load_layout_refcounted(&mut self, layout: InLayout<'_>, symbol: Symbol) {
let u64_layout = Layout::BOOL;
let refcounted = self.layout_interner.contains_refcounted(layout);
let refcounted_literal = Literal::Bool(refcounted);
self.load_literal(&symbol, &u64_layout, &refcounted_literal);
}
/// Loads the stack size of `layout` into the given `symbol`
fn load_layout_stack_size(&mut self, layout: InLayout<'_>, symbol: Symbol) {
let u64_layout = Layout::U64;

View file

@ -111,6 +111,7 @@ struct ListArgument<'a> {
alignment: Symbol,
element_width: Symbol,
element_refcounted: Symbol,
}
// Track when a variable is last used (and hence when it can be disregarded). This is non-trivial
@ -408,10 +409,19 @@ trait Backend<'a> {
let element_width = self.debug_symbol("element_width");
self.load_literal_i64(&element_width, element_width_int as i64);
let element_refcounted = self.debug_symbol("element_refcounted");
let refcounted = self.interner().contains_refcounted(element_layout);
self.load_literal(
&element_refcounted,
&Layout::BOOL,
&Literal::Bool(refcounted),
);
ListArgument {
element_layout,
alignment,
element_width,
element_refcounted,
}
}
@ -435,6 +445,26 @@ trait Backend<'a> {
element_increment
}
fn increment_n_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
let box_layout = self
.interner_mut()
.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
let element_increment = self.debug_symbol("element_increment_n");
let element_increment_symbol = self.build_indirect_inc_n(layout);
let element_increment_string = self.lambda_name_to_string(
LambdaName::no_niche(element_increment_symbol),
[box_layout].into_iter(),
None,
Layout::UNIT,
);
self.build_fn_pointer(&element_increment, element_increment_string);
element_increment
}
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
let box_layout = self
.interner_mut()
@ -1883,6 +1913,7 @@ trait Backend<'a> {
list,
list_argument.alignment,
list_argument.element_width,
list_argument.element_refcounted,
start,
len,
self.decrement_fn_pointer(element_layout),
@ -1894,6 +1925,7 @@ trait Backend<'a> {
arg_layouts[0],
Layout::U32,
layout_usize,
Layout::BOOL,
Layout::U64,
Layout::U64,
layout_usize,
@ -1913,6 +1945,9 @@ trait Backend<'a> {
let update_mode = self.debug_symbol("update_mode");
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
let inc_elem_fn = self.increment_fn_pointer(list_argument.element_layout);
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout);
let layout_usize = Layout::U64;
// list: RocList,
@ -1920,6 +1955,9 @@ trait Backend<'a> {
// element_width: usize,
// index_1: u64,
// index_2: u64,
// element_refcounted: bool,
// inc: Inc
// dec: Dec
// update_mode: UpdateMode,
self.build_fn_call(
@ -1931,6 +1969,9 @@ trait Backend<'a> {
list_argument.element_width,
i,
j,
list_argument.element_refcounted,
inc_elem_fn,
dec_elem_fn,
update_mode,
],
&[
@ -1939,6 +1980,9 @@ trait Backend<'a> {
layout_usize,
Layout::U64,
Layout::U64,
Layout::BOOL,
layout_usize,
layout_usize,
Layout::U8,
],
ret_layout,
@ -1953,11 +1997,15 @@ trait Backend<'a> {
let update_mode = self.debug_symbol("update_mode");
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout);
let layout_usize = Layout::U64;
// list: RocList,
// alignment: u32,
// element_width: usize,
// element_refcounted: bool,
// dec_elem_fn: Dec,
// update_mode: UpdateMode,
self.build_fn_call(
@ -1967,6 +2015,8 @@ trait Backend<'a> {
list,
list_argument.alignment,
list_argument.element_width,
list_argument.element_refcounted,
dec_elem_fn,
update_mode,
],
&[list_layout, Layout::U32, layout_usize, Layout::U8],
@ -2434,6 +2484,7 @@ trait Backend<'a> {
);
fn build_indirect_inc(&mut self, layout: InLayout<'a>) -> Symbol;
fn build_indirect_inc_n(&mut self, layout: InLayout<'a>) -> Symbol;
fn build_indirect_dec(&mut self, layout: InLayout<'a>) -> Symbol;
fn build_list_clone(