int unpersist_l(lua_State *L) { LoadInfo li; /* perms? str? ...? */ lua_settop(L, 2); /* perms? str? */ li.buf = luaL_checklstring(L, 2, &li.size); /* perms? str */ lua_pop(L, 1); /* It is conceivable that the buffer might now be collectable, * which would cause problems in the reader. I can't think of * any situation where there would be no other reference to the * buffer, so for now I'll leave it alone, but this is a potential * bug. */ /* perms? */ luaL_checktype(L, 1, LUA_TTABLE); /* perms */ pluto_unpersist(L, bufreader, &li); /* perms rootobj */ return 1; }
bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) { // Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters lua_settop(_state, 0); // Permanents table is placed on the stack. This has already happened at this point, because // to create the table all permanents must be accessible. This is the case only for the // beginning of the function, because the global table is emptied below pushPermanentsTable(_state, PTT_UNPERSIST); // All items from global table of _G and __METATABLES are removed. // After a garbage collection is performed, and thus all managed objects deleted // __METATABLES is not immediately removed becausen the Metatables are needed // for the finalisers of objects. static const char *clearExceptionsFirstPass[] = { "_G", "__METATABLES", 0 }; clearGlobalTable(_state, clearExceptionsFirstPass); // In the second pass, the Metatables are removed static const char *clearExceptionsSecondPass[] = { "_G", 0 }; clearGlobalTable(_state, clearExceptionsSecondPass); // Persisted Lua data Common::Array<byte> chunkData; reader.readByteArray(chunkData); // Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data ChunkreaderData cd; cd.BufferPtr = &chunkData[0]; cd.Size = chunkData.size(); cd.BufferReturned = false; pluto_unpersist(_state, chunkreader, &cd); // Permanents-Table is removed from stack lua_remove(_state, -2); // The read elements in the global table about lua_pushnil(_state); while (lua_next(_state, -2) != 0) { // The referenec to the global table (_G) must not be overwritten, or ticks from Lua total bool isGlobalReference = lua_isstring(_state, -2) && strcmp(lua_tostring(_state, -2), "_G") == 0; if (!isGlobalReference) { lua_pushvalue(_state, -2); lua_pushvalue(_state, -2); lua_settable(_state, LUA_GLOBALSINDEX); } // Pop value from the stack. The index is then ready for the next call to lua_next() lua_pop(_state, 1); } // The table with the loaded data is popped from the stack lua_pop(_state, 1); // Force garbage collection lua_gc(_state, LUA_GCCOLLECT, 0); return true; }