Carve the async-runtime fibers stream off PLAN-POST-METATYPE Stream B, mirroring the atomics carve. Grounds the B1 compiler floor against the tree: - abi(.pure) exists in the ABI enum but is inert (type_resolver maps it to .default CC, emit emits no naked attr) -> B1.0 makes it emit LLVM naked + skip prologue/ctx. Corrected the design's callconv(.naked) spelling to the real abi(.pure). - context is already an implicit *Context param (slot 0) + push Context is a stack alloca -> fiber-local for free; only shared root is the __sx_default_context global. B1.1 grounded as likely library-only (probe-first). - B1.0 snapshot story corrected: naked body is raw per-arch asm -> two arch-gated examples (aarch64 + x86_64), not one host .ir. Full xfail->green step detail + a B1.0a kickoff prompt. Baseline green (721/0). No code change; first implementation step is B1.0a.
79 lines
5.4 KiB
Markdown
79 lines
5.4 KiB
Markdown
# CHECKPOINT-FIBERS — Stream B1 (fibers + Io + M:1 scheduler)
|
|
|
|
Companion to [PLAN-FIBERS.md](PLAN-FIBERS.md). Update after every step (one step at a time,
|
|
per the cadence rule). New corpus category: `18xx` concurrency.
|
|
|
|
## Last completed step
|
|
**Carve** — wrote PLAN-FIBERS.md + this checkpoint. Grounded the B1 compiler floor against
|
|
the tree (see Decisions). Baseline verified green: `zig build && zig build test` → **721
|
|
ran, 0 failed** (one Android-SDK-gated example skipped; the trailing "failed command:" line
|
|
is the zig listen-protocol echo, not a failure). HEAD `3fad2d5`, tree clean.
|
|
|
|
## Current state
|
|
Stream A (atomics) is feature-complete (✅) and unblocks B2-channels. Stream B1 is **carved,
|
|
not started**. No fibers/Io/scheduler code exists yet. The compiler floor for B1 is grounded:
|
|
- `abi(.pure)` exists in the `ABI` enum but is **inert** — maps to `.default` CC, emits no
|
|
naked attribute. B1.0 makes it actually emit LLVM `naked`.
|
|
- `context` is already an implicit `*Context` param (slot 0) + `push Context` is a stack
|
|
`alloca` ⇒ **fiber-local for free**. The only shared root is the `__sx_default_context`
|
|
global (entry-point bind). B1.1 is therefore expected to be a **library convention** (spawn
|
|
trampoline snapshots the spawner's ctx into slot 0), **likely zero compiler change** —
|
|
confirm by probe first.
|
|
- Inline asm works end-to-end (lower→emit→JIT, aarch64 + x86_64) — the naked body reuses it.
|
|
|
|
## Next step
|
|
**B1.0a (naked-ABI lock commit)** — per PLAN-FIBERS.md "Phases → B1.0 → B1.0a" and the
|
|
kickoff prompt at the bottom of that file. Add `Function.is_naked`, thread `abi == .pure`
|
|
through `decl.zig` (skip implicit-ctx like `.c`), make `emit_llvm` **BAIL loudly** on a naked
|
|
fn, add the two arch-gated examples (`1800` aarch64 / `1801` x86_64), lock to the bail
|
|
diagnostic. STOP before B1.0b (real emission) — separate commit (cadence rule).
|
|
|
|
## Known issues / capability gaps
|
|
- **Orthogonal (not a B1 blocker):** default VALUES for comptime params don't bind on
|
|
generic-struct methods (free-fn defaults DO work) — inherited from Stream A. Only matters
|
|
if a B2 lib type wants a defaulted comptime param; atomics/fibers require explicit, so
|
|
unaffected.
|
|
- **Issue 0144 (open, independent):** calling an unrecognized bodiless `#builtin` silently
|
|
returns 0 / exit 0 — a silent-fallback footgun in the generic builtin-call path. Filed;
|
|
leave for its own fix session unless prioritized. Not a B1 blocker.
|
|
- **Deferred design gap (documented):** the B1.4 event-loop `Io` does not yet cooperate with
|
|
a platform UI run loop (CFRunLoop/NSRunLoop/ALooper); pinning gives thread-affinity, not
|
|
run-loop integration — a §6 app-target concern, out of B1 scope.
|
|
|
|
## Decisions (Stream B1 specifics; surface locked in design §4 / §4.6)
|
|
- **The async runtime is sx LIBRARY code.** The compiler provides only: the general
|
|
primitives (inline asm ✅, `abi(.pure)` naked [B1.0], atomics ✅) + fiber-safe codegen
|
|
(`context` already fiber-local — B1.1). Schedulers, fibers, channels, futures, `Io`
|
|
vtables, `mmap` stacks are all sx.
|
|
- **`abi(.pure)` is the real spelling of the design's `callconv(.naked)`** — postfix slot,
|
|
`name :: (sig) -> Ret abi(.pure) { asm { … }; }`. B1.0 = carry it into IR + emit LLVM
|
|
`naked` + skip prologue/ctx (mirror the existing `.c` skip), NOT extend the enum (it's
|
|
already there, just inert).
|
|
- **`.pure` ≠ `.c`:** a `.c` epilogue would restore SP from the wrong stack across a context
|
|
switch (SP-in ≠ SP-out by design). naked = no prologue/epilogue/frame; the asm emits its
|
|
own `ret`. This is why the switch must be naked.
|
|
- **B1.0 snapshot scope:** the `naked` attr text is arch-invariant, but a naked body is raw
|
|
per-arch asm — so B1.0 needs **two arch-gated examples** (aarch64 + x86_64, `.build`
|
|
target-gated, ir-only on mismatch), unlike atomics' single host `.ir`. The `.ir` proves
|
|
`naked` + asm emitted, NOT register-save correctness (that's B1.3's stress harness).
|
|
- **B1.1 grounded as library-only (pending probe):** push frames are stack-`alloca`'d and
|
|
the implicit ctx rides slot 0, so a spawn trampoline can pass a snapshotted ctx with no
|
|
compiler change. The design doc's "never raw TLS" guards a non-problem (context is not
|
|
TLS). Probe to confirm before sizing any compiler work.
|
|
- **Test keystones (design §10):** the **B1.3 switch-stress harness** gates the
|
|
context-switch (the one piece the deterministic `Io` can't test — §8.1.1, §10.7); the
|
|
**B1.4 deterministic-sim `Io`** (calibrated against blocking `Io` — §8.1.3) gates all
|
|
scheduling tests. Both must exist + be calibrated before the async tests they gate are
|
|
trusted. `18xx` asserts program-emitted ordering contracts, not raw interleaving.
|
|
|
|
## Log
|
|
- **carve** — wrote PLAN-FIBERS.md + CHECKPOINT-FIBERS.md. Grounded the B1 compiler floor:
|
|
`ABI.pure` inert (type_resolver.zig:237), IR `Function` has no naked flag (inst.zig:605),
|
|
attribute API pattern (emit_llvm.zig:1339 nounwind), `.c` ctx-skip precedent
|
|
(decl.zig:515), `push Context` stack-alloca + slot-0 implicit ctx (stmt.zig:1263,
|
|
lower.zig:259), `__sx_default_context` root (decl.zig:2667/2815), inline-asm corpus
|
|
(1645/1651). Corrected the design's `callconv(.naked)` → real `abi(.pure)` spelling and
|
|
the B1.0 snapshot story (two arch-gated examples, not one host `.ir`). B1.1 grounded as
|
|
likely library-only. Baseline green (721/0). Stream ready; **B1.0a is the first
|
|
implementation step.**
|