-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support shebang for command-line wasmtime scripts #3715
Comments
Personally I don't feel that Wasmtime should support wasmtime-specific extensions to the text format. If this wants to be supported then I think that this should be added to the official grammar of text files in the wasm specification itself. |
I would argue that this is wasmtime's responsibility, as a command-line executable whose function is to run .wat files on the command line. This is something all other script runners (perl, python, miniscript, etc. etc.) do, and the shebang is not part of the grammar of those languages either; it's just something the script runners are prepared to deal with. Conversely, a shebang doesn't make any sense in other contexts, e.g. in a .wat file that's part of a Visual Studio project. So I wouldn't expect to see it in the .wat spec itself. It only makes sense for people who (like me) are trying to use wasmtime like other command-line scripts, so it ought to just be something that wasmtime does. |
Shebang's are definitively part of the grammar of a language if an interpreter for it can handle them. |
@JoeStrout FWIW I think the main issue with support in wasmtime for this would be that it could potentially normalize "not quite compliant" But since this is Unix, there are probably ways to put together other tools to make a solution... one technique that might help is to write the wat content as a heredoc, something like the following (just tested):
One could conceivably write a tool that converts One could probably also use the "custom binfmt" support in Linux to recognize the magic number in a Anyway, just some ideas -- hope these help! |
(a little bit of pedantry, sorry: bash and python and friends do not have any particular support for |
Yeah, I don't think wasmtime should start accepting non-standard extensions to the file format. One way to do this if we somehow absolutely wanted to is to get the standard changed to support shebangs. That's what's happening in JavaScript. I'm not sure that it makes sense to do this though: the |
I'm surprised by the negative reactions. All I'm asking for is to skip the first line of the input if it starts with It's not a big ask, and it's a substantial quality-of-life improvement, at least for some of us. |
The "big" part of the ask is to support a non-standard extension to a standardized format, that'd then mean that that format only runs in our runtime, but not others. The right way to go about adding something like this is to propose it in the WebAssembly Community Group. As I said in my previous comment I also think that this isn't the right thing to do to begin with, but a sufficient number of people in the Community Group might disagree for it to be standardized, in which case we'd implement it. |
I'm going to close this form the discussion above. I think it's still reasonable to propose this extension to the wasm CG and the text format if you're interested though. |
Just encountered this limitation trying to run WebAssembly as a Native Messaging host. To me it seems
|
How will that work when the WebAssembly module is expected to be reading stdin from an application, e.g., the browser? |
You can write the wat file to a temporary file and then run it. Or you could store the wat file next to the shell script that runs wasmtime. You will need to do that anyway if you want to compile the wat file to a wasm file when shipping the extension. (a wat file is several times bigger than the compiled wasm file) |
That doesn't work as described in this case #5614. I tried both .wat and .wasm.
|
Did you try something like #!/usr/bin/sh
cat >foo.wat <<__END__
(module
;; Import the required fd_write WASI function which will write the given io vectors to stdout
;; The function signature for fd_write is:
;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written
(import "wasi_unstable" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))
(memory 1)
(export "memory" (memory 0))
;; Write 'hello world\n' to memory at an offset of 8 bytes
;; Note the trailing newline which is required for the text to appear
(data (i32.const 8) "hello world\n")
(func $main (export "_start")
;; Creating a new io vector within linear memory
(i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string
(i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string
(call $fd_write
(i32.const 1) ;; file_descriptor - 1 for stdout
(i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0
(i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.
(i32.const 20) ;; nwritten - A place in memory to store the number of bytes written
)
drop ;; Discard the number of bytes written from the top of the stack
)
)
__END__
wasmtime run foo.wat |
Just tried. The Native Messaging host exits. |
This specific example doesn't read from stdin and exits as soon as it wrote |
I uploaded the WASm file to https://webassembly.github.io/wabt/demo/wasm2wat/ and substituted that for the wat in your example. I'm just trying to test WebAssembly version of a Native Messaging host. Thus I asked the WebAssembly experts how to do that after not being successful using |
@bjorn3 I know for a fact that both https://github.com/guest271314/native-messaging-c and https://github.com/guest271314/native-messaging-cpp work as expected. I compiled the C version to WASM using WASI SDK. I downloaded and installed |
It shouldn't be this complicated that we have to use a shell script to run .wasm and .wat. when we have At least provide users with the option to use the shebang line. I mean the line to install
Examples of using shebang for Python, Node.js, Deno, QuickJS, Bun Native Messaging hosts:
|
In Python
These have decided to extend javascript in a way incompatible with javascript engines not included in this list like browsers, which is not something wasmtime wants to do.
As per #3715 (comment) you should suggest adding it to the official wat specification, not as a wasmtime specific extension.
I don't think this issue is related at all to the shebang: If I try diff --git a/nm_c.c b/nm_c.c
index a1afda1..e328d20 100644
--- a/nm_c.c
+++ b/nm_c.c
@@ -26,7 +26,7 @@ uint8_t* getMessage(size_t *inputLength) {
// `message[0]`).
// `sizeof(*message)` will hence return the size in bytes of the type
// `message` points at, which means it's equivalent to `sizeof(uint_8)`.
- uint8_t *message = calloc(messageLength, sizeof(*message));
+ uint8_t *message = calloc(messageLength+1, sizeof(*message));
result = fread(message, sizeof(*message), messageLength, stdin);
// `inputLength` is a pointer, so we store the length at the memory address it
// points at. This way we return 2 values at once from a function! I suspect that applying this patch will fix the communication issue that lead to the native messaging host exiting. |
I can do this just fine with the C Native Messaging host
Thanks for the patch nonetheless. Kindly file a PR explaining why, what, how so we know exactly what is going on on the record of the repository. I am not a C or C++ expert. I am far more fluent in JavaScript. I had to get help to create the C and C++ versions.
I think we should be able to use
Unfortunately that didn't change anything relevant to the Native Messaging host. How is .wat relevant to the ability to call I'm just trying to test WebAssembly as a Native Messaging host using the officially endorsed runtime. If you try the above hosts they each echo back the input from the browser. I have no idea how to do that using WebAssembly or |
I applied the patch, recompiled the C source code to WASM and the host still exited - when using the |
@bjorn3 If/when you have the time and are so inclined perhaps try testing using |
|
I will try it. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Got https://github.com/guest271314/native-messaging-c on native working after I moved it out of the |
For me an #!/usr/bin/env bash
wasmtime run nm_c.wasm Make sure to make the shell script executable though. Otherwise chromium says "Native host has exited.". |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I locked this topic as all the discussion starting yesterday is off-topic. As laid out last year, the wasmtime project is dedicated to implementing standardized features, and will not accept non-standards, non-interoperable features. This isn't a matter of purity, but a matter of wanting to foster an ecosystem that's wider than this one project. I'd again encourage those who want this feature to propose it to the WebAssembly Community Group as the right forum for discussions about changes to the standards themselves. If and when such a proposal gains traction there, we'll happily implement it in wasmtime. (@bjorn3: thank you very much for your diligent work on trying to resolve users' problems—it's much appreciated! ❤️) |
Feature
Make wasmtime hip to a shebang at the first line of the file, e.g.:
#!/usr/local/bin/wasmtime
followed by the text-format wasm code as usual. Currently, the shell runs wasmtime and feeds it the script as expected, but wasmtime chokes on the first line and fails to run the following script.
Benefit
This would allow us to write scripts that can be executed by simply setting the executable bit and invoking them, like any other shell script. It's a matter of convenience. I have a lot of scripts in a lot of different languages; I don't have to remember what tool to use to run them because they all understand shebang — except for wasmtime.
Implementation
Just special-case it: if the first line of the script file starts with "#!", then ignore it and continue with the rest of the file.
Alternatives
I could write, for every wasm script I want to run, a little 2-line shell script that runs wasmtime with the path to the actual script. That would be annoying on so many levels.
The text was updated successfully, but these errors were encountered: