debug.getupvalue
Returns an upvalue at a given index in a function.
function debug.getupvalue(func: function | number, index: number): anySynopsis
How it works
Reads an upvalueUpvalueA variable captured from an enclosing scope. When a function references a local variable from an outer function, that variable becomes an upvalue — stored in an UpVal struct that persists even after the outer function returns. from a Luau closureClosureA function value that captures its lexical environment. In Luau, closures come in two types: LClosure (Luau bytecode + Proto + upvalues) and CClosure (native C function pointer + upvalues). at the given 1-based index. Upvalues are captured variables from enclosing scopes. When multiple closures share the same upvalue (e.g., both reference the same outer local), modifying the upvalue through one closure is visible in the other.
VM internals — UpVal lifecycle
Luau represents upvalues with the
Closed upvalue: When the parent scope exits, the value is copied into
UpVal struct:
typedef struct UpVal {
GCObject header;
TValue* v; // points to stack slot (open) or &u.value (closed)
union {
TValue value; // storage when closed
struct { // linked list when open
UpVal* prev;
UpVal* next;
} open;
} u;
} UpVal;
Open upvalueUpvalueA variable captured from an enclosing scope. When a function references a local variable from an outer function, that variable becomes an upvalue — stored in an UpVal struct that persists even after the outer function returns.: v points directly into the parent function’s stack frameCall stackThe chain of CallInfo frames representing nested function calls. Each frame records the closure, base register, top, and saved program counter. Walking the call stack reveals the full execution trace.. Reading/writing the upvalue touches the live local variable.Closed upvalue: When the parent scope exits, the value is copied into
u.value and v is redirected to &u.value. The closureClosureA function value that captures its lexical environment. In Luau, closures come in two types: LClosure (Luau bytecode + Proto + upvalues) and CClosure (native C function pointer + upvalues). owns the value on the heap.debug.getupvalue dereferences closure->uprefs[index]->v to read the current value.Usage
Read an upvalue
local upvalue = function() end
local function foo()
print(upvalue)
end
print(debug.getupvalue(foo, 1)) "cc">--> upvalue (function)Parameters
func function | number A Luau function or stack level.
index number Index of the upvalue.
Returns
any The upvalue at index.