Compare commits
No commits in common. "c22638b51f1801140bc1d41387188064406f5fd6" and "f4bfff470f7e5effa919ee7173a61a6eade2d1d2" have entirely different histories.
c22638b51f
...
f4bfff470f
82
API.md
82
API.md
@ -1,82 +0,0 @@
|
|||||||
# API Quick Reference
|
|
||||||
|
|
||||||
## Core State
|
|
||||||
- New(openLibs ...bool) *State
|
|
||||||
- Close()
|
|
||||||
- Cleanup()
|
|
||||||
|
|
||||||
## Stack
|
|
||||||
- GetTop() int
|
|
||||||
- SetTop(index int)
|
|
||||||
- Pop(n int)
|
|
||||||
- PushCopy(index int)
|
|
||||||
- Remove(index int)
|
|
||||||
|
|
||||||
## Type Checks
|
|
||||||
- GetType(index int) LuaType
|
|
||||||
- IsNil/IsBoolean/IsNumber/IsString/IsTable/IsFunction(index int) bool
|
|
||||||
|
|
||||||
## Values
|
|
||||||
- ToString/ToNumber/ToBoolean(index int) T
|
|
||||||
- ToValue(index int) (any, error)
|
|
||||||
- ToTable(index int) (any, error)
|
|
||||||
- PushNil/PushBoolean/PushNumber/PushString/PushValue()
|
|
||||||
|
|
||||||
## Tables
|
|
||||||
- NewTable()
|
|
||||||
- CreateTable(narr, nrec int)
|
|
||||||
- GetTable/SetTable(index int)
|
|
||||||
- GetField/SetField(index int, key string)
|
|
||||||
- GetFieldString/Number/Bool/Table(index int, key string, default T) T
|
|
||||||
- GetTableLength(index int) int
|
|
||||||
- Next(index int) bool
|
|
||||||
- ForEachTableKV/ForEachArray(index int, fn func)
|
|
||||||
- NewTableBuilder() *TableBuilder
|
|
||||||
|
|
||||||
## Functions
|
|
||||||
- RegisterGoFunction(name string, fn GoFunction) error
|
|
||||||
- UnregisterGoFunction(name string)
|
|
||||||
- PushGoFunction(fn GoFunction) error
|
|
||||||
- Call(nargs, nresults int) error
|
|
||||||
- CallGlobal(name string, args ...any) ([]any, error)
|
|
||||||
|
|
||||||
## Globals
|
|
||||||
- GetGlobal/SetGlobal(name string)
|
|
||||||
|
|
||||||
## Execution
|
|
||||||
- LoadString/LoadFile(source string) error
|
|
||||||
- DoString/DoFile(source string) error
|
|
||||||
- Execute(code string) (int, error)
|
|
||||||
- ExecuteWithResult(code string) (any, error)
|
|
||||||
- BatchExecute(statements []string) error
|
|
||||||
|
|
||||||
## Bytecode
|
|
||||||
- CompileBytecode(code, name string) ([]byte, error)
|
|
||||||
- LoadBytecode(bytecode []byte, name string) error
|
|
||||||
- RunBytecode() error
|
|
||||||
- RunBytecodeWithResults(nresults int) error
|
|
||||||
- LoadAndRunBytecode(bytecode []byte, name string) error
|
|
||||||
- LoadAndRunBytecodeWithResults(bytecode []byte, name string, nresults int) error
|
|
||||||
- CompileAndRun(code, name string) error
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
- CheckArgs(specs ...ArgSpec) error
|
|
||||||
- CheckMinArgs/CheckExactArgs(n int) error
|
|
||||||
- SafeToString/Number/Table(index int) (T, error)
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
- PushError(format string, args ...any) int
|
|
||||||
- GetStackTrace() string
|
|
||||||
- GetErrorInfo(context string) *LuaError
|
|
||||||
- CreateLuaError(code int, context string) *LuaError
|
|
||||||
|
|
||||||
## Package
|
|
||||||
- SetPackagePath/AddPackagePath(path string) error
|
|
||||||
|
|
||||||
## Metatable
|
|
||||||
- SetMetatable(index int)
|
|
||||||
- GetMetatable(index int) bool
|
|
||||||
|
|
||||||
## Constants
|
|
||||||
- TypeNil/Boolean/Number/String/Table/Function/UserData/Thread
|
|
||||||
- LUA_MINSTACK/MAXSTACK/REGISTRYINDEX/GLOBALSINDEX
|
|
155
DOCS.md
155
DOCS.md
@ -56,6 +56,17 @@ L.Remove(-1) // Remove top element
|
|||||||
L.Remove(1) // Remove first 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
|
## Type Checks
|
||||||
|
|
||||||
### GetType(index int) LuaType
|
### GetType(index int) LuaType
|
||||||
@ -100,7 +111,7 @@ bool := L.ToBoolean(-1)
|
|||||||
```
|
```
|
||||||
|
|
||||||
### ToValue(index int) (any, error)
|
### ToValue(index int) (any, error)
|
||||||
Converts any Lua value to its Go equivalent with automatic type detection.
|
Converts any Lua value to its Go equivalent.
|
||||||
```go
|
```go
|
||||||
val, err := L.ToValue(-1)
|
val, err := L.ToValue(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,8 +119,8 @@ if err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### ToTable(index int) (any, error)
|
### ToTable(index int) (map[string]any, error)
|
||||||
Converts a Lua table to optimal Go type ([]int, []string, map[string]any, etc.).
|
Converts a Lua table to a Go map.
|
||||||
```go
|
```go
|
||||||
table, err := L.ToTable(-1)
|
table, err := L.ToTable(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -138,13 +149,19 @@ L.PushNil()
|
|||||||
```
|
```
|
||||||
|
|
||||||
### PushValue(v any) error
|
### PushValue(v any) error
|
||||||
Pushes any Go value onto the stack with comprehensive type support.
|
Pushes any Go value onto the stack.
|
||||||
```go
|
```go
|
||||||
// Supports: primitives, slices, maps with various type combinations
|
err := L.PushValue(myValue)
|
||||||
err := L.PushValue(map[string]any{
|
```
|
||||||
|
|
||||||
|
### PushTable(table map[string]any) error
|
||||||
|
Pushes a Go map as a Lua table.
|
||||||
|
```go
|
||||||
|
data := map[string]any{
|
||||||
"key": "value",
|
"key": "value",
|
||||||
"numbers": []float64{1, 2, 3},
|
"numbers": []float64{1, 2, 3},
|
||||||
})
|
}
|
||||||
|
err := L.PushTable(data)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Table Operations
|
## Table Operations
|
||||||
@ -201,25 +218,6 @@ for L.Next(-2) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### GetFieldString/Number/Bool/Table(index int, key string, default T) T
|
|
||||||
Get typed fields from tables with default values.
|
|
||||||
```go
|
|
||||||
name := L.GetFieldString(-1, "name", "unknown")
|
|
||||||
age := L.GetFieldNumber(-1, "age", 0)
|
|
||||||
active := L.GetFieldBool(-1, "active", false)
|
|
||||||
config, ok := L.GetFieldTable(-1, "config")
|
|
||||||
```
|
|
||||||
|
|
||||||
### ForEachTableKV(index int, fn func(key, value string) bool)
|
|
||||||
### ForEachArray(index int, fn func(i int, state *State) bool)
|
|
||||||
Convenient iteration helpers.
|
|
||||||
```go
|
|
||||||
L.ForEachTableKV(-1, func(key, value string) bool {
|
|
||||||
fmt.Printf("%s: %s\n", key, value)
|
|
||||||
return true // continue iteration
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Function Registration and Calling
|
## Function Registration and Calling
|
||||||
|
|
||||||
### GoFunction
|
### GoFunction
|
||||||
@ -260,12 +258,6 @@ L.PushNumber(2)
|
|||||||
err := L.Call(2, 1) // Call with 2 args, expect 1 result
|
err := L.Call(2, 1) // Call with 2 args, expect 1 result
|
||||||
```
|
```
|
||||||
|
|
||||||
### CallGlobal(name string, args ...any) ([]any, error)
|
|
||||||
Calls a global function with arguments and returns all results.
|
|
||||||
```go
|
|
||||||
results, err := L.CallGlobal("myfunction", 1, 2, "hello")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Global Operations
|
## Global Operations
|
||||||
|
|
||||||
### GetGlobal(name string)
|
### GetGlobal(name string)
|
||||||
@ -325,16 +317,6 @@ result, err := L.ExecuteWithResult("return 'hello'")
|
|||||||
// result would be "hello"
|
// result would be "hello"
|
||||||
```
|
```
|
||||||
|
|
||||||
### BatchExecute(statements []string) error
|
|
||||||
Executes multiple statements as a single batch.
|
|
||||||
```go
|
|
||||||
err := L.BatchExecute([]string{
|
|
||||||
"x = 10",
|
|
||||||
"y = 20",
|
|
||||||
"result = x + y",
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bytecode Operations
|
## Bytecode Operations
|
||||||
|
|
||||||
### CompileBytecode(code string, name string) ([]byte, error)
|
### CompileBytecode(code string, name string) ([]byte, error)
|
||||||
@ -393,35 +375,14 @@ Adds a path to package.path.
|
|||||||
err := L.AddPackagePath("./modules/?.lua")
|
err := L.AddPackagePath("./modules/?.lua")
|
||||||
```
|
```
|
||||||
|
|
||||||
## Metatable Operations
|
|
||||||
|
|
||||||
### SetMetatable(index int)
|
|
||||||
Sets the metatable for the value at the given index.
|
|
||||||
```go
|
|
||||||
L.SetMetatable(-1)
|
|
||||||
```
|
|
||||||
|
|
||||||
### GetMetatable(index int) bool
|
|
||||||
Gets the metatable for the value at the given index.
|
|
||||||
```go
|
|
||||||
if L.GetMetatable(-1) {
|
|
||||||
// Metatable is now on stack
|
|
||||||
L.Pop(1)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
### LuaError
|
### LuaError
|
||||||
Enhanced error type with detailed context information.
|
Error type containing both an error code and message.
|
||||||
```go
|
```go
|
||||||
type LuaError struct {
|
type LuaError struct {
|
||||||
Code int
|
Code int
|
||||||
Message string
|
Message string
|
||||||
File string
|
|
||||||
Line int
|
|
||||||
StackTrace string
|
|
||||||
Context string
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -432,62 +393,12 @@ trace := L.GetStackTrace()
|
|||||||
fmt.Println(trace)
|
fmt.Println(trace)
|
||||||
```
|
```
|
||||||
|
|
||||||
### GetErrorInfo(context string) *LuaError
|
### safeCall(f func() C.int) error
|
||||||
Extracts detailed error information from the Lua stack.
|
Internal function that wraps a potentially dangerous C call with stack checking.
|
||||||
```go
|
```go
|
||||||
err := L.GetErrorInfo("MyFunction")
|
err := s.safeCall(func() C.int {
|
||||||
```
|
return C.lua_pcall(s.L, C.int(nargs), C.int(nresults), 0)
|
||||||
|
})
|
||||||
### CreateLuaError(code int, context string) *LuaError
|
|
||||||
Creates a LuaError with full context information.
|
|
||||||
```go
|
|
||||||
err := L.CreateLuaError(status, "DoString")
|
|
||||||
```
|
|
||||||
|
|
||||||
### PushError(format string, args ...any) int
|
|
||||||
Pushes an error string and returns -1.
|
|
||||||
```go
|
|
||||||
return s.PushError("invalid argument: %v", arg)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
|
|
||||||
### CheckArgs(specs ...ArgSpec) error
|
|
||||||
Validates function arguments against specifications.
|
|
||||||
```go
|
|
||||||
err := s.CheckArgs(
|
|
||||||
ArgSpec{Name: "name", Type: "string", Required: true, Check: CheckString},
|
|
||||||
ArgSpec{Name: "age", Type: "number", Required: false, Check: CheckNumber},
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### CheckMinArgs/CheckExactArgs(n int) error
|
|
||||||
Argument count validation.
|
|
||||||
```go
|
|
||||||
if err := s.CheckMinArgs(2); err != nil {
|
|
||||||
return s.PushError(err.Error())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### SafeToString/Number/Table(index int) (T, error)
|
|
||||||
Safe value conversion with error handling.
|
|
||||||
```go
|
|
||||||
str, err := s.SafeToString(1)
|
|
||||||
if err != nil {
|
|
||||||
return s.PushError(err.Error())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Table Building
|
|
||||||
|
|
||||||
### NewTableBuilder() *TableBuilder
|
|
||||||
Creates a new table builder for fluent table construction.
|
|
||||||
```go
|
|
||||||
L.NewTableBuilder().
|
|
||||||
SetString("name", "John").
|
|
||||||
SetNumber("age", 30).
|
|
||||||
SetBool("active", true).
|
|
||||||
Build()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Thread Safety Notes
|
## Thread Safety Notes
|
||||||
@ -512,3 +423,9 @@ L.PushString("hello")
|
|||||||
// ... use the string
|
// ... use the string
|
||||||
L.Pop(1) // Clean up when done
|
L.Pop(1) // Clean up when done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Sandbox management:
|
||||||
|
```go
|
||||||
|
sandbox := luajit.NewSandbox()
|
||||||
|
defer sandbox.Close()
|
||||||
|
```
|
||||||
|
141
README.md
141
README.md
@ -18,6 +18,8 @@ First, grab the package:
|
|||||||
go get git.sharkk.net/Sky/LuaJIT-to-Go
|
go get git.sharkk.net/Sky/LuaJIT-to-Go
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You'll need LuaJIT's development files, but don't worry - we include libraries for Windows and Linux in the vendor directory.
|
||||||
|
|
||||||
Here's the simplest thing you can do:
|
Here's the simplest thing you can do:
|
||||||
```go
|
```go
|
||||||
L := luajit.New() // pass false to not load standard libs
|
L := luajit.New() // pass false to not load standard libs
|
||||||
@ -49,6 +51,10 @@ for i := 0; i < 1000; i++ {
|
|||||||
err := L.CompileAndRun(`return "hello"`, "greeting")
|
err := L.CompileAndRun(`return "hello"`, "greeting")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### When to Use Bytecode
|
||||||
|
|
||||||
|
Bytecode execution is consistently faster than direct execution:
|
||||||
|
|
||||||
```
|
```
|
||||||
Benchmark Ops/sec Comparison
|
Benchmark Ops/sec Comparison
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
@ -64,6 +70,12 @@ BenchmarkComplexScript 33,133 Base
|
|||||||
BenchmarkComplexScriptPrecompiled 41,044 +23.9% faster
|
BenchmarkComplexScriptPrecompiled 41,044 +23.9% faster
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use bytecode when you:
|
||||||
|
- Have code that runs frequently
|
||||||
|
- Need maximum performance
|
||||||
|
- Want to precompile your Lua code
|
||||||
|
- Are distributing Lua code to many instances
|
||||||
|
|
||||||
## Registering Go Functions
|
## Registering Go Functions
|
||||||
|
|
||||||
Want to call Go code from Lua? It's straightforward:
|
Want to call Go code from Lua? It's straightforward:
|
||||||
@ -83,27 +95,9 @@ Now in Lua:
|
|||||||
result = add(40, 2) -- result = 42
|
result = add(40, 2) -- result = 42
|
||||||
```
|
```
|
||||||
|
|
||||||
### Function Validation
|
|
||||||
|
|
||||||
Validate arguments easily:
|
|
||||||
```go
|
|
||||||
calculator := func(s *luajit.State) int {
|
|
||||||
if err := s.CheckArgs(
|
|
||||||
luajit.ArgSpec{Name: "x", Type: "number", Required: true, Check: luajit.CheckNumber},
|
|
||||||
luajit.ArgSpec{Name: "y", Type: "number", Required: true, Check: luajit.CheckNumber},
|
|
||||||
); err != nil {
|
|
||||||
return s.PushError(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
result := s.ToNumber(1) + s.ToNumber(2)
|
|
||||||
s.PushNumber(result)
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Working with Tables
|
## Working with Tables
|
||||||
|
|
||||||
Lua tables are powerful - they're like a mix of Go's maps and slices. We make it easy to work with them:
|
Lua tables are pretty powerful - they're like a mix of Go's maps and slices. We make it easy to work with them:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Go → Lua
|
// Go → Lua
|
||||||
@ -112,33 +106,11 @@ stuff := map[string]any{
|
|||||||
"age": 30,
|
"age": 30,
|
||||||
"items": []float64{1, 2, 3},
|
"items": []float64{1, 2, 3},
|
||||||
}
|
}
|
||||||
L.PushValue(stuff) // Handles all Go types automatically
|
L.PushTable(stuff)
|
||||||
|
|
||||||
// Lua → Go with automatic type detection
|
// Lua → Go
|
||||||
L.GetGlobal("some_table")
|
L.GetGlobal("some_table")
|
||||||
result, err := L.ToTable(-1) // Returns optimal Go type ([]int, map[string]string, etc.)
|
result, err := L.ToTable(-1)
|
||||||
```
|
|
||||||
|
|
||||||
### Table Builder
|
|
||||||
|
|
||||||
Build tables fluently:
|
|
||||||
```go
|
|
||||||
L.NewTableBuilder().
|
|
||||||
SetString("name", "John").
|
|
||||||
SetNumber("age", 30).
|
|
||||||
SetBool("active", true).
|
|
||||||
SetArray("scores", []any{95, 87, 92}).
|
|
||||||
Build()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Table Field Access
|
|
||||||
|
|
||||||
Get fields with defaults:
|
|
||||||
```go
|
|
||||||
L.GetGlobal("config")
|
|
||||||
host := L.GetFieldString(-1, "host", "localhost")
|
|
||||||
port := L.GetFieldNumber(-1, "port", 8080)
|
|
||||||
debug := L.GetFieldBool(-1, "debug", false)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
@ -147,30 +119,33 @@ We provide useful errors instead of mysterious panics:
|
|||||||
```go
|
```go
|
||||||
if err := L.DoString("this isn't valid Lua!"); err != nil {
|
if err := L.DoString("this isn't valid Lua!"); err != nil {
|
||||||
if luaErr, ok := err.(*luajit.LuaError); ok {
|
if luaErr, ok := err.(*luajit.LuaError); ok {
|
||||||
fmt.Printf("Error in %s:%d - %s\n", luaErr.File, luaErr.Line, luaErr.Message)
|
fmt.Printf("Error: %s\n", luaErr.Message)
|
||||||
fmt.Printf("Stack trace:\n%s\n", luaErr.StackTrace)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Memory Management
|
## Memory Management
|
||||||
|
|
||||||
The wrapper uses bytecode buffer pooling to reduce allocations:
|
The wrapper uses a custom table pooling system to reduce GC pressure when handling many tables:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Bytecode buffers are pooled and reused internally
|
// Tables are pooled and reused internally for better performance
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
bytecode, _ := L.CompileBytecode(code, "test")
|
L.GetGlobal("table")
|
||||||
// Buffer automatically returned to pool
|
table, _ := L.ToTable(-1)
|
||||||
|
// Use table...
|
||||||
|
L.Pop(1)
|
||||||
|
// Table is automatically returned to pool
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Function pointers are managed safely:
|
The sandbox also manages its environment efficiently:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Functions are registered in a thread-safe registry
|
// Environment objects are pooled and reused
|
||||||
L.RegisterGoFunction("myFunc", myGoFunc)
|
for i := 0; i < 1000; i++ {
|
||||||
defer L.Cleanup() // Cleans up all registered functions
|
result, _ := sandbox.Run("return i + 1")
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Best Practices
|
## Best Practices
|
||||||
@ -185,12 +160,7 @@ defer L.Cleanup() // Cleans up all registered functions
|
|||||||
### Bytecode Optimization
|
### Bytecode Optimization
|
||||||
- Use bytecode for frequently executed code paths
|
- Use bytecode for frequently executed code paths
|
||||||
- Consider compiling critical Lua code to bytecode at startup
|
- Consider compiling critical Lua code to bytecode at startup
|
||||||
- For small scripts (< 1024 bytes), direct execution might be faster due to compilation overhead
|
- For small scripts (< 1024 bytes), direct execution might be faster
|
||||||
|
|
||||||
### Type Conversion
|
|
||||||
- Use `ToTable()` for automagic type detection and optimized Go arrays/maps
|
|
||||||
- Use `PushValue()` for automagic Go-to-Lua conversion
|
|
||||||
- Leverage typed field accessors for config-style tables
|
|
||||||
|
|
||||||
## Advanced Features
|
## Advanced Features
|
||||||
|
|
||||||
@ -228,53 +198,14 @@ L.LoadAndRunBytecodeWithResults(bytecode, "counter", 1)
|
|||||||
L.SetGlobal("increment")
|
L.SetGlobal("increment")
|
||||||
|
|
||||||
// Later...
|
// Later...
|
||||||
results, _ := L.CallGlobal("increment") // Returns []any{1}
|
L.GetGlobal("increment")
|
||||||
results, _ = L.CallGlobal("increment") // Returns []any{2}
|
L.Call(0, 1) // Returns 1
|
||||||
|
L.Pop(1)
|
||||||
|
|
||||||
|
L.GetGlobal("increment")
|
||||||
|
L.Call(0, 1) // Returns 2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Batch Execution
|
|
||||||
|
|
||||||
Execute multiple statements efficiently:
|
|
||||||
|
|
||||||
```go
|
|
||||||
statements := []string{
|
|
||||||
"x = 10",
|
|
||||||
"y = 20",
|
|
||||||
"result = x + y",
|
|
||||||
}
|
|
||||||
err := L.BatchExecute(statements)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Package Path Management
|
|
||||||
|
|
||||||
Manage Lua module paths:
|
|
||||||
|
|
||||||
```go
|
|
||||||
L.SetPackagePath("./?.lua;./modules/?.lua")
|
|
||||||
L.AddPackagePath("./vendor/?.lua")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Conversion System
|
|
||||||
|
|
||||||
The wrapper includes a comprehensive type conversion system:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Get typed values with automatic conversion
|
|
||||||
value, ok := luajit.GetTypedValue[int](L, -1)
|
|
||||||
global, ok := luajit.GetGlobalTyped[[]string](L, "myArray")
|
|
||||||
|
|
||||||
// Convert between compatible types
|
|
||||||
result, ok := luajit.ConvertValue[map[string]int](someMap)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance Tips
|
|
||||||
|
|
||||||
- Use bytecode for repeated execution
|
|
||||||
- Prefer `CallGlobal()` for simple function calls
|
|
||||||
- Use typed field accessors for configuration parsing
|
|
||||||
- Leverage automatic type detection in `ToTable()`
|
|
||||||
- Pool your Lua states for high-throughput scenarios
|
|
||||||
|
|
||||||
## Need Help?
|
## Need Help?
|
||||||
|
|
||||||
Check out the tests in the repository - they're full of examples. If you're stuck, open an issue! We're here to help.
|
Check out the tests in the repository - they're full of examples. If you're stuck, open an issue! We're here to help.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user