diff options
| author | unwox <me@unwox.com> | 2025-09-09 17:21:12 +0600 |
|---|---|---|
| committer | unwox <me@unwox.com> | 2025-09-09 17:22:57 +0600 |
| commit | aadee458066c5d623ae2a16b8957f51418139fcd (patch) | |
| tree | 582dde598e1e317de3ed51f11a1f1ec5c5c5ac8e /lua.go | |
| parent | c26739ce130bc40ded6ff9dfea1be1eba1a2e4eb (diff) | |
small refactorings
Diffstat (limited to 'lua.go')
| -rw-r--r-- | lua.go | 119 |
1 files changed, 9 insertions, 110 deletions
@@ -24,20 +24,18 @@ static inline void luna_push_function(lua_State *l, uintptr_t f) { import "C" import ( "errors" - "fmt" "runtime/cgo" - "time" "unsafe" ) type LuaRef C.int + // Lua is a wrapper around C Lua state with several conveniences. type Lua struct { l *C.lua_State running **Lua yield func() resume func() bool - tracebackHandler LuaRef } //export luna_run_go_func @@ -53,9 +51,9 @@ func (l *Lua) Start() { l.running = &l C.luaL_openlibs(l.l) - // Put debug handler into the registry for later copies to the stack. + // Put traceback function at the start of the stack so it's always + // possible to refer to it via stack index 1. l.PushGoFunction(TracebackHandler) - l.tracebackHandler = l.PopToRef() } // Close closes the Lua context. @@ -63,22 +61,6 @@ func (l *Lua) Close() { C.lua_close(l.l) } -// Require loads and executes the file pushing results onto the Lua stack. -// FIXME: traceback handler remains dangling on the stack, we need to remove -// it somehow. -func (l *Lua) Require(file string) error { - l.PushTracebackHandler() - err := l.LoadFile(file) - if err != nil { - return errors.New("could not open the file:\n" + err.Error()) - } - err = l.PCall(0, C.LUA_MULTRET, -2) - if err != nil { - return errors.New("could not execute the file:\n" + err.Error()) - } - return nil -} - // PCall calls a function with the stack index (-nargs-1) expecting nresults // number of results. func (l *Lua) PCall(nargs int, nresults int, errfunc int) error { @@ -138,6 +120,11 @@ func (l *Lua) Pop(n int) { C.lua_settop(l.l, C.int(-n - 1)) } +// SetTop sets head of the stack at top. +func (l *Lua) SetTop(top int) { + C.lua_settop(l.l, C.int(top)) +} + // PushNil pushes tnil onto the Lua stack. func (l *Lua) PushNil() { C.lua_pushnil(l.l) @@ -208,63 +195,6 @@ func (l *Lua) RawGetI(tableOffset, i int) { C.lua_rawgeti(l.l, C.int(tableOffset), C.longlong(i)) } -// PushAny pushes value v onto the stack. -func (l *Lua) PushAny(v any) error { - switch v.(type) { - case nil: - l.PushNil() - case string: - v, _ := v.(string) - l.PushString(v) - case func (l *Lua) int: - v, _ := v.(func (l *Lua) int) - l.PushGoFunction(v) - case int: - v, _ := v.(int) - l.PushNumber(v) - case int64: - v, _ := v.(int64) - l.PushNumber(int(v)) - case float64: - v, _ := v.(float64) - l.PushFloatNumber(v) - case bool: - v, _ := v.(bool) - l.PushBoolean(v) - case map[string]any: - v, _ := v.(map[string]any) - err := l.PushObject(v) - if err != nil { - return fmt.Errorf("array push errro: ", err) - } - case []any: - v, _ := v.([]any) - err := l.PushArray(v) - if err != nil { - return fmt.Errorf("array push errro: ", err) - } - case time.Time: - v, _ := v.(time.Time) - l.PushString(v.Format(time.DateTime)) - default: - return fmt.Errorf("unsupported value type: %T", v) - } - return nil -} - -// PushObject recursively pushes string->any Go table onto the stack. -func (l *Lua) PushObject(table map[string]any) error { - l.CreateTable(len(table)) - for k, v := range table { - err := l.PushAny(v) - if err != nil { - return err - } - l.SetTableItem(k) - } - return nil -} - // PushArray recursively pushes an array of Go values onto the stack. func (l *Lua) PushArray(array []any) error { l.CreateTable(len(array)) @@ -333,45 +263,21 @@ func (l *Lua) Next() bool { // LoadAndCall loads and calls the code in the current Lua context. Whatever // the code returns is stored in the stack. To drop the results use l.Pop. -// FIXME: traceback handler remains dangling on the stack, we need to remove -// it somehow. func (l *Lua) LoadAndCall(code string) error { cstr := C.CString(code) defer C.free(unsafe.Pointer(cstr)) - l.PushTracebackHandler() if C.luaL_loadstring(l.l, cstr) != C.LUA_OK { errMsg := l.ToString(-1) l.Pop(1) return errors.New(errMsg) } - err := l.PCall(0, C.LUA_MULTRET, -2) + err := l.PCall(0, C.LUA_MULTRET, 1) if err != nil { return err } return nil } -// RestoreStackFunc remembers the Lua stack size and then restores it when a -// returned function is called. It's a helper function to avoid stack leakage. -func (l *Lua) RestoreStackFunc() func () { - before := l.StackLen() - return func () { - after := l.StackLen() - diff := after - before - if diff == 0 { - return - } else if diff < 0 { - msg := fmt.Sprintf( - "too many stack pops: len before: %d, after: %d\n", - before, - after, - ) - panic(msg) - } - C.lua_settop(l.l, C.int(before)) - } -} - // SetGlobal sets a global value at the -1 stack index with the name. func (l *Lua) SetGlobal(name string) { cstr := C.CString(name) @@ -392,16 +298,9 @@ func (l *Lua) NewThread(yield func(), resume func() bool) *Lua { running: l.running, resume: resume, yield: yield, - tracebackHandler: l.tracebackHandler, } } -// PushTracebackHandler puts the traceback handler onto the stack for using -// as a errfunc argument when calling PCall. -func (l *Lua) PushTracebackHandler() { - l.PushFromRef(l.tracebackHandler) -} - // TracebackHandler handles stack trace formatting on errors. func TracebackHandler(l *Lua) int { msg := l.ToString(-1) |
