Repository navigation
t27b(wasm): floor 17 -- the LOCALS MOUNT (statement bodies lower, fact word 11 feeds the walk) - #12378
t27b(wasm): floor 17 -- the LOCALS MOUNT (statement bodies lower, fact word 11 feeds the walk)#12378gHashTag wants to merge 2 commits into
Conversation
…12148, #5980) Floor 14 opened the local window as law (#12178), but the deleted emitter's mount fed it nothing: ir::wasm_facts projected no statement shape and wrote fact word 11 as 0, so every fn with an intermediate still refused as fn body. Floor 17 is the adapter floor -- the three pieces the mount calls, nothing else: - stmts_refusal_w: the windowed verdict of a BS_STMTS_RETURN payload. Statements are opcode spellings, the window rides the EK_VAR reads through expr_refusal_w, the value stack closes on exactly one return value, and a store REFUSES when the value it stores refused -- the verdict never rides under a local.set, or the lowering would emit a body missing those bytes. The loop/call/load/store kinds fail closed (their mounts carry the label depth, callee arity and memarg facts; the law already spells their bytes). - bodies_cap_l: bodies_cap plus one local group's six bytes per locals-carrying row -- walk_prog_locals' own reserve. - compose_module_with_image_l: the emit_with_image composer carrying the locals rows; an empty image over all-zero rows delegates to compose_module_with_image, so the scalar and mounted cuts cannot move. Five tests: the window walk, fail-closed (unbalanced, mountless kinds, the adapter's 255 marker, a partial fact row), the capacity +6, and the two composers -- the delegation pinned by byte equality in both cuts, the 49-byte locals leaf (inc: t = a + 1; return t * 2;) pinned byte for byte through walk_prog_locals, its 66-byte image twin in section id order 1, 3, 5, 7, 10, 11. 103/103 via t27b test and t27c test-report; wasm32.rs 12/12 and wasm32_equality 1/1 stay green; resealed. The mount itself (ir.rs projection + lib.rs adapter) lands in the next commit, paid by shrink.
…1 feeds the walk (floor 17's mount; Refs #11840, #12148, #5980) Floor 17's law landed in the previous commit; this is the mount it serves. The diff shrinks: +10 hand-written foreign lines, -61 (the counted files +1/-32; one duplicated test folded, see below). - ir.rs wasm_facts: a straight-line body (assignments then the trailing return, all-i32-carried locals) projects as BS_STMTS_RETURN -- each assignment lowers postfix(value) then EK_LOCAL_SET, the return walks last -- and fact word 11 carries the local count through fact_put_locals. The body verdict is the law's own windowed fold (stmts_refusal_w), so a var read past nparams + locals_n still refuses with floor 8's construct and detail byte for byte. Any other statement (If, While, Call, Store) keeps BS_OTHER's refusal; a zero-param fn still owes the const shape. - lib.rs emit_with_image: walk_prog_locals + bodies_cap_l + compose_module_with_image_l. All-zero locals rows delegate byte for byte to the old composer, so the 43-byte leaf, the 117-byte trio and the 60-byte mounted cut cannot move. - tests/wasm32.rs: the mount's end-to-end gate -- the inc leaf (the law's 49 bytes, group 01 7F inside the entry) instantiates in Node's WebAssembly and answers inc(7) = 16. The M-B byte-pin test folds: the law pins the identical two-fn framing byte for byte (the 87-byte duo and 117-byte trio, Node-verified per their law tests) and the same latency/frame source keeps its runtime gate in the neighboring Node test; stale narration prose trimmed beside it. A/B on the same spec: pre-mount the wasm32 build refused "unsupported construct fn body at line 4 (fn inc: ...)"; post-mount it emits the 49-byte module and Node answers inc(7)=16, inc(0)=2, byte-identical across rebuilds. wasm32.rs 12/12, wasm32_equality 1/1, wasm.t27 103/103.
736b575 to
b81e86f
Compare
PR DashboardGenerated at: 2026-10-25 11:05:43 UTC
Summary
Seal Status
|
Summary by t27-beesChecked by the t27 compilert27c parse, parse-complete and typecheck on each changed .t27 file at
Read by the modelThis PR implements Floor 17 (the LOCALS MOUNT) for the t27b wasm32 emitter. The stateful floor set 12-16 established the local window as law, but the deleted emitter's mount fed it nothing— Worth a look
Read: 6 files, +532 -88, the whole diff. Head |
|
; SUPERSEDED -- content landed in spec form. Master a3e7947 ('wasm floor 18 -- the LOCALS MOUNT rides beside the landed pointer-carrier floor 17',Refs #12148 #12378, PR #12610) carries this PR's core: the floor-17 pointer-carrier work landed, and floor 18's LOCALS MOUNT rides beside it -- in specs/tri/t27b/wasm.t27 with its seal, per the t27b-in-t27 law, not as the hand-written ir.rs/lib.rs variant this PR carried. ; WHERE THE CONTENT LIVES (SELF-CRITICAL): |
Pull request was closed
What
Floor 17 of the t27b wasm32 emitter: the LOCALS MOUNT. The stateful floor set 12-16 (#12178) opened the local window as law, and #12044 deleted the emitter onto the law -- but the mount fed the window nothing:
ir::wasm_factsprojected no statement shape and wrote fact word 11 as 0, so every fn with an intermediate still refused asfn body. This PR closes that gap: a straight-line body with an intermediate now emits, in 49 bytes, and runs in a standard runtime.The law (commit 1, spec + gen + seal)
specs/tri/t27b/wasm.t27floor 17 -- the three pieces the mount calls, nothing else:stmts_refusal_w: the windowed verdict of aBS_STMTS_RETURNpayload. Statements are opcode spellings, the window rides theEK_VARreads throughexpr_refusal_w, the value stack closes on exactly one return value, and a store refuses when the value it stores refused -- the verdict never rides under alocal.set, or the lowering would emit a body missing those bytes. The loop/call/load/store kinds fail closed: their mounts carry the label-depth, callee-arity and memarg facts; the law already spells their bytes.bodies_cap_l:bodies_capplus one local group's six bytes per locals-carrying row --walk_prog_locals' own reserve.compose_module_with_image_l: theemit_with_imagecomposer carrying the locals rows; an empty image over all-zero rows delegates tocompose_module_with_image, so the scalar and mounted cuts cannot move.Five tests pin every byte: the window walk, fail-closed (unbalanced streams, mountless kinds, the adapter's 255 marker, a partial fact row), the capacity +6, the delegation pinned by byte equality in both cuts, and the 49-byte locals leaf (
inc:t = a + 1; return t * 2;) throughwalk_prog_locals, with its 66-byte image twin in section id order 1, 3, 5, 7, 10, 11. 103/103, resealed.The mount (commit 2, paid by shrink: +10/-61)
ir.rs wasm_facts: assignments-then-return bodies project asBS_STMTS_RETURN;fact_put_localswrites word 11; the body verdict is the law's own windowed fold. Any other statement (If, While, Call, Store) keepsBS_OTHER's refusal; a zero-param fn still owes the const shape -- every old refusal line is byte-stable.lib.rs emit_with_image:walk_prog_locals+bodies_cap_l+compose_module_with_image_l. All-zero locals rows are byte-identical to the old path.tests/wasm32.rs: the mount's end-to-end gate (the inc leaf instantiates in Node's WebAssembly,inc(7) = 16). The M-B byte-pin test folds -- the law pins the identical two-fn framing byte for byte and the same source keeps its runtime gate in the neighboring Node test.A/B evidence
Same spec, one command apart:
unsupported construct fn body at line 4 (fn inc: the wasm32 emitter lowers ... only)inc(7)=16, inc(0)=2, byte-identical across rebuilds.Refs #11840 (wasm32 floor table), #12148 / #12178 (the stateful floor set this mounts), #5980 (the struct-path gap: this is the
localsrung of the dependency order -- the gx_ setters'varintermediates now express), #6198 (port epic).T27 work report
{ "lane": "feat/wasm32-floor-locals", "head_sha": "736b575485224e2b657f1ae8420d9c62c49ba5a5", "base": "origin/master", "commits": [ "spec(tri/t27b): wasm.t27 floor 17 -- the LOCALS MOUNT (spec+gen+seal)", "t27b(wasm): the local window mounts -- statement bodies lower, word 11 feeds the walk" ], "tests": [ {"name": "wasm.t27 law suite (t27b test + t27c test-report)", "result": "103 passed, 0 failed, 0 vacuous -- 98 prior plus 5 new floor-17 tests"}, {"name": "cargo test -p t27b --test wasm32", "result": "12 passed, 0 failed -- includes the new local-window end-to-end Node gate"}, {"name": "cargo test -p t27b --test wasm32_equality", "result": "1 passed, 0 failed -- native vs wasm32 stays equal through the CLI battery"}, {"name": "tri preflight", "result": "9 of 9 gates ok on the rebased branch before push"}, {"name": "lefthook pre-commit on both commits", "result": "own-language ok, foreign-budget ok, secret-gate ok -- no bypass used"}, {"name": "A/B probe on one spec", "result": "pre-mount refuses fn body at line 4; post-mount emits 49 bytes, Node answers inc(7)=16"} ], "budget": { "commit_1": "spec+gen+seal only -- no hand-written foreign files", "commit_2": "+10 added / -61 deleted hand-written foreign lines (ir.rs +28/-14, lib.rs +11/-14, tests/wasm32.rs +22/-50); counted files +1/-32" }, "limitations": [ "Only i32-carried locals are claimed (the law's own scope); a fn whose locals ride another carrier keeps the old refusal.", "Only straight-line statement bodies: If/While/Call/Store in a body keep BS_OTHER's refusal -- their mounts are the later floors of the stateful set (loads/globals, loops/calls, u64 carriers, void fns, pointer params).", "The windowed fold refuses the loop/call/load/store node kinds until those mounts teach it their facts; the law's lowering already spells their bytes for the floors that do.", "One duplicated M-B byte-pin test folded into the law's own byte-identical pins; the same source's runtime gate stays in tests/wasm32.rs." ] }