diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2024-06-27 19:01:28 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2024-06-27 19:01:28 -0400 |
commit | 6ee98f4e9b5ea9ade06056a9d1f4c1e0b1c00b44 (patch) | |
tree | 2bab89e3bf7c10f8e27e1fdf5543103a91cb129d /indra/llcommon/lua_function.cpp | |
parent | b347ad5deb1c9abb210ac5da0534766bf5b6f2f0 (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