diff options
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r-- | src/intercopycontext.cpp | 189 |
1 files changed, 87 insertions, 102 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index a93615b..6e9b66c 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -36,23 +36,6 @@ THE SOFTWARE. | |||
36 | 36 | ||
37 | // ################################################################################################# | 37 | // ################################################################################################# |
38 | 38 | ||
39 | // Lua 5.4.3 style of dumping (see lstrlib.c) | ||
40 | // we have to do it that way because we can't unbalance the stack between buffer operations | ||
41 | // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! | ||
42 | // luckily, this also works with earlier Lua versions | ||
43 | [[nodiscard]] | ||
44 | static int buf_writer(lua_State* L_, void const* b_, size_t size_, void* ud_) | ||
45 | { | ||
46 | luaL_Buffer* const _B{ static_cast<luaL_Buffer*>(ud_) }; | ||
47 | if (!_B->L) { | ||
48 | luaL_buffinit(L_, _B); | ||
49 | } | ||
50 | luaL_addlstring(_B, static_cast<char const*>(b_), size_); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | // ################################################################################################# | ||
55 | |||
56 | // function sentinel used to transfer native functions from/to keeper states | 39 | // function sentinel used to transfer native functions from/to keeper states |
57 | [[nodiscard]] | 40 | [[nodiscard]] |
58 | static int func_lookup_sentinel(lua_State* const L_) | 41 | static int func_lookup_sentinel(lua_State* const L_) |
@@ -93,7 +76,7 @@ static int userdata_lookup_sentinel(lua_State* const L_) | |||
93 | [[nodiscard]] | 76 | [[nodiscard]] |
94 | std::string_view InterCopyContext::findLookupName() const | 77 | std::string_view InterCopyContext::findLookupName() const |
95 | { | 78 | { |
96 | LUA_ASSERT(L1, lua_isfunction(L1, L1_i) || lua_istable(L1, L1_i) || luaG_type(L1, L1_i) == LuaType::USERDATA); | 79 | LUA_ASSERT(L1, lua_isfunction(L1, L1_i) || lua_istable(L1, L1_i) || luaW_type(L1, L1_i) == LuaType::USERDATA); |
97 | STACK_CHECK_START_REL(L1, 0); // L1: ... v ... | 80 | STACK_CHECK_START_REL(L1, 0); // L1: ... v ... |
98 | STACK_GROW(L1, 3); // up to 3 slots are necessary on error | 81 | STACK_GROW(L1, 3); // up to 3 slots are necessary on error |
99 | if (mode == LookupMode::FromKeeper) { | 82 | if (mode == LookupMode::FromKeeper) { |
@@ -114,7 +97,7 @@ std::string_view InterCopyContext::findLookupName() const | |||
114 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v | 97 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v |
115 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" | 98 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
116 | } | 99 | } |
117 | std::string_view _fqn{ luaG_tostring(L1, kIdxTop) }; | 100 | std::string_view _fqn{ luaW_tostring(L1, kIdxTop) }; |
118 | DEBUGSPEW_CODE(DebugSpew(U) << "function [C] " << _fqn << std::endl); | 101 | DEBUGSPEW_CODE(DebugSpew(U) << "function [C] " << _fqn << std::endl); |
119 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 102 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
120 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... | 103 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
@@ -122,12 +105,12 @@ std::string_view InterCopyContext::findLookupName() const | |||
122 | if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function/userdata (but not for tables) | 105 | if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function/userdata (but not for tables) |
123 | // try to discover the name of the function/userdata we want to send | 106 | // try to discover the name of the function/userdata we want to send |
124 | kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name | 107 | kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name |
125 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; | 108 | std::string_view const _from{ luaW_tostring(L1, kIdxTop) }; |
126 | lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof | 109 | lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof |
127 | lua_pushvalue(L1, L1_i); // L1: ... v ... lane_name LG_nameof t | 110 | lua_pushvalue(L1, L1_i); // L1: ... v ... lane_name LG_nameof t |
128 | lua_call(L1, 1, 2); // L1: ... v ... lane_name "type" "name"|nil | 111 | lua_call(L1, 1, 2); // L1: ... v ... lane_name "type" "name"|nil |
129 | StackIndex const _indexTypeWhat{ -2 }; | 112 | StackIndex const _indexTypeWhat{ -2 }; |
130 | std::string_view const _typewhat{ (luaG_type(L1, _indexTypeWhat) == LuaType::STRING) ? luaG_tostring(L1, _indexTypeWhat) : luaG_typename(L1, _indexTypeWhat) }; | 113 | std::string_view const _typewhat{ (luaW_type(L1, _indexTypeWhat) == LuaType::STRING) ? luaW_tostring(L1, _indexTypeWhat) : luaW_typename(L1, _indexTypeWhat) }; |
131 | // second return value can be nil if the table was not found | 114 | // second return value can be nil if the table was not found |
132 | // probable reason: the function was removed from the source Lua state before Lanes was required. | 115 | // probable reason: the function was removed from the source Lua state before Lanes was required. |
133 | std::string_view _what, _gotchaA, _gotchaB; | 116 | std::string_view _what, _gotchaA, _gotchaB; |
@@ -139,7 +122,7 @@ std::string_view InterCopyContext::findLookupName() const | |||
139 | _gotchaA = ""; | 122 | _gotchaA = ""; |
140 | _gotchaB = ""; | 123 | _gotchaB = ""; |
141 | StackIndex const _indexWhat{ kIdxTop }; | 124 | StackIndex const _indexWhat{ kIdxTop }; |
142 | _what = (luaG_type(L1, _indexWhat) == LuaType::STRING) ? luaG_tostring(L1, _indexWhat) : luaG_typename(L1, _indexWhat); | 125 | _what = (luaW_type(L1, _indexWhat) == LuaType::STRING) ? luaW_tostring(L1, _indexWhat) : luaW_typename(L1, _indexWhat); |
143 | } | 126 | } |
144 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat.data(), _gotchaA.data(), _what.data(), _from.empty() ? "main" : _from.data(), _gotchaB.data()); | 127 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat.data(), _gotchaA.data(), _what.data(), _from.empty() ? "main" : _from.data(), _gotchaB.data()); |
145 | } | 128 | } |
@@ -158,7 +141,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
158 | [[nodiscard]] | 141 | [[nodiscard]] |
159 | static lua_Integer get_mt_id(Universe* const U_, lua_State* const L_, StackIndex const idx_) | 142 | static lua_Integer get_mt_id(Universe* const U_, lua_State* const L_, StackIndex const idx_) |
160 | { | 143 | { |
161 | StackIndex const _absidx{ luaG_absindex(L_, idx_) }; | 144 | StackIndex const _absidx{ luaW_absindex(L_, idx_) }; |
162 | 145 | ||
163 | STACK_GROW(L_, 3); | 146 | STACK_GROW(L_, 3); |
164 | 147 | ||
@@ -195,11 +178,12 @@ static lua_Integer get_mt_id(Universe* const U_, lua_State* const L_, StackIndex | |||
195 | // L2 has the cache key for this function at the top of the stack | 178 | // L2 has the cache key for this function at the top of the stack |
196 | void InterCopyContext::copyFunction() const | 179 | void InterCopyContext::copyFunction() const |
197 | { | 180 | { |
198 | LUA_ASSERT(L1, L2_cache_i != 0); // L2: ... {cache} ... p | 181 | LUA_ASSERT(L1, L2_cache_i != 0); // L1: ... f L2: ... {cache} ... p |
199 | STACK_GROW(L1, 2); | 182 | STACK_GROW(L1, 2); |
200 | STACK_CHECK_START_REL(L1, 0); | 183 | STACK_CHECK_START_REL(L1, 0); |
184 | STACK_CHECK_START_REL(L2, 0); | ||
201 | 185 | ||
202 | // 'luaG_dump()' needs the function at top of stack | 186 | // 'luaW_dump()' needs the function at top of stack |
203 | // if already on top of the stack, no need to push again | 187 | // if already on top of the stack, no need to push again |
204 | bool const _needToPush{ L1_i != lua_gettop(L1) }; | 188 | bool const _needToPush{ L1_i != lua_gettop(L1) }; |
205 | if (_needToPush) { | 189 | if (_needToPush) { |
@@ -211,19 +195,17 @@ void InterCopyContext::copyFunction() const | |||
211 | // to the writer" (and we only return 0) | 195 | // to the writer" (and we only return 0) |
212 | // not sure this could ever fail but for memory shortage reasons | 196 | // not sure this could ever fail but for memory shortage reasons |
213 | // last argument is Lua 5.4-specific (no stripping) | 197 | // last argument is Lua 5.4-specific (no stripping) |
214 | luaL_Buffer B{}; | 198 | tools::PushFunctionBytecode(L1, L2, U->stripFunctions); // L1: ... f L2: ... {cache} ... p "<bytecode>" |
215 | if (luaG_dump(L1, buf_writer, &B, U->stripFunctions) != 0) { | ||
216 | raise_luaL_error(getErrL(), "internal error: function dump failed."); | ||
217 | } | ||
218 | 199 | ||
219 | // pushes dumped string on 'L1' | 200 | // if pushed, we need to pop |
220 | luaL_pushresult(&B); // L1: ... f b | ||
221 | |||
222 | // if not pushed, no need to pop | ||
223 | if (_needToPush) { | 201 | if (_needToPush) { |
224 | lua_remove(L1, -2); // L1: ... b | 202 | lua_pop(L1, 1); // L1: ... |
225 | } | 203 | } |
226 | 204 | ||
205 | // When we are done, the stack of L1 should be the original one, with the bytecode string added on top of L2 | ||
206 | STACK_CHECK(L1, 0); | ||
207 | STACK_CHECK(L2, 1); | ||
208 | |||
227 | // transfer the bytecode, then the upvalues, to create a similar closure | 209 | // transfer the bytecode, then the upvalues, to create a similar closure |
228 | { | 210 | { |
229 | char const* _fname{}; | 211 | char const* _fname{}; |
@@ -231,16 +213,16 @@ void InterCopyContext::copyFunction() const | |||
231 | if constexpr (LOG_FUNC_INFO) | 213 | if constexpr (LOG_FUNC_INFO) |
232 | { | 214 | { |
233 | lua_Debug _ar; | 215 | lua_Debug _ar; |
234 | lua_pushvalue(L1, L1_i); // L1: ... b f | 216 | lua_pushvalue(L1, L1_i); // L1: ... f |
235 | // "To get information about a function you push it onto the stack and start the what string with the character '>'." | 217 | // "To get information about a function you push it onto the stack and start the what string with the character '>'." |
236 | // fills 'fname' 'namewhat' and 'linedefined', pops function | 218 | // fills 'fname' 'namewhat' and 'linedefined', pops function |
237 | lua_getinfo(L1, ">nS", &_ar); // L1: ... b | 219 | lua_getinfo(L1, ">nS", &_ar); // L1: ... |
238 | _fname = _ar.namewhat; | 220 | _fname = _ar.namewhat; |
239 | DEBUGSPEW_CODE(DebugSpew(U) << "FNAME: " << _ar.short_src << " @ " << _ar.linedefined << std::endl); | 221 | DEBUGSPEW_CODE(DebugSpew(U) << "FNAME: " << _ar.short_src << " @ " << _ar.linedefined << std::endl); |
240 | } | 222 | } |
241 | 223 | ||
242 | { | 224 | { |
243 | std::string_view const _bytecode{ luaG_tostring(L1, kIdxTop) }; // L1: ... b | 225 | std::string_view const _bytecode{ luaW_tostring(L2, kIdxTop) }; // L2: ... {cache} ... p "<bytecode>" |
244 | LUA_ASSERT(L1, !_bytecode.empty()); | 226 | LUA_ASSERT(L1, !_bytecode.empty()); |
245 | STACK_GROW(L2, 2); | 227 | STACK_GROW(L2, 2); |
246 | // Note: Line numbers seem to be taken precisely from the | 228 | // Note: Line numbers seem to be taken precisely from the |
@@ -249,15 +231,15 @@ void InterCopyContext::copyFunction() const | |||
249 | // | 231 | // |
250 | // TBD: Can we get the function's original name through, as well? | 232 | // TBD: Can we get the function's original name through, as well? |
251 | // | 233 | // |
252 | if (luaL_loadbuffer(L2, _bytecode.data(), _bytecode.size(), _fname) != 0) { // L2: ... {cache} ... p function | 234 | if (luaL_loadbuffer(L2, _bytecode.data(), _bytecode.size(), _fname) != 0) { // L2: ... {cache} ... p "<bytecode>" function |
253 | // chunk is precompiled so only LUA_ERRMEM can happen | 235 | // chunk is precompiled so only LUA_ERRMEM can happen |
254 | // "Otherwise, it pushes an error message" | 236 | // "Otherwise, it pushes an error message" |
255 | // | 237 | // |
256 | STACK_GROW(L1, 1); | 238 | STACK_GROW(L1, 1); |
257 | raise_luaL_error(getErrL(), "%s: %s", _fname, lua_tostring(L2, -1)); | 239 | raise_luaL_error(getErrL(), "%s: %s", _fname, lua_tostring(L2, kIdxTop)); |
258 | } | 240 | } |
259 | // remove the dumped string | 241 | // remove the dumped string |
260 | lua_pop(L1, 1); // ... | 242 | lua_replace(L2, -2); // L2: ... {cache} ... p function |
261 | // now set the cache as soon as we can. | 243 | // now set the cache as soon as we can. |
262 | // this is necessary if one of the function's upvalues references it indirectly | 244 | // this is necessary if one of the function's upvalues references it indirectly |
263 | // we need to find it in the cache even if it isn't fully transfered yet | 245 | // we need to find it in the cache even if it isn't fully transfered yet |
@@ -267,6 +249,7 @@ void InterCopyContext::copyFunction() const | |||
267 | lua_rawset(L2, L2_cache_i); // L2: ... {cache} ... function | 249 | lua_rawset(L2, L2_cache_i); // L2: ... {cache} ... function |
268 | } | 250 | } |
269 | STACK_CHECK(L1, 0); | 251 | STACK_CHECK(L1, 0); |
252 | STACK_CHECK(L2, 0); // cache key is replaced by the function, so no stack level change | ||
270 | 253 | ||
271 | /* push over any upvalues; references to this function will come from | 254 | /* push over any upvalues; references to this function will come from |
272 | * cache so we don't end up in eternal loop. | 255 | * cache so we don't end up in eternal loop. |
@@ -278,12 +261,12 @@ void InterCopyContext::copyFunction() const | |||
278 | { | 261 | { |
279 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; | 262 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; |
280 | // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table | 263 | // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table |
281 | luaG_pushglobaltable(L1); // L1: ... _G | 264 | luaW_pushglobaltable(L1); // L1: ... _G |
282 | for (char const* _upname{}; (_upname = lua_getupvalue(L1, L1_i, 1 + _n)); ++_n) { // L1: ... _G up[n] | 265 | for (char const* _upname{}; (_upname = lua_getupvalue(L1, L1_i, 1 + _n)); ++_n) { // L1: ... _G up[n] |
283 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); | 266 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); |
284 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? | 267 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? |
285 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); | 268 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); |
286 | luaG_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> | 269 | luaW_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> |
287 | } else { | 270 | } else { |
288 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); | 271 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); |
289 | _c.name = _upname; | 272 | _c.name = _upname; |
@@ -297,6 +280,7 @@ void InterCopyContext::copyFunction() const | |||
297 | lua_pop(L1, 1); // L1: ... | 280 | lua_pop(L1, 1); // L1: ... |
298 | } // L2: ... {cache} ... function + 'n' upvalues (>=0) | 281 | } // L2: ... {cache} ... function + 'n' upvalues (>=0) |
299 | STACK_CHECK(L1, 0); | 282 | STACK_CHECK(L1, 0); |
283 | STACK_CHECK(L2, _n); | ||
300 | 284 | ||
301 | // Set upvalues (originally set to 'nil' by 'lua_load') | 285 | // Set upvalues (originally set to 'nil' by 'lua_load') |
302 | for (StackIndex const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { | 286 | for (StackIndex const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { |
@@ -307,6 +291,7 @@ void InterCopyContext::copyFunction() const | |||
307 | // once all upvalues have been set we are left | 291 | // once all upvalues have been set we are left |
308 | // with the function at the top of the stack // L2: ... {cache} ... function | 292 | // with the function at the top of the stack // L2: ... {cache} ... function |
309 | } | 293 | } |
294 | STACK_CHECK(L2, 0); | ||
310 | STACK_CHECK(L1, 0); | 295 | STACK_CHECK(L1, 0); |
311 | } | 296 | } |
312 | 297 | ||
@@ -327,7 +312,7 @@ void InterCopyContext::lookupNativeFunction() const | |||
327 | 312 | ||
328 | case LookupMode::ToKeeper: | 313 | case LookupMode::ToKeeper: |
329 | // push a sentinel closure that holds the lookup name as upvalue | 314 | // push a sentinel closure that holds the lookup name as upvalue |
330 | luaG_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n" | 315 | luaW_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n" |
331 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f | 316 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f |
332 | break; | 317 | break; |
333 | 318 | ||
@@ -336,16 +321,16 @@ void InterCopyContext::lookupNativeFunction() const | |||
336 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} | 321 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} |
337 | STACK_CHECK(L2, 1); | 322 | STACK_CHECK(L2, 1); |
338 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 323 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
339 | luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" | 324 | luaW_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" |
340 | LuaType const _objType{ luaG_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f | 325 | LuaType const _objType{ luaW_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f |
341 | // nil means we don't know how to transfer stuff: user should do something | 326 | // nil means we don't know how to transfer stuff: user should do something |
342 | // anything other than function or table should not happen! | 327 | // anything other than function or table should not happen! |
343 | if (_objType != LuaType::FUNCTION && _objType != LuaType::TABLE && _objType != LuaType::USERDATA) { | 328 | if (_objType != LuaType::FUNCTION && _objType != LuaType::TABLE && _objType != LuaType::USERDATA) { |
344 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name | 329 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name |
345 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; | 330 | std::string_view const _from{ luaW_tostring(L1, kIdxTop) }; |
346 | lua_pop(L1, 1); // L1: ... f ... | 331 | lua_pop(L1, 1); // L1: ... f ... |
347 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name | 332 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name |
348 | std::string_view const _to{ luaG_tostring(L2, kIdxTop) }; | 333 | std::string_view const _to{ luaW_tostring(L2, kIdxTop) }; |
349 | lua_pop(L2, 1); // L2: {} f | 334 | lua_pop(L2, 1); // L2: {} f |
350 | raise_luaL_error( | 335 | raise_luaL_error( |
351 | getErrL(), | 336 | getErrL(), |
@@ -368,7 +353,7 @@ void InterCopyContext::lookupNativeFunction() const | |||
368 | // Always pushes a function to 'L2'. | 353 | // Always pushes a function to 'L2'. |
369 | void InterCopyContext::copyCachedFunction() const | 354 | void InterCopyContext::copyCachedFunction() const |
370 | { | 355 | { |
371 | FuncSubType const _funcSubType{ luaG_getfuncsubtype(L1, L1_i) }; | 356 | FuncSubType const _funcSubType{ luaW_getfuncsubtype(L1, L1_i) }; |
372 | if (_funcSubType == FuncSubType::Bytecode) { | 357 | if (_funcSubType == FuncSubType::Bytecode) { |
373 | void* const _aspointer{ const_cast<void*>(lua_topointer(L1, L1_i)) }; | 358 | void* const _aspointer{ const_cast<void*>(lua_topointer(L1, L1_i)) }; |
374 | // TODO: Merge this and same code for tables | 359 | // TODO: Merge this and same code for tables |
@@ -386,10 +371,10 @@ void InterCopyContext::copyCachedFunction() const | |||
386 | // push a light userdata uniquely representing the function | 371 | // push a light userdata uniquely representing the function |
387 | lua_pushlightuserdata(L2, _aspointer); // L2: ... {cache} ... p | 372 | lua_pushlightuserdata(L2, _aspointer); // L2: ... {cache} ... p |
388 | 373 | ||
389 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); | 374 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaW_tostring(L2, -1) << " >>" << std::endl); |
390 | 375 | ||
391 | lua_pushvalue(L2, -1); // L2: ... {cache} ... p p | 376 | lua_pushvalue(L2, -1); // L2: ... {cache} ... p p |
392 | if (luaG_rawget(L2, L2_cache_i) == LuaType::NIL) { // function is unknown // L2: ... {cache} ... p function|nil|true | 377 | if (luaW_rawget(L2, L2_cache_i) == LuaType::NIL) { // function is unknown // L2: ... {cache} ... p function|nil|true |
393 | lua_pop(L2, 1); // L2: ... {cache} ... p | 378 | lua_pop(L2, 1); // L2: ... {cache} ... p |
394 | 379 | ||
395 | // Set to 'true' for the duration of creation; need to find self-references | 380 | // Set to 'true' for the duration of creation; need to find self-references |
@@ -405,7 +390,7 @@ void InterCopyContext::copyCachedFunction() const | |||
405 | } else { // function is native/LuaJIT: no need to cache | 390 | } else { // function is native/LuaJIT: no need to cache |
406 | lookupNativeFunction(); // L2: ... {cache} ... function | 391 | lookupNativeFunction(); // L2: ... {cache} ... function |
407 | // if the function was in fact a lookup sentinel, we can either get a function, table or full userdata here | 392 | // if the function was in fact a lookup sentinel, we can either get a function, table or full userdata here |
408 | LUA_ASSERT(L1, lua_isfunction(L2, kIdxTop) || lua_istable(L2, kIdxTop) || luaG_type(L2, kIdxTop) == LuaType::USERDATA); | 393 | LUA_ASSERT(L1, lua_isfunction(L2, kIdxTop) || lua_istable(L2, kIdxTop) || luaW_type(L2, kIdxTop) == LuaType::USERDATA); |
409 | } | 394 | } |
410 | } | 395 | } |
411 | 396 | ||
@@ -430,7 +415,7 @@ bool InterCopyContext::lookupTable() const | |||
430 | 415 | ||
431 | case LookupMode::ToKeeper: | 416 | case LookupMode::ToKeeper: |
432 | // push a sentinel closure that holds the lookup name as upvalue | 417 | // push a sentinel closure that holds the lookup name as upvalue |
433 | luaG_pushstring(L2, _fqn); // L1: ... t ... L2: "f.q.n" | 418 | luaW_pushstring(L2, _fqn); // L1: ... t ... L2: "f.q.n" |
434 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f | 419 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f |
435 | break; | 420 | break; |
436 | 421 | ||
@@ -439,26 +424,26 @@ bool InterCopyContext::lookupTable() const | |||
439 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} | 424 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} |
440 | STACK_CHECK(L2, 1); | 425 | STACK_CHECK(L2, 1); |
441 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 426 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
442 | luaG_pushstring(L2, _fqn); // L2: {} "f.q.n" | 427 | luaW_pushstring(L2, _fqn); // L2: {} "f.q.n" |
443 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) | 428 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) |
444 | // but not when we extract something out of a keeper, as there is nothing to clone! | 429 | // but not when we extract something out of a keeper, as there is nothing to clone! |
445 | if (luaG_rawget(L2, StackIndex{ -2 }) == LuaType::NIL && mode == LookupMode::LaneBody) { // L2: {} t | 430 | if (luaW_rawget(L2, StackIndex{ -2 }) == LuaType::NIL && mode == LookupMode::LaneBody) { // L2: {} t |
446 | lua_pop(L2, 2); // L1: ... t ... L2: | 431 | lua_pop(L2, 2); // L1: ... t ... L2: |
447 | STACK_CHECK(L2, 0); | 432 | STACK_CHECK(L2, 0); |
448 | return false; | 433 | return false; |
449 | } else if (!lua_istable(L2, -1)) { // this can happen if someone decides to replace same already registered item (for a example a standard lib function) with a table | 434 | } else if (!lua_istable(L2, -1)) { // this can happen if someone decides to replace same already registered item (for a example a standard lib function) with a table |
450 | kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name | 435 | kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name |
451 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; | 436 | std::string_view const _from{ luaW_tostring(L1, kIdxTop) }; |
452 | lua_pop(L1, 1); // L1: ... t ... | 437 | lua_pop(L1, 1); // L1: ... t ... |
453 | kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name | 438 | kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name |
454 | std::string_view const _to{ luaG_tostring(L2, kIdxTop) }; | 439 | std::string_view const _to{ luaW_tostring(L2, kIdxTop) }; |
455 | lua_pop(L2, 1); // L1: ... t ... L2: {} t | 440 | lua_pop(L2, 1); // L1: ... t ... L2: {} t |
456 | raise_luaL_error( | 441 | raise_luaL_error( |
457 | getErrL(), | 442 | getErrL(), |
458 | "%s: source table '%s' found as %s in %s destination transfer database.", | 443 | "%s: source table '%s' found as %s in %s destination transfer database.", |
459 | _from.empty() ? "main" : _from.data(), | 444 | _from.empty() ? "main" : _from.data(), |
460 | _fqn.data(), | 445 | _fqn.data(), |
461 | luaG_typename(L2, kIdxTop).data(), | 446 | luaW_typename(L2, kIdxTop).data(), |
462 | _to.empty() ? "main" : _to.data()); | 447 | _to.empty() ? "main" : _to.data()); |
463 | } | 448 | } |
464 | lua_remove(L2, -2); // L1: ... t ... L2: t | 449 | lua_remove(L2, -2); // L1: ... t ... L2: t |
@@ -487,8 +472,8 @@ void InterCopyContext::interCopyKeyValuePair() const | |||
487 | char* _valPath{ nullptr }; | 472 | char* _valPath{ nullptr }; |
488 | if (U->verboseErrors) { | 473 | if (U->verboseErrors) { |
489 | // for debug purposes, let's try to build a useful name | 474 | // for debug purposes, let's try to build a useful name |
490 | if (luaG_type(L1, _key_i) == LuaType::STRING) { | 475 | if (luaW_type(L1, _key_i) == LuaType::STRING) { |
491 | std::string_view const _key{ luaG_tostring(L1, _key_i) }; | 476 | std::string_view const _key{ luaW_tostring(L1, _key_i) }; |
492 | size_t const _bufLen{ name.size() + _key.size() + 2 }; // +2 for separator dot and terminating 0 | 477 | size_t const _bufLen{ name.size() + _key.size() + 2 }; // +2 for separator dot and terminating 0 |
493 | _valPath = static_cast<char*>(alloca(_bufLen)); | 478 | _valPath = static_cast<char*>(alloca(_bufLen)); |
494 | sprintf(_valPath, "%s." STRINGVIEW_FMT, name.data(), (int) _key.size(), _key.data()); | 479 | sprintf(_valPath, "%s." STRINGVIEW_FMT, name.data(), (int) _key.size(), _key.data()); |
@@ -500,15 +485,15 @@ void InterCopyContext::interCopyKeyValuePair() const | |||
500 | sprintf(_valPath, "%s[" LUA_INTEGER_FMT "]", name.data(), key); | 485 | sprintf(_valPath, "%s[" LUA_INTEGER_FMT "]", name.data(), key); |
501 | } | 486 | } |
502 | #endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503 | 487 | #endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503 |
503 | else if (luaG_type(L1, _key_i) == LuaType::NUMBER) { | 488 | else if (luaW_type(L1, _key_i) == LuaType::NUMBER) { |
504 | lua_Number const key{ lua_tonumber(L1, _key_i) }; | 489 | lua_Number const key{ lua_tonumber(L1, _key_i) }; |
505 | _valPath = (char*) alloca(name.size() + 32 + 3); // +3 for [] and terminating 0 | 490 | _valPath = (char*) alloca(name.size() + 32 + 3); // +3 for [] and terminating 0 |
506 | sprintf(_valPath, "%s[" LUA_NUMBER_FMT "]", name.data(), key); | 491 | sprintf(_valPath, "%s[" LUA_NUMBER_FMT "]", name.data(), key); |
507 | } else if (luaG_type(L1, _key_i) == LuaType::LIGHTUSERDATA) { | 492 | } else if (luaW_type(L1, _key_i) == LuaType::LIGHTUSERDATA) { |
508 | void* const _key{ lua_touserdata(L1, _key_i) }; | 493 | void* const _key{ lua_touserdata(L1, _key_i) }; |
509 | _valPath = (char*) alloca(name.size() + 16 + 5); // +5 for [U:] and terminating 0 | 494 | _valPath = (char*) alloca(name.size() + 16 + 5); // +5 for [U:] and terminating 0 |
510 | sprintf(_valPath, "%s[U:%p]", name.data(), _key); | 495 | sprintf(_valPath, "%s[U:%p]", name.data(), _key); |
511 | } else if (luaG_type(L1, _key_i) == LuaType::BOOLEAN) { | 496 | } else if (luaW_type(L1, _key_i) == LuaType::BOOLEAN) { |
512 | int const _key{ lua_toboolean(L1, _key_i) }; | 497 | int const _key{ lua_toboolean(L1, _key_i) }; |
513 | _valPath = (char*) alloca(name.size() + 8); // +8 for [], 'false' and terminating 0 | 498 | _valPath = (char*) alloca(name.size() + 8); // +8 for [], 'false' and terminating 0 |
514 | sprintf(_valPath, "%s[%s]", name.data(), _key ? "true" : "false"); | 499 | sprintf(_valPath, "%s[%s]", name.data(), _key ? "true" : "false"); |
@@ -532,7 +517,7 @@ LuaType InterCopyContext::processConversion() const | |||
532 | { | 517 | { |
533 | static constexpr int kPODmask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); | 518 | static constexpr int kPODmask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); |
534 | 519 | ||
535 | LuaType _val_type{ luaG_type(L1, L1_i) }; | 520 | LuaType _val_type{ luaW_type(L1, L1_i) }; |
536 | 521 | ||
537 | STACK_CHECK_START_REL(L1, 0); | 522 | STACK_CHECK_START_REL(L1, 0); |
538 | 523 | ||
@@ -548,7 +533,7 @@ LuaType InterCopyContext::processConversion() const | |||
548 | } | 533 | } |
549 | // we have a metatable // L1: ... mt | 534 | // we have a metatable // L1: ... mt |
550 | static constexpr std::string_view kConvertField{ "__lanesconvert" }; | 535 | static constexpr std::string_view kConvertField{ "__lanesconvert" }; |
551 | LuaType const _converterType{ luaG_getfield(L1, kIdxTop, kConvertField) }; // L1: ... mt kConvertField | 536 | LuaType const _converterType{ luaW_getfield(L1, kIdxTop, kConvertField) }; // L1: ... mt kConvertField |
552 | switch (_converterType) { | 537 | switch (_converterType) { |
553 | case LuaType::NIL: | 538 | case LuaType::NIL: |
554 | // no __lanesconvert, nothing to do | 539 | // no __lanesconvert, nothing to do |
@@ -557,18 +542,18 @@ LuaType InterCopyContext::processConversion() const | |||
557 | 542 | ||
558 | case LuaType::LIGHTUSERDATA: | 543 | case LuaType::LIGHTUSERDATA: |
559 | if (kNilSentinel.equals(L1, kIdxTop)) { | 544 | if (kNilSentinel.equals(L1, kIdxTop)) { |
560 | DEBUGSPEW_CODE(DebugSpew(U) << "converted " << luaG_typename(L1, _val_type) << " to nil" << std::endl); | 545 | DEBUGSPEW_CODE(DebugSpew(U) << "converted " << luaW_typename(L1, _val_type) << " to nil" << std::endl); |
561 | lua_replace(L1, L1_i); // L1: ... mt | 546 | lua_replace(L1, L1_i); // L1: ... mt |
562 | lua_pop(L1, 1); // L1: ... | 547 | lua_pop(L1, 1); // L1: ... |
563 | _val_type = _converterType; | 548 | _val_type = _converterType; |
564 | } else { | 549 | } else { |
565 | raise_luaL_error(getErrL(), "Invalid %s type %s", kConvertField.data(), luaG_typename(L1, _converterType).data()); | 550 | raise_luaL_error(getErrL(), "Invalid %s type %s", kConvertField.data(), luaW_typename(L1, _converterType).data()); |
566 | } | 551 | } |
567 | break; | 552 | break; |
568 | 553 | ||
569 | case LuaType::STRING: | 554 | case LuaType::STRING: |
570 | // kConvertField == "decay" -> replace source value with it's pointer | 555 | // kConvertField == "decay" -> replace source value with it's pointer |
571 | if (std::string_view const _mode{ luaG_tostring(L1, kIdxTop) }; _mode == "decay") { | 556 | if (std::string_view const _mode{ luaW_tostring(L1, kIdxTop) }; _mode == "decay") { |
572 | lua_pop(L1, 1); // L1: ... mt | 557 | lua_pop(L1, 1); // L1: ... mt |
573 | lua_pushlightuserdata(L1, const_cast<void*>(lua_topointer(L1, L1_i))); // L1: ... mt decayed | 558 | lua_pushlightuserdata(L1, const_cast<void*>(lua_topointer(L1, L1_i))); // L1: ... mt decayed |
574 | lua_replace(L1, L1_i); // L1: ... mt | 559 | lua_replace(L1, L1_i); // L1: ... mt |
@@ -581,18 +566,18 @@ LuaType InterCopyContext::processConversion() const | |||
581 | 566 | ||
582 | case LuaType::FUNCTION: | 567 | case LuaType::FUNCTION: |
583 | lua_pushvalue(L1, L1_i); // L1: ... mt kConvertField val | 568 | lua_pushvalue(L1, L1_i); // L1: ... mt kConvertField val |
584 | luaG_pushstring(L1, mode == LookupMode::ToKeeper ? "keeper" : "regular"); // L1: ... mt kConvertField val string | 569 | luaW_pushstring(L1, mode == LookupMode::ToKeeper ? "keeper" : "regular"); // L1: ... mt kConvertField val string |
585 | lua_call(L1, 2, 1); // val:kConvertField(str) -> result // L1: ... mt kConvertField converted | 570 | lua_call(L1, 2, 1); // val:kConvertField(str) -> result // L1: ... mt kConvertField converted |
586 | lua_replace(L1, L1_i); // L1: ... mt | 571 | lua_replace(L1, L1_i); // L1: ... mt |
587 | lua_pop(L1, 1); // L1: ... mt | 572 | lua_pop(L1, 1); // L1: ... mt |
588 | _val_type = luaG_type(L1, L1_i); | 573 | _val_type = luaW_type(L1, L1_i); |
589 | break; | 574 | break; |
590 | 575 | ||
591 | default: | 576 | default: |
592 | raise_luaL_error(getErrL(), "Invalid %s type %s", kConvertField.data(), luaG_typename(L1, _converterType).data()); | 577 | raise_luaL_error(getErrL(), "Invalid %s type %s", kConvertField.data(), luaW_typename(L1, _converterType).data()); |
593 | } | 578 | } |
594 | STACK_CHECK(L1, 0); | 579 | STACK_CHECK(L1, 0); |
595 | LUA_ASSERT(getErrL(), luaG_type(L1, L1_i) == _val_type); | 580 | LUA_ASSERT(getErrL(), luaW_type(L1, L1_i) == _val_type); |
596 | return _val_type; | 581 | return _val_type; |
597 | } | 582 | } |
598 | 583 | ||
@@ -615,7 +600,7 @@ bool InterCopyContext::pushCachedMetatable() const | |||
615 | // do we already know this metatable? | 600 | // do we already know this metatable? |
616 | std::ignore = kMtIdRegKey.getSubTable(L2, NArr{ 0 }, NRec{ 0 }); // L2: _R[kMtIdRegKey] | 601 | std::ignore = kMtIdRegKey.getSubTable(L2, NArr{ 0 }, NRec{ 0 }); // L2: _R[kMtIdRegKey] |
617 | lua_pushinteger(L2, _mt_id); // L2: _R[kMtIdRegKey] id | 602 | lua_pushinteger(L2, _mt_id); // L2: _R[kMtIdRegKey] id |
618 | if (luaG_rawget(L2, StackIndex{ -2 }) == LuaType::NIL) { // L2 did not know the metatable // L2: _R[kMtIdRegKey] mt|nil | 603 | if (luaW_rawget(L2, StackIndex{ -2 }) == LuaType::NIL) { // L2 did not know the metatable // L2: _R[kMtIdRegKey] mt|nil |
619 | lua_pop(L2, 1); // L2: _R[kMtIdRegKey] | 604 | lua_pop(L2, 1); // L2: _R[kMtIdRegKey] |
620 | InterCopyContext const _c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name }; | 605 | InterCopyContext const _c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name }; |
621 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: _R[kMtIdRegKey] mt? | 606 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: _R[kMtIdRegKey] mt? |
@@ -662,9 +647,9 @@ bool InterCopyContext::pushCachedTable() const | |||
662 | // push a light userdata uniquely representing the table | 647 | // push a light userdata uniquely representing the table |
663 | lua_pushlightuserdata(L2, const_cast<void*>(_p)); // L1: ... t ... L2: ... p | 648 | lua_pushlightuserdata(L2, const_cast<void*>(_p)); // L1: ... t ... L2: ... p |
664 | 649 | ||
665 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); | 650 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaW_tostring(L2, -1) << " >>" << std::endl); |
666 | 651 | ||
667 | bool const _not_found_in_cache{ luaG_rawget(L2, L2_cache_i) == LuaType::NIL }; // L1: ... t ... L2: ... {cached|nil} | 652 | bool const _not_found_in_cache{ luaW_rawget(L2, L2_cache_i) == LuaType::NIL }; // L1: ... t ... L2: ... {cached|nil} |
668 | if (_not_found_in_cache) { | 653 | if (_not_found_in_cache) { |
669 | // create a new entry in the cache | 654 | // create a new entry in the cache |
670 | lua_pop(L2, 1); // L1: ... t ... L2: ... | 655 | lua_pop(L2, 1); // L1: ... t ... L2: ... |
@@ -696,7 +681,7 @@ bool InterCopyContext::lookupUserdata() const | |||
696 | 681 | ||
697 | case LookupMode::ToKeeper: | 682 | case LookupMode::ToKeeper: |
698 | // push a sentinel closure that holds the lookup name as upvalue | 683 | // push a sentinel closure that holds the lookup name as upvalue |
699 | luaG_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n" | 684 | luaW_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n" |
700 | lua_pushcclosure(L2, userdata_lookup_sentinel, 1); // L1: ... f ... L2: f | 685 | lua_pushcclosure(L2, userdata_lookup_sentinel, 1); // L1: ... f ... L2: f |
701 | break; | 686 | break; |
702 | 687 | ||
@@ -705,16 +690,16 @@ bool InterCopyContext::lookupUserdata() const | |||
705 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} | 690 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} |
706 | STACK_CHECK(L2, 1); | 691 | STACK_CHECK(L2, 1); |
707 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 692 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
708 | luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" | 693 | luaW_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" |
709 | LuaType const _type{ luaG_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f | 694 | LuaType const _type{ luaW_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f |
710 | // nil means we don't know how to transfer stuff: user should do something | 695 | // nil means we don't know how to transfer stuff: user should do something |
711 | // anything other than function or table should not happen! | 696 | // anything other than function or table should not happen! |
712 | if (_type != LuaType::FUNCTION && _type != LuaType::TABLE) { | 697 | if (_type != LuaType::FUNCTION && _type != LuaType::TABLE) { |
713 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name | 698 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name |
714 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; | 699 | std::string_view const _from{ luaW_tostring(L1, kIdxTop) }; |
715 | lua_pop(L1, 1); // L1: ... f ... | 700 | lua_pop(L1, 1); // L1: ... f ... |
716 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name | 701 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name |
717 | std::string_view const _to{ luaG_tostring(L2, kIdxTop) }; | 702 | std::string_view const _to{ luaW_tostring(L2, kIdxTop) }; |
718 | lua_pop(L2, 1); // L2: {} f | 703 | lua_pop(L2, 1); // L2: {} f |
719 | raise_luaL_error( | 704 | raise_luaL_error( |
720 | getErrL(), | 705 | getErrL(), |
@@ -736,7 +721,7 @@ bool InterCopyContext::lookupUserdata() const | |||
736 | [[nodiscard]] | 721 | [[nodiscard]] |
737 | bool InterCopyContext::tryCopyClonable() const | 722 | bool InterCopyContext::tryCopyClonable() const |
738 | { | 723 | { |
739 | SourceIndex const _L1_i{ luaG_absindex(L1, L1_i).value() }; | 724 | SourceIndex const _L1_i{ luaW_absindex(L1, L1_i).value() }; |
740 | void* const _source{ lua_touserdata(L1, _L1_i) }; | 725 | void* const _source{ lua_touserdata(L1, _L1_i) }; |
741 | 726 | ||
742 | STACK_CHECK_START_REL(L1, 0); | 727 | STACK_CHECK_START_REL(L1, 0); |
@@ -744,7 +729,7 @@ bool InterCopyContext::tryCopyClonable() const | |||
744 | 729 | ||
745 | // Check if the source was already cloned during this copy | 730 | // Check if the source was already cloned during this copy |
746 | lua_pushlightuserdata(L2, _source); // L2: ... source | 731 | lua_pushlightuserdata(L2, _source); // L2: ... source |
747 | if (luaG_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... clone? | 732 | if (luaW_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... clone? |
748 | STACK_CHECK(L2, 1); | 733 | STACK_CHECK(L2, 1); |
749 | return true; | 734 | return true; |
750 | } else { | 735 | } else { |
@@ -759,7 +744,7 @@ bool InterCopyContext::tryCopyClonable() const | |||
759 | } | 744 | } |
760 | 745 | ||
761 | // no __lanesclone? -> not clonable | 746 | // no __lanesclone? -> not clonable |
762 | if (luaG_getfield(L1, kIdxTop, "__lanesclone") == LuaType::NIL) { // L1: ... mt nil | 747 | if (luaW_getfield(L1, kIdxTop, "__lanesclone") == LuaType::NIL) { // L1: ... mt nil |
763 | lua_pop(L1, 2); // L1: ... | 748 | lua_pop(L1, 2); // L1: ... |
764 | STACK_CHECK(L1, 0); | 749 | STACK_CHECK(L1, 0); |
765 | return false; | 750 | return false; |
@@ -769,10 +754,10 @@ bool InterCopyContext::tryCopyClonable() const | |||
769 | 754 | ||
770 | // we need to copy over the uservalues of the userdata as well | 755 | // we need to copy over the uservalues of the userdata as well |
771 | { | 756 | { |
772 | StackIndex const _mt{ luaG_absindex(L1, StackIndex{ -2 }) }; // L1: ... mt __lanesclone | 757 | StackIndex const _mt{ luaW_absindex(L1, StackIndex{ -2 }) }; // L1: ... mt __lanesclone |
773 | auto const userdata_size{ static_cast<size_t>(lua_rawlen(L1, _L1_i)) }; // make 32-bits builds happy | 758 | auto const userdata_size{ static_cast<size_t>(lua_rawlen(L1, _L1_i)) }; // make 32-bits builds happy |
774 | // extract all the uservalues, but don't transfer them yet | 759 | // extract all the uservalues, but don't transfer them yet |
775 | UserValueCount const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* | 760 | UserValueCount const _nuv{ luaW_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* |
776 | // create the clone userdata with the required number of uservalue slots | 761 | // create the clone userdata with the required number of uservalue slots |
777 | void* const _clone{ lua_newuserdatauv(L2, userdata_size, _nuv) }; // L2: ... u | 762 | void* const _clone{ lua_newuserdatauv(L2, userdata_size, _nuv) }; // L2: ... u |
778 | // copy the metatable in the target state, and give it to the clone we put there | 763 | // copy the metatable in the target state, and give it to the clone we put there |
@@ -804,7 +789,7 @@ bool InterCopyContext::tryCopyClonable() const | |||
804 | // assign uservalues | 789 | // assign uservalues |
805 | UserValueIndex _uvi{ _nuv.value() }; | 790 | UserValueIndex _uvi{ _nuv.value() }; |
806 | while (_uvi > 0) { | 791 | while (_uvi > 0) { |
807 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() }; | 792 | _c.L1_i = SourceIndex{ luaW_absindex(L1, kIdxTop).value() }; |
808 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv | 793 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv |
809 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 794 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
810 | } | 795 | } |
@@ -850,10 +835,10 @@ bool InterCopyContext::tryCopyDeep() const | |||
850 | STACK_CHECK_START_REL(L2, 0); | 835 | STACK_CHECK_START_REL(L2, 0); |
851 | 836 | ||
852 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail | 837 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail |
853 | UserValueCount const _nuv{ luaG_getalluservalues(L1, L1_i) }; // L1: ... deep ... [uv]* | 838 | UserValueCount const _nuv{ luaW_getalluservalues(L1, L1_i) }; // L1: ... deep ... [uv]* |
854 | STACK_CHECK(L1, _nuv); | 839 | STACK_CHECK(L1, _nuv); |
855 | 840 | ||
856 | DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) }; | 841 | DeepPrelude* const _deep{ *luaW_tofulluserdata<DeepPrelude*>(L1, L1_i) }; |
857 | DeepFactory::PushDeepProxy(L2, _deep, _nuv, mode, getErrL()); // L1: ... deep ... [uv]* L2: deep | 842 | DeepFactory::PushDeepProxy(L2, _deep, _nuv, mode, getErrL()); // L1: ... deep ... [uv]* L2: deep |
858 | 843 | ||
859 | // transfer all uservalues of the source in the destination | 844 | // transfer all uservalues of the source in the destination |
@@ -863,7 +848,7 @@ bool InterCopyContext::tryCopyDeep() const | |||
863 | STACK_GROW(L2, _nuv); | 848 | STACK_GROW(L2, _nuv); |
864 | UserValueIndex _uvi{ _nuv.value() }; | 849 | UserValueIndex _uvi{ _nuv.value() }; |
865 | while (_uvi) { | 850 | while (_uvi) { |
866 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() }; | 851 | _c.L1_i = SourceIndex{ luaW_absindex(L1, kIdxTop).value() }; |
867 | if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv | 852 | if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv |
868 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 853 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
869 | } | 854 | } |
@@ -911,7 +896,7 @@ bool InterCopyContext::interCopyFunction() const | |||
911 | lua_getupvalue(L1, L1_i, 2); // L1: ... u | 896 | lua_getupvalue(L1, L1_i, 2); // L1: ... u |
912 | void* _source{ lua_touserdata(L1, -1) }; | 897 | void* _source{ lua_touserdata(L1, -1) }; |
913 | lua_pushlightuserdata(L2, _source); // L2: ... source | 898 | lua_pushlightuserdata(L2, _source); // L2: ... source |
914 | if (luaG_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... u? | 899 | if (luaW_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... u? |
915 | lua_pop(L1, 1); // L1: ... | 900 | lua_pop(L1, 1); // L1: ... |
916 | STACK_CHECK(L1, 0); | 901 | STACK_CHECK(L1, 0); |
917 | STACK_CHECK(L2, 1); | 902 | STACK_CHECK(L2, 1); |
@@ -933,7 +918,7 @@ bool InterCopyContext::interCopyFunction() const | |||
933 | auto const _userdata_size{ static_cast<size_t>(lua_rawlen(L1, kIdxTop)) }; // make 32-bits builds happy | 918 | auto const _userdata_size{ static_cast<size_t>(lua_rawlen(L1, kIdxTop)) }; // make 32-bits builds happy |
934 | { | 919 | { |
935 | // extract uservalues (don't transfer them yet) | 920 | // extract uservalues (don't transfer them yet) |
936 | UserValueCount const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]* | 921 | UserValueCount const _nuv{ luaW_getalluservalues(L1, source_i) }; // L1: ... u [uv]* |
937 | STACK_CHECK(L1, _nuv + 1); | 922 | STACK_CHECK(L1, _nuv + 1); |
938 | // create the clone userdata with the required number of uservalue slots | 923 | // create the clone userdata with the required number of uservalue slots |
939 | _clone = lua_newuserdatauv(L2, _userdata_size, _nuv); // L2: ... mt u | 924 | _clone = lua_newuserdatauv(L2, _userdata_size, _nuv); // L2: ... mt u |
@@ -948,7 +933,7 @@ bool InterCopyContext::interCopyFunction() const | |||
948 | InterCopyContext _c{ *this }; | 933 | InterCopyContext _c{ *this }; |
949 | UserValueIndex _uvi{ _nuv.value() }; | 934 | UserValueIndex _uvi{ _nuv.value() }; |
950 | while (_uvi > 0) { | 935 | while (_uvi > 0) { |
951 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() }; | 936 | _c.L1_i = SourceIndex{ luaW_absindex(L1, kIdxTop).value() }; |
952 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv | 937 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv |
953 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 938 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
954 | } | 939 | } |
@@ -965,9 +950,9 @@ bool InterCopyContext::interCopyFunction() const | |||
965 | // perform the custom cloning part | 950 | // perform the custom cloning part |
966 | lua_insert(L2, -2); // L2: ... u mt | 951 | lua_insert(L2, -2); // L2: ... u mt |
967 | // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with | 952 | // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with |
968 | LuaType const _funcType{ luaG_getfield(L2, kIdxTop, "__lanesclone") }; // L2: ... u mt __lanesclone | 953 | LuaType const _funcType{ luaW_getfield(L2, kIdxTop, "__lanesclone") }; // L2: ... u mt __lanesclone |
969 | if (_funcType != LuaType::FUNCTION) { | 954 | if (_funcType != LuaType::FUNCTION) { |
970 | raise_luaL_error(getErrL(), "INTERNAL ERROR: __lanesclone is a %s, not a function", luaG_typename(L2, _funcType).data()); | 955 | raise_luaL_error(getErrL(), "INTERNAL ERROR: __lanesclone is a %s, not a function", luaW_typename(L2, _funcType).data()); |
971 | } | 956 | } |
972 | lua_remove(L2, -2); // L2: ... u __lanesclone | 957 | lua_remove(L2, -2); // L2: ... u __lanesclone |
973 | lua_pushlightuserdata(L2, _clone); // L2: ... u __lanesclone clone | 958 | lua_pushlightuserdata(L2, _clone); // L2: ... u __lanesclone clone |
@@ -1060,9 +1045,9 @@ bool InterCopyContext::interCopyNumber() const | |||
1060 | [[nodiscard]] | 1045 | [[nodiscard]] |
1061 | bool InterCopyContext::interCopyString() const | 1046 | bool InterCopyContext::interCopyString() const |
1062 | { | 1047 | { |
1063 | std::string_view const _s{ luaG_tostring(L1, L1_i) }; | 1048 | std::string_view const _s{ luaW_tostring(L1, L1_i) }; |
1064 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "'" << _s << "'" << std::endl); | 1049 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "'" << _s << "'" << std::endl); |
1065 | luaG_pushstring(L2, _s); | 1050 | luaW_pushstring(L2, _s); |
1066 | return true; | 1051 | return true; |
1067 | } | 1052 | } |
1068 | 1053 | ||
@@ -1154,7 +1139,7 @@ bool InterCopyContext::interCopyUserdata() const | |||
1154 | 1139 | ||
1155 | // Last, let's try to see if this userdata is special (aka is it some userdata that we registered in our lookup databases during module registration?) | 1140 | // Last, let's try to see if this userdata is special (aka is it some userdata that we registered in our lookup databases during module registration?) |
1156 | if (lookupUserdata()) { | 1141 | if (lookupUserdata()) { |
1157 | LUA_ASSERT(L1, luaG_type(L2, kIdxTop) == LuaType::USERDATA || (lua_tocfunction(L2, kIdxTop) == userdata_lookup_sentinel)); // from lookup data. can also be userdata_lookup_sentinel if this is a userdata we know | 1142 | LUA_ASSERT(L1, luaW_type(L2, kIdxTop) == LuaType::USERDATA || (lua_tocfunction(L2, kIdxTop) == userdata_lookup_sentinel)); // from lookup data. can also be userdata_lookup_sentinel if this is a userdata we know |
1158 | return true; | 1143 | return true; |
1159 | } | 1144 | } |
1160 | 1145 | ||
@@ -1291,8 +1276,8 @@ InterCopyResult InterCopyContext::interCopyPackage() const | |||
1291 | } const _onExit{ L2 }; | 1276 | } const _onExit{ L2 }; |
1292 | 1277 | ||
1293 | STACK_CHECK_START_REL(L1, 0); | 1278 | STACK_CHECK_START_REL(L1, 0); |
1294 | if (luaG_type(L1, L1_i) != LuaType::TABLE) { | 1279 | if (luaW_type(L1, L1_i) != LuaType::TABLE) { |
1295 | std::string_view const _msg{ luaG_pushstring(L1, "expected package as table, got a %s", luaL_typename(L1, L1_i)) }; | 1280 | std::string_view const _msg{ luaW_pushstring(L1, "expected package as table, got a %s", luaL_typename(L1, L1_i)) }; |
1296 | STACK_CHECK(L1, 1); | 1281 | STACK_CHECK(L1, 1); |
1297 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 1282 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
1298 | if (mode == LookupMode::LaneBody) { | 1283 | if (mode == LookupMode::LaneBody) { |
@@ -1300,7 +1285,7 @@ InterCopyResult InterCopyContext::interCopyPackage() const | |||
1300 | } | 1285 | } |
1301 | return InterCopyResult::Error; | 1286 | return InterCopyResult::Error; |
1302 | } | 1287 | } |
1303 | if (luaG_getmodule(L2, LUA_LOADLIBNAME) == LuaType::NIL) { // package library not loaded: do nothing | 1288 | if (luaW_getmodule(L2, LUA_LOADLIBNAME) == LuaType::NIL) { // package library not loaded: do nothing |
1304 | DEBUGSPEW_CODE(DebugSpew(U) << "'package' not loaded, nothing to do" << std::endl); | 1289 | DEBUGSPEW_CODE(DebugSpew(U) << "'package' not loaded, nothing to do" << std::endl); |
1305 | STACK_CHECK(L1, 0); | 1290 | STACK_CHECK(L1, 0); |
1306 | return InterCopyResult::Success; | 1291 | return InterCopyResult::Success; |
@@ -1317,7 +1302,7 @@ InterCopyResult InterCopyContext::interCopyPackage() const | |||
1317 | continue; | 1302 | continue; |
1318 | } | 1303 | } |
1319 | DEBUGSPEW_CODE(DebugSpew(U) << "package." << _entry << std::endl); | 1304 | DEBUGSPEW_CODE(DebugSpew(U) << "package." << _entry << std::endl); |
1320 | if (luaG_getfield(L1, L1_i, _entry) == LuaType::NIL) { | 1305 | if (luaW_getfield(L1, L1_i, _entry) == LuaType::NIL) { |
1321 | lua_pop(L1, 1); | 1306 | lua_pop(L1, 1); |
1322 | } else { | 1307 | } else { |
1323 | { | 1308 | { |
@@ -1328,9 +1313,9 @@ InterCopyResult InterCopyContext::interCopyPackage() const | |||
1328 | STACK_CHECK(L1, 0); | 1313 | STACK_CHECK(L1, 0); |
1329 | } | 1314 | } |
1330 | if (_result == InterCopyResult::Success) { | 1315 | if (_result == InterCopyResult::Success) { |
1331 | luaG_setfield(L2, StackIndex{ -2 }, _entry); // set package[entry] | 1316 | luaW_setfield(L2, StackIndex{ -2 }, _entry); // set package[entry] |
1332 | } else { | 1317 | } else { |
1333 | std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; | 1318 | std::string_view const _msg{ luaW_pushstring(L1, "failed to copy package.%s", _entry.data()) }; |
1334 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 1319 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
1335 | if (mode == LookupMode::LaneBody) { | 1320 | if (mode == LookupMode::LaneBody) { |
1336 | raise_luaL_error(getErrL(), _msg); | 1321 | raise_luaL_error(getErrL(), _msg); |