diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index 3e0904d44e2..a6c2dfefe62 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -156,37 +156,41 @@ impl Run { use wasmer_wasi::WasiVersion; let wasi_versions = Wasi::get_versions(&module); - if let Some(wasi_versions) = wasi_versions { - if wasi_versions.len() >= 2 { - let get_version_list = |versions: &BTreeSet| -> String { - versions - .iter() - .map(|v| format!("`{}`", v.get_namespace_str())) - .collect::>() - .join(", ") - }; - if self.wasi.deny_multiple_wasi_versions { - let version_list = get_version_list(&wasi_versions); - bail!("Found more than 1 WASI version in this module ({}) and `--deny-multiple-wasi-versions` is enabled.", version_list); - } else if !self.wasi.allow_multiple_wasi_versions { - let version_list = get_version_list(&wasi_versions); - warning!("Found more than 1 WASI version in this module ({}). If this is intentional, pass `--allow-multiple-wasi-versions` to suppress this warning.", version_list); + match wasi_versions { + Some(wasi_versions) if !wasi_versions.is_empty() => { + if wasi_versions.len() >= 2 { + let get_version_list = |versions: &BTreeSet| -> String { + versions + .iter() + .map(|v| format!("`{}`", v.get_namespace_str())) + .collect::>() + .join(", ") + }; + if self.wasi.deny_multiple_wasi_versions { + let version_list = get_version_list(&wasi_versions); + bail!("Found more than 1 WASI version in this module ({}) and `--deny-multiple-wasi-versions` is enabled.", version_list); + } else if !self.wasi.allow_multiple_wasi_versions { + let version_list = get_version_list(&wasi_versions); + warning!("Found more than 1 WASI version in this module ({}). If this is intentional, pass `--allow-multiple-wasi-versions` to suppress this warning.", version_list); + } } - } - let program_name = self - .command_name - .clone() - .or_else(|| { - self.path - .file_name() - .map(|f| f.to_string_lossy().to_string()) - }) - .unwrap_or_default(); - return self - .wasi - .execute(module, program_name, self.args.clone()) - .with_context(|| "WASI execution failed"); + let program_name = self + .command_name + .clone() + .or_else(|| { + self.path + .file_name() + .map(|f| f.to_string_lossy().to_string()) + }) + .unwrap_or_default(); + return self + .wasi + .execute(module, program_name, self.args.clone()) + .with_context(|| "WASI execution failed"); + } + // not WASI + _ => (), } } diff --git a/lib/engine/src/resolver.rs b/lib/engine/src/resolver.rs index a447899c3ea..a86db9ce84e 100644 --- a/lib/engine/src/resolver.rs +++ b/lib/engine/src/resolver.rs @@ -70,7 +70,14 @@ impl NamedResolver for Box { } } -/// `Resolver` implementation that always resolves to `None`. +impl NamedResolver for () { + /// Always returns `None`. + fn resolve_by_name(&self, _module: &str, _field: &str) -> Option { + None + } +} + +/// `Resolver` implementation that always resolves to `None`. Equivalent to `()`. pub struct NullResolver {} impl Resolver for NullResolver { diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index c0344018de9..fc83dd5e72d 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -88,16 +88,9 @@ impl WasiEnv { ) -> Result, WasiError> { let wasi_versions = get_wasi_versions(module, false).ok_or(WasiError::UnknownWasiVersion)?; - let mut version_iter = wasi_versions.iter(); - let mut resolver: Box = { - let version = version_iter.next().ok_or(WasiError::UnknownWasiVersion)?; - Box::new(generate_import_object_from_env( - module.store(), - self.clone(), - *version, - )) - }; - for version in version_iter { + + let mut resolver: Box = { Box::new(()) }; + for version in wasi_versions.iter() { let new_import_object = generate_import_object_from_env(module.store(), self.clone(), *version); resolver = Box::new(new_import_object.chain_front(resolver)); diff --git a/tests/integration/cli/src/assets.rs b/tests/integration/cli/src/assets.rs index f3ca082a6be..6af9cec29c2 100644 --- a/tests/integration/cli/src/assets.rs +++ b/tests/integration/cli/src/assets.rs @@ -1,10 +1,11 @@ use std::env; use std::path::PathBuf; -pub const ASSET_PATH: &str = concat!( +pub const C_ASSET_PATH: &str = concat!( env!("CARGO_MANIFEST_DIR"), "/../../../lib/c-api/tests/assets" ); +pub const ASSET_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../tests/examples"); pub const WASMER_INCLUDE_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../lib/c-api"); diff --git a/tests/integration/cli/tests/compile.rs b/tests/integration/cli/tests/compile.rs index fc74a4e0e11..b5b767dffc0 100644 --- a/tests/integration/cli/tests/compile.rs +++ b/tests/integration/cli/tests/compile.rs @@ -12,7 +12,7 @@ const OBJECT_FILE_ENGINE_TEST_C_SOURCE: &[u8] = include_bytes!("object_file_engine_test_c_source.c"); fn object_file_engine_test_wasm_path() -> String { - format!("{}/{}", ASSET_PATH, "qjs.wasm") + format!("{}/{}", C_ASSET_PATH, "qjs.wasm") } /// Data used to run the `wasmer compile` command. diff --git a/tests/integration/cli/tests/create_exe.rs b/tests/integration/cli/tests/create_exe.rs index b8302bccd5a..3669aed28f2 100644 --- a/tests/integration/cli/tests/create_exe.rs +++ b/tests/integration/cli/tests/create_exe.rs @@ -8,7 +8,7 @@ use std::process::Command; use wasmer_integration_tests_cli::*; fn create_exe_test_wasm_path() -> String { - format!("{}/{}", ASSET_PATH, "qjs.wasm") + format!("{}/{}", C_ASSET_PATH, "qjs.wasm") } const JS_TEST_SRC_CODE: &[u8] = b"function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));\n"; diff --git a/tests/integration/cli/tests/run.rs b/tests/integration/cli/tests/run.rs new file mode 100644 index 00000000000..7a2ed750eed --- /dev/null +++ b/tests/integration/cli/tests/run.rs @@ -0,0 +1,59 @@ +//! Basic tests for the `run` subcommand + +use anyhow::bail; +use std::process::Command; +use wasmer_integration_tests_cli::{ASSET_PATH, C_ASSET_PATH, WASMER_PATH}; + +fn wasi_test_wasm_path() -> String { + format!("{}/{}", C_ASSET_PATH, "qjs.wasm") +} + +fn test_no_imports_wat_path() -> String { + format!("{}/{}", ASSET_PATH, "fib.wat") +} + +#[test] +fn run_wasi_works() -> anyhow::Result<()> { + let output = Command::new(WASMER_PATH) + .arg("run") + .arg(wasi_test_wasm_path()) + .arg("--") + .arg("-e") + .arg("print(3 * (4 + 5))") + .output()?; + + if !output.status.success() { + bail!( + "linking failed with: stdout: {}\n\nstderr: {}", + std::str::from_utf8(&output.stdout) + .expect("stdout is not utf8! need to handle arbitrary bytes"), + std::str::from_utf8(&output.stderr) + .expect("stderr is not utf8! need to handle arbitrary bytes") + ); + } + + let stdout_output = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(stdout_output, "27\n"); + + Ok(()) +} + +#[test] +fn run_no_imports_wasm_works() -> anyhow::Result<()> { + let output = Command::new(WASMER_PATH) + .arg("run") + .arg(test_no_imports_wat_path()) + .output()?; + + if !output.status.success() { + bail!( + "linking failed with: stdout: {}\n\nstderr: {}", + std::str::from_utf8(&output.stdout) + .expect("stdout is not utf8! need to handle arbitrary bytes"), + std::str::from_utf8(&output.stderr) + .expect("stderr is not utf8! need to handle arbitrary bytes") + ); + } + + Ok(()) +}