diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-24 08:59:08 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-24 09:09:56 +0200 |
| commit | c3e9e26d5eb455f95e62fa8801cca9d4e7792acc (patch) | |
| tree | 5b8645817abe4eb1123647a4e9c5204d0e35d9b1 /src/intercopycontext.cpp | |
| parent | 3be94c4282bbe77895e952afb12a81e55c2a4391 (diff) | |
| download | lanes-c3e9e26d5eb455f95e62fa8801cca9d4e7792acc.tar.gz lanes-c3e9e26d5eb455f95e62fa8801cca9d4e7792acc.tar.bz2 lanes-c3e9e26d5eb455f95e62fa8801cca9d4e7792acc.zip | |
Process upvalues equal to _G in Lua51 as in other flavors
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') |
