mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
wasm: Implement List.prepend
This commit is contained in:
parent
176322d099
commit
e5e56a7795
2 changed files with 42 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue