wasm: move linking tests to test_gen and execute the module

This commit is contained in:
Brian Carroll 2022-06-14 22:09:16 +01:00
parent 115c2b524e
commit c1aa9f229a
No known key found for this signature in database
GPG key ID: 9CF4E3BF9C4722C7
5 changed files with 51 additions and 11 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@ zig-cache
*.rs.bk *.rs.bk
*.o *.o
*.tmp *.tmp
*.wasm
# llvm human-readable output # llvm human-readable output
*.ll *.ll

View file

@ -50,7 +50,7 @@ pub fn compile_and_load<'a, T: Wasm32Result>(
save_wasm_file(&compiled_bytes, build_dir_hash) save_wasm_file(&compiled_bytes, build_dir_hash)
}; };
load_bytes_into_runtime(compiled_bytes) load_bytes_into_runtime(&compiled_bytes)
} }
fn get_preprocessed_host_path() -> PathBuf { fn get_preprocessed_host_path() -> PathBuf {
@ -173,12 +173,12 @@ fn save_wasm_file(app_module_bytes: &[u8], build_dir_hash: u64) {
); );
} }
fn load_bytes_into_runtime(bytes: Vec<u8>) -> wasmer::Instance { fn load_bytes_into_runtime(bytes: &[u8]) -> wasmer::Instance {
use wasmer::{Module, Store}; use wasmer::{Module, Store};
use wasmer_wasi::WasiState; use wasmer_wasi::WasiState;
let store = Store::default(); let store = Store::default();
let wasmer_module = Module::new(&store, &bytes).unwrap(); let wasmer_module = Module::new(&store, bytes).unwrap();
// First, we create the `WasiEnv` // First, we create the `WasiEnv`
let mut wasi_env = WasiState::new("hello").finalize().unwrap(); let mut wasi_env = WasiState::new("hello").finalize().unwrap();

View file

@ -19,6 +19,9 @@ pub mod gen_tags;
mod helpers; mod helpers;
pub mod wasm_str; pub mod wasm_str;
#[cfg(feature = "gen-wasm")]
pub mod wasm_linking;
use core::ffi::c_void; use core::ffi::c_void;
/// # Safety /// # Safety

View file

@ -1,3 +1,5 @@
#![cfg(feature = "gen-wasm")]
use bumpalo::Bump; use bumpalo::Bump;
use roc_gen_wasm::Env; use roc_gen_wasm::Env;
use std::fs; use std::fs;
@ -17,8 +19,8 @@ use roc_mono::ir::{
}; };
use roc_mono::layout::{Builtin, Layout}; use roc_mono::layout::{Builtin, Layout};
const TEST_HOST_SOURCE: &str = "tests/linking_tests_host.zig"; const TEST_HOST_SOURCE: &str = "src/helpers/wasm_linking_test_host.zig";
const TEST_HOST_TARGET: &str = "tests/linking_tests_host.wasm"; const TEST_HOST_TARGET: &str = "src/helpers/wasm_linking_test_host.wasm";
fn build_host() -> std::vec::Vec<u8> { fn build_host() -> std::vec::Vec<u8> {
let args = [ let args = [
@ -171,6 +173,29 @@ impl<'a> BackendInputs<'a> {
} }
} }
fn load_bytes_into_runtime(bytes: &[u8]) -> wasmer::Instance {
use wasmer::{Function, Module, Store};
let store = Store::default();
let wasmer_module = Module::new(&store, bytes).unwrap();
let import_object = wasmer::imports!(
"env" => {
"js_called_indirectly_from_roc" => Function::new_native(&store, wasmer_import),
"js_called_indirectly_from_main" => Function::new_native(&store, wasmer_import),
"js_unused" => Function::new_native(&store, wasmer_import),
"js_called_directly_from_roc" => Function::new_native(&store, wasmer_import),
"js_called_directly_from_main" => Function::new_native(&store, wasmer_import),
}
);
wasmer::Instance::new(&wasmer_module, &import_object).unwrap()
}
fn wasmer_import(x: i32) -> i32 {
x + 100
}
#[test] #[test]
fn test_linking_without_dce() { fn test_linking_without_dce() {
let arena = Bump::new(); let arena = Bump::new();
@ -201,10 +226,11 @@ fn test_linking_without_dce() {
let (final_module, _called_preload_fns, _roc_main_index) = let (final_module, _called_preload_fns, _roc_main_index) =
roc_gen_wasm::build_app_module(&env, &mut interns, host_module, procedures); roc_gen_wasm::build_app_module(&env, &mut interns, host_module, procedures);
let mut buffer = Vec::with_capacity(final_module.size());
final_module.serialize(&mut buffer);
if std::env::var("DEBUG_WASM").is_ok() { if std::env::var("DEBUG_WASM").is_ok() {
let mut buffer = Vec::with_capacity(final_module.size()); fs::write("tests/without_dce.wasm", &buffer).unwrap();
final_module.serialize(&mut buffer);
fs::write("tests/without_dce.wasm", buffer).unwrap();
} }
let final_import_names = Vec::from_iter(final_module.import.imports.iter().map(|i| i.name)); let final_import_names = Vec::from_iter(final_module.import.imports.iter().map(|i| i.name));
@ -219,6 +245,11 @@ fn test_linking_without_dce() {
"js_called_directly_from_main", "js_called_directly_from_main",
] ]
); );
// Try to run it, make sure it doesn't crash
let instance = load_bytes_into_runtime(&buffer);
let start = instance.exports.get_function("_start").unwrap();
start.call(&[]).unwrap();
} }
#[test] #[test]
@ -255,10 +286,10 @@ fn test_linking_with_dce() {
final_module.eliminate_dead_code(env.arena, &called_preload_fns); final_module.eliminate_dead_code(env.arena, &called_preload_fns);
let mut buffer = Vec::with_capacity(final_module.size());
final_module.serialize(&mut buffer);
if std::env::var("DEBUG_WASM").is_ok() { if std::env::var("DEBUG_WASM").is_ok() {
let mut buffer = Vec::with_capacity(final_module.size()); fs::write("tests/with_dce.wasm", &buffer).unwrap();
final_module.serialize(&mut buffer);
fs::write("tests/with_dce.wasm", buffer).unwrap();
} }
let final_import_names = Vec::from_iter(final_module.import.imports.iter().map(|i| i.name)); let final_import_names = Vec::from_iter(final_module.import.imports.iter().map(|i| i.name));
@ -283,4 +314,9 @@ fn test_linking_with_dce() {
(4, "js_unused"), (4, "js_unused"),
] ]
); );
// Try to run it, make sure it doesn't crash
let instance = load_bytes_into_runtime(&buffer);
let start = instance.exports.get_function("_start").unwrap();
start.call(&[]).unwrap();
} }