aboutsummaryrefslogtreecommitdiff
path: root/src/intercopycontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r--src/intercopycontext.cpp189
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]]
44static 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]]
58static int func_lookup_sentinel(lua_State* const L_) 41static 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]]
94std::string_view InterCopyContext::findLookupName() const 77std::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]]
159static lua_Integer get_mt_id(Universe* const U_, lua_State* const L_, StackIndex const idx_) 142static 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
196void InterCopyContext::copyFunction() const 179void 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'.
369void InterCopyContext::copyCachedFunction() const 354void 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]]
737bool InterCopyContext::tryCopyClonable() const 722bool 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]]
1061bool InterCopyContext::interCopyString() const 1046bool 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);