aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/util/lua_unpersist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/util/lua_unpersist.cpp')
-rw-r--r--engines/sword25/util/lua_unpersist.cpp716
1 files changed, 0 insertions, 716 deletions
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
deleted file mode 100644
index 9c304503b9..0000000000
--- a/engines/sword25/util/lua_unpersist.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/**
- * This code is heavily based on the Pluto code base. Copyright below
- */
-
-/* Tamed Pluto - Heavy-duty persistence for Lua
- * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
- * domain. People making use of this software as part of an application
- * are politely requested to email the author at sneftel@gmail.com
- * with a brief description of the application, primarily to satisfy his
- * curiosity.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Instrumented by Stefan Reich (info@luaos.net)
- * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
- */
-
-
-#include "sword25/util/lua_persistence.h"
-
-#include "sword25/util/double_serialization.h"
-#include "sword25/util/lua_persistence_util.h"
-
-#include "common/stream.h"
-
-#include "lua/lobject.h"
-#include "lua/lstate.h"
-#include "lua/lgc.h"
-#include "lua/lopcodes.h"
-
-
-namespace Lua {
-
-struct UnSerializationInfo {
- lua_State *luaState;
- Common::ReadStream *readStream;
-};
-
-static void unpersist(UnSerializationInfo *info);
-
-static void unpersistBoolean(UnSerializationInfo *info);
-static void unpersistNumber(UnSerializationInfo *info);
-static void unpersistString(UnSerializationInfo *info);
-static void unpersistTable(UnSerializationInfo *info, int index);
-static void unpersistFunction(UnSerializationInfo *info, int index);
-static void unpersistThread(UnSerializationInfo *info, int index);
-static void unpersistProto(UnSerializationInfo *info, int index);
-static void unpersistUpValue(UnSerializationInfo *info, int index);
-static void unpersistUserData(UnSerializationInfo *info, int index);
-static void unpersistPermanent(UnSerializationInfo *info, int index);
-
-
-void unpersistLua(lua_State *luaState, Common::ReadStream *readStream) {
- UnSerializationInfo info;
- info.luaState = luaState;
- info.readStream = readStream;
-
- // The process starts with the lua stack as follows:
- // >>>>> permTbl
- // That's the table of permanents
-
- // Make sure there is enough room on the stack
- lua_checkstack(luaState, 3);
-
- // Create a table to hold indexes of everything thats already been read
- lua_newtable(luaState);
- // >>>>> permTbl indexTbl
-
- // Prevent garbage collection while we unserialize
- lua_gc(luaState, LUA_GCSTOP, 0);
-
- // Unserialize the root object
- unpersist(&info);
- // >>>>> permTbl indexTbl rootObj
-
- // Re-start garbage collection
- lua_gc(luaState, LUA_GCRESTART, 0);
-
- // Remove the indexTbl
- lua_replace(luaState, 2);
- // >>>>> permTbl rootObj
-}
-
-/* The object is left on the stack. This is primarily used by unserialize, but
- * may be used by GCed objects that may incur cycles in order to preregister
- * the object. */
-static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ...... obj
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- lua_pushvalue(info->luaState, -1);
- // >>>>> permTbl indexTbl ...... obj obj
-
- // Push the k/v pair into the indexTbl
- lua_rawseti(info->luaState, 2, index);
- // >>>>> permTbl indexTbl ...... obj
-}
-
-static void unpersist(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- byte isARealValue = info->readStream->readByte();
- if (isARealValue) {
- int index = info->readStream->readSint32LE();
- int type = info->readStream->readSint32LE();
-
- switch (type) {
- case LUA_TBOOLEAN:
- unpersistBoolean(info);
- break;
- case LUA_TLIGHTUSERDATA:
- // You can't serialize a pointer
- // It would be meaningless on the next run
- assert(0);
- break;
- case LUA_TNUMBER:
- unpersistNumber(info);
- break;
- case LUA_TSTRING:
- unpersistString(info);
- break;
- case LUA_TTABLE:
- unpersistTable(info, index);
- break;
- case LUA_TFUNCTION:
- unpersistFunction(info, index);
- break;
- case LUA_TTHREAD:
- unpersistThread(info, index);
- break;
- case LUA_TPROTO:
- unpersistProto(info, index);
- break;
- case LUA_TUPVAL:
- unpersistUpValue(info, index);
- break;
- case LUA_TUSERDATA:
- unpersistUserData(info, index);
- break;
- case PERMANENT_TYPE:
- unpersistPermanent(info, index);
- break;
- default:
- assert(0);
- }
-
-
- // >>>>> permTbl indexTbl ...... obj
- assert(lua_type(info->luaState, -1) == type ||
- type == PERMANENT_TYPE ||
- // Remember, upvalues get a special dispensation, as described in boxUpValue
- (lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
-
- registerObjectInIndexTable(info, index);
- // >>>>> permTbl indexTbl ...... obj
- } else {
- int index = info->readStream->readSint32LE();
-
- if (index == 0) {
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... nil
- } else {
- // Fetch the object from the indexTbl
-
- lua_rawgeti(info->luaState, 2, index);
- // >>>>> permTbl indexTbl ...... ?obj?
-
- assert(!lua_isnil(info->luaState, -1));
- }
- // >>>>> permTbl indexTbl ...... obj/nil
- }
-
- // >>>>> permTbl indexTbl ...... obj/nil
-}
-
-static void unpersistBoolean(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- int value = info->readStream->readSint32LE();
-
- lua_pushboolean(info->luaState, value);
- // >>>>> permTbl indexTbl ...... bool
-}
-
-static void unpersistNumber(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- // Read the serialized double
- Util::SerializedDouble serializedValue;
- serializedValue.significandOne = info->readStream->readUint32LE();
- serializedValue.signAndSignificandTwo = info->readStream->readUint32LE();
- serializedValue.exponent = info->readStream->readSint16LE();
-
- lua_Number value = Util::decodeDouble(serializedValue);
-
- lua_pushnumber(info->luaState, value);
- // >>>>> permTbl indexTbl ...... num
-}
-
-static void unpersistString(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- uint32 length = info->readStream->readUint32LE();
- char *string = new char[length];
-
- info->readStream->read(string, length);
- lua_pushlstring(info->luaState, string, length);
-
- // >>>>> permTbl indexTbl ...... string
-
- delete[] string;
-}
-
-static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- unpersist(info);
-
- // >>>>> permTbl indexTbl ...... spfunc
- lua_call(info->luaState, 0, 1);
- // >>>>> permTbl indexTbl ...... tbl
-}
-
-static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 3);
-
- // Preregister table for handling of cycles
- lua_newtable(info->luaState);
-
- // >>>>> permTbl indexTbl ...... tbl
- registerObjectInIndexTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
-
- // Unserialize metatable
- unpersist(info);
- // >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
-
- if (lua_istable(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... tbl metaTbl
- lua_setmetatable(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... tbl
- } else {
- // >>>>> permTbl indexTbl ...... tbl nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
- }
- // >>>>> permTbl indexTbl ...... tbl
-
-
- while (1) {
- // >>>>> permTbl indexTbl ...... tbl
- unpersist(info);
- // >>>>> permTbl indexTbl ...... tbl key/nil
-
- // The table serialization is nil terminated
- if (lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... tbl nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
-
- break;
- }
-
- // >>>>> permTbl indexTbl ...... tbl key
- unpersist(info);
- // >>>>> permTbl indexTbl ...... tbl value
-
- lua_rawset(info->luaState, -3);
- // >>>>> permTbl indexTbl ...... tbl
- }
-}
-
-void unpersistTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- int isSpecial = info->readStream->readSint32LE();
-
- if (isSpecial) {
- unserializeSpecialTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
- } else {
- unserializeLiteralTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
- }
-}
-
-void unpersistFunction(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- byte numUpValues = info->readStream->readByte();
-
- LClosure *lclosure = (LClosure *)lua_newLclosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
- pushClosure(info->luaState, (Closure *)lclosure);
- // >>>>> permTbl indexTbl ...... func
-
- // Put *some* proto in the closure, before the GC can find it
- lclosure->p = makeFakeProto(info->luaState, numUpValues);
-
- //Also, we need to temporarily fill the upvalues
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... func nil
-
- for (byte i = 0; i < numUpValues; ++i) {
- lclosure->upvals[i] = createUpValue(info->luaState, -1);
- }
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- // I can't see offhand how a function would ever get to be self-
- // referential, but just in case let's register it early
- registerObjectInIndexTable(info, index);
-
- // Now that it's safe, we can get the real proto
- unpersist(info);
- // >>>>> permTbl indexTbl ...... func proto
-
- lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- for (byte i = 0; i < numUpValues; ++i) {
- // >>>>> permTbl indexTbl ...... func
- unpersist(info);
- // >>>>> permTbl indexTbl ...... func func2
-
- unboxUpValue(info->luaState);
- // >>>>> permTbl indexTbl ...... func upValue
- lclosure->upvals[i] = gco2uv(getObject(info->luaState, -1)->value.gc);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-
- // Finally, the fenv
- unpersist(info);
-
- // >>>>> permTbl indexTbl ...... func ?fenv/nil?
- if (!lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... func fenv
- lua_setfenv(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... func
- } else {
- // >>>>> permTbl indexTbl ...... func nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-
- // >>>>> permTbl indexTbl ...... func
-}
-
-void unpersistThread(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- lua_State *L2;
- uint32 stacklimit = 0;
-
- L2 = lua_newthread(info->luaState);
- lua_checkstack(info->luaState, 3);
-
- // L1: permTbl indexTbl ...... thread
- // L2: (empty)
- registerObjectInIndexTable(info, index);
-
- // First, deserialize the object stack
- uint32 stackSize = info->readStream->readUint32LE();
- lua_checkstack(info->luaState, (int)stackSize);
-
- // Make sure that the first stack element (a nil, representing
- // the imaginary top-level C function) is written to the very,
- // very bottom of the stack
- L2->top--;
- for (uint32 i = 0; i < stackSize; ++i) {
- unpersist(info);
- // L1: permTbl indexTbl ...... thread obj*
- }
-
- lua_xmove(info->luaState, L2, stackSize);
- // L1: permTbl indexTbl ...... thread
- // L2: obj*
-
- // Hereafter, stacks refer to L1
-
-
- // Now, deserialize the CallInfo stack
-
- uint32 numFrames = info->readStream->readUint32LE();
-
- lua_reallocCallInfo(L2, numFrames * 2);
- for (uint32 i = 0; i < numFrames; ++i) {
- CallInfo *ci = L2->base_ci + i;
- uint32 stackbase = info->readStream->readUint32LE();
- uint32 stackfunc = info->readStream->readUint32LE();
- uint32 stacktop = info->readStream->readUint32LE();
-
- ci->nresults = info->readStream->readSint32LE();
-
- uint32 savedpc = info->readStream->readUint32LE();
-
- if (stacklimit < stacktop) {
- stacklimit = stacktop;
- }
-
- ci->base = L2->stack + stackbase;
- ci->func = L2->stack + stackfunc;
- ci->top = L2->stack + stacktop;
- ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
- ci->tailcalls = 0;
-
- // Update the pointer each time, to keep the GC happy
- L2->ci = ci;
- }
-
- // >>>>> permTbl indexTbl ...... thread
- // Deserialize the state's other parameters, with the exception of upval stuff
-
- L2->savedpc = L2->ci->savedpc;
- L2->status = info->readStream->readByte();
- uint32 stackbase = info->readStream->readUint32LE();
- uint32 stacktop = info->readStream->readUint32LE();
-
-
- L2->errfunc = info->readStream->readUint32LE();
-
- L2->base = L2->stack + stackbase;
- L2->top = L2->stack + stacktop;
-
- // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
- UpVal *uv;
- GCObject **nextslot = &L2->openupval;
- global_State *g = G(L2);
-
- while (true) {
- unpersist(info);
- // >>>>> permTbl indexTbl ...... thread upVal/nil
-
- // The list is terminated by a nil
- if (lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... thread nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
- break;
- }
-
- // >>>>> permTbl indexTbl ...... thread boxedUpVal
- unboxUpValue(info->luaState);
- // >>>>> permTbl indexTbl ...... thread boxedUpVal
-
- uv = &(getObject(info->luaState, -1)->value.gc->uv);
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
-
- uint32 stackpos = info->readStream->readUint32LE();
- uv->v = L2->stack + stackpos;
-
- GCUnlink(info->luaState, (GCObject *)uv);
-
- uv->marked = luaC_white(g);
- *nextslot = (GCObject *)uv;
- nextslot = &uv->next;
- uv->u.l.prev = &G(L2)->uvhead;
- uv->u.l.next = G(L2)->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- G(L2)->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- }
- *nextslot = NULL;
-
- // The stack must be valid at least to the highest value among the CallInfos
- // 'top' and the values up to there must be filled with 'nil'
- lua_checkstack(L2, (int)stacklimit);
- for (StkId o = L2->top; o <= L2->top + stacklimit; ++o) {
- setnilvalue(o);
- }
-}
-
-void unpersistProto(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // We have to be careful. The GC expects a lot out of protos. In particular, we need
- // to give the function a valid string for its source, and valid code, even before we
- // actually read in the real code.
- TString *source = lua_newlstr(info->luaState, "", 0);
- Proto *p = lua_newproto(info->luaState);
- p->source = source;
- p->sizecode = 1;
- p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->maxstacksize = 2;
- p->sizek = 0;
- p->sizep = 0;
-
- lua_checkstack(info->luaState, 2);
-
- pushProto(info->luaState, p);
- // >>>>> permTbl indexTbl ...... proto
-
- // We don't need to register early, since protos can never ever be
- // involved in cyclic references
-
- // Read in constant references
- int sizek = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
- for (int i = 0; i < sizek; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unpersist(info);
- // >>>>> permTbl indexTbl ...... proto k
-
- setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
- p->sizek++;
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in sub-proto references
-
- int sizep = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
- for (int i = 0; i < sizep; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unpersist(info);
- // >>>>> permTbl indexTbl ...... proto subproto
-
- p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
- p->sizep++;
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- // >>>>> permTbl indexTbl ...... proto
-
-
- // Read in code
- p->sizecode = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
- info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
-
-
- /* Read in upvalue names */
- p->sizeupvalues = info->readStream->readSint32LE();
- if (p->sizeupvalues) {
- lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
- for (int i = 0; i < p->sizeupvalues; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unpersist(info);
- // >>>>> permTbl indexTbl ...... proto str
-
- p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in local variable infos
- p->sizelocvars = info->readStream->readSint32LE();
- if (p->sizelocvars) {
- lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
- for (int i = 0; i < p->sizelocvars; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unpersist(info);
- // >>>>> permTbl indexTbl ...... proto str
-
- p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- p->locvars[i].startpc = info->readStream->readSint32LE();
- p->locvars[i].endpc = info->readStream->readSint32LE();
- }
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in source string
- unpersist(info);
- // >>>>> permTbl indexTbl ...... proto sourceStr
-
- p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in line numbers
- p->sizelineinfo = info->readStream->readSint32LE();
- if (p->sizelineinfo) {
- lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
- info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
- }
-
-
- /* Read in linedefined and lastlinedefined */
- p->linedefined = info->readStream->readSint32LE();
- p->lastlinedefined = info->readStream->readSint32LE();
-
- // Read in misc values
- p->nups = info->readStream->readByte();
- p->numparams = info->readStream->readByte();
- p->is_vararg = info->readStream->readByte();
- p->maxstacksize = info->readStream->readByte();
-}
-
-void unpersistUpValue(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
- lua_checkstack(info->luaState, 2);
-
- boxUpValue_start(info->luaState);
- // >>>>> permTbl indexTbl ...... func
- registerObjectInIndexTable(info, index);
-
- unpersist(info);
- // >>>>> permTbl indexTbl ...... func obj
-
- boxUpValue_finish(info->luaState);
- // >>>>> permTbl indexTbl ...... func
-}
-
-void unpersistUserData(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- int isspecial = info->readStream->readSint32LE();
- if (isspecial) {
- unpersist(info);
- // >>>>> permTbl indexTbl ...... specialFunc
-
- lua_call(info->luaState, 0, 1);
- // >>>>> permTbl indexTbl ...... udata
- } else {
- uint32 length = info->readStream->readUint32LE();
- lua_newuserdata(info->luaState, length);
- // >>>>> permTbl indexTbl ...... udata
- registerObjectInIndexTable(info, index);
-
- info->readStream->read(lua_touserdata(info->luaState, -1), length);
-
- unpersist(info);
- // >>>>> permTbl indexTbl ...... udata metaTable/nil
-
- lua_setmetatable(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... udata
- }
- // >>>>> permTbl indexTbl ...... udata
-}
-
-void unpersistPermanent(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- unpersist(info);
- // >>>>> permTbl indexTbl ...... permKey
-
- lua_gettable(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... perm
-}
-
-} // End of namespace Lua