wasmtime-cli: support run --invoke for components using wave#10054
wasmtime-cli: support run --invoke for components using wave#10054
run --invoke for components using wave#10054Conversation
b8e53e8 to
2c60577
Compare
|
Tried this locally and got the following: cd /Users/tpmccallum
git clone https://github.com/bytecodealliance/wasmtime.git
cd wasmtime
git checkout main
git pull origin main
git checkout pch/invoke_wave
git merge main
cargo clean
cargo build --releaseRepo I used for testing is at https://github.com/tpmccallum/testing_components/tree/main (specifically the tpmccallum@192-168-1-17 compress % /Users/tpmccallum/wasmtime/target/release/wasmtime run --invoke compress target/wasm32-wasip1/debug/compress.wasm
Error: failed to run main module `target/wasm32-wasip1/debug/compress.wasm`
Caused by:
0: parsing invoke "compress"
1: unexpected end of input at 8..8 |
|
The wave syntax requires functions to be invoked with parens, so |
|
Thanks for the response @pchickey |
|
Hi @pchickey |
|
Hi @pchickey, Run.rsOriginal/Before (Original error message)An example of a user typing Command: $ /Users/tpmccallum/test_wasmtime/wasmtime/target/release/wasmtime run --invoke "compress" /Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm Output: Error: failed to run main module `/Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm`
Caused by:
0: parsing invoke "compress"
1: unexpected end of input at 8..8An example of a user typing Command: /Users/tpmccallum/test_wasmtime/wasmtime/target/release/wasmtime run --invoke compress /Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm Output: Error: failed to run main module `/Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm`
Caused by:
0: parsing invoke "compress"
1: unexpected end of input at 8..8After (Confirming new error message that provides advice about quotes and parentheses)An example of a user typing `--invoke "compress" (with quotes). Command: $ /Users/tpmccallum/test_wasmtime/wasmtime/target/release/wasmtime run --invoke "compress" /Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm Output: Error: failed to run main module `/Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm`
Caused by:
0: failed to parse invoke 'compress': invoked function calls must include parentheses after the function name in quoted wave syntax (e.g., "compress()")
1: unexpected end of input at 8..8An example of a user typing Command: /Users/tpmccallum/test_wasmtime/wasmtime/target/release/wasmtime run --invoke compress /Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm Output: Error: failed to run main module `/Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm`
Caused by:
0: failed to parse invoke 'compress': invoked function calls must include parentheses after the function name in quoted wave syntax (e.g., "compress()")
1: unexpected end of input at 8..8After (Testing functionality of invoking a function with arguments inside the parentheses)I also updated the Rust function to accept a string argument and then tested that the proper escaping of the string argument worked: Command: /Users/tpmccallum/test_wasmtime/wasmtime/target/release/wasmtime run --invoke "compress(\"hello\")" /Users/tpmccallum/testing_components/compress/target/wasm32-wasip1/debug/compress.wasm Output: [40, 181, 47, 253, 0, 88, 41, 0, 0, 104, 101, 108, 108, 111]Documentation (
|
|
Update at #10511 |
2c60577 to
e12f933
Compare
tpmccallum
left a comment
There was a problem hiding this comment.
There was an excellent suggestion to use single quotes posted on the article about Invoke.
Using single quotes to surround the whole function call negates the need to escape double quotes around string arguments.
src/commands/run.rs
Outdated
| let invoke: &String = self.invoke.as_ref().unwrap(); | ||
|
|
||
| // Check if input is wrapped in double quotes | ||
| let lacks_quotes = !invoke.starts_with('"') && !invoke.ends_with('"'); |
There was a problem hiding this comment.
I would like to revisit this logic (and will take some help if possible).
I discussed why Rust is not able to actually check for outer quotes in this comment .
But now that I realize we can use single quotes to surround the whole function there might be another way to attempt to detect the absence of surrounding quotes (that are passed, to Rust, from the CLI). I will try and get back to this in a few hours and do some local testing.
Long story short, if a user does not envelop the function with quotes, it trips over in the CLI, before the Rust even sees it:
$ wasmtime run --invoke compress(\"hello\") compress.wasm
zsh: unknown file attribute: "wasmtime run --invoke compress("hello") compress.wasm
zsh: unknown file attribute: hThe following quoting examples do work, which is great.
$ wasmtime run --invoke "compress(\"hello\")" compress.wasm
[40, 181, 47, 253, 0, 88, 41, 0, 0, 104, 101, 108, 108, 111]$ wasmtime run --invoke 'compress("hello")' compress.wasm
[40, 181, 47, 253, 0, 88, 41, 0, 0, 104, 101, 108, 108, 111]There was a problem hiding this comment.
Just some inline updates that promote the use of ' instead of ".
|
Hi @pchickey and @alexcrichton |
| pub fn exports<'a>( | ||
| &'a self, | ||
| instance: Option<&'_ ComponentExportIndex>, | ||
| ) -> Option<impl Iterator<Item = (&'a str, types::ComponentItem, ComponentExportIndex)> + use<'a>> | ||
| { |
There was a problem hiding this comment.
I'm personally a bit hesitant to add too many flavors of accessors for exports, but would it be possible to use types::Component::exports here instead of adding these iterators?
| canonicalize_nan64(val) | ||
| } | ||
|
|
||
| #[allow(clippy::cast_possible_truncation)] |
There was a problem hiding this comment.
Is this still necessary? This currently compiles on CI so the ignoring the warning may not be necessary.
There was a problem hiding this comment.
I believe it is still necessary, yes.
For example, if I remove that line and then run the following:
rustfmt --edition 2021 crates/wasmtime/src/runtime/wave/core.rs
export CARGO_INCREMENTAL=0
export CARGO_PROFILE_DEV_DEBUG=0
export CARGO_PROFILE_TEST_DEBUG=0
export RUSTFLAGS="-D warnings"
export WIT_REQUIRE_SEMICOLONS=1
cargo clippy --workspace --all-targetsAn error appears:
error: casting `u128` to `i64` may truncate the value
--> crates/wasmtime/src/runtime/wave/core.rs:103:19
|
103 | let low = v as i64;
| ^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_truncation
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
help: ... or use `try_from` and handle the error accordingly
|
103 - let low = v as i64;
103 + let low = i64::try_from(v);
|
error: could not compile `wasmtime` (lib) due to 1 previous errorIf I add the #[allow(clippy::cast_possible_truncation)] back on line 100 the error goes away.
I originally noticed the issue in the GitHub UI. Please see screen capture below:
There was a problem hiding this comment.
Ah ok makes sense, I think it's because the wave feature must not be enabled on the clippy run which would explain this a well
| match matches.len() { | ||
| 0 => bail!("No export named `{name}` in component."), | ||
| 1 => {} | ||
| _ => bail!("Multiple exports named `{name}`: {matches:?}. FIXME: support some way to disambiguate names"), | ||
| }; |
There was a problem hiding this comment.
FWIW I think the long string above is causing rustfmt to bail out here.
* wip * wasmtime::component::Component: add iterator of exports * components_rec * exports_rec gives fully qualified name * invoke works!!! * code motion * more context in errors * fix test of invoke * Finalized enhancements for --invoke: error messages * Testing and documenting --invoke * Update if else re: invoke * Updating to fix truncation possibilities in unwrap_tuple * Add clippy annotation to resolve CI error and leave original code (that makes 2 i64 out of 1 i128 and discards extra bits). * Format (rustfmt --edition 2021) Rust files in this PR. * Removing duplicate code missed from previous conflict resolution * Add more verbose documentation * Add more verbose documentation --------- Co-authored-by: Pat Hickey <pat@moreproductive.org>
* Convert docs and error trapping to single quote approach * Adjust the error message a little
3e856ee to
d8b1666
Compare
d8b1666 to
051f906
Compare
|
@alexcrichton I rewrote the search for component exports to live in the wasmtime-cli and be much dumber/simpler than the borrowing version that was a method on Component. |

This PR adds support for
wasmtime run --invoke <wave-function-call> component.wasmto wasmtime-cli. In the existing invoke for modules, the user provides a bare function name, and only functions that do not take arguments are supported. For components, the argument to invoke is parsed into component vals using the existing wasm-wave parsing introduced in #8872. We make some effort to provide useful error messages when we can't parse the wave function call.