LuaJIT-to-Go/DOCS.md
2025-02-26 07:00:01 -06:00

425 lines
8.7 KiB
Markdown

# LuaJIT Go Wrapper API Documentation
## State Management
### New() *State
Creates a new Lua state with all standard libraries loaded.
```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
```
### 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
```
### 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
```
### 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.
```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
}
```
### 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.
```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
}
```
### GetTableLength(index int) int
Returns the length of a table at the given index.
```go
length := L.GetTableLength(-1)
```
## 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)
```
## Table Operations
### CreateTable(narr, nrec int)
Creates a new table with pre-allocated space.
```go
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 {
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.
```go
err := L.RegisterGoFunction("add", adder)
```
### UnregisterGoFunction(name string)
Removes a previously registered function.
```go
L.UnregisterGoFunction("add")
```
### 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
```
## Global Operations
### GetGlobal(name string)
Gets a global variable and pushes it onto the stack.
```go
L.GetGlobal("myGlobal")
```
### SetGlobal(name string)
Sets a global variable from the value at the top of the stack.
```go
L.PushNumber(42)
L.SetGlobal("answer") // answer = 42
```
## Code Execution
### 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
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")
```
### 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
```
### ExecuteWithResult(code string) (interface{}, error)
Executes a Lua string and returns the first result.
```go
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.
```go
bytecode, err := L.CompileBytecode("return 42", "test")
```
### LoadBytecode(bytecode []byte, name string) error
Loads precompiled bytecode without executing it.
```go
err := L.LoadBytecode(bytecode, "test")
```
### RunBytecode() error
Executes previously loaded bytecode with 0 results.
```go
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")
```
## Error Handling
### LuaError
Error type containing both an error code and message.
```go
type LuaError struct {
Code int
Message string
}
```
### GetStackTrace() string
Gets the current Lua stack trace.
```go
trace := L.GetStackTrace()
fmt.Println(trace)
```
### 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)
})
```
## 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
L := luajit.New()
defer L.Close()
defer L.Cleanup()
```
Stack management requires manual attention:
```go
L.PushString("hello")
// ... use the string
L.Pop(1) // Clean up when done
```