func GetTableInt(L *lua.State, name string) int { // Remember to check stack for 1 extra location L.PushString(name) L.GetTable(-2) r := L.ToInteger(-1) L.Pop(1) return r }
// Registers a Go function as a global variable and add it to the sandbox. func sandboxRegister(L *lua.State, name string, f interface{}) { goToLua(L, name, f) L.PushString(registryWhitelist) L.GetTable(lua.LUA_REGISTRYINDEX) L.GetGlobal(name) L.SetField(-2, name) }
func ipairsAux(L *lua.State) int { i := L.CheckInteger(2) + 1 L.PushInteger(int64(i)) L.PushInteger(int64(i)) L.GetTable(1) if L.Type(-1) == lua.LUA_TNIL { return 1 } return 2 }
func LuaTableGetString(L *lua.State, key string) string { L.PushString(key) L.GetTable(-2) r := "" if !L.IsNil(-1) { r = L.ToString(-1) } L.Pop(1) return r }
func sandboxCompile(L *lua.State, registryIndex string, name, code string) { L.PushString(registryIndex) L.GetTable(lua.LUA_REGISTRYINDEX) L.PushString(name) err := L.LoadString(code) if err != 0 { log.Fatalf("%s: %s", name, L.ToString(-1)) L.Pop(2) } else { L.SetTable(-3) } }
// 'exist' is optional. func run(L *lua.State, registryIndex string, code string, input *inputInfo, output *outputInfo, exist *inputInfo) error { // Restore the sandbox. err := L.DoString(luaRestoreSandbox) if err != nil { log.Fatal("Cannot load function to restore sandbox", err) } L.PushString(registryWhitelist) L.GetTable(lua.LUA_REGISTRYINDEX) err = L.Call(1, 0) if err != nil { log.Fatal("Failed to restore sandbox", err) } goToLua(L, "input", *input) goToLua(L, "output", *output) if exist != nil { goToLua(L, "existinfo", *exist) } // Shortcut (mostly for prescript and postscript). L.GetGlobal("input") L.GetField(-1, "tags") L.SetGlobal("i") L.Pop(1) L.GetGlobal("output") L.GetField(-1, "tags") L.SetGlobal("o") L.Pop(1) // Call the compiled script. L.PushString(registryIndex) L.GetTable(lua.LUA_REGISTRYINDEX) L.PushString(code) if L.IsTable(-2) { L.GetTable(-2) if L.IsFunction(-1) { err := L.Call(0, 0) if err != nil { L.SetTop(0) return fmt.Errorf("%s", err) } } else { L.Pop(1) } } else { L.Pop(1) } L.Pop(1) // Allow tags to be numbers for convenience. outputNumbersToStrings(L) L.GetGlobal("output") r := luar.LuaToGo(L, reflect.TypeOf(*output), -1) L.Pop(1) *output = r.(outputInfo) return nil }