From 0c110cf7428f403075d84d19855e0490144e52fb Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 26 Jun 2022 16:46:47 +0100 Subject: [PATCH] wasm: List.concat --- compiler/gen_wasm/src/low_level.rs | 31 ++++++++++++++++++- compiler/test_gen/src/gen_list.rs | 48 +++++++----------------------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/compiler/gen_wasm/src/low_level.rs b/compiler/gen_wasm/src/low_level.rs index ffd917263b..9d9fc9f9d6 100644 --- a/compiler/gen_wasm/src/low_level.rs +++ b/compiler/gen_wasm/src/low_level.rs @@ -439,7 +439,36 @@ impl<'a> LowLevelCall<'a> { } ListRepeat => todo!("{:?}", self.lowlevel), ListReverse => todo!("{:?}", self.lowlevel), - ListConcat => todo!("{:?}", self.lowlevel), + ListConcat => { + // Zig arguments Wasm types + // (return pointer) i32 + // list_a: RocList i64, i32 + // list_b: RocList i64, i32 + // alignment: u32 i32 + // element_width: usize i32 + + // Load the arguments that have symbols + backend.storage.load_symbols_for_call( + backend.env.arena, + &mut backend.code_builder, + self.arguments, + self.ret_symbol, + &WasmLayout::new(&self.ret_layout), + CallConv::Zig, + ); + + // Load monomorphization constants + if let Layout::Builtin(Builtin::List(elem_layout)) = self.ret_layout { + let (elem_width, elem_align) = + elem_layout.stack_size_and_alignment(TARGET_INFO); + backend.code_builder.i32_const(elem_align as i32); + backend.code_builder.i32_const(elem_width as i32); + } else { + internal_error!("Invalid return layout for ListConcat {:?}", self.ret_layout); + } + + backend.call_host_fn_after_loading_args(bitcode::LIST_CONCAT, 7, false); + } ListContains => todo!("{:?}", self.lowlevel), ListAppend => todo!("{:?}", self.lowlevel), ListPrepend => todo!("{:?}", self.lowlevel), diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index 6b8f8e16f9..72ac1d598e 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -1393,29 +1393,7 @@ fn list_reverse_empty_list() { } #[test] -#[cfg(any(feature = "gen-llvm"))] -fn list_concat() { - assert_evals_to!( - indoc!( - r#" - firstList : List I64 - firstList = - [] - - secondList : List I64 - secondList = - [] - - List.concat firstList secondList - "# - ), - RocList::::from_slice(&[]), - RocList - ); -} - -#[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_two_empty_lists() { assert_evals_to!( "List.concat [] []", @@ -1425,7 +1403,7 @@ fn list_concat_two_empty_lists() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_two_empty_lists_of_int() { assert_evals_to!( indoc!( @@ -1447,22 +1425,18 @@ fn list_concat_two_empty_lists_of_int() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_second_list_is_empty() { assert_evals_to!( "List.concat [12, 13] []", RocList::from_slice(&[12, 13]), RocList ); - assert_evals_to!( - "List.concat [34, 43] [64, 55, 66]", - RocList::from_slice(&[34, 43, 64, 55, 66]), - RocList - ); + } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_first_list_is_empty() { assert_evals_to!( "List.concat [] [23, 24]", @@ -1472,7 +1446,7 @@ fn list_concat_first_list_is_empty() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_two_non_empty_lists() { assert_evals_to!( "List.concat [1, 2] [3, 4]", @@ -1482,7 +1456,7 @@ fn list_concat_two_non_empty_lists() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_two_bigger_non_empty_lists() { assert_evals_to!( "List.concat [1.1, 2.2] [3.3, 4.4, 5.5]", @@ -1492,7 +1466,7 @@ fn list_concat_two_bigger_non_empty_lists() { } #[allow(dead_code)] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn assert_concat_worked(num_elems1: i64, num_elems2: i64) { let vec1: Vec = (0..num_elems1) .map(|i| 12345 % (i + num_elems1 + num_elems2 + 1)) @@ -1514,7 +1488,7 @@ fn assert_concat_worked(num_elems1: i64, num_elems2: i64) { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_empty_list() { assert_concat_worked(0, 0); assert_concat_worked(1, 0); @@ -1538,7 +1512,7 @@ fn list_concat_empty_list() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_nonempty_lists() { assert_concat_worked(1, 1); assert_concat_worked(1, 2); @@ -1554,7 +1528,7 @@ fn list_concat_nonempty_lists() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_concat_large() { with_larger_debug_stack(|| { // these values produce mono ASTs so large that