From dc4a5f6198bddc2d00f55a0177097bc9ed7935ae Mon Sep 17 00:00:00 2001 From: jyelon Date: Thu, 6 Apr 2023 14:05:12 -0400 Subject: [PATCH] A minor refactor to precede a major LuaStack refactor --- luprex/cpp/core/luastack.cpp | 117 ++++++++-------------- luprex/cpp/core/luastack.hpp | 189 ++++++++++++++++++++--------------- 2 files changed, 148 insertions(+), 158 deletions(-) diff --git a/luprex/cpp/core/luastack.cpp b/luprex/cpp/core/luastack.cpp index 47e8007d..4358ae07 100644 --- a/luprex/cpp/core/luastack.cpp +++ b/luprex/cpp/core/luastack.cpp @@ -72,7 +72,7 @@ static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { } } -lua_State *LuaStack::newstate (lua_Alloc allocf) { +lua_State *LuaCoreStack::newstate (lua_Alloc allocf) { if (allocf == nullptr) allocf = l_alloc; lua_State *L = lua_newstate(allocf, NULL); assert(L != nullptr); @@ -92,11 +92,11 @@ lua_State *LuaStack::newstate (lua_Alloc allocf) { return L; } -void LuaStack::argerr(const char *nm, const char *tp) const { +void LuaCoreStack::argerr(const char *nm, const char *tp) const { luaL_error(L_, "'%s' should be %s", nm, tp); } -bool LuaStack::isinteger(LuaSlot s) const { +bool LuaCoreStack::isinteger(LuaSlot s) const { if (lua_type(L_, s) == LUA_TNUMBER) { lua_Number result = lua_tonumber(L_, s); if (lua_Integer(result) == result) return true; @@ -104,7 +104,7 @@ bool LuaStack::isinteger(LuaSlot s) const { return false; } -bool LuaStack::isint(LuaSlot s) const { +bool LuaCoreStack::isint(LuaSlot s) const { if (lua_type(L_, s) == LUA_TNUMBER) { lua_Number result = lua_tonumber(L_, s); if (int(result) == result) return true; @@ -112,12 +112,12 @@ bool LuaStack::isint(LuaSlot s) const { return false; } -bool LuaStack::ckboolean(LuaSlot s) const { +bool LuaCoreStack::ckboolean(LuaSlot s) const { checkboolean(s, "value"); return lua_toboolean(L_, s) ? true:false; } -lua_Integer LuaStack::ckinteger(LuaSlot s) const { +lua_Integer LuaCoreStack::ckinteger(LuaSlot s) const { checknumber(s, "value"); luaL_checktype(L_, s, LUA_TNUMBER); lua_Number result = lua_tonumber(L_, s); @@ -129,7 +129,7 @@ lua_Integer LuaStack::ckinteger(LuaSlot s) const { return iresult; } -int LuaStack::ckint(LuaSlot s) const { +int LuaCoreStack::ckint(LuaSlot s) const { checknumber(s, "value"); lua_Number result = lua_tonumber(L_, s); int iresult(result); @@ -140,81 +140,46 @@ int LuaStack::ckint(LuaSlot s) const { return iresult; } -lua_Number LuaStack::cknumber(LuaSlot s) const { +lua_Number LuaCoreStack::cknumber(LuaSlot s) const { checknumber(s, "value"); return lua_tonumber(L_, s); } -eng::string LuaStack::ckstring(LuaSlot s) const { +eng::string LuaCoreStack::ckstring(LuaSlot s) const { checkstring(s, "value"); size_t len; const char *str = lua_tolstring(L_, s, &len); return eng::string(str, len); } -std::string_view LuaStack::ckstringview(LuaSlot s) const { +std::string_view LuaCoreStack::ckstringview(LuaSlot s) const { checkstring(s, "value"); size_t len; const char *str = lua_tolstring(L_, s, &len); return std::string_view(str, len); } -lua_State *LuaStack::ckthread(LuaSlot s) const { +lua_State *LuaCoreStack::ckthread(LuaSlot s) const { checkthread(s, "value"); return lua_tothread(L_, s); } -LuaToken LuaStack::cktoken(LuaSlot s) const { +LuaToken LuaCoreStack::cktoken(LuaSlot s) const { checktoken(s, "value"); return LuaToken(lua_touserdata(L_, s)); } -void LuaStack::count_slots_finalize(int narg, int nvar, int nret) { - narg_ = narg; - nret_ = nret; - nvar_ = nvar; - ngap_ = nret - nvar - narg; - if (ngap_ < 0) ngap_ = 0; - - int argtop = lua_gettop(L_); - argpos_ = argtop + 1 - narg_; - gappos_ = argpos_ + narg_; - varpos_ = gappos_ + ngap_; - retpos_ = varpos_ + nvar_; - - rettop_ = retpos_ + nret_ - 1; - finaltop_ = argpos_ + nret_ - 1; -} - -void LuaStack::clear_frame() { - lua_settop(L_, varpos_ - 1); - for (int i = 0; i < nvar_ + nret_; i++) { - lua_pushnil(L_); - } -} - -int LuaStack::result() { - lua_settop(L_, rettop_); - int i = finaltop_; - for (int j = 0; j < nret_; j++) { - lua_replace(L_, i); - i -= 1; - } - lua_settop(L_, finaltop_); - return nret_; -} - -void LuaStack::clearmetatable(LuaSlot tab) const { +void LuaCoreStack::clearmetatable(LuaSlot tab) const { lua_pushnil(L_); lua_setmetatable(L_, tab); } -void LuaStack::setmetatable(LuaSlot tab, LuaSlot mt) const { +void LuaCoreStack::setmetatable(LuaSlot tab, LuaSlot mt) const { lua_pushvalue(L_, mt); lua_setmetatable(L_, tab); } -bool LuaStack::getmetatable(LuaSlot mt, LuaSlot tab) const { +bool LuaCoreStack::getmetatable(LuaSlot mt, LuaSlot tab) const { if (lua_getmetatable(L_, tab)) { lua_replace(L_, mt); return true; @@ -225,7 +190,7 @@ bool LuaStack::getmetatable(LuaSlot mt, LuaSlot tab) const { } } -int LuaStack::next(LuaSlot tab, LuaSlot key, LuaSlot value) const { +int LuaCoreStack::next(LuaSlot tab, LuaSlot key, LuaSlot value) const { lua_pushvalue(L_, key); int ret = lua_next(L_, tab); if (ret != 0) { @@ -235,39 +200,39 @@ int LuaStack::next(LuaSlot tab, LuaSlot key, LuaSlot value) const { return ret; } -void LuaStack::getglobaltable(LuaSlot target) const { +void LuaCoreStack::getglobaltable(LuaSlot target) const { lua_pushglobaltable(L_); lua_replace(L_, target); } -void LuaStack::newtable(LuaSlot target) const { +void LuaCoreStack::newtable(LuaSlot target) const { lua_newtable(L_); lua_replace(L_, target); } -void LuaStack::createtable(LuaSlot target, int narr, int nrec) const { +void LuaCoreStack::createtable(LuaSlot target, int narr, int nrec) const { lua_createtable(L_, narr, nrec); lua_replace(L_, target); } -lua_State *LuaStack::newthread(LuaSlot target) const { +lua_State *LuaCoreStack::newthread(LuaSlot target) const { lua_State *result = lua_newthread(L_); lua_replace(L_, target); return result; } -bool LuaStack::validclassname(std::string_view cname) { +bool LuaCoreStack::validclassname(std::string_view cname) { if (cname.empty()) return false; if (cname == "_G") return false; return true; } -bool LuaStack::validclassname(LuaSlot slot) const { +bool LuaCoreStack::validclassname(LuaSlot slot) const { if (!isstring(slot)) return false; return validclassname(ckstring(slot)); } -eng::string LuaStack::classname(LuaSlot tab) const { +eng::string LuaCoreStack::classname(LuaSlot tab) const { eng::string result; if ((istable(tab)) && (gettabletype(tab) == LUA_TT_CLASS)) { LuaVar classes, name, dup; @@ -300,7 +265,7 @@ eng::string LuaStack::classname(LuaSlot tab) const { return ""; } -eng::string LuaStack::getclass(LuaSlot classtab, LuaSlot classname) const { +eng::string LuaCoreStack::getclass(LuaSlot classtab, LuaSlot classname) const { lua_checkstack(L_, 20); LuaVar globtab, cname; LuaStack LS(L_, globtab, cname); @@ -353,7 +318,7 @@ eng::string LuaStack::getclass(LuaSlot classtab, LuaSlot classname) const { } } -eng::string LuaStack::getclass(LuaSlot tab, std::string_view name) const { +eng::string LuaCoreStack::getclass(LuaSlot tab, std::string_view name) const { push_any_value(name); LuaSpecial classname(lua_gettop(L_)); eng::string err = getclass(tab, classname); @@ -361,7 +326,7 @@ eng::string LuaStack::getclass(LuaSlot tab, std::string_view name) const { return err; } -void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const { +void LuaCoreStack::makeclass(LuaSlot classtab, LuaSlot classname) const { lua_checkstack(L_, 20); LuaVar classes, globtab, cname; LuaStack LS(L_, classes, globtab, cname); @@ -397,14 +362,14 @@ void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const { LS.result(); } -void LuaStack::makeclass(LuaSlot tab, std::string_view name) const { +void LuaCoreStack::makeclass(LuaSlot tab, std::string_view name) const { push_any_value(name); LuaSpecial classname(lua_gettop(L_)); makeclass(tab, classname); lua_pop(L_, 1); } -void LuaStack::maketan(LuaSlot tab, int64_t id) const { +void LuaCoreStack::maketan(LuaSlot tab, int64_t id) const { LuaVar tangibles, metatab; LuaStack LS(L_, tangibles, metatab); @@ -438,7 +403,7 @@ void LuaStack::maketan(LuaSlot tab, int64_t id) const { } -bool LuaStack::tanblank(LuaSlot tab) const { +bool LuaCoreStack::tanblank(LuaSlot tab) const { bool result = true; if (istable(tab) && gettabletype(tab) == LUA_TT_TANGIBLE) { if (lua_getmetatable(L_, tab.index())) { @@ -453,7 +418,7 @@ bool LuaStack::tanblank(LuaSlot tab) const { return result; } -int64_t LuaStack::tanid(LuaSlot tab) const { +int64_t LuaCoreStack::tanid(LuaSlot tab) const { int64_t result = 0; if (istable(tab) && gettabletype(tab) == LUA_TT_TANGIBLE) { if (lua_getmetatable(L_, tab.index())) { @@ -468,12 +433,12 @@ int64_t LuaStack::tanid(LuaSlot tab) const { return result; } -bool LuaStack::issortablekey(LuaSlot s) const { +bool LuaCoreStack::issortablekey(LuaSlot s) const { int type = lua_type(L_, s); return (type == LUA_TBOOLEAN) || (type == LUA_TNUMBER) || (type == LUA_TSTRING); } -void LuaStack::movesortablekey(LuaSlot key, LuaStack &otherstack, LuaSlot otherslot) { +void LuaCoreStack::movesortablekey(LuaSlot key, LuaCoreStack &otherstack, LuaSlot otherslot) { int type = lua_type(L_, key); switch (type) { case LUA_TBOOLEAN: @@ -496,7 +461,7 @@ void LuaStack::movesortablekey(LuaSlot key, LuaStack &otherstack, LuaSlot others } } -void LuaStack::cleartable(LuaSlot tab, bool clearmeta) const { +void LuaCoreStack::cleartable(LuaSlot tab, bool clearmeta) const { assert(istable(tab)); lua_pushnil(L_); while (lua_next(L_, tab.index()) != 0) { @@ -511,38 +476,38 @@ void LuaStack::cleartable(LuaSlot tab, bool clearmeta) const { } } -int LuaStack::rawlen(LuaSlot obj) const { +int LuaCoreStack::rawlen(LuaSlot obj) const { return lua_rawlen(L_, obj.index()); } -int LuaStack::gettabletype(LuaSlot tab) const { +int LuaCoreStack::gettabletype(LuaSlot tab) const { uint16_t bits = lua_getflagbits(L_, tab.index()); return LUA_TT_GENERAL + (bits & 0x000F); } -void LuaStack::settabletype(LuaSlot tab, int t) const { +void LuaCoreStack::settabletype(LuaSlot tab, int t) const { assert((t >= LUA_TT_GENERAL) && (t <= LUA_TT_CLASS)); int offset = (t - LUA_TT_GENERAL); lua_modflagbits(L_, tab.index(), 0x000F, offset); } -int LuaStack::xtype(LuaSlot slot) const { +int LuaCoreStack::xtype(LuaSlot slot) const { int t = lua_type(L_, slot); if (t != LUA_TTABLE) return t; uint16_t bits = lua_getflagbits(L_, slot); return LUA_TT_GENERAL + (bits & 0x000F); } -bool LuaStack::getvisited(LuaSlot tab) const { +bool LuaCoreStack::getvisited(LuaSlot tab) const { uint16_t bits = lua_getflagbits(L_, tab.index()); return (bits & 0x0010); } -void LuaStack::setvisited(LuaSlot tab, bool visited) const { +void LuaCoreStack::setvisited(LuaSlot tab, bool visited) const { lua_modflagbits(L_, tab.index(), 0x0010, visited ? 0x0010 : 0); } -WorldType LuaStack::world_type() const { +WorldType LuaCoreStack::world_type() const { lua_pushstring(L_, "worldtype"); lua_rawget(L_, LUA_REGISTRYINDEX); lua_Integer n = lua_tointeger(L_, -1); @@ -551,7 +516,7 @@ WorldType LuaStack::world_type() const { return (WorldType)n; } -void LuaStack::guard_nopredict(const char *fn) { +void LuaCoreStack::guard_nopredict(const char *fn) { if (lua_isyieldable(L_)) { if (!is_authoritative()) { lua_yield(L_, 0); diff --git a/luprex/cpp/core/luastack.hpp b/luprex/cpp/core/luastack.hpp index 248b7bbe..a8b5cd7c 100644 --- a/luprex/cpp/core/luastack.hpp +++ b/luprex/cpp/core/luastack.hpp @@ -179,7 +179,9 @@ public: return index_; } + friend class LuaCoreStack; friend class LuaStack; + friend class LuaExtStack; }; class LuaArg : public LuaSlot {}; @@ -269,67 +271,9 @@ public: eng::string str() const; }; -class LuaStack : public eng::nevernew { -private: - int narg_; - int ngap_; - int nvar_; - int nret_; - - int argpos_; - int gappos_; - int varpos_; - int retpos_; - - int rettop_; - int finaltop_; - +class LuaCoreStack : public eng::nevernew { +protected: lua_State *L_; - - template - void count_slots(LuaArg &v, SS & ... stackslots) - { - count_slots(stackslots...); - } - template - void count_slots(LuaVar &v, SS & ... stackslots) - { - count_slots(stackslots...); - } - template - void count_slots(LuaRet &v, SS & ... stackslots) - { - count_slots(stackslots...); - } - - template - void count_slots() { - count_slots_finalize(NARG, NVAR, NRET); - } - - void count_slots_finalize(int narg, int nvar, int nret); - - template - void assign_slots(int argp, int varp, int retp, LuaArg &v, SS & ... stackslots) { - v.index_ = argp; - assign_slots(argp + 1, varp, retp, stackslots...); - } - - template - void assign_slots(int argp, int varp, int retp, LuaVar &v, SS & ... stackslots) { - v.index_ = varp; - assign_slots(argp, varp+1, retp, stackslots...); - } - - template - void assign_slots(int argp, int varp, int retp, LuaRet &v, SS & ... stackslots) { - v.index_ = retp; - assign_slots(argp, varp, retp+1, stackslots...); - } - - void assign_slots(int argp, int varp, int retp) {} - - void clear_frame(); private: // Push any value on the stack, by type. @@ -356,37 +300,17 @@ private: void push_any_values() { } - template - static void delete_pointer(void *p) { delete (T*)p; } - static void do_not_delete(void *p) { } - void argerr(const char *arg, const char *tp) const; public: - template - LuaStack(lua_State *L, SS & ... stackslots) { - L_ = L; - count_slots<0, 0, 0>(stackslots...); - if (lua_gettop(L) < narg_) { - luaL_error(L, "not enough arguments to function"); - } - assign_slots(argpos_, varpos_, retpos_, stackslots...); - clear_frame(); - } + lua_State *state() const { return L_; } - ~LuaStack() {}; - - int result(); - -public: // This is the largest integer that can be stored in a lua_Number. // In other words, any 53-bit number can be stored. static const int64_t MAXINT = 0x001FFFFFFFFFFFFF; static lua_State *newstate (lua_Alloc allocf); - lua_State *state() const { return L_; } - int type(LuaSlot s) const { return lua_type(L_, s); } void checktype(LuaSlot s, int type) const { luaL_checktype(L_, s, type); } @@ -480,7 +404,7 @@ public: // Move a sortable key (string, number, or boolean) from one lua // environment to another lua environment. WARNING: this assert-fails // if the value is not a sortable key. - void movesortablekey(LuaSlot val, LuaStack &other, LuaSlot otherslot); + void movesortablekey(LuaSlot val, LuaCoreStack &other, LuaSlot otherslot); bool rawequal(LuaSlot v1, LuaSlot v2) const { return lua_rawequal(L_, v1, v2); @@ -552,6 +476,107 @@ public: static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); } }; +class LuaStack : public LuaCoreStack { +private: + int narg_; + int ngap_; + int nvar_; + int nret_; + + int argpos_; + int gappos_; + int varpos_; + int retpos_; + + int rettop_; + int finaltop_; + +private: + + template + void assign_slots(int argp, int varp, int retp, LuaArg &v, SS & ... stackslots) { + v.index_ = argp; + assign_slots(argp + 1, varp, retp, stackslots...); + } + + template + void assign_slots(int argp, int varp, int retp, LuaVar &v, SS & ... stackslots) { + v.index_ = varp; + assign_slots(argp, varp+1, retp, stackslots...); + } + + template + void assign_slots(int argp, int varp, int retp, LuaRet &v, SS & ... stackslots) { + v.index_ = retp; + assign_slots(argp, varp, retp+1, stackslots...); + } + + void assign_slots(int argp, int varp, int retp) {} + + template + void count_slots(LuaArg &v, SS & ... stackslots) + { + count_slots(stackslots...); + } + template + void count_slots(LuaVar &v, SS & ... stackslots) + { + count_slots(stackslots...); + } + template + void count_slots(LuaRet &v, SS & ... stackslots) + { + count_slots(stackslots...); + } + + template + void count_slots() { + narg_ = NARG; + nret_ = NRET; + nvar_ = NVAR; + ngap_ = NRET - NVAR - NARG; + if (ngap_ < 0) ngap_ = 0; + + int argtop = lua_gettop(L_); + argpos_ = argtop + 1 - NARG; + gappos_ = argpos_ + NARG; + varpos_ = gappos_ + ngap_; + retpos_ = varpos_ + NVAR; + + rettop_ = retpos_ + NRET - 1; + finaltop_ = argpos_ + NRET - 1; + } + +public: + template + LuaStack(lua_State *L, SS & ... stackslots) { + L_ = L; + count_slots<0, 0, 0>(stackslots...); + if (lua_gettop(L) < narg_) { + luaL_error(L, "not enough arguments to function"); + } + assign_slots(argpos_, varpos_, retpos_, stackslots...); + lua_settop(L_, varpos_ - 1); + for (int i = 0; i < nvar_ + nret_; i++) { + lua_pushnil(L_); + } + } + + int result() { + lua_settop(L_, rettop_); + int i = finaltop_; + for (int j = 0; j < nret_; j++) { + lua_replace(L_, i); + i -= 1; + } + lua_settop(L_, finaltop_); + return nret_; + } + + ~LuaStack() {}; +}; + + // This is a helper class to help parse tables full of keywords. class LuaKeywordParser { struct cmp_char {