Skip to content

Commit

Permalink
feat(wasmtime-cli): add async support flag
Browse files Browse the repository at this point in the history
This will add a flag called `--async` that will
inject the asynchronous functions to linkers
instead of the synchronous one.
  • Loading branch information
eduardomourar committed Aug 22, 2023
1 parent 367bdc8 commit fd6cecb
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 11 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 31 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ wasmtime-wasi-http = { workspace = true, optional = true }
wasmtime-runtime = { workspace = true }
clap = { workspace = true, features = ["color", "suggestions", "derive"] }
anyhow = { workspace = true }
futures = { workspace = true }
target-lexicon = { workspace = true }
humantime = "2.0.0"
once_cell = { workspace = true }
Expand All @@ -51,14 +52,24 @@ rustix = { workspace = true, features = ["mm", "param"] }

[dev-dependencies]
# depend again on wasmtime to activate its default features for tests
wasmtime = { workspace = true, features = ['component-model', 'async', 'default', 'winch'] }
wasmtime = { workspace = true, features = [
'component-model',
'async',
'default',
'winch',
] }
env_logger = { workspace = true }
log = { workspace = true }
filecheck = { workspace = true }
tempfile = { workspace = true }
test-programs = { path = "crates/test-programs" }
wasmtime-runtime = { workspace = true }
tokio = { version = "1.8.0", features = ["rt", "time", "macros", "rt-multi-thread"] }
tokio = { version = "1.8.0", features = [
"rt",
"time",
"macros",
"rt-multi-thread",
] }
wast = { workspace = true }
criterion = "0.5.0"
num_cpus = "1.13.0"
Expand Down Expand Up @@ -187,7 +198,9 @@ byte-array-literals = { path = "crates/wasi-preview1-component-adapter/byte-arra
regalloc2 = "0.9.2"

# cap-std family:
target-lexicon = { version = "0.12.3", default-features = false, features = ["std"] }
target-lexicon = { version = "0.12.3", default-features = false, features = [
"std",
] }
cap-std = "2.0.0"
cap-rand = { version = "2.0.0", features = ["small_rng"] }
cap-fs-ext = "2.0.0"
Expand Down Expand Up @@ -215,8 +228,15 @@ wit-component = "0.13.2"

# Non-Bytecode Alliance maintained dependencies:
# --------------------------
object = { version = "0.31.1", default-features = false, features = ['read_core', 'elf', 'std'] }
gimli = { version = "0.27.0", default-features = false, features = ['read', 'std'] }
object = { version = "0.31.1", default-features = false, features = [
'read_core',
'elf',
'std',
] }
gimli = { version = "0.27.0", default-features = false, features = [
'read',
'std',
] }
anyhow = "1.0.22"
windows-sys = "0.48.0"
env_logger = "0.10"
Expand Down Expand Up @@ -255,6 +275,7 @@ default = [
"jitdump",
"wasmtime/wat",
"wasmtime/parallel-compilation",
"wasmtime/async",
"vtune",
"wasi-nn",
"wasi-threads",
Expand All @@ -266,12 +287,15 @@ vtune = ["wasmtime/vtune"]
wasi-nn = ["dep:wasmtime-wasi-nn"]
wasi-threads = ["dep:wasmtime-wasi-threads"]
wasi-http = ["dep:wasmtime-wasi-http"]
pooling-allocator = ["wasmtime/pooling-allocator", "wasmtime-cli-flags/pooling-allocator"]
pooling-allocator = [
"wasmtime/pooling-allocator",
"wasmtime-cli-flags/pooling-allocator",
]
all-arch = ["wasmtime/all-arch"]
component-model = [
"wasmtime/component-model",
"wasmtime-wast/component-model",
"wasmtime-cli-flags/component-model"
"wasmtime-cli-flags/component-model",
]
winch = ["wasmtime/winch"]
wmemcheck = ["wasmtime/wmemcheck"]
Expand Down
38 changes: 34 additions & 4 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ fn parse_profile(s: &str) -> Result<Profile> {
}
}

fn run_future<F: futures::Future>(future: F) -> F::Output {
let mut f = Box::pin(future);
futures::executor::block_on(f.as_mut())
}

static AFTER_HELP: Lazy<String> = Lazy::new(|| crate::FLAG_EXPLANATIONS.to_string());

/// Runs a WebAssembly module
Expand Down Expand Up @@ -254,6 +259,10 @@ pub struct RunCommand {
/// removed. For now this is primarily here for testing.
#[clap(long)]
preview2: bool,

/// Indicates that the async support will be enabled
#[clap(long = "async")]
async_support: bool,
}

#[derive(Clone)]
Expand Down Expand Up @@ -312,6 +321,9 @@ impl RunCommand {
}
None => {}
}
if self.async_support {
config.async_support(true);
}

config.wmemcheck(self.wmemcheck);

Expand Down Expand Up @@ -597,7 +609,12 @@ impl RunCommand {
CliLinker::Core(linker) => {
// Use "" as a default module name.
let module = module.unwrap_core();
linker.module(&mut *store, "", &module).context(format!(
if self.async_support {
run_future(linker.module_async(&mut *store, "", &module))
} else {
linker.module(&mut *store, "", &module)
}
.context(format!(
"failed to instantiate {:?}",
self.module_and_args[0]
))?;
Expand Down Expand Up @@ -689,7 +706,12 @@ impl RunCommand {
// Invoke the function and then afterwards print all the results that came
// out, if there are any.
let mut results = vec![Val::null(); ty.results().len()];
let invoke_res = func.call(store, &values, &mut results).with_context(|| {
let invoke_res = if self.async_support {
run_future(func.call_async(store, &values, &mut results))
} else {
func.call(store, &values, &mut results)
}
.with_context(|| {
if let Some(name) = &self.invoke {
format!("failed to invoke `{}`", name)
} else {
Expand Down Expand Up @@ -875,7 +897,11 @@ impl RunCommand {
match linker {
CliLinker::Core(linker) => {
if self.preview2 {
wasmtime_wasi::preview2::preview1::add_to_linker_sync(linker)?;
if self.async_support {
wasmtime_wasi::preview2::preview1::add_to_linker_async(linker)?;
} else {
wasmtime_wasi::preview2::preview1::add_to_linker_sync(linker)?;
}
self.set_preview2_ctx(store)?;
} else {
wasmtime_wasi::add_to_linker(linker, |host| {
Expand All @@ -886,7 +912,11 @@ impl RunCommand {
}
#[cfg(feature = "component-model")]
CliLinker::Component(linker) => {
wasmtime_wasi::preview2::command::sync::add_to_linker(linker)?;
if self.async_support {
wasmtime_wasi::preview2::command::add_to_linker(linker)?;
} else {
wasmtime_wasi::preview2::command::sync::add_to_linker(linker)?;
}
self.set_preview2_ctx(store)?;
}
}
Expand Down
35 changes: 35 additions & 0 deletions tests/all/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,14 @@ fn wasi_misaligned_pointer() -> Result<()> {
Ok(())
}

#[test]
fn hello_with_async() -> Result<()> {
let wasm = build_wasm("tests/all/cli_tests/hello_wasi_snapshot1.wat")?;
let stdout = run_wasmtime(&["--disable-cache", "--async", wasm.path().to_str().unwrap()])?;
assert_eq!(stdout, "Hello, world!\n");
Ok(())
}

#[test]
#[ignore] // FIXME(#6811) currently is flaky and may produce no output
fn hello_with_preview2() -> Result<()> {
Expand All @@ -743,6 +751,20 @@ fn hello_with_preview2() -> Result<()> {
Ok(())
}

#[test]
#[ignore] // FIXME(#6811) currently is flaky and may produce no output
fn hello_with_preview2_and_async() -> Result<()> {
let wasm = build_wasm("tests/all/cli_tests/hello_wasi_snapshot1.wat")?;
let stdout = run_wasmtime(&[
"--disable-cache",
"--preview2",
"--async",
wasm.path().to_str().unwrap(),
])?;
assert_eq!(stdout, "Hello, world!\n");
Ok(())
}

#[test]
#[cfg_attr(not(feature = "component-model"), ignore)]
fn component_missing_feature() -> Result<()> {
Expand Down Expand Up @@ -808,6 +830,19 @@ fn run_basic_component() -> Result<()> {
Ok(())
}

#[test]
#[cfg_attr(not(feature = "component-model"), ignore)]
fn run_basic_component_async() -> Result<()> {
let wasm = build_wasm("tests/all/cli_tests/component-basic.wat")?;
run_wasmtime(&[
"--disable-cache",
"--wasm-features=component-model",
"--async",
wasm.path().to_str().unwrap(),
])?;
Ok(())
}

#[test]
#[cfg_attr(not(feature = "component-model"), ignore)]
fn run_precompiled_component() -> Result<()> {
Expand Down

0 comments on commit fd6cecb

Please sign in to comment.