WASI-0.3.0-official inventory sweep: docs truth-sweep + system-clock host support#149
Merged
Merged
Conversation
Inventory sweep against the officially released WASI 0.3.0 spec
(2026-06-11, ~/Documents/OSS/WASI) + refreshed reference clones:
- zwasm --help: engine default is auto (was claiming interp);
list --cache/--cache-clear (shipped 2.2.0)
- main.zig doc: .cwasm v0.1/ADR-0039 -> v0.5/ADR-0203; engine default
- canon.zig: drop the stale "utf16/latin1 pending" claims (D-502
implemented them at the canon layer)
- spec_assert_runner_wasm_3_0: docstring said SKELETON; it JIT-executes
with real pass/fail accounting since Phase 10
- gc/register.zig: GC shipped; note the unwired enable_gc gate (D-525)
- README: WASI 0.3 row (core, opt-in -Dwasi=p3, official-0.3.0 deltas
pending); complete the 9-proposal list (custom annotations)
- migration guide: GC is on by default (-Dgc is inert, not "opt-in");
WASI 0.3.0 released (drop "until it settles")
- CHANGELOG: Unreleased entries + 9-proposal list completion
- reference_clones.md: add WASI monorepo / component-model /
wasi-testsuite / wasmtime-py rows; wasi-* per-interface repos archived
upstream 2025-11-25; version-pin section rewritten for the wg-3.0 /
spec_pin.yaml reality; fix the ClojureWasm path
- proposal_watch.md: 2026-07-17 review entry (official-0.3.0 WIT diff:
system-clock rename, instant{s64,u32}, monotonic wait-until/wait-for
async funcs, wasi:io deletion; wasip3 fixtures actually import 0.2.6);
WASI roadmap table de-staled (0.2 row said ACTIVE, 0.3 row claimed a
stack-switching gate contradicting the header callout)
- debt.yaml: D-523 (fixture regen vs official 0.3.0 toolchain),
D-524 (official-0.3.0 host-surface residual), D-525 (-Dgc inert)
…esolution
WASI 0.3.0 (released 2026-06-11) renamed wasi:clocks/wall-clock to
system-clock with instant{seconds: s64, nanoseconds: u32} and added
get-resolution to both clocks. Serve the sync half on the component host:
- adapter: P2Op clocks_system_now / clocks_system_get_resolution /
clocks_monotonic_get_resolution + table rows (version-stripped names
are 0.3.0-unique, no 0.2 collision) + P1Target.clock_res_get
- clocks.zig: clockTimeNsSigned (i96; pre-1970 instants representable)
+ clockResNs, with clockTimeNs/clockResGet refactored on top
(behavior-preserving)
- trampolines: p2SystemNow writes the floored instant split
(instantFromNs: {-1s, 999999999ns} = 1ns before epoch, per the WIT
example; unit-tested), get-resolution returns duration(u64) directly
- fixture test/component/wasi_p3_systemclock.{wat,wasm}: asserts real
values (seconds past 2017, 0 < resolution <= 1s) via exit code, plus
adapter classify/p1Target unit tests
The async monotonic wait-until/wait-for need a scheduler-wired timer
waitable — tracked as D-524. DA-critique 19/20 -> signed-instant fix
applied (check #12).
…tures (D-523 refined) rust-overlay input updated (2026-07-17). Nightlies 2026-07-08/-16 cannot -Z build-std wasm32-wasip3 (upstream std/sys/env/wasi.rs OsStringExt regression) — 2026-06-24 is the newest-known-good and compiles std's wasip3 0.6.0+wasi-0.3.0-rc crate; recipe re-verified, test-wasi-p3 green. Measured refutation recorded in D-523: the regenerated fixtures STILL import wasi 0.2.6 — the imports come from the borrowed wasip2 wasi-libc (sync-main stdio/env/clock route through -lc), not the nightly's std bindings, so a nightly bump alone cannot discharge the official-WIT fixture gap. Discharge now = wasip3-native wasi-libc upstream OR the wit-bindgen fixture path.
Bundled into the sweep PR per user grant (single CI run). Tag v2.3.0 is cut after merge (user-granted in-session per ADR-0156); the Homebrew formula in clojurewasm/homebrew-tap points at the v2.3.0 release assets.
Contributor
Author
|
Scope extended per user grant (bundle everything into one CI run):
|
chaploud
added a commit
that referenced
this pull request
Jul 17, 2026
…lds DCE feature.gc (#150) `check_build_dce` FAILed on `main` (all six `-Dwasm=v1_0` / `-Dwasm=v2_0` rows): `instruction.wasm_3_0.ref_test_ops.gcRefMatchesNonNullCore` was present in every non-GC binary. Root cause: ADR-0203 D1 (D-516 position-independence) holds the GC / subtyping JIT helpers as `JitRuntime` fn-pointer FIELDS whose DEFAULT is the real helper (so a reloaded `.cwasm` resolves the address in the running process — no setup wiring). A field default `= jitGcRefTest` takes the helper's ADDRESS unconditionally, and `JitRuntime` is instantiated in every build, so the whole GC cohort (`jitGcAlloc` / `jitGcArray*` / `jitGcRefTest` / `jitGcRefCast` / `jitCallIndirectResolve`) — and its `feature/gc/*` reach — stayed live even in a v1_0 build. Only the one symbol whose namespace path contains `wasm_3_0` tripped the `nm`-grep gate, but the entire cohort leaked. The emit sites read the helper via `@offsetOf` (an offset, not an address) and are comptime-fenced behind the wasm_3_0 op dispatch, so they DCE fine — the struct field default is the only always-live address-take. Fix: guard each helper body with `if (comptime !wasm_v3_plus) @Panic(...)` as the first statement. In a sub-v3 build the comptime-false remainder is un-analysed, so the default points at a bare `@panic` stub with no GC references and the GC code DCEs. v3 builds are unaffected (guard is `if (comptime false)` → real body runs; ADR-0203 D1 intact). A sub-v3 build can never emit a GC / subtyping op (the validator rejects them), so the stub is unreachable — `@panic` is the correct default (mirrors `defaultReifyExnref`). Verified: v1_0 + v2_0 forbidden-symbol scan CLEAN on both arm64-native and x86_64-linux cross (the CI leg's arch); v1_0:p1 `.text` also drops 2957749 → 2614800 B as the leaked GC code is reclaimed. `zig build test` + lint green. The regression shipped 2026-07-09 (ADR-0203) but surfaced only now: `check_build_dce` runs in the push-to-main extended leg and the intervening main pushes were doc-only (heavy legs skipped) or concurrency-cancelled, so the gate never completed until #149. Lesson: 2026-07-18-fnptr-field-default-defeats-build-option-dce.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WASI 0.3.0 was officially released 2026-06-11 (release, Bytecode Alliance announcement). This PR is the inventory sweep of zwasm's Wasm 3.0 / WASI 0.3 completeness claims against that now-official spec (reference clones pulled to current upstream), in three commits:
1. Docs/meta truth-sweep (
695f8bd03)Claim-vs-reality fixes found by the inventory:
zwasm --helpclaimedinterp (default)— the real default isauto(JIT + interp fallback); also--cache/--cache-clearwere missing from the usage textcanon.zigstill said "utf16/latin1 pending" (D-502 implemented them); the 3.0 spec runner docstring still said "SKELETON" (it JIT-executes with real accounting)-Dgc, default off)" — measured reality:-Dgcis inert (its only reader is an unconsumed re-export); GC ships with the default-Dwasm=v3_0and its strip lever is the wasm-level DCE → new debt D-525 (wire per ADR-0115 §3 or retire)-Dwasi=p3) and the complete 9-proposal list (custom annotations was missing)reference_clones.md: WASI monorepo (spec v0.3.0 + living WIT) / component-model / wasi-testsuite rows; the per-interfacewasi-*repos were archived upstream 2025-11-25; version-pin section rewritten for the wg-3.0 /spec_pin.yamlrealityproposal_watch.md: 2026-07-17 review entry recording the official-0.3.0 WIT diff; the WASI roadmap table no longer claims a stack-switching gate (contradicted its own header callout)wait-until/wait-for, version-gating note)2. Official 0.3.0 clocks host surface (
c4848d44b)0.3.0 renamed
wasi:clocks/wall-clock→system-clockwithinstant{seconds: s64, nanoseconds: u32}and addedget-resolutionto both clocks. This ships the sync half:P2Op/P1Targetextensions (0.3.0 names are collision-free with 0.2 under version-stripped matching)clockTimeNsSigned(i96 — pre-1970 instants representable, floored{-1s, 999999999ns}split per the WIT example, unit-tested) +clockResNs, with the existing P1 paths refactored on top (behavior-preserving)wasi_p3_systemclock.{wat,wasm}asserting real values (seconds past 2017, 0 < resolution ≤ 1s) via exit code; verified e2e through the CLI (exit 0)DA-critique check #12: 19/20 → the signed-instant finding fixed in the same commit.
3. Handover refresh (
79bff0e26,3dd212153)Test plan
zig build testgreen locally (aarch64-macos)zwasm run(exit 0)gate_commit.shgreen on all commitsci-required3-OS gateBench record skipped per the per-merge policy (no engine/interp/JIT hot-path change).