aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deep_test/deeptest.lua5
-rw-r--r--src/deep.cpp16
-rw-r--r--src/tools.cpp31
-rw-r--r--src/tools.h4
4 files changed, 29 insertions, 27 deletions
diff --git a/deep_test/deeptest.lua b/deep_test/deeptest.lua
index 33de003..09b638c 100644
--- a/deep_test/deeptest.lua
+++ b/deep_test/deeptest.lua
@@ -7,7 +7,7 @@ local dt = lanes.require "deep_test"
7local test_deep = true 7local test_deep = true
8local test_clonable = true 8local test_clonable = true
9local test_uvtype = "string" 9local test_uvtype = "string"
10local nupvals = _VERSION == "Lua 5.4" and 2 or 1 10local nupvals = _VERSION == "Lua 5.4" and 3 or 1
11 11
12local makeUserValue = function( obj_) 12local makeUserValue = function( obj_)
13 if test_uvtype == "string" then 13 if test_uvtype == "string" then
@@ -43,7 +43,8 @@ local performTest = function( obj_)
43 obj_:setuv( 1, makeUserValue( obj_)) 43 obj_:setuv( 1, makeUserValue( obj_))
44 -- lua 5.4 supports multiple uservalues of arbitrary types 44 -- lua 5.4 supports multiple uservalues of arbitrary types
45 if nupvals > 1 then 45 if nupvals > 1 then
46 obj_:setuv( 2, "ENDUV") 46 -- keep uv #2 as nil
47 obj_:setuv( 3, "ENDUV")
47 end 48 end
48 49
49 local t = 50 local t =
diff --git a/src/deep.cpp b/src/deep.cpp
index a824f72..735a14c 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -381,7 +381,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
381 STACK_CHECK_START_REL(L1, 0); 381 STACK_CHECK_START_REL(L1, 0);
382 STACK_CHECK_START_REL(L2, 0); 382 STACK_CHECK_START_REL(L2, 0);
383 383
384 // extract all uservalues of the source 384 // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail
385 int nuv = 0; 385 int nuv = 0;
386 while (lua_getiuservalue(L1, L1_i, nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil 386 while (lua_getiuservalue(L1, L1_i, nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil
387 ++nuv; 387 ++nuv;
@@ -391,7 +391,10 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
391 STACK_CHECK(L1, nuv); 391 STACK_CHECK(L1, nuv);
392 392
393 DeepPrelude* const u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) }; 393 DeepPrelude* const u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) };
394 char const* errmsg{ DeepFactory::PushDeepProxy(L2, u, nuv, mode) }; // L2: u 394 char const* errmsg{ DeepFactory::PushDeepProxy(L2, u, nuv, mode) }; // L1: ... u [uv]* L2: u
395 if (errmsg != nullptr) {
396 raise_luaL_error(getErrL(), errmsg);
397 }
395 398
396 // transfer all uservalues of the source in the destination 399 // transfer all uservalues of the source in the destination
397 { 400 {
@@ -399,8 +402,8 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
399 int const clone_i{ lua_gettop(L2) }; 402 int const clone_i{ lua_gettop(L2) };
400 while (nuv) { 403 while (nuv) {
401 c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; 404 c.L1_i = SourceIndex{ lua_absindex(L1, -1) };
402 if (!c.inter_copy_one()) { // L2: u uv 405 if (!c.inter_copy_one()) { // L1: ... u [uv]* L2: u uv
403 raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 406 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
404 } 407 }
405 lua_pop(L1, 1); // L1: ... u [uv]* 408 lua_pop(L1, 1); // L1: ... u [uv]*
406 // this pops the value from the stack 409 // this pops the value from the stack
@@ -412,10 +415,5 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
412 STACK_CHECK(L2, 1); 415 STACK_CHECK(L2, 1);
413 STACK_CHECK(L1, 0); 416 STACK_CHECK(L1, 0);
414 417
415 if (errmsg != nullptr) {
416 // raise the error in the proper state (not the keeper)
417 lua_State* const errL{ (mode == LookupMode::FromKeeper) ? L2 : L1 };
418 raise_luaL_error(errL, errmsg);
419 }
420 return true; 418 return true;
421} \ No newline at end of file 419} \ No newline at end of file
diff --git a/src/tools.cpp b/src/tools.cpp
index 0495561..a55ee75 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -616,7 +616,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
616 STACK_GROW(L2, 3); // up to 3 slots are necessary on error 616 STACK_GROW(L2, 3); // up to 3 slots are necessary on error
617 switch (mode) { 617 switch (mode) {
618 default: // shouldn't happen, in theory... 618 default: // shouldn't happen, in theory...
619 raise_luaL_error(L1, "internal error: unknown lookup mode"); 619 raise_luaL_error(getErrL(), "internal error: unknown lookup mode");
620 break; 620 break;
621 621
622 case LookupMode::ToKeeper: 622 case LookupMode::ToKeeper:
@@ -646,9 +646,8 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
646 lua_getglobal(L2, "decoda_name"); // L1: ... t ... L2: {} t decoda_name 646 lua_getglobal(L2, "decoda_name"); // L1: ... t ... L2: {} t decoda_name
647 to = lua_tostring(L2, -1); 647 to = lua_tostring(L2, -1);
648 lua_pop(L2, 1); // L1: ... t ... L2: {} t 648 lua_pop(L2, 1); // L1: ... t ... L2: {} t
649 // when mode_ == LookupMode::FromKeeper, L1 is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
650 raise_luaL_error( 649 raise_luaL_error(
651 (mode == LookupMode::FromKeeper) ? L2 : L1, 650 getErrL(),
652 "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database.", 651 "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database.",
653 from ? from : "main", 652 from ? from : "main",
654 fqn, 653 fqn,
@@ -889,7 +888,7 @@ void InterCopyContext::lookup_native_func() const
889 STACK_GROW(L2, 3); // up to 3 slots are necessary on error 888 STACK_GROW(L2, 3); // up to 3 slots are necessary on error
890 switch (mode) { 889 switch (mode) {
891 default: // shouldn't happen, in theory... 890 default: // shouldn't happen, in theory...
892 raise_luaL_error(L1, "internal error: unknown lookup mode"); 891 raise_luaL_error(getErrL(), "internal error: unknown lookup mode");
893 break; 892 break;
894 893
895 case LookupMode::ToKeeper: 894 case LookupMode::ToKeeper:
@@ -916,7 +915,7 @@ void InterCopyContext::lookup_native_func() const
916 lua_pop(L2, 1); // L2: {} f 915 lua_pop(L2, 1); // L2: {} f
917 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 916 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
918 raise_luaL_error( 917 raise_luaL_error(
919 (mode == LookupMode::FromKeeper) ? L2 : L1 918 getErrL()
920 , "%s%s: function '%s' not found in %s destination transfer database." 919 , "%s%s: function '%s' not found in %s destination transfer database."
921 , lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN " 920 , lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN "
922 , from ? from : "main" 921 , from ? from : "main"
@@ -1010,7 +1009,7 @@ void InterCopyContext::copy_func() const
1010 luaL_Buffer B; 1009 luaL_Buffer B;
1011 B.L = nullptr; 1010 B.L = nullptr;
1012 if (lua504_dump(L1, buf_writer, &B, 0) != 0) { 1011 if (lua504_dump(L1, buf_writer, &B, 0) != 0) {
1013 raise_luaL_error(L1, "internal error: function dump failed."); 1012 raise_luaL_error(getErrL(), "internal error: function dump failed.");
1014 } 1013 }
1015 1014
1016 // pushes dumped string on 'L1' 1015 // pushes dumped string on 'L1'
@@ -1054,7 +1053,7 @@ void InterCopyContext::copy_func() const
1054 // "Otherwise, it pushes an error message" 1053 // "Otherwise, it pushes an error message"
1055 // 1054 //
1056 STACK_GROW(L1, 1); 1055 STACK_GROW(L1, 1);
1057 raise_luaL_error(L1, "%s: %s", fname, lua_tostring(L2, -1)); 1056 raise_luaL_error(getErrL(), "%s: %s", fname, lua_tostring(L2, -1));
1058 } 1057 }
1059 // remove the dumped string 1058 // remove the dumped string
1060 lua_pop(L1, 1); // ... 1059 lua_pop(L1, 1); // ...
@@ -1094,7 +1093,7 @@ void InterCopyContext::copy_func() const
1094 DEBUGSPEW_CODE(fprintf(stderr, "copying value\n")); 1093 DEBUGSPEW_CODE(fprintf(stderr, "copying value\n"));
1095 c.L1_i = SourceIndex{ lua_gettop(L1) }; 1094 c.L1_i = SourceIndex{ lua_gettop(L1) };
1096 if (!c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues> 1095 if (!c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues>
1097 raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 1096 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
1098 } 1097 }
1099 } 1098 }
1100 lua_pop(L1, 1); // L1: ... _G 1099 lua_pop(L1, 1); // L1: ... _G
@@ -1196,7 +1195,7 @@ void InterCopyContext::copy_cached_func() const
1196 lua_pop(L2, 1); // L2: _R[kMtIdRegKey] 1195 lua_pop(L2, 1); // L2: _R[kMtIdRegKey]
1197 InterCopyContext const c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name }; 1196 InterCopyContext const c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name };
1198 if (!c.inter_copy_one()) { // L2: _R[kMtIdRegKey] mt? 1197 if (!c.inter_copy_one()) { // L2: _R[kMtIdRegKey] mt?
1199 raise_luaL_error(L1, "Error copying a metatable"); 1198 raise_luaL_error(getErrL(), "Error copying a metatable");
1200 } 1199 }
1201 1200
1202 STACK_CHECK(L2, 2); // L2: _R[kMtIdRegKey] mt 1201 STACK_CHECK(L2, 2); // L2: _R[kMtIdRegKey] mt
@@ -1275,7 +1274,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1275 LUA_ASSERT(L1, lua_istable(L2, -3)); 1274 LUA_ASSERT(L1, lua_istable(L2, -3));
1276 lua_rawset(L2, -3); // add to table (pops key & val) 1275 lua_rawset(L2, -3); // add to table (pops key & val)
1277 } else { 1276 } else {
1278 raise_luaL_error(L1, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L1, val_i)); 1277 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));
1279 } 1278 }
1280} 1279}
1281 1280
@@ -1342,7 +1341,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1342 } 1341 }
1343 STACK_CHECK(L2, 1); 1342 STACK_CHECK(L2, 1);
1344 } else { 1343 } else {
1345 raise_luaL_error(L1, "Error copying a metatable"); 1344 raise_luaL_error(getErrL(), "Error copying a metatable");
1346 } 1345 }
1347 // first, add the entry in the cache (at this point it is either the actual userdata or the keeper sentinel 1346 // first, add the entry in the cache (at this point it is either the actual userdata or the keeper sentinel
1348 lua_pushlightuserdata(L2, source); // L2: ... u source 1347 lua_pushlightuserdata(L2, source); // L2: ... u source
@@ -1356,7 +1355,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1356 while (uvi > 0) { 1355 while (uvi > 0) {
1357 c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; 1356 c.L1_i = SourceIndex{ lua_absindex(L1, -1) };
1358 if (!c.inter_copy_one()) { // L2: ... u uv 1357 if (!c.inter_copy_one()) { // L2: ... u uv
1359 raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 1358 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
1360 } 1359 }
1361 lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]* 1360 lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]*
1362 // this pops the value from the stack 1361 // this pops the value from the stack
@@ -1419,7 +1418,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1419 void* const lud{ lua_touserdata(L1, L1_i) }; 1418 void* const lud{ lua_touserdata(L1, L1_i) };
1420 lua_pushlightuserdata(L2, lud); 1419 lua_pushlightuserdata(L2, lud);
1421 } else { // raise an error 1420 } else { // raise an error
1422 raise_luaL_error(L1, "can't copy non-deep full userdata across lanes"); 1421 raise_luaL_error(getErrL(), "can't copy non-deep full userdata across lanes");
1423 } 1422 }
1424 1423
1425 STACK_CHECK(L2, 1); 1424 STACK_CHECK(L2, 1);
@@ -1489,7 +1488,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1489 while (uvi > 0) { 1488 while (uvi > 0) {
1490 c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; 1489 c.L1_i = SourceIndex{ lua_absindex(L1, -1) };
1491 if (!c.inter_copy_one()) { // L2: ... mt u uv 1490 if (!c.inter_copy_one()) { // L2: ... mt u uv
1492 raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 1491 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
1493 } 1492 }
1494 lua_pop(L1, 1); // L1: ... u [uv]* 1493 lua_pop(L1, 1); // L1: ... u [uv]*
1495 // this pops the value from the stack 1494 // this pops the value from the stack
@@ -1827,7 +1826,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1827 STACK_CHECK(L1, 1); 1826 STACK_CHECK(L1, 1);
1828 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later 1827 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later
1829 if (mode == LookupMode::LaneBody) { 1828 if (mode == LookupMode::LaneBody) {
1830 raise_lua_error(L1); 1829 raise_lua_error(getErrL());
1831 } 1830 }
1832 return InterCopyResult::Error; 1831 return InterCopyResult::Error;
1833 } 1832 }
@@ -1864,7 +1863,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1864 lua_pushfstring(L1, "failed to copy package entry %s", entry); 1863 lua_pushfstring(L1, "failed to copy package entry %s", entry);
1865 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later 1864 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later
1866 if (mode == LookupMode::LaneBody) { 1865 if (mode == LookupMode::LaneBody) {
1867 raise_lua_error(L1); 1866 raise_lua_error(getErrL());
1868 } 1867 }
1869 lua_pop(L1, 1); 1868 lua_pop(L1, 1);
1870 break; 1869 break;
diff --git a/src/tools.h b/src/tools.h
index f5fdabc..9d4ed4c 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -42,6 +42,10 @@ class InterCopyContext
42 char const* name; // that one can change when we reuse the context 42 char const* name; // that one can change when we reuse the context
43 43
44 private: 44 private:
45 // when mode == LookupMode::FromKeeper, L1 is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
46 // whon mode != LookupMode::FromKeeper, L1 is not a keeper state, therefore L1 is the state where we want to raise the error
47 lua_State* getErrL() const { return (mode == LookupMode::FromKeeper) ? L2 : L1; }
48
45 // for use in copy_cached_func 49 // for use in copy_cached_func
46 void copy_func() const; 50 void copy_func() const;
47 void lookup_native_func() const; 51 void lookup_native_func() const;