diff --git a/crates/cli/tests/dynamic_linking_test.rs b/crates/cli/tests/dynamic_linking_test.rs index 5d975a09..8890bf7d 100644 --- a/crates/cli/tests/dynamic_linking_test.rs +++ b/crates/cli/tests/dynamic_linking_test.rs @@ -60,19 +60,7 @@ fn test_errors_in_exported_functions_are_correctly_reported(builder: &mut Builde // If you need to change this test, then you've likely made a breaking change. pub fn check_for_new_imports(builder: &mut Builder) -> Result<()> { let runner = builder.input("console.js").build()?; - runner.assert_known_base_imports() -} - -#[javy_cli_test(dyn = true, root = "tests/dynamic-linking-scripts")] -// If you need to change this test, then you've likely made a breaking change. -pub fn check_for_new_imports_for_exports(builder: &mut Builder) -> Result<()> { - let runner = builder - .input("linking-with-func.js") - .wit("linking-with-func.wit") - .world("foo-test") - .build()?; - - runner.assert_known_named_function_imports() + runner.ensure_expected_imports() } #[javy_cli_test(dyn = true, root = "tests/dynamic-linking-scripts")] diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs index 3a879d73..7a28b412 100644 --- a/crates/runner/src/lib.rs +++ b/crates/runner/src/lib.rs @@ -428,67 +428,63 @@ impl Runner { }) } - pub fn assert_known_base_imports(&self) -> Result<()> { + pub fn ensure_expected_imports(&self) -> Result<()> { let module = Module::from_binary(self.linker.engine(), &self.wasm)?; let instance_name = self.plugin.namespace(); - let result = module.imports().filter(|i| { - if i.module() == instance_name && i.name() == "canonical_abi_realloc" { - let ty = i.ty(); - let f = ty.unwrap_func(); - return f.params().all(|p| p.is_i32()) - && f.params().len() == 4 - && f.results().len() == 1 - && f.results().all(|r| r.is_i32()); - } - - if i.module() == instance_name && i.name() == "eval_bytecode" { - let ty = i.ty(); - let f = ty.unwrap_func(); - return f.params().all(|p| p.is_i32()) - && f.params().len() == 2 - && f.results().len() == 0; - } - - if i.module() == instance_name && i.name() == "memory" { - let ty = i.ty(); - return ty.memory().is_some(); - } - - false - }); - - let count = result.count(); - if count == 3 { - Ok(()) - } else { - Err(anyhow!("Unexpected number of imports: {}", count)) + let imports = module + .imports() + .filter(|i| i.module() == instance_name) + .collect::>(); + if imports.len() != 4 { + bail!("Dynamically linked modules should have exactly 4 imports for {instance_name}"); } - } - pub fn assert_known_named_function_imports(&self) -> Result<()> { - self.assert_known_base_imports()?; + let realloc = imports + .iter() + .find(|i| i.name() == "canonical_abi_realloc") + .ok_or_else(|| anyhow!("Should have canonical_abi_realloc import"))?; + let ty = realloc.ty(); + let f = ty.unwrap_func(); + if !f.params().all(|p| p.is_i32()) || f.params().len() != 4 { + bail!("canonical_abi_realloc should accept 4 i32s as parameters"); + } + if !f.results().all(|p| p.is_i32()) || f.results().len() != 1 { + bail!("canonical_abi_realloc should return 1 i32 as a result"); + } - let module = Module::from_binary(self.linker.engine(), &self.wasm)?; - let instance_name = self.plugin.namespace(); - let result = module.imports().filter(|i| { - if i.module() == instance_name && i.name() == "invoke" { - let ty = i.ty(); - let f = ty.unwrap_func(); - - return f.params().len() == 4 - && f.params().all(|p| p.is_i32()) - && f.results().len() == 0; - } + imports + .iter() + .find(|i| i.name() == "memory" && i.ty().memory().is_some()) + .ok_or_else(|| anyhow!("Should have memory import named memory"))?; + + let eval_bytecode = imports + .iter() + .find(|i| i.name() == "eval_bytecode") + .ok_or_else(|| anyhow!("Should have eval_bytecode import"))?; + let ty = eval_bytecode.ty(); + let f = ty.unwrap_func(); + if !f.params().all(|p| p.is_i32()) || f.params().len() != 2 { + bail!("eval_bytecode should accept 2 i32s as parameters"); + } + if f.results().len() != 0 { + bail!("eval_bytecode should return no results"); + } - false - }); - let count = result.count(); - if count == 1 { - Ok(()) - } else { - Err(anyhow!("Unexpected number of imports: {}", count)) + let invoke = imports + .iter() + .find(|i| i.name() == "invoke") + .ok_or_else(|| anyhow!("Should have invoke import"))?; + let ty = invoke.ty(); + let f = ty.unwrap_func(); + if !f.params().all(|p| p.is_i32()) || f.params().len() != 4 { + bail!("invoke should accept 4 i32s as parameters"); + } + if f.results().len() != 0 { + bail!("invoke should return no results"); } + + Ok(()) } pub fn assert_producers(&self) -> Result<()> {