WebAssembly is a binary or textual pre-compiled format (binary = .wasm, textual = .wat) for portable compilation-target executable basing on varies source programming languages such as ECMA-script, RUST, C(++). A runtime maps the .wasm
binary code to the target machine code.
WASM has important benefits – base on the wasmer https://github.com/wasmerio/wasmer capabilities
- Secure by default. No file, network, or environment access, unless explicitly enabled.
- Supports WASI (WebAssembly system interface) and Emscripten (compiler toolchain based on LLVM) out of the box.
- Fast. Run WebAssembly at near-native speeds, with > factor 100 faster bootup time as a Docker container
- Embeddable in multiple programming languages
- Compliant with latest WebAssembly Proposals (SIMD, Reference Types, Threads, …)
The WASM pre-compilation uses two different approaches
- ahead-of-time (AOT), which translates the given WASM-bytecode into the target machine code before execution.
- juts-in-time (JIT), which dynamically interprets the given WASM-bytecode while execution.
Let us start with a small C-program hello.c
which we compile to WASM-bytecode.
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
For the compilation we use the tool emscripten (EMCC) https://github.com/emscripten-core/emscripten
emcc -g -Oz --llvm-lto 1 -s STANDALONE_WASM -s INITIAL_MEMORY=32MB -s MAXIMUM_MEMORY=4GB -mmutable-globals -mnontrapping-fptoint -msign-ext hello.c -o hello.wasm
The resulting WASM (file hello.wasm) can be executed by e.g. the runtime wasmedge https://wasmedge.org/
Notes: There are many discussion about performance ongoing. We use wasmedge (also called SSVM). Check the performance review: https://www.secondstate.io/articles/ssvm-performance/ . My perception better fit to: https://00f.net/2021/02/22/webassembly-runtimes-benchmarks/ outcomes.
wasmedge hello.wasm
More or the same can be achieved with a RUST program hello.rs
.
use std::env;
fn main() {
println!("Hello World\n");
}
The RUST program can be compiled to a WASM as follows.
Create the RUST package manager config file Cargo.toml
[package]
name = "hello"
version = "0.1.0"
authors = ["ubuntu"]
edition = "2022"
[[bin]]
name = "hello"
path = "hello.rs"
[dependencies]
Do the compilation:
cargo build --target wasm32-wasi
The compiled WASM-bytecode hello.wasm
can be shipped and managed via Linux container runtime e.g., the low-level OCI-compliant runtime crun https://github.com/containers/crun, which has given integration with e.g., wasmedge. On Ubuntu-Linux the support must be explicitelly activated. Due to that you might has to deinstall crun and re-install it.
Note: SSVM (wasmedge) is still a young project. The wasmer project is still the fastest one https://wasmer.io/
sudo apt-get remove crun
sudo apt-get install -y make git gcc build-essential pkgconf libtool \
libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
libgcrypt20-dev go-md2man autoconf python3 automake
git clone https://github.com/containers/crun
cd crun
./autogen.sh
./configure --with-wasmedge
make
sudo make install
Note: crun is the default OCI runtime e.g., for Podman.
Let us start with the Dockerfile
FROM scratch
COPY hello.wasm /
CMD ["/hello.wasm"]
Now use the builduh https://github.com/containers/buildah tooling for OCI container.
sudo buildah build --annotation "module.wasm.image/variant=compat" -t mywasm-image .
The output looks something like that:
STEP 1/3: FROM scratch
STEP 2/3: COPY hello.wasm /
STEP 3/3: CMD ["/hello.wasm"]
COMMIT mywasm-image
Getting image source signatures
Copying blob 4a84eb4c3649 skipped: already exists
Copying config ddc9d831fc done
Writing manifest to image destination
Storing signatures
--> ddc9d831fcd
Successfully tagged localhost/mywasm-image:latest
ddc9d831fcdc554b5bd7010c6184ffbcdb87f911f6522945fb8fed2f8db42dcc
Now we can run our Linux container:
sudo podman run mywasm-image:latest
The output looks like the following:
Hello World
Done. Now we have WASM manageable via Linux container tools.
Our setup looks something like the following illustration:

Interesting developments
- Second State, the developer behind wasmedge, joined the Autoware Foundation https://www.secondstate.io/articles/second-state-joins-the-autoware-foundation/
- Vector is looking at WASM https://jobs.vector.com/de/job/ARDE-3250
- Determinism resources & compiler bug analysis
- https://www.slideshare.net/FluenceLabs/fast-deterministic-and-verifiable-computations-with-webassembly-wasm-on-the-blockchain-meetup-august-19-berlin
- https://ieeexplore.ieee.org/document/9678776
- https://i.blackhat.com/USA-22/Wednesday/US-22-Ventuzelo-A-Journey-Into-Fuzzing-WebAssembly-Virtual-Machines.pdf
- How to reach (better) determinism
- Threads are disabled.
- SIMD instructions are disabled. In the future we may enable deterministic parts of SIMD.
- Floating-point NaN values are canonicalized.
- Only use non-blocking I/O
- Only use AOT compiler