Skip to content

Commit 3ea5975

Browse files
committed
module
1 parent eaeefa7 commit 3ea5975

10 files changed

Lines changed: 367 additions & 5 deletions

File tree

base/bit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ func (BitFactory) Not(v uint64) uint64 {
2727
}
2828

2929
func (BitFactory) Test(v, r uint64) bool {
30-
return 0 != (v >> r)&1
30+
return 0 != (v>>r)&1
3131
}

base/tobuffer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ func __newBufferN(L *lua.LState) Buffer {
5454
func __newBuffer1(v lua.LValue) Buffer {
5555
switch v.Type() {
5656
case lua.LTString:
57-
__stringBuffer(string(v.(lua.LString)))
57+
return __stringBuffer(string(v.(lua.LString)))
5858
case lua.LTNumber:
59-
__allocBuffer(int(v.(lua.LNumber)), 0)
59+
return __allocBuffer(int(v.(lua.LNumber)), 0)
6060
case lua.LTUserData:
61-
__dataBuffer(v.(*lua.LUserData).Value)
61+
return __dataBuffer(v.(*lua.LUserData).Value)
6262
}
6363
return nil
6464
}

demo/module.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
local M = {}
2+
3+
function M:hello(s)
4+
print("hello:",s)
5+
end
6+
7+
function M:add(a,b)
8+
return a + b
9+
end
10+
11+
return M

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module github.com/vlorc/lua-vm
22

33
require (
4+
github.com/mitchellh/mapstructure v1.1.2 // indirect
5+
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7
46
github.com/yuin/gopher-lua v0.0.0-20180827083657-b942cacc89fe
57
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
68
golang.org/x/text v0.3.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
2+
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
3+
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7 h1:noHsffKZsNfU38DwcXWEPldrTjIZ8FPNKx8mYMGnqjs=
4+
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7/go.mod h1:bbMEM6aU1WDF1ErA5YJ0p91652pGv140gGw4Ww3RGp8=
15
github.com/yuin/gopher-lua v0.0.0-20180827083657-b942cacc89fe h1:5Zfs+TirasJUUDUjrHEdMW6XoFmfQxpuPS58cJgoZBQ=
26
github.com/yuin/gopher-lua v0.0.0-20180827083657-b942cacc89fe/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
37
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=

main/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,15 @@ func main() {
4848
)
4949

5050
now := time.Now()
51-
err := p.DoFile("demo/buffer.lua")
51+
module, err := p.ModuleFile("demo/module.lua")
5252
if nil != err {
5353
println("error: ", err.Error())
5454
}
55+
56+
var add func(int, int) int
57+
module.Method("add", &add)
58+
println("add:", add(1, 2))
59+
5560
last := time.Now()
5661
println("time: ", (last.UnixNano()-now.UnixNano())/1000000, last.Unix()-now.Unix())
5762
}

pool/module.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package pool
2+
3+
import (
4+
"github.com/yuin/gopher-lua"
5+
"layeh.com/gopher-luar"
6+
"reflect"
7+
"sync"
8+
)
9+
10+
type module struct {
11+
state *lua.LState
12+
table *lua.LTable
13+
method sync.Map
14+
}
15+
16+
func (m *module) To(val interface{}, name ...string) bool {
17+
if len(name) > 0 {
18+
return __toValue(m.state.GetField(m.table, name[0]), val)
19+
}
20+
return __toValue(m.table, val)
21+
}
22+
23+
func (m *module) Call(name string, args ...interface{}) {
24+
m.__callByName(name, 0, nil, args...)
25+
}
26+
27+
func (m *module) Method(name string, val interface{}) bool {
28+
method := m.__method(name)
29+
if nil == method {
30+
return false
31+
}
32+
typ := reflect.TypeOf(val).Elem()
33+
build := func(*lua.LState) []reflect.Value {
34+
return nil
35+
}
36+
if typ.NumOut() > 0 {
37+
build = func(state *lua.LState) []reflect.Value {
38+
result := make([]reflect.Value, typ.NumOut())
39+
top := state.GetTop()
40+
for i, l := 0, typ.NumOut(); i < l; i++ {
41+
v := reflect.New(typ.Out(i))
42+
result[i] = v.Elem()
43+
if i < top {
44+
__toValue(state.Get(-(i + 1)), v.Interface())
45+
}
46+
}
47+
return result
48+
}
49+
}
50+
reflect.ValueOf(val).Elem().Set(
51+
reflect.MakeFunc(
52+
typ,
53+
func(args []reflect.Value) (results []reflect.Value) {
54+
var params []interface{}
55+
if len(args) > 0 {
56+
params = make([]interface{}, len(args))
57+
for i := range args {
58+
if args[i].IsValid() {
59+
params[i] = args[i].Interface()
60+
}
61+
}
62+
}
63+
return m.__call(method, typ.NumOut(), build, params...)
64+
}),
65+
)
66+
return true
67+
}
68+
69+
func (m *module) __method(name string) (method *lua.LFunction) {
70+
if it, ok := m.method.Load(name); ok {
71+
method = it.(*lua.LFunction)
72+
} else if f := m.state.GetField(m.table, name); lua.LTFunction == f.Type() {
73+
method = f.(*lua.LFunction)
74+
m.method.Store(name, method)
75+
}
76+
return
77+
}
78+
79+
func (m *module) __callByName(name string, nret int, result func(*lua.LState) []reflect.Value, args ...interface{}) []reflect.Value {
80+
return m.__call(m.__method(name), nret, result, args...)
81+
}
82+
83+
func (m *module) __call(method *lua.LFunction, nret int, result func(*lua.LState) []reflect.Value, args ...interface{}) []reflect.Value {
84+
thread, cancelFunc := m.state.NewThread()
85+
defer thread.Close()
86+
if cancelFunc != nil {
87+
defer cancelFunc()
88+
}
89+
defer thread.SetTop(0)
90+
thread.Push(method)
91+
thread.Push(m.table)
92+
for _, v := range args {
93+
thread.Push(luar.New(thread, v))
94+
}
95+
thread.Call(len(args)+1, nret)
96+
if nil != result {
97+
return result(thread)
98+
}
99+
return nil
100+
}

pool/pool.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,27 @@ func (p *LuaPool) Preload(load ...func(*lua.LState) error) *LuaPool {
6363
p.init = append(p.init, load...)
6464
return p
6565
}
66+
67+
func (p *LuaPool) ModuleString(source string) (LuaModule, error) {
68+
L := p.Get()
69+
if err := L.DoString(source); nil != err {
70+
return nil, err
71+
}
72+
return __toModule(L), nil
73+
}
74+
75+
func (p *LuaPool) ModuleFile(file string) (LuaModule, error) {
76+
L := p.Get()
77+
if err := L.DoFile(file); nil != err {
78+
return nil, err
79+
}
80+
return __toModule(L), nil
81+
}
82+
83+
func __toModule(state *lua.LState) LuaModule {
84+
table := state.ToTable(-1)
85+
return &module{
86+
state: state,
87+
table: table,
88+
}
89+
}

pool/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package pool
2+
3+
type LuaModule interface {
4+
To(val interface{}, name ...string) bool
5+
Call(name string, args ...interface{})
6+
Method(name string, val interface{}) bool
7+
}

0 commit comments

Comments
 (0)