wasm: Implement List.prepend

This commit is contained in:
Brian Carroll 2022-07-05 20:20:21 +01:00
parent 176322d099
commit e5e56a7795
No known key found for this signature in database
GPG key ID: 9CF4E3BF9C4722C7
2 changed files with 42 additions and 4 deletions

View file

@ -530,7 +530,45 @@ impl<'a> LowLevelCall<'a> {
backend.call_host_fn_after_loading_args(bitcode::LIST_APPEND, 7, false);
}
ListPrepend => todo!("{:?}", self.lowlevel),
ListPrepend => {
// List.prepend : List elem, elem -> List elem
let list: Symbol = self.arguments[0];
let elem: 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);
let (elem_local, elem_offset, _) =
ensure_symbol_is_in_memory(backend, elem, *elem_layout, backend.env.arena);
// Zig arguments Wasm types
// (return pointer) i32
// list: RocList i64, i32
// alignment: u32 i32
// element: Opaque i32
// element_width: usize i32
// return pointer and 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_align as i32);
backend.code_builder.get_local(elem_local);
if elem_offset > 0 {
backend.code_builder.i32_const(elem_offset as i32);
backend.code_builder.i32_add();
}
backend.code_builder.i32_const(elem_width as i32);
backend.call_host_fn_after_loading_args(bitcode::LIST_PREPEND, 6, false);
}
ListSublist => {
// As a low-level, record is destructured
// List.sublist : List elem, start : Nat, len : Nat -> List elem

View file

@ -630,7 +630,7 @@ fn list_append_longer_list() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn list_prepend() {
assert_evals_to!("List.prepend [] 1", RocList::from_slice(&[1]), RocList<i64>);
assert_evals_to!(
@ -669,7 +669,7 @@ fn list_prepend() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn list_prepend_bools() {
assert_evals_to!(
"List.prepend [True, False] True",
@ -679,7 +679,7 @@ fn list_prepend_bools() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn list_prepend_big_list() {
assert_evals_to!(
"List.prepend [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 100, 100, 100, 100] 9",