diff options
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r-- | src/intercopycontext.cpp | 87 |
1 files changed, 41 insertions, 46 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 2f83400..1487afd 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -96,38 +96,37 @@ THE SOFTWARE. | |||
96 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v | 96 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v |
97 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" | 97 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
98 | } | 98 | } |
99 | size_t _len{ 0 }; | 99 | std::string_view _fqn{ lua_tostringview(L1, -1) }; |
100 | char const* _fqn{ lua_tolstring(L1, -1, &_len) }; | ||
101 | DEBUGSPEW_CODE(Universe* const _U = universe_get(L1)); | 100 | DEBUGSPEW_CODE(Universe* const _U = universe_get(L1)); |
102 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(_U), _fqn)); | 101 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(_U), _fqn.data())); |
103 | // 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 |
104 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... | 103 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
105 | STACK_CHECK(L1, 0); | 104 | STACK_CHECK(L1, 0); |
106 | if (nullptr == _fqn && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) | 105 | if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) |
107 | _len = 0; // just in case | 106 | _fqn = std::string_view{}; // just in case |
108 | // try to discover the name of the function we want to send | 107 | // try to discover the name of the function we want to send |
109 | lua_getglobal(L1, "decoda_name"); // L1: ... v ... decoda_name | 108 | lua_getglobal(L1, "decoda_name"); // L1: ... v ... decoda_name |
110 | char const* from{ lua_tostring(L1, -1) }; | 109 | char const* _from{ lua_tostring(L1, -1) }; |
111 | lua_pushcfunction(L1, luaG_nameof); // L1: ... v ... decoda_name luaG_nameof | 110 | lua_pushcfunction(L1, luaG_nameof); // L1: ... v ... decoda_name luaG_nameof |
112 | lua_pushvalue(L1, L1_i); // L1: ... v ... decoda_name luaG_nameof t | 111 | lua_pushvalue(L1, L1_i); // L1: ... v ... decoda_name luaG_nameof t |
113 | lua_call(L1, 1, 2); // L1: ... v ... decoda_name "type" "name"|nil | 112 | lua_call(L1, 1, 2); // L1: ... v ... decoda_name "type" "name"|nil |
114 | char const* typewhat{ (lua_type(L1, -2) == LUA_TSTRING) ? lua_tostring(L1, -2) : luaL_typename(L1, -2) }; | 113 | char const* _typewhat{ (lua_type(L1, -2) == LUA_TSTRING) ? lua_tostring(L1, -2) : luaL_typename(L1, -2) }; |
115 | // 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 |
116 | // 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. |
117 | char const *what, *gotchaA, *gotchaB; | 116 | char const *_what, *_gotchaA, *_gotchaB; |
118 | if (lua_isnil(L1, -1)) { | 117 | if (lua_isnil(L1, -1)) { |
119 | gotchaA = " referenced by"; | 118 | _gotchaA = " referenced by"; |
120 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; | 119 | _gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; |
121 | what = name; | 120 | _what = name; |
122 | } else { | 121 | } else { |
123 | gotchaA = ""; | 122 | _gotchaA = ""; |
124 | gotchaB = ""; | 123 | _gotchaB = ""; |
125 | what = (lua_type(L1, -1) == LUA_TSTRING) ? lua_tostring(L1, -1) : luaL_typename(L1, -1); | 124 | _what = (lua_type(L1, -1) == LUA_TSTRING) ? lua_tostring(L1, -1) : luaL_typename(L1, -1); |
126 | } | 125 | } |
127 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); | 126 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat, _gotchaA, _what, _from ? _from : "main", _gotchaB); |
128 | } | 127 | } |
129 | STACK_CHECK(L1, 0); | 128 | STACK_CHECK(L1, 0); |
130 | return std::string_view{ _fqn, _len }; | 129 | return _fqn; |
131 | } | 130 | } |
132 | 131 | ||
133 | // ################################################################################################# | 132 | // ################################################################################################# |
@@ -208,7 +207,7 @@ void InterCopyContext::copy_func() const | |||
208 | 207 | ||
209 | // transfer the bytecode, then the upvalues, to create a similar closure | 208 | // transfer the bytecode, then the upvalues, to create a similar closure |
210 | { | 209 | { |
211 | char const* fname = nullptr; | 210 | char const* _fname{}; |
212 | #define LOG_FUNC_INFO 0 | 211 | #define LOG_FUNC_INFO 0 |
213 | #if LOG_FUNC_INFO | 212 | #if LOG_FUNC_INFO |
214 | // "To get information about a function you push it onto the | 213 | // "To get information about a function you push it onto the |
@@ -219,14 +218,13 @@ void InterCopyContext::copy_func() const | |||
219 | lua_pushvalue(L1, L1_i); // L1: ... b f | 218 | lua_pushvalue(L1, L1_i); // L1: ... b f |
220 | // fills 'fname' 'namewhat' and 'linedefined', pops function | 219 | // fills 'fname' 'namewhat' and 'linedefined', pops function |
221 | lua_getinfo(L1, ">nS", &_ar); // L1: ... b | 220 | lua_getinfo(L1, ">nS", &_ar); // L1: ... b |
222 | fname = _ar.namewhat; | 221 | _fname = _ar.namewhat; |
223 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "FNAME: %s @ %d" INDENT_END(U), _ar.short_src, _ar.linedefined)); // just gives nullptr | 222 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "FNAME: %s @ %d" INDENT_END(U), _ar.short_src, _ar.linedefined)); // just gives nullptr |
224 | } | 223 | } |
225 | #endif // LOG_FUNC_INFO | 224 | #endif // LOG_FUNC_INFO |
226 | { | 225 | { |
227 | size_t _sz; | 226 | std::string_view const _bytecode{ lua_tostringview(L1, -1) }; // L1: ... b |
228 | char const* _s{ lua_tolstring(L1, -1, &_sz) }; // L1: ... b | 227 | LUA_ASSERT(L1, !_bytecode.empty()); |
229 | LUA_ASSERT(L1, _s && _sz); | ||
230 | STACK_GROW(L2, 2); | 228 | STACK_GROW(L2, 2); |
231 | // Note: Line numbers seem to be taken precisely from the | 229 | // Note: Line numbers seem to be taken precisely from the |
232 | // original function. 'fname' is not used since the chunk | 230 | // original function. 'fname' is not used since the chunk |
@@ -234,12 +232,12 @@ void InterCopyContext::copy_func() const | |||
234 | // | 232 | // |
235 | // TBD: Can we get the function's original name through, as well? | 233 | // TBD: Can we get the function's original name through, as well? |
236 | // | 234 | // |
237 | if (luaL_loadbuffer(L2, _s, _sz, fname) != 0) { // L2: ... {cache} ... p function | 235 | if (luaL_loadbuffer(L2, _bytecode.data(), _bytecode.size(), _fname) != 0) { // L2: ... {cache} ... p function |
238 | // chunk is precompiled so only LUA_ERRMEM can happen | 236 | // chunk is precompiled so only LUA_ERRMEM can happen |
239 | // "Otherwise, it pushes an error message" | 237 | // "Otherwise, it pushes an error message" |
240 | // | 238 | // |
241 | STACK_GROW(L1, 1); | 239 | STACK_GROW(L1, 1); |
242 | raise_luaL_error(getErrL(), "%s: %s", fname, lua_tostring(L2, -1)); | 240 | raise_luaL_error(getErrL(), "%s: %s", _fname, lua_tostring(L2, -1)); |
243 | } | 241 | } |
244 | // remove the dumped string | 242 | // remove the dumped string |
245 | lua_pop(L1, 1); // ... | 243 | lua_pop(L1, 1); // ... |
@@ -268,7 +266,7 @@ void InterCopyContext::copy_func() const | |||
268 | lua_pushglobaltable(L1); // L1: ... _G | 266 | lua_pushglobaltable(L1); // L1: ... _G |
269 | #endif // LUA_VERSION_NUM | 267 | #endif // LUA_VERSION_NUM |
270 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] | 268 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] |
271 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "UPNAME[%d]: %s -> " INDENT_END(U), n, _c.name)); | 269 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "UPNAME[%d]: %s -> " INDENT_END(U), _n, _c.name)); |
272 | #if LUA_VERSION_NUM >= 502 | 270 | #if LUA_VERSION_NUM >= 502 |
273 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? | 271 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? |
274 | DEBUGSPEW_CODE(fprintf(stderr, "pushing destination global scope\n")); | 272 | DEBUGSPEW_CODE(fprintf(stderr, "pushing destination global scope\n")); |
@@ -350,7 +348,7 @@ void InterCopyContext::lookup_native_func() const | |||
350 | "%s%s: function '%s' not found in %s destination transfer database.", | 348 | "%s%s: function '%s' not found in %s destination transfer database.", |
351 | lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ", | 349 | lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ", |
352 | _from ? _from : "main", | 350 | _from ? _from : "main", |
353 | _fqn, | 351 | _fqn.data(), |
354 | _to ? _to : "main"); | 352 | _to ? _to : "main"); |
355 | return; | 353 | return; |
356 | } | 354 | } |
@@ -499,47 +497,45 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
499 | // maybe offer this possibility as a global configuration option, or a linda setting, or as a parameter of the call causing the transfer? | 497 | // maybe offer this possibility as a global configuration option, or a linda setting, or as a parameter of the call causing the transfer? |
500 | } | 498 | } |
501 | 499 | ||
502 | char* valPath{ nullptr }; | 500 | char* _valPath{ nullptr }; |
503 | if (U->verboseErrors) { | 501 | if (U->verboseErrors) { |
504 | // for debug purposes, let's try to build a useful name | 502 | // for debug purposes, let's try to build a useful name |
505 | if (lua_type(L1, _key_i) == LUA_TSTRING) { | 503 | if (lua_type(L1, _key_i) == LUA_TSTRING) { |
506 | char const* key{ lua_tostring(L1, _key_i) }; | 504 | std::string_view const _key{ lua_tostringview(L1, _key_i) }; |
507 | size_t const keyRawLen = lua_rawlen(L1, _key_i); | 505 | size_t const _bufLen{ strlen(name) + _key.size() + 2 }; // +2 for separator dot and terminating 0 |
508 | size_t const bufLen = strlen(name) + keyRawLen + 2; | 506 | _valPath = static_cast<char*>(alloca(_bufLen)); |
509 | valPath = (char*) alloca(bufLen); | 507 | sprintf(_valPath, "%s.%*s", name, static_cast<int>(_key.size()), _key.data()); |
510 | sprintf(valPath, "%s.%*s", name, (int) keyRawLen, key); | ||
511 | key = nullptr; | ||
512 | } | 508 | } |
513 | #if defined LUA_LNUM || LUA_VERSION_NUM >= 503 | 509 | #if defined LUA_LNUM || LUA_VERSION_NUM >= 503 |
514 | else if (lua_isinteger(L1, _key_i)) { | 510 | else if (lua_isinteger(L1, _key_i)) { |
515 | lua_Integer const key{ lua_tointeger(L1, _key_i) }; | 511 | lua_Integer const key{ lua_tointeger(L1, _key_i) }; |
516 | valPath = (char*) alloca(strlen(name) + 32 + 3); | 512 | _valPath = (char*) alloca(strlen(name) + 32 + 3); // +3 for [] and terminating 0 |
517 | sprintf(valPath, "%s[" LUA_INTEGER_FMT "]", name, key); | 513 | sprintf(_valPath, "%s[" LUA_INTEGER_FMT "]", name, key); |
518 | } | 514 | } |
519 | #endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503 | 515 | #endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503 |
520 | else if (lua_type(L1, _key_i) == LUA_TNUMBER) { | 516 | else if (lua_type(L1, _key_i) == LUA_TNUMBER) { |
521 | lua_Number const key{ lua_tonumber(L1, _key_i) }; | 517 | lua_Number const key{ lua_tonumber(L1, _key_i) }; |
522 | valPath = (char*) alloca(strlen(name) + 32 + 3); | 518 | _valPath = (char*) alloca(strlen(name) + 32 + 3); // +3 for [] and terminating 0 |
523 | sprintf(valPath, "%s[" LUA_NUMBER_FMT "]", name, key); | 519 | sprintf(_valPath, "%s[" LUA_NUMBER_FMT "]", name, key); |
524 | } else if (lua_type(L1, _key_i) == LUA_TLIGHTUSERDATA) { | 520 | } else if (lua_type(L1, _key_i) == LUA_TLIGHTUSERDATA) { |
525 | void* const key{ lua_touserdata(L1, _key_i) }; | 521 | void* const key{ lua_touserdata(L1, _key_i) }; |
526 | valPath = (char*) alloca(strlen(name) + 16 + 5); | 522 | _valPath = (char*) alloca(strlen(name) + 16 + 5); // +5 for [U:] and terminating 0 |
527 | sprintf(valPath, "%s[U:%p]", name, key); | 523 | sprintf(_valPath, "%s[U:%p]", name, key); |
528 | } else if (lua_type(L1, _key_i) == LUA_TBOOLEAN) { | 524 | } else if (lua_type(L1, _key_i) == LUA_TBOOLEAN) { |
529 | int const key{ lua_toboolean(L1, _key_i) }; | 525 | int const key{ lua_toboolean(L1, _key_i) }; |
530 | valPath = (char*) alloca(strlen(name) + 8); | 526 | _valPath = (char*) alloca(strlen(name) + 8); // +8 for [], 'false' and terminating 0 |
531 | sprintf(valPath, "%s[%s]", name, key ? "true" : "false"); | 527 | sprintf(_valPath, "%s[%s]", name, key ? "true" : "false"); |
532 | } | 528 | } |
533 | } | 529 | } |
534 | _c.L1_i = SourceIndex{ _val_i }; | 530 | _c.L1_i = SourceIndex{ _val_i }; |
535 | // Contents of metatables are copied with cache checking. important to detect loops. | 531 | // Contents of metatables are copied with cache checking. important to detect loops. |
536 | _c.vt = VT::NORMAL; | 532 | _c.vt = VT::NORMAL; |
537 | _c.name = valPath ? valPath : name; | 533 | _c.name = _valPath ? _valPath : name; |
538 | if (_c.inter_copy_one()) { | 534 | if (_c.inter_copy_one()) { |
539 | LUA_ASSERT(L1, lua_istable(L2, -3)); | 535 | LUA_ASSERT(L1, lua_istable(L2, -3)); |
540 | lua_rawset(L2, -3); // add to table (pops key & val) | 536 | lua_rawset(L2, -3); // add to table (pops key & val) |
541 | } else { | 537 | } else { |
542 | raise_luaL_error(getErrL(), "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L1, _val_i)); | 538 | raise_luaL_error(getErrL(), "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", _valPath, luaL_typename(L1, _val_i)); |
543 | } | 539 | } |
544 | } | 540 | } |
545 | 541 | ||
@@ -931,10 +927,9 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
931 | 927 | ||
932 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const | 928 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const |
933 | { | 929 | { |
934 | size_t _len{ 0 }; | 930 | std::string_view const _s{ lua_tostringview(L1, L1_i) }; |
935 | char const* const _s{ lua_tolstring(L1, L1_i, &_len) }; | 931 | DEBUGSPEW_CODE(fprintf(stderr, "'%s'\n", _s.data())); |
936 | DEBUGSPEW_CODE(fprintf(stderr, "'%s'\n", _s)); | 932 | lua_pushlstring(L2, _s.data(), _s.size()); |
937 | lua_pushlstring(L2, _s, _len); | ||
938 | return true; | 933 | return true; |
939 | } | 934 | } |
940 | 935 | ||