Emit Wasm
The --emit wasm flag tells the compiler to produce a .wasm module instead of
a native binary. In the default mode (VM-embedded) the result is a single
file that bundles the Zolo VM together with your bytecode; I/O capabilities are
provided by the host-shim ABI — imported functions that the WASI runtime or
JS loader inject at instantiation time.
The basic command:
zolo build 32-webassembly/01-emit-wasm.zolo --emit wasm
# -> target/01-emit-wasm-0.0.0.wasm
The simplest possible wasm program is a fn main() that calls print:
Minimal VM-embedded module; print is the only wasm-safe I/O today.
// Feature: WebAssembly output — `zolo build --emit wasm`
// Syntax: `zolo build file.zolo --emit wasm`
// When to use: run Zolo inside a WASM host (WASI runtime, or a browser
// via the generated JS glue).
// Run:
// zolo build 32-webassembly/01-emit-wasm.zolo --emit wasm
// # -> Built target/01-emit-wasm-0.0.0.wasm (...)
//
// By default this emits a VM-embedded module under the host-shim ABI:
// the Zolo VM + your bytecode are packaged into one `.wasm`, and host
// capabilities (I/O, etc.) are provided through imported shim functions.
// Default host profile is `wasi` (see 02 for `--host browser` / `--aot`).
//
// AOT (pure-wasm, no embedded VM) now executes this program end-to-end:
// zolo build 32-webassembly/01-emit-wasm.zolo --emit wasm --aot --host browser -o target/aot/01.wasm
// node crates/zolo-wasm-aot/tests/run_wasm.mjs target/aot/01.wasm
// # -> Hello from WebAssembly!
fn main() {
print("Hello from WebAssembly!")
}
// Heads-up (wasm-safe surface, current state): only `std::os` is
// wasm-safe today. crypto / log / datetime / fs / io still panic when
// called inside wasm, and `process.open()` panics at boot via
// `Instant::now()`. Keep wasm programs to plain compute + `print` for now.
//
// expected (run natively): Hello from WebAssembly!
Requires the Zolo CLI/host — open in the playground or run locally.
Current wasm-safe surface: only std::os works inside a wasm module. The
crypto, log, datetime, fs, and io modules still panic when called, and
process.open() panics at startup because it depends on Instant::now(). For
now, keep wasm programs restricted to pure computation and print.
AOT mode also runs this program from start to finish:
zolo build 32-webassembly/01-emit-wasm.zolo --emit wasm --aot --host browser \
-o target/aot/01.wasm
node crates/zolo-wasm-aot/tests/run_wasm.mjs target/aot/01.wasm
# -> Hello from WebAssembly!
Challenge
Add a second print call with the result of a simple arithmetic operation
(e.g., 2 + 2) and recompile with --emit wasm. Confirm that the generated
.wasm runs both lines in order.
See also