aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-06-06 10:23:30 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-06-06 10:23:30 +0200
commit75a7e10527f1588efa00677ee1f8f77591af0921 (patch)
tree460fd68f12ebea1a4afecd4d0e450b9aae1c5692 /src
parenta50367194b486e0abbe05aaee34b961e202635ba (diff)
downloadlanes-75a7e10527f1588efa00677ee1f8f77591af0921.tar.gz
lanes-75a7e10527f1588efa00677ee1f8f77591af0921.tar.bz2
lanes-75a7e10527f1588efa00677ee1f8f77591af0921.zip
Fix transfer of nil uservalues triggering a Lua API check because of conversion to nil sentinels in keeper states
Diffstat (limited to 'src')
-rw-r--r--src/compat.cpp35
-rw-r--r--src/compat.h8
2 files changed, 24 insertions, 19 deletions
diff --git a/src/compat.cpp b/src/compat.cpp
index 5923d29..3b026b4 100644
--- a/src/compat.cpp
+++ b/src/compat.cpp
@@ -70,7 +70,7 @@ void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, in
70// ################################################################################################# 70// #################################################################################################
71// ################################################################################################# 71// #################################################################################################
72 72
73void* lua_newuserdatauv(lua_State* L_, size_t sz_, int nuvalue_) 73void* lua_newuserdatauv(lua_State* L_, size_t sz_, [[maybe_unused]] int nuvalue_)
74{ 74{
75 LUA_ASSERT(L_, nuvalue_ <= 1); 75 LUA_ASSERT(L_, nuvalue_ <= 1);
76 return lua_newuserdata(L_, sz_); 76 return lua_newuserdata(L_, sz_);
@@ -81,26 +81,35 @@ void* lua_newuserdatauv(lua_State* L_, size_t sz_, int nuvalue_)
81// push on stack uservalue #n of full userdata at idx 81// push on stack uservalue #n of full userdata at idx
82int lua_getiuservalue(lua_State* L_, int idx_, int n_) 82int lua_getiuservalue(lua_State* L_, int idx_, int n_)
83{ 83{
84 STACK_CHECK_START_REL(L_, 0);
84 // full userdata can have only 1 uservalue before 5.4 85 // full userdata can have only 1 uservalue before 5.4
85 if (n_ > 1) { 86 if (n_ > 1) {
86 lua_pushnil(L_); 87 lua_pushnil(L_);
87 return LUA_TNONE; 88 return LUA_TNONE;
88 } 89 }
89 lua_getuservalue(L_, idx_);
90 90
91#if LUA_VERSION_NUM == 501 91#if LUA_VERSION_NUM == 501
92 /* default environment is not a nil (see lua_getfenv) */ 92 lua_getfenv(L_, idx_); // L_: ... {}|nil
93 lua_getglobal(L_, LUA_LOADLIBNAME); 93 STACK_CHECK(L_, 1);
94 // default environment is not a nil (see lua_getfenv)
95 lua_getglobal(L_, LUA_LOADLIBNAME); // L_: ... {}|nil package
94 if (lua_rawequal(L_, -2, -1) || lua_rawequal(L_, -2, LUA_GLOBALSINDEX)) { 96 if (lua_rawequal(L_, -2, -1) || lua_rawequal(L_, -2, LUA_GLOBALSINDEX)) {
95 lua_pop(L_, 2); 97 lua_pop(L_, 2); // L_: ...
96 lua_pushnil(L_); 98 lua_pushnil(L_); // L_: ... nil
97 99 STACK_CHECK(L_, 1);
98 return LUA_TNONE; 100 return LUA_TNONE;
99 } 101 }
100 lua_pop(L_, 1); /* remove package */ 102 else {
101#endif 103 lua_pop(L_, 1); // L_: ... nil
102 104 }
103 return lua_type(L_, -1); 105#else // LUA_VERSION_NUM > 501
106 lua_getuservalue(L_, idx_); // L_: {}|nil
107#endif// LUA_VERSION_NUM > 501
108 STACK_CHECK(L_, 1);
109 int const _uvType{ lua_type(L_, -1) };
110 // under Lua 5.2, there is a single uservalue that is either nil or a table.
111 // If nil, don't transfer it, as it can cause issues when copying to a Keeper state because of nil sentinel conversion
112 return (LUA_VERSION_NUM == 502 && _uvType == LUA_TNIL) ? LUA_TNONE : _uvType;
104} 113}
105 114
106// ################################################################################################# 115// #################################################################################################
@@ -118,7 +127,11 @@ int lua_setiuservalue(lua_State* L_, int idx_, int n_)
118 return 0; 127 return 0;
119 } 128 }
120 129
130#if LUA_VERSION_NUM == 501
131 lua_setfenv(L_, idx_);
132#else // LUA_VERSION_NUM == 501
121 lua_setuservalue(L_, idx_); 133 lua_setuservalue(L_, idx_);
134#endif // LUA_VERSION_NUM == 501
122 return 1; // I guess anything non-0 is ok 135 return 1; // I guess anything non-0 is ok
123} 136}
124 137
diff --git a/src/compat.h b/src/compat.h
index 6307d86..1789a8b 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -67,14 +67,6 @@ inline void lua_pushglobaltable(lua_State* L_)
67 lua_pushvalue(L_, LUA_GLOBALSINDEX); 67 lua_pushvalue(L_, LUA_GLOBALSINDEX);
68} 68}
69#endif // LUAJIT_VERSION_NUM 69#endif // LUAJIT_VERSION_NUM
70inline int lua_setuservalue(lua_State* L_, int idx_)
71{
72 return lua_setfenv(L_, idx_);
73}
74inline void lua_getuservalue(lua_State* L_, int idx_)
75{
76 lua_getfenv(L_, idx_);
77}
78inline size_t lua_rawlen(lua_State* L_, int idx_) 70inline size_t lua_rawlen(lua_State* L_, int idx_)
79{ 71{
80 return lua_objlen(L_, idx_); 72 return lua_objlen(L_, idx_);