You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(wasm): byte-level load/store IR + env_at/arg_at (ADR-015 S5) (#339)
## Summary
Unblocks INT-03 S5 (#180) by extending the wasm IR with the full
WebAssembly 1.0 §5.4.6 byte-level load/store family (opcodes
`0x2C..0x35`, `0x3A..0x3E`) and shipping the `env_at(i)` / `arg_at(i)`
string accessors that were waiting on them.
- **IR + encoder** (`lib/wasm.ml` + `lib/wasm_encode.ml`) — 14 new
`instr` constructors (`I32Load8{S,U}`, `I32Load16{S,U}`,
`I64Load8{S,U}`, `I64Load16{S,U}`, `I64Load32{S,U}`, `I32Store8`,
`I32Store16`, `I64Store{8,16,32}`). Encoder pattern mirrors the existing
full-width family one-for-one.
- **`env_at` / `arg_at` lowering** (`lib/typecheck.ml` +
`lib/codegen.ml` + `lib/wasi_runtime.ml`) — bind `Int -> String / { Time
}`; lower via on-demand `wasi_snapshot_preview1.{environ,args}_get`
imports paired with the existing `*_sizes_get` import. The codegen
helper emits a 7-phase sequence: `sizes_get` → alloc ptrvec+bytebuf →
`*_get` → resolve `ptrvec[n]` → null-terminator scan (`I32Load8U`) →
alloc length-prefixed AS string → byte-copy (`I32Load8U` / `I32Store8`).
- **Import-table dedup** (`lib/codegen.ml`) — `env_count` and `env_at`
both require `environ_sizes_get` (ditto `arg_count`/`arg_at`). The
`optional_wasi` table now lists every `(builtin, wasi_import)` pair and
the assembly pass dedupes by WASI import name (first occurrence wins),
preserving the canonical-order indexing the existing combo regression
hardened.
- Docs updated in `docs/ECOSYSTEM.adoc` and `docs/TECH-DEBT.adoc`; stale
"tracked follow-up" comments in codegen/typecheck/wasi_runtime cleared.
## Test plan
- [ ] CI `dune build` + `dune runtest` (the only build environment
available — see note below)
- [ ] `./tools/run_codegen_wasm_tests.sh` picks up the three new
fixtures automatically:
- `tests/codegen/env_at.affine` + `test_env_at.mjs` — smoke for
`string_length(env_at(0))`; verifies `environ_sizes_get` + `environ_get`
both fire and the byte-scan terminates at the right offset.
- `tests/codegen/arg_at.affine` + `test_arg_at.mjs` — same shape over
`args_get`, indexed at **1** to exercise the `n*4` ptrvec offset (not
just `index = 0` short-circuit).
- `tests/codegen/env_count_and_at.affine` + `test_env_count_and_at.mjs`
— dedup regression: instantiation fails fast if `environ_sizes_get` is
double-imported.
## Caveat — local verification
The session container's network policy blocks `opam.ocaml.org`
(`host_not_allowed`), so `opam install . --deps-only` fails and `dune
build` cannot run locally. The five modified `.ml` files were
syntax-checked with `ocamlc -stop-after parsing` (all OK) and the code
mirrors existing patterns exactly, but the type-checker hasn't been run
end-to-end against this branch. CI is the first real validation —
autofix-on-failure is wired up to follow.
https://claude.ai/code/session_01FoWm87AnVtLS5euDEAGu2A
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FoWm87AnVtLS5euDEAGu2A)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments