π Learning and exploring WebAssembly (Wasm).
I'm learning about WebAssembly. In part, by reading the book The Art of WebAssembly.
This project is laid out in the following file and directory structure:
add.wat
- A WAT (WebAssembly Text Format) program that adds two integers.
add-wat.js
- This is a "runner" program. It's a JavaScript/Node program that invokes the WAT-based Wasm module to add two integers. The Node runtime is used as an "embedding environment" for the Wasm module.
add-rust/
- A Rust (Cargo) project that produces a Wasm module that adds two integers.
add-rust.js
- This is a "runner" program for the Rust-based Wasm module.
Follow these instructions to compile and run the WAT-based Wasm program:
- Install WABT
- WABT (pronounced "wabbit") is the The WebAssembly Binary Toolkit. Find it on GitHub: https://github.com/webassembly/wabt.
- Below are the commands I used to install WABT. Choose a directory of your choice. I chose
/Users/davidgroomes/repos/opensource/wabt
. -
git clone --recurse-submodules https://github.com/WebAssembly/wabt
-
cd wabt/
-
mkdir build cd build cmake .. cmake --build .
- Make sure to add the build directory to the
PATH
. Something like:export PATH="$PATH:/Users/davidgroomes/repos/opensource/wabt/build"
- Install Node
- Use
nvm
. We need Node as an "embedding environment" to run a Wasm module.
- Use
- Compile the WAT source code
-
wat2wasm add.wat
-
- Run the program
-
node add-wat.js 1 2
- Success! You executed a Wasm module via Node!
-
Now, let's try a Rust-based Wasm module. Follow these instructions to compile and run the Rust-based Wasm module:
- Install the
wasm-bind-gen
CLI:-
cargo install -f wasm-bindgen-cli
-
- Compile the Rust code to a Wasm module:
-
cargo build --manifest-path=rust-add/Cargo.toml --target=wasm32-unknown-unknown
-
- Generate the Rust bindings for the Wasm module
-
wasm-bindgen --out-dir rust-add/pkg rust-add/target/wasm32-unknown-unknown/debug/rust_add.wasm
-
- Run the program:
-
node --experimental-wasm-modules --no-warnings add-rust.mjs 1 2
-
General clean ups, TODOs and things I wish to implement for this project:
- DONE Write some basic WAT code
- Write more WAT code
- DONE Run a WAT program from a NodeJS embedding environment
- Run a WAT program using wasm3 (a Wasm interpreter)
- DONE Compile a "hello world" Rust program to Wasm (UPDATE 2022-06-27: I don't want all this web stuff. I don't
want the final artifact to be a web page, I want to be able to run it in a NodeJS embedding environment.)
How to build a package? I think
wasm-pack build --target bundler
. UPDATE 2: Can I compile the Rust code usingcargo
directly, and use--target=wasm/32/unknown/unknown
like this https://stackoverflow.com/a/71673305/? UPDATE 3: Yes, Cargo +wasm-bind-gen
is all I need. Works great (for this toy program at least). - Compile a "hello world" Kotlin program to Wasm (This isn't possible right now. Kotlin needs to finalize and release their Wasm stuff. I think it's in flux.)
- Compile a "hello world" Go program to Wasm
- Use ES modules for
add-wat.js
. I want to avoid CommonJS as much as feasible. - Consider splitting into a
wat/
subproject and arust/
subproject.
- Book: The Art of WebAssembly
- MDN: Converting WebAssembly text format to wasm
- MDN: Compiling from Rust to WebAssembly
- Online book: Rust and WebAssembly
- GitHub repo:
wasm-bindgen
Facilitating high-level interactions between Wasm modules and JavaScript
- Node.js docs: Wasm modules
- This describes the
--experimental-wasm-modules
flag.
- This describes the