Master the fundamental concepts of build a bytecode vm through this focused micro-challenge.
Local variables live in the current call frame. `LOAD_LOCAL idx` and `STORE_LOCAL idx` are how compiled functions read and write slots without touching the operand stack for every access.
A closure captures variables from an enclosing scope. When an inner function references `x` from an outer function, `x` must outlive the outer frame. An upvalue is a cell pointing at that captured variable.
Two common strategies:
For example, a counter closure might capture `count` from an outer function and increment it each call, even after the outer function returns.
```c typedef struct { int code_address; int upvalue_count; Value* upvalues; } Closure; ```
Whether capture is by copy or by reference is the design choice behind JavaScript's classic loop-variable-in-closure bug.
When a closure escapes, captured variables must live on the heap, not in a stack frame that will disappear. Your flat upvalue array is the minimal version of what Lua and JavaScript runtimes manage with open and closed upvalue lists.
This exercise asks you to wire locals into frames and add flat closures with `OP_CLOSURE`. You will implement `LOAD_UPVALUE` and `STORE_UPVALUE` so a nested function reads a captured variable after the outer frame is gone.
Add local variables and closure support to your VM in C.
Requirements:
Test:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github