From 00397db8b6b381c18acb8ea94f3507848e0b149a Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 2 Jul 2022 22:20:34 +0200 Subject: [PATCH] implement List.dropAt for the wasm backend --- crates/compiler/gen_wasm/src/low_level.rs | 45 ++++++++++++++++++++++- crates/compiler/test_gen/src/gen_list.rs | 4 +- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 4a8067010a..f39c1eac05 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -556,7 +556,50 @@ impl<'a> LowLevelCall<'a> { backend.call_host_fn_after_loading_args(bitcode::LIST_SUBLIST, 8, false); } - ListDropAt => todo!("{:?}", self.lowlevel), + ListDropAt => { + // List.dropAt : List elem, Nat -> List elem + let list: Symbol = self.arguments[0]; + let drop_index: Symbol = self.arguments[1]; + + let elem_layout = unwrap_list_elem_layout(self.ret_layout); + let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO); + + // The refcount function receives a pointer to an element in the list + // This is the same as a Struct containing the element + let in_memory_layout = Layout::Struct { + field_order_hash: FieldOrderHash::from_ordered_fields(&[]), + field_layouts: backend.env.arena.alloc([*elem_layout]), + }; + let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec); + let dec_fn_ptr = backend.get_fn_ptr(dec_fn); + + // Zig arguments Wasm types + // (return pointer) i32 + // list: RocList, i64, i32 + // element_width: usize, i32 + // alignment: u32, i32 + // drop_index: usize, i32 + // dec: Dec, i32 + + // Load the return pointer and the list + backend.storage.load_symbols_for_call( + backend.env.arena, + &mut backend.code_builder, + &[list], + self.ret_symbol, + &WasmLayout::new(&self.ret_layout), + CallConv::Zig, + ); + + backend.code_builder.i32_const(elem_width as i32); + backend.code_builder.i32_const(elem_align as i32); + backend + .storage + .load_symbols(&mut backend.code_builder, &[drop_index]); + backend.code_builder.i32_const(dec_fn_ptr); + + backend.call_host_fn_after_loading_args(bitcode::LIST_DROP_AT, 6, false); + } ListSwap => { // List.swap : List elem, Nat, Nat -> List elem let list: Symbol = self.arguments[0]; diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index ed625eea72..134eccfdde 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -328,7 +328,7 @@ fn list_drop() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_drop_at() { assert_evals_to!( "List.dropAt [1, 2, 3] 0", @@ -376,7 +376,7 @@ fn list_intersperse() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_drop_at_shared() { assert_evals_to!( indoc!(