closure

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package api defines Lua closures, C closures, and upvalue types.

LClosure wraps a Proto (compiled function) with captured upvalues. CClosure wraps a Go function with associated upvalues. UpVal implements the open/closed duality for captured variables.

Reference: .analysis/07-runtime-infrastructure.md §2

Upvalue management: find, close, and lifecycle operations.

Reference: lua-master/lfunc.c

Closure and UpVal object pools — reuses dead structs to reduce allocation pressure.

LClosures and UpVals are the second and third most frequently allocated GC objects (after tables). Using sync.Pool lets us reuse the struct memory for short-lived closures/upvals instead of going through Go's mallocgc each time.

Index

Constants

View Source
const MaxUpVal = 255

MaxUpVal is the maximum number of upvalues per closure.

Variables

This section is empty.

Functions

func CloseUpvals

func CloseUpvals(L *state.LuaState, level int)

CloseUpvals closes all open upvalues at or above the given stack level.

func InitUpvals

func InitUpvals(cl *LClosure)

InitUpvals fills all nil upvalue slots in the closure with new closed upvalues. The caller is responsible for linking upvalues into allgc after this returns.

func PutLClosure

func PutLClosure(cl *LClosure)

PutLClosure returns an LClosure to the pool for reuse. Called by the GC sweep phase when a dead closure is unlinked. Clears all reference fields before pooling to help Go's GC.

func PutUpVal

func PutUpVal(uv *UpVal)

PutUpVal returns an UpVal to the pool for reuse. Called by the GC sweep phase when a dead upval is unlinked. Clears all reference fields before pooling to help Go's GC.

Types

type CClosure

type CClosure struct {
	object.GCHeader                 // GC metadata
	Fn              state.CFunction // the Go function
	UpVals          []object.TValue // upvalues stored inline
}

--------------------------------------------------------------------------- CClosure is a Go function closure with associated upvalues. Upvalues are stored inline as TValues (no sharing between closures).

I13 FIX: Fn uses state.CFunction (canonical type, not func(any)int). ---------------------------------------------------------------------------

func NewCClosure

func NewCClosure(fn state.CFunction, nUpvals int) *CClosure

NewCClosure creates a C closure with n upvalue slots (initially nil).

func (*CClosure) GC

func (cl *CClosure) GC() *object.GCHeader

GC returns the GC header for this C closure.

func (*CClosure) NumUpvals

func (c *CClosure) NumUpvals() int

NumUpvals returns the number of upvalues.

type LClosure

type LClosure struct {
	object.GCHeader               // GC metadata
	Proto           *object.Proto // compiled function prototype
	UpVals          []*UpVal      // captured upvalues (len == Proto.Upvalues)
}

--------------------------------------------------------------------------- LClosure is a Lua function closure. It wraps a Proto with captured upvalues. ---------------------------------------------------------------------------

func NewLClosure

func NewLClosure(p *object.Proto, nUpvals int) *LClosure

NewLClosure creates a Lua closure with n upvalue slots (initially nil).

func (*LClosure) GC

func (cl *LClosure) GC() *object.GCHeader

GC returns the GC header for this Lua closure.

type UpVal

type UpVal struct {
	object.GCHeader                      // GC metadata
	StackIdx        int                  // stack index when open, -1 when closed
	Own             object.TValue        // storage for closed value
	Next            *UpVal               // next in open list (lower stack level)
	Stack           *[]object.StackValue // pointer to owning thread's stack (for cross-thread access)
}

--------------------------------------------------------------------------- UpVal represents a captured variable (upvalue).

C4 FIX: Index-based approach to avoid dangling pointers on stack reallocation.

Open state: StackIdx >= 0, value lives at L.Stack[StackIdx].Val Closed state: StackIdx == -1, value lives in Own

The open upvalue list is sorted by stack level in descending order. ---------------------------------------------------------------------------

func FindUpval

func FindUpval(L *state.LuaState, level int) *UpVal

FindUpval finds or creates an open upvalue at the given stack level.

func (*UpVal) Close

func (uv *UpVal) Close(val object.TValue)

Close captures the current value from the stack and marks as closed. The caller must pass the current stack value at uv.StackIdx.

func (*UpVal) GC

func (uv *UpVal) GC() *object.GCHeader

GC returns the GC header for this upvalue.

func (*UpVal) Get

func (uv *UpVal) Get(stack []object.StackValue) object.TValue

Get returns the current value of the upvalue. For closed upvalues (common case), returns Own directly. For open upvalues, reads from the owning thread's stack.

func (*UpVal) IsOpen

func (uv *UpVal) IsOpen() bool

IsOpen returns true if the upvalue still points to a stack slot.

func (*UpVal) Set

func (uv *UpVal) Set(stack []object.StackValue, val object.TValue)

Set sets the value of the upvalue. For open upvalues, uses the stored stack reference (falls back to provided stack). For closed upvalues, writes to Own.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL