i really really dont know how to describe this other than the fact that the rest of my function literally doesnt run.
i am working with a c lua binding library (here) and i made a function to set a field in a table. this table is stored in the lua registry, and has to be retrieved with the Push function below to put it onto the lua stack. problem: nothing after that code runs, and the function that SetField is being called in returns immediately and i have no idea how to debug or fix this issue.
here is relevant code (this is work in progress so i dont even know if the rest of it works properly since i cant run it, but it compiles)
* t.mlr.state would be the State type of golua
type Table struct{
refIdx int
mlr *Runtime
nativeFields map[Value]Value
}
func NewTable() *Table {
return &Table{
refIdx: -1,
nativeFields: make(map[Value]Value),
}
}
func (t *Table) SetRuntime(mlr *Runtime) {
t.mlr = mlr
if t.refIdx == -1 {
mlr.state.NewTable()
t.refIdx = mlr.state.Ref(lua.LUA_REGISTRYINDEX)
mlr.state.Pop(1)
}
}
func (t *Table) Get(val Value) Value {
return NilValue
}
func (t *Table) Push() {
t.mlr.state.RawGeti(lua.LUA_REGISTRYINDEX, t.refIdx)
}
func (t *Table) SetField(key string, value Value) {
fmt.Printf("key: %s, value: %s\n", key, value.TypeName())
t.Push()
defer t.mlr.state.Pop(1)
t.mlr.pushToState(value)
t.mlr.state.SetField(-1, key)
t.mlr.state.Pop(1)
println("what")
}
// another file
func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
println("hilbish loader called")
// [... code ommitted ...]
host, _ := os.Hostname()
username := curuser.Username
if runtime.GOOS == "windows" {
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
}
println("setting ver field")
hshMod.SetField("ver", moonlight.StringValue(getVersion()))
println("setting goversion field")
hshMod.SetField("goVersion", moonlight.StringValue(runtime.Version()))
hshMod.SetField("user", moonlight.StringValue(username))
hshMod.SetField("host", moonlight.StringValue(host))
hshMod.SetField("home", moonlight.StringValue(curuser.HomeDir))
hshMod.SetField("dataDir", moonlight.StringValue(dataDir))
hshMod.SetField("interactive", moonlight.BoolValue(interactive))
hshMod.SetField("login", moonlight.BoolValue(login))
hshMod.SetField("exitCode", moonlight.IntValue(0))
//util.SetField(rtm, mod, "vimMode", rt.NilValue)
// hilbish.userDir table
hshuser := userDirLoader()
hshMod.SetField("userDir", moonlight.TableValue(hshuser))
// [... code ommitted ...]
return moonlight.TableValue(hshMod)
}
// another file again
func (mlr *Runtime) pushToState(v Value) {
switch v.Type() {
case NilType: mlr.state.PushNil()
case StringType: mlr.state.PushString(v.AsString())
case TableType:
tbl := v.AsTable()
tbl.SetRuntime(mlr)
mlr.state.RawGeti(lua.LUA_REGISTRYINDEX, tbl.refIdx)
default: mlr.state.PushNil()
}
}
//go:build midnight
package moonlight
import (
"github.com/aarzilli/golua/lua"
)
type Loader func(*Runtime) Value
func (mlr *Runtime) LoadLibrary(ldr Loader, name string) {
cluaLoader := func (L *lua.State) int {
mlr.pushToState(ldr(mlr))
return 1
}
mlr.state.GetGlobal("package")
mlr.state.GetField(-1, "preload")
mlr.state.PushGoClosure(cluaLoader)
mlr.state.SetField(-2, name)
mlr.state.Pop(1)
}
the execution cycle: LoadLibrary is called, package.preload in Lua is set to the go closure. when require 'hilbish' is used, it finally calls the hilbish loader. which is supposed to set all the fields in the table. but it never gets to pushToState (i think? somehow?)

