summaryrefslogtreecommitdiff
path: root/indra/llcommon/lua_function.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-06-27 19:01:28 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-06-27 19:01:28 -0400
commit6ee98f4e9b5ea9ade06056a9d1f4c1e0b1c00b44 (patch)
tree2bab89e3bf7c10f8e27e1fdf5543103a91cb129d /indra/llcommon/lua_function.cpp
parentb347ad5deb1c9abb210ac5da0534766bf5b6f2f0 (diff)
Make lua_emplace<T>() use Luau userdata tags with destructors.
It turns out that Luau does not honor PUC-Rio Lua's __gc metafunction, so despite elaborate measures, the previous lua_emplace<T>() implementation would not have destroyed the contained C++ T object when the resulting userdata object was garbage-collected. Moreover, using LL.atexit() as the mechanism to destroy lua_emplace<T>() userdata objects (e.g. LuaListener) would have been slightly fragile because we also want to use LL.atexit() to make the final fiber.run() call, when appropriate. Introducing an order dependency between fiber.run() and the LuaListener destructor would not be robust. Both of those problems are addressed by leveraging one of Luau's extensions over PUC-Rio Lua. A Luau userdata object can have an int tag; and a tag can have an associated C++ destructor function. When any userdata object bearing that tag is garbage-collected, Luau will call that destructor; and Luau's lua_close() function destroys all userdata objects. The resulting lua_emplace<T>() and lua_toclass<T>() code is far simpler. It only remains to generate a distinct int tag value for each different C++ type passed to the lua_emplace<T>() template. unordered_map<std::type_index, int> addresses that need.
Diffstat (limited to 'indra/llcommon/lua_function.cpp')
0 files changed, 0 insertions, 0 deletions