Documentation
¶
Overview ¶
Package lua provides a public Go API for embedding the Lua 5.5 interpreter.
This package wraps the internal implementation behind a clean, stable API suitable for embedding Lua in Go applications. It follows the C Lua API conventions (stack-based value passing, pseudo-indices, protected calls) while providing Go-idiomatic error handling and type safety.
Quick Start ¶
Create a Lua state, execute code, and close it:
L := lua.NewState()
defer L.Close()
if err := L.DoString(`print("hello from Lua")`); err != nil {
log.Fatal(err)
}
Registering Go Functions ¶
Go functions can be registered as Lua globals:
add := func(L *lua.State) int {
a := L.CheckInteger(1)
b := L.CheckInteger(2)
L.PushInteger(a + b)
return 1
}
L.PushFunction(add)
L.SetGlobal("add")
Or use the type-safe generic wrappers:
lua.Wrap2R(L, func(a, b int64) int64 { return a + b })
L.SetGlobal("add")
Modules ¶
Register Go modules that Lua code can load with require():
lua.RegisterModule(L, "mylib", map[string]lua.Function{
"hello": func(L *lua.State) int {
L.PushString("world")
return 1
},
})
Built-in modules available via require():
- "async" — coroutine-based async/await with Future and Scheduler
- "channel" — Go-style channels for Lua (Channel)
- "timer" — setTimeout/setInterval timers (TimerManager)
- "http" — HTTP client (GET/POST with async support)
- "json" — JSON encode/decode
- "hotreload" — live code reload with state preservation (ReloadPlan)
Async / Coroutines ¶
The async system provides Future-based concurrency:
sched := lua.NewScheduler(L)
L.DoString(`
local async = require("async")
async.go("return 42") -- runs in background
`)
sched.Tick() // drive coroutines forward
Use Scheduler to manage async coroutines. Use Future for Go↔Lua async communication. Futures support Cancel and context propagation.
Hot-Reload ¶
Replace module functions at runtime while preserving state:
result, err := L.ReloadModule("game.npc")
// result.Replaced = 5 functions updated
// All upvalue state (counters, caches) preserved
For fine-grained control, use the two-phase commit API:
plan, err := L.PrepareReload("mymod") // read-only preparation
if plan.HasIncompatible() {
plan.Abort() // no changes
} else {
plan.Commit() // atomic replacement
}
Sandboxing ¶
Create sandboxed states with CPU limits and restricted libraries:
L := lua.NewSandboxState(lua.SandboxConfig{
CPULimit: 100000, // max instructions
})
State Pool ¶
For high-concurrency servers, reuse Lua states:
pool := lua.NewStatePool(lua.PoolConfig{MaxStates: 10})
L := pool.Get()
defer pool.Put(L)
Type Bridge ¶
High-level type conversion between Go and Lua:
L.PushAny(map[string]any{"name": "Alice", "age": 30})
val := L.ToAny(-1) // map[string]any
var user User
L.ToStruct(-1, &user) // Lua table → Go struct
Stack-Based API ¶
Values are passed between Go and Lua via a virtual stack. Push functions move values from Go to the stack; To/Check functions read values from the stack back to Go. Positive indices count from the bottom (1 = first), negative indices count from the top (-1 = top element).
Error Handling ¶
Use State.DoString or State.DoFile for simple execution with Go error returns. For finer control, use State.Load + State.PCall which return status codes and leave error messages on the stack.
Memory Management ¶
The interpreter uses Go's garbage collector. Call State.Close when done to release internal resources promptly.
Example ¶
package main
import (
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.DoString(`print("hello from Lua")`)
}
Output: hello from Lua
Index ¶
- Constants
- Variables
- func GlobalModules() []string
- func LoadModules(L *State, modules ...Module)
- func OpenAsync(L *State)
- func OpenChannelLib(L *State)
- func OpenHTTP(L *State)
- func OpenHotReload(L *State)
- func OpenJSON(L *State)
- func OpenTimer(L *State)
- func RegisterGlobal(name string, opener ModuleOpener)
- func RegisterModule(L *State, name string, funcs map[string]Function)
- func UnregisterGlobal(name string)
- func UpvalueIndex(i int) int
- func Wrap0(L *State, fn func())
- func Wrap0E(L *State, fn func() error)
- func Wrap0R[R any](L *State, fn func() R)
- func Wrap1[A any](L *State, fn func(A))
- func Wrap1E[A, R any](L *State, fn func(A) (R, error))
- func Wrap1R[A, R any](L *State, fn func(A) R)
- func Wrap2[A, B any](L *State, fn func(A, B))
- func Wrap2E[A, B, R any](L *State, fn func(A, B) (R, error))
- func Wrap2R[A, B, R any](L *State, fn func(A, B) R)
- func Wrap3[A, B, C any](L *State, fn func(A, B, C))
- func Wrap3R[A, B, C, R any](L *State, fn func(A, B, C) R)
- type ArithOp
- type Channel
- func (c *Channel) Close()
- func (c *Channel) IsClosed() bool
- func (c *Channel) Len() int
- func (c *Channel) Recv() (any, bool)
- func (c *Channel) RecvTimeout(timeout time.Duration) (any, bool)
- func (c *Channel) Send(value any) (retErr error)
- func (c *Channel) TryRecv() (any, bool, bool)
- func (c *Channel) TrySend(value any) (sent bool)
- type Closeable
- type CompareOp
- type CoroutineHandle
- type DebugInfo
- type Executor
- type ExecutorConfig
- type FuncPair
- type Function
- type Future
- type GCWhat
- type HookFunc
- type Module
- type ModuleOpener
- type PoolConfig
- type PoolStats
- type RefTracker
- type ReloadPlan
- type ReloadResult
- type Result
- type SandboxConfig
- type Scheduler
- type StackRef
- type State
- func (L *State) AbsIndex(idx int) int
- func (L *State) ArgCheck(cond bool, arg int, extraMsg string)
- func (L *State) ArgError(arg int, extraMsg string) int
- func (L *State) ArgExpected(cond bool, arg int, tname string)
- func (L *State) Arith(op ArithOp)
- func (L *State) CPUInstructionsUsed() int64
- func (L *State) Call(nArgs, nResults int)
- func (L *State) CallRef(ref int, nArgs, nResults int) error
- func (L *State) CallSafe(nArgs, nResults int) error
- func (L *State) CheckAny(idx int)
- func (L *State) CheckInteger(idx int) int64
- func (L *State) CheckNumber(idx int) float64
- func (L *State) CheckOption(idx int, def string, opts []string) int
- func (L *State) CheckStack(n int) bool
- func (L *State) CheckString(idx int) string
- func (L *State) CheckType(idx int, tp Type)
- func (L *State) CheckUdata(idx int, tname string)
- func (L *State) CheckUserdata(n int) any
- func (L *State) ClearHookFields()
- func (L *State) Close()
- func (L *State) CloseSlot(idx int)
- func (L *State) CloseThread(from *State) int
- func (L *State) Compare(idx1, idx2 int, op CompareOp) bool
- func (L *State) Concat(n int)
- func (L *State) Context() context.Context
- func (L *State) Copy(fromIdx, toIdx int)
- func (L *State) CreateTable(nArr, nRec int)
- func (L *State) DeleteUserValue(key string)
- func (L *State) DoFile(filename string) error
- func (L *State) DoString(code string) error
- func (L *State) Dump(strip bool) []byte
- func (L *State) Error() int
- func (L *State) Errorf(format string, args ...interface{}) int
- func (L *State) FileSystem() fs.FS
- func (L *State) ForEach(idx int, fn func(*State) bool)
- func (L *State) GC(what GCWhat, args ...int) int
- func (L *State) GCCollect()
- func (L *State) GCStepAPI() bool
- func (L *State) GCTotalBytes() int64
- func (L *State) GetField(idx int, key string) Type
- func (L *State) GetFieldAny(idx int, key string) any
- func (L *State) GetFieldBool(idx int, key string) bool
- func (L *State) GetFieldInt(idx int, key string) int64
- func (L *State) GetFieldNumber(idx int, key string) float64
- func (L *State) GetFieldRef(idx int, key string) int
- func (L *State) GetFieldString(idx int, key string) string
- func (L *State) GetGCMode() string
- func (L *State) GetGCParam(name string) int64
- func (L *State) GetGlobal(name string) Type
- func (L *State) GetHook() (HookFunc, int, int)
- func (L *State) GetI(idx int, n int64) Type
- func (L *State) GetIUserValue(idx int, n int) Type
- func (L *State) GetInfo(what string, ar *DebugInfo) bool
- func (L *State) GetLocal(ar *DebugInfo, n int) string
- func (L *State) GetMetafield(idx int, field string) bool
- func (L *State) GetMetatable(idx int) bool
- func (L *State) GetStack(level int) (*DebugInfo, bool)
- func (L *State) GetSubTable(idx int, fname string) bool
- func (L *State) GetTable(idx int) Type
- func (L *State) GetTop() int
- func (L *State) GetUpvalue(funcIdx, n int) (string, bool)
- func (L *State) HasCallFrames() bool
- func (L *State) HookActive() bool
- func (L *State) HookCount() int
- func (L *State) HookMask() int
- func (L *State) Insert(idx int)
- func (L *State) IsBoolean(idx int) bool
- func (L *State) IsCFunction(idx int) bool
- func (L *State) IsFunction(idx int) bool
- func (L *State) IsGCRunning() bool
- func (L *State) IsInteger(idx int) bool
- func (L *State) IsNil(idx int) bool
- func (L *State) IsNone(idx int) bool
- func (L *State) IsNoneOrNil(idx int) bool
- func (L *State) IsNumber(idx int) bool
- func (L *State) IsString(idx int) bool
- func (L *State) IsTable(idx int) bool
- func (L *State) IsUserdata(idx int) bool
- func (L *State) IsYieldable() bool
- func (L *State) Len(idx int)
- func (L *State) LenI(idx int) int64
- func (L *State) Load(code string, name string, mode string) int
- func (L *State) LoadFile(filename string, mode string) int
- func (L *State) MemoryUsed() int64
- func (L *State) NewLib(funcs map[string]Function)
- func (L *State) NewMetatable(tname string) bool
- func (L *State) NewTable()
- func (L *State) NewTableFrom(fields map[string]any)
- func (L *State) NewThread() *State
- func (L *State) NewUserdata(size int, nUV int)
- func (L *State) Next(idx int) bool
- func (L *State) OptInteger(idx int, def int64) int64
- func (L *State) OptNumber(idx int, def float64) float64
- func (L *State) OptString(idx int, def string) string
- func (L *State) PCall(nArgs, nResults, msgHandler int) int
- func (L *State) Pop(n int)
- func (L *State) PrepareReload(moduleName string) (*ReloadPlan, error)
- func (L *State) PushAny(value any)
- func (L *State) PushBoolean(b bool)
- func (L *State) PushCloseableResource(resource Closeable)
- func (L *State) PushClosure(f Function, n int)
- func (L *State) PushFString(format string, args ...interface{}) string
- func (L *State) PushFail()
- func (L *State) PushFunction(f Function)
- func (L *State) PushGlobalTable()
- func (L *State) PushGoFunc(fn any)
- func (L *State) PushInteger(n int64)
- func (L *State) PushLightUserdata(p interface{})
- func (L *State) PushNil()
- func (L *State) PushNumber(n float64)
- func (L *State) PushResource(resource Closeable)
- func (L *State) PushString(s string) string
- func (L *State) PushThread() bool
- func (L *State) PushUserdata(value any)
- func (L *State) PushValue(idx int)
- func (L *State) RawEqual(idx1, idx2 int) bool
- func (L *State) RawGet(idx int) Type
- func (L *State) RawGetI(idx int, n int64) Type
- func (L *State) RawGetP(idx int, p uintptr) Type
- func (L *State) RawLen(idx int) int64
- func (L *State) RawSet(idx int)
- func (L *State) RawSetI(idx int, n int64)
- func (L *State) RawSetP(idx int, p uintptr)
- func (L *State) Ref(t int) int
- func (L *State) ReloadModule(name string) (*ReloadResult, error)
- func (L *State) Remove(idx int)
- func (L *State) Replace(idx int)
- func (L *State) Require(modname string, openf Function, global bool)
- func (L *State) ResetCPUCounter()
- func (L *State) Resume(from *State, nArgs int) (int, int)
- func (L *State) Rotate(idx, n int)
- func (L *State) SafeCall(nArgs, nResults int) error
- func (L *State) SafeCallFunc(fn Function, nResults int) error
- func (L *State) SetCPULimit(limit int64)
- func (L *State) SetContext(ctx context.Context)
- func (L *State) SetField(idx int, key string)
- func (L *State) SetFields(idx int, fields map[string]any)
- func (L *State) SetFileSystem(fsys fs.FS)
- func (L *State) SetFuncs(funcs map[string]Function, nUp int)
- func (L *State) SetGCMode(mode string) string
- func (L *State) SetGCParam(name string, value int64) int64
- func (L *State) SetGCStopped(stopped bool)
- func (L *State) SetGlobal(name string)
- func (L *State) SetHook(f HookFunc, mask, count int)
- func (L *State) SetHookFields(mask, count int)
- func (L *State) SetHookMarker()
- func (L *State) SetI(idx int, n int64)
- func (L *State) SetIUserValue(idx int, n int) bool
- func (L *State) SetLocal(ar *DebugInfo, n int) string
- func (L *State) SetMemoryLimit(limit int64) int64
- func (L *State) SetMetatable(idx int)
- func (L *State) SetTable(idx int)
- func (L *State) SetTop(idx int)
- func (L *State) SetUpvalue(funcIdx, n int) (string, bool)
- func (L *State) SetUserValue(key string, value any)
- func (L *State) SetUserdataValue(idx int, v any)
- func (L *State) SetWarnF(f WarnFunction, ud interface{})
- func (L *State) SetWriter(w io.Writer)
- func (L *State) Status() int
- func (L *State) StringToNumber(s string) int
- func (L *State) TestUdata(idx int, tname string) bool
- func (L *State) ToAny(idx int) any
- func (L *State) ToBoolean(idx int) bool
- func (L *State) ToClose(idx int)
- func (L *State) ToInteger(idx int) (int64, bool)
- func (L *State) ToMap(idx int) (map[string]any, bool)
- func (L *State) ToNumber(idx int) (float64, bool)
- func (L *State) ToPointer(idx int) string
- func (L *State) ToString(idx int) (string, bool)
- func (L *State) ToStruct(idx int, dest any) error
- func (L *State) ToThread(idx int) *State
- func (L *State) TolString(idx int) string
- func (L *State) Type(idx int) Type
- func (L *State) TypeError(arg int, tname string) int
- func (L *State) TypeName(tp Type) string
- func (L *State) Unref(t int, ref int)
- func (L *State) UpvalueId(funcIdx, n int) interface{}
- func (L *State) UpvalueJoin(funcIdx1, n1, funcIdx2, n2 int)
- func (L *State) UserValue(key string) any
- func (L *State) UserdataValue(idx int) any
- func (L *State) Warning(msg string, tocont bool)
- func (L *State) Where(level int)
- func (L *State) Writer() io.Writer
- func (L *State) XMove(to *State, n int)
- func (L *State) Yield(nResults int) int
- func (L *State) YieldK(nResults int, ctx int, k Function) int
- type StatePool
- type Task
- type Timer
- type TimerManager
- type Type
- type WarnFunction
Examples ¶
Constants ¶
const ( HookEventCall = state.HookCall // function call HookEventReturn = state.HookReturn // function return HookEventLine = state.HookLine // new source line HookEventCount = state.HookCount // instruction count reached HookEventTailCall = state.HookTailCall // tail call )
HookEvent constants for use with HookFunc callbacks.
const ( // RegistryIndex is the pseudo-index for the Lua registry, a global table // used to store values that need to persist across function calls. RegistryIndex = -1001000 // MultiRet signals that a function call should return all results, // used as the nResults argument to [State.Call] and [State.PCall]. MultiRet = -1 )
Pseudo-indices and special constants.
const ( // RIdxMainThread is the registry index of the main thread. RIdxMainThread = 3 // RIdxGlobals is the registry index of the global environment table. RIdxGlobals = 2 )
Well-known registry keys for accessing standard values.
const ( // RefNil is the reference returned by [State.Ref] when the value is nil. RefNil = -1 // NoRef is the "no reference" sentinel, indicating an invalid reference. NoRef = -2 )
Reference constants for State.Ref and State.Unref.
const ( OK = 0 // no errors Yield = 1 // coroutine yielded (from [State.Resume]) ErrRun = 2 // runtime error ErrSyntax = 3 // syntax error during compilation ErrMem = 4 // memory allocation error ErrErr = 5 // error while running the message handler ErrFile = 6 // file I/O error (from [State.LoadFile]) )
Status codes returned by State.PCall, State.Resume, and related functions.
const ( MaskCall = 1 << 0 // call hook — triggered on every function call MaskRet = 1 << 1 // return hook — triggered on every function return MaskLine = 1 << 2 // line hook — triggered on every new source line MaskCount = 1 << 3 // count hook — triggered every N instructions )
Hook event masks for State.SetHook. Combine with bitwise OR to set multiple hooks.
Variables ¶
var ErrCancelled = errors.New("cancelled")
ErrCancelled is returned by Future.Result when the Future was cancelled.
var ErrChannelClosed = fmt.Errorf("channel is closed")
ErrChannelClosed is returned when attempting to send on a closed channel.
Functions ¶
func GlobalModules ¶
func GlobalModules() []string
GlobalModules returns a copy of all registered global module names. Thread-safe.
func LoadModules ¶
LoadModules loads multiple modules into a State by registering each module's Open method into package.preload. After this call, each module is available via require("name").
This is the per-State equivalent of RegisterGlobal. Use LoadModules when you want a module available only in specific States rather than globally.
func OpenAsync ¶
func OpenAsync(L *State)
OpenAsync opens the "async" module and pushes it onto the stack. Registered globally via init(), so `require("async")` works automatically.
Lua API:
local async = require("async")
local future = async.go("return 42") -- run code in a goroutine
local val, err = async.await(future) -- yield until future resolves
local f = async.resolve(42) -- create an already-resolved future
local f = async.reject("oops") -- create an already-rejected future
func OpenChannelLib ¶
func OpenChannelLib(L *State)
OpenChannelLib opens the "channel" module and pushes it onto the stack. It is registered globally via init(), so `require("channel")` works automatically in any State.
Lua API:
local channel = require("channel")
local ch = channel.new(10) -- buffered channel, size 10
channel.send(ch, "hello") -- send (blocks if full)
local val, ok = channel.recv(ch) -- receive (blocks if empty)
local ok = channel.try_send(ch, val) -- non-blocking send
local val, ok = channel.try_recv(ch) -- non-blocking receive
channel.close(ch) -- close channel
local n = channel.len(ch) -- buffer length
local b = channel.is_closed(ch) -- check if closed
func OpenHTTP ¶
func OpenHTTP(L *State)
OpenHTTP opens the "http" module and pushes it onto the stack. It is registered globally via init(), so `require("http")` works automatically in any State.
Lua API:
local http = require("http")
local resp = http.get(url [, options])
local resp = http.post(url, options)
local resp = http.request(options)
Response table:
{
status = 200, -- HTTP status code (integer)
status_text = "200 OK", -- full status text
body = "...", -- response body as string
headers = { -- response headers (lowercase keys)
["content-type"] = "application/json",
},
}
On error, all functions return nil, error_string.
func OpenHotReload ¶ added in v0.8.0
func OpenHotReload(L *State)
OpenHotReload opens the "hotreload" module.
Lua API:
local hr = require("hotreload")
local result, err = hr.reload("modulename")
local plan, err = hr.prepare("modulename")
if plan then plan:commit() end
func OpenJSON ¶
func OpenJSON(L *State)
OpenJSON opens the "json" module and pushes it onto the stack. It is registered globally via init(), so `require("json")` works automatically in any State.
Lua API:
local json = require("json")
local s = json.encode({name = "Alice", age = 30})
local t = json.decode('{"name":"Alice","age":30}')
local s = json.encode_pretty({name = "Alice"})
func OpenTimer ¶
func OpenTimer(L *State)
OpenTimer opens the "timer" module and pushes it onto the stack. Registered globally via init(), so `require("timer")` works automatically.
Lua API:
local timer = require("timer")
local f = timer.delay(0.5) -- returns Future, resolves after 500ms
local id = timer.after(1.0, fn) -- calls fn after 1 second
local id = timer.every(0.1, fn) -- calls fn every 100ms
timer.cancel(id) -- cancel a timer
func RegisterGlobal ¶
func RegisterGlobal(name string, opener ModuleOpener)
RegisterGlobal registers a module opener in the global registry. Thread-safe. Typically called from package init() functions. When any State calls require("name"), the opener will be invoked if the module isn't found in package.loaded or package.preload.
Example:
func init() {
lua.RegisterGlobal("json", func(L *lua.State) {
L.NewTableFrom(map[string]any{})
L.PushFunction(jsonEncode)
L.SetField(-2, "encode")
L.PushFunction(jsonDecode)
L.SetField(-2, "decode")
})
}
func RegisterModule ¶
RegisterModule registers a set of Go functions as a Lua module that can be loaded via require(name). It sets package.preload[name] to an opener function that creates a table with the given functions.
Example:
RegisterModule(L, "mymod", map[string]lua.Function{
"greet": greetFunc,
"add": addFunc,
})
// Lua: local m = require("mymod"); m.greet("world")
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
lua.RegisterModule(L, "greet", map[string]lua.Function{
"hello": func(L *lua.State) int {
name := L.CheckString(1)
L.PushString(fmt.Sprintf("Hello, %s!", name))
return 1
},
})
L.DoString(`
local g = require("greet")
print(g.hello("World"))
`)
}
Output: Hello, World!
func UnregisterGlobal ¶
func UnregisterGlobal(name string)
UnregisterGlobal removes a module from the global registry. Thread-safe.
func UpvalueIndex ¶
UpvalueIndex returns the pseudo-index for the i-th upvalue (1-based). Use this inside a Function to access closure upvalues.
func Wrap0 ¶
func Wrap0(L *State, fn func())
Wrap0 wraps func() as a Lua function (no args, no return).
func Wrap1R ¶
Wrap1R wraps func(A) R as a Lua function.
Example ¶
package main
import (
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
lua.Wrap1R(L, func(n int) int { return n * n })
L.SetGlobal("square")
L.DoString(`print(square(7))`)
}
Output: 49
func Wrap2R ¶
Wrap2R wraps func(A, B) R as a Lua function.
Example ¶
package main
import (
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
lua.Wrap2R(L, func(a, b int) int { return a + b })
L.SetGlobal("add")
L.DoString(`print(add(3, 4))`)
}
Output: 7
Types ¶
type ArithOp ¶
type ArithOp int
ArithOp is the arithmetic operation type for State.Arith.
const ( OpAdd ArithOp = 0 // + addition OpSub ArithOp = 1 // - subtraction OpMul ArithOp = 2 // * multiplication OpMod ArithOp = 3 // % modulo OpPow ArithOp = 4 // ^ exponentiation OpDiv ArithOp = 5 // / float division OpIDiv ArithOp = 6 // // floor division OpBAnd ArithOp = 7 // & bitwise AND OpBOr ArithOp = 8 // | bitwise OR OpBXor ArithOp = 9 // ~ bitwise XOR OpShl ArithOp = 10 // << left shift OpShr ArithOp = 11 // >> right shift OpUnm ArithOp = 12 // - (unary minus) OpBNot ArithOp = 13 // ~ (bitwise NOT, unary) )
Arithmetic and bitwise operations for State.Arith.
type Channel ¶
type Channel struct {
// contains filtered or unexported fields
}
Channel is a thread-safe communication channel between Lua States or between Go and Lua. It wraps a Go channel with Lua-friendly API.
Channels carry any values; when used from Lua, values are converted via the PushAny/ToAny bridge automatically.
A Channel can be shared across goroutines and across Lua States safely because the underlying Go chan is inherently thread-safe, and the closed flag is protected by a RWMutex.
func NewChannel ¶
NewChannel creates a new Channel with the given buffer size. bufSize 0 creates an unbuffered (synchronous) channel.
func (*Channel) Close ¶
func (c *Channel) Close()
Close closes the channel. Further sends will return ErrChannelClosed. Closing an already-closed channel is a no-op.
func (*Channel) Recv ¶
Recv receives a value from the channel. Blocks until a value is available. Returns (value, true) on success, or (nil, false) if the channel is closed and empty.
func (*Channel) RecvTimeout ¶
RecvTimeout receives with a timeout. Returns (value, true) if received; (nil, false) if timeout or closed.
func (*Channel) Send ¶
Send sends a value into the channel. Blocks until received (if unbuffered) or until buffer has space. Returns ErrChannelClosed if the channel has been closed.
Note: Send does NOT hold the mutex during the blocking channel send because that would deadlock with Close on unbuffered/full channels. Instead it checks the closed flag first, then uses recover to catch any panic from sending on a concurrently-closed Go channel.
type Closeable ¶ added in v0.9.9
Closeable is any Go resource that can be closed. Matches io.Closer.
type CompareOp ¶
type CompareOp int
CompareOp is the comparison operation type for State.Compare.
const ( OpEQ CompareOp = 0 // == (may invoke __eq metamethod) OpLT CompareOp = 1 // < (may invoke __lt metamethod) OpLE CompareOp = 2 // <= (may invoke __le metamethod) )
Comparison operations for State.Compare.
type CoroutineHandle ¶ added in v0.5.1
type CoroutineHandle struct {
// contains filtered or unexported fields
}
CoroutineHandle is a handle to a spawned coroutine, used for cancellation.
func (*CoroutineHandle) ID ¶ added in v0.5.1
func (h *CoroutineHandle) ID() int
ID returns the handle's unique identifier.
type DebugInfo ¶
type DebugInfo struct {
Source string // source of the chunk (e.g. "@filename.lua" or "=stdin")
ShortSrc string // short source for error messages (max 60 chars)
LineDefined int // line where the function definition starts
LastLineDefined int // line where the function definition ends
CurrentLine int // current line being executed
Name string // function name (if known)
NameWhat string // "global", "local", "method", "field", or ""
What string // "Lua", "C", or "main"
NUps int // number of upvalues
NParams int // number of fixed parameters
IsVararg bool // true if the function is variadic
IsTailCall bool // true if this is a tail call
ExtraArgs int // number of extra arguments (vararg)
FTransfer int // index of first transferred value (for call/return hooks)
NTransfer int // number of transferred values (for call/return hooks)
// contains filtered or unexported fields
}
DebugInfo holds debug information about a function activation record. Returned by State.GetStack and filled by State.GetInfo.
Not all fields are filled by every call. The "what" parameter to State.GetInfo controls which fields are populated:
- 'n': Name, NameWhat
- 'S': Source, ShortSrc, What, LineDefined, LastLineDefined
- 'l': CurrentLine
- 'u': NUps, NParams, IsVararg
- 'f': pushes the function onto the stack
- 'r': FTransfer, NTransfer
- 't': IsTailCall, ExtraArgs
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor manages async Lua execution using a pool of States.
Thread-safe: Executor.Submit can be called from any goroutine. Each submitted Task runs in its own goroutine with an exclusively-owned Lua State obtained from the underlying StatePool.
func NewExecutor ¶
func NewExecutor(config ExecutorConfig) *Executor
NewExecutor creates a new async Lua executor.
type ExecutorConfig ¶
type ExecutorConfig struct {
// PoolConfig configures the underlying [StatePool].
PoolConfig PoolConfig
// ResultBuffer is the size of the results channel buffer.
// Default: 64.
ResultBuffer int
}
ExecutorConfig configures an Executor.
type FuncPair ¶ added in v0.8.0
type FuncPair struct {
Name string
Compatible bool // true if upvalue layout is compatible
Reason string // reason for incompatibility (if any)
// contains filtered or unexported fields
}
FuncPair represents a matched pair of old and new functions.
type Function ¶
Function is the signature for Go functions callable from Lua.
The function receives the Lua state and returns the number of results it pushed onto the stack. Arguments passed from Lua are on the stack at positive indices starting from 1.
Example:
greet := func(L *lua.State) int {
name := L.CheckString(1)
L.PushString("Hello, " + name + "!")
return 1
}
func WrapSafe ¶ added in v0.9.9
WrapSafe wraps a Go function so that Go panics are converted to Lua errors. Use this when registering Go functions that might panic.
Example:
L.PushFunction(lua.WrapSafe(func(L *lua.State) int {
// If this panics, Lua gets an error instead of a crash
data := mustParse(L.CheckString(1))
L.PushAny(data)
return 1
}))
L.SetGlobal("parse")
type Future ¶
type Future struct {
// contains filtered or unexported fields
}
Future represents the result of an async operation. Thread-safe: can be resolved from any goroutine.
func NewFutureWithContext ¶ added in v0.7.1
NewFutureWithContext creates a Future with an associated context. The returned context is derived from parent and will be cancelled when the Future completes (Resolve, Reject, or Cancel). Use this context in Go goroutines to support cancellation of in-flight operations (HTTP requests, IO, etc.).
Example:
future, ctx := lua.NewFutureWithContext(parentCtx)
go func() {
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
future.Reject(err)
return
}
future.Resolve(body)
}()
func (*Future) Cancel ¶ added in v0.5.1
func (f *Future) Cancel()
Cancel cancels the Future. Waiters are notified with ErrCancelled. Thread-safe. No-op if already done.
func (*Future) IsCancelled ¶ added in v0.5.1
IsCancelled returns true if the Future was cancelled.
func (*Future) Reject ¶
Reject completes the Future with an error. Thread-safe. Only the first Resolve/Reject takes effect.
func (*Future) Resolve ¶
Resolve completes the Future with a value. Thread-safe. Can be called from any goroutine. Only the first call takes effect; subsequent calls are no-ops.
type GCWhat ¶
type GCWhat int
GCWhat is the GC operation type for State.GC.
const ( GCStop GCWhat = 0 // stop the garbage collector GCRestart GCWhat = 1 // restart the garbage collector GCCollect GCWhat = 2 // perform a full collection cycle GCCount GCWhat = 3 // return total memory in use (KBytes) GCCountB GCWhat = 4 // return remainder bytes of memory in use GCStep GCWhat = 5 // perform an incremental GC step GCIsRunning GCWhat = 9 // return 1 if GC is running, 0 if stopped GCGen GCWhat = 10 // switch to generational GC mode GCInc GCWhat = 11 // switch to incremental GC mode )
Garbage collection operations for State.GC.
type HookFunc ¶
HookFunc is the callback type for debug hooks set via State.SetHook.
The callback receives the Lua state, the hook event (one of the HookEvent* constants), and the current source line number (-1 for non-line events). Inside the callback you may inspect the call stack via State.GetStack and State.GetInfo, but you must not yield or raise errors.
type Module ¶
type Module interface {
// Name returns the module name used in require().
Name() string
// Open registers the module into the given Lua State.
// It should push exactly one value (the module table) onto the stack.
Open(L *State)
}
Module is the standard interface for go-lua extension modules. Third-party libraries implement this to be loadable via LoadModules.
Example:
type JSONModule struct{}
func (JSONModule) Name() string { return "json" }
func (JSONModule) Open(L *lua.State) {
L.NewTableFrom(map[string]any{})
L.PushFunction(jsonEncode)
L.SetField(-2, "encode")
}
type ModuleOpener ¶
type ModuleOpener func(L *State)
ModuleOpener is a function that opens/registers a module into a Lua State. It should push exactly one value (the module table) onto the stack and return 1. Typically called automatically when require("name") triggers the global registry searcher.
type PoolConfig ¶
type PoolConfig struct {
// MaxStates is the maximum number of States in the pool.
// When the pool is full, [StatePool.Put] closes excess States.
// Default: 8.
MaxStates int
// InitFunc is called on each new State after creation.
// Use it to register modules, set globals, configure sandbox, etc.
// If nil, States are created with [NewState] defaults.
InitFunc func(L *State)
// Sandbox, if non-nil, creates sandboxed States via [NewSandboxState]
// instead of regular ones.
Sandbox *SandboxConfig
}
PoolConfig configures a StatePool.
type PoolStats ¶
type PoolStats struct {
Available int // States currently idle in the pool.
Created int // Total States created over the pool's lifetime.
MaxStates int // Configured maximum pool size.
}
PoolStats contains statistics about a StatePool.
type RefTracker ¶ added in v0.9.9
type RefTracker struct {
// contains filtered or unexported fields
}
RefTracker tracks Lua registry references for leak detection. Use during development/testing to find Ref() calls without matching Unref().
Example:
tracker := lua.NewRefTracker()
ref := tracker.Ref(L, lua.RegistryIndex)
// ... use ref ...
tracker.Unref(L, lua.RegistryIndex, ref)
// At shutdown:
leaks := tracker.Leaks()
if len(leaks) > 0 {
t.Errorf("ref leaks:\n%s", strings.Join(leaks, "\n"))
}
func NewRefTracker ¶ added in v0.9.9
func NewRefTracker() *RefTracker
NewRefTracker creates a new RefTracker.
func (*RefTracker) Count ¶ added in v0.9.9
func (t *RefTracker) Count() int
Count returns the number of currently active (unfreed) references.
func (*RefTracker) Leaks ¶ added in v0.9.9
func (t *RefTracker) Leaks() []string
Leaks returns a list of leaked references (Ref'd but never Unref'd). Each entry includes the caller location where Ref was called.
func (*RefTracker) Ref ¶ added in v0.9.9
func (t *RefTracker) Ref(L *State, idx int) int
Ref creates a registry reference and tracks it. Use instead of L.Ref(RegistryIndex).
func (*RefTracker) Reset ¶ added in v0.9.9
func (t *RefTracker) Reset()
Reset clears all tracking state.
type ReloadPlan ¶ added in v0.8.0
type ReloadPlan struct {
Module string // module name
Pairs []FuncPair // matched old↔new function pairs
Added []string // new functions not in old module
Removed []string // old functions not in new module
Warnings []string // non-fatal warnings
// contains filtered or unexported fields
}
ReloadPlan represents a prepared hot-reload operation. Created by PrepareReload, executed by Commit.
Note: The new module's init code has already been executed during PrepareReload. The plan controls only whether function replacements are applied (Commit) or discarded (Abort). Side effects from the new module's init code cannot be rolled back by Abort.
func (*ReloadPlan) Abort ¶ added in v0.8.0
func (p *ReloadPlan) Abort()
Abort discards the reload plan without modifying any state.
func (*ReloadPlan) Commit ¶ added in v0.8.0
func (p *ReloadPlan) Commit() *ReloadResult
Commit executes the reload plan. All compatible functions have their proto swapped and upvalues transferred. Incompatible functions are skipped. Returns the result summary.
func (*ReloadPlan) HasIncompatible ¶ added in v0.8.0
func (p *ReloadPlan) HasIncompatible() bool
HasIncompatible returns true if any function pair is incompatible.
func (*ReloadPlan) IncompatibleCount ¶ added in v0.8.0
func (p *ReloadPlan) IncompatibleCount() int
IncompatibleCount returns the number of incompatible function pairs.
type ReloadResult ¶ added in v0.8.0
type ReloadResult struct {
Module string
Replaced int // functions successfully replaced
Skipped int // incompatible functions skipped
Added int // new functions added to module
Removed int // functions removed from old but not new (left in place)
Warnings []string
}
ReloadResult reports the outcome of a hot-reload operation.
type Result ¶
type Result struct {
// ID matches the [Task.ID] that produced this result.
ID string
// Value is the return value (from [Task.Func], or nil for [Task.Code]).
Value any
// Error is non-nil if the Lua execution failed.
Error error
}
Result is the outcome of an async Lua Task.
type SandboxConfig ¶
type SandboxConfig struct {
// MemoryLimit is the maximum memory in bytes (0 = no limit).
MemoryLimit int64
// CPULimit is the maximum number of VM instructions (0 = no limit).
CPULimit int64
// AllowIO controls whether the io and os libraries are available.
// Default false = no io/os access.
AllowIO bool
// AllowDebug controls whether the debug library is available.
// Default false = no debug access.
AllowDebug bool
// AllowPackage controls whether the package/require library is available.
// Default false = no module loading.
AllowPackage bool
// ExtraLibs is a map of additional libraries to register.
// These are registered after the standard libraries.
ExtraLibs map[string]Function
}
SandboxConfig configures a sandboxed Lua state created by NewSandboxState.
type Scheduler ¶
type Scheduler struct {
L *State
OnError func(err error) // called when a coroutine errors during Tick
// contains filtered or unexported fields
}
Scheduler manages async coroutines within a single Lua State. NOT thread-safe — must be used from a single goroutine (the main/event loop goroutine).
func NewScheduler ¶
NewScheduler creates a new Scheduler for the given State.
func (*Scheduler) Cancel ¶ added in v0.5.1
func (s *Scheduler) Cancel(h *CoroutineHandle)
Cancel cancels a coroutine by its handle. Removes it from pending, unrefs, and cancels its future.
func (*Scheduler) Destroy ¶ added in v0.5.1
func (s *Scheduler) Destroy()
Destroy cancels all pending coroutines and releases their registry references. Call this when shutting down or hot-reloading. Safe to call from within an OnError callback during Tick.
func (*Scheduler) Spawn ¶
func (s *Scheduler) Spawn(L *State) (*CoroutineHandle, error)
Spawn creates a new coroutine from the function at the top of L's stack and starts executing it. If it yields (via await), it's added to the pending list. The function is popped from the stack. Returns a CoroutineHandle that can be used to cancel the coroutine.
type StackRef ¶
type StackRef struct {
Index int
}
StackRef references a value on the Lua stack by index. When passed to State.PushAny, it calls State.PushValue(ref.Index) to copy the stack value. This allows mixing Go values and Lua stack values in maps passed to State.NewTableFrom / State.SetFields.
Example:
L.NewTableFrom(map[string]any{
"name": "Select",
"props": lua.StackRef{Index: 1}, // copies stack index 1
})
type State ¶
type State struct {
// contains filtered or unexported fields
}
State is the main Lua interpreter state. It wraps the internal API state and provides a clean public interface.
func NewBareState ¶
func NewBareState() *State
NewBareState creates a new Lua state without loading standard libraries. Use this when you need full control over which libraries are available.
func NewSandboxState ¶
func NewSandboxState(config SandboxConfig) *State
NewSandboxState creates a new Lua state with restricted capabilities.
By default only safe libraries are loaded: a restricted base library (without dofile, loadfile, load, require), string, table, math, utf8, and coroutine. The io, os, debug, and package libraries are excluded unless explicitly enabled via SandboxConfig.
If [SandboxConfig.CPULimit] is set, a CPU instruction limit is applied via State.SetCPULimit.
If [SandboxConfig.MemoryLimit] is set and the state supports memory limiting, it will be applied.
Example:
L := lua.NewSandboxState(lua.SandboxConfig{
CPULimit: 1_000_000, // max 1M instructions
})
defer L.Close()
err := L.DoString(untrustedCode)
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewSandboxState(lua.SandboxConfig{
MemoryLimit: 10 * 1024 * 1024, // 10MB
CPULimit: 100_000, // 100K instructions
})
defer L.Close()
// Safe to execute untrusted code — io/os/debug are blocked.
err := L.DoString(`print("Hello from sandbox!")`)
if err != nil {
fmt.Println("Error:", err)
}
// Dangerous functions are removed.
err = L.DoString(`io.open("secret.txt")`)
if err != nil {
fmt.Println("io blocked:", err != nil)
}
}
Output: Hello from sandbox! io blocked: true
func NewState ¶
func NewState() *State
NewState creates a new Lua state with all standard libraries loaded.
func (*State) ArgCheck ¶
ArgCheck checks a condition for argument arg. If cond is false, raises an error with extraMsg.
func (*State) ArgError ¶
ArgError raises an error for argument arg with the given message. This function does not return.
func (*State) ArgExpected ¶
ArgExpected checks that argument arg satisfies a condition. If cond is false, raises a type error with tname.
func (*State) Arith ¶
Arith performs an arithmetic or bitwise operation on the values at the top of the stack. For binary operations, pops two operands; for unary, pops one. Pushes the result.
func (*State) CPUInstructionsUsed ¶
CPUInstructionsUsed returns the approximate number of VM instructions executed since the last State.SetCPULimit or State.ResetCPUCounter call. The value is approximate because the count hook fires every N instructions (default 1000), not on every single instruction.
func (*State) Call ¶
Call calls a function in unprotected mode. nArgs arguments are on the stack above the function. nResults is the number of expected results (or MultiRet for all).
func (*State) CallRef ¶
CallRef retrieves a function from the registry by reference ID and calls it in protected mode. nArgs arguments must already be on the stack. Returns nil on success (nResults on stack), or a Go error. Returns an error if the ref does not point to a function.
Example:
L.PushAny(eventData) // push 1 arg err := L.CallRef(refID, 1, 0)
func (*State) CallSafe ¶
CallSafe calls a function in protected mode and returns a Go error on failure. The function and nArgs arguments must already be on the stack (same as PCall). On success, nResults results are on the stack and err is nil. On failure, the error message is popped from the stack and returned as a Go error.
Example:
L.PushFunction(fn)
L.PushAny(arg)
err := L.CallSafe(1, 1)
if err != nil { log.Fatal(err) }
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.DoString(`
function divide(a, b)
if b == 0 then error("division by zero") end
return a / b
end
`)
// Successful call.
L.GetGlobal("divide")
L.PushInteger(10)
L.PushInteger(2)
err := L.CallSafe(2, 1)
if err != nil {
fmt.Println("error:", err)
return
}
val, _ := L.ToNumber(-1)
L.Pop(1)
fmt.Printf("result: %g\n", val)
// Failing call — error is returned as a Go error.
L.GetGlobal("divide")
L.PushInteger(10)
L.PushInteger(0)
err = L.CallSafe(2, 1)
fmt.Println("caught error:", err != nil)
}
Output: result: 5 caught error: true
func (*State) CheckAny ¶
CheckAny checks that there is an argument at idx (any type). Raises a Lua error if the index is not valid.
func (*State) CheckInteger ¶
CheckInteger checks that the argument at idx is an integer and returns it. Raises a Lua error if the check fails.
func (*State) CheckNumber ¶
CheckNumber checks that the argument at idx is a number and returns it. Raises a Lua error if the check fails.
func (*State) CheckOption ¶
CheckOption checks that the argument at idx is a string matching one of the options. Returns the index of the matched option. If def is non-empty and the argument is nil/absent, uses def.
func (*State) CheckStack ¶
CheckStack ensures that the stack has space for at least n extra elements. Returns false if it cannot fulfill the request.
func (*State) CheckString ¶
CheckString checks that the argument at idx is a string and returns it. Raises a Lua error if the check fails.
func (*State) CheckType ¶
CheckType checks that the argument at idx has the given type. Raises a Lua error if the check fails.
func (*State) CheckUdata ¶
CheckUdata checks that the value at idx is a userdata with metatable matching registry[tname]. Raises a type error if not.
func (*State) CheckUserdata ¶
CheckUserdata checks that the argument at position n is a userdata (full or light) and returns the Go value stored inside it. Raises a Lua error if the argument is not a userdata.
func (*State) ClearHookFields ¶
func (L *State) ClearHookFields()
ClearHookFields clears all hook fields. Deprecated: Use SetHook(nil, 0, 0) instead.
func (*State) Close ¶
func (L *State) Close()
Close releases all resources associated with the Lua state.
func (*State) CloseSlot ¶
CloseSlot closes the to-be-closed slot at the given index and sets its value to nil. The index must be the last active to-be-closed variable. Mirrors: lua_closeslot in lapi.c
func (*State) CloseThread ¶
CloseThread resets a thread (coroutine), closing all pending to-be-closed variables and putting the thread in a dead/closed state. Returns a status code. Mirrors: lua_closethread in lapi.c
func (*State) Compare ¶
Compare compares two values using the given comparison operation. May trigger __eq, __lt, or __le metamethods.
func (*State) Concat ¶
Concat concatenates the n values at the top of the stack, pops them, and pushes the result. May trigger __concat metamethod.
func (*State) Context ¶
Context returns the associated context.Context, or context.Background if none was set. Reads from the internal api.State so the context is accessible even from wrapFunction-created State wrappers.
func (*State) CreateTable ¶
CreateTable pushes a new table with pre-allocated space for nArr array elements and nRec hash elements.
func (*State) DeleteUserValue ¶
DeleteUserValue removes a previously stored user value.
func (*State) DoString ¶
DoString loads and executes a Lua string. Returns nil on success, or an error.
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
err := L.DoString(`result = 2 + 3`)
if err != nil {
fmt.Println("error:", err)
return
}
L.GetGlobal("result")
val, _ := L.ToInteger(-1)
fmt.Println(val)
}
Output: 5
func (*State) Dump ¶
Dump dumps the Lua function at the top of the stack as a binary chunk. If strip is true, debug information is removed. Returns the binary chunk bytes, or nil if the value is not a Lua function. Mirrors: lua_dump in lapi.c
func (*State) Error ¶
Error raises a Lua error with the value at the top of the stack as the error object. This function does not return.
func (*State) FileSystem ¶
FileSystem returns the current filesystem, or nil for the real OS filesystem.
func (*State) ForEach ¶
ForEach iterates over all key-value pairs in the table at idx. For each pair, the callback receives the State with key at -2 and value at -1. The callback must NOT pop the key or value — ForEach handles cleanup. If the callback returns false, iteration stops early.
Example:
L.ForEach(-1, func(L *lua.State) bool {
k, _ := L.ToString(-2)
v := L.ToAny(-1)
fmt.Println(k, v)
return true // continue
})
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
// ForEach works well with ordered integer-keyed tables.
L.DoString(`items = {"apple", "banana", "cherry"}`)
L.GetGlobal("items")
L.ForEach(-1, func(L *lua.State) bool {
idx, _ := L.ToInteger(-2)
val, _ := L.ToString(-1)
fmt.Printf("%d: %s\n", idx, val)
return true // continue iteration
})
L.Pop(1)
}
Output: 1: apple 2: banana 3: cherry
func (*State) GCCollect ¶
func (L *State) GCCollect()
GCCollect runs a full garbage collection cycle.
func (*State) GCStepAPI ¶
GCStepAPI runs a bounded incremental GC step. Returns true if a full GC cycle completed during this step.
func (*State) GCTotalBytes ¶
GCTotalBytes returns the total number of bytes tracked by the Lua GC.
func (*State) GetField ¶
GetField pushes t[key] where t is the value at idx. Returns the type of the pushed value.
func (*State) GetFieldAny ¶
GetFieldAny reads t[key] and converts it to a Go value using ToAny. Returns nil if the field is nil.
func (*State) GetFieldBool ¶
GetFieldBool reads t[key] as a bool where t is the value at idx. Returns false if the field is nil or false.
func (*State) GetFieldInt ¶
GetFieldInt reads t[key] as an int64 where t is the value at idx. Returns 0 if the field is nil or not convertible to an integer.
func (*State) GetFieldNumber ¶
GetFieldNumber reads t[key] as a float64 where t is the value at idx. Returns 0 if the field is nil or not convertible to a number.
func (*State) GetFieldRef ¶
GetFieldRef reads t[key] and if it's a function, stores it in the Lua registry and returns the reference ID. Returns RefNil if the field is not a function. The caller is responsible for calling L.Unref(RegistryIndex, ref) when the reference is no longer needed.
func (*State) GetFieldString ¶
GetFieldString reads t[key] as a string where t is the value at idx. Returns "" if the field is nil or not convertible to a string. This is equivalent to: L.GetField(idx, key); s, _ := L.ToString(-1); L.Pop(1)
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.DoString(`person = {name = "Alice", city = "Tokyo"}`)
L.GetGlobal("person")
name := L.GetFieldString(-1, "name")
city := L.GetFieldString(-1, "city")
fmt.Println(name, "lives in", city)
L.Pop(1)
}
Output: Alice lives in Tokyo
func (*State) GetGCParam ¶
GetGCParam returns the current value of a GC parameter by name. Known parameters: "pause", "stepmul", "stepsize", "minormul", "majorminor", "minormajor".
func (*State) GetGlobal ¶
GetGlobal pushes the value of the global variable name. Returns the type of the pushed value.
func (*State) GetHook ¶
GetHook returns the current hook function, mask, and count. Returns (nil, 0, 0) if no hook is set via the public API.
func (*State) GetI ¶
GetI pushes t[n] where t is the value at idx. Returns the type of the pushed value.
func (*State) GetIUserValue ¶
GetIUserValue pushes the n-th user value of the userdata at idx onto the stack. Returns the type of the pushed value, or TypeNone if invalid.
func (*State) GetInfo ¶
GetInfo fills debug info fields specified by the what string. Characters in what select which fields to fill:
- 'n': Name, NameWhat
- 'S': Source, ShortSrc, What, LineDefined, LastLineDefined
- 'l': CurrentLine
- 'u': NUps, NParams, IsVararg
- 'f': pushes the function onto the stack
- 'r': FTransfer, NTransfer
- 't': IsTailCall, ExtraArgs
func (*State) GetLocal ¶
GetLocal pushes the value of local variable n of the function at the given debug level. Returns the variable name, or "" if not found.
func (*State) GetMetafield ¶
GetMetafield pushes the metamethod field from the metatable of the value at idx. Returns true if found, false if not (nothing pushed).
func (*State) GetMetatable ¶
GetMetatable pushes the metatable of the value at idx. Returns false if the value has no metatable (nothing pushed).
func (*State) GetStack ¶
GetStack fills a DebugInfo for the given call level. Level 0 is the current running function, level 1 is the function that called the current one, etc. Returns (info, true) on success, (nil, false) if the level is invalid.
func (*State) GetSubTable ¶
GetSubTable ensures that t[fname] is a table, creating it if needed. t is at idx. Pushes the subtable. Returns true if it already existed.
func (*State) GetTable ¶
GetTable pushes t[k] where t is the value at idx and k is the value at the top of the stack. Pops the key. Returns the type of the pushed value. May trigger __index metamethod.
func (*State) GetTop ¶
GetTop returns the index of the top element (= number of elements on the stack).
func (*State) GetUpvalue ¶
GetUpvalue pushes the value of upvalue n of the closure at funcIdx. Returns (name, true) if the upvalue exists, ("", false) otherwise.
func (*State) HasCallFrames ¶
HasCallFrames returns true if the thread has call frames above the base.
func (*State) HookActive ¶
HookActive returns true if any hooks are set.
func (*State) IsCFunction ¶
IsCFunction returns true if the value at idx is a Go function.
func (*State) IsFunction ¶
IsFunction returns true if the value at idx is a function (Lua or Go).
func (*State) IsGCRunning ¶
IsGCRunning returns true if the GC is not stopped.
func (*State) IsNoneOrNil ¶
IsNoneOrNil returns true if the index is not valid or the value is nil.
func (*State) IsNumber ¶
IsNumber returns true if the value at idx is a number or a string convertible to a number.
func (*State) IsString ¶
IsString returns true if the value at idx is a string or a number (numbers are always convertible to strings).
func (*State) IsUserdata ¶
IsUserdata returns true if the value at idx is a userdata (full or light).
func (*State) IsYieldable ¶
IsYieldable returns true if the running coroutine can yield.
func (*State) Len ¶
Len pushes the length of the value at idx onto the stack. May trigger __len metamethod.
func (*State) LenI ¶
LenI returns the length of the value at idx as an integer. May trigger __len metamethod. Raises an error if the result is not an integer.
func (*State) Load ¶
Load loads a Lua chunk from a string without executing it. Pushes the compiled chunk as a function on success. Returns a status code.
func (*State) LoadFile ¶
LoadFile loads a Lua file without executing it. Pushes the compiled chunk as a function on success. Returns a status code (OK on success, or an error code). On error, an error message is pushed onto the stack.
The mode parameter controls what kind of chunks can be loaded: "t" for text only, "b" for binary only, "bt" for both (default if empty).
func (*State) MemoryUsed ¶
MemoryUsed returns the current Lua-level memory usage in bytes.
func (*State) NewMetatable ¶
NewMetatable creates a new metatable in the registry with the given name. If the registry already has a table with that name, pushes it and returns false. Otherwise creates a new table, stores it, and returns true.
func (*State) NewTable ¶
func (L *State) NewTable()
NewTable pushes a new empty table onto the stack.
func (*State) NewTableFrom ¶
NewTableFrom creates a new table, fills it with the given fields, and leaves it on top of the stack. Values are pushed using PushAny.
Example ¶
package main
import (
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.NewTableFrom(map[string]any{
"host": "localhost",
"port": 8080,
})
L.SetGlobal("config")
L.DoString(`print(config.host .. ":" .. config.port)`)
}
Output: localhost:8080
func (*State) NewThread ¶
NewThread creates a new Lua thread (coroutine), pushes it onto the stack, and returns a *State representing the new thread.
func (*State) NewUserdata ¶
NewUserdata creates a new full userdata with nUV user values and pushes it onto the stack. The size parameter is ignored (Go manages memory). Returns a handle that can be used with SetUserdataValue.
func (*State) Next ¶
Next pops a key and pushes the next key–value pair from the table at idx. Returns false when the traversal is complete (nothing pushed).
func (*State) OptInteger ¶
OptInteger returns the integer at idx, or def if the argument is nil/absent.
func (*State) OptNumber ¶
OptNumber returns the number at idx, or def if the argument is nil/absent.
func (*State) OptString ¶
OptString returns the string at idx, or def if the argument is nil/absent.
func (*State) PCall ¶
PCall calls a function in protected mode. Returns a status code: OK on success, or an error code. If msgHandler is non-zero, it is the stack index of a message handler.
func (*State) PrepareReload ¶ added in v0.8.0
func (L *State) PrepareReload(moduleName string) (*ReloadPlan, error)
PrepareReload compiles and loads new module code, creating a reload plan. This is Phase 1 of the two-phase commit — the old module table remains in package.loaded and no function replacements occur until Commit().
IMPORTANT: This method executes the new module's initialization code via require(). Any side effects in the module's init code (global writes, I/O, registry modifications, etc.) will persist even if Abort() is called afterward. Only the function replacement step is deferred to Commit().
Returns error if the module is not loaded or compilation/loading fails. On failure, the old module is fully restored in package.loaded.
func (*State) PushAny ¶
PushAny pushes any Go value onto the Lua stack, automatically selecting the appropriate Lua type:
Go type → Lua type nil → nil bool → boolean int, int8..int64 → integer uint, uint8..uint64 → integer (or number if > math.MaxInt64) float32, float64 → number string → string []byte → string []T → table (array, 1-indexed) map[string]T → table (hash) map[K]V → table (hash, keys converted via fmt.Sprint) Function → function struct → table (exported fields, using `lua` tag or lowercase name) *struct → same as struct (dereferences pointer) StackRef → copies stack value at ref.Index (via PushValue) any other → light userdata
Nested values are handled recursively.
Example ¶
package main
import (
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
// Push a Go map as a Lua table.
L.PushAny(map[string]any{
"name": "Alice",
"age": 30,
})
L.SetGlobal("user")
L.DoString(`print(user.name, user.age)`)
}
Output: Alice 30
func (*State) PushBoolean ¶
PushBoolean pushes a boolean value onto the stack.
func (*State) PushCloseableResource ¶ added in v0.9.9
PushCloseableResource pushes a Go resource with both __gc AND __close support. This allows Lua 5.5's <close> syntax:
local conn <close> = db.open(...) -- conn:close() called automatically when leaving scope
Also has __gc as a safety net if <close> is not used.
func (*State) PushClosure ¶
PushClosure pushes a Go function as a closure with n upvalues. The upvalues must be on the stack before calling this function.
func (*State) PushFString ¶
PushFString pushes a formatted string onto the stack and returns it.
func (*State) PushFail ¶
func (L *State) PushFail()
PushFail pushes a "fail" value (nil in Lua 5.5).
func (*State) PushFunction ¶
PushFunction pushes a Go function as a light C function (no upvalues).
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
add := func(L *lua.State) int {
a := L.CheckInteger(1)
b := L.CheckInteger(2)
L.PushInteger(a + b)
return 1
}
L.PushFunction(add)
L.SetGlobal("add")
L.DoString(`result = add(10, 32)`)
L.GetGlobal("result")
val, _ := L.ToInteger(-1)
fmt.Println(val)
}
Output: 42
func (*State) PushGlobalTable ¶
func (L *State) PushGlobalTable()
PushGlobalTable pushes the global table onto the stack.
func (*State) PushGoFunc ¶
PushGoFunc pushes an arbitrary Go function onto the Lua stack as a Lua-callable function. Parameters are read from the Lua stack via reflection and return values are pushed back automatically.
Supported parameter types: string, bool, int/int8/../int64, uint/uint8/../uint64, float32/float64, map[string]any, []any, any (interface{}), structs (via ToStruct), *struct.
Supported return types: same as parameters, plus error. If the last return is error and non-nil, a Lua error is raised. If the last return is error and nil, it is not pushed.
If Lua passes fewer args than the function expects, missing parameters receive their Go zero value.
Example:
L.PushGoFunc(func(name string, age int) string {
return fmt.Sprintf("Hello %s, age %d", name, age)
})
L.SetGlobal("greet")
// Lua: greet("world", 42) → "Hello world, age 42"
Example ¶
package main
import (
"strings"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
// Register a Go function — no manual stack manipulation needed.
L.PushGoFunc(func(name string, times int) string {
return strings.Repeat(name+" ", times)
})
L.SetGlobal("repeat_name")
L.DoString(`print(repeat_name("hello", 3))`)
}
Output: hello hello hello
Example (Error) ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.PushGoFunc(func(n int) (int, error) {
if n < 0 {
return 0, fmt.Errorf("negative number: %d", n)
}
return n * n, nil
})
L.SetGlobal("square")
L.DoString(`
print(square(5))
local ok, err = pcall(square, -3)
print(ok, err)
`)
}
Output: 25 false negative number: -3
func (*State) PushInteger ¶
PushInteger pushes an integer value onto the stack.
func (*State) PushLightUserdata ¶
func (L *State) PushLightUserdata(p interface{})
PushLightUserdata pushes a light userdata (Go value without metatable support).
func (*State) PushNumber ¶
PushNumber pushes a floating-point number onto the stack.
func (*State) PushResource ¶ added in v0.9.9
PushResource pushes a Go resource as userdata with a __gc metamethod. When Lua's GC collects this userdata, the resource's Close() is called. This prevents Go resource leaks when Lua code forgets to close explicitly.
The metatable is named "go.resource" and provides:
- __gc: calls resource.Close()
- close: explicit close (idempotent)
Example:
conn := db.Open(...)
L.PushResource(conn)
L.SetGlobal("conn")
// conn.Close() will be called when GC collects it or Lua calls conn:close()
func (*State) PushString ¶
PushString pushes a string onto the stack and returns it.
func (*State) PushThread ¶
PushThread pushes the running thread onto its own stack. Returns true if the thread is the main thread.
func (*State) PushUserdata ¶
PushUserdata creates a new full userdata wrapping a Go value and pushes it onto the stack. This is a convenience wrapper around NewUserdata + SetUserdataValue for the common case of storing a single Go value.
func (*State) RawGet ¶
RawGet pushes t[k] without invoking metamethods. t is at idx, k is at top. Pops the key.
func (*State) RawGetP ¶
RawGetP does t[p] where p is a light userdata pointer key. Pushes the result. Returns the type of the result. Mirrors: lua_rawgetp in lapi.c
func (*State) RawSet ¶
RawSet does t[k] = v without invoking metamethods. t is at idx, k at top-1, v at top. Pops key and value.
func (*State) RawSetI ¶
RawSetI does t[n] = v without invoking metamethods. t is at idx, v at top. Pops the value.
func (*State) RawSetP ¶
RawSetP does t[p] = v where p is a light userdata pointer key. v is the value at the top of the stack (popped). Mirrors: lua_rawsetp in lapi.c
func (*State) Ref ¶
Ref creates a reference in the table at idx. Pops the top value and stores it, returning an integer key. If the value is nil, returns RefNil and pops without storing.
func (*State) ReloadModule ¶ added in v0.8.0
func (L *State) ReloadModule(name string) (*ReloadResult, error)
ReloadModule is a convenience function that prepares and commits in one step. If preparation fails, returns error (no state modified). Incompatible functions are skipped (partial update).
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
// Load initial module
L.DoString(`
package.preload["mymod"] = function()
local M = {}
local count = 0
function M.inc() count = count + 1; return count end
function M.get() return count end
return M
end
`)
L.DoString(`
local m = require("mymod")
m.inc(); m.inc(); m.inc()
`)
// Update module (inc now adds 10)
L.DoString(`
package.preload["mymod"] = function()
local M = {}
local count = 0
function M.inc() count = count + 10; return count end
function M.get() return count end
return M
end
`)
result, _ := L.ReloadModule("mymod")
fmt.Printf("replaced: %d\n", result.Replaced)
// State preserved, new behavior active
L.DoString(`
local m = require("mymod")
print("count:", m.get()) -- preserved: 3
m.inc()
print("after inc:", m.get()) -- 3 + 10 = 13
`)
}
Output: replaced: 2 count: 3 after inc: 13
func (*State) Require ¶
Require loads a module. If the module is already in package.loaded, pushes the cached value. Otherwise calls openf to load it. If global is true, also sets it as a global.
func (*State) ResetCPUCounter ¶
func (L *State) ResetCPUCounter()
ResetCPUCounter resets the instruction counter to 0 without changing the limit. This is useful when reusing a state across multiple script executions so that each execution starts with a fresh budget.
func (*State) Resume ¶
Resume starts or resumes a coroutine. from is the calling coroutine (or nil). Returns (status, nresults). Status is OK when finished, or Yield when suspended.
func (*State) SafeCall ¶ added in v0.9.9
SafeCall calls the function at the top of the stack in protected mode. Unlike PCall, it automatically:
- Uses debug.traceback as the message handler (full Lua stack trace on error)
- Recovers from Go panics in the called function (converts to Lua error)
On success, returns nil and leaves nResults on the stack. On error, returns an error with the full Lua traceback and pops the error message.
Example:
L.GetGlobal("myfunction")
L.PushString("arg1")
err := L.SafeCall(1, 0)
if err != nil {
log.Printf("Lua error:\n%s", err)
}
func (*State) SafeCallFunc ¶ added in v0.9.9
SafeCallFunc is a convenience that pushes a Go function, calls it with SafeCall, and returns any error. Useful for calling Go functions that might panic.
Example:
err := L.SafeCallFunc(func(L *lua.State) int {
// This might panic
result := riskyOperation()
L.PushAny(result)
return 1
}, 0)
func (*State) SetCPULimit ¶
SetCPULimit sets the maximum number of Lua VM instructions this state may execute. When the limit is reached the currently running Lua code receives a Lua error: "CPU limit exceeded: <limit> instructions".
Set limit=0 to remove the CPU limit and clear the count hook installed by a previous call (unless a context is still active via State.SetContext, in which case the context-only hook remains).
Internally this uses the debug hook mechanism with MaskCount. Setting a CPU limit will override any previously set count hook. Line and call hooks set via State.SetHook are NOT affected — only the count component changes.
When used together with State.SetContext, both checks are combined into a single hook for efficiency.
Example:
L.SetCPULimit(1_000_000) // allow at most ~1 million instructions err := L.DoString(`while true do end`) // will error
func (*State) SetContext ¶
SetContext associates a Go context.Context with this Lua state. When the context is cancelled or times out, the currently running Lua code receives a Lua error: "context cancelled: <reason>".
Internally this uses the debug hook mechanism with MaskCount, the same mechanism used by State.SetCPULimit. The combined hook checks both context cancellation and CPU limits on every interval (default 1000 instructions). Setting a context will reinstall the hook to include the context check; any previously set count hook is replaced.
Pass nil to remove the context association and its hook (unless a CPU limit is still active, in which case the CPU-only hook remains).
Example:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() L.SetContext(ctx) err := L.DoString(`while true do end`) // will error after ~5 seconds
func (*State) SetField ¶
SetField does t[key] = v where t is at idx and v is at the top of the stack. Pops the value.
func (*State) SetFields ¶
SetFields sets multiple fields on the table at idx. Values are pushed using PushAny (supports all Go types). Equivalent to calling PushAny(v); SetField(idx, k) for each entry.
func (*State) SetFileSystem ¶
SetFileSystem sets a custom fs.FS for Lua file operations. When set, State.LoadFile, State.DoFile, and the package.searchers Lua-file searcher will read from this FS instead of the real filesystem.
This enables loading Lua scripts from Go's embed.FS, in-memory filesystems, or any other fs.FS implementation:
//go:embed lua/*
var luaFS embed.FS
sub, _ := fs.Sub(luaFS, "lua")
L.SetFileSystem(sub)
L.DoString(`require("mymodule")`) // loads from embedded FS
Set to nil to revert to the real OS filesystem (default).
func (*State) SetFuncs ¶
SetFuncs registers functions from a map into the table at the top of the stack. nUp is the number of upvalues (must be on the stack above the table).
func (*State) SetGCParam ¶
SetGCParam sets a GC parameter and returns the previous value.
func (*State) SetGCStopped ¶
SetGCStopped sets or clears the GC stopped flag.
func (*State) SetHook ¶
SetHook sets the debug hook function with the given mask and count. mask is a combination of MaskCall, MaskRet, MaskLine, MaskCount. count is the instruction count for count hooks (0 to disable count hooks). Pass nil as f to remove the current hook.
Example:
L.SetHook(func(L *lua.State, event int, line int) {
if event == lua.HookEventLine {
fmt.Printf("executing line %d\n", line)
}
}, lua.MaskLine, 0)
func (*State) SetHookFields ¶
SetHookFields sets the hook mask and count on the state. Deprecated: Use State.SetHook instead for a complete hook API.
func (*State) SetHookMarker ¶
func (L *State) SetHookMarker()
SetHookMarker sets a non-nil marker to indicate hooks are active. Deprecated: Use State.SetHook instead.
func (*State) SetI ¶
SetI does t[n] = v where t is at idx and v is at the top of the stack. Pops the value.
func (*State) SetIUserValue ¶
SetIUserValue sets the n-th user value of the userdata at idx to the value at the top of the stack. Pops the value. Returns false if the operation fails.
func (*State) SetLocal ¶
SetLocal sets the value of local variable n from the top of the stack. Returns the variable name, or "" if not found.
func (*State) SetMemoryLimit ¶
SetMemoryLimit sets the maximum memory (in bytes) that Lua objects can use. 0 means no limit. Returns the previous limit. When the limit is exceeded, Lua code receives an "out of memory" error that can be caught by pcall/xpcall.
func (*State) SetMetatable ¶
SetMetatable pops a table from the stack and sets it as the metatable of the value at idx.
func (*State) SetTable ¶
SetTable does t[k] = v where t is at idx, k is at top-1, v is at top. Pops both the key and value. May trigger __newindex metamethod.
func (*State) SetTop ¶
SetTop sets the stack top to idx. If the new top is larger than the old one, new elements are filled with nil. If idx is 0, all stack elements are removed.
func (*State) SetUpvalue ¶
SetUpvalue sets upvalue n of the closure at funcIdx from the top of the stack. Returns (name, true) if the upvalue exists, ("", false) otherwise.
func (*State) SetUserValue ¶
SetUserValue stores an arbitrary Go value associated with the given key. This allows embedding applications to attach per-State data without global variables. Keys are arbitrary strings. Values can be any Go type. The value is stored on the internal State and survives wrapFunction.
func (*State) SetUserdataValue ¶
SetUserdataValue sets the Go value stored in the full userdata at idx.
func (*State) SetWarnF ¶
func (L *State) SetWarnF(f WarnFunction, ud interface{})
SetWarnF sets the warning handler function. Mirrors: lua_setwarnf in lapi.c
func (*State) SetWriter ¶
SetWriter sets a custom writer for Lua print() and io.write() output. If w is nil, output reverts to os.Stdout (the default). The writer is stored on the internal api.State so it survives wrapFunction which creates fresh pkg/lua.State wrappers sharing the same api.State.
func (*State) StringToNumber ¶
StringToNumber tries to convert a string to a number and pushes it. Returns the string length + 1 on success, 0 on failure.
func (*State) TestUdata ¶
TestUdata checks if the value at idx is a userdata with metatable matching registry[tname]. Returns true if it matches.
func (*State) ToAny ¶
ToAny reads the value at the given stack index and returns it as a Go value:
Lua type → Go type
nil → nil (interface{})
boolean → bool
integer → int64
number → float64
string → string
table → []any (sequential integer keys 1..n) or map[string]any
userdata → the stored Go value (via [State.UserdataValue])
function → nil (cannot convert)
thread → nil (cannot convert)
Table detection: if the table has exactly n entries and all keys are integers 1..n, it is returned as []any. Otherwise it is returned as map[string]any with non-string keys converted via strconv or fmt.
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
L.DoString(`t = {name = "Bob", score = 95}`)
L.GetGlobal("t")
val := L.ToAny(-1)
m := val.(map[string]any)
fmt.Println(m["name"], m["score"])
L.Pop(1)
}
Output: Bob 95
func (*State) ToBoolean ¶
ToBoolean converts the value at idx to a boolean. Returns false for nil and false, true for everything else.
func (*State) ToClose ¶
ToClose marks the value at the given index as a to-be-closed variable. Like a local variable declared with <close>, the value's __close metamethod will be called when it goes out of scope. Mirrors: lua_toclose in lapi.c
func (*State) ToInteger ¶
ToInteger converts the value at idx to an integer. Returns (value, true) on success, (0, false) if the value is not an integer or a float with an exact integer representation.
func (*State) ToMap ¶
ToMap reads the value at idx as a map[string]any. Returns (map, true) if the value is a table with string keys, (nil, false) otherwise (including pure-array tables or non-table values). This is a typed convenience wrapper around ToAny for the common case.
func (*State) ToNumber ¶
ToNumber converts the value at idx to a floating-point number. Returns (value, true) on success, (0, false) if not convertible.
func (*State) ToPointer ¶
ToPointer returns a string representation of the pointer value at idx. Useful for debugging.
func (*State) ToString ¶
ToString converts the value at idx to a string. Returns (value, true) for strings and numbers (coerced in place), ("", false) for other types.
func (*State) ToStruct ¶
ToStruct reads a Lua table at the given stack index into a Go struct. The dest argument must be a non-nil pointer to a struct.
Field mapping uses the `lua` struct tag if present, otherwise the field name with its first letter lowercased. Fields tagged with `lua:"-"` are skipped. Unexported fields are always skipped.
Supported field types: string, bool, all int/uint/float variants, and nested slices/maps (via State.ToAny).
Example:
type Config struct {
Host string `lua:"host"`
Port int64 `lua:"port"`
Debug bool `lua:"debug"`
}
var cfg Config
err := L.ToStruct(-1, &cfg)
Example ¶
package main
import (
"fmt"
"github.com/akzj/go-lua/pkg/lua"
)
func main() {
L := lua.NewState()
defer L.Close()
type Config struct {
Host string `lua:"host"`
Port int `lua:"port"`
}
L.DoString(`config = {host = "localhost", port = 8080}`)
L.GetGlobal("config")
var cfg Config
L.ToStruct(-1, &cfg)
fmt.Println(cfg.Host, cfg.Port)
L.Pop(1)
}
Output: localhost 8080
func (*State) ToThread ¶
ToThread converts the value at idx to a *State (thread). Returns nil if the value is not a thread.
func (*State) TolString ¶
TolString converts the value at idx to a string, using __tostring metamethod if present. Pushes the result and returns it.
func (*State) TypeError ¶
TypeError raises a type error for argument arg. This function does not return.
func (*State) UpvalueId ¶
UpvalueId returns a unique identifier for upvalue n of the closure at funcIdx.
func (*State) UpvalueJoin ¶
UpvalueJoin makes the n1-th upvalue of funcIdx1 refer to n2-th of funcIdx2.
func (*State) UserValue ¶
UserValue retrieves a Go value previously stored with SetUserValue. Returns nil if the key was never set.
func (*State) UserdataValue ¶
UserdataValue returns the Go value stored in the userdata at idx. Returns nil if the value is not a full userdata or light userdata.
func (*State) Warning ¶
Warning emits a warning message. If tocont is true, the message is to be continued by the next call to Warning. Mirrors: lua_warning in lapi.c
type StatePool ¶
type StatePool struct {
// contains filtered or unexported fields
}
StatePool manages a pool of reusable Lua State values.
Thread-safe: StatePool.Get and StatePool.Put can be called from any goroutine. Each State returned by Get is exclusively owned by the caller until Put is called — States are never shared between goroutines.
func NewStatePool ¶
func NewStatePool(config PoolConfig) *StatePool
NewStatePool creates a new State pool with the given configuration.
func (*StatePool) Close ¶
func (p *StatePool) Close()
Close closes all States in the pool and prevents further use. After Close, StatePool.Get will still create new States, but StatePool.Put will close them immediately.
func (*StatePool) Get ¶
Get retrieves a State from the pool, or creates a new one if the pool is empty. The returned State is exclusively owned by the caller until StatePool.Put is called.
type Task ¶
type Task struct {
// ID identifies this task (for correlating results).
ID string
// Code is the Lua source code to execute.
// Either Code or Func must be set (not both).
Code string
// Func is a function to run with a Lua State.
// Use this for complex operations that need direct State access.
// Either Code or Func must be set (not both).
Func func(L *State) (any, error)
}
Task represents a unit of Lua work to be executed asynchronously by an Executor.
type Timer ¶
type Timer struct {
ID int64
Interval time.Duration
Repeat bool
Callback int // Lua registry reference to the callback function
NextFire time.Time
Canceled bool
}
Timer represents a scheduled timer managed by TimerManager.
type TimerManager ¶
type TimerManager struct {
// contains filtered or unexported fields
}
TimerManager manages all active timers for a Lua State. NOT thread-safe for Tick (must be called from the same goroutine as Lua). The mutex protects cancel operations which may come from any goroutine.
func GetTimerManager ¶
func GetTimerManager(L *State) *TimerManager
GetTimerManager returns the TimerManager for a State, creating one if needed. This is the public API for host applications that need to call Tick() in their event loop.
func NewTimerManager ¶
func NewTimerManager() *TimerManager
NewTimerManager creates a new TimerManager.
func (*TimerManager) Add ¶
func (tm *TimerManager) Add(t *Timer) int64
Add registers a timer and returns its ID.
func (*TimerManager) Cancel ¶
func (tm *TimerManager) Cancel(id int64)
Cancel marks a timer as canceled.
func (*TimerManager) Pending ¶
func (tm *TimerManager) Pending() int
Pending returns the number of active (non-canceled) timers.
func (*TimerManager) Tick ¶
func (tm *TimerManager) Tick(L *State) int
Tick checks all timers and fires expired ones. Calls the Lua callback for each expired timer via PCall. Must be called from the same goroutine that owns the Lua State. Returns the number of remaining active timers.
type Type ¶
type Type int
Type represents a Lua value type, corresponding to the LUA_T* constants in the C Lua API.
const ( TypeNil Type = 0 // LUA_TNIL — the nil value TypeBoolean Type = 1 // LUA_TBOOLEAN — true or false TypeLightUserdata Type = 2 // LUA_TLIGHTUSERDATA — raw Go interface{} without metatable TypeNumber Type = 3 // LUA_TNUMBER — integer or floating-point number TypeString Type = 4 // LUA_TSTRING — immutable string TypeTable Type = 5 // LUA_TTABLE — associative array TypeFunction Type = 6 // LUA_TFUNCTION — Lua or Go function TypeUserdata Type = 7 // LUA_TUSERDATA — full userdata with metatable support TypeThread Type = 8 // LUA_TTHREAD — coroutine TypeNone Type = -1 // LUA_TNONE — invalid or absent stack index )
Lua value types. These match the C Lua LUA_T* constants.
type WarnFunction ¶
WarnFunction is the type for warning handler functions.
Source Files
¶
- async.go
- async_lib.go
- async_scheduler.go
- autobind.go
- auxiliary.go
- bridge.go
- call.go
- channel.go
- channel_lib.go
- context.go
- convenience.go
- coroutine.go
- debug.go
- doc.go
- executor.go
- filesystem.go
- gc.go
- hotreload.go
- hotreload_lib.go
- http.go
- json.go
- module.go
- pool.go
- reftrack.go
- registry.go
- resource.go
- safecall.go
- sandbox_cpu.go
- sandbox_factory.go
- state.go
- table.go
- timer_lib.go
- types.go
- userdata.go
- values.go
- wrappers.go