diff --git a/luprex/core/cpp/world-difftab.cpp b/luprex/core/cpp/world-difftab.cpp index 112f57b0..08b217e2 100644 --- a/luprex/core/cpp/world-difftab.cpp +++ b/luprex/core/cpp/world-difftab.cpp @@ -166,11 +166,12 @@ static void transmit_value_debug_string(StreamBuffer *sb, std::ostringstream &os } } -static bool diff_tables(lua_State *synch, lua_State *master, bool cmeta, StreamBuffer *sb) { - LuaArg mtnmap, mtab, stnmap, stab; +static bool diff_tables(LuaStack &SLS0, LuaSlot stnmap, LuaSlot stab, + LuaStack &MLS0, LuaSlot mtnmap, LuaSlot mtab, + bool cmeta, StreamBuffer *sb) { LuaVar skey, mkey, sval, mval, mnil; - LuaStack SLS(synch, stnmap, stab, skey, sval); - LuaStack MLS(master, mtnmap, mtab, mkey, mval, mnil); + LuaStack SLS(SLS0.state(), skey, sval); + LuaStack MLS(MLS0.state(), mkey, mval, mnil); MLS.set(mnil, LuaNil); int nupdates = 0; @@ -296,9 +297,9 @@ static void patch_table(LuaStack &LS0, LuaSlot tangibles, LuaSlot ntmap, LuaSlot void World::diff_numbered_tables(lua_State *master, StreamBuffer *sb) { lua_State *synch = state(); - LuaVar sntmap, mntmap, stnmap, mtnmap; - LuaStack SLS(synch, sntmap, stnmap); - LuaStack MLS(master, mntmap, mtnmap); + LuaVar sntmap, mntmap, stnmap, mtnmap, stab, mtab; + LuaStack SLS(synch, sntmap, stnmap, stab); + LuaStack MLS(master, mntmap, mtnmap, mtab); SLS.rawget(sntmap, LuaRegistry, "ntmap"); MLS.rawget(mntmap, LuaRegistry, "ntmap"); SLS.rawget(stnmap, LuaRegistry, "tnmap"); @@ -313,23 +314,19 @@ void World::diff_numbered_tables(lua_State *master, StreamBuffer *sb) { int s_top = lua_gettop(synch); int m_top = lua_gettop(master); for (int id = 1; id <= m_ntables; id++) { - lua_pushvalue(master, mtnmap.index()); - lua_rawgeti(master, mtnmap.index(), id); - if (lua_type(master, -1) == LUA_TTABLE) { - lua_pushvalue(synch, stnmap.index()); - lua_rawgeti(synch, sntmap.index(), id); + MLS.rawgeti(mtab, mntmap, id); + if (MLS.istable(mtab)) { + SLS.rawgeti(stab, sntmap, id); int tw = sb->total_writes(); sb->write_int32(id); nmodified += 1; - if (!diff_tables(synch, master, true, sb)) { + if (!diff_tables(SLS, stnmap, stab, MLS, mtnmap, mtab, true, sb)) { sb->unwrite_to(tw); nmodified -= 1; } - assert(lua_gettop(synch) == s_top); - assert(lua_gettop(master) == m_top); - } else { - lua_pop(master, 2); } + assert(lua_gettop(synch) == s_top); + assert(lua_gettop(master) == m_top); } sb->overwrite_int32(write_count_after, nmodified); } @@ -337,9 +334,9 @@ void World::diff_numbered_tables(lua_State *master, StreamBuffer *sb) { void World::diff_tangible_databases(const IdVector &basis, lua_State *master, StreamBuffer *sb) { lua_State *synch = state(); - LuaVar stnmap, mtnmap, stangibles, mtangibles; - LuaStack SLS(synch, stnmap, stangibles); - LuaStack MLS(master, mtnmap, mtangibles); + LuaVar stnmap, mtnmap, stangibles, mtangibles, stab, mtab; + LuaStack SLS(synch, stnmap, stangibles, stab); + LuaStack MLS(master, mtnmap, mtangibles, mtab); SLS.rawget(stnmap, LuaRegistry, "tnmap"); MLS.rawget(mtnmap, LuaRegistry, "tnmap"); SLS.rawget(stangibles, LuaRegistry, "tangibles"); @@ -351,14 +348,12 @@ void World::diff_tangible_databases(const IdVector &basis, lua_State *master, St int s_top = lua_gettop(synch); int m_top = lua_gettop(master); for (int64_t id : basis) { - lua_pushvalue(master, mtnmap.index()); - lua_rawgeti(master, mtangibles.index(), id); - lua_pushvalue(synch, stnmap.index()); - lua_rawgeti(synch, stangibles.index(), id); + MLS.rawgeti(mtab, mtangibles, id); + SLS.rawgeti(stab, stangibles, id); int tw = sb->total_writes(); sb->write_int64(id); nmodified += 1; - if (!diff_tables(synch, master, false, sb)) { + if (!diff_tables(SLS, stnmap, stab, MLS, mtnmap, mtab, false, sb)) { sb->unwrite_to(tw); nmodified -= 1; } @@ -369,77 +364,79 @@ void World::diff_tangible_databases(const IdVector &basis, lua_State *master, St } LuaDefine(table_diffcompare, "c") { - LuaArg mtnmap, mtab, stnmap, stab; + LuaArg mtnmap, mtab, mstnmap, mstab, stnmap, stab; LuaRet dbgstring; LuaVar tthread; - LuaStack LS(L, mtnmap, mtab, stnmap, stab, dbgstring, tthread); + LuaStack MLS(L, mtnmap, mtab, mstnmap, mstab, dbgstring, tthread); // Check the arguments. - LS.checktable(mtnmap); - LS.checktable(stnmap); - LS.checktable(mtab); - LS.checktable(stab); + MLS.checktable(mtnmap); + MLS.checktable(mstnmap); + MLS.checktable(mtab); + MLS.checktable(mstab); + // Create a temporary thread to be the 'synch model'. We'll use the - // existing thread as the 'master model'. + // existing thread as the 'master model'. Move two tables to the synch thread. lua_State *synch = lua_newthread(L); lua_replace(L, tthread.index()); + lua_pushvalue(L, mstnmap.index()); + lua_pushvalue(L, mstab.index()); + lua_xmove(L, synch, 2); + LuaStack SLS(synch, stnmap, stab); + // Call tablecmp_diff. StreamBuffer sb; - lua_pushvalue(L, stnmap.index()); - lua_pushvalue(L, stab.index()); - lua_xmove(L, synch, 2); - lua_pushvalue(L, mtnmap.index()); - lua_pushvalue(L, mtab.index()); - diff_tables(synch, L, true, &sb); + diff_tables(SLS, stnmap, stab, MLS, mtnmap, mtab, true, &sb); + // Convert the output to a debug string. - LS.set(dbgstring, diff_tables_debug_string(&sb)); - return LS.result(); + MLS.set(dbgstring, diff_tables_debug_string(&sb)); + return MLS.result(); } LuaDefine(table_diffapply, "c") { - LuaArg tnmap, mtab, stab; + LuaArg mtnmap, mtab, mstab, stnmap, stab; LuaRet eql, eqlstr, rtab; - LuaVar tthread, tangibles, ntmap, key, val; - LuaStack LS(L, tnmap, mtab, stab, eql, eqlstr, rtab, tthread, tangibles, ntmap, key, val); + LuaVar tthread, tangibles, mntmap, key, val; + LuaStack MLS(L, mtnmap, mtab, mstab, eql, eqlstr, rtab, tthread, tangibles, mntmap, key, val); // Check the arguments. - LS.checktable(tnmap); - LS.checktable(mtab); - LS.checktable(stab); + MLS.checktable(mtnmap); + MLS.checktable(mtab); + MLS.checktable(mstab); // Get the tangibles map. - LS.rawget(tangibles, LuaRegistry, "tangibles"); + MLS.rawget(tangibles, LuaRegistry, "tangibles"); // Invert the tnmap to make the ntmap. - LS.set(ntmap, LuaNewTable); - LS.set(key, LuaNil); - while (LS.next(tnmap, key, val)) { - LS.rawset(ntmap, val, key); + MLS.set(mntmap, LuaNewTable); + MLS.set(key, LuaNil); + while (MLS.next(mtnmap, key, val)) { + MLS.rawset(mntmap, val, key); } // Create a temporary thread to be the 'synch model'. We'll use the // existing thread as the 'master model'. lua_State *synch = lua_newthread(L); lua_replace(L, tthread.index()); - // Call tablecmp_diff. - StreamBuffer sb; - lua_pushvalue(L, tnmap.index()); - lua_pushvalue(L, stab.index()); + lua_pushvalue(L, mtnmap.index()); + lua_pushvalue(L, mstab.index()); lua_xmove(L, synch, 2); - lua_pushvalue(L, tnmap.index()); - lua_pushvalue(L, mtab.index()); - diff_tables(synch, L, true, &sb); + LuaStack SLS(synch, stnmap, stab); - patch_table(LS, tangibles, ntmap, stab, &sb); + // Call diff_tables and patch_tables + StreamBuffer sb; + diff_tables(SLS, stnmap, stab, MLS, mtnmap, mtab, true, &sb); - LS.call(eql, table_equal, stab, mtab); - bool e = LS.ckboolean(eql); + patch_table(MLS, tangibles, mntmap, mstab, &sb); + + MLS.call(eql, table_equal, mstab, mtab); + bool e = MLS.ckboolean(eql); if (e) { - LS.set(eqlstr, "tables equal"); + MLS.set(eqlstr, "tables equal"); } else { - LS.set(eqlstr, "tables were supposed to be equal"); + MLS.set(eqlstr, "tables were supposed to be equal"); } - LS.set(rtab, stab); + MLS.set(rtab, stab); - return LS.result(); + return MLS.result(); }