fibers B1.0a: plumb abi(.pure), emit bails (lock)
First implementation step of Stream B1 (fibers). Make the inert abi(.pure) ABI carry an is_pure flag through lowering, with LLVM emission deliberately bailing loudly until B1.0b — the lock half of the lock->green cadence. - IR Function.is_pure, set from fd.abi == .pure at both declareFunction decl sites. - funcWantsImplicitCtx skips .pure (no synthetic __sx_ctx, mirroring the .c skip): a pure fn reads args from ABI registers, an implicit ctx would occupy a register slot the asm doesn't expect. - both body-lowering paths bypass lowerValueBody for .pure: lower the asm body as statements + cap with unreachable. A pure body has no sx return (the asm rets itself), so the implicit-return diagnostic must not fire. - emit_llvm Pass 2 bails loudly when func.is_pure (build-gating nonzero exit) rather than emit a framed body, whose epilogue would corrupt a context switch's deliberate SP-in != SP-out. examples/1800-concurrency-pure-asm.sx: one host example (no .build pin -- the bail fires before instruction selection, so it is host-independent), locked to the bail snapshot. B1.0b flips emit to LLVM's naked attribute + asm-only body and pins the example per-arch. The sx-facing name is "pure" throughout (field, diagnostic); LLVM's naked attribute is only the B1.0b lowering mechanism. Suite green (722/0).
This commit is contained in:
@@ -640,6 +640,16 @@ pub const Function = struct {
|
||||
/// drops the leftover declaration. See current/PLAN-COMPILER-VM.md (S3).
|
||||
is_compiler_domain: bool = false,
|
||||
|
||||
/// True for an `abi(.pure)` function — no calling-convention
|
||||
/// prologue/epilogue/frame, no implicit `__sx_ctx`. Its body is a single
|
||||
/// inline-asm block that reads args from ABI registers and emits its own
|
||||
/// `ret` (the context-switch primitive; design §4.6). emit_llvm lowers this
|
||||
/// via LLVM's `naked` function attribute and generates no frame setup. A
|
||||
/// `.c` epilogue would restore SP from the wrong stack across a context
|
||||
/// switch (SP-in ≠ SP-out by design), which is why `.pure` is distinct
|
||||
/// from `.c`.
|
||||
is_pure: bool = false,
|
||||
|
||||
pub const Param = struct {
|
||||
name: StringId,
|
||||
ty: TypeId,
|
||||
|
||||
Reference in New Issue
Block a user