diff --git a/Cargo.lock b/Cargo.lock index c85cd7b8..18486de9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1506,15 +1506,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "serde_bytes" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" -dependencies = [ - "serde", -] - [[package]] name = "serde_cbor" version = "0.11.2" @@ -1556,18 +1547,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" -dependencies = [ - "indexmap 1.9.3", - "ryu", - "serde", - "yaml-rust", -] - [[package]] name = "serde_yaml" version = "0.9.30" @@ -1850,16 +1829,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.10" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -2092,7 +2071,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "virtual-fs" version = "0.11.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "async-trait", @@ -2115,7 +2094,7 @@ dependencies = [ [[package]] name = "virtual-mio" version = "0.3.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "async-trait", "bytes", @@ -2129,7 +2108,7 @@ dependencies = [ [[package]] name = "virtual-net" version = "0.6.2" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "async-trait", @@ -2218,7 +2197,7 @@ dependencies = [ [[package]] name = "wai-bindgen-wasmer" version = "0.18.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "bitflags 1.3.2", @@ -2401,7 +2380,7 @@ dependencies = [ [[package]] name = "wasmer" version = "4.2.5" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "bytes", "cfg-if", @@ -2430,7 +2409,7 @@ dependencies = [ [[package]] name = "wasmer-compiler" version = "4.2.5" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "backtrace", "bytes", @@ -2444,8 +2423,6 @@ dependencies = [ "region", "rkyv", "self_cell", - "serde", - "serde_bytes", "shared-buffer", "smallvec", "thiserror", @@ -2457,7 +2434,7 @@ dependencies = [ [[package]] name = "wasmer-derive" version = "4.2.5" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "proc-macro-error", "proc-macro2", @@ -2468,7 +2445,7 @@ dependencies = [ [[package]] name = "wasmer-journal" version = "0.1.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "async-trait", @@ -2535,7 +2512,7 @@ dependencies = [ "serde", "serde_cbor", "serde_json", - "serde_yaml 0.9.30", + "serde_yaml", "thiserror", "toml 0.8.8", ] @@ -2543,7 +2520,7 @@ dependencies = [ [[package]] name = "wasmer-types" version = "4.2.5" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "bytecheck", "enum-iterator", @@ -2552,7 +2529,6 @@ dependencies = [ "more-asserts", "rkyv", "serde", - "serde_bytes", "target-lexicon", "thiserror", ] @@ -2560,7 +2536,7 @@ dependencies = [ [[package]] name = "wasmer-vm" version = "4.2.5" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "backtrace", "cc", @@ -2579,7 +2555,6 @@ dependencies = [ "more-asserts", "region", "scopeguard", - "serde", "thiserror", "wasmer-types", "winapi", @@ -2588,7 +2563,7 @@ dependencies = [ [[package]] name = "wasmer-wasix" version = "0.18.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "async-trait", @@ -2622,7 +2597,7 @@ dependencies = [ "serde_cbor", "serde_derive", "serde_json", - "serde_yaml 0.8.26", + "serde_yaml", "sha2", "shared-buffer", "tempfile", @@ -2654,7 +2629,7 @@ dependencies = [ [[package]] name = "wasmer-wasix-types" version = "0.18.0" -source = "git+https://github.com/wasmerio/wasmer?branch=master#0cf0f5b26debffa1d4e615732ab1b55b991ef687" +source = "git+https://github.com/wasmerio/wasmer?branch=wasi-runner-custom-imports#0426d8fc7dd14cd8977b1a24a7d7975d27734910" dependencies = [ "anyhow", "bitflags 1.3.2", @@ -2999,12 +2974,3 @@ name = "xxhash-rust" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53be06678ed9e83edb1745eb72efc0bbcd7b5c3c35711a860906aed827a13d61" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] diff --git a/Cargo.toml b/Cargo.toml index b2dc7958..31c227c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ wasm-bindgen = { version = "0.2" } wasm-bindgen-derive = "0.2.1" wasm-bindgen-futures = "0.4" wasm-bindgen-test = "0.3.37" -wasmer = { version = "4.2.5", default-features = false, features = ["js", "js-default", "tracing", "wasm-types-polyfill", "enable-serde"] } +wasmer = { version = "4.2.5", default-features = false, features = ["js", "js-default", "wasm-types-polyfill"] } wasmer-wasix = { version = "0.18", default-features = false, features = ["js", "js-default"] } webc = "5.3.0" @@ -95,10 +95,10 @@ dwarf-debug-info = false wasm-opt = ["--enable-threads", "--enable-bulk-memory", "-Oz"] [patch.crates-io] -virtual-net = { git = "https://github.com/wasmerio/wasmer", branch = "master" } -virtual-fs = { git = "https://github.com/wasmerio/wasmer", branch = "master" } -wasmer-wasix = { git = "https://github.com/wasmerio/wasmer", branch = "master" } -wasmer = { git = "https://github.com/wasmerio/wasmer", branch = "master" } +virtual-net = { git = "https://github.com/wasmerio/wasmer", branch = "wasi-runner-custom-imports" } +virtual-fs = { git = "https://github.com/wasmerio/wasmer", branch = "wasi-runner-custom-imports" } +wasmer-wasix = { git = "https://github.com/wasmerio/wasmer", branch = "wasi-runner-custom-imports" } +wasmer = { git = "https://github.com/wasmerio/wasmer", branch = "wasi-runner-custom-imports" } # virtual-net = { path = "../wasmer/lib/virtual-net" } # virtual-fs = { path = "../wasmer/lib/virtual-fs" } # wasmer-wasix = { path = "../wasmer/lib/wasix" } diff --git a/src/options.rs b/src/options.rs index 53a66c46..e877792a 100644 --- a/src/options.rs +++ b/src/options.rs @@ -4,6 +4,7 @@ use anyhow::Context; use js_sys::Array; use virtual_fs::TmpFileSystem; use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue, UnwrapThrowExt}; +use wasmer::{Extern, Imports}; use wasmer_wasix::WasiEnvBuilder; use crate::{runtime::Runtime, utils::Error, Directory, DirectoryInit, JsRuntime, StringOrBytes}; @@ -41,6 +42,10 @@ type CommonOptions = { * files. */ mount?: Record; + /** + * Additional items that may be imported by the WebAssembly instance. + */ + imports?: Record>; }; /** @@ -82,6 +87,9 @@ extern "C" { #[wasm_bindgen(method, getter)] fn env(this: &CommonOptions) -> JsValue; + #[wasm_bindgen(method, getter)] + fn imports(this: &CommonOptions) -> JsValue; + #[wasm_bindgen(method, getter)] fn stdin(this: &CommonOptions) -> Option; @@ -139,6 +147,31 @@ impl CommonOptions { Ok(mounted_directories) } + + pub(crate) fn load_imports(&self) -> Result { + let mut imports = Imports::default(); + + if let Ok(obj) = self.imports().dyn_into() { + for (namespace, ns) in crate::utils::object_entries(&obj)? { + let namespace = String::from(namespace); + let ns = ns + .dyn_ref::() + .context("Expected a record of records")?; + + for (name, value) in crate::utils::object_entries(&ns)? { + let name = String::from(name); + let extern_value = interpret_import(value).ok_or_else(|| { + Error::js(js_sys::TypeError::new(&format!( + "Invalid type for {namespace}/{name}" + ))) + })?; + imports.define(&namespace, &name, extern_value); + } + } + } + + Ok(Imports::default()) + } } impl Default for CommonOptions { @@ -150,6 +183,10 @@ impl Default for CommonOptions { } } +fn interpret_import(_value: JsValue) -> Option { + todo!() +} + #[wasm_bindgen] extern "C" { #[wasm_bindgen(typescript_type = "RunOptions", extends = CommonOptions)] diff --git a/src/run.rs b/src/run.rs index 887aad62..4665be80 100644 --- a/src/run.rs +++ b/src/run.rs @@ -37,6 +37,9 @@ async fn run_wasix_inner(wasm_module: WasmModule, config: RunOptions) -> Result< let mut builder = WasiEnvBuilder::new(program_name).runtime(runtime.clone()); let (stdin, stdout, stderr) = config.configure_builder(&mut builder)?; + let imports = config.load_imports()?; + builder.add_imports(&imports); + let (exit_code_tx, exit_code_rx) = oneshot::channel(); let module: wasmer::Module = wasm_module.to_module(&*runtime).await?; diff --git a/src/wasmer.rs b/src/wasmer.rs index be5adaf9..8df6b4f1 100644 --- a/src/wasmer.rs +++ b/src/wasmer.rs @@ -216,23 +216,26 @@ pub(crate) async fn configure_runner( Error, > { let args = options.parse_args()?; - runner.set_args(args); + runner.with_args(args); let env = options.parse_env()?; - runner.set_envs(env); + runner.with_envs(env); + + let imports = options.load_imports()?; + runner.with_imports(&imports); for (dest, dir) in options.mounted_directories()? { - runner.mount(dest, Arc::new(dir)); + runner.with_mount(dest, Arc::new(dir)); } if let Some(uses) = options.uses() { let uses = crate::utils::js_string_array(uses)?; let packages = load_injected_packages(uses, runtime).await?; - runner.add_injected_packages(packages); + runner.with_injected_packages(packages); } let (stderr_pipe, stderr_stream) = crate::streams::output_pipe(); - runner.set_stderr(Box::new(stderr_pipe)); + runner.with_stderr(Box::new(stderr_pipe)); let tty_options = runtime.tty_options().clone(); match setup_tty(options, tty_options) { @@ -243,16 +246,16 @@ pub(crate) async fn configure_runner( stdin_stream, } => { tracing::debug!("Setting up interactive TTY"); - runner.set_stdin(Box::new(stdin_pipe)); - runner.set_stdout(Box::new(stdout_pipe)); + runner.with_stdin(Box::new(stdin_pipe)); + runner.with_stdout(Box::new(stdout_pipe)); runtime.set_connected_to_tty(true); Ok((Some(stdin_stream), stdout_stream, stderr_stream)) } TerminalMode::NonInteractive { stdin } => { tracing::debug!("Setting up non-interactive TTY"); let (stdout_pipe, stdout_stream) = crate::streams::output_pipe(); - runner.set_stdin(Box::new(stdin)); - runner.set_stdout(Box::new(stdout_pipe)); + runner.with_stdin(Box::new(stdin)); + runner.with_stdout(Box::new(stdout_pipe)); // HACK: Make sure we don't report stdin as interactive. This // doesn't belong here because now it'll affect every other