aboutsummaryrefslogtreecommitdiff
path: root/src/intercopycontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r--src/intercopycontext.cpp30
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')