Slice 2 — Clock + Random providers#368
Merged
taybenlor merged 10 commits intoApr 29, 2026
Merged
Conversation
Providers can throw WASIXError(result) to return a specific errno; any other thrown value becomes EIO via the debug hook. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SystemClockProvider: Date.now() for REALTIME, performance.now() for MONOTONIC; CPU clocks fall back to monotonic. SystemRandomProvider: wraps crypto.getRandomValues in 64 KiB chunks. FixedClockProvider: frozen or tick-advancing deterministic clock. SeededRandomProvider: SFC32 PRNG, deterministic across all JS engines. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces ENOSYS stubs with real implementations. Reads provider from context; falls back to lazily-created SystemClockProvider / SystemRandomProvider when context slot is unset, matching preview1 default behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ight lib/main.ts exports SystemClockProvider, SystemRandomProvider, FixedClockProvider, SeededRandomProvider from package root. src/main.ts attaches them to window so Playwright specs can construct providers in page.evaluate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
wasix-clock-random: calls clock_time_get(MONOTONIC) twice with a 5M-iter spin between calls and asserts delta > 0; calls random_get(32) and asserts non-zero. Exits 1 / 2 on failure, 0 on success. wasix-deterministic: calls random_get(8) + clock_time_get(REALTIME) and hex-encodes the 16 bytes for fd_write; Playwright runs it twice with identical FixedClockProvider + SeededRandomProvider and asserts the golden hex output. Built fresh by `npm run build:tests` via wat2wasm; not committed. cargo-wasix is unavailable here — see PR deviation note.
Slice 2 introduces hand-rolled WAT smoke binaries (wasix-clock-random, wasix-deterministic). Chain wat2wasm onto the existing cargo step so both the Rust .wasi.wasm artefacts (used by the existing args/stdio/ wasix-smoke specs) and the new .wasm artefacts get built by a single `npm run build:tests` invocation. No swallow — if cargo is missing, build:tests fails loudly.
wasix-clock-random.spec.ts: tests both binaries across chromium/firefox/ webkit. Clock-random asserts exit 0; deterministic asserts stdout is byte-identical across two runs with FixedClockProvider + SeededRandomProvider. package.json build:tests extended with wat2wasm calls for the two new test binaries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both SystemClockProvider and FixedClockProvider were exhaustive at compile time over ClockId but returned undefined at runtime for unknown numeric ids — which the outer wasix_clock_time_get / wasix_clock_res_get handlers surfaced as EIO. The WASIX and preview1 specs say unknown clock ids should be EINVAL. Add a default arm throwing WASIXError(EINVAL) to each now() / resolution() switch (four switches total) so the error model matches the spec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`packages/wasi`'s `build:tests:wat` step (added in this slice) shells out to wat2wasm to compile the hand-written WAT smoke binaries. The Actions runner image doesn't ship wabt by default, so the step fails with `wat2wasm: command not found`. apt installs wabt from Ubuntu's official repos.
The previous determinism check only asserted run1 === run2 and non-empty stdout — silent algorithm drift that still produced matching output across two runs would pass. Per review, pin the exact byte sequence. The WAT now hex-encodes the 16 bytes (8 random + 8 clock) into 32 ASCII chars before fd_write, so the bytes survive TextDecoder intact. The spec asserts the literal golden: `b4b5424d031fbb710000000000000000` (SFC32 seed=42 first 8 bytes + FixedClock(0n,0n) REALTIME u64 LE). Verified against a node WASI shim using the in-tree provider algorithms; bytes match.
Owner
|
LGTM |
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
Wires sync clock + random providers into WASIX per
WASIX-PLAN.md:WASIXError(wasix-32v1.ts) — providers throw it; the syscall layer translates toResult.*. Anything else thrown becomesEIOvia the existingdebughook.SystemClockProvider(performance.now()forMONOTONIC,Date.now()for the rest),SystemRandomProvider(crypto.getRandomValues),FixedClockProvider(epochNs, tick)(per-call advance, default0n= frozen),SeededRandomProvider(seed)(SFC32 with 15 warm-up rounds — integer-only, engine-identical).wasix_32v1.clock_time_get,clock_res_get,random_getcall through to the provider; lazy-initialised system defaults when no provider is supplied. UnknownClockIdreturnsEINVAL, notEIO.ClockIdenum —REALTIME,MONOTONIC,PROCESS_CPUTIME,THREAD_CPUTIME.lib/main.tsand attached towindowfor Playwright.wasix-clock-random.watasserts MONOTONIC delta > 0 and non-zero random bytes;wasix-deterministic.wathex-encodes 8 SFC32(seed=42) bytes + 8 bytes fromFixedClock(0n,0n)to stdout. Spec asserts the literal goldenb4b5424d031fbb710000000000000000across two runs — pins the algorithm rather than just round-trip equality.apt-get install wabtsowat2wasmis available in the PR test workflow.Deviation note — hand-rolled WAT, not
cargo wasixSame substitution as Slice 1: cargo-wasix isn't installable in this repo's toolchain, so the smoke binaries are written in WAT and built via
wat2wasm. The slice spec called out thecargo wasixpath as a preference rather than a requirement.Test plan
wasix-clock-random.spec.ts(CI run at tip)args/stdio/wasix-smokespecstsc --noEmitcleanFollow-ups (already stacked on this branch)