Skip to content

feat(t27b): memory primitives -- frame slots, loads/stores, rodata, bounds (Refs #5977) - #6007

Merged
gHashTag merged 1 commit into
masterfrom
claude/t27b-memory
Oct 4, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/t27b-memory

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Stacked on #5992. The base is claude/t27b-coverage, so this diff shows only this PR's commit. GitHub retargets it to master once #5992 merges.

Summary

This adds the memory primitives that t27b will lower structs, fixed arrays, slices and strings onto. Each one works end to end in the interpreter (the oracle), the JIT and the Mach-O object. No front-end construct lowers to them yet; that comes in the next PRs of #5977.

IR (one contiguous memory-lane block in ir.rs):

  • Ty::Ptr;
  • Slot(k) and Data(k) addresses;
  • Load{addr, off} and Store{addr, off, value};
  • Offset{base, idx, scale};
  • Bounds{idx, len, site}, a checked index that traps;
  • Copy{dst, src, size};
  • Func::slots and Program::data;
  • TrapKind::Bounds = 16, numbered high so the scalar lane can add kinds below it.

Interpreter. Memory is modelled byte by byte:

  • slots are allocated per call, with a gap between objects;
  • a written flag is kept for each byte, and Copy copies those flags too.

The interpreter faults on each of these, and never treats them as a pass:

  • a read of bytes never written;
  • an access outside every live slot or blob, including through a slot of a call that has returned;
  • a store into read-only data;
  • a bool load of any byte other than 0 or 1.

A fault is a lowering defect, and --check counts it as a mismatch.

Codegen (AArch64):

  • The aggregate area sits below x29 and can be up to 16 KiB. Addresses past 4 KiB use the lsl #12 form.
  • Loads and stores relative to x29 use ldur/stur. Other loads and stores use the uimm, unscaled or register form, with sign-extending narrow loads.
  • Data addresses are adrp + add.
  • Offset uses a shifted add, or madd when the scale is not a power of two.
  • Bounds is cmp + b.hs to the trap stub.
  • Copy is unrolled in 8/4/2/1-byte steps, or becomes a post-indexed loop past 64 bytes.

JIT. Data blobs are appended to the image, and the adrp/add pairs are patched in place.

Mach-O. A __TEXT,__const section is added, with ARM64_RELOC_PAGE21 / PAGEOFF12 relocation pairs against local l_t27b_data.N symbols.

Encoders. There are new encoders for sized load/store, adr and adrp, with disassembly for each. 32 new encodings are verified against clang, plus a comparison against otool output.

Tests

  • Differential test. The random program generator now covers every primitive:

    • frame slots from 1 byte up to 9000 bytes, so slot addresses go past 4 KiB;
    • data blobs;
    • loads and stores of every scalar type at constant, masked and bounds-checked indices;
    • copies, short ones and looped ones;
    • functions that take a pointer into the caller's frame, which is the hidden-pointer ABI for aggregates.

    It found 0 mismatches:

    overflow mode programs functions functions with frame slots bounds traps compared
    trap 2500 11037 6628 3631
    wrap 2500 11231 6781 6799
  • tests/macho.rs builds an object that reads data across two pages and copies between slots. It links that object with clang into a C harness, runs it, and compares every result with the interpreter.

  • tests/memory.rs pins each fault the interpreter raises, plus the little-endian layout and sign extension.

  • cargo check --target x86_64-unknown-linux-gnu --all-targets passes.

Numbers

t27b corpus specs/ (1185 files) is unchanged: 47 supported and all pass, 0 mismatches. Nothing lowers to these primitives yet.

Refs #5977. Part of #5905.

🤖 Generated with Claude Code

…ounds

The IR primitives that structs, arrays, slices and strings lower onto,
end to end through the interpreter, the JIT and the Mach-O object:

- Ty::Ptr; ExprKind::Slot / Data / Load{addr,off} / Offset{base,idx,
  scale} / Bounds{idx,len,site}; Stmt::Store / Copy; Func::slots;
  Program::data; TrapKind::Bounds = 16 (numbered high, so the scalar
  lane can add kinds below it).
- eval (the oracle): a byte-addressed model with per-call slots, a gap
  between objects and per-byte written flags. It faults on a read of
  unwritten bytes, an access outside a live slot or blob, a store into
  data, and a bool load of anything but 0/1. A fault is a lowering
  defect and never agrees with the JIT.
- codegen:
  - an aggregate area below x29, up to 16 KiB;
  - x29-relative ldur/stur fast paths;
  - uimm, unscaled and register load/store forms, with signed narrow
    loads;
  - ADRP + ADD for data;
  - shifted add or madd for Offset;
  - cmp + b.hs to a Bounds trap stub;
  - Copy unrolled 8/4/2/1, or as a post-indexed loop past 64 bytes.
- JIT: data blobs appended to the image and patched in place.
- Mach-O: a __const section with PAGE21/PAGEOFF12 relocations against
  local l_t27b_data.N symbols.
- a64: sized load/store, adr/adrp encoders and disassembly, with 32
  new clang-verified encodings and an otool comparison.

Tests:
- The random differential generator covers every primitive: slots up
  to 9000 bytes, data blobs, loads and stores of every scalar type at
  constant, masked and bounds-checked indices, short and looped
  copies, and pointer parameters into the caller's frame (the
  hidden-pointer ABI). 0 mismatches over 2500 programs per overflow
  mode.
- tests/macho.rs links an object with clang and runs it against the
  interpreter.
- tests/memory.rs pins the interpreter's faults.

Corpus unchanged (47 pass): nothing lowers to these yet.

Refs #5977

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gHashTag
gHashTag changed the base branch from claude/t27b-coverage to master October 4, 2026 12:44
@gHashTag
gHashTag merged commit 997dfc9 into master Oct 4, 2026
32 of 33 checks passed
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