diff --git a/compiler/gen_wasm/src/lib.rs b/compiler/gen_wasm/src/lib.rs index 7cca526acb..50f1e81350 100644 --- a/compiler/gen_wasm/src/lib.rs +++ b/compiler/gen_wasm/src/lib.rs @@ -264,5 +264,5 @@ pub const DEBUG_LOG_SETTINGS: WasmDebugLogSettings = WasmDebugLogSettings { let_stmt_ir: false && cfg!(debug_assertions), instructions: false && cfg!(debug_assertions), storage_map: false && cfg!(debug_assertions), - keep_test_binary: false && cfg!(debug_assertions), + keep_test_binary: true && cfg!(debug_assertions), }; diff --git a/compiler/gen_wasm/src/low_level.rs b/compiler/gen_wasm/src/low_level.rs index b396a83adc..281e1d204d 100644 --- a/compiler/gen_wasm/src/low_level.rs +++ b/compiler/gen_wasm/src/low_level.rs @@ -1028,7 +1028,7 @@ pub fn call_higher_order_lowlevel<'a>( Layout::Builtin(Builtin::List(elem_x)), Layout::Builtin(Builtin::List(elem_ret)), ) => (elem_x, elem_ret), - _ => unreachable!("invalid arguments layout for {:?}", op), + _ => internal_error!("invalid arguments layout for {:?}", op), }; let elem_x_size = elem_x.stack_size(TARGET_INFO); let (elem_ret_size, elem_ret_align) = elem_ret.stack_size_and_alignment(TARGET_INFO); @@ -1071,7 +1071,7 @@ pub fn call_higher_order_lowlevel<'a>( Layout::Builtin(Builtin::List(y)), Layout::Builtin(Builtin::List(ret)), ) => (x, y, ret), - _ => unreachable!("invalid arguments layout for {:?}", op), + _ => internal_error!("invalid arguments layout for {:?}", op), }; let elem_x_size = elem_x.stack_size(TARGET_INFO); let elem_y_size = elem_y.stack_size(TARGET_INFO); @@ -1124,8 +1124,80 @@ pub fn call_higher_order_lowlevel<'a>( ); } - ListMap3 { .. } - | ListMap4 { .. } + ListMap3 { xs, ys, zs } => { + let list_x = backend.storage.symbol_layouts[xs]; + let list_y = backend.storage.symbol_layouts[ys]; + let list_z = backend.storage.symbol_layouts[zs]; + + let (elem_x, elem_y, elem_z, elem_ret) = match (list_x, list_y, list_z, return_layout) { + ( + Layout::Builtin(Builtin::List(x)), + Layout::Builtin(Builtin::List(y)), + Layout::Builtin(Builtin::List(z)), + Layout::Builtin(Builtin::List(ret)), + ) => (x, y, z, ret), + e => internal_error!("invalid arguments layout for {:?}\n{:?}", op, e), + }; + let elem_x_size = elem_x.stack_size(TARGET_INFO); + let elem_y_size = elem_y.stack_size(TARGET_INFO); + let elem_z_size = elem_y.stack_size(TARGET_INFO); + let (elem_ret_size, elem_ret_align) = elem_ret.stack_size_and_alignment(TARGET_INFO); + + let dec_x_fn_ptr = backend.get_refcount_fn_ptr(*elem_x, HelperOp::Dec); + let dec_y_fn_ptr = backend.get_refcount_fn_ptr(*elem_y, HelperOp::Dec); + let dec_z_fn_ptr = backend.get_refcount_fn_ptr(*elem_z, HelperOp::Dec); + + let cb = &mut backend.code_builder; + + /* Load Wasm arguments + return ptr i32 + list1: RocList, i64, i64 + list2: RocList, i64, i64 + list3: RocList, i64, i64 + caller: Caller3, i32 + data: Opaque, i32 + inc_n_data: IncN, i32 + data_is_owned: bool, i32 + alignment: u32, i32 + a_width: usize, i32 + b_width: usize, i32 + c_width: usize, i32 + d_width: usize, i32 + dec_a: Dec, i32 + dec_b: Dec, i32 + dec_c: Dec, i32 + */ + backend.storage.load_symbols(cb, &[return_sym]); + backend.storage.load_symbol_zig(cb, *xs); + backend.storage.load_symbol_zig(cb, *ys); + backend.storage.load_symbol_zig(cb, *zs); + cb.i32_const(wrapper_fn_ptr); + if closure_data_exists { + backend.storage.load_symbols(cb, &[*captured_environment]); + } else { + cb.i32_const(0); // null pointer + } + cb.i32_const(inc_fn_ptr); + cb.i32_const(*owns_captured_environment as i32); + cb.i32_const(elem_ret_align as i32); + cb.i32_const(elem_x_size as i32); + cb.i32_const(elem_y_size as i32); + cb.i32_const(elem_z_size as i32); + cb.i32_const(elem_ret_size as i32); + cb.i32_const(dec_x_fn_ptr); + cb.i32_const(dec_y_fn_ptr); + cb.i32_const(dec_z_fn_ptr); + + let num_wasm_args = 19; + let has_return_val = false; + backend.call_zig_builtin_after_loading_args( + bitcode::LIST_MAP3, + num_wasm_args, + has_return_val, + ); + } + + ListMap4 { .. } | ListMapWithIndex { .. } | ListKeepIf { .. } | ListWalk { .. } diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index 92ab071fa2..74ad1281b2 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -1137,7 +1137,7 @@ fn list_map4_different_length() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_map3_group() { assert_evals_to!( indoc!( @@ -1151,7 +1151,7 @@ fn list_map3_group() { } #[test] -#[cfg(any(feature = "gen-llvm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_map3_different_length() { assert_evals_to!( indoc!(