aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-29 11:23:21 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-29 11:23:21 +0200
commit05921ccb8205a4dcf1897dd8be9aa30a09e9a379 (patch)
tree9bb3c3139fbdf1ca8b409163877f6a3f69a81260 /src
parent6b836d54fdbea502f47c546f8f04c347eba46d5c (diff)
downloadlanes-05921ccb8205a4dcf1897dd8be9aa30a09e9a379.tar.gz
lanes-05921ccb8205a4dcf1897dd8be9aa30a09e9a379.tar.bz2
lanes-05921ccb8205a4dcf1897dd8be9aa30a09e9a379.zip
PushDeepProxy internal change
Diffstat (limited to 'src')
-rw-r--r--src/deep.cpp87
-rw-r--r--src/deep.h2
-rw-r--r--src/intercopycontext.cpp9
-rw-r--r--src/lanes.cpp12
4 files changed, 48 insertions, 62 deletions
diff --git a/src/deep.cpp b/src/deep.cpp
index a39e0f8..dfa3579 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -177,28 +177,29 @@ void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_)
177 177
178/* 178/*
179 * Push a proxy userdata on the stack. 179 * Push a proxy userdata on the stack.
180 * returns nullptr if ok, else some error string related to bad factory behavior or module require problem 180 * raises an error in case of problem (error cannot happen with mode_ == LookupMode::ToKeeper)
181 * (error cannot happen with mode_ == LookupMode::ToKeeper)
182 * 181 *
183 * Initializes necessary structures if it's the first time 'factory' is being 182 * Initializes necessary structures if it's the first time 'factory' is being used in
184 * used in this Lua state (metatable, registring it). Otherwise, increments the 183 * this Lua state (metatable, registring it). Otherwise, increments the reference count.
185 * reference count.
186 */ 184 */
187std::string_view DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int nuv_, LookupMode mode_) 185void DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int nuv_, LookupMode mode_, lua_State* errL_)
188{ 186{
189 // Check if a proxy already exists 187 STACK_CHECK_START_REL(L_, 0);
190 kDeepProxyCacheRegKey.getSubTableMode(L_, "v"); // L_: DPC 188 kDeepProxyCacheRegKey.getSubTableMode(L_, "v"); // L_: DPC
189
190 // Check if a proxy already exists
191 lua_pushlightuserdata(L_, prelude_); // L_: DPC deep 191 lua_pushlightuserdata(L_, prelude_); // L_: DPC deep
192 lua_rawget(L_, -2); // L_: DPC proxy 192 lua_rawget(L_, -2); // L_: DPC proxy
193 if (!lua_isnil(L_, -1)) { 193 if (!lua_isnil(L_, -1)) {
194 lua_remove(L_, -2); // L_: proxy 194 lua_remove(L_, -2); // L_: proxy
195 return std::string_view{}; 195 STACK_CHECK(L_, 1);
196 return;
196 } else { 197 } else {
197 lua_pop(L_, 1); // L_: DPC 198 lua_pop(L_, 1); // L_: DPC
198 } 199 }
200 STACK_CHECK(L_, 1);
199 201
200 STACK_GROW(L_, 7); 202 STACK_GROW(L_, 7);
201 STACK_CHECK_START_REL(L_, 0);
202 203
203 // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) 204 // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4)
204 DeepPrelude** const _proxy{ lua_newuserdatauv<DeepPrelude*>(L_, nuv_) }; // L_: DPC proxy 205 DeepPrelude** const _proxy{ lua_newuserdatauv<DeepPrelude*>(L_, nuv_) }; // L_: DPC proxy
@@ -219,9 +220,7 @@ std::string_view DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_,
219 factory.createMetatable(L_); // L_: DPC proxy metatable 220 factory.createMetatable(L_); // L_: DPC proxy metatable
220 if (lua_gettop(L_) - _oldtop != 1 || !lua_istable(L_, -1)) { 221 if (lua_gettop(L_) - _oldtop != 1 || !lua_istable(L_, -1)) {
221 // factory didn't push exactly 1 value, or the value it pushed is not a table: ERROR! 222 // factory didn't push exactly 1 value, or the value it pushed is not a table: ERROR!
222 lua_settop(L_, _oldtop); // L_: DPC proxy X 223 raise_luaL_error(errL_, "Bad DeepFactory::createMetatable overload: unexpected pushed value");
223 lua_pop(L_, 3); // L_:
224 return "Bad DeepFactory::createMetatable overload: unexpected pushed value";
225 } 224 }
226 // if the metatable contains a __gc, we will call it from our own 225 // if the metatable contains a __gc, we will call it from our own
227 std::ignore = luaG_getfield(L_, -1, "__gc"); // L_: DPC proxy metatable __gc 226 std::ignore = luaG_getfield(L_, -1, "__gc"); // L_: DPC proxy metatable __gc
@@ -248,40 +247,42 @@ std::string_view DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_,
248 // L.registry._LOADED exists without having registered the 'package' library. 247 // L.registry._LOADED exists without having registered the 'package' library.
249 lua_getglobal(L_, "require"); // L_: DPC proxy metatable require() 248 lua_getglobal(L_, "require"); // L_: DPC proxy metatable require()
250 // check that the module is already loaded (or being loaded, we are happy either way) 249 // check that the module is already loaded (or being loaded, we are happy either way)
251 if (lua_isfunction(L_, -1)) { 250 if (!lua_isfunction(L_, -1)) { // a module name, but no require() function :-(
252 std::ignore = lua_pushstringview(L_, _modname); // L_: DPC proxy metatable require() "module" 251 raise_luaL_error(errL_, "lanes receiving deep userdata should register the 'package' library");
253 if (luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) == LuaType::TABLE) { // L_: DPC proxy metatable require() "module" _R._LOADED 252 }
254 lua_pushvalue(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED "module" 253
255 lua_rawget(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED module 254 std::ignore = lua_pushstringview(L_, _modname); // L_: DPC proxy metatable require() "module"
256 int const _alreadyloaded{ lua_toboolean(L_, -1) }; 255 if (luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) != LuaType::TABLE) { // L_: DPC proxy metatable require() "module" _R._LOADED
257 if (!_alreadyloaded) { // not loaded 256 // no L.registry._LOADED; can this ever happen?
258 lua_pop(L_, 2); // L_: DPC proxy metatable require() "module" 257 lua_pop(L_, 6); // L_:
259 // require "modname" 258 raise_luaL_error(errL_, "unexpected error while requiring a module identified by DeepFactory::moduleName");
260 LuaError const _require_result{ lua_pcall(L_, 1, 0, 0) }; // L_: DPC proxy metatable error? 259 }
261 if (_require_result != LuaError::OK) { 260
262 // failed, return the error message 261 lua_pushvalue(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED "module"
263 lua_pushfstring(L_, "error while requiring '" STRINGVIEW_FMT "' identified by DeepFactory::moduleName: ", _modname.size(), _modname.data()); 262 lua_rawget(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED module
264 lua_insert(L_, -2); // L_: DPC proxy metatable prefix error 263 int const _alreadyloaded{ lua_toboolean(L_, -1) };
265 lua_concat(L_, 2); // L_: DPC proxy metatable error 264 if (!_alreadyloaded) { // not loaded
266 return lua_tostringview(L_, -1); 265 lua_pop(L_, 2); // L_: DPC proxy metatable require() "module"
267 } 266 // require "modname". in case of error, raise it in errL_
268 } else { // already loaded, we are happy 267 if (L_ == errL_) {
269 lua_pop(L_, 4); // L_: DPC proxy metatable 268 lua_call(L_, 1, 0); // L_: DPC proxy metatable module
269 } else {
270 LuaError const _require_result{ lua_pcall(L_, 1, 0, 0) }; // L_: DPC proxy metatable error?
271 if (_require_result != LuaError::OK) {
272 // failed, raise the error in the proper state
273 std::ignore = lua_pushstringview(errL_, lua_tostringview(L_, -1));
274 raise_lua_error(errL_);
270 } 275 }
271 } else { // no L.registry._LOADED; can this ever happen?
272 lua_pop(L_, 6); // L_:
273 return std::string_view{ "unexpected error while requiring a module identified by DeepFactory::moduleName" };
274 } 276 }
275 } else { // a module name, but no require() function :-( 277 } else { // already loaded, we are happy
276 lua_pop(L_, 4); // L_: 278 lua_pop(L_, 4); // L_: DPC proxy metatable
277 return std::string_view{ "lanes receiving deep userdata should register the 'package' library" };
278 } 279 }
279 } 280 }
280 } 281 }
281 STACK_CHECK(L_, 2); // DPC proxy metatable 282 STACK_CHECK(L_, 3); // DPC proxy metatable
282 LUA_ASSERT(L_, lua_type_as_enum(L_, -2) == LuaType::USERDATA); 283 LUA_ASSERT(L_, lua_type_as_enum(L_, -2) == LuaType::USERDATA);
283 LUA_ASSERT(L_, lua_istable(L_, -1)); 284 LUA_ASSERT(L_, lua_istable(L_, -1));
284 lua_setmetatable(L_, -2); // DPC proxy 285 lua_setmetatable(L_, -2); // DPC proxy
285 286
286 // If we're here, we obviously had to create a new proxy, so cache it. 287 // If we're here, we obviously had to create a new proxy, so cache it.
287 lua_pushlightuserdata(L_, prelude_); // L_: DPC proxy deep 288 lua_pushlightuserdata(L_, prelude_); // L_: DPC proxy deep
@@ -289,8 +290,7 @@ std::string_view DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_,
289 lua_rawset(L_, -4); // L_: DPC proxy 290 lua_rawset(L_, -4); // L_: DPC proxy
290 lua_remove(L_, -2); // L_: proxy 291 lua_remove(L_, -2); // L_: proxy
291 LUA_ASSERT(L_, lua_type_as_enum(L_, -1) == LuaType::USERDATA); 292 LUA_ASSERT(L_, lua_type_as_enum(L_, -1) == LuaType::USERDATA);
292 STACK_CHECK(L_, 0); 293 STACK_CHECK(L_, 1);
293 return std::string_view{};
294} 294}
295 295
296// ################################################################################################# 296// #################################################################################################
@@ -335,10 +335,7 @@ int DeepFactory::pushDeepUserdata(DestState L_, int nuv_) const
335 raise_luaL_error(L_, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack"); 335 raise_luaL_error(L_, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack");
336 } 336 }
337 337
338 std::string_view const _err{ DeepFactory::PushDeepProxy(L_, _prelude, nuv_, LookupMode::LaneBody) }; // proxy 338 DeepFactory::PushDeepProxy(L_, _prelude, nuv_, LookupMode::LaneBody, L_); // proxy
339 if (!_err.empty()) {
340 raise_luaL_error(L_, _err.data());
341 }
342 STACK_CHECK(L_, 1); 339 STACK_CHECK(L_, 1);
343 return 1; 340 return 1;
344} 341}
diff --git a/src/deep.h b/src/deep.h
index dc32251..4b52b51 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -75,7 +75,7 @@ class DeepFactory
75 [[nodiscard]] int pushDeepUserdata(DestState L_, int nuv_) const; 75 [[nodiscard]] int pushDeepUserdata(DestState L_, int nuv_) const;
76 [[nodiscard]] DeepPrelude* toDeep(lua_State* L_, int index_) const; 76 [[nodiscard]] DeepPrelude* toDeep(lua_State* L_, int index_) const;
77 static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); 77 static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_);
78 [[nodiscard]] static std::string_view PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_); 78 static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_);
79}; 79};
80 80
81// ################################################################################################# 81// #################################################################################################
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index 978a69b..8058838 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -731,7 +731,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
731 STACK_CHECK_START_REL(L2, 0); 731 STACK_CHECK_START_REL(L2, 0);
732 732
733 // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail 733 // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail
734 int _nuv = 0; 734 int _nuv{ 0 };
735 while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil 735 while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil
736 ++_nuv; 736 ++_nuv;
737 } 737 }
@@ -739,11 +739,8 @@ void InterCopyContext::inter_copy_keyvaluepair() const
739 lua_pop(L1, 1); // L1: ... u [uv]* 739 lua_pop(L1, 1); // L1: ... u [uv]*
740 STACK_CHECK(L1, _nuv); 740 STACK_CHECK(L1, _nuv);
741 741
742 DeepPrelude* const u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) }; 742 DeepPrelude* const _u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) };
743 std::string_view const errmsg{ DeepFactory::PushDeepProxy(L2, u, _nuv, mode) }; // L1: ... u [uv]* L2: u 743 DeepFactory::PushDeepProxy(L2, _u, _nuv, mode, getErrL()); // L1: ... u [uv]* L2: u
744 if (!errmsg.empty()) {
745 raise_luaL_error(getErrL(), errmsg.data());
746 }
747 744
748 // transfer all uservalues of the source in the destination 745 // transfer all uservalues of the source in the destination
749 { 746 {
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 109fba4..bd5f69e 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -701,16 +701,8 @@ LUAG_FUNC(configure)
701 } 701 }
702 702
703 STACK_CHECK(L_, 2); 703 STACK_CHECK(L_, 2);
704 704 DeepFactory::PushDeepProxy(DestState{ L_ }, _U->timerLinda, 0, LookupMode::LaneBody, L_); // L_: settings M timerLinda
705 { 705 lua_setfield(L_, -2, "timer_gateway"); // L_: settings M
706 std::string_view const _errmsg{
707 DeepFactory::PushDeepProxy(DestState{ L_ }, _U->timerLinda, 0, LookupMode::LaneBody)
708 }; // L_: settings M timerLinda
709 if (!_errmsg.empty()) {
710 raise_luaL_error(L_, _errmsg.data());
711 }
712 lua_setfield(L_, -2, "timer_gateway"); // L_: settings M
713 }
714 STACK_CHECK(L_, 2); 706 STACK_CHECK(L_, 2);
715 707
716 // prepare the metatable for threads 708 // prepare the metatable for threads