Compare commits
No commits in common. "d484e4cfbff9ccdb5f4e3b1fcc0a8bea762d8db3" and "0230a3b514e915207a0d8ce0f27dc24f113f2f29" have entirely different histories.
d484e4cfbf
...
0230a3b514
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -5,8 +5,9 @@
|
||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
*.exe
|
*.exe
|
||||||
*.exe~
|
*.exe~
|
||||||
*.dylib
|
|
||||||
*.dll
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
@ -20,4 +21,3 @@
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
.idea
|
|
||||||
|
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
9
.idea/ljtg.iml
Normal file
9
.idea/ljtg.iml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
10
.idea/material_theme_project_new.xml
Normal file
10
.idea/material_theme_project_new.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MaterialThemeProjectNewConfig">
|
||||||
|
<option name="metadata">
|
||||||
|
<MTProjectMetadataState>
|
||||||
|
<option name="userId" value="3fdbffe2:19499e3ad4d:-7fff" />
|
||||||
|
</MTProjectMetadataState>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/ljtg.iml" filepath="$PROJECT_DIR$/.idea/ljtg.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
270
DOCS.md
270
DOCS.md
|
@ -1,270 +0,0 @@
|
||||||
# LuaJIT Go Wrapper API Documentation
|
|
||||||
|
|
||||||
## State Management
|
|
||||||
|
|
||||||
### NewSafe() *State
|
|
||||||
Creates a new Lua state with stack safety enabled.
|
|
||||||
```go
|
|
||||||
L := luajit.NewSafe()
|
|
||||||
defer L.Close()
|
|
||||||
defer L.Cleanup()
|
|
||||||
```
|
|
||||||
|
|
||||||
### New() *State
|
|
||||||
Creates a new Lua state without stack safety checks.
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### IsFunction(index int) bool
|
|
||||||
### IsTable(index int) bool
|
|
||||||
### IsUserData(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
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 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)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Function Registration
|
|
||||||
|
|
||||||
### RegisterGoFunction(name string, fn GoFunction) error
|
|
||||||
Registers a Go function that can be called from Lua.
|
|
||||||
```go
|
|
||||||
adder := func(s *State) int {
|
|
||||||
sum := s.ToNumber(1) + s.ToNumber(2)
|
|
||||||
s.PushNumber(sum)
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
err := L.RegisterGoFunction("add", adder)
|
|
||||||
```
|
|
||||||
|
|
||||||
### UnregisterGoFunction(name string)
|
|
||||||
Removes a previously registered function.
|
|
||||||
```go
|
|
||||||
L.UnregisterGoFunction("add")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Package Management
|
|
||||||
|
|
||||||
### SetPackagePath(path string) error
|
|
||||||
Sets the Lua package.path variable.
|
|
||||||
```go
|
|
||||||
err := L.SetPackagePath("./?.lua;/usr/local/share/lua/5.1/?.lua")
|
|
||||||
```
|
|
||||||
|
|
||||||
### AddPackagePath(path string) error
|
|
||||||
Adds a path to the existing package.path.
|
|
||||||
```go
|
|
||||||
err := L.AddPackagePath("./modules/?.lua")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code Execution
|
|
||||||
|
|
||||||
### DoString(str 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")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Table Operations
|
|
||||||
|
|
||||||
### GetField(index int, key string)
|
|
||||||
Gets a field from a table at the given index.
|
|
||||||
```go
|
|
||||||
L.GetField(-1, "name") // gets table.name
|
|
||||||
```
|
|
||||||
|
|
||||||
### SetField(index int, key string)
|
|
||||||
Sets a field in a table at the given index.
|
|
||||||
```go
|
|
||||||
L.PushString("value")
|
|
||||||
L.SetField(-2, "key") // table.key = "value"
|
|
||||||
```
|
|
||||||
|
|
||||||
### GetGlobal(name string)
|
|
||||||
Gets a global variable.
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
## 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)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 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.NewSafe()
|
|
||||||
defer L.Close()
|
|
||||||
defer L.Cleanup()
|
|
||||||
```
|
|
||||||
|
|
||||||
Stack management in unsafe mode requires manual attention:
|
|
||||||
```go
|
|
||||||
L := luajit.New()
|
|
||||||
L.PushString("hello")
|
|
||||||
// ... use the string
|
|
||||||
L.Pop(1) // Clean up when done
|
|
||||||
```
|
|
134
README.md
134
README.md
|
@ -1,133 +1,3 @@
|
||||||
# LuaJIT Go Wrapper
|
# LuaJIT-to-Go
|
||||||
|
|
||||||
Hey there! This is a Go wrapper for LuaJIT that makes it easy to embed Lua in your Go applications. We've focused on making it both safe and fast, while keeping the API clean and intuitive.
|
Go wrapper for LuaJIT.
|
||||||
|
|
||||||
## What's This For?
|
|
||||||
|
|
||||||
This wrapper lets you run Lua code from Go and easily pass data back and forth between the two languages. You might want this if you're:
|
|
||||||
- Adding scripting support to your application
|
|
||||||
- Building a game engine
|
|
||||||
- Creating a configuration system
|
|
||||||
- Writing an embedded rules engine
|
|
||||||
- Building test automation tools
|
|
||||||
|
|
||||||
## Get Started
|
|
||||||
|
|
||||||
First, grab the package:
|
|
||||||
```bash
|
|
||||||
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:
|
|
||||||
```go
|
|
||||||
L := luajit.NewSafe()
|
|
||||||
defer L.Close()
|
|
||||||
defer L.Cleanup()
|
|
||||||
|
|
||||||
err := L.DoString(`print("Hey from Lua!")`)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stack Safety: Choose Your Adventure
|
|
||||||
|
|
||||||
One of the key decisions you'll make is whether to use stack-safe mode. Here's what that means:
|
|
||||||
|
|
||||||
### Stack-Safe Mode (NewSafe())
|
|
||||||
```go
|
|
||||||
L := luajit.NewSafe()
|
|
||||||
```
|
|
||||||
Think of this as driving with guardrails. It's perfect when:
|
|
||||||
- You're new to Lua or embedding scripting languages
|
|
||||||
- You're writing a server or long-running application
|
|
||||||
- You want to handle untrusted Lua code
|
|
||||||
- You'd rather have slightly slower code than mysterious crashes
|
|
||||||
|
|
||||||
The safe mode will:
|
|
||||||
- Prevent stack overflows
|
|
||||||
- Check types more thoroughly
|
|
||||||
- Clean up after messy Lua code
|
|
||||||
- Give you better error messages
|
|
||||||
|
|
||||||
### Non-Stack-Safe Mode (New())
|
|
||||||
```go
|
|
||||||
L := luajit.New()
|
|
||||||
```
|
|
||||||
This is like taking off the training wheels. Use it when:
|
|
||||||
- You know exactly how your Lua code behaves
|
|
||||||
- You've profiled your application and need more speed
|
|
||||||
- You're doing lots of rapid, simple Lua calls
|
|
||||||
- You're writing performance-critical code
|
|
||||||
|
|
||||||
The unsafe mode:
|
|
||||||
- Skips most safety checks
|
|
||||||
- Runs noticeably faster
|
|
||||||
- Gives you direct control over the stack
|
|
||||||
- Can crash spectacularly if you make a mistake
|
|
||||||
|
|
||||||
Most applications should start with stack-safe mode and only switch to unsafe mode if profiling shows it's necessary.
|
|
||||||
|
|
||||||
## Registering Go Functions
|
|
||||||
|
|
||||||
Want to call Go code from Lua? Easy:
|
|
||||||
```go
|
|
||||||
// This function adds two numbers and returns the result
|
|
||||||
adder := func(s *luajit.State) int {
|
|
||||||
sum := s.ToNumber(1) + s.ToNumber(2)
|
|
||||||
s.PushNumber(sum)
|
|
||||||
return 1 // we're returning one value
|
|
||||||
}
|
|
||||||
|
|
||||||
L.RegisterGoFunction("add", adder)
|
|
||||||
```
|
|
||||||
|
|
||||||
Now in Lua:
|
|
||||||
```lua
|
|
||||||
result = add(40, 2) -- result = 42
|
|
||||||
```
|
|
||||||
|
|
||||||
## Working with Tables
|
|
||||||
|
|
||||||
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 → Lua
|
|
||||||
stuff := map[string]interface{}{
|
|
||||||
"name": "Arthur Dent",
|
|
||||||
"age": 30,
|
|
||||||
"items": []float64{1, 2, 3},
|
|
||||||
}
|
|
||||||
L.PushTable(stuff)
|
|
||||||
|
|
||||||
// Lua → Go
|
|
||||||
L.GetGlobal("some_table")
|
|
||||||
result, err := L.ToTable(-1)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
We try to give you useful errors instead of mysterious panics:
|
|
||||||
```go
|
|
||||||
if err := L.DoString("this isn't valid Lua!"); err != nil {
|
|
||||||
if luaErr, ok := err.(*luajit.LuaError); ok {
|
|
||||||
fmt.Printf("Oops: %s\n", luaErr.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## A Few Tips
|
|
||||||
|
|
||||||
- Always use those `defer L.Close()` and `defer L.Cleanup()` calls - they prevent memory leaks
|
|
||||||
- Each Lua state should stick to one goroutine
|
|
||||||
- For concurrent stuff, create multiple states
|
|
||||||
- You can share functions between states safely
|
|
||||||
- Keep an eye on your stack in unsafe mode - it won't clean up after itself
|
|
||||||
- Start with stack-safe mode and measure before optimizing
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT Licensed - do whatever you want with it!
|
|
6
generate.go
Normal file
6
generate.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//go:build exclude
|
||||||
|
|
||||||
|
package luajit
|
||||||
|
|
||||||
|
//go:generate cp -r ../include ./include
|
||||||
|
//go:generate cp -r ../lib ./lib
|
BIN
lib/linux/libluajit.a
Normal file
BIN
lib/linux/libluajit.a
Normal file
Binary file not shown.
BIN
lib/linux/libluajit.so
Normal file
BIN
lib/linux/libluajit.so
Normal file
Binary file not shown.
BIN
lib/windows/liblua51.a
Normal file
BIN
lib/windows/liblua51.a
Normal file
Binary file not shown.
BIN
lib/windows/libluajit-5.1.dll.a
Normal file
BIN
lib/windows/libluajit-5.1.dll.a
Normal file
Binary file not shown.
BIN
lib/windows/libluajit.a
Normal file
BIN
lib/windows/libluajit.a
Normal file
Binary file not shown.
BIN
lib/windows/lua51.dll
Normal file
BIN
lib/windows/lua51.dll
Normal file
Binary file not shown.
BIN
vendor/luajit/linux/libluajit.a
vendored
BIN
vendor/luajit/linux/libluajit.a
vendored
Binary file not shown.
BIN
vendor/luajit/windows/libluajit.a
vendored
BIN
vendor/luajit/windows/libluajit.a
vendored
Binary file not shown.
|
@ -1,9 +1,9 @@
|
||||||
package luajit
|
package luajit
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo CFLAGS: -I${SRCDIR}/vendor/luajit/include
|
#cgo CFLAGS: -I${SRCDIR}/include
|
||||||
#cgo windows LDFLAGS: -L${SRCDIR}/vendor/luajit/windows -lluajit -static
|
#cgo windows LDFLAGS: -L${SRCDIR}/lib/windows -llua51
|
||||||
#cgo !windows LDFLAGS: -L${SRCDIR}/vendor/luajit/linux -lluajit -static
|
#cgo !windows LDFLAGS: -L${SRCDIR}/lib/linux -lluajit
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user