lua脚本解析支持预编译缓存
This commit is contained in:
parent
8ad636517b
commit
b44b7945b8
75
vm.go
75
vm.go
@ -8,7 +8,11 @@
|
|||||||
package lua
|
package lua
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
luaCompile "github.com/yuin/gopher-lua"
|
luaCompile "github.com/yuin/gopher-lua"
|
||||||
|
"github.com/yuin/gopher-lua/ast"
|
||||||
|
"github.com/yuin/gopher-lua/parse"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,19 +20,57 @@ var (
|
|||||||
VMInstance *VM
|
VMInstance *VM
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitVM(poolSize int) {
|
// InitVM 初始化lua虚拟机
|
||||||
|
func InitVM(poolSize int, preComplierScript map[string]string) error {
|
||||||
if poolSize <= 0 {
|
if poolSize <= 0 {
|
||||||
poolSize = 32
|
poolSize = 32
|
||||||
}
|
}
|
||||||
VMInstance = &VM{
|
VMInstance = &VM{
|
||||||
l: &sync.RWMutex{},
|
l: &sync.RWMutex{},
|
||||||
pool: make([]*luaCompile.LState, 0),
|
scriptLock: &sync.RWMutex{},
|
||||||
|
pool: make([]*luaCompile.LState, 0),
|
||||||
|
preComplierScript: make(map[string]*luaCompile.FunctionProto),
|
||||||
}
|
}
|
||||||
|
for scriptID, scriptContent := range preComplierScript {
|
||||||
|
if err := VMInstance.AddScript(scriptID, scriptContent); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type VM struct {
|
type VM struct {
|
||||||
l *sync.RWMutex
|
l *sync.RWMutex
|
||||||
pool []*luaCompile.LState
|
scriptLock *sync.RWMutex
|
||||||
|
pool []*luaCompile.LState // lua虚拟机实例池
|
||||||
|
preComplierScript map[string]*luaCompile.FunctionProto // 预编译的脚本内容
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddScript 脚本编译
|
||||||
|
func (v *VM) AddScript(scriptID string, script string) error {
|
||||||
|
v.scriptLock.Lock()
|
||||||
|
defer v.scriptLock.Unlock()
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
chunk []ast.Stmt
|
||||||
|
proto *luaCompile.FunctionProto
|
||||||
|
)
|
||||||
|
|
||||||
|
if chunk, err = parse.Parse(strings.NewReader(script), scriptID); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if proto, err = luaCompile.Compile(chunk, scriptID); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.preComplierScript[scriptID] = proto
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveScript 删除一个已编译的脚本
|
||||||
|
func (v *VM) RemoveScript(scriptID string) {
|
||||||
|
v.scriptLock.Lock()
|
||||||
|
defer v.scriptLock.Unlock()
|
||||||
|
delete(v.preComplierScript, scriptID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVm 获取一个VM实例
|
// GetVm 获取一个VM实例
|
||||||
@ -59,6 +101,29 @@ func (v *VM) Shutdown() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunPreCompileScript 执行预编译过的脚本
|
||||||
|
func (v *VM) RunPreCompileScript(scriptID string) (*luaCompile.LState, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
proto *luaCompile.FunctionProto
|
||||||
|
exists bool
|
||||||
|
)
|
||||||
|
v.scriptLock.Lock()
|
||||||
|
if proto, exists = v.preComplierScript[scriptID]; !exists {
|
||||||
|
v.scriptLock.Unlock()
|
||||||
|
return nil, fmt.Errorf("preComplier script %s not found", scriptID)
|
||||||
|
}
|
||||||
|
v.scriptLock.Unlock()
|
||||||
|
l := v.GetVm()
|
||||||
|
lFunc := l.NewFunctionFromProto(proto)
|
||||||
|
l.Push(lFunc)
|
||||||
|
if err = l.PCall(0, luaCompile.MultRet, nil); nil != err {
|
||||||
|
v.Close(l)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return l, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Run 运行脚本
|
// Run 运行脚本
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user