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

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