-
Notifications
You must be signed in to change notification settings - Fork 1
/
lua_vm.go
99 lines (89 loc) · 1.85 KB
/
lua_vm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package lua
import (
"errors"
)
// #cgo LDFLAGS: -lluajit-5.1 -ldl -lm
//#include "glua.h"
import "C"
type gLuaVM struct {
id int64
queue chan *gLuaContext
vm *C.struct_lua_State
threads map[int64]*gLuaThread
}
func newGLuaVM() *gLuaVM {
gl := &gLuaVM{
queue: make(chan *gLuaContext, 128),
threads: make(map[int64]*gLuaThread),
}
gl.id, gl.vm = createLuaState()
return gl
}
func (gl *gLuaVM) destory() {
close(gl.queue)
C.lua_close(gl.vm)
gl.vm = nil
}
func (gl *gLuaVM) process(ctx *gLuaContext) {
if ctx.vmId == 0 {
ctx.vmId = gl.id
res, err := gl.call(ctx)
if err != nil {
ctx.callback <- err
} else {
ctx.callback <- res
}
} else {
res, err := gl.resume(ctx)
if err != nil {
ctx.callback <- err
} else {
ctx.callback <- res
}
}
}
func (gl *gLuaVM) destoryThread(t *gLuaThread) {
t.destory()
delete(gl.threads, t.id)
var (
index C.int
count C.int
)
count = C.lua_gettop(gl.vm)
for index = 1; index <= count; index++ {
vType := C.lua_type(gl.vm, index)
if vType == C.LUA_TTHREAD {
ptr := C.lua_tothread(gl.vm, index)
if ptr == t.thread {
C.lua_remove(gl.vm, index)
t.thread = nil
return
}
}
}
}
func (gl *gLuaVM) call(ctx *gLuaContext) (interface{}, error) {
thread := newGLuaThread(gl.vm)
gl.threads[thread.id] = thread
res, err := thread.call(ctx.scriptPath, ctx.methodName, ctx.args...)
if err != nil && err.Error() == "LUA_YIELD" {
ctx.threadId = thread.id
return nil, err
} else {
gl.destoryThread(thread)
return res, err
}
}
func (gl *gLuaVM) resume(ctx *gLuaContext) (interface{}, error) {
thread, ok := gl.threads[ctx.threadId]
if ok == false {
return nil, errors.New("Invalid Lua Thread")
}
res, err := thread.resume(ctx.args...)
if err != nil && err.Error() == "LUA_YIELD" {
return nil, err
} else {
gl.destoryThread(thread)
return res, err
}
}