Skip to content

Commit

Permalink
Ignore ordering of function names in Wasm linking test
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-carroll committed Sep 30, 2023
1 parent 42d148d commit 3837c42
Showing 1 changed file with 46 additions and 55 deletions.
101 changes: 46 additions & 55 deletions crates/compiler/test_gen/src/wasm_linking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ fn get_native_result() -> i32 {
fn test_help(
eliminate_dead_code: bool,
expected_host_import_names: &[&str],
expected_final_import_names: &[&str],
expected_name_section_start: &[(u32, &str)],
expected_linked_import_names: &[&str],
expected_eliminated_names: &[&str],
dump_filename: &str,
) {
let arena = Bump::new();
Expand All @@ -268,12 +268,14 @@ fn test_help(
procedures,
} = 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!(&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,
&mut layout_interner,
&mut interns,
Expand All @@ -282,97 +284,86 @@ fn test_help(
);

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() {
let mut buffer = Vec::with_capacity(final_module.size());
final_module.serialize(&mut buffer);
let mut buffer = Vec::with_capacity(linked_module.size());
linked_module.serialize(&mut buffer);
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);

let name_count = expected_name_section_start.len();
assert_eq!(
&final_module.names.function_names[0..name_count],
expected_name_section_start
// eliminated imports appear after the non-eliminated ones in the name section
let import_count = linked_import_names.len();
let eliminated_count = expected_eliminated_names.len();
let eliminated_names = Vec::from_iter(
linked_module.names.function_names[import_count..][..eliminated_count]
.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());
}

const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 9] = [
"__linear_memory",
"__stack_pointer",
"js_called_indirectly_from_roc",
"js_unused",
"js_called_directly_from_roc",
"js_called_directly_from_main",
"roc__app_proc_1_exposed",
"js_called_indirectly_from_main",
"__indirect_function_table",
const EXPECTED_HOST_IMPORT_NAMES: [&'static str; 8] = [
"__linear_memory", // linked with the Roc app, not imported from JS
"__stack_pointer", // linked with the Roc app, not imported from JS
"js_called_directly_from_main", // imported from JS
"js_called_directly_from_roc", // imported from JS
"js_called_indirectly_from_main", // imported from JS
"js_called_indirectly_from_roc", // imported from JS
"js_unused", // Dead code. If DCE enabled, not imported from JS.
"roc__app_proc_1_exposed", // linked with the Roc app, not imported from JS
];

#[test]
fn test_linking_without_dce() {
let expected_final_import_names = &[
"js_called_indirectly_from_roc",
"js_unused", // not eliminated
"js_called_directly_from_roc",
let eliminate_dead_code = false;
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_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 dump_filename = "build/without_dce.wasm";
let expected_eliminated_names = &[];

test_help(
eliminate_dead_code,
&EXPECTED_HOST_IMPORT_NAMES,
expected_final_import_names,
expected_name_section_start,
expected_linked_import_names,
expected_eliminated_names,
dump_filename,
);
}

#[test]
fn test_linking_with_dce() {
let eliminate_dead_code = true;
let dump_filename = "build/with_dce.wasm";

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_directly_from_roc",
"js_called_indirectly_from_main",
"js_called_indirectly_from_roc",
];

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 dump_filename = "build/with_dce.wasm";
let expected_eliminated_names = &["js_unused"];

test_help(
eliminate_dead_code,
&EXPECTED_HOST_IMPORT_NAMES,
expected_final_import_names,
expected_name_section_start,
expected_eliminated_names,
dump_filename,
);
}

0 comments on commit 3837c42

Please sign in to comment.