mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
repl: move wasm32_test_result to gen_wasm, and extract Wasm32Sized from FromWasm32Memory
This commit is contained in:
parent
70e19053f0
commit
e9871947d3
7 changed files with 96 additions and 63 deletions
|
@ -4,6 +4,10 @@ mod low_level;
|
||||||
mod storage;
|
mod storage;
|
||||||
pub mod wasm_module;
|
pub mod wasm_module;
|
||||||
|
|
||||||
|
// Helpers for interfacing to a Wasm module from outside
|
||||||
|
pub mod wasm32_sized;
|
||||||
|
pub mod wasm32_test_result;
|
||||||
|
|
||||||
use bumpalo::{self, collections::Vec, Bump};
|
use bumpalo::{self, collections::Vec, Bump};
|
||||||
|
|
||||||
use roc_collections::all::{MutMap, MutSet};
|
use roc_collections::all::{MutMap, MutSet};
|
||||||
|
|
78
compiler/gen_wasm/src/wasm32_sized.rs
Normal file
78
compiler/gen_wasm/src/wasm32_sized.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use roc_std::{RocDec, RocList, RocOrder, RocStr};
|
||||||
|
|
||||||
|
pub trait Wasm32Sized: Sized {
|
||||||
|
const SIZE_OF_WASM: usize;
|
||||||
|
const ALIGN_OF_WASM: usize;
|
||||||
|
const ACTUAL_WIDTH: usize = if (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM) == 0 {
|
||||||
|
Self::SIZE_OF_WASM
|
||||||
|
} else {
|
||||||
|
Self::SIZE_OF_WASM + (Self::ALIGN_OF_WASM - (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! wasm32_sized_primitive {
|
||||||
|
($($type_name:ident ,)+) => {
|
||||||
|
$(
|
||||||
|
impl Wasm32Sized for $type_name {
|
||||||
|
const SIZE_OF_WASM: usize = core::mem::size_of::<$type_name>();
|
||||||
|
const ALIGN_OF_WASM: usize = core::mem::align_of::<$type_name>();
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm32_sized_primitive!(
|
||||||
|
u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64, bool, RocDec, RocOrder,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Wasm32Sized for () {
|
||||||
|
const SIZE_OF_WASM: usize = 0;
|
||||||
|
const ALIGN_OF_WASM: usize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Wasm32Sized for RocStr {
|
||||||
|
const SIZE_OF_WASM: usize = 8;
|
||||||
|
const ALIGN_OF_WASM: usize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Wasm32Sized> Wasm32Sized for RocList<T> {
|
||||||
|
const SIZE_OF_WASM: usize = 8;
|
||||||
|
const ALIGN_OF_WASM: usize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Wasm32Sized> Wasm32Sized for &'_ T {
|
||||||
|
const SIZE_OF_WASM: usize = 4;
|
||||||
|
const ALIGN_OF_WASM: usize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Wasm32Sized, const N: usize> Wasm32Sized for [T; N] {
|
||||||
|
const SIZE_OF_WASM: usize = N * T::SIZE_OF_WASM;
|
||||||
|
const ALIGN_OF_WASM: usize = T::ALIGN_OF_WASM;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Wasm32Sized for usize {
|
||||||
|
const SIZE_OF_WASM: usize = 4;
|
||||||
|
const ALIGN_OF_WASM: usize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Wasm32Sized, U: Wasm32Sized> Wasm32Sized for (T, U) {
|
||||||
|
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM;
|
||||||
|
const ALIGN_OF_WASM: usize = max2(T::SIZE_OF_WASM, U::SIZE_OF_WASM);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized> Wasm32Sized for (T, U, V) {
|
||||||
|
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM;
|
||||||
|
const ALIGN_OF_WASM: usize = max3(T::SIZE_OF_WASM, U::SIZE_OF_WASM, V::SIZE_OF_WASM);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn max2(a: usize, b: usize) -> usize {
|
||||||
|
if a > b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn max3(a: usize, b: usize, c: usize) -> usize {
|
||||||
|
max2(max2(a, b), c)
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
|
|
||||||
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
|
use crate::wasm32_sized::Wasm32Sized;
|
||||||
use roc_gen_wasm::wasm_module::{
|
use crate::wasm_module::{
|
||||||
linking::SymInfo, linking::WasmObjectSymbol, Align, CodeBuilder, Export, ExportType, LocalId,
|
linking::SymInfo, linking::WasmObjectSymbol, Align, CodeBuilder, Export, ExportType, LocalId,
|
||||||
Signature, ValueType, WasmModule,
|
Signature, ValueType, WasmModule,
|
||||||
};
|
};
|
||||||
|
@ -136,7 +136,7 @@ impl<T: Wasm32TestResult> Wasm32TestResult for &'_ T {
|
||||||
|
|
||||||
impl<T, const N: usize> Wasm32TestResult for [T; N]
|
impl<T, const N: usize> Wasm32TestResult for [T; N]
|
||||||
where
|
where
|
||||||
T: Wasm32TestResult + FromWasm32Memory,
|
T: Wasm32TestResult + Wasm32Sized,
|
||||||
{
|
{
|
||||||
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
||||||
build_wrapper_body_stack_memory(code_builder, main_function_index, N * T::ACTUAL_WIDTH)
|
build_wrapper_body_stack_memory(code_builder, main_function_index, N * T::ACTUAL_WIDTH)
|
||||||
|
@ -155,8 +155,8 @@ impl Wasm32TestResult for () {
|
||||||
|
|
||||||
impl<T, U> Wasm32TestResult for (T, U)
|
impl<T, U> Wasm32TestResult for (T, U)
|
||||||
where
|
where
|
||||||
T: Wasm32TestResult + FromWasm32Memory,
|
T: Wasm32TestResult + Wasm32Sized,
|
||||||
U: Wasm32TestResult + FromWasm32Memory,
|
U: Wasm32TestResult + Wasm32Sized,
|
||||||
{
|
{
|
||||||
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
||||||
build_wrapper_body_stack_memory(
|
build_wrapper_body_stack_memory(
|
||||||
|
@ -169,9 +169,9 @@ where
|
||||||
|
|
||||||
impl<T, U, V> Wasm32TestResult for (T, U, V)
|
impl<T, U, V> Wasm32TestResult for (T, U, V)
|
||||||
where
|
where
|
||||||
T: Wasm32TestResult + FromWasm32Memory,
|
T: Wasm32TestResult + Wasm32Sized,
|
||||||
U: Wasm32TestResult + FromWasm32Memory,
|
U: Wasm32TestResult + Wasm32Sized,
|
||||||
V: Wasm32TestResult + FromWasm32Memory,
|
V: Wasm32TestResult + Wasm32Sized,
|
||||||
{
|
{
|
||||||
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
fn build_wrapper_body(code_builder: &mut CodeBuilder, main_function_index: u32) {
|
||||||
build_wrapper_body_stack_memory(
|
build_wrapper_body_stack_memory(
|
|
@ -1,22 +1,12 @@
|
||||||
|
use roc_gen_wasm::wasm32_sized::Wasm32Sized;
|
||||||
use roc_std::{RocDec, RocList, RocOrder, RocStr};
|
use roc_std::{RocDec, RocList, RocOrder, RocStr};
|
||||||
|
|
||||||
pub trait FromWasm32Memory: Sized {
|
pub trait FromWasm32Memory: Wasm32Sized {
|
||||||
const SIZE_OF_WASM: usize;
|
|
||||||
const ALIGN_OF_WASM: usize;
|
|
||||||
const ACTUAL_WIDTH: usize = if (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM) == 0 {
|
|
||||||
Self::SIZE_OF_WASM
|
|
||||||
} else {
|
|
||||||
Self::SIZE_OF_WASM + (Self::ALIGN_OF_WASM - (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM))
|
|
||||||
};
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self;
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! from_wasm_memory_primitive_decode {
|
macro_rules! from_wasm_memory_primitive_decode {
|
||||||
($type_name:ident) => {
|
($type_name:ident) => {
|
||||||
const SIZE_OF_WASM: usize = core::mem::size_of::<$type_name>();
|
|
||||||
const ALIGN_OF_WASM: usize = core::mem::align_of::<$type_name>();
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
|
@ -53,16 +43,10 @@ from_wasm_memory_primitive!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl FromWasm32Memory for () {
|
impl FromWasm32Memory for () {
|
||||||
const SIZE_OF_WASM: usize = 0;
|
|
||||||
const ALIGN_OF_WASM: usize = 0;
|
|
||||||
|
|
||||||
fn decode(_: &wasmer::Memory, _: u32) -> Self {}
|
fn decode(_: &wasmer::Memory, _: u32) -> Self {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWasm32Memory for RocStr {
|
impl FromWasm32Memory for RocStr {
|
||||||
const SIZE_OF_WASM: usize = 8;
|
|
||||||
const ALIGN_OF_WASM: usize = 4;
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
let bytes = <u64 as FromWasm32Memory>::decode(memory, offset);
|
let bytes = <u64 as FromWasm32Memory>::decode(memory, offset);
|
||||||
|
|
||||||
|
@ -90,9 +74,6 @@ impl FromWasm32Memory for RocStr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
|
impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
|
||||||
const SIZE_OF_WASM: usize = 8;
|
|
||||||
const ALIGN_OF_WASM: usize = 4;
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
let bytes = <u64 as FromWasm32Memory>::decode(memory, offset);
|
let bytes = <u64 as FromWasm32Memory>::decode(memory, offset);
|
||||||
|
|
||||||
|
@ -104,7 +85,7 @@ impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
|
||||||
for i in 0..length {
|
for i in 0..length {
|
||||||
let item = <T as FromWasm32Memory>::decode(
|
let item = <T as FromWasm32Memory>::decode(
|
||||||
memory,
|
memory,
|
||||||
elements + i * <T as FromWasm32Memory>::SIZE_OF_WASM as u32,
|
elements + i * <T as Wasm32Sized>::SIZE_OF_WASM as u32,
|
||||||
);
|
);
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
|
@ -114,9 +95,6 @@ impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FromWasm32Memory> FromWasm32Memory for &'_ T {
|
impl<T: FromWasm32Memory> FromWasm32Memory for &'_ T {
|
||||||
const SIZE_OF_WASM: usize = 4;
|
|
||||||
const ALIGN_OF_WASM: usize = 4;
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
let elements = <u32 as FromWasm32Memory>::decode(memory, offset);
|
let elements = <u32 as FromWasm32Memory>::decode(memory, offset);
|
||||||
|
|
||||||
|
@ -129,12 +107,9 @@ impl<T: FromWasm32Memory> FromWasm32Memory for &'_ T {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FromWasm32Memory + Clone, const N: usize> FromWasm32Memory for [T; N] {
|
impl<T: FromWasm32Memory + Clone, const N: usize> FromWasm32Memory for [T; N] {
|
||||||
const SIZE_OF_WASM: usize = N * T::SIZE_OF_WASM;
|
|
||||||
const ALIGN_OF_WASM: usize = T::ALIGN_OF_WASM;
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
let ptr: wasmer::WasmPtr<u8, wasmer::Array> = wasmer::WasmPtr::new(offset);
|
let ptr: wasmer::WasmPtr<u8, wasmer::Array> = wasmer::WasmPtr::new(offset);
|
||||||
let width = <T as FromWasm32Memory>::SIZE_OF_WASM as u32 * N as u32;
|
let width = <T as Wasm32Sized>::SIZE_OF_WASM as u32 * N as u32;
|
||||||
let foobar = (ptr.deref(memory, 0, width)).unwrap();
|
let foobar = (ptr.deref(memory, 0, width)).unwrap();
|
||||||
let wasm_slice: &[T; N] = unsafe { &*(foobar as *const _ as *const [T; N]) };
|
let wasm_slice: &[T; N] = unsafe { &*(foobar as *const _ as *const [T; N]) };
|
||||||
|
|
||||||
|
@ -143,18 +118,12 @@ impl<T: FromWasm32Memory + Clone, const N: usize> FromWasm32Memory for [T; N] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWasm32Memory for usize {
|
impl FromWasm32Memory for usize {
|
||||||
const SIZE_OF_WASM: usize = 4;
|
|
||||||
const ALIGN_OF_WASM: usize = 4;
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
<u32 as FromWasm32Memory>::decode(memory, offset) as usize
|
<u32 as FromWasm32Memory>::decode(memory, offset) as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FromWasm32Memory, U: FromWasm32Memory> FromWasm32Memory for (T, U) {
|
impl<T: FromWasm32Memory, U: FromWasm32Memory> FromWasm32Memory for (T, U) {
|
||||||
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM;
|
|
||||||
const ALIGN_OF_WASM: usize = max2(T::SIZE_OF_WASM, U::SIZE_OF_WASM);
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
T::ALIGN_OF_WASM >= U::ALIGN_OF_WASM,
|
T::ALIGN_OF_WASM >= U::ALIGN_OF_WASM,
|
||||||
|
@ -169,22 +138,7 @@ impl<T: FromWasm32Memory, U: FromWasm32Memory> FromWasm32Memory for (T, U) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn max2(a: usize, b: usize) -> usize {
|
|
||||||
if a > b {
|
|
||||||
a
|
|
||||||
} else {
|
|
||||||
b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn max3(a: usize, b: usize, c: usize) -> usize {
|
|
||||||
max2(max2(a, b), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: FromWasm32Memory, U: FromWasm32Memory, V: FromWasm32Memory> FromWasm32Memory for (T, U, V) {
|
impl<T: FromWasm32Memory, U: FromWasm32Memory, V: FromWasm32Memory> FromWasm32Memory for (T, U, V) {
|
||||||
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM;
|
|
||||||
const ALIGN_OF_WASM: usize = max3(T::SIZE_OF_WASM, U::SIZE_OF_WASM, V::SIZE_OF_WASM);
|
|
||||||
|
|
||||||
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
fn decode(memory: &wasmer::Memory, offset: u32) -> Self {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
T::ALIGN_OF_WASM >= U::ALIGN_OF_WASM,
|
T::ALIGN_OF_WASM >= U::ALIGN_OF_WASM,
|
||||||
|
|
|
@ -7,8 +7,6 @@ pub mod from_wasm32_memory;
|
||||||
pub mod llvm;
|
pub mod llvm;
|
||||||
#[cfg(feature = "gen-wasm")]
|
#[cfg(feature = "gen-wasm")]
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
#[cfg(feature = "gen-wasm")]
|
|
||||||
pub mod wasm32_test_result;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn zig_executable() -> String {
|
pub fn zig_executable() -> String {
|
||||||
|
|
|
@ -7,9 +7,9 @@ use std::path::{Path, PathBuf};
|
||||||
use wasmer::{Memory, WasmPtr};
|
use wasmer::{Memory, WasmPtr};
|
||||||
|
|
||||||
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
|
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
|
||||||
use crate::helpers::wasm32_test_result::Wasm32TestResult;
|
|
||||||
use roc_can::builtins::builtin_defs_map;
|
use roc_can::builtins::builtin_defs_map;
|
||||||
use roc_collections::all::{MutMap, MutSet};
|
use roc_collections::all::{MutMap, MutSet};
|
||||||
|
use roc_gen_wasm::wasm32_test_result::Wasm32TestResult;
|
||||||
use roc_gen_wasm::{DEBUG_LOG_SETTINGS, MEMORY_NAME};
|
use roc_gen_wasm::{DEBUG_LOG_SETTINGS, MEMORY_NAME};
|
||||||
|
|
||||||
// Should manually match build.rs
|
// Should manually match build.rs
|
||||||
|
|
|
@ -157,7 +157,7 @@ pub async fn repl_wasm_entrypoint_from_js(src: String) -> Result<String, String>
|
||||||
TODO
|
TODO
|
||||||
- reuse code from test_gen/src/wasm.rs
|
- reuse code from test_gen/src/wasm.rs
|
||||||
- use return type to create test_wrapper
|
- use return type to create test_wrapper
|
||||||
|
- preload builtins and libc platform
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let app_module_bytes: &[u8] = &[];
|
let app_module_bytes: &[u8] = &[];
|
||||||
|
@ -175,7 +175,6 @@ pub async fn repl_wasm_entrypoint_from_js(src: String) -> Result<String, String>
|
||||||
/*
|
/*
|
||||||
TODO
|
TODO
|
||||||
- gen_and_eval_wasm
|
- gen_and_eval_wasm
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Create a String representation of the result value
|
// Create a String representation of the result value
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue