Ignore ordering of function names in Wasm linking test

This commit is contained in:
Brian Carroll 2023-09-30 16:50:25 +01:00 committed by Brendan Hansknecht
parent ca283197b9
commit 89acb6461a
No known key found for this signature in database
GPG key ID: 0EA784685083E75B

View file

@ -254,8 +254,8 @@ fn get_native_result() -> i32 {
fn test_help( fn test_help(
eliminate_dead_code: bool, eliminate_dead_code: bool,
expected_host_import_names: &[&str], expected_host_import_names: &[&str],
expected_final_import_names: &[&str], expected_linked_import_names: &[&str],
expected_name_section_start: &[(u32, &str)], expected_eliminated_names: &[&str],
dump_filename: &str, dump_filename: &str,
) { ) {
let arena = Bump::new(); let arena = Bump::new();
@ -268,12 +268,14 @@ fn test_help(
procedures, procedures,
} = BackendInputs::new(&arena); } = BackendInputs::new(&arena);
let host_import_names = Vec::from_iter(host_module.import.imports.iter().map(|imp| imp.name)); let mut host_import_names =
Vec::from_iter(host_module.import.imports.iter().map(|imp| imp.name));
host_import_names.sort();
assert_eq!(&host_import_names, expected_host_import_names); assert_eq!(&host_import_names, expected_host_import_names);
assert!(&host_module.names.function_names.is_empty()); assert!(&host_module.names.function_names.is_empty());
let (mut final_module, called_fns, _roc_main_index) = roc_gen_wasm::build_app_module( let (mut linked_module, called_fns, _roc_main_index) = roc_gen_wasm::build_app_module(
&env, &env,
&mut layout_interner, &mut layout_interner,
&mut interns, &mut interns,
@ -282,97 +284,86 @@ fn test_help(
); );
if eliminate_dead_code { if eliminate_dead_code {
final_module.eliminate_dead_code(env.arena, called_fns); linked_module.eliminate_dead_code(env.arena, called_fns);
} }
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()); let mut buffer = Vec::with_capacity(linked_module.size());
final_module.serialize(&mut buffer); linked_module.serialize(&mut buffer);
fs::write(dump_filename, &buffer).unwrap(); fs::write(dump_filename, &buffer).unwrap();
} }
let final_import_names = Vec::from_iter(final_module.import.imports.iter().map(|i| i.name)); let linked_import_names = Vec::from_iter(linked_module.import.imports.iter().map(|i| i.name));
assert_eq!(&linked_import_names, expected_linked_import_names);
assert_eq!(&final_import_names, expected_final_import_names); // eliminated imports appear after the non-eliminated ones in the name section
let import_count = linked_import_names.len();
let name_count = expected_name_section_start.len(); let eliminated_count = expected_eliminated_names.len();
assert_eq!( let eliminated_names = Vec::from_iter(
&final_module.names.function_names[0..name_count], linked_module.names.function_names[import_count..][..eliminated_count]
expected_name_section_start .iter()
.map(|(_, name)| *name),
); );
assert_eq!(&eliminated_names, expected_eliminated_names);
let wasm_result = execute_wasm_module(&arena, final_module).unwrap(); let wasm_result = execute_wasm_module(&arena, linked_module).unwrap();
assert_eq!(wasm_result, get_native_result()); assert_eq!(wasm_result, get_native_result());
} }
const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 9] = [ const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 8] = [
"__linear_memory", "__linear_memory", // linked with the Roc app, not imported from JS
"__stack_pointer", "__stack_pointer", // linked with the Roc app, not imported from JS
"js_called_indirectly_from_roc", "js_called_directly_from_main", // imported from JS
"js_unused", "js_called_directly_from_roc", // imported from JS
"js_called_directly_from_roc", "js_called_indirectly_from_main", // imported from JS
"js_called_directly_from_main", "js_called_indirectly_from_roc", // imported from JS
"roc__app_proc_1_exposed", "js_unused", // Dead code. If DCE enabled, not imported from JS.
"js_called_indirectly_from_main", "roc__app_proc_1_exposed", // linked with the Roc app, not imported from JS
"__indirect_function_table",
]; ];
#[test] #[test]
fn test_linking_without_dce() { fn test_linking_without_dce() {
let expected_final_import_names = &[
"js_called_indirectly_from_roc",
"js_unused", // not eliminated
"js_called_directly_from_roc",
"js_called_directly_from_main",
"js_called_indirectly_from_main",
];
let expected_name_section_start = &[
(0, "js_called_indirectly_from_roc"),
(1, "js_unused"), // not eliminated
(2, "js_called_directly_from_roc"),
(3, "js_called_directly_from_main"),
(4, "js_called_indirectly_from_main"),
];
let eliminate_dead_code = false; let eliminate_dead_code = false;
let dump_filename = "build/without_dce.wasm"; let dump_filename = "build/without_dce.wasm";
let expected_linked_import_names = &[
"js_called_directly_from_main",
"js_called_directly_from_roc",
"js_called_indirectly_from_main",
"js_called_indirectly_from_roc",
"js_unused",
];
let expected_eliminated_names = &[];
test_help( test_help(
eliminate_dead_code, eliminate_dead_code,
&EXPECTED_HOST_IMPORT_NAMES, &EXPECTED_HOST_IMPORT_NAMES,
expected_final_import_names, expected_linked_import_names,
expected_name_section_start, expected_eliminated_names,
dump_filename, dump_filename,
); );
} }
#[test] #[test]
fn test_linking_with_dce() { fn test_linking_with_dce() {
let expected_final_import_names = &[
"js_called_indirectly_from_roc",
// "js_unused", // eliminated
"js_called_directly_from_roc",
"js_called_directly_from_main",
"js_called_indirectly_from_main",
];
let expected_name_section_start = &[
(0, "js_called_indirectly_from_roc"),
(1, "js_called_directly_from_roc"), // index changed
(2, "js_called_directly_from_main"), // index changed
(3, "js_called_indirectly_from_main"), // index changed
(4, "js_unused"), // still exists, but now an internal dummy, with index changed
];
let eliminate_dead_code = true; let eliminate_dead_code = true;
let dump_filename = "build/with_dce.wasm"; let dump_filename = "build/with_dce.wasm";
let expected_final_import_names = &[
"js_called_directly_from_main",
"js_called_directly_from_roc",
"js_called_indirectly_from_main",
"js_called_indirectly_from_roc",
];
let expected_eliminated_names = &["js_unused"];
test_help( test_help(
eliminate_dead_code, eliminate_dead_code,
&EXPECTED_HOST_IMPORT_NAMES, &EXPECTED_HOST_IMPORT_NAMES,
expected_final_import_names, expected_final_import_names,
expected_name_section_start, expected_eliminated_names,
dump_filename, dump_filename,
); );
} }