diff options
Diffstat (limited to 'luajit.go')
| -rw-r--r-- | luajit.go | 113 |
1 files changed, 5 insertions, 108 deletions
@@ -25,9 +25,7 @@ import "C" import ( "errors" "fmt" - "reflect" "runtime/cgo" - "slices" "time" "unsafe" ) @@ -199,6 +197,11 @@ func (l *Lua) GetTableItem(key string) { C.lua_getfield(l.l, -1, C.CString(key)) } +// RawGetI pushes onto the stack value from table from tableOffset at index i. +func (l *Lua) RawGetI(tableOffset, i int) { + C.lua_rawgeti(l.l, C.int(tableOffset), C.int(i)) +} + // PushAny pushes value v onto the stack. func (l *Lua) PushAny(v any) error { switch v.(type) { @@ -341,112 +344,6 @@ func (l *Lua) LoadAndCall(code string) error { return nil } -// Scan scans values from the Lua stack into vars according to their types. -func (l *Lua) Scan(vars ...any) error { - slices.Reverse(vars) - for i, v := range vars { - t := reflect.TypeOf(v) - // unwrap pointers - for t.Kind() == reflect.Ptr { - t = t.Elem() - } - tk := t.Kind() - if t.Name() == "LuaRef" { - if l.IsFunction(-1) == false { - return fmt.Errorf( - "passed arg #%d must be function", - len(vars)-i, - ) - } - *v.(*LuaRef) = l.PopToRef() - } else if t.String() == "cgo.Handle" { - if l.IsNumber(-1) == false { - return fmt.Errorf( - "passed arg #%d must be Go handler", - len(vars)-i, - ) - } - *v.(*cgo.Handle) = cgo.Handle(uintptr(l.ToInt(-1))) - l.Pop(1) - } else if tk == reflect.String { - if l.IsString(-1) == false { - return fmt.Errorf( - "passed arg #%d must be string", - len(vars)-i, - ) - } - *v.(*string) = l.ToString(-1) - l.Pop(1) - } else if tk == reflect.Int { - if l.IsNumber(-1) == false { - return fmt.Errorf( - "passed arg #%d must be number", - len(vars)-i, - ) - } - *v.(*int) = l.ToInt(-1) - l.Pop(1) - } else if tk == reflect.Map && t.Key().Kind() == reflect.String { - // TODO: should be possible to use maps with any types - // of value, not only strings. - vm, _ := v.(*map[string]string) - l.PushNil() - for l.Next() { - if !l.IsString(-1) { - return fmt.Errorf( - "map arg #%d must only have string values", - len(vars)-i, - ) - } - if !l.IsString(-2) { - return fmt.Errorf( - "map arg #%d must only have string keys", - len(vars)-i, - ) - } - v := l.ToString(-1) - l.Pop(1) - // We must not pop the item key from the stack - // because otherwise C.lua_next won't work - // properly. - k := l.ToString(-1) - (*vm)[k] = v - } - l.Pop(1) - } else if tk == reflect.Slice && - t.Elem().Kind() == reflect.Interface { - if !l.IsTable(-1) { - return fmt.Errorf( - "passed arg #%d must be a table", - len(vars)-i, - ) - } - va, _ := v.(*[]any) - l.PushNil() - for l.Next() { - var v any = nil - if l.IsString(-1) { - v = l.ToString(-1) - } else if l.IsNumber(-1) { - v = l.ToInt(-1) - } else if l.IsBoolean(-1) { - v = l.ToBoolean(-1) - } else if l.IsNil(-1) { - v = nil - } else { - return fmt.Errorf("unknown value in array") - } - l.Pop(1) - (*va) = append((*va), v) - } - l.Pop(1) - } else { - return fmt.Errorf("unknown var type: %s", t) - } - } - 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 () { |
