filc_abi.pl
Fil-C ABI lowering, before AMD64 placement and instruction selection.
lower_function/4 reads two synchronized views: checked operations (proof/access pairs already fused) and ordinary operations for liveness. It never inserts an instruction into either view. Each abi(Actions) occupies its original closed instruction interval, including all its helper calls. Memory operations pass through unchanged.
The product is a function with a frame, entry actions, lowered blocks, exception exit, public object and origins. Frames name payload slots, ordered roots and aliases, not native offsets. Fast words explicitly split pointers into address/lower; generic cells carry separate data and aux sources, including zero aux for scalars. registers/buffer(N) chooses the return protocol; AMD64 assigns registers and buffer bytes.
framePlain, Roots, Aliases includes localName, Size in Plain for nonescaping objects, separate from temporary slots. The special stack_auxName roots form a suffix before the setjmp slots; originWhich, Catch, NRoots, NSetjmps, NLocals describes that order to the collector. initialize_localName zeroes payload and aux and publishes the stack-aux root without a safepoint. It does not produce a heap lower or an address value.
returns_twice invokes native setjmp in the current body and restores payloads without a safepoint before writing the full native int result. Setjmp disables sharing even for unreachable sites. Its snapshots contain every logical temporary/phi payload, never frame bookkeeping or jmpbuf payloads. Snapshot roots are stable from entry; jmpbuf roots are last and persist across nonlocal returns. Variadic entry promotes the incoming packet eagerly and passes an invocation-lived hidden pointer to the private body. promote_incoming uses the original packet size, then roots that pointer in the body before any further safepoint. See docs/setjmp.md and abi-findings.md.
The bijective base-11 encoding is independent of native locations.
A buffer has one exception byte followed by N full payload/lower words.
No physical locations: these are ordered words and their sources.
Generic cells are one eightbyte per source value, not per fast word. Source names for adapters are abstract too: data(I), aux(I), snapshot.
Results name their channels explicitly. Scalar floating results are distinct from integer slots; the target must test the exception first.
Adapter plans are consumed by public generic entries and weak thunks. The void generic result is one zero word, despite having no fast value.
Native saves are indexed by flattened word, generic cells by value. The caller, not these saves, roots every incoming capability.