diff options
| author | unwox <me@unwox.com> | 2024-06-17 14:28:27 +0600 |
|---|---|---|
| committer | unwox <me@unwox.com> | 2024-06-18 10:31:00 +0600 |
| commit | 701d73e4a47964ea40100ab2f329ef1dcc0a6f83 (patch) | |
| tree | 5b82a1f56922c8dc3cc79a329ad6f21f65649b64 | |
| parent | cae471d4bced5f7490cc18e86b50e51df64ddb7b (diff) | |
make it possible to push go functions onto the lua stack
| -rw-r--r-- | lua.go | 63 | ||||
| -rw-r--r-- | main.go | 1 | ||||
| -rw-r--r-- | worker.go | 12 |
3 files changed, 65 insertions, 11 deletions
@@ -6,12 +6,24 @@ package main #include <lua.h> #include <lualib.h> #include <lauxlib.h> + +extern int luna_run_go_func(uintptr_t); + +static inline int luna_run(lua_State *l) { + return luna_run_go_func(lua_tonumber(l, lua_upvalueindex(1))); +} + +static inline void luna_push_function(lua_State *l, uintptr_t f) { + lua_pushinteger(l, f); + lua_pushcclosure(l, luna_run, 1); +} */ import "C" import ( "errors" - "unsafe" "log" + "runtime/cgo" + "unsafe" ) type LuaRef C.longlong @@ -19,6 +31,13 @@ type Lua struct { l *C.lua_State } +//export luna_run_go_func +func luna_run_go_func(f C.uintptr_t) C.int { + log.Println(f) + fn := cgo.Handle(f).Value().(func() int) + return C.int(fn()) +} + func (l *Lua) Start() { l.l = C.luaL_newstate() C.luaL_openlibs(l.l) @@ -89,8 +108,26 @@ func (l *Lua) PushString(str string) { C.lua_pushstring(l.l, cstr) } -func (l *Lua) PushTable(table map[string]string) { - C.lua_createtable(l.l, 0, C.int(len(table))) +// You may need to delete handle with .Delete() method later. +func (l *Lua) PushGoFunction(f func (l *Lua) int) cgo.Handle { + h := cgo.NewHandle(func () int { + return f(l) + }) + C.luna_push_function(l.l, C.uintptr_t(h)) + return h +} + +// CreateTable pushes a new table onto the stack. +func (l *Lua) CreateTable(len int) { + C.lua_createtable(l.l, 0, C.int(len)) +} +func (l *Lua) SetTableItem(key string) { + cstr := C.CString(key) + defer C.free(unsafe.Pointer(cstr)) + C.lua_setfield(l.l, -2, C.CString(key)) +} +func (l *Lua) PushStringTable(table map[string]string) { + l.CreateTable(len(table)) for k, v := range table { l.PushString(v) C.lua_setfield(l.l, -2, C.CString(k)) @@ -101,6 +138,13 @@ func (l *Lua) PushFromRef(ref LuaRef) { C.lua_rawgeti(l.l, C.LUA_REGISTRYINDEX, C.longlong(ref)); } +func (l *Lua) PushTableItem(key string) { + ckey := C.CString(key) + defer C.free(unsafe.Pointer(ckey)) + C.lua_pushstring(l.l, ckey); + C.lua_gettable(l.l, -2); +} + func (l *Lua) IsString(index int) bool { return C.lua_isstring(l.l, C.int(index)) == 1 } @@ -138,13 +182,6 @@ func (l *Lua) LoadString(code string) error { return nil } -func (l *Lua) PushTableItem(key string) { - ckey := C.CString(key) - defer C.free(unsafe.Pointer(ckey)) - C.lua_pushstring(l.l, ckey); - C.lua_gettable(l.l, -2); -} - func (l *Lua) RestoreStackFunc() func () { before := l.StackLen() return func () { @@ -162,3 +199,9 @@ func (l *Lua) RestoreStackFunc() func () { C.lua_settop(l.l, C.int(before)) } } + +func (l *Lua) SetGlobal(name string) { + cstr := C.CString(name) + defer C.free(unsafe.Pointer(cstr)) + C.lua_setglobal(l.l, cstr) +} @@ -55,6 +55,7 @@ func main() { go wrk.Listen() defer wrk.Stop() } + go func () { reader := bufio.NewReader(os.Stdin) for { @@ -85,7 +85,7 @@ func (w *Worker) Listen() { for k := range r.request.Header { fh[k] = r.request.Header.Get(k) } - w.lua.PushTable(fh) + w.lua.PushStringTable(fh) body, err := io.ReadAll(r.request.Body) if err != nil { @@ -173,6 +173,16 @@ func (w *Worker) Stop() { w.lua.Close() } +func (w *Worker) initLunaModule() { + w.lua.CreateTable(1) + w.lua.PushGoFunction(func (l *Lua) int { + l.PushString("Hello, " + l.ToString(-1)) + return 1 + }) + w.lua.SetTableItem("helloFromGo") + w.lua.SetGlobal("luna") +} + func (w *Worker) initRoutes() error { defer w.lua.RestoreStackFunc()() w.lua.PushFromRef(w.api) |
