diff options
author | nat-goodspeed <nat@lindenlab.com> | 2024-03-15 14:56:43 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-15 14:56:43 -0400 |
commit | c5dec705cf6bb3dce9381c9ec574335356051297 (patch) | |
tree | 0620f4bab572b1cd38ba8e8db03130b1e65ec1f7 /indra/llcommon/lua_function.cpp | |
parent | ee8bc528bbf97ee8cc488651fb263b07b5c1c818 (diff) | |
parent | bac113e30d987d7884c58490e6ea39a1bbd87d05 (diff) |
Merge pull request #1004 from secondlife/lua-leap
Add leap.lua module to mediate LEAP request/response viewer interactions.
Diffstat (limited to 'indra/llcommon/lua_function.cpp')
-rw-r--r-- | indra/llcommon/lua_function.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/indra/llcommon/lua_function.cpp b/indra/llcommon/lua_function.cpp index 78abb8ba7e..b5de5099ba 100644 --- a/indra/llcommon/lua_function.cpp +++ b/indra/llcommon/lua_function.cpp @@ -16,9 +16,11 @@ // STL headers // std headers #include <algorithm> +#include <exception> #include <iomanip> // std::quoted #include <map> #include <memory> // std::unique_ptr +#include <typeinfo> // external library headers // other Linden headers #include "hexdump.h" @@ -26,6 +28,7 @@ #include "llsd.h" #include "llsdutil.h" #include "lualistener.h" +#include "stringize.h" /***************************************************************************** * luau namespace @@ -496,16 +499,45 @@ std::pair<int, LLSD> LuaState::expr(const std::string& desc, const std::string& // aha, at least one entry on the stack! if (result.first == 1) { - result.second = lua_tollsd(mState, 1); + // Don't forget that lua_tollsd() can throw Lua errors. + try + { + result.second = lua_tollsd(mState, 1); + } + catch (const std::exception& error) + { + // lua_tollsd() is designed to be called from a lua_function(), + // that is, from a C++ function called by Lua. In case of error, + // it throws a Lua error to be caught by the Lua runtime. expr() + // is a peculiar use case in which our C++ code is calling + // lua_tollsd() after return from the Lua runtime. We must catch + // the exception thrown for a Lua error, else it will propagate + // out to the main coroutine and terminate the viewer -- but since + // we instead of the Lua runtime catch it, our lua_State retains + // its internal error status. Any subsequent lua_pcall() calls + // with this lua_State will report error regardless of whether the + // chunk runs successfully. Get a new lua_State(). + initLuaState(); + return { -1, stringize(LLError::Log::classname(error), ": ", error.what()) }; + } // pop the result we claimed lua_settop(mState, 0); return result; } // multiple entries on the stack - for (int index = 1; index <= result.first; ++index) + try + { + for (int index = 1; index <= result.first; ++index) + { + result.second.append(lua_tollsd(mState, index)); + } + } + catch (const std::exception& error) { - result.second.append(lua_tollsd(mState, index)); + // see above comments regarding lua_State's error status + initLuaState(); + return { -1, stringize(LLError::Log::classname(error), ": ", error.what()) }; } // pop everything lua_settop(mState, 0); |