summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-06-18 18:01:39 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-06-18 18:01:39 -0400
commitc6001e6a20389b4d32813c7f61b56ff79f575723 (patch)
tree0000f3c435113c1eafbee4fe47716e856b77305c /indra/newview
parent6bbd39f54a71a1d223c6e74b47c6b0cf9f72eb7e (diff)
Improve diagnostic output from running 'require' module.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llluamanager.cpp75
1 files changed, 48 insertions, 27 deletions
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 8b6f7a4698..3ed72c34f3 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -454,45 +454,70 @@ bool LLRequireResolver::findModuleImpl(const std::string& absolutePath)
void LLRequireResolver::runModule(const std::string& desc, const std::string& code)
{
// Here we just loaded a new module 'code', need to run it and get its result.
- // Module needs to run in a new thread, isolated from the rest.
- // Note: we create ML on main thread so that it doesn't inherit environment of L.
- lua_State *GL = lua_mainthread(L);
-// lua_State *ML = lua_newthread(GL);
- // Try loading modules on Lua's main thread instead.
- lua_State *ML = GL;
- // lua_newthread() pushed the new thread object on GL's stack. Move to L's.
-// lua_xmove(GL, L, 1);
-
- // new thread needs to have the globals sandboxed
-// luaL_sandboxthread(ML);
+ lua_State *ML = lua_mainthread(L);
{
// If loadstring() returns (! LUA_OK) then there's an error message on
// the stack. If it returns LUA_OK then the newly-loaded module code
// is on the stack.
- if (lluau::loadstring(ML, desc, code) == LUA_OK)
+ LL_DEBUGS("Lua") << "Loading module " << desc << LL_ENDL;
+ if (lluau::loadstring(ML, desc, code) != LUA_OK)
{
- // luau uses Lua 5.3's version of lua_resume():
- // run the coroutine on ML, "from" L, passing no arguments.
-// int status = lua_resume(ML, L, 0);
- // we expect one return value
- int status = lua_pcall(ML, 0, 1, 0);
+ // error message on stack top
+ LL_DEBUGS("Lua") << "Error loading module " << desc << ": "
+ << lua_tostring(ML, -1) << LL_ENDL;
+ lua_pushliteral(ML, "loadstring: ");
+ // stack contains error, "loadstring: "
+ // swap: insert stack top at position -2
+ lua_insert(ML, -2);
+ // stack contains "loadstring: ", error
+ lua_concat(ML, 2);
+ // stack contains "loadstring: " + error
+ }
+ else // module code on stack top
+ {
+ // push debug module
+ lua_getglobal(ML, "debug");
+ // push debug.traceback
+ lua_getfield(ML, -1, "traceback");
+ // stack contains module code, debug, debug.traceback
+ // ditch debug
+ lua_replace(ML, -2);
+ // stack contains module code, debug.traceback
+ // swap: insert stack top at position -2
+ lua_insert(ML, -2);
+ // stack contains debug.traceback, module code
+ LL_DEBUGS("Lua") << "Loaded module " << desc << ", running" << LL_ENDL;
+ // no arguments, one return value
+ // pass debug.traceback as the error function
+ int status = lua_pcall(ML, 0, 1, -2);
+ // lua_pcall() has popped the module code and replaced it with its
+ // return value. Regardless of status or the type of the stack
+ // top, get rid of debug.traceback on the stack.
+ lua_remove(ML, -2);
if (status == LUA_OK)
{
- if (lua_gettop(ML) == 0)
- lua_pushfstring(ML, "module %s must return a value", desc.data());
- else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1))
+ auto top{ lua_gettop(ML) };
+ std::string type{ (top == 0)? "nothing"
+ : lua_typename(ML, lua_type(ML, -1)) };
+ LL_DEBUGS("Lua") << "Module " << desc << " returned " << type << LL_ENDL;
+ if ((top == 0) || ! (lua_istable(ML, -1) || lua_isfunction(ML, -1)))
+ {
lua_pushfstring(ML, "module %s must return a table or function, not %s",
- desc.data(), lua_typename(ML, lua_type(ML, -1)));
+ desc.data(), type.data());
+ }
}
else if (status == LUA_YIELD)
{
+ LL_DEBUGS("Lua") << "Module " << desc << " yielded" << LL_ENDL;
lua_pushfstring(ML, "module %s can not yield", desc.data());
}
- else if (!lua_isstring(ML, -1))
+ else
{
- lua_pushfstring(ML, "unknown error while running module %s", desc.data());
+ llassert(lua_isstring(ML, -1));
+ LL_DEBUGS("Lua") << "Module " << desc << " error: "
+ << lua_tostring(ML, -1) << LL_ENDL;
}
}
}
@@ -502,8 +527,4 @@ void LLRequireResolver::runModule(const std::string& desc, const std::string& co
{
lua_xmove(ML, L, 1);
}
- // remove ML from L's stack
-// lua_remove(L, -2);
-// // DON'T call lua_close(ML)! Since ML is only a thread of L, corrupts L too!
-// lua_close(ML);
}