diff options
Diffstat (limited to 'src/tools.cpp')
-rw-r--r-- | src/tools.cpp | 635 |
1 files changed, 317 insertions, 318 deletions
diff --git a/src/tools.cpp b/src/tools.cpp index 2497ba7..e11cad5 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
@@ -45,34 +45,34 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | |||
45 | /* | 45 | /* |
46 | * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it | 46 | * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it |
47 | */ | 47 | */ |
48 | void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const char* mode_) | 48 | void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_) |
49 | { | 49 | { |
50 | STACK_GROW(L, 3); | 50 | STACK_GROW(L_, 3); |
51 | STACK_CHECK_START_REL(L, 0); | 51 | STACK_CHECK_START_REL(L_, 0); |
52 | 52 | ||
53 | key_.pushValue(L); // {}|nil | 53 | key_.pushValue(L_); // {}|nil |
54 | STACK_CHECK(L, 1); | 54 | STACK_CHECK(L_, 1); |
55 | 55 | ||
56 | if (lua_isnil(L, -1)) | 56 | if (lua_isnil(L_, -1)) |
57 | { | 57 | { |
58 | lua_pop(L, 1); // | 58 | lua_pop(L_, 1); // |
59 | lua_newtable(L); // {} | 59 | lua_newtable(L_); // {} |
60 | // _R[key_] = {} | 60 | // _R[key_] = {} |
61 | key_.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // {} | 61 | key_.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // {} |
62 | STACK_CHECK(L, 1); | 62 | STACK_CHECK(L_, 1); |
63 | 63 | ||
64 | // Set its metatable if requested | 64 | // Set its metatable if requested |
65 | if (mode_) | 65 | if (mode_) |
66 | { | 66 | { |
67 | lua_newtable(L); // {} mt | 67 | lua_newtable(L_); // {} mt |
68 | lua_pushliteral(L, "__mode"); // {} mt "__mode" | 68 | lua_pushliteral(L_, "__mode"); // {} mt "__mode" |
69 | lua_pushstring(L, mode_); // {} mt "__mode" mode | 69 | lua_pushstring(L_, mode_); // {} mt "__mode" mode |
70 | lua_rawset(L, -3); // {} mt | 70 | lua_rawset(L_, -3); // {} mt |
71 | lua_setmetatable(L, -2); // {} | 71 | lua_setmetatable(L_, -2); // {} |
72 | } | 72 | } |
73 | } | 73 | } |
74 | STACK_CHECK(L, 1); | 74 | STACK_CHECK(L_, 1); |
75 | LUA_ASSERT(L, lua_istable(L, -1)); | 75 | LUA_ASSERT(L_, lua_istable(L_, -1)); |
76 | } | 76 | } |
77 | 77 | ||
78 | // ################################################################################################# | 78 | // ################################################################################################# |
@@ -81,9 +81,9 @@ void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const cha | |||
81 | * Push a registry subtable (keyed by unique 'key_') onto the stack. | 81 | * Push a registry subtable (keyed by unique 'key_') onto the stack. |
82 | * If the subtable does not exist, it is created and chained. | 82 | * If the subtable does not exist, it is created and chained. |
83 | */ | 83 | */ |
84 | void push_registry_subtable(lua_State* L, RegistryUniqueKey key_) | 84 | void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_) |
85 | { | 85 | { |
86 | push_registry_subtable_mode(L, key_, nullptr); | 86 | push_registry_subtable_mode(L_, key_, nullptr); |
87 | } | 87 | } |
88 | 88 | ||
89 | // ################################################################################################# | 89 | // ################################################################################################# |
@@ -104,11 +104,11 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, | |||
104 | 104 | ||
105 | // ################################################################################################# | 105 | // ################################################################################################# |
106 | 106 | ||
107 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L) | 107 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) |
108 | { | 108 | { |
109 | Universe* const U{ universe_get(L) }; | 109 | Universe* const U{ universe_get(L_) }; |
110 | // push a new full userdata on the stack, giving access to the universe's protected allocator | 110 | // push a new full userdata on the stack, giving access to the universe's protected allocator |
111 | [[maybe_unused]] AllocatorDefinition* const def{ new (L) AllocatorDefinition{ U->protected_allocator.makeDefinition() } }; | 111 | [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ U->protected_allocator.makeDefinition() } }; |
112 | return 1; | 112 | return 1; |
113 | } | 113 | } |
114 | 114 | ||
@@ -116,33 +116,33 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, | |||
116 | 116 | ||
117 | // called once at the creation of the universe (therefore L is the master Lua state everything originates from) | 117 | // called once at the creation of the universe (therefore L is the master Lua state everything originates from) |
118 | // Do I need to disable this when compiling for LuaJIT to prevent issues? | 118 | // Do I need to disable this when compiling for LuaJIT to prevent issues? |
119 | void initialize_allocator_function(Universe* U, lua_State* L) | 119 | void initialize_allocator_function(Universe* U, lua_State* L_) |
120 | { | 120 | { |
121 | STACK_CHECK_START_REL(L, 1); // settings | 121 | STACK_CHECK_START_REL(L_, 1); // settings |
122 | lua_getfield(L, -1, "allocator"); // settings allocator|nil|"protected" | 122 | lua_getfield(L_, -1, "allocator"); // settings allocator|nil|"protected" |
123 | if (!lua_isnil(L, -1)) | 123 | if (!lua_isnil(L_, -1)) |
124 | { | 124 | { |
125 | // store C function pointer in an internal variable | 125 | // store C function pointer in an internal variable |
126 | U->provide_allocator = lua_tocfunction(L, -1); // settings allocator | 126 | U->provide_allocator = lua_tocfunction(L_, -1); // settings allocator |
127 | if (U->provide_allocator != nullptr) | 127 | if (U->provide_allocator != nullptr) |
128 | { | 128 | { |
129 | // make sure the function doesn't have upvalues | 129 | // make sure the function doesn't have upvalues |
130 | char const* upname = lua_getupvalue(L, -1, 1); // settings allocator upval? | 130 | char const* upname = lua_getupvalue(L_, -1, 1); // settings allocator upval? |
131 | if (upname != nullptr) // should be "" for C functions with upvalues if any | 131 | if (upname != nullptr) // should be "" for C functions with upvalues if any |
132 | { | 132 | { |
133 | raise_luaL_error(L, "config.allocator() shouldn't have upvalues"); | 133 | raise_luaL_error(L_, "config.allocator() shouldn't have upvalues"); |
134 | } | 134 | } |
135 | // remove this C function from the config table so that it doesn't cause problems | 135 | // remove this C function from the config table so that it doesn't cause problems |
136 | // when we transfer the config table in newly created Lua states | 136 | // when we transfer the config table in newly created Lua states |
137 | lua_pushnil(L); // settings allocator nil | 137 | lua_pushnil(L_); // settings allocator nil |
138 | lua_setfield(L, -3, "allocator"); // settings allocator | 138 | lua_setfield(L_, -3, "allocator"); // settings allocator |
139 | } | 139 | } |
140 | else if (lua_type(L, -1) == LUA_TSTRING) // should be "protected" | 140 | else if (lua_type(L_, -1) == LUA_TSTRING) // should be "protected" |
141 | { | 141 | { |
142 | LUA_ASSERT(L, strcmp(lua_tostring(L, -1), "protected") == 0); | 142 | LUA_ASSERT(L_, strcmp(lua_tostring(L_, -1), "protected") == 0); |
143 | // set the original allocator to call from inside protection by the mutex | 143 | // set the original allocator to call from inside protection by the mutex |
144 | U->protected_allocator.initFrom(L); | 144 | U->protected_allocator.initFrom(L_); |
145 | U->protected_allocator.installIn(L); | 145 | U->protected_allocator.installIn(L_); |
146 | // before a state is created, this function will be called to obtain the allocator | 146 | // before a state is created, this function will be called to obtain the allocator |
147 | U->provide_allocator = luaG_provide_protected_allocator; | 147 | U->provide_allocator = luaG_provide_protected_allocator; |
148 | } | 148 | } |
@@ -150,14 +150,14 @@ void initialize_allocator_function(Universe* U, lua_State* L) | |||
150 | else | 150 | else |
151 | { | 151 | { |
152 | // just grab whatever allocator was provided to lua_newstate | 152 | // just grab whatever allocator was provided to lua_newstate |
153 | U->protected_allocator.initFrom(L); | 153 | U->protected_allocator.initFrom(L_); |
154 | } | 154 | } |
155 | lua_pop(L, 1); // settings | 155 | lua_pop(L_, 1); // settings |
156 | STACK_CHECK(L, 1); | 156 | STACK_CHECK(L_, 1); |
157 | 157 | ||
158 | lua_getfield(L, -1, "internal_allocator"); // settings "libc"|"allocator" | 158 | lua_getfield(L_, -1, "internal_allocator"); // settings "libc"|"allocator" |
159 | { | 159 | { |
160 | char const* allocator = lua_tostring(L, -1); | 160 | char const* allocator = lua_tostring(L_, -1); |
161 | if (strcmp(allocator, "libc") == 0) | 161 | if (strcmp(allocator, "libc") == 0) |
162 | { | 162 | { |
163 | U->internal_allocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; | 163 | U->internal_allocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; |
@@ -173,15 +173,14 @@ void initialize_allocator_function(Universe* U, lua_State* L) | |||
173 | U->internal_allocator = U->protected_allocator; | 173 | U->internal_allocator = U->protected_allocator; |
174 | } | 174 | } |
175 | } | 175 | } |
176 | lua_pop(L, 1); // settings | 176 | lua_pop(L_, 1); // settings |
177 | STACK_CHECK(L, 1); | 177 | STACK_CHECK(L_, 1); |
178 | } | 178 | } |
179 | 179 | ||
180 | // ################################################################################################# | 180 | // ################################################################################################# |
181 | 181 | ||
182 | [[nodiscard]] static int dummy_writer(lua_State* L, void const* p, size_t sz, void* ud) | 182 | [[nodiscard]] static int dummy_writer([[maybe_unused]] lua_State* L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) |
183 | { | 183 | { |
184 | (void)L; (void)p; (void)sz; (void) ud; // unused | ||
185 | return 666; | 184 | return 666; |
186 | } | 185 | } |
187 | 186 | ||
@@ -207,24 +206,24 @@ enum class FuncSubType | |||
207 | FastJIT | 206 | FastJIT |
208 | } ; | 207 | } ; |
209 | 208 | ||
210 | FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) | 209 | FuncSubType luaG_getfuncsubtype(lua_State* L_, int _i) |
211 | { | 210 | { |
212 | if (lua_tocfunction(L, _i)) // nullptr for LuaJIT-fast && bytecode functions | 211 | if (lua_tocfunction(L_, _i)) // nullptr for LuaJIT-fast && bytecode functions |
213 | { | 212 | { |
214 | return FuncSubType::Native; | 213 | return FuncSubType::Native; |
215 | } | 214 | } |
216 | { | 215 | { |
217 | int mustpush{ 0 }; | 216 | int mustpush{ 0 }; |
218 | if (lua_absindex(L, _i) != lua_gettop(L)) | 217 | if (lua_absindex(L_, _i) != lua_gettop(L_)) |
219 | { | 218 | { |
220 | lua_pushvalue(L, _i); | 219 | lua_pushvalue(L_, _i); |
221 | mustpush = 1; | 220 | mustpush = 1; |
222 | } | 221 | } |
223 | // the provided writer fails with code 666 | 222 | // the provided writer fails with code 666 |
224 | // therefore, anytime we get 666, this means that lua_dump() attempted a dump | 223 | // therefore, anytime we get 666, this means that lua_dump() attempted a dump |
225 | // all other cases mean this is either a C or LuaJIT-fast function | 224 | // all other cases mean this is either a C or LuaJIT-fast function |
226 | int const dumpres{ lua504_dump(L, dummy_writer, nullptr, 0) }; | 225 | int const dumpres{ lua504_dump(L_, dummy_writer, nullptr, 0) }; |
227 | lua_pop(L, mustpush); | 226 | lua_pop(L_, mustpush); |
228 | if (dumpres == 666) | 227 | if (dumpres == 666) |
229 | { | 228 | { |
230 | return FuncSubType::Bytecode; | 229 | return FuncSubType::Bytecode; |
@@ -236,28 +235,28 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) | |||
236 | // ################################################################################################# | 235 | // ################################################################################################# |
237 | 236 | ||
238 | // inspired from tconcat() in ltablib.c | 237 | // inspired from tconcat() in ltablib.c |
239 | [[nodiscard]] static char const* luaG_pushFQN(lua_State* L, int t, int last, size_t* length) | 238 | [[nodiscard]] static char const* luaG_pushFQN(lua_State* L_, int t, int last, size_t* length) |
240 | { | 239 | { |
241 | luaL_Buffer b; | 240 | luaL_Buffer b; |
242 | STACK_CHECK_START_REL(L, 0); | 241 | STACK_CHECK_START_REL(L_, 0); |
243 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... | 242 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... |
244 | luaL_buffinit(L, &b); // ... {} ... &b? | 243 | luaL_buffinit(L_, &b); // ... {} ... &b? |
245 | int i = 1; | 244 | int i = 1; |
246 | for (; i < last; ++i) | 245 | for (; i < last; ++i) |
247 | { | 246 | { |
248 | lua_rawgeti( L, t, i); | 247 | lua_rawgeti( L_, t, i); |
249 | luaL_addvalue( &b); | 248 | luaL_addvalue( &b); |
250 | luaL_addlstring(&b, "/", 1); | 249 | luaL_addlstring(&b, "/", 1); |
251 | } | 250 | } |
252 | if (i == last) // add last value (if interval was not empty) | 251 | if (i == last) // add last value (if interval was not empty) |
253 | { | 252 | { |
254 | lua_rawgeti(L, t, i); | 253 | lua_rawgeti(L_, t, i); |
255 | luaL_addvalue(&b); | 254 | luaL_addvalue(&b); |
256 | } | 255 | } |
257 | // &b is popped at that point (-> replaced by the result) | 256 | // &b is popped at that point (-> replaced by the result) |
258 | luaL_pushresult(&b); // ... {} ... "<result>" | 257 | luaL_pushresult(&b); // ... {} ... "<result>" |
259 | STACK_CHECK(L, 1); | 258 | STACK_CHECK(L_, 1); |
260 | return lua_tolstring( L, -1, length); | 259 | return lua_tolstring( L_, -1, length); |
261 | } | 260 | } |
262 | 261 | ||
263 | // ################################################################################################# | 262 | // ################################################################################################# |
@@ -270,7 +269,7 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) | |||
270 | * if we already had an entry of type [o] = ..., replace the name if the new one is shorter | 269 | * if we already had an entry of type [o] = ..., replace the name if the new one is shorter |
271 | * pops the processed object from the stack | 270 | * pops the processed object from the stack |
272 | */ | 271 | */ |
273 | static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _depth) | 272 | static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _depth) |
274 | { | 273 | { |
275 | // slot 1 in the stack contains the table that receives everything we found | 274 | // slot 1 in the stack contains the table that receives everything we found |
276 | int const dest{ _ctx_base }; | 275 | int const dest{ _ctx_base }; |
@@ -283,18 +282,18 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, | |||
283 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); | 282 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); |
284 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 283 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
285 | 284 | ||
286 | STACK_CHECK_START_REL(L, 0); | 285 | STACK_CHECK_START_REL(L_, 0); |
287 | // first, raise an error if the function is already known | 286 | // first, raise an error if the function is already known |
288 | lua_pushvalue(L, -1); // ... {bfc} k o o | 287 | lua_pushvalue(L_, -1); // ... {bfc} k o o |
289 | lua_rawget(L, dest); // ... {bfc} k o name? | 288 | lua_rawget(L_, dest); // ... {bfc} k o name? |
290 | prevName = lua_tolstring( L, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) | 289 | prevName = lua_tolstring( L_, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) |
291 | // push name in fqn stack (note that concatenation will crash if name is a not string or a number) | 290 | // push name in fqn stack (note that concatenation will crash if name is a not string or a number) |
292 | lua_pushvalue(L, -3); // ... {bfc} k o name? k | 291 | lua_pushvalue(L_, -3); // ... {bfc} k o name? k |
293 | LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER || lua_type(L, -1) == LUA_TSTRING); | 292 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING); |
294 | ++_depth; | 293 | ++_depth; |
295 | lua_rawseti(L, fqn, _depth); // ... {bfc} k o name? | 294 | lua_rawseti(L_, fqn, _depth); // ... {bfc} k o name? |
296 | // generate name | 295 | // generate name |
297 | DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n" | 296 | DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n" |
298 | // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order | 297 | // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order |
299 | // on different VMs even when the tables are populated the exact same way. | 298 | // on different VMs even when the tables are populated the exact same way. |
300 | // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), | 299 | // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), |
@@ -304,11 +303,11 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, | |||
304 | // Also, nothing prevents any external module from exposing a given object under several names, so... | 303 | // Also, nothing prevents any external module from exposing a given object under several names, so... |
305 | // Therefore, when we encounter an object for which a name was previously registered, we need to select the names | 304 | // Therefore, when we encounter an object for which a name was previously registered, we need to select the names |
306 | // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded | 305 | // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded |
307 | if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L, -2, -1))) | 306 | if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L_, -2, -1))) |
308 | { | 307 | { |
309 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName)); | 308 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName)); |
310 | // the previous name is 'smaller' than the one we just generated: keep it! | 309 | // the previous name is 'smaller' than the one we just generated: keep it! |
311 | lua_pop(L, 3); // ... {bfc} k | 310 | lua_pop(L_, 3); // ... {bfc} k |
312 | } | 311 | } |
313 | else | 312 | else |
314 | { | 313 | { |
@@ -316,63 +315,63 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, | |||
316 | if (prevName) | 315 | if (prevName) |
317 | { | 316 | { |
318 | // clear the previous name for the database to avoid clutter | 317 | // clear the previous name for the database to avoid clutter |
319 | lua_insert(L, -2); // ... {bfc} k o "f.q.n" prevName | 318 | lua_insert(L_, -2); // ... {bfc} k o "f.q.n" prevName |
320 | // t[prevName] = nil | 319 | // t[prevName] = nil |
321 | lua_pushnil(L); // ... {bfc} k o "f.q.n" prevName nil | 320 | lua_pushnil(L_); // ... {bfc} k o "f.q.n" prevName nil |
322 | lua_rawset(L, dest); // ... {bfc} k o "f.q.n" | 321 | lua_rawset(L_, dest); // ... {bfc} k o "f.q.n" |
323 | } | 322 | } |
324 | else | 323 | else |
325 | { | 324 | { |
326 | lua_remove(L, -2); // ... {bfc} k o "f.q.n" | 325 | lua_remove(L_, -2); // ... {bfc} k o "f.q.n" |
327 | } | 326 | } |
328 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename(L, lua_type( L, -2)), newName)); | 327 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename(L, lua_type( L, -2)), newName)); |
329 | // prepare the stack for database feed | 328 | // prepare the stack for database feed |
330 | lua_pushvalue(L, -1); // ... {bfc} k o "f.q.n" "f.q.n" | 329 | lua_pushvalue(L_, -1); // ... {bfc} k o "f.q.n" "f.q.n" |
331 | lua_pushvalue(L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o | 330 | lua_pushvalue(L_, -3); // ... {bfc} k o "f.q.n" "f.q.n" o |
332 | LUA_ASSERT(L, lua_rawequal(L, -1, -4)); | 331 | LUA_ASSERT(L_, lua_rawequal(L_, -1, -4)); |
333 | LUA_ASSERT(L, lua_rawequal(L, -2, -3)); | 332 | LUA_ASSERT(L_, lua_rawequal(L_, -2, -3)); |
334 | // t["f.q.n"] = o | 333 | // t["f.q.n"] = o |
335 | lua_rawset(L, dest); // ... {bfc} k o "f.q.n" | 334 | lua_rawset(L_, dest); // ... {bfc} k o "f.q.n" |
336 | // t[o] = "f.q.n" | 335 | // t[o] = "f.q.n" |
337 | lua_rawset(L, dest); // ... {bfc} k | 336 | lua_rawset(L_, dest); // ... {bfc} k |
338 | // remove table name from fqn stack | 337 | // remove table name from fqn stack |
339 | lua_pushnil(L); // ... {bfc} k nil | 338 | lua_pushnil(L_); // ... {bfc} k nil |
340 | lua_rawseti(L, fqn, _depth); // ... {bfc} k | 339 | lua_rawseti(L_, fqn, _depth); // ... {bfc} k |
341 | } | 340 | } |
342 | -- _depth; | 341 | -- _depth; |
343 | STACK_CHECK(L, -1); | 342 | STACK_CHECK(L_, -1); |
344 | } | 343 | } |
345 | 344 | ||
346 | // ################################################################################################# | 345 | // ################################################################################################# |
347 | 346 | ||
348 | static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) | 347 | static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _i, int _depth) |
349 | { | 348 | { |
350 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i | 349 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i |
351 | int const fqn = _ctx_base + 1; | 350 | int const fqn = _ctx_base + 1; |
352 | // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops | 351 | // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops |
353 | int const cache = _ctx_base + 2; | 352 | int const cache = _ctx_base + 2; |
354 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) | 353 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) |
355 | int const breadth_first_cache = lua_gettop(L) + 1; | 354 | int const breadth_first_cache = lua_gettop(L_) + 1; |
356 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); | 355 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); |
357 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 356 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
358 | 357 | ||
359 | STACK_GROW(L, 6); | 358 | STACK_GROW(L_, 6); |
360 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) | 359 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) |
361 | STACK_CHECK_START_REL(L, 0); // ... {_i} | 360 | STACK_CHECK_START_REL(L_, 0); // ... {_i} |
362 | 361 | ||
363 | // if object is a userdata, replace it by its metatable | 362 | // if object is a userdata, replace it by its metatable |
364 | if (lua_type(L, _i) == LUA_TUSERDATA) | 363 | if (lua_type(L_, _i) == LUA_TUSERDATA) |
365 | { | 364 | { |
366 | lua_getmetatable(L, _i); // ... {_i} mt | 365 | lua_getmetatable(L_, _i); // ... {_i} mt |
367 | lua_replace(L, _i); // ... {_i} | 366 | lua_replace(L_, _i); // ... {_i} |
368 | } | 367 | } |
369 | 368 | ||
370 | // if table is already visited, we are done | 369 | // if table is already visited, we are done |
371 | lua_pushvalue(L, _i); // ... {_i} {} | 370 | lua_pushvalue(L_, _i); // ... {_i} {} |
372 | lua_rawget(L, cache); // ... {_i} nil|n | 371 | lua_rawget(L_, cache); // ... {_i} nil|n |
373 | lua_Integer visit_count{ lua_tointeger(L, -1) }; // 0 if nil, else n | 372 | lua_Integer visit_count{ lua_tointeger(L_, -1) }; // 0 if nil, else n |
374 | lua_pop(L, 1); // ... {_i} | 373 | lua_pop(L_, 1); // ... {_i} |
375 | STACK_CHECK(L, 0); | 374 | STACK_CHECK(L_, 0); |
376 | if (visit_count > 0) | 375 | if (visit_count > 0) |
377 | { | 376 | { |
378 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); | 377 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); |
@@ -380,88 +379,88 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
380 | } | 379 | } |
381 | 380 | ||
382 | // remember we visited this table (1-visit count) | 381 | // remember we visited this table (1-visit count) |
383 | lua_pushvalue(L, _i); // ... {_i} {} | 382 | lua_pushvalue(L_, _i); // ... {_i} {} |
384 | lua_pushinteger(L, visit_count + 1); // ... {_i} {} 1 | 383 | lua_pushinteger(L_, visit_count + 1); // ... {_i} {} 1 |
385 | lua_rawset(L, cache); // ... {_i} | 384 | lua_rawset(L_, cache); // ... {_i} |
386 | STACK_CHECK(L, 0); | 385 | STACK_CHECK(L_, 0); |
387 | 386 | ||
388 | // this table is at breadth_first_cache index | 387 | // this table is at breadth_first_cache index |
389 | lua_newtable(L); // ... {_i} {bfc} | 388 | lua_newtable(L_); // ... {_i} {bfc} |
390 | LUA_ASSERT(L, lua_gettop(L) == breadth_first_cache); | 389 | LUA_ASSERT(L_, lua_gettop(L_) == breadth_first_cache); |
391 | // iterate over all entries in the processed table | 390 | // iterate over all entries in the processed table |
392 | lua_pushnil(L); // ... {_i} {bfc} nil | 391 | lua_pushnil(L_); // ... {_i} {bfc} nil |
393 | while( lua_next(L, _i) != 0) // ... {_i} {bfc} k v | 392 | while( lua_next(L_, _i) != 0) // ... {_i} {bfc} k v |
394 | { | 393 | { |
395 | // just for debug, not actually needed | 394 | // just for debug, not actually needed |
396 | //char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"; | 395 | //char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"; |
397 | // subtable: process it recursively | 396 | // subtable: process it recursively |
398 | if (lua_istable(L, -1)) // ... {_i} {bfc} k {} | 397 | if (lua_istable(L_, -1)) // ... {_i} {bfc} k {} |
399 | { | 398 | { |
400 | // increment visit count to make sure we will actually scan it at this recursive level | 399 | // increment visit count to make sure we will actually scan it at this recursive level |
401 | lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} | 400 | lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} |
402 | lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} {} | 401 | lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} {} |
403 | lua_rawget(L, cache); // ... {_i} {bfc} k {} {} n? | 402 | lua_rawget(L_, cache); // ... {_i} {bfc} k {} {} n? |
404 | visit_count = lua_tointeger(L, -1) + 1; // 1 if we got nil, else n+1 | 403 | visit_count = lua_tointeger(L_, -1) + 1; // 1 if we got nil, else n+1 |
405 | lua_pop(L, 1); // ... {_i} {bfc} k {} {} | 404 | lua_pop(L_, 1); // ... {_i} {bfc} k {} {} |
406 | lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n | 405 | lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n |
407 | lua_rawset(L, cache); // ... {_i} {bfc} k {} | 406 | lua_rawset(L_, cache); // ... {_i} {bfc} k {} |
408 | // store the table in the breadth-first cache | 407 | // store the table in the breadth-first cache |
409 | lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k | 408 | lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k |
410 | lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k {} | 409 | lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k {} |
411 | lua_rawset(L, breadth_first_cache); // ... {_i} {bfc} k {} | 410 | lua_rawset(L_, breadth_first_cache); // ... {_i} {bfc} k {} |
412 | // generate a name, and if we already had one name, keep whichever is the shorter | 411 | // generate a name, and if we already had one name, keep whichever is the shorter |
413 | update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k | 412 | update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k |
414 | } | 413 | } |
415 | else if (lua_isfunction(L, -1) && (luaG_getfuncsubtype(L, -1) != FuncSubType::Bytecode)) | 414 | else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, -1) != FuncSubType::Bytecode)) |
416 | { | 415 | { |
417 | // generate a name, and if we already had one name, keep whichever is the shorter | 416 | // generate a name, and if we already had one name, keep whichever is the shorter |
418 | // this pops the function from the stack | 417 | // this pops the function from the stack |
419 | update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k | 418 | update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k |
420 | } | 419 | } |
421 | else | 420 | else |
422 | { | 421 | { |
423 | lua_pop(L, 1); // ... {_i} {bfc} k | 422 | lua_pop(L_, 1); // ... {_i} {bfc} k |
424 | } | 423 | } |
425 | STACK_CHECK(L, 2); | 424 | STACK_CHECK(L_, 2); |
426 | } | 425 | } |
427 | // now process the tables we encountered at that depth | 426 | // now process the tables we encountered at that depth |
428 | ++ _depth; | 427 | ++ _depth; |
429 | lua_pushnil(L); // ... {_i} {bfc} nil | 428 | lua_pushnil(L_); // ... {_i} {bfc} nil |
430 | while (lua_next(L, breadth_first_cache) != 0) // ... {_i} {bfc} k {} | 429 | while (lua_next(L_, breadth_first_cache) != 0) // ... {_i} {bfc} k {} |
431 | { | 430 | { |
432 | DEBUGSPEW_CODE(char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"); | 431 | DEBUGSPEW_CODE(char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"); |
433 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); | 432 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); |
434 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 433 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
435 | // un-visit this table in case we do need to process it | 434 | // un-visit this table in case we do need to process it |
436 | lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} | 435 | lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} |
437 | lua_rawget(L, cache); // ... {_i} {bfc} k {} n | 436 | lua_rawget(L_, cache); // ... {_i} {bfc} k {} n |
438 | LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER); | 437 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER); |
439 | visit_count = lua_tointeger(L, -1) - 1; | 438 | visit_count = lua_tointeger(L_, -1) - 1; |
440 | lua_pop(L, 1); // ... {_i} {bfc} k {} | 439 | lua_pop(L_, 1); // ... {_i} {bfc} k {} |
441 | lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} | 440 | lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} |
442 | if (visit_count > 0) | 441 | if (visit_count > 0) |
443 | { | 442 | { |
444 | lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n | 443 | lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n |
445 | } | 444 | } |
446 | else | 445 | else |
447 | { | 446 | { |
448 | lua_pushnil(L); // ... {_i} {bfc} k {} {} nil | 447 | lua_pushnil(L_); // ... {_i} {bfc} k {} {} nil |
449 | } | 448 | } |
450 | lua_rawset(L, cache); // ... {_i} {bfc} k {} | 449 | lua_rawset(L_, cache); // ... {_i} {bfc} k {} |
451 | // push table name in fqn stack (note that concatenation will crash if name is a not string!) | 450 | // push table name in fqn stack (note that concatenation will crash if name is a not string!) |
452 | lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k | 451 | lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k |
453 | lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} k {} | 452 | lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc} k {} |
454 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, lua_gettop(L), _depth); | 453 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, lua_gettop(L_), _depth); |
455 | lua_pop(L, 1); // ... {_i} {bfc} k | 454 | lua_pop(L_, 1); // ... {_i} {bfc} k |
456 | STACK_CHECK(L, 2); | 455 | STACK_CHECK(L_, 2); |
457 | } | 456 | } |
458 | // remove table name from fqn stack | 457 | // remove table name from fqn stack |
459 | lua_pushnil(L); // ... {_i} {bfc} nil | 458 | lua_pushnil(L_); // ... {_i} {bfc} nil |
460 | lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} | 459 | lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc} |
461 | -- _depth; | 460 | -- _depth; |
462 | // we are done with our cache | 461 | // we are done with our cache |
463 | lua_pop(L, 1); // ... {_i} | 462 | lua_pop(L_, 1); // ... {_i} |
464 | STACK_CHECK(L, 0); | 463 | STACK_CHECK(L_, 0); |
465 | // we are done // ... {_i} {bfc} | 464 | // we are done // ... {_i} {bfc} |
466 | } | 465 | } |
467 | 466 | ||
@@ -470,64 +469,64 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
470 | /* | 469 | /* |
471 | * create a "fully.qualified.name" <-> function equivalence database | 470 | * create a "fully.qualified.name" <-> function equivalence database |
472 | */ | 471 | */ |
473 | void populate_func_lookup_table(lua_State* L, int i_, char const* name_) | 472 | void populate_func_lookup_table(lua_State* L_, int i_, char const* name_) |
474 | { | 473 | { |
475 | int const ctx_base = lua_gettop(L) + 1; | 474 | int const ctx_base = lua_gettop(L_) + 1; |
476 | int const in_base = lua_absindex(L, i_); | 475 | int const in_base = lua_absindex(L_, i_); |
477 | int start_depth = 0; | 476 | int start_depth = 0; |
478 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); | 477 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); |
479 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); | 478 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); |
480 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 479 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
481 | STACK_GROW(L, 3); | 480 | STACK_GROW(L_, 3); |
482 | STACK_CHECK_START_REL(L, 0); | 481 | STACK_CHECK_START_REL(L_, 0); |
483 | kLookupRegKey.pushValue(L); // {} | 482 | kLookupRegKey.pushValue(L_); // {} |
484 | STACK_CHECK(L, 1); | 483 | STACK_CHECK(L_, 1); |
485 | LUA_ASSERT(L, lua_istable(L, -1)); | 484 | LUA_ASSERT(L_, lua_istable(L_, -1)); |
486 | if (lua_type(L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function | 485 | if (lua_type(L_, in_base) == LUA_TFUNCTION) // for example when a module is a simple function |
487 | { | 486 | { |
488 | name_ = name_ ? name_ : "nullptr"; | 487 | name_ = name_ ? name_ : "nullptr"; |
489 | lua_pushvalue(L, in_base); // {} f | 488 | lua_pushvalue(L_, in_base); // {} f |
490 | lua_pushstring(L, name_); // {} f _name | 489 | lua_pushstring(L_, name_); // {} f _name |
491 | lua_rawset(L, -3); // {} | 490 | lua_rawset(L_, -3); // {} |
492 | lua_pushstring(L, name_); // {} _name | 491 | lua_pushstring(L_, name_); // {} _name |
493 | lua_pushvalue(L, in_base); // {} _name f | 492 | lua_pushvalue(L_, in_base); // {} _name f |
494 | lua_rawset(L, -3); // {} | 493 | lua_rawset(L_, -3); // {} |
495 | lua_pop(L, 1); // | 494 | lua_pop(L_, 1); // |
496 | } | 495 | } |
497 | else if (lua_type(L, in_base) == LUA_TTABLE) | 496 | else if (lua_type(L_, in_base) == LUA_TTABLE) |
498 | { | 497 | { |
499 | lua_newtable(L); // {} {fqn} | 498 | lua_newtable(L_); // {} {fqn} |
500 | if (name_) | 499 | if (name_) |
501 | { | 500 | { |
502 | STACK_CHECK(L, 2); | 501 | STACK_CHECK(L_, 2); |
503 | lua_pushstring(L, name_); // {} {fqn} "name" | 502 | lua_pushstring(L_, name_); // {} {fqn} "name" |
504 | // generate a name, and if we already had one name, keep whichever is the shorter | 503 | // generate a name, and if we already had one name, keep whichever is the shorter |
505 | lua_pushvalue(L, in_base); // {} {fqn} "name" t | 504 | lua_pushvalue(L_, in_base); // {} {fqn} "name" t |
506 | update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, start_depth); // {} {fqn} "name" | 505 | update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, start_depth); // {} {fqn} "name" |
507 | // don't forget to store the name at the bottom of the fqn stack | 506 | // don't forget to store the name at the bottom of the fqn stack |
508 | ++ start_depth; | 507 | ++ start_depth; |
509 | lua_rawseti(L, -2, start_depth); // {} {fqn} | 508 | lua_rawseti(L_, -2, start_depth); // {} {fqn} |
510 | STACK_CHECK(L, 2); | 509 | STACK_CHECK(L_, 2); |
511 | } | 510 | } |
512 | // retrieve the cache, create it if we haven't done it yet | 511 | // retrieve the cache, create it if we haven't done it yet |
513 | kLookupCacheRegKey.pushValue(L); // {} {fqn} {cache}? | 512 | kLookupCacheRegKey.pushValue(L_); // {} {fqn} {cache}? |
514 | if (lua_isnil(L, -1)) | 513 | if (lua_isnil(L_, -1)) |
515 | { | 514 | { |
516 | lua_pop(L, 1); // {} {fqn} | 515 | lua_pop(L_, 1); // {} {fqn} |
517 | lua_newtable(L); // {} {fqn} {cache} | 516 | lua_newtable(L_); // {} {fqn} {cache} |
518 | kLookupCacheRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); | 517 | kLookupCacheRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); |
519 | STACK_CHECK(L, 3); | 518 | STACK_CHECK(L_, 3); |
520 | } | 519 | } |
521 | // process everything we find in that table, filling in lookup data for all functions and tables we see there | 520 | // process everything we find in that table, filling in lookup data for all functions and tables we see there |
522 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, in_base, start_depth); | 521 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, in_base, start_depth); |
523 | lua_pop(L, 3); | 522 | lua_pop(L_, 3); |
524 | } | 523 | } |
525 | else | 524 | else |
526 | { | 525 | { |
527 | lua_pop(L, 1); // | 526 | lua_pop(L_, 1); // |
528 | raise_luaL_error(L, "unsupported module type %s", lua_typename(L, lua_type(L, in_base))); | 527 | raise_luaL_error(L_, "unsupported module type %s", lua_typename(L_, lua_type(L_, in_base))); |
529 | } | 528 | } |
530 | STACK_CHECK(L, 0); | 529 | STACK_CHECK(L_, 0); |
531 | } | 530 | } |
532 | 531 | ||
533 | // ################################################################################################# | 532 | // ################################################################################################# |
@@ -540,36 +539,36 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
540 | /* | 539 | /* |
541 | * Get a unique ID for metatable at [i]. | 540 | * Get a unique ID for metatable at [i]. |
542 | */ | 541 | */ |
543 | [[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L, int i) | 542 | [[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L_, int i) |
544 | { | 543 | { |
545 | i = lua_absindex(L, i); | 544 | i = lua_absindex(L_, i); |
546 | 545 | ||
547 | STACK_GROW(L, 3); | 546 | STACK_GROW(L_, 3); |
548 | 547 | ||
549 | STACK_CHECK_START_REL(L, 0); | 548 | STACK_CHECK_START_REL(L_, 0); |
550 | push_registry_subtable(L, kMtIdRegKey); // ... _R[kMtIdRegKey] | 549 | push_registry_subtable(L_, kMtIdRegKey); // ... _R[kMtIdRegKey] |
551 | lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} | 550 | lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt} |
552 | lua_rawget(L, -2); // ... _R[kMtIdRegKey] mtk? | 551 | lua_rawget(L_, -2); // ... _R[kMtIdRegKey] mtk? |
553 | 552 | ||
554 | lua_Integer id{ lua_tointeger(L, -1) }; // 0 for nil | 553 | lua_Integer id{ lua_tointeger(L_, -1) }; // 0 for nil |
555 | lua_pop(L, 1); // ... _R[kMtIdRegKey] | 554 | lua_pop(L_, 1); // ... _R[kMtIdRegKey] |
556 | STACK_CHECK(L, 1); | 555 | STACK_CHECK(L_, 1); |
557 | 556 | ||
558 | if (id == 0) | 557 | if (id == 0) |
559 | { | 558 | { |
560 | id = U->next_mt_id.fetch_add(1, std::memory_order_relaxed); | 559 | id = U->next_mt_id.fetch_add(1, std::memory_order_relaxed); |
561 | 560 | ||
562 | // Create two-way references: id_uint <-> table | 561 | // Create two-way references: id_uint <-> table |
563 | lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} | 562 | lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt} |
564 | lua_pushinteger(L, id); // ... _R[kMtIdRegKey] {mt} id | 563 | lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] {mt} id |
565 | lua_rawset(L, -3); // ... _R[kMtIdRegKey] | 564 | lua_rawset(L_, -3); // ... _R[kMtIdRegKey] |
566 | 565 | ||
567 | lua_pushinteger(L, id); // ... _R[kMtIdRegKey] id | 566 | lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] id |
568 | lua_pushvalue(L, i); // ... _R[kMtIdRegKey] id {mt} | 567 | lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] id {mt} |
569 | lua_rawset(L, -3); // ... _R[kMtIdRegKey] | 568 | lua_rawset(L_, -3); // ... _R[kMtIdRegKey] |
570 | } | 569 | } |
571 | lua_pop(L, 1); // ... | 570 | lua_pop(L_, 1); // ... |
572 | STACK_CHECK(L, 0); | 571 | STACK_CHECK(L_, 0); |
573 | 572 | ||
574 | return id; | 573 | return id; |
575 | } | 574 | } |
@@ -577,25 +576,25 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
577 | // ################################################################################################# | 576 | // ################################################################################################# |
578 | 577 | ||
579 | // function sentinel used to transfer native functions from/to keeper states | 578 | // function sentinel used to transfer native functions from/to keeper states |
580 | [[nodiscard]] static int func_lookup_sentinel(lua_State* L) | 579 | [[nodiscard]] static int func_lookup_sentinel(lua_State* L_) |
581 | { | 580 | { |
582 | raise_luaL_error(L, "function lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); | 581 | raise_luaL_error(L_, "function lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); |
583 | } | 582 | } |
584 | 583 | ||
585 | // ################################################################################################# | 584 | // ################################################################################################# |
586 | 585 | ||
587 | // function sentinel used to transfer native table from/to keeper states | 586 | // function sentinel used to transfer native table from/to keeper states |
588 | [[nodiscard]] static int table_lookup_sentinel(lua_State* L) | 587 | [[nodiscard]] static int table_lookup_sentinel(lua_State* L_) |
589 | { | 588 | { |
590 | raise_luaL_error(L, "table lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); | 589 | raise_luaL_error(L_, "table lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); |
591 | } | 590 | } |
592 | 591 | ||
593 | // ################################################################################################# | 592 | // ################################################################################################# |
594 | 593 | ||
595 | // function sentinel used to transfer cloned full userdata from/to keeper states | 594 | // function sentinel used to transfer cloned full userdata from/to keeper states |
596 | [[nodiscard]] static int userdata_clone_sentinel(lua_State* L) | 595 | [[nodiscard]] static int userdata_clone_sentinel(lua_State* L_) |
597 | { | 596 | { |
598 | raise_luaL_error(L, "userdata clone sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); | 597 | raise_luaL_error(L_, "userdata clone sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); |
599 | } | 598 | } |
600 | 599 | ||
601 | // ################################################################################################# | 600 | // ################################################################################################# |
@@ -603,55 +602,55 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
603 | /* | 602 | /* |
604 | * retrieve the name of a function/table in the lookup database | 603 | * retrieve the name of a function/table in the lookup database |
605 | */ | 604 | */ |
606 | [[nodiscard]] static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char const* upName_, size_t* len_) | 605 | [[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i, LookupMode mode_, char const* upName_, size_t* len_) |
607 | { | 606 | { |
608 | DEBUGSPEW_CODE( Universe* const U = universe_get( L)); | 607 | DEBUGSPEW_CODE( Universe* const U = universe_get( L_)); |
609 | char const* fqn; | 608 | char const* fqn; |
610 | LUA_ASSERT(L, lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... | 609 | LUA_ASSERT(L_, lua_isfunction( L_, i) || lua_istable( L_, i)); // ... v ... |
611 | STACK_CHECK_START_REL(L, 0); | 610 | STACK_CHECK_START_REL(L_, 0); |
612 | STACK_GROW( L, 3); // up to 3 slots are necessary on error | 611 | STACK_GROW( L_, 3); // up to 3 slots are necessary on error |
613 | if (mode_ == LookupMode::FromKeeper) | 612 | if (mode_ == LookupMode::FromKeeper) |
614 | { | 613 | { |
615 | lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! | 614 | lua_CFunction f = lua_tocfunction( L_, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! |
616 | if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) | 615 | if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) |
617 | { | 616 | { |
618 | lua_getupvalue( L, i, 1); // ... v ... "f.q.n" | 617 | lua_getupvalue( L_, i, 1); // ... v ... "f.q.n" |
619 | } | 618 | } |
620 | else | 619 | else |
621 | { | 620 | { |
622 | // if this is not a sentinel, this is some user-created table we wanted to lookup | 621 | // if this is not a sentinel, this is some user-created table we wanted to lookup |
623 | LUA_ASSERT(L, nullptr == f && lua_istable(L, i)); | 622 | LUA_ASSERT(L_, nullptr == f && lua_istable(L_, i)); |
624 | // push anything that will convert to nullptr string | 623 | // push anything that will convert to nullptr string |
625 | lua_pushnil( L); // ... v ... nil | 624 | lua_pushnil( L_); // ... v ... nil |
626 | } | 625 | } |
627 | } | 626 | } |
628 | else | 627 | else |
629 | { | 628 | { |
630 | // fetch the name from the source state's lookup table | 629 | // fetch the name from the source state's lookup table |
631 | kLookupRegKey.pushValue(L); // ... v ... {} | 630 | kLookupRegKey.pushValue(L_); // ... v ... {} |
632 | STACK_CHECK( L, 1); | 631 | STACK_CHECK( L_, 1); |
633 | LUA_ASSERT(L, lua_istable( L, -1)); | 632 | LUA_ASSERT(L_, lua_istable( L_, -1)); |
634 | lua_pushvalue( L, i); // ... v ... {} v | 633 | lua_pushvalue( L_, i); // ... v ... {} v |
635 | lua_rawget( L, -2); // ... v ... {} "f.q.n" | 634 | lua_rawget( L_, -2); // ... v ... {} "f.q.n" |
636 | } | 635 | } |
637 | fqn = lua_tolstring( L, -1, len_); | 636 | fqn = lua_tolstring( L_, -1, len_); |
638 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); | 637 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); |
639 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 638 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
640 | lua_pop( L, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... | 639 | lua_pop( L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... |
641 | STACK_CHECK( L, 0); | 640 | STACK_CHECK( L_, 0); |
642 | if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) | 641 | if (nullptr == fqn && !lua_istable(L_, i)) // raise an error if we try to send an unknown function (but not for tables) |
643 | { | 642 | { |
644 | char const *from, *typewhat, *what, *gotchaA, *gotchaB; | 643 | char const *from, *typewhat, *what, *gotchaA, *gotchaB; |
645 | // try to discover the name of the function we want to send | 644 | // try to discover the name of the function we want to send |
646 | lua_getglobal( L, "decoda_name"); // ... v ... decoda_name | 645 | lua_getglobal( L_, "decoda_name"); // ... v ... decoda_name |
647 | from = lua_tostring( L, -1); | 646 | from = lua_tostring( L_, -1); |
648 | lua_pushcfunction( L, luaG_nameof); // ... v ... decoda_name luaG_nameof | 647 | lua_pushcfunction( L_, luaG_nameof); // ... v ... decoda_name luaG_nameof |
649 | lua_pushvalue( L, i); // ... v ... decoda_name luaG_nameof t | 648 | lua_pushvalue( L_, i); // ... v ... decoda_name luaG_nameof t |
650 | lua_call( L, 1, 2); // ... v ... decoda_name "type" "name"|nil | 649 | lua_call( L_, 1, 2); // ... v ... decoda_name "type" "name"|nil |
651 | typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2); | 650 | typewhat = (lua_type( L_, -2) == LUA_TSTRING) ? lua_tostring( L_, -2) : luaL_typename( L_, -2); |
652 | // second return value can be nil if the table was not found | 651 | // second return value can be nil if the table was not found |
653 | // probable reason: the function was removed from the source Lua state before Lanes was required. | 652 | // probable reason: the function was removed from the source Lua state before Lanes was required. |
654 | if (lua_isnil( L, -1)) | 653 | if (lua_isnil( L_, -1)) |
655 | { | 654 | { |
656 | gotchaA = " referenced by"; | 655 | gotchaA = " referenced by"; |
657 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; | 656 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; |
@@ -661,13 +660,13 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
661 | { | 660 | { |
662 | gotchaA = ""; | 661 | gotchaA = ""; |
663 | gotchaB = ""; | 662 | gotchaB = ""; |
664 | what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1); | 663 | what = (lua_type( L_, -1) == LUA_TSTRING) ? lua_tostring( L_, -1) : luaL_typename( L_, -1); |
665 | } | 664 | } |
666 | raise_luaL_error(L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); | 665 | raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); |
667 | *len_ = 0; | 666 | *len_ = 0; |
668 | return nullptr; | 667 | return nullptr; |
669 | } | 668 | } |
670 | STACK_CHECK( L, 0); | 669 | STACK_CHECK( L_, 0); |
671 | return fqn; | 670 | return fqn; |
672 | } | 671 | } |
673 | 672 | ||
@@ -787,7 +786,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
787 | /* | 786 | /* |
788 | * Return some name helping to identify an object | 787 | * Return some name helping to identify an object |
789 | */ | 788 | */ |
790 | [[nodiscard]] static int discover_object_name_recur(lua_State* L, int shortest_, int depth_) | 789 | [[nodiscard]] static int discover_object_name_recur(lua_State* L_, int shortest_, int depth_) |
791 | { | 790 | { |
792 | int const what = 1; // o "r" {c} {fqn} ... {?} | 791 | int const what = 1; // o "r" {c} {fqn} ... {?} |
793 | int const result = 2; | 792 | int const result = 2; |
@@ -798,72 +797,72 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
798 | { | 797 | { |
799 | return shortest_; | 798 | return shortest_; |
800 | } | 799 | } |
801 | STACK_GROW(L, 3); | 800 | STACK_GROW(L_, 3); |
802 | STACK_CHECK_START_REL(L, 0); | 801 | STACK_CHECK_START_REL(L_, 0); |
803 | // stack top contains the table to search in | 802 | // stack top contains the table to search in |
804 | lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} | 803 | lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} |
805 | lua_rawget(L, cache); // o "r" {c} {fqn} ... {?} nil/1 | 804 | lua_rawget(L_, cache); // o "r" {c} {fqn} ... {?} nil/1 |
806 | // if table is already visited, we are done | 805 | // if table is already visited, we are done |
807 | if (!lua_isnil(L, -1)) | 806 | if (!lua_isnil(L_, -1)) |
808 | { | 807 | { |
809 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} | 808 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} |
810 | return shortest_; | 809 | return shortest_; |
811 | } | 810 | } |
812 | // examined table is not in the cache, add it now | 811 | // examined table is not in the cache, add it now |
813 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} | 812 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} |
814 | lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} | 813 | lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} |
815 | lua_pushinteger(L, 1); // o "r" {c} {fqn} ... {?} {?} 1 | 814 | lua_pushinteger(L_, 1); // o "r" {c} {fqn} ... {?} {?} 1 |
816 | lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} | 815 | lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?} |
817 | // scan table contents | 816 | // scan table contents |
818 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} nil | 817 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} nil |
819 | while (lua_next(L, -2)) // o "r" {c} {fqn} ... {?} k v | 818 | while (lua_next(L_, -2)) // o "r" {c} {fqn} ... {?} k v |
820 | { | 819 | { |
821 | //char const *const strKey = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : nullptr; // only for debugging | 820 | //char const *const strKey = (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : nullptr; // only for debugging |
822 | //lua_Number const numKey = (lua_type(L, -2) == LUA_TNUMBER) ? lua_tonumber(L, -2) : -6666; // only for debugging | 821 | //lua_Number const numKey = (lua_type(L_, -2) == LUA_TNUMBER) ? lua_tonumber(L_, -2) : -6666; // only for debugging |
823 | STACK_CHECK(L, 2); | 822 | STACK_CHECK(L_, 2); |
824 | // append key name to fqn stack | 823 | // append key name to fqn stack |
825 | ++ depth_; | 824 | ++ depth_; |
826 | lua_pushvalue(L, -2); // o "r" {c} {fqn} ... {?} k v k | 825 | lua_pushvalue(L_, -2); // o "r" {c} {fqn} ... {?} k v k |
827 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v | 826 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v |
828 | if (lua_rawequal(L, -1, what)) // is it what we are looking for? | 827 | if (lua_rawequal(L_, -1, what)) // is it what we are looking for? |
829 | { | 828 | { |
830 | STACK_CHECK(L, 2); | 829 | STACK_CHECK(L_, 2); |
831 | // update shortest name | 830 | // update shortest name |
832 | if (depth_ < shortest_) | 831 | if (depth_ < shortest_) |
833 | { | 832 | { |
834 | shortest_ = depth_; | 833 | shortest_ = depth_; |
835 | std::ignore = luaG_pushFQN(L, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn" | 834 | std::ignore = luaG_pushFQN(L_, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn" |
836 | lua_replace(L, result); // o "r" {c} {fqn} ... {?} k v | 835 | lua_replace(L_, result); // o "r" {c} {fqn} ... {?} k v |
837 | } | 836 | } |
838 | // no need to search further at this level | 837 | // no need to search further at this level |
839 | lua_pop(L, 2); // o "r" {c} {fqn} ... {?} | 838 | lua_pop(L_, 2); // o "r" {c} {fqn} ... {?} |
840 | STACK_CHECK(L, 0); | 839 | STACK_CHECK(L_, 0); |
841 | break; | 840 | break; |
842 | } | 841 | } |
843 | switch (lua_type(L, -1)) // o "r" {c} {fqn} ... {?} k v | 842 | switch (lua_type(L_, -1)) // o "r" {c} {fqn} ... {?} k v |
844 | { | 843 | { |
845 | default: // nil, boolean, light userdata, number and string aren't identifiable | 844 | default: // nil, boolean, light userdata, number and string aren't identifiable |
846 | break; | 845 | break; |
847 | 846 | ||
848 | case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} | 847 | case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} |
849 | STACK_CHECK(L, 2); | 848 | STACK_CHECK(L_, 2); |
850 | shortest_ = discover_object_name_recur(L, shortest_, depth_); | 849 | shortest_ = discover_object_name_recur(L_, shortest_, depth_); |
851 | // search in the table's metatable too | 850 | // search in the table's metatable too |
852 | if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} | 851 | if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} |
853 | { | 852 | { |
854 | if (lua_istable(L, -1)) | 853 | if (lua_istable(L_, -1)) |
855 | { | 854 | { |
856 | ++ depth_; | 855 | ++ depth_; |
857 | lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" | 856 | lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" |
858 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} | 857 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} |
859 | shortest_ = discover_object_name_recur(L, shortest_, depth_); | 858 | shortest_ = discover_object_name_recur(L_, shortest_, depth_); |
860 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} k {} {mt} nil | 859 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k {} {mt} nil |
861 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} | 860 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} |
862 | -- depth_; | 861 | -- depth_; |
863 | } | 862 | } |
864 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k {} | 863 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k {} |
865 | } | 864 | } |
866 | STACK_CHECK(L, 2); | 865 | STACK_CHECK(L_, 2); |
867 | break; | 866 | break; |
868 | 867 | ||
869 | case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T | 868 | case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T |
@@ -871,61 +870,61 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
871 | break; | 870 | break; |
872 | 871 | ||
873 | case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U | 872 | case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U |
874 | STACK_CHECK(L, 2); | 873 | STACK_CHECK(L_, 2); |
875 | // search in the object's metatable (some modules are built that way) | 874 | // search in the object's metatable (some modules are built that way) |
876 | if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} | 875 | if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k U {mt} |
877 | { | 876 | { |
878 | if (lua_istable(L, -1)) | 877 | if (lua_istable(L_, -1)) |
879 | { | 878 | { |
880 | ++ depth_; | 879 | ++ depth_; |
881 | lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" | 880 | lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" |
882 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} | 881 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} |
883 | shortest_ = discover_object_name_recur(L, shortest_, depth_); | 882 | shortest_ = discover_object_name_recur(L_, shortest_, depth_); |
884 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} k U {mt} nil | 883 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k U {mt} nil |
885 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} | 884 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} |
886 | -- depth_; | 885 | -- depth_; |
887 | } | 886 | } |
888 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U | 887 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U |
889 | } | 888 | } |
890 | STACK_CHECK(L, 2); | 889 | STACK_CHECK(L_, 2); |
891 | // search in the object's uservalues | 890 | // search in the object's uservalues |
892 | { | 891 | { |
893 | int uvi = 1; | 892 | int uvi = 1; |
894 | while (lua_getiuservalue(L, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u} | 893 | while (lua_getiuservalue(L_, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u} |
895 | { | 894 | { |
896 | if (lua_istable(L, -1)) // if it is a table, look inside | 895 | if (lua_istable(L_, -1)) // if it is a table, look inside |
897 | { | 896 | { |
898 | ++ depth_; | 897 | ++ depth_; |
899 | lua_pushliteral(L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" | 898 | lua_pushliteral(L_, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" |
900 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} | 899 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} |
901 | shortest_ = discover_object_name_recur(L, shortest_, depth_); | 900 | shortest_ = discover_object_name_recur(L_, shortest_, depth_); |
902 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} k v {u} nil | 901 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k v {u} nil |
903 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} | 902 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} |
904 | -- depth_; | 903 | -- depth_; |
905 | } | 904 | } |
906 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U | 905 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U |
907 | ++ uvi; | 906 | ++ uvi; |
908 | } | 907 | } |
909 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now | 908 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now |
910 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U | 909 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U |
911 | } | 910 | } |
912 | STACK_CHECK(L, 2); | 911 | STACK_CHECK(L_, 2); |
913 | break; | 912 | break; |
914 | } | 913 | } |
915 | // make ready for next iteration | 914 | // make ready for next iteration |
916 | lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k | 915 | lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k |
917 | // remove name from fqn stack | 916 | // remove name from fqn stack |
918 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} k nil | 917 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k nil |
919 | lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k | 918 | lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k |
920 | STACK_CHECK(L, 1); | 919 | STACK_CHECK(L_, 1); |
921 | -- depth_; | 920 | -- depth_; |
922 | } // o "r" {c} {fqn} ... {?} | 921 | } // o "r" {c} {fqn} ... {?} |
923 | STACK_CHECK(L, 0); | 922 | STACK_CHECK(L_, 0); |
924 | // remove the visited table from the cache, in case a shorter path to the searched object exists | 923 | // remove the visited table from the cache, in case a shorter path to the searched object exists |
925 | lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} | 924 | lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} |
926 | lua_pushnil(L); // o "r" {c} {fqn} ... {?} {?} nil | 925 | lua_pushnil(L_); // o "r" {c} {fqn} ... {?} {?} nil |
927 | lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} | 926 | lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?} |
928 | STACK_CHECK(L, 0); | 927 | STACK_CHECK(L_, 0); |
929 | return shortest_; | 928 | return shortest_; |
930 | } | 929 | } |
931 | 930 | ||
@@ -934,47 +933,47 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
934 | /* | 933 | /* |
935 | * "type", "name" = lanes.nameof( o) | 934 | * "type", "name" = lanes.nameof( o) |
936 | */ | 935 | */ |
937 | int luaG_nameof( lua_State* L) | 936 | int luaG_nameof( lua_State* L_) |
938 | { | 937 | { |
939 | int const what{ lua_gettop(L) }; | 938 | int const what{ lua_gettop(L_) }; |
940 | if (what > 1) | 939 | if (what > 1) |
941 | { | 940 | { |
942 | raise_luaL_argerror( L, what, "too many arguments."); | 941 | raise_luaL_argerror( L_, what, "too many arguments."); |
943 | } | 942 | } |
944 | 943 | ||
945 | // nil, boolean, light userdata, number and string aren't identifiable | 944 | // nil, boolean, light userdata, number and string aren't identifiable |
946 | if (lua_type( L, 1) < LUA_TTABLE) | 945 | if (lua_type( L_, 1) < LUA_TTABLE) |
947 | { | 946 | { |
948 | lua_pushstring( L, luaL_typename( L, 1)); // o "type" | 947 | lua_pushstring( L_, luaL_typename( L_, 1)); // o "type" |
949 | lua_insert( L, -2); // "type" o | 948 | lua_insert( L_, -2); // "type" o |
950 | return 2; | 949 | return 2; |
951 | } | 950 | } |
952 | 951 | ||
953 | STACK_GROW( L, 4); | 952 | STACK_GROW( L_, 4); |
954 | STACK_CHECK_START_REL(L, 0); | 953 | STACK_CHECK_START_REL(L_, 0); |
955 | // this slot will contain the shortest name we found when we are done | 954 | // this slot will contain the shortest name we found when we are done |
956 | lua_pushnil( L); // o nil | 955 | lua_pushnil( L_); // o nil |
957 | // push a cache that will contain all already visited tables | 956 | // push a cache that will contain all already visited tables |
958 | lua_newtable( L); // o nil {c} | 957 | lua_newtable( L_); // o nil {c} |
959 | // push a table whose contents are strings that, when concatenated, produce unique name | 958 | // push a table whose contents are strings that, when concatenated, produce unique name |
960 | lua_newtable( L); // o nil {c} {fqn} | 959 | lua_newtable( L_); // o nil {c} {fqn} |
961 | lua_pushliteral( L, "_G"); // o nil {c} {fqn} "_G" | 960 | lua_pushliteral( L_, "_G"); // o nil {c} {fqn} "_G" |
962 | lua_rawseti( L, -2, 1); // o nil {c} {fqn} | 961 | lua_rawseti( L_, -2, 1); // o nil {c} {fqn} |
963 | // this is where we start the search | 962 | // this is where we start the search |
964 | lua_pushglobaltable( L); // o nil {c} {fqn} _G | 963 | lua_pushglobaltable( L_); // o nil {c} {fqn} _G |
965 | (void) discover_object_name_recur( L, 6666, 1); | 964 | (void) discover_object_name_recur( L_, 6666, 1); |
966 | if (lua_isnil( L, 2)) // try again with registry, just in case... | 965 | if (lua_isnil( L_, 2)) // try again with registry, just in case... |
967 | { | 966 | { |
968 | lua_pop( L, 1); // o nil {c} {fqn} | 967 | lua_pop( L_, 1); // o nil {c} {fqn} |
969 | lua_pushliteral( L, "_R"); // o nil {c} {fqn} "_R" | 968 | lua_pushliteral( L_, "_R"); // o nil {c} {fqn} "_R" |
970 | lua_rawseti( L, -2, 1); // o nil {c} {fqn} | 969 | lua_rawseti( L_, -2, 1); // o nil {c} {fqn} |
971 | lua_pushvalue( L, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R | 970 | lua_pushvalue( L_, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R |
972 | (void) discover_object_name_recur( L, 6666, 1); | 971 | (void) discover_object_name_recur( L_, 6666, 1); |
973 | } | 972 | } |
974 | lua_pop( L, 3); // o "result" | 973 | lua_pop( L_, 3); // o "result" |
975 | STACK_CHECK( L, 1); | 974 | STACK_CHECK( L_, 1); |
976 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" | 975 | lua_pushstring( L_, luaL_typename( L_, 1)); // o "result" "type" |
977 | lua_replace( L, -3); // "type" "result" | 976 | lua_replace( L_, -3); // "type" "result" |
978 | return 2; | 977 | return 2; |
979 | } | 978 | } |
980 | 979 | ||
@@ -1090,12 +1089,12 @@ static char const* vt_names[] = | |||
1090 | // we have to do it that way because we can't unbalance the stack between buffer operations | 1089 | // we have to do it that way because we can't unbalance the stack between buffer operations |
1091 | // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! | 1090 | // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! |
1092 | // luckily, this also works with earlier Lua versions | 1091 | // luckily, this also works with earlier Lua versions |
1093 | [[nodiscard]] static int buf_writer(lua_State* L, void const* b, size_t size, void* ud) | 1092 | [[nodiscard]] static int buf_writer(lua_State* L_, void const* b, size_t size, void* ud) |
1094 | { | 1093 | { |
1095 | luaL_Buffer* B = (luaL_Buffer*) ud; | 1094 | luaL_Buffer* B = (luaL_Buffer*) ud; |
1096 | if (!B->L) | 1095 | if (!B->L) |
1097 | { | 1096 | { |
1098 | luaL_buffinit( L, B); | 1097 | luaL_buffinit( L_, B); |
1099 | } | 1098 | } |
1100 | luaL_addlstring( B, (char const*) b, size); | 1099 | luaL_addlstring( B, (char const*) b, size); |
1101 | return 0; | 1100 | return 0; |