You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(vm): upvalue capture for closures (by value, single level) (#94)
## What
Adds **upvalue capture** to VM closures — the deferred follow-up from
#93. Previously a lambda could only use its params + globals;
referencing an enclosing local compiled to a `LoadGlobal` that failed at
runtime. Now closures capture enclosing locals.
- **Compiler**: the flat locals list becomes a **stack of scopes**. A
lambda pushes a scope; the enclosing scope stays visible. Name
resolution is now: `LoadLocal` (current scope) → `LoadUpvalue` (captured
from the enclosing scope, recorded + deduped) → `LoadGlobal`. The lambda
emits `MakeClosure(func_idx, upvalue_srcs)`.
- **Value**: `VmClosure` now carries `{ func_idx, upvalues: Vec<Value>
}` (was just an index); the 5 exhaustive `Value` matches updated.
- **bytecode**: `MakeClosure(usize, Vec<usize>)` + new
`LoadUpvalue(usize)`.
- **machine**: `CallFrame` carries `upvalues`; `MakeClosure` captures
the listed enclosing locals **by value**; `CallValue` installs the
closure's upvalues into the new frame; `LoadUpvalue` reads them.
## Verification
- **Full lib suite green: 188 passed, 0 failed** (+2 tests).
- New tests: `(|x| x + n)(5)` → 15 (single capture); `(|x| x + a +
b)(3)` → 123 (multiple).
- `rustfmt` + `clippy` (CI mode) clean.
## Scope (documented limitations → follow-ups)
- **By-value capture**: the closure snapshots captured values at
creation; mutation *through* a captured variable isn't reflected back to
the enclosing scope. (The interpreter captures by reference via a shared
env; matching that needs reference cells.)
- **Single-level nesting**: a lambda captures its immediate enclosing
function's locals, not a grand-enclosing scope (no recursive upvalue
threading yet).
## Remaining VM follow-ups
By-reference / multi-level capture · interpreter↔VM parity harness ·
`.wbc` serialization · worker statements · consent grant-sources.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_013wg3Mtq2QFhYi4XVw1Z6z7
---
_Generated by [Claude
Code](https://claude.ai/code/session_013wg3Mtq2QFhYi4XVw1Z6z7)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments