diff options
Diffstat (limited to 'src/intercopycontext.cpp')
| -rw-r--r-- | src/intercopycontext.cpp | 38 |
1 files changed, 10 insertions, 28 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 7be1326..653eeb6 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_) |
| @@ -211,19 +194,18 @@ void InterCopyContext::copyFunction() const | |||
| 211 | // to the writer" (and we only return 0) | 194 | // to the writer" (and we only return 0) |
| 212 | // not sure this could ever fail but for memory shortage reasons | 195 | // not sure this could ever fail but for memory shortage reasons |
| 213 | // last argument is Lua 5.4-specific (no stripping) | 196 | // last argument is Lua 5.4-specific (no stripping) |
| 214 | luaL_Buffer B{}; | 197 | if (tools::PushFunctionBytecode(L1, U->stripFunctions) != 0) { // L1: ... f "<bytecode>" |
| 215 | if (luaW_dump(L1, buf_writer, &B, U->stripFunctions) != 0) { | ||
| 216 | raise_luaL_error(getErrL(), "internal error: function dump failed."); | 198 | raise_luaL_error(getErrL(), "internal error: function dump failed."); |
| 217 | } | 199 | } |
| 218 | 200 | ||
| 219 | // pushes dumped string on 'L1' | 201 | // 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) { | 202 | if (_needToPush) { |
| 224 | lua_remove(L1, -2); // L1: ... b | 203 | lua_remove(L1, -2); // L1: ... "<bytecode>" |
| 225 | } | 204 | } |
| 226 | 205 | ||
| 206 | // When we are done, the stack should be the original one, with the bytecode string added on top | ||
| 207 | STACK_CHECK(L1, 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: ... "<bytecode>" 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: ... "<bytecode>" |
| 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{ luaW_tostring(L1, kIdxTop) }; // L1: ... b | 225 | std::string_view const _bytecode{ luaW_tostring(L1, kIdxTop) }; // L1: ... "<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 |
| @@ -257,7 +239,7 @@ void InterCopyContext::copyFunction() const | |||
| 257 | raise_luaL_error(getErrL(), "%s: %s", _fname, lua_tostring(L2, -1)); | 239 | raise_luaL_error(getErrL(), "%s: %s", _fname, lua_tostring(L2, -1)); |
| 258 | } | 240 | } |
| 259 | // remove the dumped string | 241 | // remove the dumped string |
| 260 | lua_pop(L1, 1); // ... | 242 | lua_pop(L1, 1); // L1: ... |
| 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 |
