summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/lua_function.cpp17
-rw-r--r--indra/llcommon/lua_function.h162
2 files changed, 168 insertions, 11 deletions
diff --git a/indra/llcommon/lua_function.cpp b/indra/llcommon/lua_function.cpp
index 42bba80ed5..b173d17ede 100644
--- a/indra/llcommon/lua_function.cpp
+++ b/indra/llcommon/lua_function.cpp
@@ -32,6 +32,8 @@
#include "lualistener.h"
#include "stringize.h"
+using namespace std::literals; // e.g. std::string_view literals: "this"sv
+
const S32 INTERRUPTS_MAX_LIMIT = 20000;
const S32 INTERRUPTS_SUSPEND_LIMIT = 100;
@@ -41,7 +43,7 @@ const S32 INTERRUPTS_SUSPEND_LIMIT = 100;
int DistinctInt::mValues{0};
/*****************************************************************************
-* luau namespace
+* lluau namespace
*****************************************************************************/
namespace
{
@@ -93,21 +95,14 @@ fsyspath lluau::source_path(lua_State* L)
void lluau::set_interrupts_counter(lua_State *L, S32 counter)
{
- luaL_checkstack(L, 2, nullptr);
- lua_pushstring(L, "_INTERRUPTS");
- lua_pushinteger(L, counter);
- lua_rawset(L, LUA_REGISTRYINDEX);
+ lua_rawsetfield(L, LUA_REGISTRYINDEX, "_INTERRUPTS"sv, lua_Integer(counter));
}
void lluau::check_interrupts_counter(lua_State* L)
{
- luaL_checkstack(L, 1, nullptr);
- lua_pushstring(L, "_INTERRUPTS");
- lua_rawget(L, LUA_REGISTRYINDEX);
- S32 counter = lua_tointeger(L, -1);
- lua_pop(L, 1);
+ auto counter = lua_rawgetfield<lua_Integer>(L, LUA_REGISTRYINDEX, "_INTERRUPTS"sv);
- lluau::set_interrupts_counter(L, ++counter);
+ set_interrupts_counter(L, ++counter);
if (counter > INTERRUPTS_MAX_LIMIT)
{
lluau::error(L, "Possible infinite loop, terminated.");
diff --git a/indra/llcommon/lua_function.h b/indra/llcommon/lua_function.h
index 7f7a7566f3..7b59af30f5 100644
--- a/indra/llcommon/lua_function.h
+++ b/indra/llcommon/lua_function.h
@@ -18,6 +18,7 @@
#include "luau/lualib.h"
#include "fsyspath.h"
#include "llerror.h"
+#include "llsd.h"
#include "stringize.h"
#include <exception> // std::uncaught_exceptions()
#include <memory> // std::shared_ptr
@@ -169,6 +170,167 @@ private:
};
/*****************************************************************************
+* lua_push() wrappers for generic code
+*****************************************************************************/
+inline
+void lua_push(lua_State* L, bool b)
+{
+ lua_pushboolean(L, int(b));
+}
+
+inline
+void lua_push(lua_State* L, lua_CFunction fn)
+{
+ lua_pushcfunction(L, fn, "");
+}
+
+inline
+void lua_push(lua_State* L, lua_Integer n)
+{
+ lua_pushinteger(L, n);
+}
+
+inline
+void lua_push(lua_State* L, void* p)
+{
+ lua_pushlightuserdata(L, p);
+}
+
+inline
+void lua_push(lua_State* L, const LLSD& data)
+{
+ lua_pushllsd(L, data);
+}
+
+inline
+void lua_push(lua_State* L, const char* s, size_t len)
+{
+ lua_pushlstring(L, s, len);
+}
+
+inline
+void lua_push(lua_State* L)
+{
+ lua_pushnil(L);
+}
+
+inline
+void lua_push(lua_State* L, lua_Number n)
+{
+ lua_pushnumber(L, n);
+}
+
+inline
+void lua_push(lua_State* L, const std::string& s)
+{
+ lua_pushstdstring(L, s);
+}
+
+inline
+void lua_push(lua_State* L, const char* s)
+{
+ lua_pushstring(L, s);
+}
+
+/*****************************************************************************
+* lua_to() wrappers for generic code
+*****************************************************************************/
+template <typename T>
+auto lua_to(lua_State* L, int index);
+
+template <>
+inline
+auto lua_to<bool>(lua_State* L, int index)
+{
+ return lua_toboolean(L, index);
+}
+
+template <>
+inline
+auto lua_to<lua_CFunction>(lua_State* L, int index)
+{
+ return lua_tocfunction(L, index);
+}
+
+template <>
+inline
+auto lua_to<lua_Integer>(lua_State* L, int index)
+{
+ return lua_tointeger(L, index);
+}
+
+template <>
+inline
+auto lua_to<LLSD>(lua_State* L, int index)
+{
+ return lua_tollsd(L, index);
+}
+
+template <>
+inline
+auto lua_to<lua_Number>(lua_State* L, int index)
+{
+ return lua_tonumber(L, index);
+}
+
+template <>
+inline
+auto lua_to<std::string>(lua_State* L, int index)
+{
+ return lua_tostdstring(L, index);
+}
+
+template <>
+inline
+auto lua_to<void*>(lua_State* L, int index)
+{
+ return lua_touserdata(L, index);
+}
+
+/*****************************************************************************
+* field operations
+*****************************************************************************/
+// return to C++, from table at index, the value of field k
+template <typename T>
+auto lua_getfieldv(lua_State* L, int index, const char* k)
+{
+ luaL_checkstack(L, 1, nullptr);
+ lua_getfield(L, index, k);
+ LuaPopper pop(L, 1);
+ return lua_to<T>(L, -1);
+}
+
+// set in table at index, as field k, the specified C++ value
+template <typename T>
+auto lua_setfieldv(lua_State* L, int index, const char* k, const T& value)
+{
+ luaL_checkstack(L, 1, nullptr);
+ lua_push(L, value);
+ lua_setfield(L, index, k);
+}
+
+// return to C++, from table at index, the value of field k (without metamethods)
+template <typename T>
+auto lua_rawgetfield(lua_State* L, int index, const std::string_view& k)
+{
+ luaL_checkstack(L, 1, nullptr);
+ lua_pushlstring(L, k.data(), k.length());
+ lua_rawget(L, index);
+ LuaPopper pop(L, 1);
+ return lua_to<T>(L, -1);
+}
+
+// set in table at index, as field k, the specified C++ value (without metamethods)
+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_pushlstring(L, k.data(), k.length());
+ lua_push(L, value);
+ lua_rawset(L, index);
+}
+
+/*****************************************************************************
* lua_function (and helper class LuaFunction)
*****************************************************************************/
/**