Skip to content

Pr/wasm driver harness - #2222

Open
tokyovigilante wants to merge 4 commits into
nim-lang:masterfrom
tokyovigilante:pr/wasm-driver-harness
Open

Pr/wasm driver harness#2222
tokyovigilante wants to merge 4 commits into
nim-lang:masterfrom
tokyovigilante:pr/wasm-driver-harness

Conversation

@tokyovigilante

Copy link
Copy Markdown
Contributor

No description provided.

tokyovigilante and others added 4 commits July 29, 2026 23:19
`nimony w file.nim` runs the standard pipeline (nifler → nimsem → hexer →
dce, orchestrated by nifmake) to per-module Leng `.c.nif`, then one
whole-program `ithaqua` node emits the final `.wasm` — ithaqua (in the
sibling `nativenif` repository) is codegen and linker in one, so there is
no per-module backend step, no C compiler and no link stage. The target
is implied after CLI parsing (wasm32 / standalone / 32 bits) so the bare
command works, forwarded to nimsem on its command line. `-r` runs the
module under node through the standard host shim
(tests/ithaqua/run_wasm.js provides the fixed env import set).

The other backends are untouched: every new arm is gated on
`backendWasm`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- osalloc: a standalone heap for targets with no mmap — a zero-initialized
  fixed region with a page-aligned bump pointer (the allocator's chunk
  headers assume page-masked base addresses), growable on wasm32 through a
  `memory.grow` provider once the fixed region is exhausted.
- dyncalls: the freestanding arm must not reference libc loader symbols;
  the error path is compiled rather than assumed dead.
- memory: nimNoLibc arms for the mem* helpers.

These are the pieces the wasm backend's standalone target needs to make
`system.nim` and the core stdlib compile and run without a libc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`hastur wasmdiff` pushes every fixture in `tests/ithaqua/` through BOTH
pipelines — `nimony n` (arkham + nifasm, the oracle) and `nimony w`
(hexer → dce → ithaqua) — runs both artifacts (natively; under
`node run_wasm.js`) and requires byte-identical stdout and matching exit
codes. Per-leg nimcache isolation; fixtures cover strings, seqs, tables
and sets, sorting, math and float printing, parsing, base64/digests,
deques/heaps, exceptions, and heap growth.

The oracle cuts both ways: this differential setup has repeatedly found
native-backend bugs where the wasm output was correct —
`tests/ithaqua/nativebugs/` quarantines minimal repros with a README
ledger. Two closure fixtures stay out of the corpus until the
closure-side fixes land, because they currently crash the NATIVE leg
(see tests/ithaqua/README.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The optimizer gate existed because ithaqua derives sibling module
filenames from the MAIN input's extension, so the whole module set must
switch to `.oc.nif` together — which is exactly what happens once the
ithaqua node's inputs go through the optimized names (the per-module
`optimize` nodes were already emitted upstream of the wasm skip). With
ithaqua's initializer-type inference (the nativenif ithaqua branch),
`nimony w --opt:speed` runs Shoggoth end-to-end: the 19-fixture
differential corpus is byte-identical to the unoptimized leg. Optimized
wasm runs ~25-35% larger (inlining trades size for speed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant