mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-01 13:35:53 +00:00
57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
// Package lua provides shared GopherLua programs and state management for Xray scripts.
|
|||
|
|
package lua
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bufio"
|
||
|
|
"context"
|
||
|
|
"os"
|
||
|
|
|
||
|
|
glua "github.com/yuin/gopher-lua"
|
||
|
|
"github.com/yuin/gopher-lua/parse"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Program holds immutable bytecode that can be run by independent LStates.
|
||
|
|
type Program struct {
|
||
|
|
proto *glua.FunctionProto
|
||
|
|
}
|
||
|
|
|
||
|
|
// CompileFile reads and compiles a Lua file once.
|
||
|
|
func CompileFile(path string) (*Program, error) {
|
||
|
|
f, err := os.Open(path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer f.Close()
|
||
|
|
chunk, err := parse.Parse(bufio.NewReader(f), path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
proto, err := glua.Compile(chunk, path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &Program{proto: proto}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewState creates a VM, makes modules available, and executes the file top level.
|
||
|
|
// Module loaders run only when Lua calls require. Each state gets its own globals.
|
||
|
|
// The caller owns the returned state.
|
||
|
|
func (p *Program) NewState(ctx context.Context, register func(*glua.LState)) (*glua.LState, error) {
|
||
|
|
L := glua.NewState()
|
||
|
|
if register != nil {
|
||
|
|
register(L)
|
||
|
|
}
|
||
|
|
L.SetContext(ctx)
|
||
|
|
L.Push(L.NewFunctionFromProto(p.proto))
|
||
|
|
err := L.PCall(0, 0, nil)
|
||
|
|
L.RemoveContext()
|
||
|
|
if err == nil {
|
||
|
|
err = ctx.Err()
|
||
|
|
}
|
||
|
|
if err != nil {
|
||
|
|
L.Close()
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return L, nil
|
||
|
|
}
|