Implement WASM export and standalone execution

Add `wafer build` to compile Forth source files to standalone .wasm modules,
and `wafer run` to execute them. The same .wasm file works with both the
wafer runtime (via wasmtime) and in browsers (via generated JS loader).

New CLI subcommands:
- `wafer build file.fth -o file.wasm` — compile to standalone WASM
- `wafer build file.fth -o file.wasm --js` — also generate JS/HTML loader
- `wafer build file.fth --entry WORD` — custom entry point
- `wafer run file.wasm` — execute pre-compiled module

Entry point resolution: --entry flag > MAIN word > recorded top-level execution.
Memory snapshot embedded as WASM data section preserves VARIABLE/CONSTANT state.
Metadata in custom "wafer" section enables the runner to provide host functions.

New modules: export.rs (orchestration), runner.rs (wasmtime host), js_loader.rs
(browser support). Refactored codegen.rs to share logic between consolidation
and export via compile_multi_word_module(). Added ir_bodies tracking for
VARIABLE, CONSTANT, CREATE, VALUE, DEFER, BUFFER:, MARKER, 2CONSTANT,
2VARIABLE, 2VALUE, FVARIABLE defining words.

Removed dead code: dot_func field, unused wafer-web stub crate, wasmtime-wasi
dependency from CLI, orphaned --consolidate/--output CLI flags.

425 tests pass (414 original + 11 new including 7 round-trip integration tests).
This commit is contained in:
2026-04-04 11:33:11 +02:00
parent 321903831d
commit 3a0f328f90
12 changed files with 1202 additions and 928 deletions
-5
View File
@@ -5,16 +5,11 @@ version.workspace = true
edition.workspace = true
license.workspace = true
[package.metadata.cargo-machete]
ignored = ["wasmtime", "wasmtime-wasi"]
[lints]
workspace = true
[dependencies]
wafer-core = { path = "../core", version = "0.1.0" }
wasmtime = { workspace = true }
wasmtime-wasi = { workspace = true }
anyhow = { workspace = true }
clap = { version = "4", features = ["derive"] }
rustyline = "15"