Overview of GopherLua
mastergoto statement from Lua 5.2) written entirely in Go. It is designed to be a scripting language with extensible semantics, providing Go APIs to embed Lua scripting into Go host programs.repository·master·Indexed 27 days ago
https://github.com/yuin/gopher-luaGopherLua is a Lua 5.1+ VM and compiler implemented in Go, allowing developers to embed Lua scripting capabilities into Go applications. It supports Lua 5.2 goto statements, provides Go APIs for extensible semantics, and includes a standalone interpreter called glua. Key features include LState configuration, Go function integration, LUserData for custom types, and support for Go channels and context for termination.
goto statement from Lua 5.2) written entirely in Go. It is designed to be a scripting language with extensible semantics, providing Go APIs to embed Lua scripting into Go host programs.An LState is not goroutine-safe. Use one LState per goroutine and communicate via Go channels. GopherLua provides LChannel to bridge Go channels into Lua.
Restrictions: Do NOT send the following objects over channels: LThread (state), LFunction, LUserData, or a LTable with a metatable.
Lua API for Channels:
channel.make([buf:int]) -> ch:channelchannel.select(case:table, ...) -> {index:int, recv:any, ok:bool}ch:send(data:any)ch:receive() -> ok:bool, data:anych:close()GopherLua provides a standalone interpreter called glua which supports the same options as the standard Lua interpreter. You can install it using go get.
go get github.com/yuin/gopher-lua/cmd/gluaYou can create a Lua module by defining a Loader function in Go. This loader uses L.SetFuncs to register a map of LGFunction exports into a new table and then returns that table to Lua via L.Push.
// mymodule.go
func Loader(L *lua.LState) int {
mod := L.SetFuncs(L.NewTable(), exports)
L.SetField(mod, "name", lua.LString("value"))
L.Push(mod)
return 1
}
var exports = map[string]lua.LGFunction{
"myfunc": myfunc,
}
// In your main.go, preload it:
L.PreloadModule("mymodule", mymodule.Loader)To use GopherLua in your Go project, install it using go get:
$ go get github.com/yuin/gopher-luaTo save memory when multiple LState instances need to run the same script, compile the script once into a *lua.FunctionProto and use DoCompiledFile to run it in different states. This is safe because the bytecode is read-only.
// Compile once
proto, err := lua.Compile(chunk, filePath)
// Run in multiple states
func Example() {
codeToShare, _ := CompileLua("mylua.lua")
a := lua.NewState()
b := lua.NewState()
DoCompiledFile(a, codeToShare)
DoCompiledFile(b, codeToShare)
}When migrating from standard Lua to GopherLua, be aware of the following behavioral differences:
channel type. The channel table provides functions for these operations.goto and ::label:: statements.os.setenv(name, value) to set environment variables.string.dump, os.setlocale, lua_Debug.namewhat, and package.loadlib are not supported. Debug hooks are also unsupported.collectgarbage does not take arguments and triggers garbage collection for the entire Go program.file:setvbuf does not support line buffering.Use LUserData to wrap Go structs and expose them to Lua. This involves:
L.NewTypeMetatable.newPerson) that creates the LUserData, assigns the Go struct to ud.Value, and sets the metatable.L.CheckUserData in Go functions to retrieve the underlying struct.type Person struct {
Name string
}
func newPerson(L *lua.LState) int {
person := &Person{L.CheckString(1)}
ud := L.NewUserData()
ud.Value = person
L.SetMetatable(ud, L.GetTypeMetatable("person"))
L.Push(ud)
return 1
}
// In Lua:
// p = person.new("Steeve")To use GopherLua, import the package and create a new state using lua.NewState(). You can execute Lua code directly from a string using L.DoString() or from a file using L.DoFile(). Always ensure you call L.Close() to release resources.
import (
"github.com/yuin/gopher-lua"
)
L := lua.NewState()
defer L.Close()
// Run from string
if err := L.DoString(`print("hello")`); err != nil {
panic(err)
}
// Run from file
if err := L.DoFile("hello.lua"); err != nil {
panic(err)
}When creating an LState, use lua.Options to control library loading and error reporting:
SkipOpenLibs: If true, GopherLua will not open built-in libraries by default. You must manually open them using OpenXXX functions.IncludeGoStackTrace: If true, GopherLua will include Go stack traces when panics occur.You can tune the memory and performance of an LState by passing lua.Options to lua.NewState().
RegistrySize (initial), RegistryMaxSize (maximum), and RegistryGrowStep (increment size). If RegistryMaxSize is 0, it will not auto-grow.CallStackSize to set the limit.MinimizeStackMemory: true to enable auto-growing/shrinking (saves memory but has a small performance cost). If false, the stack is fixed at CallStackSize.L := lua.NewState(lua.Options{
RegistrySize: 1024 * 20,
RegistryMaxSize: 1024 * 80,
RegistryGrowStep: 32,
CallStackSize: 120,
MinimizeStackMemory: true,
})
defer L.Close()print, type, load, etc.), call OpenBase(L) on your *LState. This function sets up the global environment _G, defines _VERSION, and registers the core Lua functions.