diff options
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r-- | src/intercopycontext.cpp | 30 |
1 files changed, 9 insertions, 21 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index adbb502..6684f3f 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -209,19 +209,17 @@ void InterCopyContext::copy_func() const | |||
209 | { | 209 | { |
210 | char const* _fname{}; | 210 | char const* _fname{}; |
211 | #define LOG_FUNC_INFO 0 | 211 | #define LOG_FUNC_INFO 0 |
212 | #if LOG_FUNC_INFO | 212 | if constexpr (LOG_FUNC_INFO) |
213 | // "To get information about a function you push it onto the | ||
214 | // stack and start the what string with the character '>'." | ||
215 | // | ||
216 | { | 213 | { |
217 | lua_Debug _ar; | 214 | lua_Debug _ar; |
218 | lua_pushvalue(L1, L1_i); // L1: ... b f | 215 | lua_pushvalue(L1, L1_i); // L1: ... b f |
216 | // "To get information about a function you push it onto the stack and start the what string with the character '>'." | ||
219 | // fills 'fname' 'namewhat' and 'linedefined', pops function | 217 | // fills 'fname' 'namewhat' and 'linedefined', pops function |
220 | lua_getinfo(L1, ">nS", &_ar); // L1: ... b | 218 | lua_getinfo(L1, ">nS", &_ar); // L1: ... b |
221 | _fname = _ar.namewhat; | 219 | _fname = _ar.namewhat; |
222 | DEBUGSPEW_CODE(DebugSpew(U) << "FNAME: " << _ar.short_src << " @ " << _ar.linedefined << std::endl); | 220 | DEBUGSPEW_CODE(DebugSpew(U) << "FNAME: " << _ar.short_src << " @ " << _ar.linedefined << std::endl); |
223 | } | 221 | } |
224 | #endif // LOG_FUNC_INFO | 222 | |
225 | { | 223 | { |
226 | std::string_view const _bytecode{ lua_tostringview(L1, -1) }; // L1: ... b | 224 | std::string_view const _bytecode{ lua_tostringview(L1, -1) }; // L1: ... b |
227 | LUA_ASSERT(L1, !_bytecode.empty()); | 225 | LUA_ASSERT(L1, !_bytecode.empty()); |
@@ -255,26 +253,20 @@ void InterCopyContext::copy_func() const | |||
255 | * cache so we don't end up in eternal loop. | 253 | * cache so we don't end up in eternal loop. |
256 | * Lua5.2 and Lua5.3: one of the upvalues is _ENV, which we don't want to copy! | 254 | * Lua5.2 and Lua5.3: one of the upvalues is _ENV, which we don't want to copy! |
257 | * instead, the function shall have LUA_RIDX_GLOBALS taken in the destination state! | 255 | * instead, the function shall have LUA_RIDX_GLOBALS taken in the destination state! |
256 | * TODO: this can probably be factorized as InterCopyContext::copyUpvalues(...) | ||
258 | */ | 257 | */ |
259 | int _n{ 0 }; | 258 | int _n{ 0 }; |
260 | { | 259 | { |
261 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; | 260 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; |
262 | #if LUA_VERSION_NUM >= 502 | 261 | // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table |
263 | // Starting with Lua 5.2, each Lua function gets its environment as one of its upvalues (named LUA_ENV, aka "_ENV" by default) | ||
264 | // Generally this is LUA_RIDX_GLOBALS, which we don't want to copy from the source to the destination state... | ||
265 | // -> if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table | ||
266 | lua_pushglobaltable(L1); // L1: ... _G | 262 | lua_pushglobaltable(L1); // L1: ... _G |
267 | #endif // LUA_VERSION_NUM | ||
268 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] | 263 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] |
269 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); | 264 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); |
270 | #if LUA_VERSION_NUM >= 502 | ||
271 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? | 265 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? |
272 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); | 266 | DEBUGSPEW_CODE(DebugSpew(U) << "pushing destination global scope" << std::endl); |
273 | lua_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> | 267 | lua_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> |
274 | } else | 268 | } else { |
275 | #endif // LUA_VERSION_NUM | 269 | DEBUGSPEW_CODE(DebugSpew(U) << "copying value" << std::endl); |
276 | { | ||
277 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); | ||
278 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; | 270 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; |
279 | if (!_c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues> | 271 | if (!_c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues> |
280 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 272 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
@@ -282,12 +274,8 @@ void InterCopyContext::copy_func() const | |||
282 | } | 274 | } |
283 | lua_pop(L1, 1); // L1: ... _G | 275 | lua_pop(L1, 1); // L1: ... _G |
284 | } | 276 | } |
285 | #if LUA_VERSION_NUM >= 502 | ||
286 | lua_pop(L1, 1); // L1: ... | 277 | lua_pop(L1, 1); // L1: ... |
287 | #endif // LUA_VERSION_NUM | 278 | } // L2: ... {cache} ... function + 'n' upvalues (>=0) |
288 | } | ||
289 | // L2: ... {cache} ... function + 'n' upvalues (>=0) | ||
290 | |||
291 | STACK_CHECK(L1, 0); | 279 | STACK_CHECK(L1, 0); |
292 | 280 | ||
293 | // Set upvalues (originally set to 'nil' by 'lua_load') | 281 | // Set upvalues (originally set to 'nil' by 'lua_load') |