Added luasnap checkpointing mechanism

This commit is contained in:
2021-02-09 17:15:54 -05:00
parent 368d066cc7
commit 8f557ff387
11 changed files with 349 additions and 73 deletions

View File

@@ -38,17 +38,20 @@ int LuaStack::collect_tagged_pointer(lua_State *L) {
}
void LuaStack::register_all_userdata(lua_State *L) {
LuaVar tab, lud;
LuaStack LS(L, tab, lud);
LuaVar tab, lud, classtab, classname;
LuaStack LS(L, tab, lud, classtab, classname);
auto regs = LuaFunctionReg::all();
for (const LuaFunctionReg *r : regs) {
const std::string &name = util::tolower(r->get_name());
lua_CFunction tag = r->get_func();
std::string mode = r->get_mode();
LS.set(classname, name);
if (mode.find('t') != std::string::npos) { // Register type
LS.newtable(tab);
LS.setfield(tab, "type", name);
LS.setfield(tab, "__gc", collect_tagged_pointer);
LS.makeclass(classtab, classname);
LS.setfield(tab, "__index", classtab);
LS.setlightuserdata(lud, (void *)tag);
LS.rawset(LuaRegistry, lud, tab);
}
@@ -202,6 +205,37 @@ void LuaStack::newtable(LuaSlot target) const {
lua_replace(L_, target);
}
void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const {
int top = lua_gettop(L_);
checkstring(classname);
// Special case: if the classname is _G, return global env.
lua_pushstring(L_, "_G");
int eqlg = lua_equal(L_, -1, classname.index());
lua_settop(L_, top);
if (eqlg) {
set(classtab, LuaGlobals);
return;
}
// Get the classtab from the global environment.
// Create it if it doesn't exist.
rawget(classtab, LuaGlobals, classname);
if (isnil(classtab)) {
newtable(classtab);
rawset(LuaGlobals, classname, classtab);
}
// If the name isn't bound to a table, abort.
if (!istable(classtab)) {
luaL_error(L_, "%s is not a class", ckstring(classname).c_str());
}
// Repair the special fields.
setfield(classtab, "__index", classtab);
setfield(classtab, "__class", classname);
}
void LuaStack::setlightuserdata(LuaSlot target, void *p) const {
lua_pushlightuserdata(L_, p);
lua_replace(L_, target);