Files
sx/examples/1803-concurrency-naked-asm-param.sx
agra a7fe165684 fibers: rename ABI variant .pure -> .naked
"pure" universally means side-effect-free (GCC __attribute__((pure)),
FP purity, D's pure) — the opposite of a register-clobbering context
switch. The concept is "naked": no compiler-generated prologue/epilogue,
body is raw asm that emits its own ret. That is the established term
everywhere (LLVM's naked function attribute — which we literally emit —
plus Zig callconv(.naked), Rust #[naked], GCC/Clang __attribute__
((naked))). Rename the keyword + everything keyed off it so concept,
surface, field, and the emitted LLVM attribute all agree.

- ast.zig: ABI enum variant pure -> naked (+ doc).
- parser: accept abi(.naked); error text updated.
- IR Function.is_pure -> is_naked; type_resolver/decl/generic/pack/
  emit_llvm references updated; diagnostics say abi(.naked).
- examples 1800-1803 renamed *-pure-* -> *-naked-* (source + expected/
  snapshots; .ir/.exit/.stdout/.stderr are byte-identical — the emitted
  IR is unchanged, only the keyword spelling differs).
- docs (PLAN-FIBERS, CHECKPOINT-FIBERS, PLAN-POST-METATYPE, the design
  roadmap, the compiler-API checkpoint/design) updated; the naming
  rationale now records why .naked over .pure.

No semantic change — pure cosmetics. Suite green (725/0).
2026-06-20 17:01:09 +03:00

26 lines
1.1 KiB
Plaintext

// Stream B1 (fibers) — an `abi(.pure)` function with PARAMETERS reads its args
// from ABI registers (the shape the fiber context-switch needs: `swap_context`
// reads `from`/`to` from x0/x1).
//
// A naked function has no frame, so params are NOT spilled to stack slots — they
// stay in their ABI registers and the asm body reads them directly. Here `a` is
// in x0, `b` in x1 (aarch64 AAPCS), and the result returns in x0: `add x0, x0,
// x1`. The lowering skips the param-alloca loop for `.pure` (decl.zig /
// generic.zig); the LLVM args are declared-but-unused, which the verifier allows
// (spilling them would emit `store i64 %0, …` → "cannot use argument of naked
// function"). aarch64-pinned; runs end-to-end (exit 42), ir-only on a mismatch.
//
// Regression for an adversarial-review finding: before the param-alloca guard, a
// param-bearing `.pure` fn emitted invalid LLVM (loud verifier error) instead of
// a working naked function.
add :: (a: i64, b: i64) -> i64 abi(.pure) {
asm volatile {
#string A
add x0, x0, x1
ret
A
};
}
main :: () -> i64 { return add(40, 2); }