Implement LuaExtraArgs

This commit is contained in:
2023-04-13 13:26:45 -04:00
parent cf8b573364
commit 30155ae388
4 changed files with 126 additions and 74 deletions

View File

@@ -156,16 +156,18 @@
class LuaSlot : public eng::nevernew {
protected:
int index_;
constexpr LuaSlot(int n) : index_(n) {}
private:
inline operator int() const {
return index_;
}
public:
LuaSlot() {
index_ = 0;
}
int index() const {
public:
constexpr LuaSlot() : index_(0) {}
inline int index() const {
return index_;
}
@@ -181,20 +183,30 @@ class LuaVar : public LuaSlot {};
class LuaSpecial : public LuaSlot {
public:
LuaSpecial(int n) {
index_ = n;
}
constexpr LuaSpecial(int n) : LuaSlot(n) {}
};
extern LuaSpecial LuaRegistry;
class LuaUpvalue : public LuaSlot {
public:
LuaUpvalue(int n) {
index_ = lua_upvalueindex(n);
}
class LuaExtraArgs {
private:
int index_;
int size_;
public:
LuaExtraArgs() {
index_ = 0;
size_ = 0;
}
LuaSpecial operator[] (int n) const { return LuaSpecial(index_ + n); }
int size() const { return size_; }
friend class LuaCoreStack;
friend class LuaDefStack;
};
class LuaNilMarker {};
extern LuaNilMarker LuaNil;
@@ -283,27 +295,33 @@ protected:
int nret;
int narg;
int nvar;
constexpr Counts(int r, int a, int v) : nret(r), narg(a), nvar(v) {}
int nextra;
constexpr Counts(int nr, int na, int nv, int ne) : nret(nr), narg(na), nvar(nv), nextra(ne) {}
};
template<int NRET, int NARG, int NVAR, class... SS>
template<int NRET, int NARG, int NVAR, int NEXTRA, class... SS>
constexpr static Counts count_slots(LuaRet &v, SS & ... stackslots)
{
return count_slots<NRET+1, NARG, NVAR>(stackslots...);
return count_slots<NRET+1, NARG, NVAR, NEXTRA>(stackslots...);
}
template<int NRET, int NARG, int NVAR, class... SS>
template<int NRET, int NARG, int NVAR, int NEXTRA, class... SS>
constexpr static Counts count_slots(LuaArg &v, SS & ... stackslots)
{
return count_slots<NRET, NARG+1, NVAR>(stackslots...);
return count_slots<NRET, NARG+1, NVAR, NEXTRA>(stackslots...);
}
template<int NRET, int NARG, int NVAR, class... SS>
template<int NRET, int NARG, int NVAR, int NEXTRA, class... SS>
constexpr static Counts count_slots(LuaVar &v, SS & ... stackslots)
{
return count_slots<NRET, NARG, NVAR+1>(stackslots...);
return count_slots<NRET, NARG, NVAR+1, NEXTRA>(stackslots...);
}
template<int NRET, int NARG, int NVAR>
template<int NRET, int NARG, int NVAR, int NEXTRA, class... SS>
constexpr static Counts count_slots(LuaExtraArgs &v, SS & ... stackslots)
{
return count_slots<NRET, NARG, NVAR, NEXTRA+1>(stackslots...);
}
template<int NRET, int NARG, int NVAR, int NEXTRA>
constexpr static Counts count_slots() {
return Counts(NRET, NARG, NVAR);
return Counts(NRET, NARG, NVAR, NEXTRA);
}
private:
@@ -649,47 +667,76 @@ public:
class LuaDefStack : public LuaCoreStack {
private:
int top_;
int nret_;
template<int RETP, int ARGP, int VARP, class... SS>
template<int RETP, int ARGP, int VARP, int EXTRAP, int EXTRAC, class... SS>
void assign_slots(LuaRet &v, SS & ... stackslots) {
v.index_ = RETP;
assign_slots<RETP+1, ARGP, VARP>(stackslots...);
assign_slots<RETP+1, ARGP, VARP, EXTRAP, EXTRAC>(stackslots...);
}
template<int RETP, int ARGP, int VARP, class... SS>
template<int RETP, int ARGP, int VARP, int EXTRAP, int EXTRAC, class... SS>
void assign_slots(LuaArg &v, SS & ... stackslots) {
v.index_ = ARGP;
assign_slots<RETP, ARGP+1, VARP>(stackslots...);
assign_slots<RETP, ARGP+1, VARP, EXTRAP, EXTRAC>(stackslots...);
}
template<int RETP, int ARGP, int VARP, class... SS>
template<int RETP, int ARGP, int VARP, int EXTRAP, int EXTRAC, class... SS>
void assign_slots(LuaVar &v, SS & ... stackslots) {
v.index_ = VARP;
assign_slots<RETP, ARGP, VARP+1>(stackslots...);
assign_slots<RETP, ARGP, VARP+1, EXTRAP, EXTRAC>(stackslots...);
}
template<int NRET, int NARG, int NVAR>
template<int RETP, int ARGP, int VARP, int EXTRAP, int EXTRAC, class... SS>
void assign_slots(LuaExtraArgs &v, SS & ... stackslots) {
v.index_ = EXTRAP;
v.size_ = EXTRAC;
assign_slots<RETP, ARGP, VARP, EXTRAP, EXTRAC>(stackslots...);
}
template<int RETP, int ARGP, int VARP, int EXTRAP, int EXTRAC>
void assign_slots() {}
template<class... SS>
void vassign_slots(int retp, int argp, int varp, int extrap, int extrac, LuaRet &v, SS & ... stackslots) {
v.index_ = retp;
vassign_slots(retp+1, argp, varp, extrap, extrac, stackslots...);
}
template<class... SS>
void vassign_slots(int retp, int argp, int varp, int extrap, int extrac, LuaArg &v, SS & ... stackslots) {
v.index_ = argp;
vassign_slots(retp, argp+1, varp, extrap, extrac, stackslots...);
}
template<class... SS>
void vassign_slots(int retp, int argp, int varp, int extrap, int extrac, LuaVar &v, SS & ... stackslots) {
v.index_ = varp;
vassign_slots(retp, argp, varp+1, extrap, extrac, stackslots...);
}
template<class... SS>
void vassign_slots(int retp, int argp, int varp, int extrap, int extrac, LuaExtraArgs &v, SS & ... stackslots) {
v.index_ = extrap;
v.size_ = extrac;
vassign_slots(retp, argp, varp, extrap, extrac, stackslots...);
}
void vassign_slots(int retp, int argp, int varp, int extrap, int extrac) {}
public:
template<class... SS>
inline LuaDefStack(lua_State *L, SS & ... stackslots) : LuaCoreStack(L) {
constexpr Counts counts = count_slots<0, 0, 0>(stackslots...);
if (lua_gettop(L_) != counts.narg) {
luaL_error(L_, "function expects exactly %d arguments", counts.narg);
constexpr Counts counts = count_slots<0, 0, 0, 0>(stackslots...);
if (lua_gettop(L_) < counts.narg) {
luaL_error(L_, "function expects at least %d arguments", counts.narg);
}
lua_checkstack(L, counts.narg + counts.nvar + counts.nret + 20);
for (int i = 0; i < counts.nret; i ++) {
lua_pushnil(L_);
lua_insert(L_, i + 1);
}
for (int i = 0; i < counts.nvar; i++) {
lua_checkstack(L, counts.nvar + counts.nret + 20);
int top = lua_gettop(L);
for (int i = 0; i < counts.nvar + counts.nret; i ++) {
lua_pushnil(L_);
}
assign_slots<1, 1 + counts.nret, 1 + counts.nret + counts.narg>(stackslots...);
vassign_slots(1 + counts.nvar + top, 1, 1 + top, 1 + counts.narg, top - counts.narg, stackslots...);
top_ = top + counts.nvar + counts.nret;
nret_ = counts.nret;
}
int result() {
lua_settop(L_, nret_);
lua_settop(L_, top_);
return nret_;
}
@@ -730,9 +777,10 @@ private:
public:
template<class... SS>
LuaExtStack(lua_State *L, SS & ... stackslots) : LuaCoreStack(L) {
constexpr Counts counts = count_slots<0, 0, 0>(stackslots...);
constexpr Counts counts = count_slots<0, 0, 0, 0>(stackslots...);
static_assert(counts.narg == 0, "LuaExtStack doesn't allow LuaArg parameters");
static_assert(counts.nret == 0, "LuaExtStack doesn't allow LuaRet parameters");
static_assert(counts.nextra == 0, "LuaExtStack doesn't allow LuaExtraArgs parameters");
lua_checkstack(L_, counts.nvar + 20);
oldtop_ = lua_gettop(L_);
for (int i = 0; i < counts.nvar; i++) {