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
Floors 3-4 of the wasm32 format law: floor 3 (local groups, func entries, vec_prefix framing, code_section with the explicit count, the instruction floor: i32.const 0x41+sleb reusing floor 1's sleb -- the textbook C0 BB 78 for -123456 pinned -- local.get, local.set, i32.add, end) + floor 4 (export_entry and export_section framing, call, the control family block/loop/if/else/br/br_if/return, i64_const, i64_add, local_tee, drop). The capstone: a whole module exporting one function 'answer' returning i32.const 42 -- 39 bytes, sections in ascending id order (1, 3, 7, 10), the shape wasm validation accepts. One self-correction recorded (the subagent's own two-entry export assert said 12; the hand recompute says 11 -- the assert was the defect, the fn was right; no byte of the law changed). 20/20 under t27c test-report and t27b, 0 vacuous. Floor 5 mapped: memory (id 5) + data (id 11) for rodata/strings, the global section (the __stack_pointer mutable global a C-ABI module opens with), the load/store family with align+offset immediates + sub/mul/comparisons + unreachable/nop, the boundary vectors (i64.const at -2^63, the 10-byte sleb; a multi-byte uleb past 2^21), typed blocktypes when a slice demands them.
t27c parse, parse-complete and typecheck on each changed .t27 file at f621d26. Nothing was generated, built or run. A pass means the file is well formed, not that it is right.
specs/tri/t27b/wasm.t27: parses and typechecks.
Read by the model
This PR adds floors 3-4 of the wasm32 specification: export section, call/control flow opcodes, and i64 instruction floor, plus a capstone test composing a minimal valid module exporting answer returning 42.
Worth a look
specs/tri/t27b/wasm.t27:114-133 (export_section): The function writes the vector count at at + 1 + hl (after the section id and uleb length), then copies entries_joined, then writes the section id at at and the uleb length at at+1. This means the vector count and entries are written before the section header bytes exist at their final positions. If entries_joined overlaps with the section's own output range (the comment warns against this), the early write at n (which starts at at + 1 + hl) could clobber the header bytes that are written later. The tests build entries_joined in separate scratch buffers so this doesn't trigger, but the function's contract doesn't enforce or check non-overlap.
specs/tri/t27b/wasm.t27:114-133 (export_section): vec_prefix is called with at + 1 + hl as the output offset, but vec_prefix writes the uleb count directly at that offset. The section body layout is [uleb count][entries_joined], which is correct, but the total body length passed in the section header (body_len = vl + entries_joined.len) includes vl (the uleb count length) — this matches. However, vec_prefix returns the new offset after writing the count, and that return value is ignored; the subsequent copy of entries_joined starts at n which was set to that return value. This is correct ifvec_prefix writes exactly vl bytes. But vec_prefix is the generic vector prefix writer used elsewhere (e.g., code_section), and its implementation isn't shown in this diff — if it ever writes more or fewer bytes than vl, the section framing would be wrong.
specs/tri/t27b/wasm.t27:150-157 (i64_const): Reuses sleb from floor 1 for the immediate. The test at line 800 pins i64.const 4294967296 (2^32) as 42 80 80 80 80 10 (5 continuation bytes + final). sleb encodes signed values; 2^32 fits in unsigned u64 but as a signed i64 it's positive and the sleb encoding matches uleb for positive values. This works but relies on sleb correctly handling values up to 2^63-1. The floor 1 sleb implementation isn't in this diff.
specs/tri/t27b/wasm.t27:830-870 (whole_module_exporting_answer_pins_every_byte): The export section body is built with vec_prefix(export_body, 0, 1) then export_entry. export_entry writes [uleb name_len][name][kind][uleb index]. The test expects the export section to be 07 0A 01 06 61 6E 73 77 65 72 00 00 (12 bytes: id 07, body len 0A, count 01, entry 9 bytes). But export_section is not used in this capstone test — the export section is built manually via section(buf, n, SEC_EXPORT, export_body[0..eb_n]). The section function (from floor 1/2, not shown) must frame the section as [id][uleb body_len][body]. The test expects body_len=0A (10 decimal), which is 1 (count) + 9 (entry) = 10. This matches. However, the export_section function exists but isn't exercised by the capstone; the two code paths (manual section vs export_section) could diverge.
specs/tri/t27b/wasm.t27:114-133 (export_section): The function takes entries_joined as []const u8 but the caller must ensure it's not a slice into out that overlaps the section being written. The comment acknowledges this ("must not lie inside the section's own byte range — build it in the caller's scratch, as the tests do"). This is a latent footgun: a future caller building the export section in-place (e.g., writing entries directly into the output buffer) would cause corruption.
Read: 2 files, +343 -12, the whole diff. Head f621d26. Model: openai-compatible/nvidia/nemotron-3-ultra-550b-a55b. Commands: @t27-bees review | summary | help | pause | resume. Free for every repository.
These columns do not partition: 6 + 36 + 0 + 0 = 42, and there are 43 open PRs. A PR is being counted twice or not at all.
Seal Status
⚠️STALE -- sha256(compiler.rs)=182a47746c33 != manifest seal=87e5cbd3ad94.
The committed NMSE numbers were certified against an older compiler.rs.
Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
owner-approved-foreignOwner-approved exception to the only-t27 rule: hand-written foreign code allowed in this PR
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Floors 3-4 of the wasm32 format law: floor 3 (local groups, func entries, vec_prefix framing, code_section with the explicit count, the instruction floor: i32.const 0x41+sleb reusing floor 1's sleb -- the textbook C0 BB 78 for -123456 pinned -- local.get, local.set, i32.add, end) + floor 4 (export_entry and export_section framing, call, the control family block/loop/if/else/br/br_if/return, i64_const, i64_add, local_tee, drop). The capstone: a whole module exporting one function 'answer' returning i32.const 42 -- 39 bytes, sections in ascending id order (1, 3, 7, 10), the shape wasm validation accepts. One self-correction recorded (the subagent's own two-entry export assert said 12; the hand recompute says 11 -- the assert was the defect, the fn was right; no byte of the law changed). 20/20 under t27c test-report and t27b, 0 vacuous. Floor 5 mapped: memory (id 5) + data (id 11) for rodata/strings, the global section (the __stack_pointer mutable global a C-ABI module opens with), the load/store family with align+offset immediates + sub/mul/comparisons + unreachable/nop, the boundary vectors (i64.const at -2^63, the 10-byte sleb; a multi-byte uleb past 2^21), typed blocktypes when a slice demands them.