Compare commits

..

No commits in common. "d484e4cfbff9ccdb5f4e3b1fcc0a8bea762d8db3" and "0230a3b514e915207a0d8ce0f27dc24f113f2f29" have entirely different histories.

23 changed files with 54 additions and 407 deletions

4
.gitignore vendored
View File

@ -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
View 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
View 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>

View 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
View 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
View 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
View File

@ -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
View File

@ -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
View 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

Binary file not shown.

BIN
lib/linux/libluajit.so Normal file

Binary file not shown.

BIN
lib/windows/liblua51.a Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/windows/libluajit.a Normal file

Binary file not shown.

BIN
lib/windows/lua51.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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>