Skip to content

codegen: emit typedwasm.access-sites carrier (typed-wasm ADR-0003) #251

@hyperpolymath

Description

@hyperpolymath

Context

typed-wasm proposals 0001 + 0002 reached `[accepted]` 2026-05-30 and were
promoted to typed-wasm ADR-0002 (multi-producer carrier sections) +
ADR-0003 (`typedwasm.access-sites` access-site carrier).

The access-site carrier maps each typed memory load/store instruction's
`(function_index, instruction_byte_offset)` to the resolved
`(region_id, field_id)` it intended. Without it the verifier can
re-derive regions/fields exist (via `typedwasm.regions`) but cannot
re-check that any given `i32.load offset=N` was supposed to target a
specific declared field.

`ephapax-wasm` already emits `typedwasm.ownership` (lib.rs ~line 1277;
custom-section assembly ~line 4577). The access-sites carrier is the
producer-side counterpart to typed-wasm PR #109's
`verify_access_sites_from_module` pass.

The AffineScript counterpart is tracked at affinescript#462. Filing
this issue per typed-wasm proposal 0001 Appendix B
"Producer-readiness checklist" — both shipping producers need
access-sites emission for v1 stabilisation.

(This issue was originally classifier-blocked in an earlier session;
owner directed filing now.)

What needs to land

Encoder (~25 LOC)

A new helper in the same module that hosts the `typedwasm.ownership`
encoder (currently inline in `src/ephapax-wasm/src/lib.rs` around line
1277). Wire format per typed-wasm proposal 0002 §"Wire format":

```
u16le version (= ACCESS_SITES_VERSION = 1)
u32le entry_count
for each entry (strictly ordered by (func_idx, byte_offset)):
u32le func_idx
u32le instruction_byte_offset
u32le region_id
u32le field_id
```

Encoding option B (LEB128 per field) per typed-wasm proposal 0002
§"Wire format" measurement (~5B/access, ~1.1% module overhead).

Custom-section assembly (~5 LOC)

Add the new section to the custom-sections list at
`src/ephapax-wasm/src/lib.rs` line ~4577 alongside
`typedwasm.ownership`, gated by "any typed access emitted".

Blocker: threading `(region_id, field_id)` from typecheck to codegen

This is the bulk of the work. Today the IR/codegen pipeline has typed
access at the type level — `ephapax-typing` knows the resolved
`(region, field)` at typecheck time, but by the time codegen emits
`i32.load offset=N` / `i32.store offset=N` (~lines 1351–1475 in
lib.rs), the semantic `(region, field)` annotation is gone.

To emit access-sites, codegen needs `(region_id, field_id)` available
at every emission site. Three options:

  1. IR annotation — add resolved `(region_id, field_id)` to the
    typed-access IR node, populated by `ephapax-typing`, consumed by
    `ephapax-wasm`. Likely cleanest.
  2. Side-table — `ephapax-typing` produces a `Map<expr_id,
    (region_id, field_id)>` that `ephapax-wasm` consults during
    emission. Less invasive to the IR shape.
  3. Re-resolve at codegen — duplicate typechecker resolution
    logic in codegen. Code smell; avoid unless options 1/2 are
    blocked.

Test coverage

New isolation test mirroring `typedwasm.ownership` round-trip
coverage (the existing test pattern in
`src/ephapax-wasm/tests/` covers ownership; the access-sites version
should construct a module, emit, verify parse+lookup).

Complexity assessment

Multi-file refactor, blocked on the typecheck → codegen
threading. The encoder + custom-section assembly is a single-day
slice; the threading is the bulk of the work and touches
`src/ephapax-typing/` (or wherever the resolution happens) +
`src/ephapax-wasm/src/lib.rs` field-emission sites.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions