aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-03 11:25:07 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-03 11:25:07 +0200
commit4995040204ca27b13ed4e52ad01d76111ae6b081 (patch)
treed4b78ee5382918c76a653d0483e904f1378404e6 /src
parenta2824ef0c87034d535d3b12e6d582dfcf2265f27 (diff)
downloadlanes-4995040204ca27b13ed4e52ad01d76111ae6b081.tar.gz
lanes-4995040204ca27b13ed4e52ad01d76111ae6b081.tar.bz2
lanes-4995040204ca27b13ed4e52ad01d76111ae6b081.zip
Some code factorization
Diffstat (limited to 'src')
-rw-r--r--src/compat.cpp12
-rw-r--r--src/compat.h3
-rw-r--r--src/deep.cpp24
-rw-r--r--src/keeper.cpp2
-rw-r--r--src/lanes.cpp70
-rw-r--r--src/state.cpp2
-rw-r--r--src/tools.cpp56
-rw-r--r--src/tools.h3
-rw-r--r--src/uniquekey.h22
9 files changed, 83 insertions, 111 deletions
diff --git a/src/compat.cpp b/src/compat.cpp
index 6ceed8f..1d38917 100644
--- a/src/compat.cpp
+++ b/src/compat.cpp
@@ -7,17 +7,17 @@
7 7
8// ################################################################################################# 8// #################################################################################################
9 9
10// a small helper to obtain the "package" module table from the registry instead of relying on the presence of _G.package 10// a small helper to obtain a module's table from the registry instead of relying on the presence of _G["<name>"]
11int luaG_getpackage(lua_State* L_) 11LuaType luaG_getmodule(lua_State* L_, char const* name_)
12{ 12{
13 STACK_CHECK_START_REL(L_, 0); 13 STACK_CHECK_START_REL(L_, 0);
14 int type{ lua503_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil 14 LuaType type{ static_cast<LuaType>(lua503_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE)) };// L_: _R._LOADED|nil
15 if (type != LUA_TTABLE) { // L_: _R._LOADED|nil 15 if (type != LuaType::TABLE) { // L_: _R._LOADED|nil
16 STACK_CHECK(L_, 1); 16 STACK_CHECK(L_, 1);
17 return type; 17 return type;
18 } 18 }
19 type = lua503_getfield(L_, -1, LUA_LOADLIBNAME); // L_: _R._LOADED package|nil 19 type = static_cast<LuaType>(lua503_getfield(L_, -1, name_)); // L_: _R._LOADED {module}|nil
20 lua_remove(L_, -2); // L_: package|nil 20 lua_remove(L_, -2); // L_: {module}|nil
21 STACK_CHECK(L_, 1); 21 STACK_CHECK(L_, 1);
22 return type; 22 return type;
23} 23}
diff --git a/src/compat.h b/src/compat.h
index f98e142..3a61268 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -21,6 +21,7 @@ extern "C"
21#endif // 64 bits 21#endif // 64 bits
22#else // LUA_JITLIBNAME 22#else // LUA_JITLIBNAME
23#define LUAJIT_FLAVOR() 0 23#define LUAJIT_FLAVOR() 0
24#define LUA_JITLIBNAME "jit"
24#endif // LUA_JITLIBNAME 25#endif // LUA_JITLIBNAME
25 26
26// code is now preferring Lua 5.4 API 27// code is now preferring Lua 5.4 API
@@ -219,4 +220,4 @@ inline char const* lua_typename(lua_State* L_, LuaType t_)
219 return lua_typename(L_, static_cast<int>(t_)); 220 return lua_typename(L_, static_cast<int>(t_));
220} 221}
221 222
222int luaG_getpackage(lua_State* L_); 223LuaType luaG_getmodule(lua_State* L_, char const* name_);
diff --git a/src/deep.cpp b/src/deep.cpp
index 735a14c..6570e55 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -71,7 +71,7 @@ void DeepFactory::storeDeepLookup(lua_State* L_) const
71 // the deep metatable is at the top of the stack // L_: mt 71 // the deep metatable is at the top of the stack // L_: mt
72 STACK_GROW(L_, 3); 72 STACK_GROW(L_, 3);
73 STACK_CHECK_START_REL(L_, 0); // L_: mt 73 STACK_CHECK_START_REL(L_, 0); // L_: mt
74 push_registry_subtable(L_, kDeepLookupRegKey); // L_: mt {} 74 std::ignore = kDeepLookupRegKey.getSubTable(L_, 0, 0); // L_: mt {}
75 lua_pushvalue(L_, -2); // L_: mt {} mt 75 lua_pushvalue(L_, -2); // L_: mt {} mt
76 lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} mt factory 76 lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} mt factory
77 lua_rawset(L_, -3); // L_: mt {} 77 lua_rawset(L_, -3); // L_: mt {}
@@ -176,6 +176,26 @@ void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_)
176 176
177// ################################################################################################# 177// #################################################################################################
178 178
179// TODO: convert to UniqueKey::getSubTableMode
180static void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_)
181{
182 STACK_GROW(L_, 4);
183 STACK_CHECK_START_REL(L_, 0);
184 if (!key_.getSubTable(L_, 0, 0)) { // L_: {}
185 // Set its metatable if requested
186 if (mode_) {
187 lua_createtable(L_, 0, 1); // L_: {} mt
188 lua_pushliteral(L_, "__mode"); // L_: {} mt "__mode"
189 lua_pushstring(L_, mode_); // L_: {} mt "__mode" mode
190 lua_rawset(L_, -3); // L_: {} mt
191 lua_setmetatable(L_, -2); // L_: {}
192 }
193 }
194 STACK_CHECK(L_, 1);
195}
196
197// #################################################################################################
198
179/* 199/*
180 * Push a proxy userdata on the stack. 200 * Push a proxy userdata on the stack.
181 * returns nullptr if ok, else some error string related to bad factory behavior or module require problem 201 * returns nullptr if ok, else some error string related to bad factory behavior or module require problem
@@ -228,7 +248,7 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
228 lua_getfield(L_, -1, "__gc"); // L_: DPC proxy metatable __gc 248 lua_getfield(L_, -1, "__gc"); // L_: DPC proxy metatable __gc
229 } else { 249 } else {
230 // keepers need a minimal metatable that only contains our own __gc 250 // keepers need a minimal metatable that only contains our own __gc
231 lua_newtable(L_); // L_: DPC proxy metatable 251 lua_createtable(L_, 0, 1); // L_: DPC proxy metatable
232 lua_pushnil(L_); // L_: DPC proxy metatable nil 252 lua_pushnil(L_); // L_: DPC proxy metatable nil
233 } 253 }
234 if (lua_isnil(L_, -1)) { 254 if (lua_isnil(L_, -1)) {
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 8e76247..bb510f4 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -658,7 +658,7 @@ void init_keepers(Universe* U_, lua_State* L_)
658 STACK_CHECK(K, 0); 658 STACK_CHECK(K, 0);
659 659
660 // copy package.path and package.cpath from the source state 660 // copy package.path and package.cpath from the source state
661 if (luaG_getpackage(L_) != LUA_TNIL) { // L_: settings package K: 661 if (luaG_getmodule(L_, LUA_LOADLIBNAME) != LuaType::NIL) { // L_: settings package K:
662 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately 662 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately
663 InterCopyContext c{ U_, DestState{ K }, SourceState{ L_ }, {}, SourceIndex{ lua_absindex(L_, -1) }, {}, LookupMode::ToKeeper, {} }; 663 InterCopyContext c{ U_, DestState{ K }, SourceState{ L_ }, {}, SourceIndex{ lua_absindex(L_, -1) }, {}, LookupMode::ToKeeper, {} };
664 if (c.inter_copy_package() != InterCopyResult::Success) { // L_: settings ... error_msg K: 664 if (c.inter_copy_package() != InterCopyResult::Success) { // L_: settings ... error_msg K:
diff --git a/src/lanes.cpp b/src/lanes.cpp
index d027cff..87edb02 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -206,13 +206,16 @@ static void securize_debug_threadname(lua_State* L_, Lane* lane_)
206{ 206{
207 STACK_CHECK_START_REL(L_, 0); 207 STACK_CHECK_START_REL(L_, 0);
208 STACK_GROW(L_, 3); 208 STACK_GROW(L_, 3);
209 lua_getiuservalue(L_, 1, 1); 209 // a Lane's uservalue should be a table
210 lua_newtable(L_); 210 lua_getiuservalue(L_, 1, 1); // L_: lane ... {uv}
211 LUA_ASSERT(L_, lua_istable(L_, -1));
212 // we don't care about the actual key, so long as it's unique and can't collide with anything.
213 lua_newtable(L_); // L_: lane ... {uv} {}
211 // Lua 5.1 can't do 'lane_->debugName = lua_pushstring(L_, lane_->debugName);' 214 // Lua 5.1 can't do 'lane_->debugName = lua_pushstring(L_, lane_->debugName);'
212 lua_pushstring(L_, lane_->debugName); 215 lua_pushstring(L_, lane_->debugName); // L_: lane ... {uv} {} name
213 lane_->debugName = lua_tostring(L_, -1); 216 lane_->debugName = lua_tostring(L_, -1);
214 lua_rawset(L_, -3); 217 lua_rawset(L_, -3); // L_: lane ... {uv}
215 lua_pop(L_, 1); 218 lua_pop(L_, 1); // L_: lane
216 STACK_CHECK(L_, 0); 219 STACK_CHECK(L_, 0);
217} 220}
218 221
@@ -253,25 +256,6 @@ Lane::~Lane()
253// ########################################## Finalizer ############################################ 256// ########################################## Finalizer ############################################
254// ################################################################################################# 257// #################################################################################################
255 258
256// Push the finalizers table on the stack.
257// If there is no existing table, create ti.
258static void push_finalizers_table(lua_State* L_)
259{
260 STACK_GROW(L_, 3);
261 STACK_CHECK_START_REL(L_, 0);
262
263 kFinalizerRegKey.pushValue(L_); // L_: ?
264 if (lua_isnil(L_, -1)) { // L_: nil?
265 lua_pop(L_, 1); // L_:
266 // store a newly created table in the registry, but leave it on the stack too
267 lua_newtable(L_); // L_: t
268 kFinalizerRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // L_: t
269 }
270 STACK_CHECK(L_, 1);
271}
272
273// #################################################################################################
274
275// void= finalizer( finalizer_func ) 259// void= finalizer( finalizer_func )
276// 260//
277// finalizer_func( [err, stack_tbl] ) 261// finalizer_func( [err, stack_tbl] )
@@ -283,13 +267,14 @@ LUAG_FUNC(set_finalizer)
283{ 267{
284 luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function"); 268 luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function");
285 luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments"); 269 luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments");
270 STACK_GROW(L_, 3);
286 // Get the current finalizer table (if any), create one if it doesn't exist 271 // Get the current finalizer table (if any), create one if it doesn't exist
287 push_finalizers_table(L_); // L_: finalizer {finalisers} 272 std::ignore = kFinalizerRegKey.getSubTable(L_, 1, 0); // L_: finalizer {finalisers}
288 STACK_GROW(L_, 2); 273 // must cast to int, not lua_Integer, because LuaJIT signature of lua_rawseti is not the same as PUC-Lua.
289 lua_pushinteger(L_, lua_rawlen(L_, -1) + 1); // L_: finalizer {finalisers} idx 274 int const idx{ static_cast<int>(lua_rawlen(L_, -1) + 1) };
290 lua_pushvalue(L_, 1); // L_: finalizer {finalisers} idx finalizer 275 lua_pushvalue(L_, 1); // L_: finalizer {finalisers} finalizer
291 lua_rawset(L_, -3); // L_: finalizer {finalisers} 276 lua_rawseti(L_, -2, idx); // L_: finalizer {finalisers}
292 lua_pop(L_, 2); // L_: 277 // no need to adjust the stack, Lua does this for us
293 return 0; 278 return 0;
294} 279}
295 280
@@ -1020,13 +1005,13 @@ LUAG_FUNC(lane_new)
1020 1005
1021 // Create uservalue for the userdata 1006 // Create uservalue for the userdata
1022 // (this is where lane body return values will be stored when the handle is indexed by a numeric key) 1007 // (this is where lane body return values will be stored when the handle is indexed by a numeric key)
1023 lua_newtable(m_L); // m_L: ... lane uv 1008 lua_newtable(m_L); // m_L: ... lane {uv}
1024 1009
1025 // Store the gc_cb callback in the uservalue 1010 // Store the gc_cb callback in the uservalue
1026 if (m_gc_cb_idx > 0) { 1011 if (m_gc_cb_idx > 0) {
1027 kLaneGC.pushKey(m_L); // m_L: ... lane uv k 1012 kLaneGC.pushKey(m_L); // m_L: ... lane {uv} k
1028 lua_pushvalue(m_L, m_gc_cb_idx); // m_L: ... lane uv k gc_cb 1013 lua_pushvalue(m_L, m_gc_cb_idx); // m_L: ... lane {uv} k gc_cb
1029 lua_rawset(m_L, -3); // m_L: ... lane uv 1014 lua_rawset(m_L, -3); // m_L: ... lane {uv}
1030 } 1015 }
1031 1016
1032 lua_setiuservalue(m_L, -2, 1); // m_L: ... lane 1017 lua_setiuservalue(m_L, -2, 1); // m_L: ... lane
@@ -1515,7 +1500,7 @@ LUAG_FUNC(threads)
1515 lua_newtable(L_); // L_: {} 1500 lua_newtable(L_); // L_: {}
1516 while (lane != TRACKING_END) { 1501 while (lane != TRACKING_END) {
1517 // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other 1502 // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other
1518 lua_newtable(L_); // L_: {} {} 1503 lua_createtable(L_, 0, 2); // L_: {} {}
1519 lua_pushstring(L_, lane->debugName); // L_: {} {} "name" 1504 lua_pushstring(L_, lane->debugName); // L_: {} {} "name"
1520 lua_setfield(L_, -2, "name"); // L_: {} {} 1505 lua_setfield(L_, -2, "name"); // L_: {} {}
1521 lane->pushThreadStatus(L_); // L_: {} {} "status" 1506 lane->pushThreadStatus(L_); // L_: {} {} "status"
@@ -1648,11 +1633,11 @@ LUAG_FUNC(configure)
1648 if (U == nullptr) { 1633 if (U == nullptr) {
1649 U = universe_create(L_); // L_: settings universe 1634 U = universe_create(L_); // L_: settings universe
1650 DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); 1635 DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U });
1651 lua_newtable(L_); // L_: settings universe mt 1636 lua_createtable(L_, 0, 1); // L_: settings universe {mt}
1652 lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe mt shutdown_timeout 1637 lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout
1653 lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe mt shutdown_timeout shutdown_mode 1638 lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode
1654 lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe mt universe_gc 1639 lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe {mt} universe_gc
1655 lua_setfield(L_, -2, "__gc"); // L_: settings universe mt 1640 lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt}
1656 lua_setmetatable(L_, -2); // L_: settings universe 1641 lua_setmetatable(L_, -2); // L_: settings universe
1657 lua_pop(L_, 1); // L_: settings 1642 lua_pop(L_, 1); // L_: settings
1658 lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors 1643 lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors
@@ -1862,12 +1847,11 @@ LANES_API int luaopen_lanes_core(lua_State* L_)
1862 STACK_CHECK_START_REL(L_, 0); 1847 STACK_CHECK_START_REL(L_, 0);
1863 1848
1864 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too 1849 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too
1865 lua_getglobal(L_, "jit"); // L_: {jit?}
1866#if LUAJIT_FLAVOR() == 0 1850#if LUAJIT_FLAVOR() == 0
1867 if (!lua_isnil(L_, -1)) 1851 if (luaG_getmodule(L_, LUA_JITLIBNAME) != LuaType::NIL)
1868 raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT"); 1852 raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT");
1869#else 1853#else
1870 if (lua_isnil(L_, -1)) 1854 if (luaG_getmodule(L_, LUA_JITLIBNAME) == LuaType::NIL)
1871 raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua"); 1855 raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua");
1872#endif 1856#endif
1873 lua_pop(L_, 1); // L_: 1857 lua_pop(L_, 1); // L_:
diff --git a/src/state.cpp b/src/state.cpp
index 2893907..a3dfbcd 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -233,7 +233,7 @@ void initializeOnStateCreate(Universe* U_, lua_State* L_)
233 233
234// ################################################################################################# 234// #################################################################################################
235 235
236lua_State* create_state(Universe* U_, lua_State* from_) 236lua_State* create_state([[maybe_unused]] Universe* U_, lua_State* from_)
237{ 237{
238 lua_State* L; 238 lua_State* L;
239#if LUAJIT_FLAVOR() == 64 239#if LUAJIT_FLAVOR() == 64
diff --git a/src/tools.cpp b/src/tools.cpp
index 049a065..302d4cc 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -42,48 +42,6 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull };
42 42
43// ################################################################################################# 43// #################################################################################################
44 44
45// does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it
46void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_)
47{
48 STACK_GROW(L_, 3);
49 STACK_CHECK_START_REL(L_, 0);
50
51 key_.pushValue(L_); // L_: {}|nil
52 STACK_CHECK(L_, 1);
53
54 if (lua_isnil(L_, -1)) {
55 lua_pop(L_, 1); // L_:
56 lua_newtable(L_); // L_: {}
57 // _R[key_] = {}
58 key_.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // L_: {}
59 STACK_CHECK(L_, 1);
60
61 // Set its metatable if requested
62 if (mode_) {
63 lua_newtable(L_); // L_: {} mt
64 lua_pushliteral(L_, "__mode"); // L_: {} mt "__mode"
65 lua_pushstring(L_, mode_); // L_: {} mt "__mode" mode
66 lua_rawset(L_, -3); // L_: {} mt
67 lua_setmetatable(L_, -2); // L_: {}
68 }
69 }
70 STACK_CHECK(L_, 1);
71 LUA_ASSERT(L_, lua_istable(L_, -1));
72}
73
74// #################################################################################################
75
76/*
77 * Push a registry subtable (keyed by unique 'key_') onto the stack.
78 * If the subtable does not exist, it is created and chained.
79 */
80void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_)
81{
82 push_registry_subtable_mode(L_, key_, nullptr);
83}
84
85// #################################################################################################
86
87// same as PUC-Lua l_alloc 45// same as PUC-Lua l_alloc
88extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) 46extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_)
89{ 47{
@@ -459,13 +417,7 @@ void populate_func_lookup_table(lua_State* L_, int i_, char const* name_)
459 STACK_CHECK(L_, 2); 417 STACK_CHECK(L_, 2);
460 } 418 }
461 // retrieve the cache, create it if we haven't done it yet 419 // retrieve the cache, create it if we haven't done it yet
462 kLookupCacheRegKey.pushValue(L_); // L_: {} {fqn} {cache}? 420 std::ignore = kLookupCacheRegKey.getSubTable(L_, 0, 0); // L_: {} {fqn} {cache}
463 if (lua_isnil(L_, -1)) {
464 lua_pop(L_, 1); // L_: {} {fqn}
465 lua_newtable(L_); // L_: {} {fqn} {cache}
466 kLookupCacheRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); });
467 STACK_CHECK(L_, 3);
468 }
469 // process everything we find in that table, filling in lookup data for all functions and tables we see there 421 // process everything we find in that table, filling in lookup data for all functions and tables we see there
470 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, dbIdx, in_base, startDepth); 422 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, dbIdx, in_base, startDepth);
471 lua_pop(L_, 3); // L_: 423 lua_pop(L_, 3); // L_:
@@ -491,7 +443,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
491 STACK_GROW(L_, 3); 443 STACK_GROW(L_, 3);
492 444
493 STACK_CHECK_START_REL(L_, 0); 445 STACK_CHECK_START_REL(L_, 0);
494 push_registry_subtable(L_, kMtIdRegKey); // L_: ... _R[kMtIdRegKey] 446 std::ignore = kMtIdRegKey.getSubTable(L_, 0, 0); // L_: ... _R[kMtIdRegKey]
495 lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt} 447 lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt}
496 lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk? 448 lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk?
497 449
@@ -1186,7 +1138,7 @@ void InterCopyContext::copy_cached_func() const
1186 STACK_CHECK_START_REL(L2, 0); 1138 STACK_CHECK_START_REL(L2, 0);
1187 STACK_GROW(L2, 4); 1139 STACK_GROW(L2, 4);
1188 // do we already know this metatable? 1140 // do we already know this metatable?
1189 push_registry_subtable(L2, kMtIdRegKey); // L2: _R[kMtIdRegKey] 1141 std::ignore = kMtIdRegKey.getSubTable(L2, 0, 0); // L2: _R[kMtIdRegKey]
1190 lua_pushinteger(L2, mt_id); // L2: _R[kMtIdRegKey] id 1142 lua_pushinteger(L2, mt_id); // L2: _R[kMtIdRegKey] id
1191 lua_rawget(L2, -2); // L2: _R[kMtIdRegKey] mt|nil 1143 lua_rawget(L2, -2); // L2: _R[kMtIdRegKey] mt|nil
1192 STACK_CHECK(L2, 2); 1144 STACK_CHECK(L2, 2);
@@ -1830,7 +1782,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1830 } 1782 }
1831 return InterCopyResult::Error; 1783 return InterCopyResult::Error;
1832 } 1784 }
1833 if (luaG_getpackage(L2) == LUA_TNIL) { // package library not loaded: do nothing 1785 if (luaG_getmodule(L2, LUA_LOADLIBNAME) == LuaType::NIL) { // package library not loaded: do nothing
1834 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END(U))); 1786 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END(U)));
1835 STACK_CHECK(L1, 0); 1787 STACK_CHECK(L1, 0);
1836 return InterCopyResult::Success; 1788 return InterCopyResult::Success;
diff --git a/src/tools.h b/src/tools.h
index 9d4ed4c..53d3a99 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -8,9 +8,6 @@ class Universe;
8 8
9// ################################################################################################# 9// #################################################################################################
10 10
11void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_);
12void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_);
13
14enum class VT 11enum class VT
15{ 12{
16 NORMAL, // keep this one first so that it's the value we get when we default-construct 13 NORMAL, // keep this one first so that it's the value we get when we default-construct
diff --git a/src/uniquekey.h b/src/uniquekey.h
index da699b0..6265a56 100644
--- a/src/uniquekey.h
+++ b/src/uniquekey.h
@@ -68,7 +68,7 @@ class RegistryUniqueKey
68 } 68 }
69 // --------------------------------------------------------------------------------------------- 69 // ---------------------------------------------------------------------------------------------
70 template <typename T> 70 template <typename T>
71 T* readLightUserDataValue(lua_State* const L_) const 71 [[nodiscard]] T* readLightUserDataValue(lua_State* const L_) const
72 { 72 {
73 STACK_GROW(L_, 1); 73 STACK_GROW(L_, 1);
74 STACK_CHECK_START_REL(L_, 0); 74 STACK_CHECK_START_REL(L_, 0);
@@ -79,7 +79,7 @@ class RegistryUniqueKey
79 return value; 79 return value;
80 } 80 }
81 // --------------------------------------------------------------------------------------------- 81 // ---------------------------------------------------------------------------------------------
82 bool readBoolValue(lua_State* const L_) const 82 [[nodiscard]] bool readBoolValue(lua_State* const L_) const
83 { 83 {
84 STACK_GROW(L_, 1); 84 STACK_GROW(L_, 1);
85 STACK_CHECK_START_REL(L_, 0); 85 STACK_CHECK_START_REL(L_, 0);
@@ -89,6 +89,24 @@ class RegistryUniqueKey
89 STACK_CHECK(L_, 0); 89 STACK_CHECK(L_, 0);
90 return value; 90 return value;
91 } 91 }
92 // ---------------------------------------------------------------------------------------------
93 // equivalent to luaL_getsubtable
94 [[nodiscard]] bool getSubTable(lua_State* const L_, int narr_, int nrec_) const
95 {
96 STACK_CHECK_START_REL(L_, 0);
97 pushValue(L_); // L_: {}|nil
98 if (!lua_isnil(L_, -1)) {
99 LUA_ASSERT(L_, lua_istable(L_, -1));
100 STACK_CHECK(L_, 1);
101 return true; // table already exists
102 }
103 lua_pop(L_, 1); // L_:
104 // store a newly created table in the registry, but leave it on the stack too
105 lua_createtable(L_, narr_, nrec_); // L_: {}
106 setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // L_: {}
107 STACK_CHECK(L_, 1);
108 return false;
109 }
92}; 110};
93 111
94// ################################################################################################# 112// #################################################################################################