"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).
23 lines
1008 B
Plaintext
23 lines
1008 B
Plaintext
// Stream B1 (fibers) — `abi(.pure)` on a GENERIC function emits a correct naked
|
|
// body (regression for an adversarial-review finding).
|
|
//
|
|
// A generic function is monomorphized through a different Function-creation path
|
|
// (lower/generic.zig) than a plain decl. That path originally left `is_pure`
|
|
// unset, so a generic `abi(.pure)` instance silently shipped a FRAMED body — it
|
|
// returned 42 but leaked the prologue's stack adjustment (the exact SP-in ≠
|
|
// SP-out corruption the `.pure` ABI exists to avoid). generic.zig (and the
|
|
// sibling pack-expansion path in pack.zig) now set `is_pure` and emit the
|
|
// asm-only naked body. This pins that: the monomorphized `answer__i64` is a
|
|
// proper naked function (no frame), returning 42. aarch64-pinned (the asm body
|
|
// is per-arch); runs end-to-end on a matching host, ir-only elsewhere.
|
|
answer :: ($T: Type) -> i64 abi(.pure) {
|
|
asm volatile {
|
|
#string A
|
|
mov x0, #42
|
|
ret
|
|
A
|
|
};
|
|
}
|
|
|
|
main :: () -> i64 { return answer(i64); }
|