aboutsummaryrefslogtreecommitdiff
path: root/src/tools.cpp
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-10-08 18:42:39 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-10-08 18:42:39 +0200
commit16b5070c0cd56e10c5074eb9903dbc3ae4e15a61 (patch)
treef6d5cdb74b505e13aa3261f7ab6192da0133b7b9 /src/tools.cpp
parente939e5e6a894a042d3301e47faa05264445f27f6 (diff)
downloadlanes-16b5070c0cd56e10c5074eb9903dbc3ae4e15a61.tar.gz
lanes-16b5070c0cd56e10c5074eb9903dbc3ae4e15a61.tar.bz2
lanes-16b5070c0cd56e10c5074eb9903dbc3ae4e15a61.zip
Sprinkling StackIndex all over the place
Diffstat (limited to 'src/tools.cpp')
-rw-r--r--src/tools.cpp50
1 files changed, 24 insertions, 26 deletions
diff --git a/src/tools.cpp b/src/tools.cpp
index d580f67..d0204a6 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -66,7 +66,7 @@ static constexpr int kWriterReturnCode{ 666 };
66 * +-----------------+-------------------+------------+----------+ 66 * +-----------------+-------------------+------------+----------+
67 */ 67 */
68 68
69FuncSubType luaG_getfuncsubtype(lua_State* const L_, int const i_) 69FuncSubType luaG_getfuncsubtype(lua_State* const L_, StackIndex const i_)
70{ 70{
71 if (lua_tocfunction(L_, i_)) { // nullptr for LuaJIT-fast && bytecode functions 71 if (lua_tocfunction(L_, i_)) { // nullptr for LuaJIT-fast && bytecode functions
72 return FuncSubType::Native; 72 return FuncSubType::Native;
@@ -92,7 +92,7 @@ FuncSubType luaG_getfuncsubtype(lua_State* const L_, int const i_)
92namespace tools { 92namespace tools {
93 93
94 // inspired from tconcat() in ltablib.c 94 // inspired from tconcat() in ltablib.c
95 std::string_view PushFQN(lua_State* const L_, int const t_, int const last_) 95 std::string_view PushFQN(lua_State* const L_, StackIndex const t_, int const last_)
96 { 96 {
97 STACK_CHECK_START_REL(L_, 0); 97 STACK_CHECK_START_REL(L_, 0);
98 // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... 98 // Lua 5.4 pushes &b as light userdata on the stack. be aware of it...
@@ -111,7 +111,7 @@ namespace tools {
111 // &b is popped at that point (-> replaced by the result) 111 // &b is popped at that point (-> replaced by the result)
112 luaL_pushresult(&_b); // L_: ... {} ... "<result>" 112 luaL_pushresult(&_b); // L_: ... {} ... "<result>"
113 STACK_CHECK(L_, 1); 113 STACK_CHECK(L_, 1);
114 return luaG_tostring(L_, -1); 114 return luaG_tostring(L_, kIdxTop);
115 } 115 }
116 116
117} // namespace tools 117} // namespace tools
@@ -126,12 +126,12 @@ namespace tools {
126 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter 126 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter
127 * pops the processed object from the stack 127 * pops the processed object from the stack
128 */ 128 */
129static void update_lookup_entry(lua_State* L_, int ctxBase_, int depth_) 129static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, int const depth_)
130{ 130{
131 // slot 1 in the stack contains the table that receives everything we found 131 // slot 1 in the stack contains the table that receives everything we found
132 int const _dest{ ctxBase_ }; 132 StackIndex const _dest{ ctxBase_ };
133 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i 133 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
134 int const _fqn{ ctxBase_ + 1 }; 134 StackIndex const _fqn{ ctxBase_ + 1 };
135 135
136 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); 136 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) });
137 DEBUGSPEW_CODE(DebugSpew(_U) << "update_lookup_entry()" << std::endl); 137 DEBUGSPEW_CODE(DebugSpew(_U) << "update_lookup_entry()" << std::endl);
@@ -141,14 +141,14 @@ static void update_lookup_entry(lua_State* L_, int ctxBase_, int depth_)
141 // first, raise an error if the function is already known 141 // first, raise an error if the function is already known
142 lua_pushvalue(L_, -1); // L_: ... {bfc} k o o 142 lua_pushvalue(L_, -1); // L_: ... {bfc} k o o
143 lua_rawget(L_, _dest); // L_: ... {bfc} k o name? 143 lua_rawget(L_, _dest); // L_: ... {bfc} k o name?
144 std::string_view const _prevName{ luaG_tostring(L_, -1) }; // nullptr if we got nil (first encounter of this object) 144 std::string_view const _prevName{ luaG_tostring(L_, kIdxTop) }; // nullptr if we got nil (first encounter of this object)
145 // push name in fqn stack (note that concatenation will crash if name is a not string or a number) 145 // push name in fqn stack (note that concatenation will crash if name is a not string or a number)
146 lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k 146 lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k
147 LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::NUMBER || luaG_type(L_, -1) == LuaType::STRING); 147 LUA_ASSERT(L_, luaG_type(L_, kIdxTop) == LuaType::NUMBER || luaG_type(L_, kIdxTop) == LuaType::STRING);
148 ++depth_; 148 int const _deeper{ depth_ + 1 };
149 lua_rawseti(L_, _fqn, depth_); // L_: ... {bfc} k o name? 149 lua_rawseti(L_, _fqn, _deeper); // L_: ... {bfc} k o name?
150 // generate name 150 // generate name
151 std::string_view const _newName{ tools::PushFQN(L_, _fqn, depth_) }; // L_: ... {bfc} k o name? "f.q.n" 151 std::string_view const _newName{ tools::PushFQN(L_, _fqn, _deeper) }; // L_: ... {bfc} k o name? "f.q.n"
152 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order 152 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
153 // on different VMs even when the tables are populated the exact same way. 153 // on different VMs even when the tables are populated the exact same way.
154 // Also, when Lua is built with compatibility options (such as LUA_COMPAT_ALL), some base libraries register functions under multiple names. 154 // Also, when Lua is built with compatibility options (such as LUA_COMPAT_ALL), some base libraries register functions under multiple names.
@@ -183,21 +183,20 @@ static void update_lookup_entry(lua_State* L_, int ctxBase_, int depth_)
183 lua_rawset(L_, _dest); // L_: ... {bfc} k 183 lua_rawset(L_, _dest); // L_: ... {bfc} k
184 // remove table name from fqn stack 184 // remove table name from fqn stack
185 lua_pushnil(L_); // L_: ... {bfc} k nil 185 lua_pushnil(L_); // L_: ... {bfc} k nil
186 lua_rawseti(L_, _fqn, depth_); // L_: ... {bfc} k 186 lua_rawseti(L_, _fqn, _deeper); // L_: ... {bfc} k
187 } 187 }
188 --depth_;
189 STACK_CHECK(L_, -1); 188 STACK_CHECK(L_, -1);
190} 189}
191 190
192// ################################################################################################# 191// #################################################################################################
193 192
194static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, int depth_) 193static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex const dbIdx_, StackIndex const i_, int const depth_)
195{ 194{
196 // slot dbIdx_ contains the lookup database table 195 // slot dbIdx_ contains the lookup database table
197 // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_ 196 // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_
198 int const _fqn{ dbIdx_ + 1 }; 197 StackIndex const _fqn{ dbIdx_ + 1 };
199 // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops 198 // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops
200 int const _cache{ dbIdx_ + 2 }; 199 StackIndex const _cache{ dbIdx_ + 2 };
201 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); 200 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) });
202 DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl); 201 DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl);
203 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 202 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
@@ -253,7 +252,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_,
253 lua_rawset(L_, breadthFirstCache); // L_: ... {i_} {bfc} k {} 252 lua_rawset(L_, breadthFirstCache); // L_: ... {i_} {bfc} k {}
254 // generate a name, and if we already had one name, keep whichever is the shorter 253 // generate a name, and if we already had one name, keep whichever is the shorter
255 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k 254 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k
256 } else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, -1) != FuncSubType::Bytecode)) { 255 } else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, kIdxTop) != FuncSubType::Bytecode)) {
257 // generate a name, and if we already had one name, keep whichever is the shorter 256 // generate a name, and if we already had one name, keep whichever is the shorter
258 // this pops the function from the stack 257 // this pops the function from the stack
259 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k 258 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k
@@ -263,7 +262,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_,
263 STACK_CHECK(L_, 2); 262 STACK_CHECK(L_, 2);
264 } 263 }
265 // now process the tables we encountered at that depth 264 // now process the tables we encountered at that depth
266 ++depth_; 265 int const _deeper{ depth_ + 1 };
267 lua_pushnil(L_); // L_: ... {i_} {bfc} nil 266 lua_pushnil(L_); // L_: ... {i_} {bfc} nil
268 while (lua_next(L_, breadthFirstCache) != 0) { // L_: ... {i_} {bfc} k {} 267 while (lua_next(L_, breadthFirstCache) != 0) { // L_: ... {i_} {bfc} k {}
269 DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : std::string_view{ "<not a string>" } }); 268 DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : std::string_view{ "<not a string>" } });
@@ -272,7 +271,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_,
272 // un-visit this table in case we do need to process it 271 // un-visit this table in case we do need to process it
273 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} 272 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {}
274 lua_rawget(L_, _cache); // L_: ... {i_} {bfc} k {} n 273 lua_rawget(L_, _cache); // L_: ... {i_} {bfc} k {} n
275 LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::NUMBER); 274 LUA_ASSERT(L_, luaG_type(L_, kIdxTop) == LuaType::NUMBER);
276 _visit_count = lua_tointeger(L_, -1) - 1; 275 _visit_count = lua_tointeger(L_, -1) - 1;
277 lua_pop(L_, 1); // L_: ... {i_} {bfc} k {} 276 lua_pop(L_, 1); // L_: ... {i_} {bfc} k {}
278 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} 277 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {}
@@ -284,15 +283,14 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_,
284 lua_rawset(L_, _cache); // L_: ... {i_} {bfc} k {} 283 lua_rawset(L_, _cache); // L_: ... {i_} {bfc} k {}
285 // push table name in fqn stack (note that concatenation will crash if name is a not string!) 284 // push table name in fqn stack (note that concatenation will crash if name is a not string!)
286 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k 285 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k
287 lua_rawseti(L_, _fqn, depth_); // L_: ... {i_} {bfc} k {} 286 lua_rawseti(L_, _fqn, _deeper); // L_: ... {i_} {bfc} k {}
288 populate_func_lookup_table_recur(L_, dbIdx_, lua_gettop(L_), depth_); 287 populate_func_lookup_table_recur(L_, dbIdx_, StackIndex{ lua_gettop(L_) }, _deeper);
289 lua_pop(L_, 1); // L_: ... {i_} {bfc} k 288 lua_pop(L_, 1); // L_: ... {i_} {bfc} k
290 STACK_CHECK(L_, 2); 289 STACK_CHECK(L_, 2);
291 } 290 }
292 // remove table name from fqn stack 291 // remove table name from fqn stack
293 lua_pushnil(L_); // L_: ... {i_} {bfc} nil 292 lua_pushnil(L_); // L_: ... {i_} {bfc} nil
294 lua_rawseti(L_, _fqn, depth_); // L_: ... {i_} {bfc} 293 lua_rawseti(L_, _fqn, _deeper); // L_: ... {i_} {bfc}
295 --depth_;
296 // we are done with our cache 294 // we are done with our cache
297 lua_pop(L_, 1); // L_: ... {i_} 295 lua_pop(L_, 1); // L_: ... {i_}
298 STACK_CHECK(L_, 0); 296 STACK_CHECK(L_, 0);
@@ -304,9 +302,9 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_,
304namespace tools { 302namespace tools {
305 303
306 // create a "fully.qualified.name" <-> function equivalence database 304 // create a "fully.qualified.name" <-> function equivalence database
307 void PopulateFuncLookupTable(lua_State* const L_, int const i_, std::string_view const& name_) 305 void PopulateFuncLookupTable(lua_State* const L_, StackIndex const i_, std::string_view const& name_)
308 { 306 {
309 int const _in_base{ luaG_absindex(L_, i_) }; 307 StackIndex const _in_base{ luaG_absindex(L_, i_) };
310 DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_)); 308 DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_));
311 std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; 309 std::string_view _name{ name_.empty() ? std::string_view{} : name_ };
312 DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": PopulateFuncLookupTable('" << _name << "')" << std::endl); 310 DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": PopulateFuncLookupTable('" << _name << "')" << std::endl);
@@ -314,7 +312,7 @@ namespace tools {
314 STACK_GROW(L_, 3); 312 STACK_GROW(L_, 3);
315 STACK_CHECK_START_REL(L_, 0); 313 STACK_CHECK_START_REL(L_, 0);
316 kLookupRegKey.pushValue(L_); // L_: {} 314 kLookupRegKey.pushValue(L_); // L_: {}
317 int const _dbIdx{ lua_gettop(L_) }; 315 StackIndex const _dbIdx{ lua_gettop(L_) };
318 STACK_CHECK(L_, 1); 316 STACK_CHECK(L_, 1);
319 LUA_ASSERT(L_, lua_istable(L_, -1)); 317 LUA_ASSERT(L_, lua_istable(L_, -1));
320 if (luaG_type(L_, _in_base) == LuaType::FUNCTION) { // for example when a module is a simple function 318 if (luaG_type(L_, _in_base) == LuaType::FUNCTION) { // for example when a module is a simple function