diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-08 18:42:39 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-08 18:42:39 +0200 |
commit | 16b5070c0cd56e10c5074eb9903dbc3ae4e15a61 (patch) | |
tree | f6d5cdb74b505e13aa3261f7ab6192da0133b7b9 /src/tools.cpp | |
parent | e939e5e6a894a042d3301e47faa05264445f27f6 (diff) | |
download | lanes-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.cpp | 50 |
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 | ||
69 | FuncSubType luaG_getfuncsubtype(lua_State* const L_, int const i_) | 69 | FuncSubType 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_) | |||
92 | namespace tools { | 92 | namespace 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 | */ |
129 | static void update_lookup_entry(lua_State* L_, int ctxBase_, int depth_) | 129 | static 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 | ||
194 | static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, int depth_) | 193 | static 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_, | |||
304 | namespace tools { | 302 | namespace 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 |