Closed bakkot closed 5 months ago
Thanks for the report, and I'd love to see this! I've never been certain enough of what I'd want this to look like to implement it but I think it'd be great to have!
For some of the technical bits it should be ok to actually skip wasi support and use the wasm32-unknown-unknown
target since most of the libraries don't need the filesystem or env vars or things like that. If you're ok with it I think it would be best to architect this as something which lives in-tree and is deployed to github pages on all merges to main
. I'm happy to help with the CI bits here too.
As for the actual integration with the web, I might recommend one of two approaches:
jco
would enable "componentizing" everything to be easily used from JS. A bit of a self-dogfood if you will.wasm-bindgen
would be a bit more old-school but should work well for this purpose.Whichever you find easiest I think would be a great place to start. If you need any help please just let me know!
Dogfooding sounds fun, but I'd probably need more help with it. I expect I could whip something up with wasm-bindgen
largely on my own.
For the dogfooding option, what would the process actually look like, concretely? It looks like wit-component
isn't meant to be used directly, in preference for cargo component
, so would the idea be to do cargo install cargo-component
in CI, and then cargo component build --target wasm32-unknown-unknown
followed by jco transpile
?
Starting with wasm-bindgen
sounds reasonable to me. My thinking is that a jco based experience would be as you mention, but that's mostly just to lean into components I don't think it is substantially different than wasm-bindgen at this time otherwise.
The cargo-component
approach was actually fairly straightforward,
Unfortunately the wasm32-unknown-unknown
target immediately panics (i.e., hits an unreachable
wasm instruction) if I try to wat::parse_str
anything nontrivial.
Building for wasm32-wasi
works, and from checking the output, it seems to be pulling in environ_get
, environ_sizes_get
, fd_write
, proc_exit
, and random_get
. Of those, it only actually calls random_get
, which I'm guessing is where the pani comes from.
I see that wasmparser
has a feature to disable hash maps, but I don't know why wasmparser
would be involved here. In any case, adding wasmparser = { path = "../../crates/wasmparser", features = ["no-hash-maps"] }
did not change anything. Maybe there's a different thing I need to do to disable it?
It's true yeah with wasm32-unknown-unknown
debugging isn't fun, and you'd probably need something like console_error_panic_hook
to help debug the unreachable
(which is probably a rust panic).
Stubbing a small set of wasm32-wasi
functions like that shouldn't be too hard though, things like environ_*
could be noops returning zero-size things.
In theory you shouldn't need to frob hash maps at all, randomness is used by default on wasi but it won't panic on wasm32-unknown-unknown
.
I have occasionally wanted to use these tools on the web. I've used wat2wasm and the other playgrounds from wabt a lot, and the lack of a similar easy way of using wasm-tools keeps tripping me up.
Would you accept a PR which adds a GitHub action which uses the
wasm32-wasi
artifact from a release and wraps it up with a browser-based wasi implementation to live on GitHub Pages? I'm imagining something very simple, just a text box / file upload for input and a text box / download button for output plus a place to enter the command and see stdout/stderr.