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