8.7 KiB
LuaJIT Go Wrapper API Documentation
State Management
New() *State
Creates a new Lua state with all standard libraries loaded.
L := luajit.New()
defer L.Close()
defer L.Cleanup()
Close()
Closes the Lua state and frees associated resources.
L.Close()
Cleanup()
Cleans up the function registry and other internal resources.
L.Cleanup()
Stack Operations
GetTop() int
Returns the index of the top element in the stack.
top := L.GetTop() // 0 for empty stack
SetTop(index int)
Sets the stack top to a specific index.
L.SetTop(2) // Truncate stack to 2 elements
PushCopy(index int)
Pushes a copy of the value at the given index onto the stack.
L.PushCopy(-1) // Duplicate the top element
Pop(n int)
Removes n elements from the stack.
L.Pop(1) // Remove top element
L.Pop(2) // Remove top two elements
Remove(index int)
Removes the element at the given index.
L.Remove(-1) // Remove top element
L.Remove(1) // Remove first element
absIndex(index int) int
Internal function that converts a possibly negative index to its absolute position.
checkStack(n int) error
Internal function that ensures there's enough space for n new elements.
if err := L.checkStack(2); err != nil {
return err
}
Type Checks
GetType(index int) LuaType
Returns the type of the value at the given index.
if L.GetType(-1) == TypeString {
// Handle string
}
IsNil(index int) bool
IsBoolean(index int) bool
IsNumber(index int) bool
IsString(index int) bool
IsTable(index int) bool
IsFunction(index int) bool
Type checking functions for specific Lua types.
if L.IsTable(-1) {
table, err := L.ToTable(-1)
}
Value Retrieval
ToString(index int) string
Converts the value at the given index to a string.
str := L.ToString(-1)
ToNumber(index int) float64
Converts the value to a number.
num := L.ToNumber(-1)
ToBoolean(index int) bool
Converts the value to a boolean.
bool := L.ToBoolean(-1)
ToValue(index int) (interface{}, error)
Converts any Lua value to its Go equivalent.
val, err := L.ToValue(-1)
if err != nil {
return err
}
ToTable(index int) (map[string]interface{}, error)
Converts a Lua table to a Go map.
table, err := L.ToTable(-1)
if err != nil {
return nil, err
}
GetTableLength(index int) int
Returns the length of a table at the given index.
length := L.GetTableLength(-1)
Value Pushing
PushNil()
PushBoolean(b bool)
PushNumber(n float64)
PushString(str string)
Basic value pushing functions.
L.PushString("hello")
L.PushNumber(42)
L.PushBoolean(true)
L.PushNil()
PushValue(v interface{}) error
Pushes any Go value onto the stack.
err := L.PushValue(myValue)
PushTable(table map[string]interface{}) error
Pushes a Go map as a Lua table.
data := map[string]interface{}{
"key": "value",
"numbers": []float64{1, 2, 3},
}
err := L.PushTable(data)
Table Operations
CreateTable(narr, nrec int)
Creates a new table with pre-allocated space.
L.CreateTable(10, 5) // Space for 10 array elements, 5 records
NewTable()
Creates a new empty table and pushes it onto the stack.
L.NewTable()
GetTable(index int)
Gets a table field (t[k]) where t is at the given index and k is at the top of the stack.
L.PushString("key")
L.GetTable(-2) // Gets table["key"]
SetTable(index int)
Sets a table field (t[k] = v) where t is at the given index, k is at -2, and v is at -1.
L.PushString("key")
L.PushString("value")
L.SetTable(-3) // table["key"] = "value"
GetField(index int, key string)
Gets a table field t[k] and pushes it onto the stack.
L.GetField(-1, "name") // gets table.name
SetField(index int, key string)
Sets a table field t[k] = v, where v is the value at the top of the stack.
L.PushString("value")
L.SetField(-2, "key") // table.key = "value"
Next(index int) bool
Pops a key from the stack and pushes the next key-value pair from the table.
L.PushNil() // Start iteration
for L.Next(-2) {
// Stack now has key at -2 and value at -1
key := L.ToString(-2)
value := L.ToString(-1)
L.Pop(1) // Remove value, keep key for next iteration
}
Function Registration and Calling
GoFunction
Type definition for Go functions callable from Lua.
type GoFunction func(*State) int
PushGoFunction(fn GoFunction) error
Wraps a Go function and pushes it onto the Lua stack.
adder := func(s *luajit.State) int {
sum := s.ToNumber(1) + s.ToNumber(2)
s.PushNumber(sum)
return 1
}
err := L.PushGoFunction(adder)
RegisterGoFunction(name string, fn GoFunction) error
Registers a Go function as a global Lua function.
err := L.RegisterGoFunction("add", adder)
UnregisterGoFunction(name string)
Removes a previously registered function.
L.UnregisterGoFunction("add")
Call(nargs, nresults int) error
Calls a function with the given number of arguments and results.
L.GetGlobal("myfunction")
L.PushNumber(1)
L.PushNumber(2)
err := L.Call(2, 1) // Call with 2 args, expect 1 result
Global Operations
GetGlobal(name string)
Gets a global variable and pushes it onto the stack.
L.GetGlobal("myGlobal")
SetGlobal(name string)
Sets a global variable from the value at the top of the stack.
L.PushNumber(42)
L.SetGlobal("answer") // answer = 42
Code Execution
LoadString(code string) error
Loads a Lua chunk from a string without executing it.
err := L.LoadString("return 42")
LoadFile(filename string) error
Loads a Lua chunk from a file without executing it.
err := L.LoadFile("script.lua")
DoString(code string) error
Executes a string of Lua code.
err := L.DoString(`
local x = 40
local y = 2
result = x + y
`)
DoFile(filename string) error
Executes a Lua file.
err := L.DoFile("script.lua")
Execute(code string) (int, error)
Executes a Lua string and returns the number of results left on the stack.
nresults, err := L.Execute("return 1, 2, 3")
// nresults would be 3
ExecuteWithResult(code string) (interface{}, error)
Executes a Lua string and returns the first result.
result, err := L.ExecuteWithResult("return 'hello'")
// result would be "hello"
Bytecode Operations
CompileBytecode(code string, name string) ([]byte, error)
Compiles a Lua chunk to bytecode without executing it.
bytecode, err := L.CompileBytecode("return 42", "test")
LoadBytecode(bytecode []byte, name string) error
Loads precompiled bytecode without executing it.
err := L.LoadBytecode(bytecode, "test")
RunBytecode() error
Executes previously loaded bytecode with 0 results.
err := L.RunBytecode()
RunBytecodeWithResults(nresults int) error
Executes bytecode and keeps nresults on the stack.
err := L.RunBytecodeWithResults(1)
LoadAndRunBytecode(bytecode []byte, name string) error
Loads and executes bytecode.
err := L.LoadAndRunBytecode(bytecode, "test")
LoadAndRunBytecodeWithResults(bytecode []byte, name string, nresults int) error
Loads and executes bytecode, preserving results.
err := L.LoadAndRunBytecodeWithResults(bytecode, "test", 1)
CompileAndRun(code string, name string) error
Compiles and immediately executes Lua code.
err := L.CompileAndRun("answer = 42", "test")
Package Path Operations
SetPackagePath(path string) error
Sets the Lua package.path.
err := L.SetPackagePath("./?.lua;/usr/local/share/lua/5.1/?.lua")
AddPackagePath(path string) error
Adds a path to package.path.
err := L.AddPackagePath("./modules/?.lua")
Error Handling
LuaError
Error type containing both an error code and message.
type LuaError struct {
Code int
Message string
}
GetStackTrace() string
Gets the current Lua stack trace.
trace := L.GetStackTrace()
fmt.Println(trace)
safeCall(f func() C.int) error
Internal function that wraps a potentially dangerous C call with stack checking.
err := s.safeCall(func() C.int {
return C.lua_pcall(s.L, C.int(nargs), C.int(nresults), 0)
})
Thread Safety Notes
- The function registry is thread-safe
- Individual Lua states are not thread-safe
- Create separate states for concurrent operations
- Use the function registry to share functions between states
Memory Management
Always pair state creation with cleanup:
L := luajit.New()
defer L.Close()
defer L.Cleanup()
Stack management requires manual attention:
L.PushString("hello")
// ... use the string
L.Pop(1) // Clean up when done