diff options
Diffstat (limited to 'indra/llcommon/lua_function.h')
-rw-r--r-- | indra/llcommon/lua_function.h | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/indra/llcommon/lua_function.h b/indra/llcommon/lua_function.h index 7b59af30f5..6965e206ab 100644 --- a/indra/llcommon/lua_function.h +++ b/indra/llcommon/lua_function.h @@ -60,11 +60,11 @@ namespace lluau int loadstring(lua_State* L, const std::string& desc, const std::string& text); fsyspath source_path(lua_State* L); - - void set_interrupts_counter(lua_State *L, S32 counter); - void check_interrupts_counter(lua_State* L); } // namespace lluau +// must be a macro because LL_PRETTY_FUNCTION is context-sensitive +#define lluau_checkstack(L, n) luaL_checkstack((L), (n), LL_PRETTY_FUNCTION) + std::string lua_tostdstring(lua_State* L, int index); void lua_pushstdstring(lua_State* L, const std::string& str); LLSD lua_tollsd(lua_State* L, int index); @@ -107,10 +107,18 @@ public: // Find or create LuaListener for passed lua_State. static LuaListener& obtainListener(lua_State* L); + // Given lua_State* L, return the LuaState object managing (the main Lua + // thread for) L. + static LuaState& getParent(lua_State* L); + + void set_interrupts_counter(S32 counter); + void check_interrupts_counter(); + private: script_finished_fn mCallback; lua_State* mState; std::string mError; + S32 mInterrupts{ 0 }; }; /***************************************************************************** @@ -170,6 +178,32 @@ private: }; /***************************************************************************** +* LuaStackDelta +*****************************************************************************/ +/** + * Instantiate LuaStackDelta in a block to compare the Lua data stack depth on + * entry (LuaStackDelta construction) and exit. Optionally, pass the expected + * depth increment. (But be aware that LuaStackDelta cannot observe the effect + * of a LuaPopper or LuaRemover declared previously in the same block.) + */ +class LuaStackDelta +{ +public: + LuaStackDelta(lua_State* L, const std::string& where, int delta=0); + LuaStackDelta(const LuaStackDelta&) = delete; + LuaStackDelta& operator=(const LuaStackDelta&) = delete; + + ~LuaStackDelta(); + +private: + lua_State* L; + std::string mWhere; + int mDepth, mDelta; +}; + +#define lua_checkdelta(L, ...) LuaStackDelta delta(L, LL_PRETTY_FUNCTION, ##__VA_ARGS__) + +/***************************************************************************** * lua_push() wrappers for generic code *****************************************************************************/ inline @@ -294,7 +328,8 @@ auto lua_to<void*>(lua_State* L, int index) template <typename T> auto lua_getfieldv(lua_State* L, int index, const char* k) { - luaL_checkstack(L, 1, nullptr); + lua_checkdelta(L); + lluau_checkstack(L, 1); lua_getfield(L, index, k); LuaPopper pop(L, 1); return lua_to<T>(L, -1); @@ -304,7 +339,8 @@ auto lua_getfieldv(lua_State* L, int index, const char* k) template <typename T> auto lua_setfieldv(lua_State* L, int index, const char* k, const T& value) { - luaL_checkstack(L, 1, nullptr); + lua_checkdelta(L); + lluau_checkstack(L, 1); lua_push(L, value); lua_setfield(L, index, k); } @@ -313,7 +349,8 @@ auto lua_setfieldv(lua_State* L, int index, const char* k, const T& value) template <typename T> auto lua_rawgetfield(lua_State* L, int index, const std::string_view& k) { - luaL_checkstack(L, 1, nullptr); + lua_checkdelta(L); + lluau_checkstack(L, 1); lua_pushlstring(L, k.data(), k.length()); lua_rawget(L, index); LuaPopper pop(L, 1); @@ -324,7 +361,8 @@ auto lua_rawgetfield(lua_State* L, int index, const std::string_view& k) template <typename T> void lua_rawsetfield(lua_State* L, int index, const std::string_view& k, const T& value) { - luaL_checkstack(L, 2, nullptr); + lua_checkdelta(L); + lluau_checkstack(L, 2); lua_pushlstring(L, k.data(), k.length()); lua_push(L, value); lua_rawset(L, index); @@ -430,7 +468,8 @@ DistinctInt TypeTag<T>::value; template <class T, typename... ARGS> void lua_emplace(lua_State* L, ARGS&&... args) { - luaL_checkstack(L, 1, nullptr); + lua_checkdelta(L, 1); + lluau_checkstack(L, 1); int tag{ TypeTag<T>::value }; if (! lua_getuserdatadtor(L, tag)) { @@ -464,6 +503,7 @@ void lua_emplace(lua_State* L, ARGS&&... args) template <class T> T* lua_toclass(lua_State* L, int index) { + lua_checkdelta(L); // get void* pointer to userdata (if that's what it is) void* ptr{ lua_touserdatatagged(L, index, TypeTag<T>::value) }; // Derive the T* from ptr. If in future lua_emplace() must manually |