From 3e3805297301b15f688297c9c7f65153aec86818 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 29 Apr 2024 12:22:28 +0200 Subject: Function parameters L → L_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cancel.cpp | 86 +++--- src/cancel.h | 8 +- src/compat.cpp | 86 +++--- src/compat.h | 6 +- src/deep.cpp | 92 +++--- src/keeper.cpp | 472 ++++++++++++++-------------- src/keeper.h | 22 +- src/lanes.cpp | 823 ++++++++++++++++++++++++------------------------- src/lanes.h | 6 +- src/lanes_private.h | 4 +- src/linda.cpp | 256 +++++++-------- src/linda.h | 2 +- src/lindafactory.cpp | 2 +- src/macros_and_utils.h | 28 +- src/state.cpp | 102 +++--- src/state.h | 6 +- src/tools.cpp | 635 +++++++++++++++++++------------------- src/tools.h | 10 +- src/universe.cpp | 32 +- src/universe.h | 24 +- 20 files changed, 1345 insertions(+), 1357 deletions(-) diff --git a/src/cancel.cpp b/src/cancel.cpp index cff1443..82c6def 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp @@ -51,9 +51,9 @@ THE SOFTWARE. * Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'raise_cancel_error()' called, * to make execution of the lane end. */ -[[nodiscard]] static inline CancelRequest cancel_test(lua_State* L) +[[nodiscard]] static inline CancelRequest cancel_test(lua_State* L_) { - Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L) }; + Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L_) }; // 'lane' is nullptr for the original main state (and no-one can cancel that) return lane ? lane->cancel_request : CancelRequest::None; } @@ -68,21 +68,21 @@ THE SOFTWARE. // LUAG_FUNC(cancel_test) { - CancelRequest test{ cancel_test(L) }; - lua_pushboolean(L, test != CancelRequest::None); + CancelRequest test{ cancel_test(L_) }; + lua_pushboolean(L_, test != CancelRequest::None); return 1; } // ################################################################################################# // ################################################################################################# -[[nodiscard]] static void cancel_hook(lua_State* L, [[maybe_unused]] lua_Debug* ar) +[[nodiscard]] static void cancel_hook(lua_State* L_, [[maybe_unused]] lua_Debug* ar) { DEBUGSPEW_CODE(fprintf(stderr, "cancel_hook\n")); - if (cancel_test(L) != CancelRequest::None) + if (cancel_test(L_) != CancelRequest::None) { - lua_sethook(L, nullptr, 0, 0); - raise_cancel_error(L); + lua_sethook(L_, nullptr, 0, 0); + raise_cancel_error(L_); } } @@ -204,16 +204,16 @@ CancelOp which_cancel_op(char const* op_string_) // ################################################################################################# -[[nodiscard]] static CancelOp which_cancel_op(lua_State* L, int idx_) +[[nodiscard]] static CancelOp which_cancel_op(lua_State* L_, int idx_) { - if (lua_type(L, idx_) == LUA_TSTRING) + if (lua_type(L_, idx_) == LUA_TSTRING) { - char const* const str{ lua_tostring(L, idx_) }; + char const* const str{ lua_tostring(L_, idx_) }; CancelOp op{ which_cancel_op(str) }; - lua_remove(L, idx_); // argument is processed, remove it + lua_remove(L_, idx_); // argument is processed, remove it if (op == CancelOp::Invalid) { - raise_luaL_error(L, "invalid hook option %s", str); + raise_luaL_error(L_, "invalid hook option %s", str); } return op; } @@ -225,58 +225,52 @@ CancelOp which_cancel_op(char const* op_string_) // bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lindas]) LUAG_FUNC(thread_cancel) { - Lane* const lane{ ToLane(L, 1) }; - CancelOp const op{ which_cancel_op(L, 2) }; // this removes the op string from the stack + Lane* const lane{ ToLane(L_, 1) }; + CancelOp const op{ which_cancel_op(L_, 2) }; // this removes the op string from the stack int hook_count{ 0 }; if (static_cast(op) > static_cast(CancelOp::Soft)) // hook is requested { - hook_count = static_cast(luaL_checkinteger(L, 2)); - lua_remove(L, 2); // argument is processed, remove it - if (hook_count < 1) - { - raise_luaL_error(L, "hook count cannot be < 1"); + hook_count = static_cast(luaL_checkinteger(L_, 2)); + lua_remove(L_, 2); // argument is processed, remove it + if (hook_count < 1) { + raise_luaL_error(L_, "hook count cannot be < 1"); } } lua_Duration wait_timeout{ 0.0 }; - if (lua_type(L, 2) == LUA_TNUMBER) - { - wait_timeout = lua_Duration{ lua_tonumber(L, 2) }; - lua_remove(L, 2); // argument is processed, remove it - if (wait_timeout.count() < 0.0) - { - raise_luaL_error(L, "cancel timeout cannot be < 0"); + if (lua_type(L_, 2) == LUA_TNUMBER) { + wait_timeout = lua_Duration{ lua_tonumber(L_, 2) }; + lua_remove(L_, 2); // argument is processed, remove it + if (wait_timeout.count() < 0.0) { + raise_luaL_error(L_, "cancel timeout cannot be < 0"); } } // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired bool wake_lane{ op != CancelOp::Soft }; - if (lua_gettop(L) >= 2) - { - if (!lua_isboolean(L, 2)) - { - raise_luaL_error(L, "wake_lindas parameter is not a boolean"); + if (lua_gettop(L_) >= 2) { + if (!lua_isboolean(L_, 2)) { + raise_luaL_error(L_, "wake_lindas parameter is not a boolean"); } - wake_lane = lua_toboolean(L, 2); - lua_remove(L, 2); // argument is processed, remove it + wake_lane = lua_toboolean(L_, 2); + lua_remove(L_, 2); // argument is processed, remove it } - STACK_CHECK_START_REL(L, 0); - switch (thread_cancel(lane, op, hook_count, wait_timeout, wake_lane)) - { - default: // should never happen unless we added a case and forgot to handle it - LUA_ASSERT(L, false); + STACK_CHECK_START_REL(L_, 0); + switch (thread_cancel(lane, op, hook_count, wait_timeout, wake_lane)) { + default: // should never happen unless we added a case and forgot to handle it + LUA_ASSERT(L_, false); break; - case CancelResult::Timeout: - lua_pushboolean(L, 0); // false - lua_pushstring(L, "timeout"); // false "timeout" + case CancelResult::Timeout: + lua_pushboolean(L_, 0); // false + lua_pushstring(L_, "timeout"); // false "timeout" break; - case CancelResult::Cancelled: - lua_pushboolean(L, 1); // true - lane->pushThreadStatus(L); // true status + case CancelResult::Cancelled: + lua_pushboolean(L_, 1); // true + lane->pushThreadStatus(L_); // true status break; } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); return 2; } diff --git a/src/cancel.h b/src/cancel.h index 8c8063f..59ebefe 100644 --- a/src/cancel.h +++ b/src/cancel.h @@ -51,11 +51,11 @@ static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_er [[nodiscard]] CancelOp which_cancel_op(char const* op_string_); [[nodiscard]] CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hook_count_, lua_Duration secs_, bool wake_lindas_); -[[noreturn]] static inline void raise_cancel_error(lua_State* L) +[[noreturn]] static inline void raise_cancel_error(lua_State* L_) { - STACK_GROW(L, 1); - kCancelError.pushKey(L); // special error value - raise_lua_error(L); + STACK_GROW(L_, 1); + kCancelError.pushKey(L_); // special error value + raise_lua_error(L_); } // ################################################################################################# diff --git a/src/compat.cpp b/src/compat.cpp index 712aa23..41a206a 100644 --- a/src/compat.cpp +++ b/src/compat.cpp @@ -12,37 +12,35 @@ // ################################################################################################# // Copied from Lua 5.2 loadlib.c -static int luaL_getsubtable(lua_State* L, int idx, const char* fname) +static int luaL_getsubtable(lua_State* L_, int idx, const char* fname) { - lua_getfield(L, idx, fname); - if (lua_istable(L, -1)) - return 1; /* table already there */ - else - { - lua_pop(L, 1); /* remove previous result */ - idx = lua_absindex(L, idx); - lua_newtable(L); - lua_pushvalue(L, -1); /* copy to be left at top */ - lua_setfield(L, idx, fname); /* assign new table to field */ - return 0; /* false, because did not find table there */ + lua_getfield(L_, idx, fname); + if (lua_istable(L_, -1)) + return 1; /* table already there */ + else { + lua_pop(L_, 1); /* remove previous result */ + idx = lua_absindex(L_, idx); + lua_newtable(L_); + lua_pushvalue(L_, -1); /* copy to be left at top */ + lua_setfield(L_, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ } } // ################################################################################################# -void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) +void luaL_requiref(lua_State* L_, const char* modname, lua_CFunction openf, int glb) { - lua_pushcfunction(L, openf); - lua_pushstring(L, modname); /* argument to open function */ - lua_call(L, 1, 1); /* open module */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - lua_pushvalue(L, -2); /* make copy of module (call result) */ - lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ - lua_pop(L, 1); /* remove _LOADED table */ - if (glb) - { - lua_pushvalue(L, -1); /* copy of 'mod' */ - lua_setglobal(L, modname); /* _G[modname] = module */ + lua_pushcfunction(L_, openf); + lua_pushstring(L_, modname); /* argument to open function */ + lua_call(L_, 1, 1); /* open module */ + luaL_getsubtable(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_pushvalue(L_, -2); /* make copy of module (call result) */ + lua_setfield(L_, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L_, 1); /* remove _LOADED table */ + if (glb) { + lua_pushvalue(L_, -1); /* copy of 'mod' */ + lua_setglobal(L_, modname); /* _G[modname] = module */ } } #endif // LUA_VERSION_NUM @@ -53,60 +51,56 @@ void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int g // ################################################################################################# // ################################################################################################# -void* lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue) +void* lua_newuserdatauv(lua_State* L_, size_t sz, int nuvalue) { - LUA_ASSERT(L, nuvalue <= 1); - return lua_newuserdata(L, sz); + LUA_ASSERT(L_, nuvalue <= 1); + return lua_newuserdata(L_, sz); } // ################################################################################################# // push on stack uservalue #n of full userdata at idx -int lua_getiuservalue(lua_State* L, int idx, int n) +int lua_getiuservalue(lua_State* L_, int idx, int n) { // full userdata can have only 1 uservalue before 5.4 - if (n > 1) - { - lua_pushnil(L); + if (n > 1) { + lua_pushnil(L_); return LUA_TNONE; } - lua_getuservalue(L, idx); + lua_getuservalue(L_, idx); #if LUA_VERSION_NUM == 501 /* default environment is not a nil (see lua_getfenv) */ - lua_getglobal(L, "package"); - if (lua_rawequal(L, -2, -1) || lua_rawequal(L, -2, LUA_GLOBALSINDEX)) - { - lua_pop(L, 2); - lua_pushnil(L); + lua_getglobal(L_, "package"); + if (lua_rawequal(L_, -2, -1) || lua_rawequal(L_, -2, LUA_GLOBALSINDEX)) { + lua_pop(L_, 2); + lua_pushnil(L_); return LUA_TNONE; } - lua_pop(L, 1); /* remove package */ + lua_pop(L_, 1); /* remove package */ #endif - return lua_type(L, -1); + return lua_type(L_, -1); } // ################################################################################################# // Pops a value from the stack and sets it as the new n-th user value associated to the full userdata at the given index. // Returns 0 if the userdata does not have that value. -int lua_setiuservalue(lua_State* L, int idx, int n) +int lua_setiuservalue(lua_State* L_, int idx, int n) { if (n > 1 #if LUA_VERSION_NUM == 501 - || lua_type(L, -1) != LUA_TTABLE + || lua_type(L_, -1) != LUA_TTABLE #endif - ) - { - lua_pop(L, 1); + ) { + lua_pop(L_, 1); return 0; } - lua_setuservalue(L, idx); + lua_setuservalue(L_, idx); return 1; // I guess anything non-0 is ok } #endif // LUA_VERSION_NUM - diff --git a/src/compat.h b/src/compat.h index 037a3ba..a7ad1f3 100644 --- a/src/compat.h +++ b/src/compat.h @@ -36,11 +36,11 @@ extern "C" #define lua_setuservalue lua_setfenv #define lua_getuservalue lua_getfenv #define lua_rawlen lua_objlen -#define luaG_registerlibfuncs(L, _funcs) luaL_register(L, nullptr, _funcs) +#define luaG_registerlibfuncs(L_, _funcs) luaL_register(L_, nullptr, _funcs) #define LUA_OK 0 #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value -void luaL_requiref(lua_State* L, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources -#define lua504_dump(L, writer, data, strip) lua_dump(L, writer, data) +void luaL_requiref(lua_State* L_, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources +#define lua504_dump(L_, writer_, data_, strip_) lua_dump(L_, writer_, data_) #define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1 #endif // LUA_VERSION_NUM == 501 diff --git a/src/deep.cpp b/src/deep.cpp index 5a62000..10f589e 100644 --- a/src/deep.cpp +++ b/src/deep.cpp @@ -66,19 +66,19 @@ static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. * Pops the both values off the stack. */ -static void set_deep_lookup(lua_State* L) +static void set_deep_lookup(lua_State* L_) { - STACK_GROW( L, 3); - STACK_CHECK_START_REL(L, 2); // a b - push_registry_subtable( L, kDeepLookupRegKey); // a b {} - STACK_CHECK( L, 3); - lua_insert( L, -3); // {} a b - lua_pushvalue( L, -1); // {} a b b - lua_pushvalue( L,-3); // {} a b b a - lua_rawset( L, -5); // {} a b - lua_rawset( L, -3); // {} - lua_pop( L, 1); // - STACK_CHECK( L, 0); + STACK_GROW( L_, 3); + STACK_CHECK_START_REL(L_, 2); // a b + push_registry_subtable( L_, kDeepLookupRegKey); // a b {} + STACK_CHECK( L_, 3); + lua_insert( L_, -3); // {} a b + lua_pushvalue( L_, -1); // {} a b b + lua_pushvalue( L_,-3); // {} a b b a + lua_rawset( L_, -5); // {} a b + lua_rawset( L_, -3); // {} + lua_pop( L_, 1); // + STACK_CHECK( L_, 0); } // ################################################################################################# @@ -87,18 +87,18 @@ static void set_deep_lookup(lua_State* L) * Pops the key (metatable or factory) off the stack, and replaces with the * deep lookup value (factory/metatable/nil). */ -static void get_deep_lookup(lua_State* L) +static void get_deep_lookup(lua_State* L_) { - STACK_GROW( L, 1); - STACK_CHECK_START_REL(L, 1); // a - kDeepLookupRegKey.pushValue(L); // a {} - if (!lua_isnil( L, -1)) + STACK_GROW( L_, 1); + STACK_CHECK_START_REL(L_, 1); // a + kDeepLookupRegKey.pushValue(L_); // a {} + if (!lua_isnil( L_, -1)) { - lua_insert( L, -2); // {} a - lua_rawget( L, -2); // {} b + lua_insert( L_, -2); // {} a + lua_rawget( L_, -2); // {} b } - lua_remove( L, -2); // a|b - STACK_CHECK( L, 1); + lua_remove( L_, -2); // a|b + STACK_CHECK( L_, 1); } // ################################################################################################# @@ -107,12 +107,12 @@ static void get_deep_lookup(lua_State* L) * Return the registered factory for 'index' (deep userdata proxy), * or nullptr if 'index' is not a deep userdata proxy. */ -[[nodiscard]] static inline DeepFactory* get_factory(lua_State* L, int index, LookupMode mode_) +[[nodiscard]] static inline DeepFactory* get_factory(lua_State* L_, int index, LookupMode mode_) { // when looking inside a keeper, we are 100% sure the object is a deep userdata if (mode_ == LookupMode::FromKeeper) { - DeepPrelude* const proxy{ *lua_tofulluserdata(L, index) }; + DeepPrelude* const proxy{ *lua_tofulluserdata(L_, index) }; // we can (and must) cast and fetch the internally stored factory return &proxy->m_factory; } @@ -121,31 +121,31 @@ static void get_deep_lookup(lua_State* L) // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database // it is the only way to ensure that the userdata is indeed a deep userdata! // of course, we could just trust the caller, but we won't - STACK_GROW( L, 1); - STACK_CHECK_START_REL(L, 0); + STACK_GROW( L_, 1); + STACK_CHECK_START_REL(L_, 0); - if (!lua_getmetatable( L, index)) // deep ... metatable? + if (!lua_getmetatable( L_, index)) // deep ... metatable? { return nullptr; // no metatable: can't be a deep userdata object! } // replace metatable with the factory pointer, if it is actually a deep userdata - get_deep_lookup( L); // deep ... factory|nil + get_deep_lookup( L_); // deep ... factory|nil - DeepFactory* const ret{ lua_tolightuserdata(L, -1) }; // nullptr if not a userdata - lua_pop( L, 1); - STACK_CHECK( L, 0); + DeepFactory* const ret{ lua_tolightuserdata(L_, -1) }; // nullptr if not a userdata + lua_pop( L_, 1); + STACK_CHECK( L_, 0); return ret; } } // ################################################################################################# -void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_) +void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_) { - STACK_CHECK_START_REL(L, 0); - o_->m_factory.deleteDeepObjectInternal(L, o_); - STACK_CHECK(L, 0); + STACK_CHECK_START_REL(L_, 0); + o_->m_factory.deleteDeepObjectInternal(L_, o_); + STACK_CHECK(L_, 0); } // ################################################################################################# @@ -156,9 +156,9 @@ void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_) * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0. * */ -[[nodiscard]] static int deep_userdata_gc(lua_State* L) +[[nodiscard]] static int deep_userdata_gc(lua_State* L_) { - DeepPrelude* const* const proxy{ lua_tofulluserdata(L, 1) }; + DeepPrelude* const* const proxy{ lua_tofulluserdata(L_, 1) }; DeepPrelude* const p{ *proxy }; // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded @@ -168,14 +168,14 @@ void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_) if (isLastRef) { // retrieve wrapped __gc - lua_pushvalue( L, lua_upvalueindex( 1)); // self __gc? - if (!lua_isnil( L, -1)) + lua_pushvalue( L_, lua_upvalueindex( 1)); // self __gc? + if (!lua_isnil( L_, -1)) { - lua_insert( L, -2); // __gc self - lua_call( L, 1, 0); // + lua_insert( L_, -2); // __gc self + lua_call( L_, 1, 0); // } // we don't really know what remains on the stack at that point (depending on us finding a __gc or not), but we don't care - DeepFactory::DeleteDeepObject(L, p); + DeepFactory::DeleteDeepObject(L_, p); } return 0; } @@ -388,17 +388,17 @@ int DeepFactory::pushDeepUserdata(DestState L, int nuv_) const * Reference count is not changed, and access to the deep userdata is not * serialized. It is the module's responsibility to prevent conflicting usage. */ -DeepPrelude* DeepFactory::toDeep(lua_State* L, int index) const +DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index) const { - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // ensure it is actually a deep userdata we created - if (get_factory(L, index, LookupMode::LaneBody) != this) + if (get_factory(L_, index, LookupMode::LaneBody) != this) { return nullptr; // no metatable, or wrong kind } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); - DeepPrelude** const proxy{ lua_tofulluserdata(L, index) }; + DeepPrelude** const proxy{ lua_tofulluserdata(L_, index) }; return *proxy; } diff --git a/src/keeper.cpp b/src/keeper.cpp index 51f6388..33da736 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp @@ -67,9 +67,9 @@ class keeper_fifo // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception static void operator delete([[maybe_unused]] void* p_, KeeperState L_) { LUA_ASSERT(L_, !"should never be called"); } - [[nodiscard]] static keeper_fifo* getPtr(lua_State* L, int idx_) + [[nodiscard]] static keeper_fifo* getPtr(lua_State* L_, int idx_) { - return lua_tofulluserdata(L, idx_); + return lua_tofulluserdata(L_, idx_); } }; @@ -78,16 +78,16 @@ static constexpr int kContentsTableIndex{ 1 }; // ################################################################################################# // replaces the fifo ud by its uservalue on the stack -[[nodiscard]] static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) +[[nodiscard]] static keeper_fifo* prepare_fifo_access(lua_State* L_, int idx_) { - keeper_fifo* const fifo{ keeper_fifo::getPtr(L, idx_) }; + keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, idx_) }; if (fifo != nullptr) { - idx_ = lua_absindex(L, idx_); - STACK_GROW(L, 1); + idx_ = lua_absindex(L_, idx_); + STACK_GROW(L_, 1); // we can replace the fifo userdata in the stack without fear of it being GCed, there are other references around - lua_getiuservalue(L, idx_, kContentsTableIndex); - lua_replace(L, idx_); + lua_getiuservalue(L_, idx_, kContentsTableIndex); + lua_replace(L_, idx_); } return fifo; } @@ -96,15 +96,15 @@ static constexpr int kContentsTableIndex{ 1 }; // in: nothing // out: { first = 1, count = 0, limit = -1} -[[nodiscard]] static keeper_fifo* fifo_new(KeeperState L) +[[nodiscard]] static keeper_fifo* fifo_new(KeeperState L_) { - STACK_GROW(L, 2); - STACK_CHECK_START_REL(L, 0); - keeper_fifo* const fifo{ new (L) keeper_fifo{} }; - STACK_CHECK(L, 1); - lua_newtable(L); - lua_setiuservalue(L, -2, kContentsTableIndex); - STACK_CHECK(L, 1); + STACK_GROW(L_, 2); + STACK_CHECK_START_REL(L_, 0); + keeper_fifo* const fifo{ new (L_) keeper_fifo{} }; + STACK_CHECK(L_, 1); + lua_newtable(L_); + lua_setiuservalue(L_, -2, kContentsTableIndex); + STACK_CHECK(L_, 1); return fifo; } @@ -112,15 +112,15 @@ static constexpr int kContentsTableIndex{ 1 }; // in: expect fifo ... on top of the stack // out: nothing, removes all pushed values from the stack -static void fifo_push(lua_State* L, keeper_fifo* fifo_, int count_) +static void fifo_push(lua_State* L_, keeper_fifo* fifo_, int count_) { - int const idx{ lua_gettop(L) - count_ }; + int const idx{ lua_gettop(L_) - count_ }; int const start{ fifo_->first + fifo_->count - 1 }; // pop all additional arguments, storing them in the fifo for (int i = count_; i >= 1; --i) { // store in the fifo the value at the top of the stack at the specified index, popping it from the stack - lua_rawseti(L, idx, start + i); + lua_rawseti(L_, idx, start + i); } fifo_->count += count_; } @@ -132,12 +132,12 @@ static void fifo_push(lua_State* L, keeper_fifo* fifo_, int count_) // expects exactly 1 value on the stack! // currently only called with a count of 1, but this may change in the future // function assumes that there is enough data in the fifo to satisfy the request -static void fifo_peek(lua_State* L, keeper_fifo* fifo_, int count_) +static void fifo_peek(lua_State* L_, keeper_fifo* fifo_, int count_) { - STACK_GROW(L, count_); + STACK_GROW(L_, count_); for (int i = 0; i < count_; ++i) { - lua_rawgeti(L, 1, (fifo_->first + i)); + lua_rawgeti(L_, 1, (fifo_->first + i)); } } @@ -145,29 +145,29 @@ static void fifo_peek(lua_State* L, keeper_fifo* fifo_, int count_) // in: fifo // out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) -static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) +static void fifo_pop( lua_State* L_, keeper_fifo* fifo_, int count_) { - LUA_ASSERT(L, lua_istable(L, -1)); - int const fifo_idx{ lua_gettop(L) }; // ... fifotbl + LUA_ASSERT(L_, lua_istable(L_, -1)); + int const fifo_idx{ lua_gettop(L_) }; // ... fifotbl // each iteration pushes a value on the stack! - STACK_GROW(L, count_ + 2); + STACK_GROW(L_, count_ + 2); // skip first item, we will push it last for (int i = 1; i < count_; ++i) { int const at{ fifo_->first + i }; // push item on the stack - lua_rawgeti(L, fifo_idx, at); // ... fifotbl val + lua_rawgeti(L_, fifo_idx, at); // ... fifotbl val // remove item from the fifo - lua_pushnil(L); // ... fifotbl val nil - lua_rawseti(L, fifo_idx, at); // ... fifotbl val + lua_pushnil(L_); // ... fifotbl val nil + lua_rawseti(L_, fifo_idx, at); // ... fifotbl val } // now process first item { int const at{ fifo_->first }; - lua_rawgeti(L, fifo_idx, at); // ... fifotbl vals val - lua_pushnil(L); // ... fifotbl vals val nil - lua_rawseti(L, fifo_idx, at); // ... fifotbl vals val - lua_replace(L, fifo_idx); // ... vals + lua_rawgeti(L_, fifo_idx, at); // ... fifotbl vals val + lua_pushnil(L_); // ... fifotbl vals val nil + lua_rawseti(L_, fifo_idx, at); // ... fifotbl vals val + lua_replace(L_, fifo_idx); // ... vals } // avoid ever-growing indexes by resetting each time we detect the fifo is empty @@ -184,26 +184,26 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) // out: fifos[ud] // xxh64 of string "kFifosRegKey" generated at https://www.pelock.com/products/hash-calculator static constexpr RegistryUniqueKey kFifosRegKey{ 0x37F11CE5A6D191AAull }; -static void push_table(lua_State* L, int idx_) +static void push_table(lua_State* L_, int idx_) { - STACK_GROW(L, 5); - STACK_CHECK_START_REL(L, 0); - idx_ = lua_absindex(L, idx_); - kFifosRegKey.pushValue(L); // ud fifos - lua_pushvalue(L, idx_); // ud fifos ud - lua_rawget(L, -2); // ud fifos fifos[ud] - STACK_CHECK(L, 2); - if (lua_isnil(L, -1)) + STACK_GROW(L_, 5); + STACK_CHECK_START_REL(L_, 0); + idx_ = lua_absindex(L_, idx_); + kFifosRegKey.pushValue(L_); // ud fifos + lua_pushvalue(L_, idx_); // ud fifos ud + lua_rawget(L_, -2); // ud fifos fifos[ud] + STACK_CHECK(L_, 2); + if (lua_isnil(L_, -1)) { - lua_pop(L, 1); // ud fifos + lua_pop(L_, 1); // ud fifos // add a new fifos table for this linda - lua_newtable(L); // ud fifos fifos[ud] - lua_pushvalue(L, idx_); // ud fifos fifos[ud] ud - lua_pushvalue(L, -2); // ud fifos fifos[ud] ud fifos[ud] - lua_rawset(L, -4); // ud fifos fifos[ud] + lua_newtable(L_); // ud fifos fifos[ud] + lua_pushvalue(L_, idx_); // ud fifos fifos[ud] ud + lua_pushvalue(L_, -2); // ud fifos fifos[ud] ud fifos[ud] + lua_rawset(L_, -4); // ud fifos fifos[ud] } - lua_remove(L, -2); // ud fifos[ud] - STACK_CHECK(L, 1); + lua_remove(L_, -2); // ud fifos[ud] + STACK_CHECK(L_, 1); } // ################################################################################################# @@ -263,16 +263,16 @@ int keeper_push_linda_storage(Linda& linda_, DestState L) // ################################################################################################# // in: linda_ud -int keepercall_clear(lua_State* L) +int keepercall_clear(lua_State* L_) { - STACK_GROW(L, 3); - STACK_CHECK_START_REL(L, 0); - kFifosRegKey.pushValue(L); // ud fifos - lua_pushvalue(L, 1); // ud fifos ud - lua_pushnil(L); // ud fifos ud nil - lua_rawset(L, -3); // ud fifos - lua_pop(L, 1); // ud - STACK_CHECK(L, 0); + STACK_GROW(L_, 3); + STACK_CHECK_START_REL(L_, 0); + kFifosRegKey.pushValue(L_); // ud fifos + lua_pushvalue(L_, 1); // ud fifos ud + lua_pushnil(L_); // ud fifos ud nil + lua_rawset(L_, -3); // ud fifos + lua_pop(L_, 1); // ud + STACK_CHECK(L_, 0); return 0; } @@ -280,35 +280,35 @@ int keepercall_clear(lua_State* L) // in: linda_ud, key, ... // out: true|false -int keepercall_send(lua_State* L) +int keepercall_send(lua_State* L_) { - int const n{ lua_gettop(L) - 2 }; - push_table(L, 1); // ud key ... fifos + int const n{ lua_gettop(L_) - 2 }; + push_table(L_, 1); // ud key ... fifos // get the fifo associated to this key in this linda, create it if it doesn't exist - lua_pushvalue(L, 2); // ud key ... fifos key - lua_rawget(L, -2); // ud key ... fifos fifo - if (lua_isnil(L, -1)) + lua_pushvalue(L_, 2); // ud key ... fifos key + lua_rawget(L_, -2); // ud key ... fifos fifo + if (lua_isnil(L_, -1)) { - lua_pop(L, 1); // ud key ... fifos - std::ignore = fifo_new(KeeperState{ L }); // ud key ... fifos fifo - lua_pushvalue(L, 2); // ud key ... fifos fifo key - lua_pushvalue(L, -2); // ud key ... fifos fifo key fifo - lua_rawset(L, -4); // ud key ... fifos fifo - } - lua_remove(L, -2); // ud key ... fifo - keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; + lua_pop(L_, 1); // ud key ... fifos + std::ignore = fifo_new(KeeperState{ L_ }); // ud key ... fifos fifo + lua_pushvalue(L_, 2); // ud key ... fifos fifo key + lua_pushvalue(L_, -2); // ud key ... fifos fifo key fifo + lua_rawset(L_, -4); // ud key ... fifos fifo + } + lua_remove(L_, -2); // ud key ... fifo + keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) }; if (fifo->limit >= 0 && fifo->count + n > fifo->limit) { - lua_settop(L, 0); // - lua_pushboolean(L, 0); // false + lua_settop(L_, 0); // + lua_pushboolean(L_, 0); // false } else { - fifo = prepare_fifo_access(L, -1); // ud fifotbl - lua_replace(L, 2); // ud fifotbl ... - fifo_push(L, fifo, n); // ud fifotbl - lua_settop(L, 0); // - lua_pushboolean(L, 1); // true + fifo = prepare_fifo_access(L_, -1); // ud fifotbl + lua_replace(L_, 2); // ud fifotbl ... + fifo_push(L_, fifo, n); // ud fifotbl + lua_settop(L_, 0); // + lua_pushboolean(L_, 1); // true } return 1; } @@ -317,33 +317,33 @@ int keepercall_send(lua_State* L) // in: linda_ud, key [, key]? // out: (key, val) or nothing -int keepercall_receive(lua_State* L) +int keepercall_receive(lua_State* L_) { - int const top{ lua_gettop(L) }; - push_table(L, 1); // ud keys fifos - lua_replace(L, 1); // fifos keys + int const top{ lua_gettop(L_) }; + push_table(L_, 1); // ud keys fifos + lua_replace(L_, 1); // fifos keys for (int i = 2; i <= top; ++i) { - lua_pushvalue(L, i); // fifos keys key[i] - lua_rawget(L, 1); // fifos keys fifo - keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos keys fifotbl + lua_pushvalue(L_, i); // fifos keys key[i] + lua_rawget(L_, 1); // fifos keys fifo + keeper_fifo* const fifo{ prepare_fifo_access(L_, -1) }; // fifos keys fifotbl if (fifo != nullptr && fifo->count > 0) { - fifo_pop(L, fifo, 1); // fifos keys val - if (!lua_isnil(L, -1)) + fifo_pop(L_, fifo, 1); // fifos keys val + if (!lua_isnil(L_, -1)) { - lua_replace(L, 1); // val keys - lua_settop(L, i); // val keys key[i] + lua_replace(L_, 1); // val keys + lua_settop(L_, i); // val keys key[i] if (i != 2) { - lua_replace(L, 2); // val key keys - lua_settop(L, 2); // val key + lua_replace(L_, 2); // val key keys + lua_settop(L_, 2); // val key } - lua_insert(L, 1); // key, val + lua_insert(L_, 1); // key, val return 2; } } - lua_settop(L, top); // data keys + lua_settop(L_, top); // data keys } // nothing to receive return 0; @@ -352,29 +352,29 @@ int keepercall_receive(lua_State* L) // ################################################################################################# // in: linda_ud key mincount [maxcount] -int keepercall_receive_batched(lua_State* L) +int keepercall_receive_batched(lua_State* L_) { - int const min_count{ static_cast(lua_tointeger(L, 3)) }; + int const min_count{ static_cast(lua_tointeger(L_, 3)) }; if (min_count > 0) { - int const max_count{ static_cast(luaL_optinteger(L, 4, min_count)) }; - lua_settop(L, 2); // ud key - lua_insert(L, 1); // key ud - push_table(L, 2); // key ud fifos - lua_remove(L, 2); // key fifos - lua_pushvalue(L, 1); // key fifos key - lua_rawget(L, 2); // key fifos fifo - lua_remove(L, 2); // key fifo - keeper_fifo* const fifo{ prepare_fifo_access(L, 2) }; // key fifotbl + int const max_count{ static_cast(luaL_optinteger(L_, 4, min_count)) }; + lua_settop(L_, 2); // ud key + lua_insert(L_, 1); // key ud + push_table(L_, 2); // key ud fifos + lua_remove(L_, 2); // key fifos + lua_pushvalue(L_, 1); // key fifos key + lua_rawget(L_, 2); // key fifos fifo + lua_remove(L_, 2); // key fifo + keeper_fifo* const fifo{ prepare_fifo_access(L_, 2) }; // key fifotbl if (fifo != nullptr && fifo->count >= min_count) { - fifo_pop(L, fifo, std::min( max_count, fifo->count)); // key ... + fifo_pop(L_, fifo, std::min( max_count, fifo->count)); // key ... } else { - lua_settop(L, 0); // + lua_settop(L_, 0); // } - return lua_gettop(L); + return lua_gettop(L_); } else { @@ -386,23 +386,23 @@ int keepercall_receive_batched(lua_State* L) // in: linda_ud key n // out: true or nil -int keepercall_limit(lua_State* L) +int keepercall_limit(lua_State* L_) { - int const limit{ static_cast(lua_tointeger(L, 3)) }; - push_table(L, 1); // ud key n fifos - lua_replace(L, 1); // fifos key n - lua_pop(L, 1); // fifos key - lua_pushvalue(L, -1); // fifos key key - lua_rawget(L, -3); // fifos key fifo|nil - keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; + int const limit{ static_cast(lua_tointeger(L_, 3)) }; + push_table(L_, 1); // ud key n fifos + lua_replace(L_, 1); // fifos key n + lua_pop(L_, 1); // fifos key + lua_pushvalue(L_, -1); // fifos key key + lua_rawget(L_, -3); // fifos key fifo|nil + keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) }; if (fifo == nullptr) { // fifos key nil - lua_pop(L, 1); // fifos key - fifo = fifo_new(KeeperState{ L }); // fifos key fifo - lua_rawset(L, -3); // fifos + lua_pop(L_, 1); // fifos key + fifo = fifo_new(KeeperState{ L_ }); // fifos key fifo + lua_rawset(L_, -3); // fifos } // remove any clutter on the stack - lua_settop(L, 0); + lua_settop(L_, 0); // return true if we decide that blocked threads waiting to write on that key should be awakened // this is the case if we detect the key was full but it is no longer the case if ( @@ -410,49 +410,49 @@ int keepercall_limit(lua_State* L) && ((limit < 0) || (fifo->count < limit)) // the key is not full if unlimited or count is lower than the new limit ) { - lua_pushboolean(L, 1); // true + lua_pushboolean(L_, 1); // true } // set the new limit fifo->limit = limit; // return 0 or 1 value - return lua_gettop(L); + return lua_gettop(L_); } // ################################################################################################# // in: linda_ud key [[val] ...] //out: true if the linda was full but it's no longer the case, else nothing -int keepercall_set(lua_State* L) +int keepercall_set(lua_State* L_) { bool should_wake_writers{ false }; - STACK_GROW(L, 6); + STACK_GROW(L_, 6); // retrieve fifos associated with the linda - push_table(L, 1); // ud key [val [, ...]] fifos - lua_replace(L, 1); // fifos key [val [, ...]] + push_table(L_, 1); // ud key [val [, ...]] fifos + lua_replace(L_, 1); // fifos key [val [, ...]] // make sure we have a value on the stack - if (lua_gettop(L) == 2) // fifos key + if (lua_gettop(L_) == 2) // fifos key { - lua_pushvalue(L, -1); // fifos key key - lua_rawget(L, 1); // fifos key fifo|nil + lua_pushvalue(L_, -1); // fifos key key + lua_rawget(L_, 1); // fifos key fifo|nil // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! - keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; + keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) }; if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil { // fifos key fifo if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it { - lua_pop(L, 1); // fifos key - lua_pushnil(L); // fifos key nil - lua_rawset(L, -3); // fifos + lua_pop(L_, 1); // fifos key + lua_pushnil(L_); // fifos key nil + lua_rawset(L_, -3); // fifos } else { // we create room if the fifo was full but it is no longer the case should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit); - lua_remove(L, -2); // fifos fifo - lua_newtable(L); // fifos fifo {} - lua_setiuservalue(L, -2, kContentsTableIndex); // fifos fifo + lua_remove(L_, -2); // fifos fifo + lua_newtable(L_); // fifos fifo {} + lua_setiuservalue(L_, -2, kContentsTableIndex); // fifos fifo fifo->first = 1; fifo->count = 0; } @@ -460,59 +460,59 @@ int keepercall_set(lua_State* L) } else // set/replace contents stored at the specified key? { - int const count{ lua_gettop(L) - 2 }; // number of items we want to store - lua_pushvalue(L, 2); // fifos key [val [, ...]] key - lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil - keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; + int const count{ lua_gettop(L_) - 2 }; // number of items we want to store + lua_pushvalue(L_, 2); // fifos key [val [, ...]] key + lua_rawget(L_, 1); // fifos key [val [, ...]] fifo|nil + keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) }; if (fifo == nullptr) // can be nullptr if we store a value at a new key { // fifos key [val [, ...]] nil // no need to wake writers in that case, because a writer can't wait on an inexistent key - lua_pop(L, 1); // fifos key [val [, ...]] - std::ignore = fifo_new(KeeperState{ L }); // fifos key [val [, ...]] fifo - lua_pushvalue(L, 2); // fifos key [val [, ...]] fifo key - lua_pushvalue(L, -2); // fifos key [val [, ...]] fifo key fifo - lua_rawset(L, 1); // fifos key [val [, ...]] fifo + lua_pop(L_, 1); // fifos key [val [, ...]] + std::ignore = fifo_new(KeeperState{ L_ }); // fifos key [val [, ...]] fifo + lua_pushvalue(L_, 2); // fifos key [val [, ...]] fifo key + lua_pushvalue(L_, -2); // fifos key [val [, ...]] fifo key fifo + lua_rawset(L_, 1); // fifos key [val [, ...]] fifo } else // the fifo exists, we just want to update its contents { // fifos key [val [, ...]] fifo // we create room if the fifo was full but it is no longer the case should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit); // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! - lua_newtable(L); // fifos key [val [, ...]] fifo {} - lua_setiuservalue(L, -2, kContentsTableIndex); // fifos key [val [, ...]] fifo + lua_newtable(L_); // fifos key [val [, ...]] fifo {} + lua_setiuservalue(L_, -2, kContentsTableIndex); // fifos key [val [, ...]] fifo fifo->first = 1; fifo->count = 0; } - fifo = prepare_fifo_access(L, -1); // fifos key [val [, ...]] fifotbl + fifo = prepare_fifo_access(L_, -1); // fifos key [val [, ...]] fifotbl // move the fifo below the values we want to store - lua_insert(L, 3); // fifos key fifotbl [val [, ...]] - fifo_push(L, fifo, count); // fifos key fifotbl + lua_insert(L_, 3); // fifos key fifotbl [val [, ...]] + fifo_push(L_, fifo, count); // fifos key fifotbl } - return should_wake_writers ? (lua_pushboolean(L, 1), 1) : 0; + return should_wake_writers ? (lua_pushboolean(L_, 1), 1) : 0; } // ################################################################################################# // in: linda_ud key [count] // out: at most values -int keepercall_get(lua_State* L) +int keepercall_get(lua_State* L_) { int count{ 1 }; - if (lua_gettop(L) == 3) // ud key count + if (lua_gettop(L_) == 3) // ud key count { - count = static_cast(lua_tointeger(L, 3)); - lua_pop(L, 1); // ud key + count = static_cast(lua_tointeger(L_, 3)); + lua_pop(L_, 1); // ud key } - push_table(L, 1); // ud key fifos - lua_replace(L, 1); // fifos key - lua_rawget(L, 1); // fifos fifo - keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos fifotbl + push_table(L_, 1); // ud key fifos + lua_replace(L_, 1); // fifos key + lua_rawget(L_, 1); // fifos fifo + keeper_fifo* const fifo{ prepare_fifo_access(L_, -1) }; // fifos fifotbl if (fifo != nullptr && fifo->count > 0) { - lua_remove(L, 1); // fifotbl + lua_remove(L_, 1); // fifotbl count = std::min(count, fifo->count); // read value off the fifo - fifo_peek(L, fifo, count); // fifotbl ... + fifo_peek(L_, fifo, count); // fifotbl ... return count; } // no fifo was ever registered for this key, or it is empty @@ -522,69 +522,69 @@ int keepercall_get(lua_State* L) // ################################################################################################# // in: linda_ud [, key [, ...]] -int keepercall_count(lua_State* L) +int keepercall_count(lua_State* L_) { - push_table(L, 1); // ud keys fifos - switch (lua_gettop(L)) + push_table(L_, 1); // ud keys fifos + switch (lua_gettop(L_)) { // no key is specified: return a table giving the count of all known keys case 2: // ud fifos - lua_newtable(L); // ud fifos out - lua_replace(L, 1); // out fifos - lua_pushnil(L); // out fifos nil - while (lua_next(L, 2)) // out fifos key fifo + lua_newtable(L_); // ud fifos out + lua_replace(L_, 1); // out fifos + lua_pushnil(L_); // out fifos nil + while (lua_next(L_, 2)) // out fifos key fifo { - keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; - lua_pop(L, 1); // out fifos key - lua_pushvalue(L, -1); // out fifos key key - lua_pushinteger(L, fifo->count); // out fifos key key count - lua_rawset(L, -5); // out fifos key + keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) }; + lua_pop(L_, 1); // out fifos key + lua_pushvalue(L_, -1); // out fifos key key + lua_pushinteger(L_, fifo->count); // out fifos key key count + lua_rawset(L_, -5); // out fifos key } - lua_pop(L, 1); // out + lua_pop(L_, 1); // out break; // 1 key is specified: return its count case 3: // ud key fifos - lua_replace(L, 1); // fifos key - lua_rawget(L, -2); // fifos fifo|nil - if (lua_isnil(L, -1)) // the key is unknown + lua_replace(L_, 1); // fifos key + lua_rawget(L_, -2); // fifos fifo|nil + if (lua_isnil(L_, -1)) // the key is unknown { // fifos nil - lua_remove(L, -2); // nil + lua_remove(L_, -2); // nil } else // the key is known { // fifos fifo - keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; - lua_pushinteger(L, fifo->count); // fifos fifo count - lua_replace(L, -3); // count fifo - lua_pop(L, 1); // count + keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) }; + lua_pushinteger(L_, fifo->count); // fifos fifo count + lua_replace(L_, -3); // count fifo + lua_pop(L_, 1); // count } break; // a variable number of keys is specified: return a table of their counts default: // ud keys fifos - lua_newtable(L); // ud keys... fifos out - lua_replace(L, 1); // out keys... fifos + lua_newtable(L_); // ud keys... fifos out + lua_replace(L_, 1); // out keys... fifos // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable - lua_insert(L, 2); // out fifos keys... - while (lua_gettop(L) > 2) + lua_insert(L_, 2); // out fifos keys... + while (lua_gettop(L_) > 2) { - lua_pushvalue(L, -1); // out fifos keys... key - lua_rawget(L, 2); // out fifos keys... fifo|nil - keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; - lua_pop(L, 1); // out fifos keys... + lua_pushvalue(L_, -1); // out fifos keys... key + lua_rawget(L_, 2); // out fifos keys... fifo|nil + keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) }; + lua_pop(L_, 1); // out fifos keys... if (fifo != nullptr) // the key is known { - lua_pushinteger(L, fifo->count); // out fifos keys... count - lua_rawset(L, 1); // out fifos keys... + lua_pushinteger(L_, fifo->count); // out fifos keys... count + lua_rawset(L_, 1); // out fifos keys... } else // the key is unknown { - lua_pop(L, 1); // out fifos keys... + lua_pop(L_, 1); // out fifos keys... } } // all keys are exhausted // out fifos - lua_pop(L, 1); // out + lua_pop(L_, 1); // out } - LUA_ASSERT(L, lua_gettop(L) == 1); + LUA_ASSERT(L_, lua_gettop(L_) == 1); return 1; } @@ -651,23 +651,23 @@ void close_keepers(Universe* U) * function never fails. * settings table is expected at position 1 on the stack */ -void init_keepers(Universe* U, lua_State* L) +void init_keepers(Universe* U, lua_State* L_) { - LUA_ASSERT(L, lua_gettop(L) == 1 && lua_istable(L, 1)); - STACK_CHECK_START_REL(L, 0); // L K - lua_getfield(L, 1, "nb_keepers"); // settings nb_keepers - int const nb_keepers{ static_cast(lua_tointeger(L, -1)) }; - lua_pop(L, 1); // settings + LUA_ASSERT(L_, lua_gettop(L_) == 1 && lua_istable(L_, 1)); + STACK_CHECK_START_REL(L_, 0); // L_ K + lua_getfield(L_, 1, "nb_keepers"); // settings nb_keepers + int const nb_keepers{ static_cast(lua_tointeger(L_, -1)) }; + lua_pop(L_, 1); // settings if (nb_keepers < 1) { - raise_luaL_error(L, "Bad number of keepers (%d)", nb_keepers); + raise_luaL_error(L_, "Bad number of keepers (%d)", nb_keepers); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); - lua_getfield(L, 1, "keepers_gc_threshold"); // settings keepers_gc_threshold - int const keepers_gc_threshold{ static_cast(lua_tointeger(L, -1)) }; - lua_pop(L, 1); // settings - STACK_CHECK(L, 0); + lua_getfield(L_, 1, "keepers_gc_threshold"); // settings keepers_gc_threshold + int const keepers_gc_threshold{ static_cast(lua_tointeger(L_, -1)) }; + lua_pop(L_, 1); // settings + STACK_CHECK(L_, 0); // Keepers contains an array of 1 Keeper, adjust for the actual number of keeper states { @@ -675,7 +675,7 @@ void init_keepers(Universe* U, lua_State* L) U->keepers = static_cast(U->internal_allocator.alloc(bytes)); if (U->keepers == nullptr) { - raise_luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); + raise_luaL_error(L_, "init_keepers() failed while creating keeper array; out of memory"); } U->keepers->Keepers::Keepers(); U->keepers->gc_threshold = keepers_gc_threshold; @@ -689,10 +689,10 @@ void init_keepers(Universe* U, lua_State* L) for (int i = 0; i < nb_keepers; ++i) // settings { // note that we will leak K if we raise an error later - KeeperState const K{ create_state(U, L) }; + KeeperState const K{ create_state(U, L_) }; if (K == nullptr) { - raise_luaL_error(L, "init_keepers() failed while creating keeper states; out of memory"); + raise_luaL_error(L_, "init_keepers() failed while creating keeper states; out of memory"); } U->keepers->keeper_array[i].L = K; @@ -717,35 +717,35 @@ void init_keepers(Universe* U, lua_State* L) STACK_CHECK(K, 0); // copy package.path and package.cpath from the source state (TODO: use _R._LOADED.package instead of _G.package) - lua_getglobal(L, "package"); // settings package - if (!lua_isnil(L, -1)) + lua_getglobal(L_, "package"); // settings package + if (!lua_isnil(L_, -1)) { // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately - InterCopyContext c{ U, DestState{ K }, SourceState{ L }, {}, SourceIndex{ lua_absindex(L, -1) }, {}, LookupMode::ToKeeper, {} }; + InterCopyContext c{ U, DestState{ K }, SourceState{ L_ }, {}, SourceIndex{ lua_absindex(L_, -1) }, {}, LookupMode::ToKeeper, {} }; if (c.inter_copy_package() != InterCopyResult::Success) { // if something went wrong, the error message is at the top of the stack - lua_remove(L, -2); // settings error_msg - raise_lua_error(L); + lua_remove(L_, -2); // settings error_msg + raise_lua_error(L_); } } - lua_pop(L, 1); // settings - STACK_CHECK(L, 0); + lua_pop(L_, 1); // settings + STACK_CHECK(L_, 0); STACK_CHECK(K, 0); // attempt to call on_state_create(), if we have one and it is a C function // (only support a C function because we can't transfer executable Lua code in keepers) - // will raise an error in L in case of problem - call_on_state_create(U, K, L, LookupMode::ToKeeper); + // will raise an error in L_ in case of problem + call_on_state_create(U, K, L_, LookupMode::ToKeeper); // to see VM name in Decoda debugger lua_pushfstring(K, "Keeper #%d", i + 1); // "Keeper #n" lua_setglobal(K, "decoda_name"); // // create the fifos table in the keeper state - kFifosRegKey.setValue(K, [](lua_State* L) { lua_newtable(L); }); + kFifosRegKey.setValue(K, [](lua_State* L_) { lua_newtable(L_); }); STACK_CHECK(K, 0); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); } // ################################################################################################# @@ -776,25 +776,25 @@ void Linda::releaseKeeper(Keeper* K_) const // ################################################################################################# -void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_) +void keeper_toggle_nil_sentinels(lua_State* L_, int val_i_, LookupMode const mode_) { - int const n{ lua_gettop(L) }; + int const n{ lua_gettop(L_) }; for (int i = val_i_; i <= n; ++i) { if (mode_ == LookupMode::ToKeeper) { - if (lua_isnil(L, i)) + if (lua_isnil(L_, i)) { - kNilSentinel.pushKey(L); - lua_replace(L, i); + kNilSentinel.pushKey(L_); + lua_replace(L_, i); } } else { - if (kNilSentinel.equals(L, i)) + if (kNilSentinel.equals(L_, i)) { - lua_pushnil(L); - lua_replace(L, i); + lua_pushnil(L_); + lua_replace(L_, i); } } } @@ -811,20 +811,20 @@ void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode * * Returns: number of return values (pushed to 'L'), unset in case of error */ -KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua_State* L, void* linda, int starting_index) +KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua_State* L_, void* linda, int starting_index) { KeeperCallResult result; - int const args{ starting_index ? (lua_gettop(L) - starting_index + 1) : 0 }; + int const args{ starting_index ? (lua_gettop(L_) - starting_index + 1) : 0 }; int const top_K{ lua_gettop(K) }; // if we didn't do anything wrong, the keeper stack should be clean - LUA_ASSERT(L, lua_gettop(K) == 0); + LUA_ASSERT(L_, lua_gettop(K) == 0); STACK_GROW(K, 2); PUSH_KEEPER_FUNC(K, func_); // func_ lua_pushlightuserdata(K, linda); // func_ linda if ( (args == 0) || - (InterCopyContext{ U, DestState{ K }, SourceState{ L }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(args) == InterCopyResult::Success) + (InterCopyContext{ U, DestState{ K }, SourceState{ L_ }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(args) == InterCopyResult::Success) ) { // func_ linda args... lua_call(K, 1 + args, LUA_MULTRET); // result... @@ -835,8 +835,8 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) if ( (retvals == 0) || - (InterCopyContext{ U, DestState{ L }, SourceState{ K }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success) - ) // K->L + (InterCopyContext{ U, DestState{ L_ }, SourceState{ K }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success) + ) // K->L_ { result.emplace(retvals); } @@ -862,7 +862,7 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua int const gc_usage_after{ lua_gc(K, LUA_GCCOUNT, 0) }; if (gc_usage_after > gc_threshold) [[unlikely]] { - raise_luaL_error(L, "Keeper GC threshold is too low, need at least %d", gc_usage_after); + raise_luaL_error(L_, "Keeper GC threshold is too low, need at least %d", gc_usage_after); } } } diff --git a/src/keeper.h b/src/keeper.h index 6688fe0..3740fc5 100644 --- a/src/keeper.h +++ b/src/keeper.h @@ -39,24 +39,24 @@ struct Keepers // xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; -void init_keepers(Universe* U, lua_State* L); +void init_keepers(Universe* U, lua_State* L_); void close_keepers(Universe* U); -void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); +void keeper_toggle_nil_sentinels(lua_State* L_, int val_i_, LookupMode const mode_); [[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L); using keeper_api_t = lua_CFunction; #define KEEPER_API(_op) keepercall_##_op #define PUSH_KEEPER_FUNC lua_pushcfunction // lua_Cfunctions to run inside a keeper state -[[nodiscard]] int keepercall_clear(lua_State* L); -[[nodiscard]] int keepercall_send(lua_State* L); -[[nodiscard]] int keepercall_receive(lua_State* L); -[[nodiscard]] int keepercall_receive_batched(lua_State* L); -[[nodiscard]] int keepercall_limit(lua_State* L); -[[nodiscard]] int keepercall_get(lua_State* L); -[[nodiscard]] int keepercall_set(lua_State* L); -[[nodiscard]] int keepercall_count(lua_State* L); +[[nodiscard]] int keepercall_clear(lua_State* L_); +[[nodiscard]] int keepercall_send(lua_State* L_); +[[nodiscard]] int keepercall_receive(lua_State* L_); +[[nodiscard]] int keepercall_receive_batched(lua_State* L_); +[[nodiscard]] int keepercall_limit(lua_State* L_); +[[nodiscard]] int keepercall_get(lua_State* L_); +[[nodiscard]] int keepercall_set(lua_State* L_); +[[nodiscard]] int keepercall_count(lua_State* L_); using KeeperCallResult = Unique>; -[[nodiscard]] KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t _func, lua_State* L, void* linda, int starting_index); +[[nodiscard]] KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t _func, lua_State* L_, void* linda, int starting_index); diff --git a/src/lanes.cpp b/src/lanes.cpp index e150eea..d87d93e 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -202,22 +202,22 @@ void Lane::startThread(int priority_) #define ERROR_FULL_STACK 1 // must be either 0 or 1 as we do some index arithmetics with it! // intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed -static void securize_debug_threadname(lua_State* L, Lane* lane_) +static void securize_debug_threadname(lua_State* L_, Lane* lane_) { - STACK_CHECK_START_REL(L, 0); - STACK_GROW(L, 3); - lua_getiuservalue(L, 1, 1); - lua_newtable(L); + STACK_CHECK_START_REL(L_, 0); + STACK_GROW(L_, 3); + lua_getiuservalue(L_, 1, 1); + lua_newtable(L_); // Lua 5.1 can't do 'lane_->debug_name = lua_pushstring(L, lane_->debug_name);' - lua_pushstring(L, lane_->debug_name); - lane_->debug_name = lua_tostring(L, -1); - lua_rawset(L, -3); - lua_pop(L, 1); - STACK_CHECK(L, 0); + lua_pushstring(L_, lane_->debug_name); + lane_->debug_name = lua_tostring(L_, -1); + lua_rawset(L_, -3); + lua_pop(L_, 1); + STACK_CHECK(L_, 0); } #if ERROR_FULL_STACK -[[nodiscard]] static int lane_error(lua_State* L); +[[nodiscard]] static int lane_error(lua_State* L_); // xxh64 of string "kStackTraceRegKey" generated at https://www.pelock.com/products/hash-calculator static constexpr RegistryUniqueKey kStackTraceRegKey{ 0x3F327747CACAA904ull }; #endif // ERROR_FULL_STACK @@ -255,20 +255,20 @@ Lane::~Lane() // Push the finalizers table on the stack. // If there is no existing table, create ti. -static void push_finalizers_table(lua_State* L) +static void push_finalizers_table(lua_State* L_) { - STACK_GROW(L, 3); - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 3); + STACK_CHECK_START_REL(L_, 0); - kFinalizerRegKey.pushValue(L); // ? - if (lua_isnil(L, -1)) // nil? + kFinalizerRegKey.pushValue(L_); // ? + if (lua_isnil(L_, -1)) // nil? { - lua_pop(L, 1); // + lua_pop(L_, 1); // // store a newly created table in the registry, but leave it on the stack too - lua_newtable(L); // t - kFinalizerRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // t + lua_newtable(L_); // t + kFinalizerRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // t } - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); } // ################################################################################################# @@ -283,21 +283,21 @@ static void push_finalizers_table(lua_State* L) // LUAG_FUNC(set_finalizer) { - luaL_argcheck(L, lua_isfunction(L, 1), 1, "finalizer should be a function"); - luaL_argcheck(L, lua_gettop( L) == 1, 1, "too many arguments"); + luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function"); + luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments"); // Get the current finalizer table (if any), create one if it doesn't exist - push_finalizers_table(L); // finalizer {finalisers} - STACK_GROW(L, 2); - lua_pushinteger(L, lua_rawlen(L, -1) + 1); // finalizer {finalisers} idx - lua_pushvalue(L, 1); // finalizer {finalisers} idx finalizer - lua_rawset(L, -3); // finalizer {finalisers} - lua_pop(L, 2); // + push_finalizers_table(L_); // finalizer {finalisers} + STACK_GROW(L_, 2); + lua_pushinteger(L_, lua_rawlen(L_, -1) + 1); // finalizer {finalisers} idx + lua_pushvalue(L_, 1); // finalizer {finalisers} idx finalizer + lua_rawset(L_, -3); // finalizer {finalisers} + lua_pop(L_, 2); return 0; } // ################################################################################################# -static void push_stack_trace(lua_State* L, int rc_, int stk_base_) +static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) { // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry switch(rc_) @@ -308,16 +308,16 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_) case LUA_ERRRUN: // cancellation or a runtime error #if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler { - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // fetch the call stack table from the registry where the handler stored it - STACK_GROW(L, 1); + STACK_GROW(L_, 1); // yields nil if no stack was generated (in case of cancellation for example) - kStackTraceRegKey.pushValue(L); // err trace|nil - STACK_CHECK(L, 1); + kStackTraceRegKey.pushValue(L_); // err trace|nil + STACK_CHECK(L_, 1); // For cancellation the error message is kCancelError, and a stack trace isn't placed // For other errors, the message can be whatever was thrown, and we should have a stack trace table - LUA_ASSERT(L, lua_type(L, 1 + stk_base_) == (kCancelError.equals(L, stk_base_) ? LUA_TNIL : LUA_TTABLE)); + LUA_ASSERT(L_, lua_type(L_, 1 + stk_base_) == (kCancelError.equals(L_, stk_base_) ? LUA_TNIL : LUA_TTABLE)); // Just leaving the stack trace table on the stack is enough to get it through to the master. break; } @@ -327,7 +327,7 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_) case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) default: // we should have a single value which is either a string (the error message) or kCancelError - LUA_ASSERT(L, (lua_gettop(L) == stk_base_) && ((lua_type(L, stk_base_) == LUA_TSTRING) || kCancelError.equals(L, stk_base_))); + LUA_ASSERT(L_, (lua_gettop(L_) == stk_base_) && ((lua_type(L_, stk_base_) == LUA_TSTRING) || kCancelError.equals(L_, stk_base_))); break; } } @@ -347,45 +347,45 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_) // TBD: should we add stack trace on failing finalizer, wouldn't be hard.. // -[[nodiscard]] static int run_finalizers(lua_State* L, int lua_rc_) +[[nodiscard]] static int run_finalizers(lua_State* L_, int lua_rc_) { - kFinalizerRegKey.pushValue(L); // ... finalizers? - if (lua_isnil(L, -1)) + kFinalizerRegKey.pushValue(L_); // ... finalizers? + if (lua_isnil(L_, -1)) { - lua_pop(L, 1); + lua_pop(L_, 1); return 0; // no finalizers } - STACK_GROW(L, 5); + STACK_GROW(L_, 5); - int const finalizers_index{ lua_gettop(L) }; - int const err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L, lane_error), lua_gettop(L)) : 0 }; + int const finalizers_index{ lua_gettop(L_) }; + int const err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 }; int rc{ LUA_OK }; - for (int n = static_cast(lua_rawlen(L, finalizers_index)); n > 0; --n) + for (int n = static_cast(lua_rawlen(L_, finalizers_index)); n > 0; --n) { int args = 0; - lua_pushinteger(L, n); // ... finalizers lane_error n - lua_rawget(L, finalizers_index); // ... finalizers lane_error finalizer - LUA_ASSERT(L, lua_isfunction(L, -1)); + lua_pushinteger(L_, n); // ... finalizers lane_error n + lua_rawget(L_, finalizers_index); // ... finalizers lane_error finalizer + LUA_ASSERT(L_, lua_isfunction(L_, -1)); if (lua_rc_ != LUA_OK) // we have an error message and an optional stack trace at the bottom of the stack { - LUA_ASSERT(L, finalizers_index == 2 || finalizers_index == 3); + LUA_ASSERT(L_, finalizers_index == 2 || finalizers_index == 3); //char const* err_msg = lua_tostring(L, 1); - lua_pushvalue(L, 1); // ... finalizers lane_error finalizer err_msg + lua_pushvalue(L_, 1); // ... finalizers lane_error finalizer err_msg // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM if (finalizers_index == 3) { - lua_pushvalue(L, 2); // ... finalizers lane_error finalizer err_msg stack_trace + lua_pushvalue(L_, 2); // ... finalizers lane_error finalizer err_msg stack_trace } args = finalizers_index - 1; } // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace - rc = lua_pcall(L, args, 0, err_handler_index); // ... finalizers lane_error err_msg2? + rc = lua_pcall(L_, args, 0, err_handler_index); // ... finalizers lane_error err_msg2? if (rc != LUA_OK) { - push_stack_trace(L, rc, lua_gettop(L)); + push_stack_trace(L_, rc, lua_gettop(L_)); // If one finalizer fails, don't run the others. Return this // as the 'real' error, replacing what we could have had (or not) // from the actual code. @@ -397,18 +397,18 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_) if (rc != LUA_OK) { // ERROR_FULL_STACK accounts for the presence of lane_error on the stack - int const nb_err_slots{ lua_gettop(L) - finalizers_index - ERROR_FULL_STACK }; + int const nb_err_slots{ lua_gettop(L_) - finalizers_index - ERROR_FULL_STACK }; // a finalizer generated an error, this is what we leave of the stack for (int n = nb_err_slots; n > 0; --n) { - lua_replace(L, n); + lua_replace(L_, n); } // leave on the stack only the error and optional stack trace produced by the error in the finalizer - lua_settop(L, nb_err_slots); + lua_settop(L_, nb_err_slots); } else // no error from the finalizers, make sure only the original return values from the lane body remain on the stack { - lua_settop(L, finalizers_index - 1); + lua_settop(L_, finalizers_index - 1); } return rc; @@ -481,11 +481,11 @@ static void selfdestruct_add(Lane* lane_) /* * Process end; cancel any still free-running threads */ -[[nodiscard]] static int universe_gc(lua_State* L) +[[nodiscard]] static int universe_gc(lua_State* L_) { - Universe* const U{ lua_tofulluserdata(L, 1) }; - lua_Duration const shutdown_timeout{ lua_tonumber(L, lua_upvalueindex(1)) }; - [[maybe_unused]] char const* const op_string{ lua_tostring(L, lua_upvalueindex(2)) }; + Universe* const U{ lua_tofulluserdata(L_, 1) }; + lua_Duration const shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; + [[maybe_unused]] char const* const op_string{ lua_tostring(L_, lua_upvalueindex(2)) }; CancelOp const op{ which_cancel_op(op_string) }; if (U->selfdestruct_first != SELFDESTRUCT_END) @@ -556,7 +556,7 @@ static void selfdestruct_add(Lane* lane_) if (lane != SELFDESTRUCT_END) { // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) - raise_luaL_error(L, "Zombie thread %s refuses to die!", lane->debug_name); + raise_luaL_error(L_, "Zombie thread %s refuses to die!", lane->debug_name); } } @@ -564,22 +564,22 @@ static void selfdestruct_add(Lane* lane_) if (U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer { [[maybe_unused]] int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) }; - LUA_ASSERT(L, prev_ref_count == 1); // this should be the last reference - DeepFactory::DeleteDeepObject(L, U->timer_deep); + LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference + DeepFactory::DeleteDeepObject(L_, U->timer_deep); U->timer_deep = nullptr; } close_keepers(U); // remove the protected allocator, if any - U->protected_allocator.removeFrom(L); + U->protected_allocator.removeFrom(L_); U->Universe::~Universe(); // universe is no longer available (nor necessary) // we need to do this in case some deep userdata objects were created before Lanes was initialized, // as potentially they will be garbage collected after Lanes at application shutdown - universe_store(L, nullptr); + universe_store(L_, nullptr); return 0; } @@ -593,23 +593,22 @@ static void selfdestruct_add(Lane* lane_) // LUAG_FUNC( set_singlethreaded) { - lua_Integer cores = luaL_optinteger(L, 1, 1); - (void) cores; // prevent "unused" warning + [[maybe_unused]] lua_Integer const cores{ luaL_optinteger(L_, 1, 1) }; #ifdef PLATFORM_OSX #ifdef _UTILBINDTHREADTOCPU if (cores > 1) { - raise_luaL_error(L, "Limiting to N>1 cores not possible"); + raise_luaL_error(L_, "Limiting to N>1 cores not possible"); } // requires 'chudInitialize()' utilBindThreadToCPU(0); // # of CPU to run on (we cannot limit to 2..N CPUs?) return 0; #else - raise_luaL_error(L, "Not available: compile with _UTILBINDTHREADTOCPU"); + raise_luaL_error(L_, "Not available: compile with _UTILBINDTHREADTOCPU"); #endif #else - raise_luaL_error(L, "not implemented"); + raise_luaL_error(L_, "not implemented"); #endif } @@ -638,35 +637,35 @@ static constexpr RegistryUniqueKey kExtendedStackTraceRegKey{ 0x38147AD48FB426E2 LUAG_FUNC( set_error_reporting) { - luaL_checktype(L, 1, LUA_TSTRING); - char const* mode{ lua_tostring(L, 1) }; - lua_pushliteral(L, "extended"); + luaL_checktype(L_, 1, LUA_TSTRING); + char const* mode{ lua_tostring(L_, 1) }; + lua_pushliteral(L_, "extended"); bool const extended{ strcmp(mode, "extended") == 0 }; bool const basic{ strcmp(mode, "basic") == 0 }; if (!extended && !basic) { - raise_luaL_error(L, "unsupported error reporting model %s", mode); + raise_luaL_error(L_, "unsupported error reporting model %s", mode); } - kExtendedStackTraceRegKey.setValue(L, [extended](lua_State* L) { lua_pushboolean(L, extended ? 1 : 0); }); + kExtendedStackTraceRegKey.setValue(L_, [extended](lua_State* L_) { lua_pushboolean(L_, extended ? 1 : 0); }); return 0; } -[[nodiscard]] static int lane_error(lua_State* L) +[[nodiscard]] static int lane_error(lua_State* L_) { // error message (any type) - STACK_CHECK_START_ABS(L, 1); // some_error + STACK_CHECK_START_ABS(L_, 1); // some_error // Don't do stack survey for cancelled lanes. // - if (kCancelError.equals(L, 1)) + if (kCancelError.equals(L_, 1)) { return 1; // just pass on } - STACK_GROW(L, 3); - bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L) }; - STACK_CHECK(L, 1); + STACK_GROW(L_, 3); + bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L_) }; + STACK_CHECK(L_, 1); // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()' // caller to fetch. This bypasses the Lua 5.1 limitation of only one @@ -678,50 +677,50 @@ LUAG_FUNC( set_error_reporting) // // table of { "sourcefile.lua:", ... } // - lua_newtable(L); // some_error {} + lua_newtable(L_); // some_error {} // Best to start from level 1, but in some cases it might be a C function // and we don't get '.currentline' for that. It's okay - just keep level // and table index growing separate. --AKa 22-Jan-2009 // lua_Debug ar; - for (int n = 1; lua_getstack(L, n, &ar); ++n) + for (int n = 1; lua_getstack(L_, n, &ar); ++n) { - lua_getinfo(L, extended ? "Sln" : "Sl", &ar); + lua_getinfo(L_, extended ? "Sln" : "Sl", &ar); if (extended) { - lua_newtable(L); // some_error {} {} + lua_newtable(L_); // some_error {} {} - lua_pushstring(L, ar.source); // some_error {} {} source - lua_setfield(L, -2, "source"); // some_error {} {} + lua_pushstring(L_, ar.source); // some_error {} {} source + lua_setfield(L_, -2, "source"); // some_error {} {} - lua_pushinteger(L, ar.currentline); // some_error {} {} currentline - lua_setfield(L, -2, "currentline"); // some_error {} {} + lua_pushinteger(L_, ar.currentline); // some_error {} {} currentline + lua_setfield(L_, -2, "currentline"); // some_error {} {} - lua_pushstring(L, ar.name); // some_error {} {} name - lua_setfield(L, -2, "name"); // some_error {} {} + lua_pushstring(L_, ar.name); // some_error {} {} name + lua_setfield(L_, -2, "name"); // some_error {} {} - lua_pushstring(L, ar.namewhat); // some_error {} {} namewhat - lua_setfield(L, -2, "namewhat"); // some_error {} {} + lua_pushstring(L_, ar.namewhat); // some_error {} {} namewhat + lua_setfield(L_, -2, "namewhat"); // some_error {} {} - lua_pushstring(L, ar.what); // some_error {} {} what - lua_setfield(L, -2, "what"); // some_error {} {} + lua_pushstring(L_, ar.what); // some_error {} {} what + lua_setfield(L_, -2, "what"); // some_error {} {} } else if (ar.currentline > 0) { - lua_pushfstring(L, "%s:%d", ar.short_src, ar.currentline); // some_error {} "blah:blah" + lua_pushfstring(L_, "%s:%d", ar.short_src, ar.currentline); // some_error {} "blah:blah" } else { - lua_pushfstring(L, "%s:?", ar.short_src); // some_error {} "blah" + lua_pushfstring(L_, "%s:?", ar.short_src); // some_error {} "blah" } - lua_rawseti(L, -2, (lua_Integer) n); // some_error {} + lua_rawseti(L_, -2, (lua_Integer) n); // some_error {} } // store the stack trace table in the registry - kStackTraceRegKey.setValue(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error + kStackTraceRegKey.setValue(L_, [](lua_State* L_) { lua_insert(L_, -2); }); // some_error - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); return 1; // the untouched error value } #endif // ERROR_FULL_STACK @@ -733,19 +732,19 @@ LUAG_FUNC(set_debug_threadname) // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator constexpr RegistryUniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; // C s_lane structure is a light userdata upvalue - Lane* const lane{ lua_tolightuserdata(L, lua_upvalueindex(1)) }; - luaL_checktype(L, -1, LUA_TSTRING); // "name" - lua_settop(L, 1); - STACK_CHECK_START_ABS(L, 1); + Lane* const lane{ lua_tolightuserdata(L_, lua_upvalueindex(1)) }; + luaL_checktype(L_, -1, LUA_TSTRING); // "name" + lua_settop(L_, 1); + STACK_CHECK_START_ABS(L_, 1); // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... - hidden_regkey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); - STACK_CHECK(L, 1); - lane->debug_name = lua_tostring(L, -1); + hidden_regkey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); + STACK_CHECK(L_, 1); + lane->debug_name = lua_tostring(L_, -1); // keep a direct pointer on the string THREAD_SETNAME(lane->debug_name); // to see VM name in Decoda debugger Virtual Machine window - lua_setglobal(L, "decoda_name"); // - STACK_CHECK(L, 0); + lua_setglobal(L_, "decoda_name"); // + STACK_CHECK(L_, 0); return 0; } @@ -753,9 +752,9 @@ LUAG_FUNC(set_debug_threadname) LUAG_FUNC(get_debug_threadname) { - Lane* const lane{ ToLane(L, 1) }; - luaL_argcheck(L, lua_gettop(L) == 1, 2, "too many arguments"); - lua_pushstring(L, lane->debug_name); + Lane* const lane{ ToLane(L_, 1) }; + luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments"); + lua_pushstring(L_, lane->debug_name); return 1; } @@ -763,15 +762,15 @@ LUAG_FUNC(get_debug_threadname) LUAG_FUNC(set_thread_priority) { - lua_Integer const prio{ luaL_checkinteger(L, 1) }; + lua_Integer const prio{ luaL_checkinteger(L_, 1) }; // public Lanes API accepts a generic range -3/+3 // that will be remapped into the platform-specific scheduler priority scheme // On some platforms, -3 is equivalent to -2 and +3 to +2 if (prio < kThreadPrioMin || prio > kThreadPrioMax) { - raise_luaL_error(L, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); + raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); } - THREAD_SET_PRIORITY(static_cast(prio), universe_get(L)->m_sudo); + THREAD_SET_PRIORITY(static_cast(prio), universe_get(L_)->m_sudo); return 0; } @@ -779,10 +778,10 @@ LUAG_FUNC(set_thread_priority) LUAG_FUNC(set_thread_affinity) { - lua_Integer const affinity{ luaL_checkinteger(L, 1) }; + lua_Integer const affinity{ luaL_checkinteger(L_, 1) }; if (affinity <= 0) { - raise_luaL_error(L, "invalid affinity (%d)", affinity); + raise_luaL_error(L_, "invalid affinity (%d)", affinity); } THREAD_SET_AFFINITY( static_cast(affinity)); return 0; @@ -920,18 +919,18 @@ static void lane_main(Lane* lane) // upvalue[1]: _G.require LUAG_FUNC(require) { - char const* name = lua_tostring(L, 1); - int const nargs = lua_gettop(L); - DEBUGSPEW_CODE(Universe* U = universe_get(L)); - STACK_CHECK_START_REL(L, 0); + char const* name = lua_tostring(L_, 1); + int const nargs = lua_gettop(L_); + DEBUGSPEW_CODE(Universe* U = universe_get(L_)); + STACK_CHECK_START_REL(L_, 0); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - lua_pushvalue(L, lua_upvalueindex(1)); // "name" require - lua_insert(L, 1); // require "name" - lua_call(L, nargs, 1); // module - populate_func_lookup_table(L, -1, name); + lua_pushvalue(L_, lua_upvalueindex(1)); // "name" require + lua_insert(L_, 1); // require "name" + lua_call(L_, nargs, 1); // module + populate_func_lookup_table(L_, -1, name); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END, name)); - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); return 1; } @@ -942,18 +941,18 @@ LUAG_FUNC(require) // lanes.register( "modname", module) LUAG_FUNC(register) { - char const* name = luaL_checkstring(L, 1); - LuaType const mod_type{ lua_type_as_enum(L, 2) }; + char const* name = luaL_checkstring(L_, 1); + LuaType const mod_type{ lua_type_as_enum(L_, 2) }; // ignore extra parameters, just in case - lua_settop(L, 2); - luaL_argcheck(L, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); + lua_settop(L_, 2); + luaL_argcheck(L_, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); DEBUGSPEW_CODE(Universe* U = universe_get(L)); - STACK_CHECK_START_REL(L, 0); // "name" mod_table + STACK_CHECK_START_REL(L_, 0); // "name" mod_table DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - populate_func_lookup_table(L, -1, name); + populate_func_lookup_table(L_, -1, name); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END, name)); - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); return 0; } @@ -976,38 +975,38 @@ static constexpr UniqueKey kLaneGC{ 0x5D6122141727F960ull }; // LUAG_FUNC(lane_new) { - char const* const libs_str{ lua_tostring(L, 2) }; - bool const have_priority{ !lua_isnoneornil(L, 3) }; - int const priority{ have_priority ? (int) lua_tointeger(L, 3) : kThreadPrioDefault }; - int const globals_idx{ lua_isnoneornil(L, 4) ? 0 : 4 }; - int const package_idx{ lua_isnoneornil(L, 5) ? 0 : 5 }; - int const required_idx{ lua_isnoneornil(L, 6) ? 0 : 6 }; - int const gc_cb_idx{ lua_isnoneornil(L, 7) ? 0 : 7 }; + char const* const libs_str{ lua_tostring(L_, 2) }; + bool const have_priority{ !lua_isnoneornil(L_, 3) }; + int const priority{ have_priority ? static_cast(lua_tointeger(L_, 3)) : kThreadPrioDefault }; + int const globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 }; + int const package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 }; + int const required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 }; + int const gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 }; static constexpr int kFixedArgsIdx{ 7 }; - int const nargs{ lua_gettop(L) - kFixedArgsIdx }; - Universe* const U{ universe_get(L) }; - LUA_ASSERT(L, nargs >= 0); + int const nargs{ lua_gettop(L_) - kFixedArgsIdx }; + Universe* const U{ universe_get(L_) }; + LUA_ASSERT(L_, nargs >= 0); // public Lanes API accepts a generic range -3/+3 // that will be remapped into the platform-specific scheduler priority scheme // On some platforms, -3 is equivalent to -2 and +3 to +2 if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax)) { - raise_luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); + raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); } /* --- Create and prepare the sub state --- */ DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END)); // populate with selected libraries at the same time - lua_State* const L2{ luaG_newstate(U, SourceState{ L }, libs_str) }; // L // L2 + lua_State* const L2{ luaG_newstate(U, SourceState{ L_ }, libs_str) }; // L // L2 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) Lane* const lane{ new (U) Lane{ U, L2 } }; if (lane == nullptr) { - raise_luaL_error(L, "could not create lane: out of memory"); + raise_luaL_error(L_, "could not create lane: out of memory"); } class OnExit @@ -1090,7 +1089,7 @@ LUAG_FUNC(lane_new) m_lane->m_ready.count_down(); m_lane = nullptr; } - } onExit{ L, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; + } onExit{ L_, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); lane->startThread(priority); @@ -1098,22 +1097,22 @@ LUAG_FUNC(lane_new) STACK_GROW( L2, nargs + 3); // STACK_CHECK_START_REL(L2, 0); - STACK_GROW(L, 3); // func libs priority globals package required gc_cb [... args ...] - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 3); // func libs priority globals package required gc_cb [... args ...] + STACK_CHECK_START_REL(L_, 0); // give a default "Lua" name to the thread to see VM name in Decoda debugger lua_pushfstring( L2, "Lane #%p", L2); // "..." lua_setglobal( L2, "decoda_name"); // - LUA_ASSERT(L, lua_gettop( L2) == 0); + LUA_ASSERT(L_, lua_gettop( L2) == 0); // package if (package_idx != 0) { DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END)); // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack - InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, SourceIndex{ package_idx }, {}, {}, {} }; + InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, SourceIndex{ package_idx }, {}, {}, {} }; [[maybe_unused]] InterCopyResult const ret{ c.inter_copy_package() }; - LUA_ASSERT(L, ret == InterCopyResult::Success); // either all went well, or we should not even get here + LUA_ASSERT(L_, ret == InterCopyResult::Success); // either all went well, or we should not even get here } // modules to require in the target lane *before* the function is transfered! @@ -1123,23 +1122,23 @@ LUAG_FUNC(lane_new) DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require 'required' list\n" INDENT_END)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); // should not happen, was checked in lanes.lua before calling lane_new() - if (lua_type(L, required_idx) != LUA_TTABLE) + if (lua_type(L_, required_idx) != LUA_TTABLE) { - raise_luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx)); + raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, required_idx)); } - lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil - while (lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" + lua_pushnil(L_); // func libs priority globals package required gc_cb [... args ...] nil + while (lua_next(L_, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" { - if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired) + if (lua_type(L_, -1) != LUA_TSTRING || lua_type(L_, -2) != LUA_TNUMBER || lua_tonumber(L_, -2) != nbRequired) { - raise_luaL_error(L, "required module list should be a list of strings"); + raise_luaL_error(L_, "required module list should be a list of strings"); } else { // require the module in the target state, and populate the lookup table there too size_t len; - char const* name = lua_tolstring(L, -1, &len); + char const* name = lua_tolstring(L_, -1, &len); DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); // require the module in the target lane @@ -1147,7 +1146,7 @@ LUAG_FUNC(lane_new) if (lua_isnil( L2, -1)) { lua_pop( L2, 1); // - raise_luaL_error(L, "cannot pre-require modules without loading 'package' library first"); + raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first"); } else { @@ -1155,20 +1154,20 @@ LUAG_FUNC(lane_new) if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode { // propagate error to main state if any - InterCopyContext c{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }; + InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }; std::ignore = c.inter_move(1); // func libs priority globals package required gc_cb [... args ...] n "modname" error - raise_lua_error(L); + raise_lua_error(L_); } // after requiring the module, register the functions it exported in our name<->function database populate_func_lookup_table( L2, -1, name); lua_pop( L2, 1); // } } - lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] n + lua_pop(L_, 1); // func libs priority globals package required gc_cb [... args ...] n ++ nbRequired; } // func libs priority globals package required gc_cb [... args ...] } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); STACK_CHECK(L2, 0); // // Appending the specified globals to the global environment @@ -1177,83 +1176,83 @@ LUAG_FUNC(lane_new) if (globals_idx != 0) { DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END)); - if (!lua_istable(L, globals_idx)) + if (!lua_istable(L_, globals_idx)) { - raise_luaL_error(L, "Expected table, got %s", luaL_typename(L, globals_idx)); + raise_luaL_error(L_, "Expected table, got %s", luaL_typename(L_, globals_idx)); } DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil + lua_pushnil(L_); // func libs priority globals package required gc_cb [... args ...] nil // Lua 5.2 wants us to push the globals table on the stack - InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; + InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; lua_pushglobaltable(L2); // _G - while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v + while( lua_next(L_, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v { std::ignore = c.inter_copy(2); // _G k v // assign it in L2's globals table lua_rawset(L2, -3); // _G - lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k + lua_pop(L_, 1); // func libs priority globals package required gc_cb [... args ...] k } // func libs priority globals package required gc_cb [... args ...] lua_pop( L2, 1); // } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); STACK_CHECK(L2, 0); // Lane main function - LuaType const func_type{ lua_type_as_enum(L, 1) }; + LuaType const func_type{ lua_type_as_enum(L_, 1) }; if (func_type == LuaType::FUNCTION) { DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func - InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; + lua_pushvalue(L_, 1); // func libs priority globals package required gc_cb [... args ...] func + InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; InterCopyResult const res{ c.inter_move(1) }; // func libs priority globals package required gc_cb [... args ...] // func if (res != InterCopyResult::Success) { - raise_luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L_, "tried to copy unsupported types"); } } else if (func_type == LuaType::STRING) { DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END)); // compile the string - if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func + if (luaL_loadstring(L2, lua_tostring(L_, 1)) != 0) // func { - raise_luaL_error(L, "error when parsing lane function code"); + raise_luaL_error(L_, "error when parsing lane function code"); } } else { - raise_luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); + raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, func_type)); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); STACK_CHECK(L2, 1); - LUA_ASSERT(L, lua_isfunction(L2, 1)); + LUA_ASSERT(L_, lua_isfunction(L2, 1)); // revive arguments if (nargs > 0) { DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; + InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; InterCopyResult const res{ c.inter_move(nargs) }; // func libs priority globals package required gc_cb // func [... args ...] if (res != InterCopyResult::Success) { - raise_luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L_, "tried to copy unsupported types"); } } - STACK_CHECK(L, -nargs); - LUA_ASSERT(L, lua_gettop(L) == kFixedArgsIdx); + STACK_CHECK(L_, -nargs); + LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx); // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). kLanePointerRegKey.setValue(L2, [lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); }); // func [... args ...] STACK_CHECK(L2, 1 + nargs); - STACK_CHECK_RESET_REL(L, 0); + STACK_CHECK_RESET_REL(L_, 0); // all went well, the lane's thread can start working onExit.success(); // we should have the lane userdata on top of the stack - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); return 1; } @@ -1271,24 +1270,24 @@ LUAG_FUNC(lane_new) // and the issue of canceling/killing threads at gc is not very nice, either // (would easily cause waits at gc cycle, which we don't want). // -[[nodiscard]] static int lane_gc(lua_State* L) +[[nodiscard]] static int lane_gc(lua_State* L_) { bool have_gc_cb{ false }; - Lane* const lane{ ToLane(L, 1) }; // ud + Lane* const lane{ ToLane(L_, 1) }; // ud // if there a gc callback? - lua_getiuservalue(L, 1, 1); // ud uservalue - kLaneGC.pushKey(L); // ud uservalue __gc - lua_rawget(L, -2); // ud uservalue gc_cb|nil - if (!lua_isnil(L, -1)) + lua_getiuservalue(L_, 1, 1); // ud uservalue + kLaneGC.pushKey(L_); // ud uservalue __gc + lua_rawget(L_, -2); // ud uservalue gc_cb|nil + if (!lua_isnil(L_, -1)) { - lua_remove(L, -2); // ud gc_cb|nil - lua_pushstring(L, lane->debug_name); // ud gc_cb name + lua_remove(L_, -2); // ud gc_cb|nil + lua_pushstring(L_, lane->debug_name); // ud gc_cb name have_gc_cb = true; } else { - lua_pop(L, 2); // ud + lua_pop(L_, 2); // ud } // We can read 'lane->status' without locks, but not wait for it @@ -1299,8 +1298,8 @@ LUAG_FUNC(lane_new) assert(lane->selfdestruct_next); if (have_gc_cb) { - lua_pushliteral(L, "selfdestruct"); // ud gc_cb name status - lua_call(L, 2, 0); // ud + lua_pushliteral(L_, "selfdestruct"); // ud gc_cb name status + lua_call(L_, 2, 0); // ud } return 0; } @@ -1319,8 +1318,8 @@ LUAG_FUNC(lane_new) // do this after lane cleanup in case the callback triggers an error if (have_gc_cb) { - lua_pushliteral(L, "closed"); // ud gc_cb name status - lua_call(L, 2, 0); // ud + lua_pushliteral(L_, "closed"); // ud gc_cb name status + lua_call(L_, 2, 0); // ud } return 0; } @@ -1374,27 +1373,27 @@ void Lane::pushThreadStatus(lua_State* L_) // LUAG_FUNC(thread_join) { - Lane* const lane{ ToLane(L, 1) }; - lua_Duration const duration{ luaL_optnumber(L, 2, -1.0) }; + Lane* const lane{ ToLane(L_, 1) }; + lua_Duration const duration{ luaL_optnumber(L_, 2, -1.0) }; lua_State* const L2{ lane->L }; bool const done{ !lane->m_thread.joinable() || lane->waitForCompletion(duration) }; if (!done || !L2) { - STACK_GROW(L, 2); - lua_pushnil(L); - lua_pushliteral(L, "timeout"); + STACK_GROW(L_, 2); + lua_pushnil(L_); + lua_pushliteral(L_, "timeout"); return 2; } - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // Thread is Done/Error/Cancelled; all ours now int ret{ 0 }; Universe* const U{ lane->U }; // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed // so store it in the userdata uservalue at a key that can't possibly collide - securize_debug_threadname(L, lane); + securize_debug_threadname(L_, lane); switch (lane->m_status) { case Lane::Done: @@ -1402,10 +1401,10 @@ LUAG_FUNC(thread_join) int const n{ lua_gettop(L2) }; // whole L2 stack if ( (n > 0) && - (InterCopyContext{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) + (InterCopyContext{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) ) { - raise_luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L_, "tried to copy unsupported types"); } ret = n; } @@ -1414,13 +1413,13 @@ LUAG_FUNC(thread_join) case Lane::Error: { int const n{ lua_gettop(L2) }; - STACK_GROW(L, 3); - lua_pushnil(L); + STACK_GROW(L_, 3); + lua_pushnil(L_); // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... - InterCopyContext c{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }; + InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }; if (c.inter_move(n) != InterCopyResult::Success) // nil "err" [trace] { - raise_luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); + raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -n)); } ret = 1 + n; } @@ -1432,12 +1431,12 @@ LUAG_FUNC(thread_join) default: DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->m_status)); - LUA_ASSERT(L, false); + LUA_ASSERT(L_, false); ret = 0; } lua_close(L2); lane->L = nullptr; - STACK_CHECK(L, ret); + STACK_CHECK(L_, ret); return ret; } @@ -1454,60 +1453,60 @@ LUAG_FUNC(thread_index) { static constexpr int kSelf{ 1 }; static constexpr int kKey{ 2 }; - Lane* const lane{ ToLane(L, kSelf) }; - LUA_ASSERT(L, lua_gettop(L) == 2); + Lane* const lane{ ToLane(L_, kSelf) }; + LUA_ASSERT(L_, lua_gettop(L_) == 2); - STACK_GROW(L, 8); // up to 8 positions are needed in case of error propagation + STACK_GROW(L_, 8); // up to 8 positions are needed in case of error propagation // If key is numeric, wait until the thread returns and populate the environment with the return values - if (lua_type(L, kKey) == LUA_TNUMBER) + if (lua_type(L_, kKey) == LUA_TNUMBER) { static constexpr int kUsr{ 3 }; // first, check that we don't already have an environment that holds the requested value { // If key is found in the uservalue, return it - lua_getiuservalue(L, kSelf, 1); - lua_pushvalue(L, kKey); - lua_rawget(L, kUsr); - if (!lua_isnil(L, -1)) + lua_getiuservalue(L_, kSelf, 1); + lua_pushvalue(L_, kKey); + lua_rawget(L_, kUsr); + if (!lua_isnil(L_, -1)) { return 1; } - lua_pop(L, 1); + lua_pop(L_, 1); } { // check if we already fetched the values from the thread or not - lua_pushinteger(L, 0); - lua_rawget(L, kUsr); - bool const fetched{ !lua_isnil(L, -1) }; - lua_pop(L, 1); // back to our 2 args + uservalue on the stack + lua_pushinteger(L_, 0); + lua_rawget(L_, kUsr); + bool const fetched{ !lua_isnil(L_, -1) }; + lua_pop(L_, 1); // back to our 2 args + uservalue on the stack if (!fetched) { - lua_pushinteger(L, 0); - lua_pushboolean(L, 1); - lua_rawset(L, kUsr); + lua_pushinteger(L_, 0); + lua_pushboolean(L_, 1); + lua_rawset(L_, kUsr); // wait until thread has completed - lua_pushcfunction(L, LG_thread_join); - lua_pushvalue(L, kSelf); - lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ + lua_pushcfunction(L_, LG_thread_join); + lua_pushvalue(L_, kSelf); + lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ switch (lane->m_status) { default: // this is an internal error, we probably never get here - lua_settop(L, 0); - lua_pushliteral(L, "Unexpected status: "); - lua_pushstring(L, thread_status_string(lane->m_status)); - lua_concat(L, 2); - raise_lua_error(L); + lua_settop(L_, 0); + lua_pushliteral(L_, "Unexpected status: "); + lua_pushstring(L_, thread_status_string(lane->m_status)); + lua_concat(L_, 2); + raise_lua_error(L_); [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack case Lane::Done: // got regular return values { - int const nvalues{ lua_gettop(L) - 3 }; + int const nvalues{ lua_gettop(L_) - 3 }; for (int i = nvalues; i > 0; --i) { // pop the last element of the stack, to store it in the uservalue at its proper index - lua_rawseti(L, kUsr, i); + lua_rawseti(L_, kUsr, i); } } break; @@ -1516,11 +1515,11 @@ LUAG_FUNC(thread_index) // me[-2] could carry the stack table, but even // me[-1] is rather unnecessary (and undocumented); // use ':join()' instead. --AKa 22-Jan-2009 - LUA_ASSERT(L, lua_isnil(L, 4) && !lua_isnil(L, 5) && lua_istable(L, 6)); + LUA_ASSERT(L_, lua_isnil(L_, 4) && !lua_isnil(L_, 5) && lua_istable(L_, 6)); // store errstring at key -1 - lua_pushnumber(L, -1); - lua_pushvalue(L, 5); - lua_rawset(L, kUsr); + lua_pushnumber(L_, -1); + lua_pushvalue(L_, 5); + lua_rawset(L_, kUsr); break; case Lane::Cancelled: @@ -1528,13 +1527,13 @@ LUAG_FUNC(thread_index) break; } } - lua_settop(L, 3); // self KEY ENV - int const key{ static_cast(lua_tointeger(L, kKey)) }; + lua_settop(L_, 3); // self KEY ENV + int const key{ static_cast(lua_tointeger(L_, kKey)) }; if (key != -1) { - lua_pushnumber(L, -1); // self KEY ENV -1 - lua_rawget(L, kUsr); // self KEY ENV "error"|nil - if (!lua_isnil(L, -1)) // an error was stored + lua_pushnumber(L_, -1); // self KEY ENV -1 + lua_rawget(L_, kUsr); // self KEY ENV "error"|nil + if (!lua_isnil(L_, -1)) // an error was stored { // Note: Lua 5.1 interpreter is not prepared to show // non-string errors, so we use 'tostring()' here @@ -1547,50 +1546,50 @@ LUAG_FUNC(thread_index) // Level 3 should show the line where 'h[x]' was read // but this only seems to work for string messages // (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009 - lua_getmetatable(L, kSelf); // self KEY ENV "error" mt - lua_getfield(L, -1, "cached_error"); // self KEY ENV "error" mt error() - lua_getfield(L, -2, "cached_tostring"); // self KEY ENV "error" mt error() tostring() - lua_pushvalue(L, 4); // self KEY ENV "error" mt error() tostring() "error" - lua_call(L, 1, 1); // tostring( errstring) -- just in case // self KEY ENV "error" mt error() "error" - lua_pushinteger(L, 3); // self KEY ENV "error" mt error() "error" 3 - lua_call(L, 2, 0); // error( tostring( errstring), 3) // self KEY ENV "error" mt + lua_getmetatable(L_, kSelf); // self KEY ENV "error" mt + lua_getfield(L_, -1, "cached_error"); // self KEY ENV "error" mt error() + lua_getfield(L_, -2, "cached_tostring"); // self KEY ENV "error" mt error() tostring() + lua_pushvalue(L_, 4); // self KEY ENV "error" mt error() tostring() "error" + lua_call(L_, 1, 1); // tostring( errstring) -- just in case // self KEY ENV "error" mt error() "error" + lua_pushinteger(L_, 3); // self KEY ENV "error" mt error() "error" 3 + lua_call(L_, 2, 0); // error( tostring( errstring), 3) // self KEY ENV "error" mt } else { - lua_pop(L, 1); // self KEY ENV + lua_pop(L_, 1); // self KEY ENV } } - lua_rawgeti(L, kUsr, key); + lua_rawgeti(L_, kUsr, key); } return 1; } - if (lua_type(L, kKey) == LUA_TSTRING) + if (lua_type(L_, kKey) == LUA_TSTRING) { - char const* const keystr{ lua_tostring(L, kKey) }; - lua_settop(L, 2); // keep only our original arguments on the stack + char const* const keystr{ lua_tostring(L_, kKey) }; + lua_settop(L_, 2); // keep only our original arguments on the stack if (strcmp( keystr, "status") == 0) { - lane->pushThreadStatus(L); // push the string representing the status + lane->pushThreadStatus(L_); // push the string representing the status return 1; } // return self.metatable[key] - lua_getmetatable(L, kSelf); // self KEY mt - lua_replace(L, -3); // mt KEY - lua_rawget(L, -2); // mt value + lua_getmetatable(L_, kSelf); // self KEY mt + lua_replace(L_, -3); // mt KEY + lua_rawget(L_, -2); // mt value // only "cancel" and "join" are registered as functions, any other string will raise an error - if (!lua_iscfunction(L, -1)) + if (!lua_iscfunction(L_, -1)) { - raise_luaL_error(L, "can't index a lane with '%s'", keystr); + raise_luaL_error(L_, "can't index a lane with '%s'", keystr); } return 1; } // unknown key - lua_getmetatable(L, kSelf); - lua_getfield(L, -1, "cached_error"); - lua_pushliteral(L, "Unknown key: "); - lua_pushvalue(L, kKey); - lua_concat(L, 2); - lua_call(L, 1, 0); // error( "Unknown key: " .. key) -> doesn't return + lua_getmetatable(L_, kSelf); + lua_getfield(L_, -1, "cached_error"); + lua_pushliteral(L_, "Unknown key: "); + lua_pushvalue(L_, kKey); + lua_concat(L_, 2); + lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return return 0; } @@ -1601,8 +1600,8 @@ LUAG_FUNC(thread_index) // Return a list of all known lanes LUAG_FUNC(threads) { - int const top{ lua_gettop(L) }; - Universe* const U{ universe_get(L) }; + int const top{ lua_gettop(L_) }; + Universe* const U{ universe_get(L_) }; // List _all_ still running threads // @@ -1611,20 +1610,20 @@ LUAG_FUNC(threads) { Lane* lane{ U->tracking_first }; int index = 0; - lua_newtable(L); // {} + lua_newtable(L_); // {} while (lane != TRACKING_END) { // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other - lua_newtable(L); // {} {} - lua_pushstring(L, lane->debug_name); // {} {} "name" - lua_setfield(L, -2, "name"); // {} {} - lane->pushThreadStatus(L); // {} {} "status" - lua_setfield(L, -2, "status"); // {} {} - lua_rawseti(L, -2, ++index); // {} + lua_newtable(L_); // {} {} + lua_pushstring(L_, lane->debug_name); // {} {} "name" + lua_setfield(L_, -2, "name"); // {} {} + lane->pushThreadStatus(L_); // {} {} "status" + lua_setfield(L_, -2, "status"); // {} {} + lua_rawseti(L_, -2, ++index); // {} lane = lane->tracking_next; } } - return lua_gettop(L) - top; // 0 or 1 + return lua_gettop(L_) - top; // 0 or 1 } #endif // HAVE_LANE_TRACKING() @@ -1643,7 +1642,7 @@ LUAG_FUNC(now_secs) auto const now{ std::chrono::system_clock::now() }; lua_Duration duration { now.time_since_epoch() }; - lua_pushnumber(L, duration.count()); + lua_pushnumber(L_, duration.count()); return 1; } @@ -1664,8 +1663,8 @@ LUAG_FUNC(wakeup_conv) // .yday (day of the year) // .isdst (daylight saving on/off) - STACK_CHECK_START_REL(L, 0); - auto readInteger = [L](char const* name_) + STACK_CHECK_START_REL(L_, 0); + auto readInteger = [L = L_](char const* name_) { lua_getfield(L, 1, name_); lua_Integer const val{ lua_tointeger(L, -1) }; @@ -1678,15 +1677,15 @@ LUAG_FUNC(wakeup_conv) int const hour{ readInteger("hour") }; int const min{ readInteger("min") }; int const sec{ readInteger("sec") }; - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); // If Lua table has '.isdst' we trust that. If it does not, we'll let // 'mktime' decide on whether the time is within DST or not (value -1). // - lua_getfield(L, 1, "isdst" ); - int const isdst{ lua_isboolean(L, -1) ? lua_toboolean(L, -1) : -1 }; - lua_pop(L,1); - STACK_CHECK(L, 0); + lua_getfield(L_, 1, "isdst" ); + int const isdst{ lua_isboolean(L_, -1) ? lua_toboolean(L_, -1) : -1 }; + lua_pop(L_,1); + STACK_CHECK(L_, 0); std::tm t{}; t.tm_year = year - 1900; @@ -1697,7 +1696,7 @@ LUAG_FUNC(wakeup_conv) t.tm_sec= sec; // 0..60 t.tm_isdst= isdst; // 0/1/negative - lua_pushnumber(L, static_cast(std::mktime(&t))); // resolution: 1 second + lua_pushnumber(L_, static_cast(std::mktime(&t))); // resolution: 1 second return 1; } @@ -1705,7 +1704,7 @@ LUAG_FUNC(wakeup_conv) // ######################################## Module linkage ######################################### // ################################################################################################# -extern int LG_linda(lua_State* L); +extern int LG_linda(lua_State* L_); static struct luaL_Reg const lanes_functions[] = { { "linda", LG_linda }, @@ -1740,148 +1739,148 @@ LUAG_FUNC(configure) ); } - Universe* U = universe_get(L); + Universe* U = universe_get(L_); bool const from_master_state{ U == nullptr }; - char const* name = luaL_checkstring(L, lua_upvalueindex(1)); - LUA_ASSERT(L, lua_type(L, 1) == LUA_TTABLE); + char const* name = luaL_checkstring(L_, lua_upvalueindex(1)); + LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); - STACK_GROW(L, 4); - STACK_CHECK_START_ABS(L, 1); // settings + STACK_GROW(L_, 4); + STACK_CHECK_START_ABS(L_, 1); // settings DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); if (U == nullptr) { - U = universe_create(L); // settings universe + U = universe_create(L_); // settings universe DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); - lua_newtable( L); // settings universe mt - lua_getfield(L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout - lua_getfield(L, 1, "shutdown_mode"); // settings universe mt shutdown_timeout shutdown_mode - lua_pushcclosure(L, universe_gc, 2); // settings universe mt universe_gc - lua_setfield(L, -2, "__gc"); // settings universe mt - lua_setmetatable(L, -2); // settings universe - lua_pop(L, 1); // settings - lua_getfield(L, 1, "verbose_errors"); // settings verbose_errors - U->verboseErrors = lua_toboolean(L, -1) ? true : false; - lua_pop(L, 1); // settings - lua_getfield(L, 1, "demote_full_userdata"); // settings demote_full_userdata - U->demoteFullUserdata = lua_toboolean(L, -1) ? true : false; - lua_pop(L, 1); // settings + lua_newtable(L_); // settings universe mt + lua_getfield(L_, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout + lua_getfield(L_, 1, "shutdown_mode"); // settings universe mt shutdown_timeout shutdown_mode + lua_pushcclosure(L_, universe_gc, 2); // settings universe mt universe_gc + lua_setfield(L_, -2, "__gc"); // settings universe mt + lua_setmetatable(L_, -2); // settings universe + lua_pop(L_, 1); // settings + lua_getfield(L_, 1, "verbose_errors"); // settings verbose_errors + U->verboseErrors = lua_toboolean(L_, -1) ? true : false; + lua_pop(L_, 1); // settings + lua_getfield(L_, 1, "demote_full_userdata"); // settings demote_full_userdata + U->demoteFullUserdata = lua_toboolean(L_, -1) ? true : false; + lua_pop(L_, 1); // settings #if HAVE_LANE_TRACKING() - lua_getfield(L, 1, "track_lanes"); // settings track_lanes - U->tracking_first = lua_toboolean(L, -1) ? TRACKING_END : nullptr; - lua_pop(L, 1); // settings + lua_getfield(L_, 1, "track_lanes"); // settings track_lanes + U->tracking_first = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; + lua_pop(L_, 1); // settings #endif // HAVE_LANE_TRACKING() // Linked chains handling U->selfdestruct_first = SELFDESTRUCT_END; - initialize_allocator_function( U, L); - initialize_on_state_create( U, L); - init_keepers( U, L); - STACK_CHECK(L, 1); + initialize_allocator_function( U, L_); + initialize_on_state_create( U, L_); + init_keepers( U, L_); + STACK_CHECK(L_, 1); // Initialize 'timer_deep'; a common Linda object shared by all states - lua_pushcfunction(L, LG_linda); // settings lanes.linda - lua_pushliteral(L, "lanes-timer"); // settings lanes.linda "lanes-timer" - lua_call(L, 1, 1); // settings linda - STACK_CHECK(L, 2); + lua_pushcfunction(L_, LG_linda); // settings lanes.linda + lua_pushliteral(L_, "lanes-timer"); // settings lanes.linda "lanes-timer" + lua_call(L_, 1, 1); // settings linda + STACK_CHECK(L_, 2); // Proxy userdata contents is only a 'DeepPrelude*' pointer - U->timer_deep = *lua_tofulluserdata(L, -1); + U->timer_deep = *lua_tofulluserdata(L_, -1); // increment refcount so that this linda remains alive as long as the universe exists. U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); - lua_pop(L, 1); // settings + lua_pop(L_, 1); // settings } - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); // Serialize calls to 'require' from now on, also in the primary state - serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); + serialize_require( DEBUGSPEW_PARAM_COMMA( U) L_); // Retrieve main module interface table - lua_pushvalue(L, lua_upvalueindex( 2)); // settings M + lua_pushvalue(L_, lua_upvalueindex( 2)); // settings M // remove configure() (this function) from the module interface - lua_pushnil( L); // settings M nil - lua_setfield(L, -2, "configure"); // settings M + lua_pushnil( L_); // settings M nil + lua_setfield(L_, -2, "configure"); // settings M // add functions to the module's table - luaG_registerlibfuncs(L, lanes_functions); + luaG_registerlibfuncs(L_, lanes_functions); #if HAVE_LANE_TRACKING() // register core.threads() only if settings say it should be available if (U->tracking_first != nullptr) { - lua_pushcfunction(L, LG_threads); // settings M LG_threads() - lua_setfield(L, -2, "threads"); // settings M + lua_pushcfunction(L_, LG_threads); // settings M LG_threads() + lua_setfield(L_, -2, "threads"); // settings M } #endif // HAVE_LANE_TRACKING() - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); { - char const* errmsg{ DeepFactory::PushDeepProxy(DestState{ L }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep + char const* errmsg{ DeepFactory::PushDeepProxy(DestState{ L_ }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep if (errmsg != nullptr) { - raise_luaL_error(L, errmsg); + raise_luaL_error(L_, errmsg); } - lua_setfield(L, -2, "timer_gateway"); // settings M + lua_setfield(L_, -2, "timer_gateway"); // settings M } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); // prepare the metatable for threads // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } // - if (luaL_newmetatable(L, "Lane")) // settings M mt + if (luaL_newmetatable(L_, "Lane")) // settings M mt { - lua_pushcfunction(L, lane_gc); // settings M mt lane_gc - lua_setfield(L, -2, "__gc"); // settings M mt - lua_pushcfunction(L, LG_thread_index); // settings M mt LG_thread_index - lua_setfield(L, -2, "__index"); // settings M mt - lua_getglobal(L, "error"); // settings M mt error - LUA_ASSERT(L, lua_isfunction(L, -1)); - lua_setfield(L, -2, "cached_error"); // settings M mt - lua_getglobal(L, "tostring"); // settings M mt tostring - LUA_ASSERT(L, lua_isfunction(L, -1)); - lua_setfield(L, -2, "cached_tostring"); // settings M mt - lua_pushcfunction(L, LG_thread_join); // settings M mt LG_thread_join - lua_setfield(L, -2, "join"); // settings M mt - lua_pushcfunction(L, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname - lua_setfield(L, -2, "get_debug_threadname"); // settings M mt - lua_pushcfunction(L, LG_thread_cancel); // settings M mt LG_thread_cancel - lua_setfield(L, -2, "cancel"); // settings M mt - lua_pushliteral(L, "Lane"); // settings M mt "Lane" - lua_setfield(L, -2, "__metatable"); // settings M mt + lua_pushcfunction(L_, lane_gc); // settings M mt lane_gc + lua_setfield(L_, -2, "__gc"); // settings M mt + lua_pushcfunction(L_, LG_thread_index); // settings M mt LG_thread_index + lua_setfield(L_, -2, "__index"); // settings M mt + lua_getglobal(L_, "error"); // settings M mt error + LUA_ASSERT(L_, lua_isfunction(L_, -1)); + lua_setfield(L_, -2, "cached_error"); // settings M mt + lua_getglobal(L_, "tostring"); // settings M mt tostring + LUA_ASSERT(L_, lua_isfunction(L_, -1)); + lua_setfield(L_, -2, "cached_tostring"); // settings M mt + lua_pushcfunction(L_, LG_thread_join); // settings M mt LG_thread_join + lua_setfield(L_, -2, "join"); // settings M mt + lua_pushcfunction(L_, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname + lua_setfield(L_, -2, "get_debug_threadname"); // settings M mt + lua_pushcfunction(L_, LG_thread_cancel); // settings M mt LG_thread_cancel + lua_setfield(L_, -2, "cancel"); // settings M mt + lua_pushliteral(L_, "Lane"); // settings M mt "Lane" + lua_setfield(L_, -2, "__metatable"); // settings M mt } - lua_pushcclosure(L, LG_lane_new, 1); // settings M lane_new - lua_setfield(L, -2, "lane_new"); // settings M + lua_pushcclosure(L_, LG_lane_new, 1); // settings M lane_new + lua_setfield(L_, -2, "lane_new"); // settings M // we can't register 'lanes.require' normally because we want to create an upvalued closure - lua_getglobal(L, "require"); // settings M require - lua_pushcclosure(L, LG_require, 1); // settings M lanes.require - lua_setfield(L, -2, "require"); // settings M + lua_getglobal(L_, "require"); // settings M require + lua_pushcclosure(L_, LG_require, 1); // settings M lanes.require + lua_setfield(L_, -2, "require"); // settings M lua_pushfstring( - L, "%d.%d.%d" + L_, "%d.%d.%d" , LANES_VERSION_MAJOR, LANES_VERSION_MINOR, LANES_VERSION_PATCH ); // settings M VERSION - lua_setfield(L, -2, "version"); // settings M + lua_setfield(L_, -2, "version"); // settings M - lua_pushinteger(L, kThreadPrioMax); // settings M kThreadPrioMax - lua_setfield(L, -2, "max_prio"); // settings M + lua_pushinteger(L_, kThreadPrioMax); // settings M kThreadPrioMax + lua_setfield(L_, -2, "max_prio"); // settings M - kCancelError.pushKey(L); // settings M kCancelError - lua_setfield(L, -2, "cancel_error"); // settings M + kCancelError.pushKey(L_); // settings M kCancelError + lua_setfield(L_, -2, "cancel_error"); // settings M - kNilSentinel.pushKey(L); // settings M kNilSentinel - lua_setfield(L, -2, "null"); // settings M + kNilSentinel.pushKey(L_); // settings M kNilSentinel + lua_setfield(L_, -2, "null"); // settings M - STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings' + STACK_CHECK(L_, 2); // reference stack contains only the function argument 'settings' // we'll need this every time we transfer some C function from/to this state - kLookupRegKey.setValue(L, [](lua_State* L) { lua_newtable(L); }); // settings M - STACK_CHECK(L, 2); + kLookupRegKey.setValue(L_, [](lua_State* L_) { lua_newtable(L_); }); // settings M + STACK_CHECK(L_, 2); // register all native functions found in that module in the transferable functions database // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) // for example in package.loaded["lanes.core"].* - populate_func_lookup_table(L, -1, name); - STACK_CHECK(L, 2); + populate_func_lookup_table(L_, -1, name); + STACK_CHECK(L_, 2); // record all existing C/JIT-fast functions // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack @@ -1890,15 +1889,15 @@ LUAG_FUNC(configure) // don't do this when called during the initialization of a new lane, // because we will do it after on_state_create() is called, // and we don't want to skip _G because of caching in case globals are created then - lua_pushglobaltable( L); // settings M _G - populate_func_lookup_table(L, -1, nullptr); - lua_pop(L, 1); // settings M + lua_pushglobaltable(L_); // settings M _G + populate_func_lookup_table(L_, -1, nullptr); + lua_pop(L_, 1); // settings M } - lua_pop(L, 1); // settings + lua_pop(L_, 1); // settings // set _R[kConfigRegKey] = settings - kConfigRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); - STACK_CHECK(L, 1); + kConfigRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); + STACK_CHECK(L_, 1); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); // Return the settings table return 1; @@ -1962,70 +1961,70 @@ static void EnableCrashingOnCrashes(void) } #endif // PLATFORM_WIN32 && !defined NDEBUG -LANES_API int luaopen_lanes_core( lua_State* L) +LANES_API int luaopen_lanes_core( lua_State* L_) { #if defined PLATFORM_WIN32 && !defined NDEBUG EnableCrashingOnCrashes(); #endif // defined PLATFORM_WIN32 && !defined NDEBUG - STACK_GROW(L, 4); - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 4); + STACK_CHECK_START_REL(L_, 0); // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too - lua_getglobal(L, "jit"); // {jit?} + lua_getglobal(L_, "jit"); // {jit?} #if LUAJIT_FLAVOR() == 0 - if (!lua_isnil(L, -1)) - raise_luaL_error(L, "Lanes is built for PUC-Lua, don't run from LuaJIT"); + if (!lua_isnil(L_, -1)) + raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT"); #else - if (lua_isnil(L, -1)) - raise_luaL_error(L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); + if (lua_isnil(L_, -1)) + raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua"); #endif - lua_pop(L, 1); // - STACK_CHECK(L, 0); + lua_pop(L_, 1); // + STACK_CHECK(L_, 0); // Create main module interface table // we only have 1 closure, which must be called to configure Lanes - lua_newtable(L); // M - lua_pushvalue(L, 1); // M "lanes.core" - lua_pushvalue(L, -2); // M "lanes.core" M - lua_pushcclosure(L, LG_configure, 2); // M LG_configure() - kConfigRegKey.pushValue(L); // M LG_configure() settings - if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately + lua_newtable(L_); // M + lua_pushvalue(L_, 1); // M "lanes.core" + lua_pushvalue(L_, -2); // M "lanes.core" M + lua_pushcclosure(L_, LG_configure, 2); // M LG_configure() + kConfigRegKey.pushValue(L_); // M LG_configure() settings + if (!lua_isnil(L_, -1)) // this is not the first require "lanes.core": call configure() immediately { - lua_pushvalue(L, -1); // M LG_configure() settings settings - lua_setfield(L, -4, "settings"); // M LG_configure() settings - lua_call(L, 1, 0); // M + lua_pushvalue(L_, -1); // M LG_configure() settings settings + lua_setfield(L_, -4, "settings"); // M LG_configure() settings + lua_call(L_, 1, 0); // M } else { // will do nothing on first invocation, as we haven't stored settings in the registry yet - lua_setfield(L, -3, "settings"); // M LG_configure() - lua_setfield(L, -2, "configure"); // M + lua_setfield(L_, -3, "settings"); // M LG_configure() + lua_setfield(L_, -2, "configure"); // M } - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); return 1; } -[[nodiscard]] static int default_luaopen_lanes(lua_State* L) +[[nodiscard]] static int default_luaopen_lanes(lua_State* L_) { - int const rc{ luaL_loadfile(L, "lanes.lua") || lua_pcall(L, 0, 1, 0) }; + int const rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) }; if (rc != LUA_OK) { - raise_luaL_error(L, "failed to initialize embedded Lanes"); + raise_luaL_error(L_, "failed to initialize embedded Lanes"); } return 1; } // call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application -LANES_API void luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) +LANES_API void luaopen_lanes_embedded( lua_State* L_, lua_CFunction _luaopen_lanes) { - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded - luaL_requiref(L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core - lua_pop(L, 1); // ... - STACK_CHECK(L, 0); + luaL_requiref(L_, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core + lua_pop(L_, 1); // ... + STACK_CHECK(L_, 0); // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it - luaL_requiref(L, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes - STACK_CHECK(L, 1); + luaL_requiref(L_, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes + STACK_CHECK(L_, 1); } diff --git a/src/lanes.h b/src/lanes.h index 287e405..6fea869 100644 --- a/src/lanes.h +++ b/src/lanes.h @@ -23,9 +23,9 @@ extern "C" #define LANES_VERSION_GREATER_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH > PATCH)))) #define LANES_VERSION_GREATER_OR_EQUAL(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH >= PATCH)))) -LANES_API [[nodiscard]] int luaopen_lanes_core(lua_State* L); +LANES_API [[nodiscard]] int luaopen_lanes_core(lua_State* L_); // Call this to work with embedded Lanes instead of calling luaopen_lanes_core() -LANES_API void luaopen_lanes_embedded(lua_State* L, lua_CFunction _luaopen_lanes); -using luaopen_lanes_embedded_t = void (*)(lua_State* L, lua_CFunction luaopen_lanes_); +LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction _luaopen_lanes); +using luaopen_lanes_embedded_t = void (*)(lua_State* L_, lua_CFunction luaopen_lanes_); static_assert(std::is_same_v, "signature changed: check all uses of luaopen_lanes_embedded_t"); diff --git a/src/lanes_private.h b/src/lanes_private.h index 859c8a2..083ac4e 100644 --- a/src/lanes_private.h +++ b/src/lanes_private.h @@ -98,7 +98,7 @@ static constexpr RegistryUniqueKey kLanePointerRegKey{ 0x2D8CF03FE9F0A51Aull }; // 'Lane' are malloc/free'd and the handle only carries a pointer. // This is not deep userdata since the handle's not portable among lanes. // -[[nodiscard]] inline Lane* ToLane(lua_State* L, int i_) +[[nodiscard]] inline Lane* ToLane(lua_State* L_, int i_) { - return *(static_cast(luaL_checkudata(L, i_, "Lane"))); + return *(static_cast(luaL_checkudata(L_, i_, "Lane"))); } diff --git a/src/linda.cpp b/src/linda.cpp index 67a97c2..f88158a 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -127,11 +127,11 @@ template // ################################################################################################# -static void check_key_types(lua_State* L, int start_, int end_) +static void check_key_types(lua_State* L_, int start_, int end_) { for (int i{ start_ }; i <= end_; ++i) { - LuaType const t{ lua_type_as_enum(L, i) }; + LuaType const t{ lua_type_as_enum(L_, i) }; switch (t) { case LuaType::BOOLEAN: @@ -144,25 +144,25 @@ static void check_key_types(lua_State* L, int start_, int end_) static constexpr std::array, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; for (UniqueKey const& key : kKeysToCheck) { - if (key.equals(L, i)) + if (key.equals(L_, i)) { - raise_luaL_error(L, "argument #%d: can't use %s as a key", i, key.m_debugName); + raise_luaL_error(L_, "argument #%d: can't use %s as a key", i, key.m_debugName); break; } } } break; } - raise_luaL_error(L, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); + raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); } } // ################################################################################################# // used to perform all linda operations that access keepers -int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) +int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) { - Linda* const linda{ ToLinda(L, 1) }; + Linda* const linda{ ToLinda(L_, 1) }; // acquire the keeper Keeper* const K{ linda->acquireKeeper() }; @@ -170,13 +170,13 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) if (KL == nullptr) return 0; // if we didn't do anything wrong, the keeper stack should be clean - LUA_ASSERT(L, lua_gettop(KL) == 0); + LUA_ASSERT(L_, lua_gettop(KL) == 0); // push the function to be called and move it before the arguments - lua_pushcfunction(L, f_); - lua_insert(L, 1); + lua_pushcfunction(L_, f_); + lua_insert(L_, 1); // do a protected call - int const rc{ lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) }; + int const rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) }; // whatever happens, the keeper state stack must be empty when we are done lua_settop(KL, 0); @@ -186,10 +186,10 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) // if there was an error, forward it if (rc != LUA_OK) { - raise_lua_error(L); + raise_lua_error(L_); } // return whatever the actual operation provided - return lua_gettop(L); + return lua_gettop(L_); } // ################################################################################################# @@ -205,27 +205,27 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) */ LUAG_FUNC(linda_send) { - auto send = [](lua_State* L) + auto send = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; + Linda* const linda{ ToLinda(L_, 1) }; std::chrono::time_point until{ std::chrono::time_point::max() }; int key_i{ 2 }; // index of first key, if timeout not there - if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion + if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion { - lua_Duration const duration{ lua_tonumber(L, 2) }; + lua_Duration const duration{ lua_tonumber(L_, 2) }; if (duration.count() >= 0.0) { until = std::chrono::steady_clock::now() + std::chrono::duration_cast(duration); } ++key_i; } - else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key + else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key { ++key_i; } - bool const as_nil_sentinel{ kNilSentinel.equals(L, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided + bool const as_nil_sentinel{ kNilSentinel.equals(L_, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided if (as_nil_sentinel) { // the real key to send data to is after the kNilSentinel marker @@ -233,31 +233,31 @@ LUAG_FUNC(linda_send) } // make sure the key is of a valid type - check_key_types(L, key_i, key_i); + check_key_types(L_, key_i, key_i); - STACK_GROW(L, 1); + STACK_GROW(L_, 1); // make sure there is something to send - if (lua_gettop(L) == key_i) + if (lua_gettop(L_) == key_i) { if (as_nil_sentinel) { // send a single nil if nothing is provided - kNilSentinel.pushKey(L); + kNilSentinel.pushKey(L_); } else { - raise_luaL_error(L, "no data to send"); + raise_luaL_error(L_, "no data to send"); } } // convert nils to some special non-nil sentinel in sent values - keeper_toggle_nil_sentinels(L, key_i + 1, LookupMode::ToKeeper); + keeper_toggle_nil_sentinels(L_, key_i + 1, LookupMode::ToKeeper); bool ret{ false }; CancelRequest cancel{ CancelRequest::None }; KeeperCallResult pushed; { - Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L) }; + Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L_) }; Keeper* const K{ linda->whichKeeper() }; KeeperState const KL{ K ? K->L : nullptr }; if (KL == nullptr) @@ -279,15 +279,15 @@ LUAG_FUNC(linda_send) } STACK_CHECK(KL, 0); - pushed = keeper_call(linda->U, KL, KEEPER_API(send), L, linda, key_i); + pushed = keeper_call(linda->U, KL, KEEPER_API(send), L_, linda, key_i); if (!pushed.has_value()) { break; } - LUA_ASSERT(L, pushed.value() == 1); + LUA_ASSERT(L_, pushed.value() == 1); - ret = lua_toboolean(L, -1) ? true : false; - lua_pop(L, 1); + ret = lua_toboolean(L_, -1) ? true : false; + lua_pop(L_, 1); if (ret) { @@ -309,9 +309,9 @@ LUAG_FUNC(linda_send) { // change status of lane to "waiting" prev_status = lane->m_status; // Running, most likely - LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case + LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case lane->m_status = Lane::Waiting; - LUA_ASSERT(L, lane->m_waiting_on == nullptr); + LUA_ASSERT(L_, lane->m_waiting_on == nullptr); lane->m_waiting_on = &linda->m_read_happened; } // could not send because no room: wait until some data was read before trying again, or until timeout is reached @@ -331,26 +331,26 @@ LUAG_FUNC(linda_send) if (!pushed.has_value()) { - raise_luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L_, "tried to copy unsupported types"); } switch (cancel) { case CancelRequest::Soft: // if user wants to soft-cancel, the call returns lanes.cancel_error - kCancelError.pushKey(L); + kCancelError.pushKey(L_); return 1; case CancelRequest::Hard: // raise an error interrupting execution only in case of hard cancel - raise_cancel_error(L); // raises an error and doesn't return + raise_cancel_error(L_); // raises an error and doesn't return default: - lua_pushboolean(L, ret); // true (success) or false (timeout) + lua_pushboolean(L_, ret); // true (success) or false (timeout) return 1; } }; - return Linda::ProtectedCall(L, send); + return Linda::ProtectedCall(L_, send); } // ################################################################################################# @@ -368,22 +368,22 @@ LUAG_FUNC(linda_send) */ LUAG_FUNC(linda_receive) { - auto receive = [](lua_State* L) + auto receive = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; + Linda* const linda{ ToLinda(L_, 1) }; std::chrono::time_point until{ std::chrono::time_point::max() }; int key_i{ 2 }; // index of first key, if timeout not there - if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion + if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion { - lua_Duration const duration{ lua_tonumber(L, 2) }; + lua_Duration const duration{ lua_tonumber(L_, 2) }; if (duration.count() >= 0.0) { until = std::chrono::steady_clock::now() + std::chrono::duration_cast(duration); } ++key_i; } - else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key + else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key { ++key_i; } @@ -391,39 +391,39 @@ LUAG_FUNC(linda_receive) keeper_api_t selected_keeper_receive{ nullptr }; int expected_pushed_min{ 0 }, expected_pushed_max{ 0 }; // are we in batched mode? - kLindaBatched.pushKey(L); - int const is_batched{ lua501_equal(L, key_i, -1) }; - lua_pop(L, 1); + kLindaBatched.pushKey(L_); + int const is_batched{ lua501_equal(L_, key_i, -1) }; + lua_pop(L_, 1); if (is_batched) { // no need to pass linda.batched in the keeper state ++key_i; // make sure the keys are of a valid type - check_key_types(L, key_i, key_i); + check_key_types(L_, key_i, key_i); // receive multiple values from a single slot selected_keeper_receive = KEEPER_API(receive_batched); // we expect a user-defined amount of return value - expected_pushed_min = (int) luaL_checkinteger(L, key_i + 1); - expected_pushed_max = (int) luaL_optinteger(L, key_i + 2, expected_pushed_min); + expected_pushed_min = (int) luaL_checkinteger(L_, key_i + 1); + expected_pushed_max = (int) luaL_optinteger(L_, key_i + 2, expected_pushed_min); // don't forget to count the key in addition to the values ++expected_pushed_min; ++expected_pushed_max; if (expected_pushed_min > expected_pushed_max) { - raise_luaL_error(L, "batched min/max error"); + raise_luaL_error(L_, "batched min/max error"); } } else { // make sure the keys are of a valid type - check_key_types(L, key_i, lua_gettop(L)); + check_key_types(L_, key_i, lua_gettop(L_)); // receive a single value, checking multiple slots selected_keeper_receive = KEEPER_API(receive); // we expect a single (value, key) pair of returned values expected_pushed_min = expected_pushed_max = 2; } - Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L) }; + Lane* const lane{ kLanePointerRegKey.readLightUserDataValue(L_) }; Keeper* const K{ linda->whichKeeper() }; KeeperState const KL{ K ? K->L : nullptr }; if (KL == nullptr) @@ -447,16 +447,16 @@ LUAG_FUNC(linda_receive) } // all arguments of receive() but the first are passed to the keeper's receive function - pushed = keeper_call(linda->U, KL, selected_keeper_receive, L, linda, key_i); + pushed = keeper_call(linda->U, KL, selected_keeper_receive, L_, linda, key_i); if (!pushed.has_value()) { break; } if (pushed.value() > 0) { - LUA_ASSERT(L, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); + LUA_ASSERT(L_, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); // replace sentinels with real nils - keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); + keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); // To be done from within the 'K' locking area // linda->m_read_happened.notify_all(); @@ -475,9 +475,9 @@ LUAG_FUNC(linda_receive) { // change status of lane to "waiting" prev_status = lane->m_status; // Running, most likely - LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case + LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case lane->m_status = Lane::Waiting; - LUA_ASSERT(L, lane->m_waiting_on == nullptr); + LUA_ASSERT(L_, lane->m_waiting_on == nullptr); lane->m_waiting_on = &linda->m_write_happened; } // not enough data to read: wakeup when data was sent, or when timeout is reached @@ -496,25 +496,25 @@ LUAG_FUNC(linda_receive) if (!pushed.has_value()) { - raise_luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L_, "tried to copy unsupported types"); } switch (cancel) { case CancelRequest::Soft: // if user wants to soft-cancel, the call returns kCancelError - kCancelError.pushKey(L); + kCancelError.pushKey(L_); return 1; case CancelRequest::Hard: // raise an error interrupting execution only in case of hard cancel - raise_cancel_error(L); // raises an error and doesn't return + raise_cancel_error(L_); // raises an error and doesn't return default: return pushed.value(); } }; - return Linda::ProtectedCall(L, receive); + return Linda::ProtectedCall(L_, receive); } // ################################################################################################# @@ -529,12 +529,12 @@ LUAG_FUNC(linda_receive) */ LUAG_FUNC(linda_set) { - auto set = [](lua_State* L) + auto set = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; - bool const has_value{ lua_gettop(L) > 2 }; + Linda* const linda{ ToLinda(L_, 1) }; + bool const has_value{ lua_gettop(L_) > 2 }; // make sure the key is of a valid type (throws an error if not the case) - check_key_types(L, 2, 2); + check_key_types(L_, 2, 2); Keeper* const K{ linda->whichKeeper() }; KeeperCallResult pushed; @@ -543,12 +543,12 @@ LUAG_FUNC(linda_set) if (has_value) { // convert nils to some special non-nil sentinel in sent values - keeper_toggle_nil_sentinels(L, 3, LookupMode::ToKeeper); + keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper); } - pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L, linda, 2); + pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L_, linda, 2); if (pushed.has_value()) // no error? { - LUA_ASSERT(L, pushed.value() == 0 || pushed.value() == 1); + LUA_ASSERT(L_, pushed.value() == 0 || pushed.value() == 1); if (has_value) { @@ -558,7 +558,7 @@ LUAG_FUNC(linda_set) if (pushed.value() == 1) { // the key was full, but it is no longer the case, tell writers they should wake - LUA_ASSERT(L, lua_type(L, -1) == LUA_TBOOLEAN && lua_toboolean(L, -1) == 1); + LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area } } @@ -566,14 +566,14 @@ LUAG_FUNC(linda_set) else // linda is cancelled { // do nothing and return lanes.cancel_error - kCancelError.pushKey(L); + kCancelError.pushKey(L_); pushed.emplace(1); } // must trigger any error after keeper state has been released - return OptionalValue(pushed, L, "tried to copy unsupported types"); + return OptionalValue(pushed, L_, "tried to copy unsupported types"); }; - return Linda::ProtectedCall(L, set); + return Linda::ProtectedCall(L_, set); } // ################################################################################################# @@ -585,17 +585,17 @@ LUAG_FUNC(linda_set) */ LUAG_FUNC(linda_count) { - auto count = [](lua_State* L) + auto count = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; + Linda* const linda{ ToLinda(L_, 1) }; // make sure the keys are of a valid type - check_key_types(L, 2, lua_gettop(L)); + check_key_types(L_, 2, lua_gettop(L_)); Keeper* const K{ linda->whichKeeper() }; - KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L, linda, 2) }; - return OptionalValue(pushed, L, "tried to count an invalid key"); + KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L_, linda, 2) }; + return OptionalValue(pushed, L_, "tried to count an invalid key"); }; - return Linda::ProtectedCall(L, count); + return Linda::ProtectedCall(L_, count); } // ################################################################################################# @@ -607,35 +607,35 @@ LUAG_FUNC(linda_count) */ LUAG_FUNC(linda_get) { - auto get = [](lua_State* L) + auto get = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; - lua_Integer const count{ luaL_optinteger(L, 3, 1) }; - luaL_argcheck(L, count >= 1, 3, "count should be >= 1"); - luaL_argcheck(L, lua_gettop(L) <= 3, 4, "too many arguments"); + Linda* const linda{ ToLinda(L_, 1) }; + lua_Integer const count{ luaL_optinteger(L_, 3, 1) }; + luaL_argcheck(L_, count >= 1, 3, "count should be >= 1"); + luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); // make sure the key is of a valid type (throws an error if not the case) - check_key_types(L, 2, 2); + check_key_types(L_, 2, 2); KeeperCallResult pushed; if (linda->simulate_cancel == CancelRequest::None) { Keeper* const K{ linda->whichKeeper() }; - pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L, linda, 2); + pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2); if (pushed.value_or(0) > 0) { - keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); + keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); } } else // linda is cancelled { // do nothing and return lanes.cancel_error - kCancelError.pushKey(L); + kCancelError.pushKey(L_); pushed.emplace(1); } // an error can be raised if we attempt to read an unregistered function - return OptionalValue(pushed, L, "tried to copy unsupported types"); + return OptionalValue(pushed, L_, "tried to copy unsupported types"); }; - return Linda::ProtectedCall(L, get); + return Linda::ProtectedCall(L_, get); } // ################################################################################################# @@ -648,38 +648,38 @@ LUAG_FUNC(linda_get) */ LUAG_FUNC(linda_limit) { - auto limit = [](lua_State* L) + auto limit = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; + Linda* const linda{ ToLinda(L_, 1) }; // make sure we got 3 arguments: the linda, a key and a limit - luaL_argcheck( L, lua_gettop( L) == 3, 2, "wrong number of arguments"); + luaL_argcheck( L_, lua_gettop( L_) == 3, 2, "wrong number of arguments"); // make sure we got a numeric limit - luaL_checknumber( L, 3); + luaL_checknumber( L_, 3); // make sure the key is of a valid type - check_key_types( L, 2, 2); + check_key_types( L_, 2, 2); KeeperCallResult pushed; if (linda->simulate_cancel == CancelRequest::None) { Keeper* const K{ linda->whichKeeper() }; - pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L, linda, 2); - LUA_ASSERT(L, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads + pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2); + LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads if (pushed.value() == 1) { - LUA_ASSERT(L, lua_type( L, -1) == LUA_TBOOLEAN && lua_toboolean( L, -1) == 1); + LUA_ASSERT(L_, lua_type( L_, -1) == LUA_TBOOLEAN && lua_toboolean( L_, -1) == 1); linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area } } else // linda is cancelled { // do nothing and return lanes.cancel_error - kCancelError.pushKey(L); + kCancelError.pushKey(L_); pushed.emplace(1); } // propagate pushed boolean if any return pushed.value(); }; - return Linda::ProtectedCall(L, limit); + return Linda::ProtectedCall(L_, limit); } // ################################################################################################# @@ -691,10 +691,10 @@ LUAG_FUNC(linda_limit) */ LUAG_FUNC(linda_cancel) { - Linda* const linda{ ToLinda(L, 1) }; - char const* who = luaL_optstring(L, 2, "both"); + Linda* const linda{ ToLinda(L_, 1) }; + char const* who = luaL_optstring(L_, 2, "both"); // make sure we got 3 arguments: the linda, a key and a limit - luaL_argcheck(L, lua_gettop(L) <= 2, 2, "wrong number of arguments"); + luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); linda->simulate_cancel = CancelRequest::Soft; if (strcmp(who, "both") == 0) // tell everyone writers to wake up @@ -716,7 +716,7 @@ LUAG_FUNC(linda_cancel) } else { - raise_luaL_error(L, "unknown wake hint '%s'", who); + raise_luaL_error(L_, "unknown wake hint '%s'", who); } return 0; } @@ -735,8 +735,8 @@ LUAG_FUNC(linda_cancel) */ LUAG_FUNC(linda_deep) { - Linda* const linda{ ToLinda(L, 1) }; - lua_pushlightuserdata(L, linda); // just the address + Linda* const linda{ ToLinda(L_, 1) }; + lua_pushlightuserdata(L_, linda); // just the address return 1; } @@ -751,9 +751,9 @@ LUAG_FUNC(linda_deep) */ template -[[nodiscard]] static int LindaToString(lua_State* L, int idx_) +[[nodiscard]] static int LindaToString(lua_State* L_, int idx_) { - Linda* const linda{ ToLinda(L, idx_) }; + Linda* const linda{ ToLinda(L_, idx_) }; if (linda != nullptr) { char text[128]; @@ -762,7 +762,7 @@ template len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName()); else len = sprintf(text, "Linda: %p", linda); - lua_pushlstring(L, text, len); + lua_pushlstring(L_, text, len); return 1; } return 0; @@ -770,7 +770,7 @@ template LUAG_FUNC(linda_tostring) { - return LindaToString(L, 1); + return LindaToString(L_, 1); } // ################################################################################################# @@ -786,21 +786,21 @@ LUAG_FUNC(linda_concat) { // linda1? linda2? bool atLeastOneLinda{ false }; // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. - if (LindaToString(L, 1)) + if (LindaToString(L_, 1)) { atLeastOneLinda = true; - lua_replace(L, 1); + lua_replace(L_, 1); } - if (LindaToString(L, 2)) + if (LindaToString(L_, 2)) { atLeastOneLinda = true; - lua_replace(L, 2); + lua_replace(L_, 2); } if (!atLeastOneLinda) // should not be possible { - raise_luaL_error(L, "internal error: linda_concat called on non-Linda"); + raise_luaL_error(L_, "internal error: linda_concat called on non-Linda"); } - lua_concat(L, 2); + lua_concat(L_, 2); return 1; } @@ -812,12 +812,12 @@ LUAG_FUNC(linda_concat) */ LUAG_FUNC(linda_dump) { - auto dump = [](lua_State* L) + auto dump = [](lua_State* L_) { - Linda* const linda{ ToLinda(L, 1) }; - return keeper_push_linda_storage(*linda, DestState{ L }); + Linda* const linda{ ToLinda(L_, 1) }; + return keeper_push_linda_storage(*linda, DestState{ L_ }); }; - return Linda::ProtectedCall(L, dump); + return Linda::ProtectedCall(L_, dump); } // ################################################################################################# @@ -828,12 +828,12 @@ LUAG_FUNC(linda_dump) */ LUAG_FUNC(linda_towatch) { - Linda* const linda{ ToLinda(L, 1) }; - int pushed{ keeper_push_linda_storage(*linda, DestState{ L }) }; + Linda* const linda{ ToLinda(L_, 1) }; + int pushed{ keeper_push_linda_storage(*linda, DestState{ L_ }) }; if (pushed == 0) { // if the linda is empty, don't return nil - pushed = LindaToString(L, 1); + pushed = LindaToString(L_, 1); } return pushed; } @@ -870,17 +870,17 @@ namespace global { */ LUAG_FUNC(linda) { - int const top{ lua_gettop(L) }; - luaL_argcheck(L, top <= 2, top, "too many arguments"); + int const top{ lua_gettop(L_) }; + luaL_argcheck(L_, top <= 2, top, "too many arguments"); if (top == 1) { - LuaType const t{ lua_type_as_enum(L, 1) }; - luaL_argcheck(L, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); + LuaType const t{ lua_type_as_enum(L_, 1) }; + luaL_argcheck(L_, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); } else if (top == 2) { - luaL_checktype(L, 1, LUA_TSTRING); - luaL_checktype(L, 2, LUA_TNUMBER); + luaL_checktype(L_, 1, LUA_TSTRING); + luaL_checktype(L_, 2, LUA_TNUMBER); } - return LindaFactory::Instance.pushDeepUserdata(DestState{ L }, 0); + return LindaFactory::Instance.pushDeepUserdata(DestState{ L_ }, 0); } diff --git a/src/linda.h b/src/linda.h index dbf48b3..7a21571 100644 --- a/src/linda.h +++ b/src/linda.h @@ -59,7 +59,7 @@ class Linda Linda& operator=(Linda const&) = delete; Linda& operator=(Linda const&&) = delete; - [[nodiscard]] static int ProtectedCall(lua_State* L, lua_CFunction f_); + [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); private: void setName(char const* name_, size_t len_); diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp index 81e472d..3ee0ba4 100644 --- a/src/lindafactory.cpp +++ b/src/lindafactory.cpp @@ -49,7 +49,7 @@ void LindaFactory::createMetatable(lua_State* L_) const lua_setfield(L_, -2, "__metatable"); // the linda functions - luaL_setfuncs(L_, mLindaMT, 0); + luaG_registerlibfuncs(L_, mLindaMT); // some constants kLindaBatched.pushKey(L_); diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index be331a1..dfde550 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -49,6 +49,7 @@ template // ################################################################################################# +#if LUA_VERSION_NUM >= 504 // use this instead of Lua's luaL_typeerror template [[noreturn]] static inline void raise_luaL_typeerror(lua_State* L_, int arg_, char const* tname_) @@ -56,6 +57,7 @@ template std::ignore = luaL_typeerror(L_, arg_, tname_); // doesn't return assert(false); // we should never get here, but i'm paranoid } +#endif // LUA_VERSION_NUM // ################################################################################################# @@ -182,42 +184,42 @@ class StackChecker // ################################################################################################# -inline void STACK_GROW(lua_State* L, int n_) +inline void STACK_GROW(lua_State* L_, int n_) { - if (!lua_checkstack(L, n_)) { - raise_luaL_error(L, "Cannot grow stack!"); + if (!lua_checkstack(L_, n_)) { + raise_luaL_error(L_, "Cannot grow stack!"); } } // ################################################################################################# -#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L) +#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L_) // ################################################################################################# // a small helper to extract a full userdata pointer from the stack in a safe way template -[[nodiscard]] T* lua_tofulluserdata(lua_State* L, int index_) +[[nodiscard]] T* lua_tofulluserdata(lua_State* L_, int index_) { - LUA_ASSERT(L, lua_isnil(L, index_) || lua_type(L, index_) == LUA_TUSERDATA); - return static_cast(lua_touserdata(L, index_)); + LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_type(L_, index_) == LUA_TUSERDATA); + return static_cast(lua_touserdata(L_, index_)); } template -[[nodiscard]] auto lua_tolightuserdata(lua_State* L, int index_) +[[nodiscard]] auto lua_tolightuserdata(lua_State* L_, int index_) { - LUA_ASSERT(L, lua_isnil(L, index_) || lua_islightuserdata(L, index_)); + LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_islightuserdata(L_, index_)); if constexpr (std::is_pointer_v) { - return static_cast(lua_touserdata(L, index_)); + return static_cast(lua_touserdata(L_, index_)); } else { - return static_cast(lua_touserdata(L, index_)); + return static_cast(lua_touserdata(L_, index_)); } } template -[[nodiscard]] T* lua_newuserdatauv(lua_State* L, int nuvalue_) +[[nodiscard]] T* lua_newuserdatauv(lua_State* L_, int nuvalue_) { - return static_cast(lua_newuserdatauv(L, sizeof(T), nuvalue_)); + return static_cast(lua_newuserdatauv(L_, sizeof(T), nuvalue_)); } // ################################################################################################# diff --git a/src/state.cpp b/src/state.cpp index 9898812..d6dfb89 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -49,34 +49,34 @@ THE SOFTWARE. // // Upvalues: [1]: original 'require' function // -[[nodiscard]] static int luaG_new_require(lua_State* L) +[[nodiscard]] static int luaG_new_require(lua_State* L_) { int rc; - int const args = lua_gettop( L); // args - Universe* U = universe_get( L); + int const args = lua_gettop( L_); // args + Universe* U = universe_get( L_); //char const* modname = luaL_checkstring( L, 1); - STACK_GROW( L, 1); + STACK_GROW( L_, 1); - lua_pushvalue( L, lua_upvalueindex( 1)); // args require - lua_insert( L, 1); // require args + lua_pushvalue( L_, lua_upvalueindex( 1)); // args require + lua_insert( L_, 1); // require args // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would // leave us locked, blocking any future 'require' calls from other lanes. U->require_cs.lock(); // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET - rc = lua_pcall( L, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s) + rc = lua_pcall( L_, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s) U->require_cs.unlock(); // the required module (or an error message) is left on the stack as returned value by original require function if (rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ? { - raise_lua_error(L); + raise_lua_error(L_); } // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 - return lua_gettop(L); // result(s) + return lua_gettop(L_); // result(s) } // ################################################################################################# @@ -84,38 +84,38 @@ THE SOFTWARE. /* * Serialize calls to 'require', if it exists */ -void serialize_require(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) +void serialize_require(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L_) { - STACK_GROW(L, 1); - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 1); + STACK_CHECK_START_REL(L_, 0); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); // Check 'require' is there and not already wrapped; if not, do nothing // - lua_getglobal(L, "require"); - if (lua_isfunction(L, -1) && lua_tocfunction(L, -1) != luaG_new_require) + lua_getglobal(L_, "require"); + if (lua_isfunction(L_, -1) && lua_tocfunction(L_, -1) != luaG_new_require) { // [-1]: original 'require' function - lua_pushcclosure(L, luaG_new_require, 1 /*upvalues*/); - lua_setglobal(L, "require"); + lua_pushcclosure(L_, luaG_new_require, 1 /*upvalues*/); + lua_setglobal(L_, "require"); } else { // [-1]: nil - lua_pop(L, 1); + lua_pop(L_, 1); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); } // ################################################################################################# /*---=== luaG_newstate ===---*/ -[[nodiscard]] static int require_lanes_core(lua_State* L) +[[nodiscard]] static int require_lanes_core(lua_State* L_) { // leaves a copy of 'lanes.core' module table on the stack - luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); + luaL_requiref( L_, "lanes.core", luaopen_lanes_core, 0); return 1; } @@ -159,7 +159,7 @@ static luaL_Reg const libs[] = // ################################################################################################# -static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, char const* name_, size_t len_) +static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, char const* name_, size_t len_) { for (int i{ 0 }; libs[i].name; ++i) { @@ -171,16 +171,16 @@ static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, char const { bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) - luaL_requiref( L, name_, libfunc, !isLanesCore); + luaL_requiref( L_, name_, libfunc, !isLanesCore); // lanes.core doesn't declare a global, so scan it here and now if (isLanesCore == true) { - populate_func_lookup_table( L, -1, name_); + populate_func_lookup_table( L_, -1, name_); } - lua_pop( L, 1); - STACK_CHECK( L, 0); + lua_pop( L_, 1); + STACK_CHECK( L_, 0); } break; } @@ -208,33 +208,33 @@ static void copy_one_time_settings(Universe* U, SourceState L1, DestState L2) raise_luaL_error(L1, "failed to copy settings when loading lanes.core"); } // set L2:_R[kConfigRegKey] = settings - kConfigRegKey.setValue(L2, [](lua_State* L) { lua_insert(L, -2); }); // config + kConfigRegKey.setValue(L2, [](lua_State* L_) { lua_insert(L_, -2); }); // config STACK_CHECK(L2, 0); STACK_CHECK(L1, 0); } // ################################################################################################# -void initialize_on_state_create( Universe* U, lua_State* L) +void initialize_on_state_create( Universe* U, lua_State* L_) { - STACK_CHECK_START_REL(L, 1); // settings - lua_getfield(L, -1, "on_state_create"); // settings on_state_create|nil - if (!lua_isnil(L, -1)) + STACK_CHECK_START_REL(L_, 1); // settings + lua_getfield(L_, -1, "on_state_create"); // settings on_state_create|nil + if (!lua_isnil(L_, -1)) { // store C function pointer in an internal variable - U->on_state_create_func = lua_tocfunction(L, -1); // settings on_state_create + U->on_state_create_func = lua_tocfunction(L_, -1); // settings on_state_create if (U->on_state_create_func != nullptr) { // make sure the function doesn't have upvalues - char const* upname = lua_getupvalue(L, -1, 1); // settings on_state_create upval? + char const* upname = lua_getupvalue(L_, -1, 1); // settings on_state_create upval? if (upname != nullptr) // should be "" for C functions with upvalues if any { - raise_luaL_error(L, "on_state_create shouldn't have upvalues"); + raise_luaL_error(L_, "on_state_create shouldn't have upvalues"); } // remove this C function from the config table so that it doesn't cause problems // when we transfer the config table in newly created Lua states - lua_pushnil(L); // settings on_state_create nil - lua_setfield(L, -3, "on_state_create"); // settings on_state_create + lua_pushnil(L_); // settings on_state_create nil + lua_setfield(L_, -3, "on_state_create"); // settings on_state_create } else { @@ -242,8 +242,8 @@ void initialize_on_state_create( Universe* U, lua_State* L) U->on_state_create_func = (lua_CFunction) initialize_on_state_create; } } - lua_pop(L, 1); // settings - STACK_CHECK(L, 1); + lua_pop(L_, 1); // settings + STACK_CHECK(L_, 1); } // ################################################################################################# @@ -281,16 +281,16 @@ lua_State* create_state(Universe* U, lua_State* from_) // ################################################################################################# -void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMode mode_) +void call_on_state_create(Universe* U, lua_State* L_, lua_State* from_, LookupMode mode_) { if (U->on_state_create_func != nullptr) { - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); if (U->on_state_create_func != (lua_CFunction) initialize_on_state_create) { // C function: recreate a closure in the new state, bypassing the lookup scheme - lua_pushcfunction(L, U->on_state_create_func); // on_state_create() + lua_pushcfunction(L_, U->on_state_create_func); // on_state_create() } else // Lua function located in the config table, copied when we opened "lanes.core" { @@ -298,21 +298,21 @@ void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMod { // if attempting to call in a keeper state, do nothing because the function doesn't exist there // this doesn't count as an error though - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); return; } - kConfigRegKey.pushValue(L); // {} - STACK_CHECK(L, 1); - lua_getfield(L, -1, "on_state_create"); // {} on_state_create() - lua_remove(L, -2); // on_state_create() + kConfigRegKey.pushValue(L_); // {} + STACK_CHECK(L_, 1); + lua_getfield(L_, -1, "on_state_create"); // {} on_state_create() + lua_remove(L_, -2); // on_state_create() } - STACK_CHECK(L, 1); + STACK_CHECK(L_, 1); // capture error and raise it in caller state - if (lua_pcall(L, 0, 0, 0) != LUA_OK) + if (lua_pcall(L_, 0, 0, 0) != LUA_OK) { - raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L, -1) ? lua_tostring(L, -1) : lua_typename(L, lua_type(L, -1))); + raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L_, -1) ? lua_tostring(L_, -1) : lua_typename(L_, lua_type(L_, -1))); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); } } @@ -344,7 +344,7 @@ lua_State* luaG_newstate(Universe* U, SourceState from_, char const* libs_) STACK_CHECK(L, 0); // we'll need this every time we transfer some C function from/to this state - kLookupRegKey.setValue(L, [](lua_State* L) { lua_newtable(L); }); + kLookupRegKey.setValue(L, [](lua_State* L_) { lua_newtable(L_); }); STACK_CHECK(L, 0); // neither libs (not even 'base') nor special init func: we are done diff --git a/src/state.h b/src/state.h index 2d65f16..9e43b41 100644 --- a/src/state.h +++ b/src/state.h @@ -6,7 +6,7 @@ enum class LookupMode; class Universe; -void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); +void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_); // ################################################################################################# @@ -15,5 +15,5 @@ void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); // ################################################################################################# -void initialize_on_state_create(Universe* U, lua_State* L); -void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMode mode_); +void initialize_on_state_create(Universe* U, lua_State* L_); +void call_on_state_create(Universe* U, lua_State* L_, lua_State* from_, LookupMode mode_); diff --git a/src/tools.cpp b/src/tools.cpp index 2497ba7..e11cad5 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -45,34 +45,34 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; /* * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it */ -void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const char* mode_) +void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_) { - STACK_GROW(L, 3); - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 3); + STACK_CHECK_START_REL(L_, 0); - key_.pushValue(L); // {}|nil - STACK_CHECK(L, 1); + key_.pushValue(L_); // {}|nil + STACK_CHECK(L_, 1); - if (lua_isnil(L, -1)) + if (lua_isnil(L_, -1)) { - lua_pop(L, 1); // - lua_newtable(L); // {} + lua_pop(L_, 1); // + lua_newtable(L_); // {} // _R[key_] = {} - key_.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // {} - STACK_CHECK(L, 1); + key_.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // {} + STACK_CHECK(L_, 1); // Set its metatable if requested if (mode_) { - lua_newtable(L); // {} mt - lua_pushliteral(L, "__mode"); // {} mt "__mode" - lua_pushstring(L, mode_); // {} mt "__mode" mode - lua_rawset(L, -3); // {} mt - lua_setmetatable(L, -2); // {} + lua_newtable(L_); // {} mt + lua_pushliteral(L_, "__mode"); // {} mt "__mode" + lua_pushstring(L_, mode_); // {} mt "__mode" mode + lua_rawset(L_, -3); // {} mt + lua_setmetatable(L_, -2); // {} } } - STACK_CHECK(L, 1); - LUA_ASSERT(L, lua_istable(L, -1)); + STACK_CHECK(L_, 1); + LUA_ASSERT(L_, lua_istable(L_, -1)); } // ################################################################################################# @@ -81,9 +81,9 @@ void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const cha * Push a registry subtable (keyed by unique 'key_') onto the stack. * If the subtable does not exist, it is created and chained. */ -void push_registry_subtable(lua_State* L, RegistryUniqueKey key_) +void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_) { - push_registry_subtable_mode(L, key_, nullptr); + push_registry_subtable_mode(L_, key_, nullptr); } // ################################################################################################# @@ -104,11 +104,11 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, // ################################################################################################# -[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L) +[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) { - Universe* const U{ universe_get(L) }; + Universe* const U{ universe_get(L_) }; // push a new full userdata on the stack, giving access to the universe's protected allocator - [[maybe_unused]] AllocatorDefinition* const def{ new (L) AllocatorDefinition{ U->protected_allocator.makeDefinition() } }; + [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ U->protected_allocator.makeDefinition() } }; return 1; } @@ -116,33 +116,33 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, // called once at the creation of the universe (therefore L is the master Lua state everything originates from) // Do I need to disable this when compiling for LuaJIT to prevent issues? -void initialize_allocator_function(Universe* U, lua_State* L) +void initialize_allocator_function(Universe* U, lua_State* L_) { - STACK_CHECK_START_REL(L, 1); // settings - lua_getfield(L, -1, "allocator"); // settings allocator|nil|"protected" - if (!lua_isnil(L, -1)) + STACK_CHECK_START_REL(L_, 1); // settings + lua_getfield(L_, -1, "allocator"); // settings allocator|nil|"protected" + if (!lua_isnil(L_, -1)) { // store C function pointer in an internal variable - U->provide_allocator = lua_tocfunction(L, -1); // settings allocator + U->provide_allocator = lua_tocfunction(L_, -1); // settings allocator if (U->provide_allocator != nullptr) { // make sure the function doesn't have upvalues - char const* upname = lua_getupvalue(L, -1, 1); // settings allocator upval? + char const* upname = lua_getupvalue(L_, -1, 1); // settings allocator upval? if (upname != nullptr) // should be "" for C functions with upvalues if any { - raise_luaL_error(L, "config.allocator() shouldn't have upvalues"); + raise_luaL_error(L_, "config.allocator() shouldn't have upvalues"); } // remove this C function from the config table so that it doesn't cause problems // when we transfer the config table in newly created Lua states - lua_pushnil(L); // settings allocator nil - lua_setfield(L, -3, "allocator"); // settings allocator + lua_pushnil(L_); // settings allocator nil + lua_setfield(L_, -3, "allocator"); // settings allocator } - else if (lua_type(L, -1) == LUA_TSTRING) // should be "protected" + else if (lua_type(L_, -1) == LUA_TSTRING) // should be "protected" { - LUA_ASSERT(L, strcmp(lua_tostring(L, -1), "protected") == 0); + LUA_ASSERT(L_, strcmp(lua_tostring(L_, -1), "protected") == 0); // set the original allocator to call from inside protection by the mutex - U->protected_allocator.initFrom(L); - U->protected_allocator.installIn(L); + U->protected_allocator.initFrom(L_); + U->protected_allocator.installIn(L_); // before a state is created, this function will be called to obtain the allocator U->provide_allocator = luaG_provide_protected_allocator; } @@ -150,14 +150,14 @@ void initialize_allocator_function(Universe* U, lua_State* L) else { // just grab whatever allocator was provided to lua_newstate - U->protected_allocator.initFrom(L); + U->protected_allocator.initFrom(L_); } - lua_pop(L, 1); // settings - STACK_CHECK(L, 1); + lua_pop(L_, 1); // settings + STACK_CHECK(L_, 1); - lua_getfield(L, -1, "internal_allocator"); // settings "libc"|"allocator" + lua_getfield(L_, -1, "internal_allocator"); // settings "libc"|"allocator" { - char const* allocator = lua_tostring(L, -1); + char const* allocator = lua_tostring(L_, -1); if (strcmp(allocator, "libc") == 0) { U->internal_allocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; @@ -173,15 +173,14 @@ void initialize_allocator_function(Universe* U, lua_State* L) U->internal_allocator = U->protected_allocator; } } - lua_pop(L, 1); // settings - STACK_CHECK(L, 1); + lua_pop(L_, 1); // settings + STACK_CHECK(L_, 1); } // ################################################################################################# -[[nodiscard]] static int dummy_writer(lua_State* L, void const* p, size_t sz, void* ud) +[[nodiscard]] static int dummy_writer([[maybe_unused]] lua_State* L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) { - (void)L; (void)p; (void)sz; (void) ud; // unused return 666; } @@ -207,24 +206,24 @@ enum class FuncSubType FastJIT } ; -FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) +FuncSubType luaG_getfuncsubtype(lua_State* L_, int _i) { - if (lua_tocfunction(L, _i)) // nullptr for LuaJIT-fast && bytecode functions + if (lua_tocfunction(L_, _i)) // nullptr for LuaJIT-fast && bytecode functions { return FuncSubType::Native; } { int mustpush{ 0 }; - if (lua_absindex(L, _i) != lua_gettop(L)) + if (lua_absindex(L_, _i) != lua_gettop(L_)) { - lua_pushvalue(L, _i); + lua_pushvalue(L_, _i); mustpush = 1; } // the provided writer fails with code 666 // therefore, anytime we get 666, this means that lua_dump() attempted a dump // all other cases mean this is either a C or LuaJIT-fast function - int const dumpres{ lua504_dump(L, dummy_writer, nullptr, 0) }; - lua_pop(L, mustpush); + int const dumpres{ lua504_dump(L_, dummy_writer, nullptr, 0) }; + lua_pop(L_, mustpush); if (dumpres == 666) { return FuncSubType::Bytecode; @@ -236,28 +235,28 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) // ################################################################################################# // inspired from tconcat() in ltablib.c -[[nodiscard]] static char const* luaG_pushFQN(lua_State* L, int t, int last, size_t* length) +[[nodiscard]] static char const* luaG_pushFQN(lua_State* L_, int t, int last, size_t* length) { luaL_Buffer b; - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... - luaL_buffinit(L, &b); // ... {} ... &b? + luaL_buffinit(L_, &b); // ... {} ... &b? int i = 1; for (; i < last; ++i) { - lua_rawgeti( L, t, i); + lua_rawgeti( L_, t, i); luaL_addvalue( &b); luaL_addlstring(&b, "/", 1); } if (i == last) // add last value (if interval was not empty) { - lua_rawgeti(L, t, i); + lua_rawgeti(L_, t, i); luaL_addvalue(&b); } // &b is popped at that point (-> replaced by the result) luaL_pushresult(&b); // ... {} ... "" - STACK_CHECK(L, 1); - return lua_tolstring( L, -1, length); + STACK_CHECK(L_, 1); + return lua_tolstring( L_, -1, length); } // ################################################################################################# @@ -270,7 +269,7 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) * if we already had an entry of type [o] = ..., replace the name if the new one is shorter * pops the processed object from the stack */ -static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _depth) +static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _depth) { // slot 1 in the stack contains the table that receives everything we found int const dest{ _ctx_base }; @@ -283,18 +282,18 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - STACK_CHECK_START_REL(L, 0); + STACK_CHECK_START_REL(L_, 0); // first, raise an error if the function is already known - lua_pushvalue(L, -1); // ... {bfc} k o o - lua_rawget(L, dest); // ... {bfc} k o name? - prevName = lua_tolstring( L, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) + lua_pushvalue(L_, -1); // ... {bfc} k o o + lua_rawget(L_, dest); // ... {bfc} k o name? + prevName = lua_tolstring( L_, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) // push name in fqn stack (note that concatenation will crash if name is a not string or a number) - lua_pushvalue(L, -3); // ... {bfc} k o name? k - LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER || lua_type(L, -1) == LUA_TSTRING); + lua_pushvalue(L_, -3); // ... {bfc} k o name? k + LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING); ++_depth; - lua_rawseti(L, fqn, _depth); // ... {bfc} k o name? + lua_rawseti(L_, fqn, _depth); // ... {bfc} k o name? // generate name - DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n" + DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n" // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order // on different VMs even when the tables are populated the exact same way. // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), @@ -304,11 +303,11 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, // Also, nothing prevents any external module from exposing a given object under several names, so... // Therefore, when we encounter an object for which a name was previously registered, we need to select the names // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded - if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L, -2, -1))) + if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L_, -2, -1))) { DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName)); // the previous name is 'smaller' than the one we just generated: keep it! - lua_pop(L, 3); // ... {bfc} k + lua_pop(L_, 3); // ... {bfc} k } else { @@ -316,63 +315,63 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, if (prevName) { // clear the previous name for the database to avoid clutter - lua_insert(L, -2); // ... {bfc} k o "f.q.n" prevName + lua_insert(L_, -2); // ... {bfc} k o "f.q.n" prevName // t[prevName] = nil - lua_pushnil(L); // ... {bfc} k o "f.q.n" prevName nil - lua_rawset(L, dest); // ... {bfc} k o "f.q.n" + lua_pushnil(L_); // ... {bfc} k o "f.q.n" prevName nil + lua_rawset(L_, dest); // ... {bfc} k o "f.q.n" } else { - lua_remove(L, -2); // ... {bfc} k o "f.q.n" + lua_remove(L_, -2); // ... {bfc} k o "f.q.n" } DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename(L, lua_type( L, -2)), newName)); // prepare the stack for database feed - lua_pushvalue(L, -1); // ... {bfc} k o "f.q.n" "f.q.n" - lua_pushvalue(L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o - LUA_ASSERT(L, lua_rawequal(L, -1, -4)); - LUA_ASSERT(L, lua_rawequal(L, -2, -3)); + lua_pushvalue(L_, -1); // ... {bfc} k o "f.q.n" "f.q.n" + lua_pushvalue(L_, -3); // ... {bfc} k o "f.q.n" "f.q.n" o + LUA_ASSERT(L_, lua_rawequal(L_, -1, -4)); + LUA_ASSERT(L_, lua_rawequal(L_, -2, -3)); // t["f.q.n"] = o - lua_rawset(L, dest); // ... {bfc} k o "f.q.n" + lua_rawset(L_, dest); // ... {bfc} k o "f.q.n" // t[o] = "f.q.n" - lua_rawset(L, dest); // ... {bfc} k + lua_rawset(L_, dest); // ... {bfc} k // remove table name from fqn stack - lua_pushnil(L); // ... {bfc} k nil - lua_rawseti(L, fqn, _depth); // ... {bfc} k + lua_pushnil(L_); // ... {bfc} k nil + lua_rawseti(L_, fqn, _depth); // ... {bfc} k } -- _depth; - STACK_CHECK(L, -1); + STACK_CHECK(L_, -1); } // ################################################################################################# -static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) +static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _i, int _depth) { // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i int const fqn = _ctx_base + 1; // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops int const cache = _ctx_base + 2; // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) - int const breadth_first_cache = lua_gettop(L) + 1; + int const breadth_first_cache = lua_gettop(L_) + 1; DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - STACK_GROW(L, 6); + STACK_GROW(L_, 6); // slot _i contains a table where we search for functions (or a full userdata with a metatable) - STACK_CHECK_START_REL(L, 0); // ... {_i} + STACK_CHECK_START_REL(L_, 0); // ... {_i} // if object is a userdata, replace it by its metatable - if (lua_type(L, _i) == LUA_TUSERDATA) + if (lua_type(L_, _i) == LUA_TUSERDATA) { - lua_getmetatable(L, _i); // ... {_i} mt - lua_replace(L, _i); // ... {_i} + lua_getmetatable(L_, _i); // ... {_i} mt + lua_replace(L_, _i); // ... {_i} } // if table is already visited, we are done - lua_pushvalue(L, _i); // ... {_i} {} - lua_rawget(L, cache); // ... {_i} nil|n - lua_Integer visit_count{ lua_tointeger(L, -1) }; // 0 if nil, else n - lua_pop(L, 1); // ... {_i} - STACK_CHECK(L, 0); + lua_pushvalue(L_, _i); // ... {_i} {} + lua_rawget(L_, cache); // ... {_i} nil|n + lua_Integer visit_count{ lua_tointeger(L_, -1) }; // 0 if nil, else n + lua_pop(L_, 1); // ... {_i} + STACK_CHECK(L_, 0); if (visit_count > 0) { DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); @@ -380,88 +379,88 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) } // remember we visited this table (1-visit count) - lua_pushvalue(L, _i); // ... {_i} {} - lua_pushinteger(L, visit_count + 1); // ... {_i} {} 1 - lua_rawset(L, cache); // ... {_i} - STACK_CHECK(L, 0); + lua_pushvalue(L_, _i); // ... {_i} {} + lua_pushinteger(L_, visit_count + 1); // ... {_i} {} 1 + lua_rawset(L_, cache); // ... {_i} + STACK_CHECK(L_, 0); // this table is at breadth_first_cache index - lua_newtable(L); // ... {_i} {bfc} - LUA_ASSERT(L, lua_gettop(L) == breadth_first_cache); + lua_newtable(L_); // ... {_i} {bfc} + LUA_ASSERT(L_, lua_gettop(L_) == breadth_first_cache); // iterate over all entries in the processed table - lua_pushnil(L); // ... {_i} {bfc} nil - while( lua_next(L, _i) != 0) // ... {_i} {bfc} k v + lua_pushnil(L_); // ... {_i} {bfc} nil + while( lua_next(L_, _i) != 0) // ... {_i} {bfc} k v { // just for debug, not actually needed //char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"; // subtable: process it recursively - if (lua_istable(L, -1)) // ... {_i} {bfc} k {} + if (lua_istable(L_, -1)) // ... {_i} {bfc} k {} { // increment visit count to make sure we will actually scan it at this recursive level - lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} - lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} {} - lua_rawget(L, cache); // ... {_i} {bfc} k {} {} n? - visit_count = lua_tointeger(L, -1) + 1; // 1 if we got nil, else n+1 - lua_pop(L, 1); // ... {_i} {bfc} k {} {} - lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n - lua_rawset(L, cache); // ... {_i} {bfc} k {} + lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} + lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} {} + lua_rawget(L_, cache); // ... {_i} {bfc} k {} {} n? + visit_count = lua_tointeger(L_, -1) + 1; // 1 if we got nil, else n+1 + lua_pop(L_, 1); // ... {_i} {bfc} k {} {} + lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n + lua_rawset(L_, cache); // ... {_i} {bfc} k {} // store the table in the breadth-first cache - lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k - lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k {} - lua_rawset(L, breadth_first_cache); // ... {_i} {bfc} k {} + lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k + lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k {} + lua_rawset(L_, breadth_first_cache); // ... {_i} {bfc} k {} // generate a name, and if we already had one name, keep whichever is the shorter - update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k + update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k } - else if (lua_isfunction(L, -1) && (luaG_getfuncsubtype(L, -1) != FuncSubType::Bytecode)) + else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, -1) != FuncSubType::Bytecode)) { // generate a name, and if we already had one name, keep whichever is the shorter // this pops the function from the stack - update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k + update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k } else { - lua_pop(L, 1); // ... {_i} {bfc} k + lua_pop(L_, 1); // ... {_i} {bfc} k } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); } // now process the tables we encountered at that depth ++ _depth; - lua_pushnil(L); // ... {_i} {bfc} nil - while (lua_next(L, breadth_first_cache) != 0) // ... {_i} {bfc} k {} + lua_pushnil(L_); // ... {_i} {bfc} nil + while (lua_next(L_, breadth_first_cache) != 0) // ... {_i} {bfc} k {} { DEBUGSPEW_CODE(char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"); DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); // un-visit this table in case we do need to process it - lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} - lua_rawget(L, cache); // ... {_i} {bfc} k {} n - LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER); - visit_count = lua_tointeger(L, -1) - 1; - lua_pop(L, 1); // ... {_i} {bfc} k {} - lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} + lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} + lua_rawget(L_, cache); // ... {_i} {bfc} k {} n + LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER); + visit_count = lua_tointeger(L_, -1) - 1; + lua_pop(L_, 1); // ... {_i} {bfc} k {} + lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} if (visit_count > 0) { - lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n + lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n } else { - lua_pushnil(L); // ... {_i} {bfc} k {} {} nil + lua_pushnil(L_); // ... {_i} {bfc} k {} {} nil } - lua_rawset(L, cache); // ... {_i} {bfc} k {} + lua_rawset(L_, cache); // ... {_i} {bfc} k {} // push table name in fqn stack (note that concatenation will crash if name is a not string!) - lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k - lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} k {} - populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, lua_gettop(L), _depth); - lua_pop(L, 1); // ... {_i} {bfc} k - STACK_CHECK(L, 2); + lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k + lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc} k {} + populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, lua_gettop(L_), _depth); + lua_pop(L_, 1); // ... {_i} {bfc} k + STACK_CHECK(L_, 2); } // remove table name from fqn stack - lua_pushnil(L); // ... {_i} {bfc} nil - lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} + lua_pushnil(L_); // ... {_i} {bfc} nil + lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc} -- _depth; // we are done with our cache - lua_pop(L, 1); // ... {_i} - STACK_CHECK(L, 0); + lua_pop(L_, 1); // ... {_i} + STACK_CHECK(L_, 0); // we are done // ... {_i} {bfc} } @@ -470,64 +469,64 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) /* * create a "fully.qualified.name" <-> function equivalence database */ -void populate_func_lookup_table(lua_State* L, int i_, char const* name_) +void populate_func_lookup_table(lua_State* L_, int i_, char const* name_) { - int const ctx_base = lua_gettop(L) + 1; - int const in_base = lua_absindex(L, i_); + int const ctx_base = lua_gettop(L_) + 1; + int const in_base = lua_absindex(L_, i_); int start_depth = 0; DEBUGSPEW_CODE(Universe* U = universe_get(L)); DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); - STACK_GROW(L, 3); - STACK_CHECK_START_REL(L, 0); - kLookupRegKey.pushValue(L); // {} - STACK_CHECK(L, 1); - LUA_ASSERT(L, lua_istable(L, -1)); - if (lua_type(L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function + STACK_GROW(L_, 3); + STACK_CHECK_START_REL(L_, 0); + kLookupRegKey.pushValue(L_); // {} + STACK_CHECK(L_, 1); + LUA_ASSERT(L_, lua_istable(L_, -1)); + if (lua_type(L_, in_base) == LUA_TFUNCTION) // for example when a module is a simple function { name_ = name_ ? name_ : "nullptr"; - lua_pushvalue(L, in_base); // {} f - lua_pushstring(L, name_); // {} f _name - lua_rawset(L, -3); // {} - lua_pushstring(L, name_); // {} _name - lua_pushvalue(L, in_base); // {} _name f - lua_rawset(L, -3); // {} - lua_pop(L, 1); // + lua_pushvalue(L_, in_base); // {} f + lua_pushstring(L_, name_); // {} f _name + lua_rawset(L_, -3); // {} + lua_pushstring(L_, name_); // {} _name + lua_pushvalue(L_, in_base); // {} _name f + lua_rawset(L_, -3); // {} + lua_pop(L_, 1); // } - else if (lua_type(L, in_base) == LUA_TTABLE) + else if (lua_type(L_, in_base) == LUA_TTABLE) { - lua_newtable(L); // {} {fqn} + lua_newtable(L_); // {} {fqn} if (name_) { - STACK_CHECK(L, 2); - lua_pushstring(L, name_); // {} {fqn} "name" + STACK_CHECK(L_, 2); + lua_pushstring(L_, name_); // {} {fqn} "name" // generate a name, and if we already had one name, keep whichever is the shorter - lua_pushvalue(L, in_base); // {} {fqn} "name" t - update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, start_depth); // {} {fqn} "name" + lua_pushvalue(L_, in_base); // {} {fqn} "name" t + update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, start_depth); // {} {fqn} "name" // don't forget to store the name at the bottom of the fqn stack ++ start_depth; - lua_rawseti(L, -2, start_depth); // {} {fqn} - STACK_CHECK(L, 2); + lua_rawseti(L_, -2, start_depth); // {} {fqn} + STACK_CHECK(L_, 2); } // retrieve the cache, create it if we haven't done it yet - kLookupCacheRegKey.pushValue(L); // {} {fqn} {cache}? - if (lua_isnil(L, -1)) + kLookupCacheRegKey.pushValue(L_); // {} {fqn} {cache}? + if (lua_isnil(L_, -1)) { - lua_pop(L, 1); // {} {fqn} - lua_newtable(L); // {} {fqn} {cache} - kLookupCacheRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); - STACK_CHECK(L, 3); + lua_pop(L_, 1); // {} {fqn} + lua_newtable(L_); // {} {fqn} {cache} + kLookupCacheRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); + STACK_CHECK(L_, 3); } // process everything we find in that table, filling in lookup data for all functions and tables we see there - populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, in_base, start_depth); - lua_pop(L, 3); + populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, in_base, start_depth); + lua_pop(L_, 3); } else { - lua_pop(L, 1); // - raise_luaL_error(L, "unsupported module type %s", lua_typename(L, lua_type(L, in_base))); + lua_pop(L_, 1); // + raise_luaL_error(L_, "unsupported module type %s", lua_typename(L_, lua_type(L_, in_base))); } - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); } // ################################################################################################# @@ -540,36 +539,36 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; /* * Get a unique ID for metatable at [i]. */ -[[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L, int i) +[[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L_, int i) { - i = lua_absindex(L, i); + i = lua_absindex(L_, i); - STACK_GROW(L, 3); + STACK_GROW(L_, 3); - STACK_CHECK_START_REL(L, 0); - push_registry_subtable(L, kMtIdRegKey); // ... _R[kMtIdRegKey] - lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} - lua_rawget(L, -2); // ... _R[kMtIdRegKey] mtk? + STACK_CHECK_START_REL(L_, 0); + push_registry_subtable(L_, kMtIdRegKey); // ... _R[kMtIdRegKey] + lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt} + lua_rawget(L_, -2); // ... _R[kMtIdRegKey] mtk? - lua_Integer id{ lua_tointeger(L, -1) }; // 0 for nil - lua_pop(L, 1); // ... _R[kMtIdRegKey] - STACK_CHECK(L, 1); + lua_Integer id{ lua_tointeger(L_, -1) }; // 0 for nil + lua_pop(L_, 1); // ... _R[kMtIdRegKey] + STACK_CHECK(L_, 1); if (id == 0) { id = U->next_mt_id.fetch_add(1, std::memory_order_relaxed); // Create two-way references: id_uint <-> table - lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} - lua_pushinteger(L, id); // ... _R[kMtIdRegKey] {mt} id - lua_rawset(L, -3); // ... _R[kMtIdRegKey] + lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt} + lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] {mt} id + lua_rawset(L_, -3); // ... _R[kMtIdRegKey] - lua_pushinteger(L, id); // ... _R[kMtIdRegKey] id - lua_pushvalue(L, i); // ... _R[kMtIdRegKey] id {mt} - lua_rawset(L, -3); // ... _R[kMtIdRegKey] + lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] id + lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] id {mt} + lua_rawset(L_, -3); // ... _R[kMtIdRegKey] } - lua_pop(L, 1); // ... - STACK_CHECK(L, 0); + lua_pop(L_, 1); // ... + STACK_CHECK(L_, 0); return id; } @@ -577,25 +576,25 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; // ################################################################################################# // function sentinel used to transfer native functions from/to keeper states -[[nodiscard]] static int func_lookup_sentinel(lua_State* L) +[[nodiscard]] static int func_lookup_sentinel(lua_State* L_) { - raise_luaL_error(L, "function lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L_, "function lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); } // ################################################################################################# // function sentinel used to transfer native table from/to keeper states -[[nodiscard]] static int table_lookup_sentinel(lua_State* L) +[[nodiscard]] static int table_lookup_sentinel(lua_State* L_) { - raise_luaL_error(L, "table lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L_, "table lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); } // ################################################################################################# // function sentinel used to transfer cloned full userdata from/to keeper states -[[nodiscard]] static int userdata_clone_sentinel(lua_State* L) +[[nodiscard]] static int userdata_clone_sentinel(lua_State* L_) { - raise_luaL_error(L, "userdata clone sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L_, "userdata clone sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); } // ################################################################################################# @@ -603,55 +602,55 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; /* * retrieve the name of a function/table in the lookup database */ -[[nodiscard]] static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char const* upName_, size_t* len_) +[[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i, LookupMode mode_, char const* upName_, size_t* len_) { - DEBUGSPEW_CODE( Universe* const U = universe_get( L)); + DEBUGSPEW_CODE( Universe* const U = universe_get( L_)); char const* fqn; - LUA_ASSERT(L, lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... - STACK_CHECK_START_REL(L, 0); - STACK_GROW( L, 3); // up to 3 slots are necessary on error + LUA_ASSERT(L_, lua_isfunction( L_, i) || lua_istable( L_, i)); // ... v ... + STACK_CHECK_START_REL(L_, 0); + STACK_GROW( L_, 3); // up to 3 slots are necessary on error if (mode_ == LookupMode::FromKeeper) { - lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! + lua_CFunction f = lua_tocfunction( L_, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) { - lua_getupvalue( L, i, 1); // ... v ... "f.q.n" + lua_getupvalue( L_, i, 1); // ... v ... "f.q.n" } else { // if this is not a sentinel, this is some user-created table we wanted to lookup - LUA_ASSERT(L, nullptr == f && lua_istable(L, i)); + LUA_ASSERT(L_, nullptr == f && lua_istable(L_, i)); // push anything that will convert to nullptr string - lua_pushnil( L); // ... v ... nil + lua_pushnil( L_); // ... v ... nil } } else { // fetch the name from the source state's lookup table - kLookupRegKey.pushValue(L); // ... v ... {} - STACK_CHECK( L, 1); - LUA_ASSERT(L, lua_istable( L, -1)); - lua_pushvalue( L, i); // ... v ... {} v - lua_rawget( L, -2); // ... v ... {} "f.q.n" + kLookupRegKey.pushValue(L_); // ... v ... {} + STACK_CHECK( L_, 1); + LUA_ASSERT(L_, lua_istable( L_, -1)); + lua_pushvalue( L_, i); // ... v ... {} v + lua_rawget( L_, -2); // ... v ... {} "f.q.n" } - fqn = lua_tolstring( L, -1, len_); + fqn = lua_tolstring( L_, -1, len_); DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database - lua_pop( L, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... - STACK_CHECK( L, 0); - if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) + lua_pop( L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... + STACK_CHECK( L_, 0); + if (nullptr == fqn && !lua_istable(L_, i)) // raise an error if we try to send an unknown function (but not for tables) { char const *from, *typewhat, *what, *gotchaA, *gotchaB; // try to discover the name of the function we want to send - lua_getglobal( L, "decoda_name"); // ... v ... decoda_name - from = lua_tostring( L, -1); - lua_pushcfunction( L, luaG_nameof); // ... v ... decoda_name luaG_nameof - lua_pushvalue( L, i); // ... v ... decoda_name luaG_nameof t - lua_call( L, 1, 2); // ... v ... decoda_name "type" "name"|nil - typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2); + lua_getglobal( L_, "decoda_name"); // ... v ... decoda_name + from = lua_tostring( L_, -1); + lua_pushcfunction( L_, luaG_nameof); // ... v ... decoda_name luaG_nameof + lua_pushvalue( L_, i); // ... v ... decoda_name luaG_nameof t + lua_call( L_, 1, 2); // ... v ... decoda_name "type" "name"|nil + typewhat = (lua_type( L_, -2) == LUA_TSTRING) ? lua_tostring( L_, -2) : luaL_typename( L_, -2); // second return value can be nil if the table was not found // probable reason: the function was removed from the source Lua state before Lanes was required. - if (lua_isnil( L, -1)) + if (lua_isnil( L_, -1)) { gotchaA = " referenced by"; gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; @@ -661,13 +660,13 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; { gotchaA = ""; gotchaB = ""; - what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1); + what = (lua_type( L_, -1) == LUA_TSTRING) ? lua_tostring( L_, -1) : luaL_typename( L_, -1); } - raise_luaL_error(L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); + raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); *len_ = 0; return nullptr; } - STACK_CHECK( L, 0); + STACK_CHECK( L_, 0); return fqn; } @@ -787,7 +786,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; /* * Return some name helping to identify an object */ -[[nodiscard]] static int discover_object_name_recur(lua_State* L, int shortest_, int depth_) +[[nodiscard]] static int discover_object_name_recur(lua_State* L_, int shortest_, int depth_) { int const what = 1; // o "r" {c} {fqn} ... {?} int const result = 2; @@ -798,72 +797,72 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; { return shortest_; } - STACK_GROW(L, 3); - STACK_CHECK_START_REL(L, 0); + STACK_GROW(L_, 3); + STACK_CHECK_START_REL(L_, 0); // stack top contains the table to search in - lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} - lua_rawget(L, cache); // o "r" {c} {fqn} ... {?} nil/1 + lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} + lua_rawget(L_, cache); // o "r" {c} {fqn} ... {?} nil/1 // if table is already visited, we are done - if (!lua_isnil(L, -1)) + if (!lua_isnil(L_, -1)) { - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} return shortest_; } // examined table is not in the cache, add it now - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} - lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} - lua_pushinteger(L, 1); // o "r" {c} {fqn} ... {?} {?} 1 - lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} + lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} + lua_pushinteger(L_, 1); // o "r" {c} {fqn} ... {?} {?} 1 + lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?} // scan table contents - lua_pushnil(L); // o "r" {c} {fqn} ... {?} nil - while (lua_next(L, -2)) // o "r" {c} {fqn} ... {?} k v + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} nil + while (lua_next(L_, -2)) // o "r" {c} {fqn} ... {?} k v { - //char const *const strKey = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : nullptr; // only for debugging - //lua_Number const numKey = (lua_type(L, -2) == LUA_TNUMBER) ? lua_tonumber(L, -2) : -6666; // only for debugging - STACK_CHECK(L, 2); + //char const *const strKey = (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : nullptr; // only for debugging + //lua_Number const numKey = (lua_type(L_, -2) == LUA_TNUMBER) ? lua_tonumber(L_, -2) : -6666; // only for debugging + STACK_CHECK(L_, 2); // append key name to fqn stack ++ depth_; - lua_pushvalue(L, -2); // o "r" {c} {fqn} ... {?} k v k - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v - if (lua_rawequal(L, -1, what)) // is it what we are looking for? + lua_pushvalue(L_, -2); // o "r" {c} {fqn} ... {?} k v k + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v + if (lua_rawequal(L_, -1, what)) // is it what we are looking for? { - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); // update shortest name if (depth_ < shortest_) { shortest_ = depth_; - std::ignore = luaG_pushFQN(L, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn" - lua_replace(L, result); // o "r" {c} {fqn} ... {?} k v + std::ignore = luaG_pushFQN(L_, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn" + lua_replace(L_, result); // o "r" {c} {fqn} ... {?} k v } // no need to search further at this level - lua_pop(L, 2); // o "r" {c} {fqn} ... {?} - STACK_CHECK(L, 0); + lua_pop(L_, 2); // o "r" {c} {fqn} ... {?} + STACK_CHECK(L_, 0); break; } - switch (lua_type(L, -1)) // o "r" {c} {fqn} ... {?} k v + switch (lua_type(L_, -1)) // o "r" {c} {fqn} ... {?} k v { default: // nil, boolean, light userdata, number and string aren't identifiable break; case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} - STACK_CHECK(L, 2); - shortest_ = discover_object_name_recur(L, shortest_, depth_); + STACK_CHECK(L_, 2); + shortest_ = discover_object_name_recur(L_, shortest_, depth_); // search in the table's metatable too - if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} + if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} { - if (lua_istable(L, -1)) + if (lua_istable(L_, -1)) { ++ depth_; - lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} - shortest_ = discover_object_name_recur(L, shortest_, depth_); - lua_pushnil(L); // o "r" {c} {fqn} ... {?} k {} {mt} nil - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} + lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} + shortest_ = discover_object_name_recur(L_, shortest_, depth_); + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k {} {mt} nil + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} -- depth_; } - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k {} + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k {} } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); break; case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T @@ -871,61 +870,61 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; break; case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); // search in the object's metatable (some modules are built that way) - if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} + if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k U {mt} { - if (lua_istable(L, -1)) + if (lua_istable(L_, -1)) { ++ depth_; - lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} - shortest_ = discover_object_name_recur(L, shortest_, depth_); - lua_pushnil(L); // o "r" {c} {fqn} ... {?} k U {mt} nil - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} + lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} + shortest_ = discover_object_name_recur(L_, shortest_, depth_); + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k U {mt} nil + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} -- depth_; } - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); // search in the object's uservalues { int uvi = 1; - while (lua_getiuservalue(L, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u} + while (lua_getiuservalue(L_, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u} { - if (lua_istable(L, -1)) // if it is a table, look inside + if (lua_istable(L_, -1)) // if it is a table, look inside { ++ depth_; - lua_pushliteral(L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} - shortest_ = discover_object_name_recur(L, shortest_, depth_); - lua_pushnil(L); // o "r" {c} {fqn} ... {?} k v {u} nil - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} + lua_pushliteral(L_, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} + shortest_ = discover_object_name_recur(L_, shortest_, depth_); + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k v {u} nil + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} -- depth_; } - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U ++ uvi; } // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U } - STACK_CHECK(L, 2); + STACK_CHECK(L_, 2); break; } // make ready for next iteration - lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k + lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k // remove name from fqn stack - lua_pushnil(L); // o "r" {c} {fqn} ... {?} k nil - lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k - STACK_CHECK(L, 1); + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k nil + lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k + STACK_CHECK(L_, 1); -- depth_; } // o "r" {c} {fqn} ... {?} - STACK_CHECK(L, 0); + STACK_CHECK(L_, 0); // remove the visited table from the cache, in case a shorter path to the searched object exists - lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} - lua_pushnil(L); // o "r" {c} {fqn} ... {?} {?} nil - lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} - STACK_CHECK(L, 0); + lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?} + lua_pushnil(L_); // o "r" {c} {fqn} ... {?} {?} nil + lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?} + STACK_CHECK(L_, 0); return shortest_; } @@ -934,47 +933,47 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; /* * "type", "name" = lanes.nameof( o) */ -int luaG_nameof( lua_State* L) +int luaG_nameof( lua_State* L_) { - int const what{ lua_gettop(L) }; + int const what{ lua_gettop(L_) }; if (what > 1) { - raise_luaL_argerror( L, what, "too many arguments."); + raise_luaL_argerror( L_, what, "too many arguments."); } // nil, boolean, light userdata, number and string aren't identifiable - if (lua_type( L, 1) < LUA_TTABLE) + if (lua_type( L_, 1) < LUA_TTABLE) { - lua_pushstring( L, luaL_typename( L, 1)); // o "type" - lua_insert( L, -2); // "type" o + lua_pushstring( L_, luaL_typename( L_, 1)); // o "type" + lua_insert( L_, -2); // "type" o return 2; } - STACK_GROW( L, 4); - STACK_CHECK_START_REL(L, 0); + STACK_GROW( L_, 4); + STACK_CHECK_START_REL(L_, 0); // this slot will contain the shortest name we found when we are done - lua_pushnil( L); // o nil + lua_pushnil( L_); // o nil // push a cache that will contain all already visited tables - lua_newtable( L); // o nil {c} + lua_newtable( L_); // o nil {c} // push a table whose contents are strings that, when concatenated, produce unique name - lua_newtable( L); // o nil {c} {fqn} - lua_pushliteral( L, "_G"); // o nil {c} {fqn} "_G" - lua_rawseti( L, -2, 1); // o nil {c} {fqn} + lua_newtable( L_); // o nil {c} {fqn} + lua_pushliteral( L_, "_G"); // o nil {c} {fqn} "_G" + lua_rawseti( L_, -2, 1); // o nil {c} {fqn} // this is where we start the search - lua_pushglobaltable( L); // o nil {c} {fqn} _G - (void) discover_object_name_recur( L, 6666, 1); - if (lua_isnil( L, 2)) // try again with registry, just in case... - { - lua_pop( L, 1); // o nil {c} {fqn} - lua_pushliteral( L, "_R"); // o nil {c} {fqn} "_R" - lua_rawseti( L, -2, 1); // o nil {c} {fqn} - lua_pushvalue( L, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R - (void) discover_object_name_recur( L, 6666, 1); - } - lua_pop( L, 3); // o "result" - STACK_CHECK( L, 1); - lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" - lua_replace( L, -3); // "type" "result" + lua_pushglobaltable( L_); // o nil {c} {fqn} _G + (void) discover_object_name_recur( L_, 6666, 1); + if (lua_isnil( L_, 2)) // try again with registry, just in case... + { + lua_pop( L_, 1); // o nil {c} {fqn} + lua_pushliteral( L_, "_R"); // o nil {c} {fqn} "_R" + lua_rawseti( L_, -2, 1); // o nil {c} {fqn} + lua_pushvalue( L_, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R + (void) discover_object_name_recur( L_, 6666, 1); + } + lua_pop( L_, 3); // o "result" + STACK_CHECK( L_, 1); + lua_pushstring( L_, luaL_typename( L_, 1)); // o "result" "type" + lua_replace( L_, -3); // "type" "result" return 2; } @@ -1090,12 +1089,12 @@ static char const* vt_names[] = // we have to do it that way because we can't unbalance the stack between buffer operations // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! // luckily, this also works with earlier Lua versions -[[nodiscard]] static int buf_writer(lua_State* L, void const* b, size_t size, void* ud) +[[nodiscard]] static int buf_writer(lua_State* L_, void const* b, size_t size, void* ud) { luaL_Buffer* B = (luaL_Buffer*) ud; if (!B->L) { - luaL_buffinit( L, B); + luaL_buffinit( L_, B); } luaL_addlstring( B, (char const*) b, size); return 0; diff --git a/src/tools.h b/src/tools.h index f83a01c..b58ae00 100644 --- a/src/tools.h +++ b/src/tools.h @@ -8,8 +8,8 @@ class Universe; // ################################################################################################# -void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const char* mode_); -void push_registry_subtable(lua_State* L, RegistryUniqueKey key_); +void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_); +void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_); enum class VT { @@ -77,10 +77,10 @@ class InterCopyContext // ################################################################################################# -[[nodiscard]] int luaG_nameof(lua_State* L); +[[nodiscard]] int luaG_nameof(lua_State* L_); -void populate_func_lookup_table(lua_State* L, int _i, char const* _name); -void initialize_allocator_function(Universe* U, lua_State* L); +void populate_func_lookup_table(lua_State* L_, int _i, char const* _name); +void initialize_allocator_function(Universe* U, lua_State* L_); // ################################################################################################# diff --git a/src/universe.cpp b/src/universe.cpp index 4eca0c9..062d552 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -73,34 +73,34 @@ Universe::Universe() // ################################################################################################# // only called from the master state -Universe* universe_create(lua_State* L) +Universe* universe_create(lua_State* L_) { - LUA_ASSERT(L, universe_get(L) == nullptr); - Universe* const U{ lua_newuserdatauv(L, 0) }; // universe + LUA_ASSERT(L_, universe_get(L_) == nullptr); + Universe* const U{ lua_newuserdatauv(L_, 0) }; // universe U->Universe::Universe(); - STACK_CHECK_START_REL(L, 1); - kUniverseFullRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); - kUniverseLightRegKey.setValue(L, [U](lua_State* L) { lua_pushlightuserdata(L, U); }); - STACK_CHECK(L, 1); + STACK_CHECK_START_REL(L_, 1); + kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); + kUniverseLightRegKey.setValue(L_, [U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); + STACK_CHECK(L_, 1); return U; } // ################################################################################################# -void universe_store(lua_State* L, Universe* U) +void universe_store(lua_State* L_, Universe* U) { - LUA_ASSERT(L, !U || universe_get(L) == nullptr); - STACK_CHECK_START_REL(L, 0); - kUniverseLightRegKey.setValue(L, [U](lua_State* L) { U ? lua_pushlightuserdata(L, U) : lua_pushnil(L); }); - STACK_CHECK(L, 0); + LUA_ASSERT(L_, !U || universe_get(L_) == nullptr); + STACK_CHECK_START_REL(L_, 0); + kUniverseLightRegKey.setValue(L_, [U](lua_State* L_) { U ? lua_pushlightuserdata(L_, U) : lua_pushnil(L_); }); + STACK_CHECK(L_, 0); } // ################################################################################################# -Universe* universe_get(lua_State* L) +Universe* universe_get(lua_State* L_) { - STACK_CHECK_START_REL(L, 0); - Universe* const universe{ kUniverseLightRegKey.readLightUserDataValue(L) }; - STACK_CHECK(L, 0); + STACK_CHECK_START_REL(L_, 0); + Universe* const universe{ kUniverseLightRegKey.readLightUserDataValue(L_) }; + STACK_CHECK(L_, 0); return universe; } diff --git a/src/universe.h b/src/universe.h index 128c4d9..2fd487e 100644 --- a/src/universe.h +++ b/src/universe.h @@ -34,7 +34,7 @@ class AllocatorDefinition void* m_allocUD{ nullptr }; [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state - [[nodiscard]] static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 0); } + [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); } // always embedded somewhere else or "in-place constructed" as a full userdata // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception static void operator delete([[maybe_unused]] void* p_, lua_State* L_) { LUA_ASSERT(L_, !"should never be called"); } @@ -50,9 +50,9 @@ class AllocatorDefinition AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; - void initFrom(lua_State* L) + void initFrom(lua_State* L_) { - m_allocF = lua_getallocf(L, &m_allocUD); + m_allocF = lua_getallocf(L_, &m_allocUD); } void* lua_alloc(void* ptr_, size_t osize_, size_t nsize_) @@ -89,25 +89,25 @@ class ProtectedAllocator public: // we are not like our base class: we can't be created inside a full userdata (or we would have to install a metatable and __gc handler to destroy ourselves properly) - [[nodiscard]] static void* operator new(size_t size_, lua_State* L) noexcept = delete; - static void operator delete(void* p_, lua_State* L) = delete; + [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept = delete; + static void operator delete(void* p_, lua_State* L_) = delete; AllocatorDefinition makeDefinition() { return AllocatorDefinition{ protected_lua_Alloc, this }; } - void installIn(lua_State* L) + void installIn(lua_State* L_) { - lua_setallocf(L, protected_lua_Alloc, this); + lua_setallocf(L_, protected_lua_Alloc, this); } - void removeFrom(lua_State* L) + void removeFrom(lua_State* L_) { // remove the protected allocator, if any if (m_allocF != nullptr) { // install the non-protected allocator - lua_setallocf(L, m_allocF, m_allocUD); + lua_setallocf(L_, m_allocF, m_allocUD); } } }; @@ -182,9 +182,9 @@ class Universe // ################################################################################################# -[[nodiscard]] Universe* universe_get(lua_State* L); -[[nodiscard]] Universe* universe_create(lua_State* L); -void universe_store(lua_State* L, Universe* U); +[[nodiscard]] Universe* universe_get(lua_State* L_); +[[nodiscard]] Universe* universe_create(lua_State* L_); +void universe_store(lua_State* L_, Universe* U); // ################################################################################################# -- cgit v1.2.3-55-g6feb