Remove more instances of LuaOldStack

This commit is contained in:
2023-04-11 17:08:32 -04:00
parent 3fd4067969
commit cfa9aa6a2a

View File

@@ -20,47 +20,23 @@ int World::number_lua_tables(const IdVector &basis) {
// This is conceptually recursive, but we're going to use an // This is conceptually recursive, but we're going to use an
// explicit stack (the lua stack). // explicit stack (the lua stack).
lua_State *L = state(); lua_State *L = state();
LuaVar tnmap, ntmap, tangibles, tab, key, val, xid;
LuaOldStack LS(L, tnmap, ntmap, tangibles, tab, key, val, xid);
LS.set(tnmap, LuaNewTable);
LS.set(ntmap, LuaNewTable);
LS.rawset(LuaRegistry, "tnmap", tnmap);
LS.rawset(LuaRegistry, "ntmap", ntmap);
LS.rawget(tangibles, LuaRegistry, "tangibles");
int nextid = 1; int nextid = 1;
int top = lua_gettop(L); {
LuaVar tnmap, ntmap, tangibles, tab, key, val, xid;
LuaExtStack LS(L, tnmap, ntmap, tangibles, tab, key, val, xid);
LS.set(tnmap, LuaNewTable);
LS.set(ntmap, LuaNewTable);
LS.rawset(LuaRegistry, "tnmap", tnmap);
LS.rawset(LuaRegistry, "ntmap", ntmap);
LS.rawget(tangibles, LuaRegistry, "tangibles");
int top = lua_gettop(L);
// Push all subtables onto the stack. Note that we may push // Push all subtables onto the stack. Note that we may push
// the same table twice, that's OK. // the same table twice, that's OK.
for (int64_t id : basis) { for (int64_t id : basis) {
LS.rawget(tab, tangibles, id); LS.rawget(tab, tangibles, id);
assert(LS.istable(tab)); assert(LS.istable(tab));
// Traverse subtables. // Traverse subtables.
LS.set(key, LuaNil);
while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
}
}
// Pop tables from the stack one by one. If the table is not
// already numbered, number it and push subtables onto the stack.
while (lua_gettop(L) > top) {
lua_replace(L, tab.index());
LS.rawget(xid, tnmap, tab);
if (LS.isnil(xid)) {
int id = nextid++;
LS.rawset(tnmap, tab, id);
LS.rawset(ntmap, id, tab);
// Traverse the metatable.
LS.getmetatable(val, tab);
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
// Traverse the subtables.
LS.set(key, LuaNil); LS.set(key, LuaNil);
while (LS.next(tab, key, val)) { while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) { if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
@@ -69,9 +45,34 @@ int World::number_lua_tables(const IdVector &basis) {
} }
} }
} }
// Pop tables from the stack one by one. If the table is not
// already numbered, number it and push subtables onto the stack.
while (lua_gettop(L) > top) {
lua_replace(L, tab.index());
LS.rawget(xid, tnmap, tab);
if (LS.isnil(xid)) {
int id = nextid++;
LS.rawset(tnmap, tab, id);
LS.rawset(ntmap, id, tab);
// Traverse the metatable.
LS.getmetatable(val, tab);
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
// Traverse the subtables.
LS.set(key, LuaNil);
while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
}
}
}
} }
LS.result();
assert(stack_is_clear()); assert(stack_is_clear());
return nextid - 1; return nextid - 1;
} }
@@ -79,8 +80,8 @@ int World::number_lua_tables(const IdVector &basis) {
void World::pair_lua_tables(const IdVector &basis, lua_State *master) { void World::pair_lua_tables(const IdVector &basis, lua_State *master) {
lua_State *synch = state(); lua_State *synch = state();
LuaVar stangibles, mtangibles, sntmap, mntmap, stnmap, mtnmap, stab, mtab, skey, mkey, sval, mval, sidx, midx; LuaVar stangibles, mtangibles, sntmap, mntmap, stnmap, mtnmap, stab, mtab, skey, mkey, sval, mval, sidx, midx;
LuaOldStack SLS(synch, stangibles, stab, skey, sval, sntmap, stnmap, sidx); LuaExtStack SLS(synch, stangibles, stab, skey, sval, sntmap, stnmap, sidx);
LuaOldStack MLS(master, mtangibles, mtab, mkey, mval, mntmap, mtnmap, midx); LuaExtStack MLS(master, mtangibles, mtab, mkey, mval, mntmap, mtnmap, midx);
// Fetch the tangible databases // Fetch the tangible databases
SLS.rawget(stangibles, LuaRegistry, "tangibles"); SLS.rawget(stangibles, LuaRegistry, "tangibles");
@@ -168,63 +169,29 @@ void World::pair_lua_tables(const IdVector &basis, lua_State *master) {
lua_pushvalue(synch, sval.index()); lua_pushvalue(synch, sval.index());
} }
} }
MLS.result();
SLS.result();
} }
int World::number_remaining_tables(const IdVector &basis, lua_State *master) { int World::number_remaining_tables(const IdVector &basis, lua_State *master) {
// This is conceptually recursive, but we're going to use an // This is conceptually recursive, but we're going to use an
// explicit stack (the lua stack). // explicit stack (the lua stack).
lua_State *L = master;
LuaVar tnmap, ntmap, tangibles, tab, key, val, xid;
LuaOldStack LS(L, tnmap, ntmap, tangibles, tab, key, val, xid);
LS.rawget(tnmap, LuaRegistry, "tnmap");
LS.rawget(ntmap, LuaRegistry, "ntmap");
LS.rawget(tangibles, LuaRegistry, "tangibles");
int ntables = LS.rawlen(ntmap);
eng::vector<bool> visited; eng::vector<bool> visited;
visited.assign(ntables + 1, false); int ntables;
int top = lua_gettop(L); {
lua_State *L = master;
LuaVar tnmap, ntmap, tangibles, tab, key, val, xid;
LuaExtStack LS(L, tnmap, ntmap, tangibles, tab, key, val, xid);
LS.rawget(tnmap, LuaRegistry, "tnmap");
LS.rawget(ntmap, LuaRegistry, "ntmap");
LS.rawget(tangibles, LuaRegistry, "tangibles");
ntables = LS.rawlen(ntmap);
visited.assign(ntables + 1, false);
int top = lua_gettop(L);
// Push all subtables onto the stack. Note that we may push // Push all subtables onto the stack. Note that we may push
// the same table twice, that's OK. // the same table twice, that's OK.
for (int64_t id : basis) { for (int64_t id : basis) {
LS.rawget(tab, tangibles, id); LS.rawget(tab, tangibles, id);
assert(LS.istable(tab)); assert(LS.istable(tab));
LS.set(key, LuaNil);
while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
}
}
// Pop tables from the stack one by one. If the table is not
// numbered, number it. If it is not visited, visit it.
while (lua_gettop(L) > top) {
lua_replace(L, tab.index());
int id = 0;
LS.rawget(xid, tnmap, tab);
if (!LS.isnumber(xid)) {
id = visited.size();
LS.rawset(tnmap, tab, id);
LS.rawset(ntmap, id, tab);
visited.push_back(false);
} else {
id = LS.cknumber(xid);
assert((id >= 0) && (id < int(visited.size())));
}
if (!visited[id]) {
visited[id] = true;
// Traverse the metatable.
LS.getmetatable(val, tab);
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
// Traverse the subtables.
LS.set(key, LuaNil); LS.set(key, LuaNil);
while (LS.next(tab, key, val)) { while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) { if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
@@ -233,35 +200,68 @@ int World::number_remaining_tables(const IdVector &basis, lua_State *master) {
} }
} }
} }
}
LS.result(); // Pop tables from the stack one by one. If the table is not
// numbered, number it. If it is not visited, visit it.
while (lua_gettop(L) > top) {
lua_replace(L, tab.index());
int id = 0;
LS.rawget(xid, tnmap, tab);
if (!LS.isnumber(xid)) {
id = visited.size();
LS.rawset(tnmap, tab, id);
LS.rawset(ntmap, id, tab);
visited.push_back(false);
} else {
id = LS.cknumber(xid);
assert((id >= 0) && (id < int(visited.size())));
}
if (!visited[id]) {
visited[id] = true;
// Traverse the metatable.
LS.getmetatable(val, tab);
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
// Traverse the subtables.
LS.set(key, LuaNil);
while (LS.next(tab, key, val)) {
if (LS.istable(val) && LS.gettabletype(val)==LUA_TT_GENERAL) {
lua_checkstack(L, 10);
lua_pushvalue(L, val.index());
}
}
}
}
}
assert(stack_is_clear()); assert(stack_is_clear());
return visited.size() - 1 - ntables; return visited.size() - 1 - ntables;
} }
void World::create_new_tables(int n) { void World::create_new_tables(int n) {
LuaVar tnmap, ntmap, tab; {
LuaOldStack LS(state(), tnmap, ntmap, tab); LuaVar tnmap, ntmap, tab;
LS.rawget(tnmap, LuaRegistry, "tnmap"); LuaExtStack LS(state(), tnmap, ntmap, tab);
LS.rawget(ntmap, LuaRegistry, "ntmap"); LS.rawget(tnmap, LuaRegistry, "tnmap");
assert(LS.istable(tnmap)); LS.rawget(ntmap, LuaRegistry, "ntmap");
assert(LS.istable(ntmap)); assert(LS.istable(tnmap));
int ntables = LS.rawlen(ntmap); assert(LS.istable(ntmap));
int nextid = ntables + 1; int ntables = LS.rawlen(ntmap);
for (int i = 0; i < n; i++) { int nextid = ntables + 1;
int id = nextid++; for (int i = 0; i < n; i++) {
LS.newtable(tab); int id = nextid++;
LS.rawset(ntmap, id, tab); LS.newtable(tab);
LS.rawset(tnmap, tab, id); LS.rawset(ntmap, id, tab);
LS.rawset(tnmap, tab, id);
}
} }
LS.result();
assert(stack_is_clear()); assert(stack_is_clear());
} }
void World::unnumber_lua_tables() { void World::unnumber_lua_tables() {
// All we have to do is remove these tables from the registry. // All we have to do is remove these tables from the registry.
LuaOldStack LS(state()); LuaExtStack LS(state());
LS.rawset(LuaRegistry, "tnmap", LuaNil); LS.rawset(LuaRegistry, "tnmap", LuaNil);
LS.rawset(LuaRegistry, "ntmap", LuaNil); LS.rawset(LuaRegistry, "ntmap", LuaNil);
} }