diff --git a/README.md b/README.md index cede7e5..00167ce 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,22 @@ defer inst.Close(ctx) _, err = inst.Call(ctx, "wasi:cli/run@0.2.3#run") ``` -Call an interface export directly with `inst.CallExport("component:adder/calc", "add", uint32(2), uint32(3))`, or serve a `wasi:http/incoming-handler` component straight to `net/http` — `*component.Instance` satisfies `http.Handler`. The API is young and, like the rest of wazy, makes no stability promise. [WASI 0.3][wasi] and async are the next target. +Call an interface export directly with `inst.CallExport("component:adder/calc", "add", uint32(2), uint32(3))`, or serve a `wasi:http/incoming-handler` component straight to `net/http` — `*component.Instance` satisfies `http.Handler`. The API is young and, like the rest of wazy, makes no stability promise. + +## Async — the Component Model async ABI (WASI 0.3) + +wazy runs the Component Model's async ABI: components that suspend, await, and resume — the model [WASI 0.3][wasi] is built on. Upstream [wazero][wazero] has none of it, and no other pure-Go runtime does either. + +- **Callback and stackful lift** — both async lift shapes. A guest task that returns WAIT/YIELD is driven by a deterministic per-composition scheduler; a stackful task suspends on a goroutine with an unbuffered-channel baton, so exactly one runs at a time — race-free by construction, verified under `-race`. +- **Streams and futures** — `stream`/`future` with rendezvous copy and per-element `own` resource transfer, synchronous and asynchronous read/write, and cancellation. +- **Task lifecycle** — subtasks, cancellation, backpressure, context-local storage, and borrow scopes that hold across async calls. +- **`thread.*`** — a cooperative fiber runtime (`thread.new-indirect`, `yield`, `suspend`, `yield-then-resume`) built on the same goroutine-plus-baton primitive. + +It passes **all 31 official Component Model async `.wast` conformance suites** (one carries a fixture fix filed upstream as [component-model#679][pr679]), cross-checked by a differential trace-oracle that byte-compares wazy against the spec reference (`definitions.py`). Goroutines and channels back futures, streams, and threads naturally — the one place Go's substrate is an asset over the hand-written event loops other runtimes need. ## Moving fast -wazy is an actively developed performance fork, built for the modern Wasm platform upstream does not target — the Component Model and WASI 0.2 today (above), WASI 0.3 and async next. +wazy is an actively developed performance fork, built for the modern Wasm platform upstream does not target — the Component Model, WASI 0.2, and the async ABI today (above), with the full WASI 0.3 host-interface surface next. That choice has a cost. wazy makes no API-stability promise. It has already broken compatibility with wazero, including host-function registration, and will do so again when that makes the runtime faster or moves it toward the Component Model. @@ -98,3 +109,4 @@ Apache 2.0. See [LICENSE](LICENSE). [wazero]: https://github.com/tetratelabs/wazero [cm]: https://component-model.bytecodealliance.org/ [wasi]: https://wasi.dev/ +[pr679]: https://github.com/WebAssembly/component-model/pull/679 diff --git a/TODOS.md b/TODOS.md index 69ecd94..dee852d 100644 --- a/TODOS.md +++ b/TODOS.md @@ -1,10 +1,9 @@ # TODOS -## WASI 0.3 / async component-model follow-on -- **What:** Add the native async ABI on top of the real WASI 0.2 Component Model runtime: `future`/`stream`, task/subtask lifecycle, a host event loop, and reworked async interfaces (`wasi:io` is deleted in 0.3, folded into the Canonical ABI). -- **Why:** Would make wazy the only pure-Go runtime that can run async 0.3 components. Go's goroutines+channels back futures/streams more naturally than Wasmtime's Rust event loop — the one place wazy's substrate is an asset. -- **Context:** ~8–10k LOC on top of the p2 runtime. Reference: Wasmtime + `bytecodealliance/wasip3-prototyping`, and the async section of the component-model `definitions.py`. Zero pure-Go prior art. Highest-variance part is async correctness debugging. -- **Depends on / blocked by:** p2 CM runtime shipped and solid (done). Also blocked on the 0.3 spec settling — as of 2026-07 Wasmtime still marks its p3 support experimental/unstable. Do NOT start early; spec churn will waste the work. +## Component Model async ABI — DONE +- **DONE (the async ABI on top of the WASI 0.2 CM runtime):** callback and stackful lift, `future`/`stream` (rendezvous copy, per-element `own` transfer, sync + async read/write, cancellation), task/subtask lifecycle (cancellation, backpressure, context storage, borrow scopes), a deterministic per-composition scheduler, and a `thread.*` cooperative fiber runtime (`new-indirect`/`yield`/`suspend`/`yield-then-resume`). Goroutines + an unbuffered-channel baton give exactly-one-runnable semantics (race-free, verified under `-race`) — the substrate advantage the plan predicted. +- **Conformance:** all 31 official Component Model async `.wast` suites pass (0 skip, 0 fail), cross-checked by a differential trace-oracle vs the spec reference (`definitions.py`). One suite (`sync-streams`) carries a fixture fix filed upstream as WebAssembly/component-model#679 — the runtime itself needed no change. Design docs: `docs/component-model-async-*.md`. +- **Follow-on still open:** the full WASI 0.3 host-interface surface (the reworked `wasi:io`/`wasi:sockets`/`wasi:http` 0.3 worlds folded into the async ABI) once the 0.3 spec settles — Wasmtime still marks its p3 support experimental as of 2026-07. The async ABI substrate is ready for it. ## Internal nested-component composition — func linking + cross-component resources DONE - **DONE (func linking, commit cd793ee):** A component binary that declares diff --git a/llms.txt b/llms.txt index 06f320d..00c810a 100644 --- a/llms.txt +++ b/llms.txt @@ -1,8 +1,8 @@ # wazy -> A fast, pure-Go WebAssembly runtime: zero dependencies, no CGO. Embeds Wasm compiled from Rust, C/C++, TinyGo, Zig, and more, and runs it with an optimizing amd64/arm64 compiler or a portable interpreter. Derived from wazero; focused on performance and WASI/WebAssembly standards conformance. +> A fast, pure-Go WebAssembly runtime: zero dependencies, no CGO. Embeds Wasm compiled from Rust, C/C++, TinyGo, Zig, and more, and runs it with an optimizing amd64/arm64 compiler or a portable interpreter. Derived from wazero; focused on performance and standards conformance. Beyond core Wasm it runs the WebAssembly Component Model, WASI 0.2, and the Component Model async ABI (the WASI 0.3 model — streams, futures, tasks, threads) — none of which upstream wazero targets. -wazy is a Go library: `go get github.com/samyfodil/wazy`. The public API lives in the root package, with `api/` for shared types and `experimental/` for unstable features. WASI preview1 is provided by `imports/wasi_snapshot_preview1`. +wazy is a Go library: `go get github.com/samyfodil/wazy`. The public API lives in the root package, with `api/` for shared types and `experimental/` for unstable features. WASI preview1 is provided by `imports/wasi_snapshot_preview1`; the Component Model, WASI 0.2 host interfaces, and the async ABI live in the `component` package. The async runtime passes all 31 official Component Model async `.wast` conformance suites. ## Documentation @@ -19,6 +19,7 @@ wazy is a Go library: `go get github.com/samyfodil/wazy`. The public API lives i - [Optimizing compiler](internal/engine/native): amd64/arm64 JIT backend. - [Interpreter](internal/engine/interpreter): portable fallback engine. - [WASI preview1](imports/wasi_snapshot_preview1): WASI host module. +- [Component Model + WASI 0.2 + async](component): Component Model runtime (Canonical ABI, resources, multi-module graphs), WASI 0.2 host interfaces, and the async ABI (streams, futures, tasks, `thread.*`). - [CLI](cmd/wazy): command-line runner. ## Optional