test_gen: support RocResult for Wasm tests

This commit is contained in:
Brian Carroll 2022-07-06 08:59:50 +01:00
parent 617e18af98
commit a9aee13086
No known key found for this signature in database
GPG key ID: 9CF4E3BF9C4722C7
4 changed files with 49 additions and 6 deletions

View file

@ -14,7 +14,7 @@ use crate::wasm_module::{
linking::SymInfo, linking::WasmObjectSymbol, Align, CodeBuilder, Export, ExportType, LocalId,
Signature, ValueType, WasmModule,
};
use roc_std::{RocDec, RocList, RocOrder, RocStr};
use roc_std::{RocDec, RocList, RocOrder, RocResult, RocStr};
/// Type-driven wrapper generation
pub trait Wasm32Result {
@ -200,6 +200,24 @@ impl<T: Wasm32Result> Wasm32Result for RocList<T> {
}
}
impl<T: Wasm32Sized, E: Wasm32Sized> Wasm32Result for RocResult<T, E> {
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
build_wrapper_body_stack_memory(
code_builder,
main_function_index,
max2(T::ACTUAL_WIDTH, E::ACTUAL_WIDTH) + max2(T::ALIGN_OF_WASM, E::ALIGN_OF_WASM),
)
}
}
fn max2(a: usize, b: usize) -> usize {
if a > b {
a
} else {
b
}
}
impl<T: Wasm32Result> Wasm32Result for &'_ T {
build_wrapper_body_primitive!(i32_store, Align::Bytes4);
}

View file

@ -1,4 +1,4 @@
use roc_std::{RocDec, RocList, RocOrder, RocStr};
use roc_std::{RocDec, RocList, RocOrder, RocStr, RocResult};
pub trait Wasm32Sized: Sized {
const SIZE_OF_WASM: usize;
@ -41,6 +41,11 @@ impl<T: Wasm32Sized> Wasm32Sized for RocList<T> {
const ALIGN_OF_WASM: usize = 4;
}
impl<T: Wasm32Sized, E: Wasm32Sized> Wasm32Sized for RocResult<T, E> {
const ALIGN_OF_WASM: usize = max2(T::ALIGN_OF_WASM, E::ALIGN_OF_WASM);
const SIZE_OF_WASM: usize = max2(T::ACTUAL_WIDTH, E::ACTUAL_WIDTH) + 1;
}
impl<T: Wasm32Sized> Wasm32Sized for &'_ T {
const SIZE_OF_WASM: usize = 4;
const ALIGN_OF_WASM: usize = 4;

View file

@ -224,7 +224,7 @@ fn is_err() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn roc_result_ok() {
assert_evals_to!(
indoc!(
@ -241,7 +241,7 @@ fn roc_result_ok() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn roc_result_err() {
assert_evals_to!(
indoc!(
@ -258,7 +258,7 @@ fn roc_result_err() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn issue_2583_specialize_errors_behind_unified_branches() {
assert_evals_to!(
r#"

View file

@ -1,5 +1,5 @@
use roc_gen_wasm::wasm32_sized::Wasm32Sized;
use roc_std::{RocDec, RocList, RocOrder, RocStr};
use roc_std::{RocDec, RocList, RocOrder, RocResult, RocStr};
use std::convert::TryInto;
pub trait FromWasmerMemory: Wasm32Sized {
@ -95,6 +95,26 @@ impl<T: FromWasmerMemory + Clone> FromWasmerMemory for RocList<T> {
}
}
impl<T: FromWasmerMemory + Wasm32Sized, E: FromWasmerMemory + Wasm32Sized> FromWasmerMemory
for RocResult<T, E>
{
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
let tag_offset = if T::ACTUAL_WIDTH > E::ACTUAL_WIDTH {
T::ACTUAL_WIDTH
} else {
E::ACTUAL_WIDTH
};
let tag = <u8 as FromWasmerMemory>::decode(memory, offset + tag_offset as u32);
if tag == 1 {
let value = <T as FromWasmerMemory>::decode(memory, offset);
RocResult::ok(value)
} else {
let payload = <E as FromWasmerMemory>::decode(memory, offset);
RocResult::err(payload)
}
}
}
impl<T: FromWasmerMemory> FromWasmerMemory for &'_ T {
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
let elements = <u32 as FromWasmerMemory>::decode(memory, offset);