Figure 4 — Self-Describing Stack Frames

Capability stack with interleaved CALL frames (tag=0) and LAMBDA frames (tag=1), and RETURN restoration logic

CAPABILITY STACK grows downward ▼ SP ▶ Tag=0 CR5 (Services C-List) CR6 (Active C-List) CR14 (Active Nucleus) PC return address LAMBDA_PC | LAMBDA-active CALL frame Full domain context 2 words Tag=1 PC only (LAMBDA return) LAMBDA Minimal: 1 word. Restore PC only. Tag=0 CR5 (Services C-List) CR6 (Active C-List) CR14 (Active Nucleus) PC return address LAMBDA_PC | LAMBDA-active CALL frame Tag=0 CR5 (Services C-List) CR6 (Active C-List) CR14 (Active Nucleus) PC return address LAMBDA_PC | LAMBDA-active CALL frame stack bottom CALL frame: 2 words [E-GT · machine word (FLAGS·PC·STO)] LAMBDA frame: 1 word [machine word (FLAGS·PC·STO)] EXECUTION TRACE How this stack was built: 1. CALL CR6 ; push CALL frame (tag=0) 2. CALL CR6 ; push CALL frame (tag=0) 3. LAMBDA CR2, x ; set LAMBDA-active flag (no stack push — machine status) 4. CALL CR6 ; save LAMBDA state, push CALL frame (tag=0) + clears LAMBDA-active 5. LAMBDA CR3, y ; new LAMBDA in called domain (no stack push — machine status) ◀ SP is here. Stack has 3 CALL + 1 LAMBDA RETURN LOGIC How RETURN inspects the tag RETURN LAMBDA-active in status? Yes Fast path Restore PC from status Clear flag ~1 cycle Zero stack No Pop stack frame Inspect tag bit Tag = 0 CALL frame restore 1. Check E on saved CR6 GT 2. Restore CR5 3. Restore CR6 4. Restore CR14 (all via mLoad) 5. Restore PC 5+ cycles Full domain restoration Each CR goes through mLoad Tag = 1 LAMBDA frame restore 1. Restore PC 2. Re-set LAMBDA-active ~2 cycles PC only No mLoad KEY INSIGHT The 1-bit tag makes the stack self-describing: Tag = 0 (CALL): Frame: [word 0: E-GT] + [word 1: FLAGS·PC·STO] RETURN re-derives CR5/CR6/CR14 via mLoad (5+ cycles) Tag = 1 (LAMBDA): Frame holds PC only (1 word) RETURN restores PC, no mLoad (~2 cycles) LAMBDA frames appear on stack only when CALL intervened during a LAMBDA body. In the common case (no CALL), no frame is pushed at all. SIZE COMPARISON CALL frame: 2 words 1 LAMBDA frame: 1 word (2x smaller) LAMBDA frames are 50% smaller than CALL frames In common case (fast path): 100% smaller — no frame at all
CALL frame (tag=0) — full domain context, 2 words
LAMBDA frame (tag=1) — PC only, 1 word
Decision point
Fast path (zero stack access)