Added luasnap checkpointing mechanism
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user