Skip to content

feat(codegen): heterogeneous funcref tables — runtime type check via the type-id sidecar (#676) - #696

Merged
avrabe merged 1 commit into
mainfrom
feat/676-heterogeneous-tables
Jul 10, 2026
Merged

feat(codegen): heterogeneous funcref tables — runtime type check via the type-id sidecar (#676)#696
avrabe merged 1 commit into
mainfrom
feat/676-heterogeneous-tables

Conversation

@avrabe

@avrabe avrabe commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Closes #676 — the terminal layer of falcon's call_indirect story, after #642 guards (#646), #650 multi-table (#653) and #664 null slots (#669).

What

A heterogeneous funcref table (mixed signatures — falcon's fused 41-slot dispatch table) can never satisfy the closed-world type check, so all 20 dispatch functions loud-declined. WASM Core §4.4.8 makes a call_indirect type mismatch a runtime trap, so the sound lowering is the runtime check itself:

Oracles

🤖 Generated with Claude Code

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.09763% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-synthesis/src/instruction_selector.rs 95.97% 6 Missing ⚠️
crates/synth-backend/src/arm_encoder.rs 95.87% 4 Missing ⚠️
crates/synth-core/src/wasm_decoder.rs 99.13% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe
avrabe force-pushed the feat/676-heterogeneous-tables branch from 618695a to e52957b Compare July 10, 2026 16:58
…the type-id sidecar (#676)

A HETEROGENEOUS funcref table (mixed signatures — falcon's fused 41-slot
dispatch table) can never satisfy the closed-world type check, so every
call_indirect through it loud-declined (20 falcon funcs). WASM Core §4.4.8
makes the mismatch a RUNTIME trap, so the sound lowering is the runtime
check itself: the object now carries a type-id sidecar
(.synth.table_type_ids — one LE u32 STRUCTURAL signature class id per
slot, region order; structurally-equal types share one dense 1-based id,
the meld 31-decls/25-distinct shape; id 0 reserved for null slots) which
the extended R11 layout contract places at R11 + sum(all table sizes)*4,
mirroring the pointer region slot for slot. The dispatch inserts, between
the #642 bounds guard and the pointer load, on both Thumb-2 and A32:

  mov ip, idx, lsl #2 ; add ip, r11, ip ; ldr ip, [ip, #type_off]
  cmp ip, #expected_class_id ; beq ok ; udf

The compare subsumes the #664 null trap (id 0 never equals an expected
id >= 1), so heterogeneous dispatches emit null_check=false. Encoding
ranges decline loudly (sidecar offset > LDR imm12, class id > 255).

Homogeneous tables emit type_check=None + no sidecar section — bytes
identical BY CONSTRUCTION (the #650 offset-0 / #664 null_check=false
trick): whole-ELF cmp verified against origin/main on the #642/#650/#664
fixtures x cortex-m3/r5, frozen anchors 10/10, workspace green. The
estimator is untouched (CallIndirect is direct-selector-only, excluded
from the #511 agreement oracle).

New CI-gated differential (call_indirect_676_differential.py, Thumb-2 +
A32): mixed 5-slot table (two classes interleaved + structural-dup type +
nulls) — matching-class calls equal wasmtime, wrong-class ("indirect call
type mismatch"), null and OOB indices all stop at a UDF; wasmtime's trap
REASONS are asserted per category. Non-vacuous red: a build without the
check CALLS the wrong-typed function and returns a wrong value. Red at
compile on origin/main (capability upgrade). Object-level contract locked
in cargo CI (heterogeneous_table_676.rs: sidecar ids [1,2,1,0,0] +
no-sidecar for the homogeneous fixtures).

Lineage: #642 guards (#646), #650 multi-table (#653), #664 null slots
(#669) — this closes the terminal layer of falcon's call_indirect story.

Closes #676

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@avrabe
avrabe force-pushed the feat/676-heterogeneous-tables branch from e52957b to 1673483 Compare July 10, 2026 17:26
@avrabe
avrabe merged commit 49d6c8f into main Jul 10, 2026
38 checks passed
@avrabe
avrabe deleted the feat/676-heterogeneous-tables branch July 10, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant