mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
test_gen: pass Wasm linking test without DCE
This commit is contained in:
parent
b585bd5fde
commit
9fef0c319f
2 changed files with 61 additions and 41 deletions
|
@ -6,7 +6,7 @@ extern fn js_unused() i32;
|
||||||
|
|
||||||
extern fn roc__app_proc_1_exposed() i32;
|
extern fn roc__app_proc_1_exposed() i32;
|
||||||
|
|
||||||
export fn host_called_indirectly_from_roc() i32 {
|
fn host_called_indirectly_from_roc() i32 {
|
||||||
return 0x40;
|
return 0x40;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ export fn host_called_directly_from_roc() i32 {
|
||||||
return 0x80 | host_called_indirectly_from_roc() | js_called_indirectly_from_roc();
|
return 0x80 | host_called_indirectly_from_roc() | js_called_indirectly_from_roc();
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn host_called_indirectly_from_main() i32 {
|
fn host_called_indirectly_from_main() i32 {
|
||||||
return 0x100;
|
return 0x100;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn host_called_directly_from_main() i32 {
|
fn host_called_directly_from_main() i32 {
|
||||||
return 0x200 | host_called_indirectly_from_main() | js_called_indirectly_from_main();
|
return 0x200 | host_called_indirectly_from_main() | js_called_indirectly_from_main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ use roc_mono::ir::{
|
||||||
UpdateModeId,
|
UpdateModeId,
|
||||||
};
|
};
|
||||||
use roc_mono::layout::{Builtin, CapturesNiche, LambdaName, Layout, STLayoutInterner};
|
use roc_mono::layout::{Builtin, CapturesNiche, LambdaName, Layout, STLayoutInterner};
|
||||||
use roc_wasm_module::WasmModule;
|
use roc_wasm_interp::{wasi, ImportDispatcher, Instance, WasiDispatcher};
|
||||||
use wasm3::{Environment, Module};
|
use roc_wasm_module::{Value, WasmModule};
|
||||||
|
|
||||||
const LINKING_TEST_HOST_WASM: &str = "build/wasm_linking_test_host.wasm";
|
const LINKING_TEST_HOST_WASM: &str = "build/wasm_linking_test_host.wasm";
|
||||||
const LINKING_TEST_HOST_NATIVE: &str = "build/wasm_linking_test_host";
|
const LINKING_TEST_HOST_NATIVE: &str = "build/wasm_linking_test_host";
|
||||||
|
@ -183,39 +183,61 @@ impl<'a> BackendInputs<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_wasm_module(final_module: WasmModule<'_>) -> i32 {
|
struct TestDispatcher<'a> {
|
||||||
let mut wasm_bytes = Vec::with_capacity(final_module.size());
|
wasi: WasiDispatcher<'a>,
|
||||||
final_module.serialize(&mut wasm_bytes);
|
}
|
||||||
|
|
||||||
let env = Environment::new().unwrap();
|
impl ImportDispatcher for TestDispatcher<'_> {
|
||||||
let rt = env.create_runtime(1024 * 60).unwrap();
|
fn dispatch(
|
||||||
|
&mut self,
|
||||||
|
module_name: &str,
|
||||||
|
function_name: &str,
|
||||||
|
arguments: &[Value],
|
||||||
|
memory: &mut [u8],
|
||||||
|
) -> Option<Value> {
|
||||||
|
if module_name == wasi::MODULE_NAME {
|
||||||
|
self.wasi.dispatch(function_name, arguments, memory)
|
||||||
|
} else if module_name == "env" {
|
||||||
|
match function_name {
|
||||||
|
"js_called_directly_from_roc" => Some(Value::I32(0x01)),
|
||||||
|
"js_called_indirectly_from_roc" => Some(Value::I32(0x02)),
|
||||||
|
"js_called_directly_from_main" => Some(Value::I32(0x04)),
|
||||||
|
"js_called_indirectly_from_main" => Some(Value::I32(0x08)),
|
||||||
|
"js_unused" => Some(Value::I32(0x10)),
|
||||||
|
_ => panic!("Unknown import env.{}", function_name),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"TestDispatcher does not implement {}.{}",
|
||||||
|
module_name, function_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let parsed_module = Module::parse(&env, &wasm_bytes[..]).unwrap();
|
fn execute_wasm_module<'a>(arena: &'a Bump, orig_module: WasmModule<'a>) -> Result<i32, String> {
|
||||||
let mut module = rt.load_module(parsed_module).unwrap();
|
// FIXME: see if we can skip serializing and re-parsing!
|
||||||
module
|
// Some metadata seems to be left over from the host file. e.g. CodeSection::section_start
|
||||||
.link_closure("env", "js_called_directly_from_roc", |_, ()| Ok(0x01i32))
|
let module = {
|
||||||
.unwrap();
|
let mut buffer = Vec::with_capacity(orig_module.size());
|
||||||
module
|
orig_module.serialize(&mut buffer);
|
||||||
.link_closure("env", "js_called_indirectly_from_roc", |_, ()| Ok(0x02i32))
|
WasmModule::preload(arena, &buffer, false).map_err(|e| format!("{:?}", e))?
|
||||||
.unwrap();
|
};
|
||||||
module
|
|
||||||
.link_closure("env", "js_called_directly_from_main", |_, ()| Ok(0x04i32))
|
let dispatcher = TestDispatcher {
|
||||||
.unwrap();
|
wasi: wasi::WasiDispatcher { args: &[] },
|
||||||
module
|
};
|
||||||
.link_closure("env", "js_called_indirectly_from_main", |_, ()| Ok(0x08i32))
|
let is_debug_mode = true;
|
||||||
.unwrap();
|
let mut inst = Instance::for_module(&arena, &module, dispatcher, is_debug_mode)?;
|
||||||
module
|
|
||||||
.link_closure("env", "js_unused", |_, ()| Ok(0x10i32))
|
|
||||||
.unwrap_or_else(|_| {});
|
|
||||||
|
|
||||||
// In Zig, main can only return u8 or void, but our result is too wide for that.
|
// In Zig, main can only return u8 or void, but our result is too wide for that.
|
||||||
// But I want to use main so that I can test that _start is created for it!
|
// But I want to use main so that I can test that _start is created for it!
|
||||||
// So return void from main, and call another function to get the result.
|
// So return void from main, and call another function to get the result.
|
||||||
let start = module.find_function::<(), ()>("_start").unwrap();
|
inst.call_export(&module, "_start", [])?;
|
||||||
start.call().unwrap();
|
inst.call_export(&module, "read_host_result", [])?
|
||||||
|
.ok_or(String::from("expected a return value"))?
|
||||||
let read_host_result = module.find_function::<(), i32>("read_host_result").unwrap();
|
.expect_i32()
|
||||||
read_host_result.call().unwrap()
|
.map_err(|type_err| format!("{:?}", type_err))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_native_result() -> i32 {
|
fn get_native_result() -> i32 {
|
||||||
|
@ -272,9 +294,7 @@ fn test_help(
|
||||||
expected_name_section_start
|
expected_name_section_start
|
||||||
);
|
);
|
||||||
|
|
||||||
let wasm_result = execute_wasm_module(final_module);
|
let wasm_result = execute_wasm_module(&arena, final_module).unwrap();
|
||||||
|
|
||||||
// As well as having the right structure, it should return the right result!
|
|
||||||
assert_eq!(wasm_result, get_native_result());
|
assert_eq!(wasm_result, get_native_result());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +302,11 @@ const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 9] = [
|
||||||
"__linear_memory",
|
"__linear_memory",
|
||||||
"__stack_pointer",
|
"__stack_pointer",
|
||||||
"js_called_indirectly_from_roc",
|
"js_called_indirectly_from_roc",
|
||||||
"js_called_indirectly_from_main",
|
|
||||||
"js_unused",
|
"js_unused",
|
||||||
"js_called_directly_from_roc",
|
"js_called_directly_from_roc",
|
||||||
"js_called_directly_from_main",
|
"js_called_directly_from_main",
|
||||||
"roc__app_proc_1_exposed",
|
"roc__app_proc_1_exposed",
|
||||||
|
"js_called_indirectly_from_main",
|
||||||
"__indirect_function_table",
|
"__indirect_function_table",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -294,18 +314,18 @@ const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 9] = [
|
||||||
fn test_linking_without_dce() {
|
fn test_linking_without_dce() {
|
||||||
let expected_final_import_names = &[
|
let expected_final_import_names = &[
|
||||||
"js_called_indirectly_from_roc",
|
"js_called_indirectly_from_roc",
|
||||||
"js_called_indirectly_from_main",
|
|
||||||
"js_unused", // not eliminated
|
"js_unused", // not eliminated
|
||||||
"js_called_directly_from_roc",
|
"js_called_directly_from_roc",
|
||||||
"js_called_directly_from_main",
|
"js_called_directly_from_main",
|
||||||
|
"js_called_indirectly_from_main",
|
||||||
];
|
];
|
||||||
|
|
||||||
let expected_name_section_start = &[
|
let expected_name_section_start = &[
|
||||||
(0, "js_called_indirectly_from_roc"),
|
(0, "js_called_indirectly_from_roc"),
|
||||||
(1, "js_called_indirectly_from_main"),
|
(1, "js_unused"), // not eliminated
|
||||||
(2, "js_unused"), // not eliminated
|
(2, "js_called_directly_from_roc"),
|
||||||
(3, "js_called_directly_from_roc"),
|
(3, "js_called_directly_from_main"),
|
||||||
(4, "js_called_directly_from_main"),
|
(4, "js_called_indirectly_from_main"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let eliminate_dead_code = false;
|
let eliminate_dead_code = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue