Files
sx/examples/1800-concurrency-naked-asm.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) — `abi(.pure)` emits a naked function end-to-end.
//
// An `abi(.pure)` function has no calling-convention prologue/epilogue/frame
// and no implicit `__sx_ctx`: its body is a single asm block that sets the
// return register and emits its own `ret`. This is the substrate the per-arch
// fiber context-switch is built on (design §4.6) — a `.c` epilogue would
// restore SP from the wrong stack across a switch (SP-in ≠ SP-out by design).
//
// Lowered via LLVM's `naked` function attribute: the body is emitted verbatim
// (the inline asm + its own `ret`) with NO frame setup; the IR shows
// `attributes #N = { naked noinline nounwind }` and the bare asm. aarch64-pinned
// (the asm body is per-arch); runs end-to-end here (exit 42), ir-only on a
// mismatch. See the x86_64 sibling 1802. NOTE: the `.ir` proves the `naked`
// keyword + asm emitted, NOT register-save correctness (that's the B1.3
// switch-stress harness's job).
answer :: () -> i64 abi(.pure) {
asm volatile {
#string ASM
mov x0, #42
ret
ASM
};
}
main :: () -> i64 { return answer(); }