Repository navigation
Conversation
an address model may state a thread-local access single under a condition: where the build does not meet it one thread runs, and the threadless legalisation makes every such variable an ordinary global, read from the target's statement and never its name. where the build meets it the variable is refused, naming it.
a piece placed as an operand of the target's own call form takes the width of the convention row's word, so an extending fill widens a narrow integer to it, as wasm's basic c abi passes an i8 as an i32.
the webassembly rows of every axis: locals, structured control, physical addressing, function slots, typed values and stack evaluation, clang's data layout at either width, the basic c abi with every piece an operand of wasm's call and the stack pointer homed in __stack_pointer, and wasi preview1's static model whose thread-local accesses are single under the atomics extension.
Options.warnings is where a warning the compilation gives is written, none for nowhere. mirl emit writes them to its diagnostics.
the family admits locals, structured control, physical addressing and stack evaluation, and runs the register family's rows after the threadless legalisation. its back end writes one final module of mink's wasm container: functions typed by their placement, imports from the environment's import module, a table slot for every function whose address is taken, globals laid out in linear memory as one data segment below which the stack grows, and each body emitted from the region tree. a single-use value the next instruction reads stays on the stack and every other is held in a local assigned by live range. a merge's block parameters are its construct's block results. a constant-time function compiles with masc's warning that wasm cannot guarantee its timing.
octalide
marked this pull request as ready for review
October 17, 2026 03:12
BasicCABI.md passes a struct or union that, through nested structs, unions and arrays, holds one scalar and is aligned no more than it as that scalar. the classifier now admits unions and a 128-bit member, refuses an over-aligned aggregate, and a piece in an operand place takes the type of the scalar member it carries whole (abi.carried), so a struct of one float is an f32, of one double an f64, and a struct of a struct of one i64 an i64.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #79
The webassembly family: wasm32 and wasm64 under the basic C ABI, and wasm32 under WASI preview1. It absorbs #80, #84, #85 and #90.
What changed
Access.single{condition}in the address model says one thread runs where the build does not meet the condition. The newmirl.legal.threadlesspass reads it from the target's own statement and never its name. It makes a thread-local global an ordinary global on a threadless build, and it refuses one by name withWhy.threadedwhere threads run. WASI statessingleunder the atomics extension for every model.mirl.target.wasm.axes). The capabilities are values in locals, structured control, physical addressing, stack evaluation, function slots and typed values. The data layout is clang's for each width, and the float NaN rule is cited from the core specification's NaN propagation section. wasm64 differs only in its pointer rows. The WASI model is static, with every thread-local modelsingle.mirl.target.wasm.abi). It hasfile: nil, operand pieces numbered from the first param andpointer_home: global(__stack_pointer). A scalar of at most 64 bits is one piece and an i128 argument is two i64 pieces. A singleton is a struct or union that, through nested structs, unions and arrays, holds one scalar and is aligned no more than it. It passes as that scalar's own type, as BasicCABI.md states. Anything else goes by reference. A result by reference takes an address param first.place_bitswidens a narrow piece in an operand place to the row's word, so an i8 passes as an i32. The newabi.carriedgives a piece in an operand place the type of the scalar member it carries whole, sostruct{float}is an f32,struct{double}an f64 andstruct{struct{i64}}an i64.mirl.target.wasm.*), which writes one final module of mink's wasm container:signature: function types from the placement. A declaration, a definition and a direct call all read the same type.local: a value the next instruction reads as its one use stays on the stack, with no instruction moved. Every other value goes in a local assigned by live range over the IR's liveness, and values of one type share a local where their ranges do not meet.code: structured emission from the region tree.if.br_tablewhen it is dense, or a chain of tests otherwise.loopinside its merge block, about its latch block.ftoiuses the saturating truncations. Atomics are plain accesses where one thread runs.__stack_pointerand given back before each return.module: imports from the environment's import module (wasi_snapshot_preview1, orenvwith no environment). Each function whose address is taken gets a table slot from 1, filled by an active element segment. Globals are laid out in linear memory from the host's image base as one data segment, with the stack growing down from that base. The memory and every function other images see are exported. masc's stream holds the types, index spaces and labels, and its container states the sections.func.addrand function address constants give a table slot, andcall_indirectcarries the signature of the call's own pieces. Fold does no address arithmetic, so it already refuses arithmetic on a slot.mirl.ct.check. A walk masc answersUnreadcompiles with masc's warning (ct.UNGUARANTEED), written to the newOptions.warnings. A secret the walk finds where none may be is refused.mirl.target.wasm.familyadmits the wasm capabilities. Its rows are the register family's, withthreadlessfirst.Back.wasmandOptions.warningsare new, andmirl emitwrites warnings to stderr.DW_OP_WASM_locationis added for locals and operand-stack entries in the producer's single locations.doc/ir/target.mdcovers the wasm family,Access.singleand the operandplace_bitsrule.Choices
rem_sof MIN by -1 gives 0, so the helpers insert the overflow test.br_tablewhen its cases span fewer than 4 values per case plus 4. Otherwise it is a chain of tests.Limits
fma,extractandinsert, variadics, overflow-checked arithmetic,bswapand the wide multiply and divide forms are refused as unselected.ftoito a width other than 32 or 64 is refused. It needs nontrapping-fptoint, which the baseline has to carry.Moved to #342
func.addrgives a slot,call_indirectcarries its signature, the fold refuses slot arithmetic, and other targets stay byte-identical.struct{float}as f32,struct{double}as f64,struct{struct{i64}}as i64,union{float}as f32,struct{float[1]}as f32,struct{char}as i32,struct{__int128}as two i64, an over-alignedstruct{float}andstruct{float, float}by reference, and astruct{__int128}result by reference.DW_OP_WASM_locationfor locals, globals and operands, with code byte-identical with and without debug info.Unreadwalk is not refused.Ran locally:
mach check . -a '*',mach build . -a cliandmach fmt --check ..