5.2 KiB
PR-6.2 — Closure Capture Materialization
Briefing
Closures must capture values from the current stack frame into a heap-allocated environment.
This PR defines:
- How captured values are materialized.
- How the environment layout is constructed.
No CALL_CLOSURE yet.
Target
Define bytecode semantics for closure creation:
Introduce instruction (placeholder name):
MAKE_CLOSURE fn_id, capture_count
Semantics:
- Pop
capture_countvalues from stack (top-first). - Allocate closure object with those values stored in-order.
- Push resulting
HeapRefto stack.
Work Items
- Define new opcode
MAKE_CLOSURE. - Implement stack semantics.
- Ensure captured values are copied (not borrowed).
- Update interpreter to support opcode.
Acceptance Checklist
- MAKE_CLOSURE opcode exists.
- Stack pops correct number of values.
- Closure allocated correctly.
- Closure ref pushed to stack.
Tests
- Create closure capturing 0 values.
- Create closure capturing 2 values.
- Validate env order correctness.
Junie Instructions
You MAY:
- Add opcode.
- Modify interpreter dispatch.
- Add tests.
You MUST NOT:
- Implement CALL_CLOSURE yet.
- Modify GC behavior.
- Change verifier in this PR.
If capture order semantics unclear, STOP and ask.
Definition of Done
Closures can be created with captured environment and exist as heap values.
PR-6.3 — CALL_CLOSURE Instruction
Briefing
Closures must be invokable at runtime. This PR introduces dynamic invocation semantics for closures.
Target
Introduce opcode:
CALL_CLOSURE arg_count
Semantics:
-
Stack layout before call:
[... args..., closure_ref] -
Pop closure_ref.
-
Validate it is ObjectKind::Closure.
-
Pop
arg_countarguments. -
Create new call frame:
- Locals initialized with captured env first (design choice below).
- Arguments appended after captures.
-
Jump to function entry (fn_id).
Work Items
- Add
CALL_CLOSUREopcode. - Validate closure_ref type.
- Integrate into call frame creation logic.
- Respect function signature for ret_slots.
Acceptance Checklist
- CALL_CLOSURE implemented.
- Correct stack consumption.
- Correct frame initialization.
- Error on non-closure value.
Tests
- Simple closure returning constant.
- Closure capturing value and using it.
- Error when calling non-closure.
Junie Instructions
You MAY:
- Add opcode and dispatch.
- Modify call frame initialization.
- Add tests.
You MUST NOT:
- Redesign stack model.
- Introduce coroutine behavior here.
- Change GC.
If frame layout decision is ambiguous, STOP and ask before choosing ordering.
Definition of Done
Closures can be invoked dynamically and execute correctly.
PR-6.4 — GC Traversal for Closures
Briefing
Closures introduce heap-to-heap references through their captured environments.
The GC must traverse:
closure -> env -> inner HeapRefs
This PR updates the GC mark phase to correctly traverse closure environments.
Target
Extend GC mark logic:
-
When encountering ObjectKind::Closure:
- Iterate over env values.
- If a value contains HeapRef → mark referenced object.
Work Items
- Update mark traversal switch for Closure.
- Ensure no panics on malformed env.
- Add tests for nested closure references.
Acceptance Checklist
- GC marks env HeapRefs.
- No regression in existing GC tests.
- Nested closures retained correctly.
Tests
- Closure capturing another closure.
- Closure capturing heap object.
- Unreferenced closure collected.
Junie Instructions
You MAY:
- Modify mark traversal.
- Add GC tests.
You MUST NOT:
- Implement compaction.
- Change sweep policy.
If unsure whether env values may contain non-heap values, ask before assuming.
Definition of Done
GC correctly traverses closure environments.
PR-6.5 — Verifier Support for Closures
Briefing
The verifier must understand closure values as a distinct type and validate dynamic calls safely.
Closures are heap objects but semantically represent callable values.
Target
Extend verifier to:
- Introduce a stack type:
ClosureValue. - Validate MAKE_CLOSURE stack effects.
- Validate CALL_CLOSURE argument counts.
- Validate ret_slots against function signature.
Work Items
- Add closure type to verifier type lattice.
- Define stack transitions for MAKE_CLOSURE.
- Define stack transitions for CALL_CLOSURE.
- Ensure deterministic failure on misuse.
Acceptance Checklist
- Verifier understands closure values.
- Invalid CALL_CLOSURE rejected.
- ret_slots validated.
- All tests pass.
Tests
- Valid closure call passes verification.
- CALL_CLOSURE with wrong arg count fails.
- CALL_CLOSURE on non-closure fails.
Junie Instructions
You MAY:
- Extend verifier type model.
- Add tests.
You MUST NOT:
- Weaken verification rules.
- Introduce runtime-only checks instead of verifier checks.
If closure typing conflicts with current stack model, STOP and ask.
Definition of Done
Verifier fully supports closure creation and invocation.