ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

lrestore.cpp

Go to the documentation of this file.
00001 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
00002 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
00003 
00004 #include "common/endian.h"
00005 #include "common/debug.h"
00006 
00007 #include "engines/grim/savegame.h"
00008 
00009 #include "engines/grim/lua/ltask.h"
00010 #include "engines/grim/lua/lauxlib.h"
00011 #include "engines/grim/lua/lmem.h"
00012 #include "engines/grim/lua/ldo.h"
00013 #include "engines/grim/lua/ltm.h"
00014 #include "engines/grim/lua/ltable.h"
00015 #include "engines/grim/lua/lvm.h"
00016 #include "engines/grim/lua/lopcodes.h"
00017 #include "engines/grim/lua/lstring.h"
00018 #include "engines/grim/lua/lstate.h"
00019 #include "engines/grim/lua/lua.h"
00020 
00021 namespace Grim {
00022 
00023 static void restoreObjectValue(TObject *object, SaveGame *savedState) {
00024     object->ttype = (lua_Type)savedState->readLESint32();
00025 
00026     switch (object->ttype) {
00027         case LUA_T_NUMBER:
00028         case LUA_T_TASK:
00029             {
00030                 object->value.n = savedState->readFloat();
00031             }
00032             break;
00033         case LUA_T_NIL:
00034             {
00035                 object->value.ts = nullptr;
00036             }
00037             break;
00038         case LUA_T_ARRAY:
00039             {
00040                 PointerId ptr;
00041                 ptr.id = savedState->readLEUint64();
00042                 object->value.a = (Hash *)makePointerFromId(ptr);
00043             }
00044             break;
00045         case LUA_T_USERDATA:
00046             {
00047                 object->value.ud.id = savedState->readLESint32();
00048                 object->value.ud.tag = savedState->readLESint32();
00049                 if (savedState->saveMinorVersion() == 0) {
00050                     savedState->readLEUint32();
00051                     savedState->readLEUint32();
00052                 }
00053             }
00054             break;
00055         case LUA_T_STRING:
00056             {
00057                 PointerId ptr;
00058                 ptr.id = savedState->readLEUint64();
00059                 object->value.ts = (TaggedString *)makePointerFromId(ptr);
00060             }
00061             break;
00062         case LUA_T_PROTO:
00063         case LUA_T_PMARK:
00064             {
00065                 PointerId ptr;
00066                 ptr.id = savedState->readLEUint64();
00067                 object->value.tf = (TProtoFunc *)makePointerFromId(ptr);
00068             }
00069             break;
00070         case LUA_T_CPROTO:
00071         case LUA_T_CMARK:
00072             {
00073                 PointerId ptr;
00074                 ptr.id = savedState->readLEUint64();
00075 
00076                 // WORKAROUND: C++ forbids casting from a pointer-to-function to a
00077                 // pointer-to-object. We use a union to work around that.
00078                 union {
00079                     void *objPtr;
00080                     lua_CFunction funcPtr;
00081                 } ptrUnion;
00082 
00083                 ptrUnion.objPtr = makePointerFromId(ptr);
00084                 object->value.f = ptrUnion.funcPtr;
00085             }
00086             break;
00087         case LUA_T_CLOSURE:
00088         case LUA_T_CLMARK:
00089             {
00090                 PointerId ptr;
00091                 ptr.id = savedState->readLEUint64();
00092                 object->value.cl = (Closure *)makePointerFromId(ptr);
00093             }
00094             break;
00095         case LUA_T_LINE:
00096             {
00097                 object->value.i = savedState->readLESint32();
00098             }
00099             break;
00100         default:
00101             PointerId ptr;
00102             ptr.id = savedState->readLEUint64();
00103             object->value.ts = (TaggedString *)makePointerFromId(ptr);
00104     }
00105 }
00106 
00107 struct ArrayIDObj {
00108     void *object;
00109     PointerId idObj;
00110 };
00111 
00112 static int sortCallback(const void *id1, const void *id2) {
00113     if (((const ArrayIDObj *)id1)->idObj.id > ((const ArrayIDObj *)id2)->idObj.id) {
00114         return 1;
00115     } else if (((const ArrayIDObj *)id1)->idObj.id < ((const ArrayIDObj *)id2)->idObj.id) {
00116         return -1;
00117     } else {
00118         return 0;
00119     }
00120 }
00121 
00122 int32 arrayHashTablesCount = 0;
00123 int32 arrayProtoFuncsCount = 0;
00124 int32 arrayClosuresCount = 0;
00125 int32 arrayStringsCount = 0;
00126 ArrayIDObj *arrayStrings = nullptr;
00127 ArrayIDObj *arrayHashTables = nullptr;
00128 ArrayIDObj *arrayClosures = nullptr;
00129 ArrayIDObj *arrayProtoFuncs = nullptr;
00130 static bool arraysAllreadySort = false;
00131 
00132 static void recreateObj(TObject *obj) {
00133     if (obj->ttype == LUA_T_CPROTO) {
00134         uintptr id = ((uintptr)(obj->value.f)) >> 16;
00135         luaL_libList *list = list_of_libs;
00136         while (list) {
00137             if (id == 0)
00138                 break;
00139             id--;
00140             list = list->next;
00141         }
00142 
00143         int32 numberFunc = (uintptr)(obj->value.f) & 0xffff;
00144         if (list && id == 0 && numberFunc < list->number) {
00145             obj->value.f = list->list[numberFunc].func;
00146         } else {
00147             obj->value.f = nullptr;
00148             assert(obj->value.f);
00149         }
00150     } else if (obj->ttype == LUA_T_NIL || obj->ttype == LUA_T_LINE || obj->ttype == LUA_T_NUMBER ||
00151             obj->ttype == LUA_T_TASK || obj->ttype == LUA_T_USERDATA) {
00152         return;
00153     } else {
00154         if (obj->value.i == 0)
00155             return;
00156 
00157         if (!arraysAllreadySort) {
00158             arraysAllreadySort = true;
00159             qsort(arrayHashTables, arrayHashTablesCount, sizeof(ArrayIDObj), sortCallback);
00160             qsort(arrayProtoFuncs, arrayProtoFuncsCount, sizeof(ArrayIDObj), sortCallback);
00161             qsort(arrayClosures, arrayClosuresCount, sizeof(ArrayIDObj), sortCallback);
00162             qsort(arrayStrings, arrayStringsCount, sizeof(ArrayIDObj), sortCallback);
00163         }
00164 
00165         ArrayIDObj *found;
00166         ArrayIDObj tmpId;
00167         tmpId.object = nullptr;
00168 
00169         switch (obj->ttype) {
00170         case LUA_T_PMARK:
00171             tmpId.idObj = makeIdFromPointer(obj->value.tf);
00172             found = (ArrayIDObj *)bsearch(&tmpId, arrayProtoFuncs, arrayProtoFuncsCount, sizeof(ArrayIDObj), sortCallback);
00173             assert(found);
00174             obj->value.tf = (TProtoFunc *)found->object;
00175             break;
00176         case LUA_T_PROTO:
00177             tmpId.idObj = makeIdFromPointer(obj->value.tf);
00178             found = (ArrayIDObj *)bsearch(&tmpId, arrayProtoFuncs, arrayProtoFuncsCount, sizeof(ArrayIDObj), sortCallback);
00179             assert(found);
00180             obj->value.tf = (TProtoFunc *)found->object;
00181             break;
00182         case LUA_T_CLOSURE:
00183             tmpId.idObj = makeIdFromPointer(obj->value.cl);
00184             found = (ArrayIDObj *)bsearch(&tmpId, arrayClosures, arrayClosuresCount, sizeof(ArrayIDObj), sortCallback);
00185             assert(found);
00186             obj->value.cl = (Closure *)found->object;
00187             break;
00188         case LUA_T_ARRAY:
00189             tmpId.idObj = makeIdFromPointer(obj->value.a);
00190             found = (ArrayIDObj *)bsearch(&tmpId, arrayHashTables, arrayHashTablesCount, sizeof(ArrayIDObj), sortCallback);
00191             assert(found);
00192             obj->value.a = (Hash *)found->object;
00193             break;
00194         case LUA_T_STRING:
00195             tmpId.idObj = makeIdFromPointer(obj->value.ts);
00196             found = (ArrayIDObj *)bsearch(&tmpId, arrayStrings, arrayStringsCount, sizeof(ArrayIDObj), sortCallback);
00197             assert(found);
00198             obj->value.ts = (TaggedString *)found->object;
00199             break;
00200         default:
00201             obj->value.i = 0;
00202             obj->value.ts = nullptr;
00203             return;
00204         }
00205     }
00206 }
00207 
00208 void lua_Restore(SaveGame *savedState) {
00209     savedState->beginSection('LUAS');
00210 
00211     lua_close();
00212     lua_rootState = lua_state = luaM_new(LState);
00213     lua_stateinit(lua_state);
00214     lua_resetglobals();
00215 
00216     arrayStringsCount = savedState->readLESint32();
00217     arrayClosuresCount = savedState->readLESint32();
00218     arrayHashTablesCount = savedState->readLESint32();
00219     arrayProtoFuncsCount = savedState->readLESint32();
00220     int32 rootGlobalCount = savedState->readLESint32();
00221 
00222     arrayStrings = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayStringsCount);
00223     ArrayIDObj *arraysObj = arrayStrings;
00224     int32 maxStringsLength;
00225     maxStringsLength = savedState->readLESint32();
00226     char *tempStringBuffer = (char *)luaM_malloc(maxStringsLength + 1); // add extra char for 0 terminate string
00227 
00228     //printf("1: %d\n", g_grim->_savedState->getBufferPos());
00229 
00230     int32 i;
00231     for (i = 0; i < arrayStringsCount; i++) {
00232         arraysObj->idObj.id = savedState->readLEUint64();
00233         int32 constIndex = savedState->readLESint32();
00234 
00235         TaggedString *tempString = nullptr;
00236         if (constIndex != -1) {
00237             TObject obj;
00238             restoreObjectValue(&obj, savedState);
00239             int32 length = savedState->readLESint32();
00240             savedState->read(tempStringBuffer, length);
00241             tempStringBuffer[length] = '\0';
00242             tempString = luaS_new(tempStringBuffer);
00243             tempString->globalval = obj;
00244         }
00245         assert(tempString);
00246         tempString->constindex = constIndex;
00247         arraysObj->object = tempString;
00248         arraysObj++;
00249     }
00250     luaM_free(tempStringBuffer);
00251 
00252     //printf("2: %d\n", g_grim->_savedState->getBufferPos());
00253 
00254     int32 l;
00255     Closure *tempClosure;
00256     GCnode *prevClosure = &rootcl;
00257     arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayClosuresCount);
00258     arrayClosures = arraysObj;
00259     for (i = 0; i < arrayClosuresCount; i++) {
00260         arraysObj->idObj.id = savedState->readLEUint64();
00261         int32 countElements = savedState->readLESint32();
00262         tempClosure = (Closure *)luaM_malloc((countElements * sizeof(TObject)) + sizeof(Closure));
00263         luaO_insertlist(prevClosure, (GCnode *)tempClosure);
00264         prevClosure = (GCnode *)tempClosure;
00265 
00266         tempClosure->nelems = countElements;
00267         for (l = 0; l <= tempClosure->nelems; l++) {
00268             restoreObjectValue(&tempClosure->consts[l], savedState);
00269         }
00270         arraysObj->object = tempClosure;
00271         arraysObj++;
00272     }
00273 
00274     Hash *tempHash;
00275     GCnode *prevHash = &roottable;
00276     arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayHashTablesCount);
00277     arrayHashTables = arraysObj;
00278     for (i = 0; i < arrayHashTablesCount; i++) {
00279         arraysObj->idObj.id = savedState->readLEUint64();
00280         tempHash = luaM_new(Hash);
00281         tempHash->nhash = savedState->readLESint32();
00282         tempHash->nuse = savedState->readLESint32();
00283         tempHash->htag = savedState->readLESint32();
00284         tempHash->node = hashnodecreate(tempHash->nhash);
00285         luaO_insertlist(prevHash, (GCnode *)tempHash);
00286         prevHash = (GCnode *)tempHash;
00287 
00288         for (l = 0; l < tempHash->nuse; l++) {
00289             restoreObjectValue(&tempHash->node[l].ref, savedState);
00290             restoreObjectValue(&tempHash->node[l].val, savedState);
00291         }
00292         arraysObj->object = tempHash;
00293         arraysObj++;
00294     }
00295 
00296     TProtoFunc *tempProtoFunc;
00297     GCnode *oldProto = &rootproto;
00298     arrayProtoFuncs = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayProtoFuncsCount);
00299     arraysObj = arrayProtoFuncs;
00300     for (i = 0; i < arrayProtoFuncsCount; i++) {
00301         arraysObj->idObj.id = savedState->readLEUint64();
00302         tempProtoFunc = luaM_new(TProtoFunc);
00303         luaO_insertlist(oldProto, (GCnode *)tempProtoFunc);
00304         oldProto = (GCnode *)tempProtoFunc;
00305         PointerId ptr;
00306         ptr.id = savedState->readLEUint64();
00307         tempProtoFunc->fileName = (TaggedString *)makePointerFromId(ptr);
00308         tempProtoFunc->lineDefined = savedState->readLESint32();
00309         tempProtoFunc->nconsts = savedState->readLESint32();
00310         if (tempProtoFunc->nconsts > 0) {
00311             tempProtoFunc->consts = (TObject *)luaM_malloc(tempProtoFunc->nconsts * sizeof(TObject));
00312         } else {
00313             tempProtoFunc->consts = nullptr;
00314         }
00315 
00316         for (l = 0; l < tempProtoFunc->nconsts; l++) {
00317             restoreObjectValue(&tempProtoFunc->consts[l], savedState);
00318         }
00319 
00320         int32 countVariables = savedState->readLESint32();
00321         if (countVariables) {
00322             tempProtoFunc->locvars = (LocVar *)luaM_malloc(countVariables * sizeof(LocVar));
00323         } else {
00324             tempProtoFunc->locvars = nullptr;
00325         }
00326 
00327         for (l = 0; l < countVariables; l++) {
00328             ptr.id = savedState->readLEUint64();
00329             tempProtoFunc->locvars[l].varname = (TaggedString *)makePointerFromId(ptr);
00330             tempProtoFunc->locvars[l].line = savedState->readLESint32();
00331         }
00332 
00333         int32 codeSize = savedState->readLESint32();
00334         tempProtoFunc->code = (byte *)luaM_malloc(codeSize);
00335         savedState->read(tempProtoFunc->code, codeSize);
00336         arraysObj->object = tempProtoFunc;
00337         arraysObj++;
00338     }
00339 
00340     for (i = 0; i < NUM_HASHS; i++) {
00341         stringtable *tempStringTable = &string_root[i];
00342         for (l = 0; l < tempStringTable->size; l++) {
00343             TaggedString *tempString = tempStringTable->hash[l];
00344             if (tempString && tempString->constindex != -1 && tempString != &EMPTY) {
00345                 recreateObj(&tempString->globalval);
00346             }
00347         }
00348     }
00349 
00350     tempProtoFunc = (TProtoFunc *)rootproto.next;
00351     while (tempProtoFunc) {
00352         TObject tempObj;
00353         tempObj.value.ts = (TaggedString *)tempProtoFunc->fileName;
00354         tempObj.ttype = LUA_T_STRING;
00355         recreateObj(&tempObj);
00356         tempProtoFunc->fileName = (TaggedString *)tempObj.value.ts;
00357         for (i = 0; i < tempProtoFunc->nconsts; i++) {
00358             recreateObj(&tempProtoFunc->consts[i]);
00359         }
00360 
00361         if (tempProtoFunc->locvars) {
00362             for (i = 0; tempProtoFunc->locvars[i].line != -1; i++) {
00363                 TObject tempObj2;
00364                 tempObj2.value.ts = tempProtoFunc->locvars[i].varname;
00365                 tempObj2.ttype = LUA_T_STRING;
00366                 recreateObj(&tempObj2);
00367                 tempProtoFunc->locvars[i].varname = (TaggedString *)tempObj2.value.ts;
00368             }
00369         }
00370         tempProtoFunc = (TProtoFunc *)tempProtoFunc->head.next;
00371     }
00372 
00373     tempHash = (Hash *)roottable.next;
00374     while (tempHash) {
00375         for (i = 0; i < tempHash->nuse; i++) {
00376             recreateObj(&tempHash->node[i].ref);
00377             recreateObj(&tempHash->node[i].val);
00378         }
00379         Node *oldNode = tempHash->node;
00380         tempHash->node = hashnodecreate(tempHash->nhash);
00381         for (i = 0; i < tempHash->nuse; i++) {
00382             Node *newNode = oldNode + i;
00383             if (newNode->ref.ttype != LUA_T_NIL && newNode->val.ttype != LUA_T_NIL) {
00384                 *node(tempHash, present(tempHash, &newNode->ref)) = *newNode;
00385             }
00386         }
00387         luaM_free(oldNode);
00388         tempHash = (Hash *)tempHash->head.next;
00389     }
00390 
00391     tempClosure = (Closure *)rootcl.next;
00392     while (tempClosure) {
00393         for (i = 0; i <= tempClosure->nelems; i++) {
00394             recreateObj(&tempClosure->consts[i]);
00395         }
00396         tempClosure = (Closure *)tempClosure->head.next;
00397     }
00398 
00399     TaggedString *tempListString = (TaggedString *)&(rootglobal);
00400     for (i = 0; i < rootGlobalCount; i++) {
00401         TObject tempObj;
00402         TaggedString *tempString = nullptr;
00403         tempObj.ttype = LUA_T_STRING;
00404         PointerId ptr;
00405         ptr.id = savedState->readLEUint64();
00406         tempObj.value.ts = (TaggedString *)makePointerFromId(ptr);
00407         recreateObj(&tempObj);
00408         tempString = (TaggedString *)tempObj.value.ts;
00409         assert(tempString);
00410         tempListString->head.next = (GCnode *)tempString;
00411         tempListString = tempString;
00412     }
00413     tempListString->head.next = nullptr;
00414 
00415     restoreObjectValue(&errorim, savedState);
00416     recreateObj(&errorim);
00417 
00418     IMtable_size = savedState->readLESint32();
00419     if (IMtable_size > 0) {
00420         IMtable = (IM *)luaM_malloc(IMtable_size * sizeof(IM));
00421         for (i = 0; i < IMtable_size; i++) {
00422             IM *im = &IMtable[i];
00423             for (l = 0; l < IM_N; l++) {
00424                 restoreObjectValue(&im->int_method[l], savedState);
00425                 recreateObj(&im->int_method[l]);
00426             }
00427         }
00428     } else {
00429         IMtable = nullptr;
00430     }
00431 
00432     last_tag = savedState->readLESint32();
00433     refSize = savedState->readLESint32();
00434     if (refSize > 0) {
00435         refArray = (ref *)luaM_malloc(refSize * sizeof(ref));
00436         for (i = 0; i < refSize; i++) {
00437             restoreObjectValue(&refArray[i].o, savedState);
00438             recreateObj(&refArray[i].o);
00439             refArray[i].status = (Status)savedState->readLESint32();
00440         }
00441     } else {
00442         refArray = nullptr;
00443     }
00444 
00445     GCthreshold = savedState->readLESint32();
00446     nblocks = savedState->readLESint32();
00447 
00448     Mbuffsize = savedState->readLESint32();
00449     Mbuffer = (char *)luaM_malloc(Mbuffsize);
00450     savedState->read(Mbuffer, Mbuffsize);
00451     int32 MbaseOffset;
00452     MbaseOffset = savedState->readLESint32();
00453     Mbuffbase = MbaseOffset + Mbuffer;
00454     Mbuffnext = savedState->readLESint32();
00455 
00456     globalTaskSerialId = savedState->readLESint32();
00457 
00458     int32 countStates = savedState->readLESint32();
00459     int32 currentState = savedState->readLESint32();
00460 
00461     LState *state = lua_rootState;
00462     for (l = 0; l < countStates; l++) {
00463         if (l == 0)
00464             state = lua_rootState;
00465         else {
00466             LState *s = luaM_new(LState);
00467             lua_stateinit(s);
00468             state->next = s;
00469             s->prev = state;
00470             state = s;
00471         }
00472         int32 countTasks = savedState->readLESint32();
00473         if (countTasks) {
00474             lua_Task *task = nullptr;
00475             for (i = 0; i < countTasks; i++) {
00476                 if (i == 0) {
00477                     task = state->task = luaM_new(lua_Task);
00478                     lua_taskinit(task, nullptr, 0, 0);
00479                 } else {
00480                     lua_Task *t = luaM_new(lua_Task);
00481                     lua_taskinit(t, nullptr, 0, 0);
00482                     task->next = t;
00483                     task = t;
00484                 }
00485 
00486                 task->S = &state->stack;
00487 
00488                 TObject tempObj;
00489                 tempObj.ttype = LUA_T_CLOSURE;
00490                 PointerId ptr;
00491                 ptr.id = savedState->readLEUint64();
00492                 tempObj.value.cl = (Closure *)makePointerFromId(ptr);
00493                 recreateObj(&tempObj);
00494                 task->cl = (Closure *)tempObj.value.cl;
00495                 tempObj.ttype = LUA_T_PROTO;
00496                 ptr.id = savedState->readLEUint64();
00497                 tempObj.value.tf = (TProtoFunc *)makePointerFromId(ptr);
00498                 recreateObj(&tempObj);
00499                 task->tf = (TProtoFunc *)tempObj.value.tf;
00500 
00501                 task->base = savedState->readLESint32();
00502                 task->some_base = savedState->readLESint32();
00503                 task->some_results = savedState->readLESint32();
00504                 task->some_flag = savedState->readBool();
00505                 int32 pcOffset = savedState->readLESint32();
00506                 task->pc = task->tf->code + pcOffset;
00507                 task->aux = savedState->readLESint32();
00508                 task->consts = task->tf->consts;
00509             }
00510         } else {
00511             state->task = nullptr;
00512         }
00513         int32 n = savedState->readLESint32();
00514         if (n < 0) {
00515             state->some_task = nullptr;
00516         } else {
00517             state->some_task = state->task;
00518             for (; n; n--)
00519                 state->some_task = state->some_task->next;
00520         }
00521 
00522         state->updated = savedState->readBool();
00523 
00524         byte pauseState = savedState->readByte();
00525         state->all_paused = pauseState & LUA_SG_ALL_PAUSED;
00526         state->paused = (pauseState & LUA_SG_PAUSED) ? true : false;
00527 
00528         state->state_counter1 = savedState->readLESint32();
00529         state->state_counter2 = savedState->readLESint32();
00530 
00531         int32 stackLastSize = savedState->readLESint32();
00532         if (state->stack.stack)
00533             luaM_free(state->stack.stack);
00534 
00535         state->stack.stack = (TObject *)luaM_malloc(stackLastSize * sizeof(TObject));
00536         state->stack.last = state->stack.stack + stackLastSize - 1;
00537 
00538         int32 stackTopSize = savedState->readLESint32();
00539         state->stack.top = state->stack.stack + stackTopSize;
00540         for (i = 0; i < stackTopSize; i++) {
00541             restoreObjectValue(&state->stack.stack[i], savedState);
00542             recreateObj(&state->stack.stack[i]);
00543         }
00544 
00545         state->Cstack.base = savedState->readLESint32();
00546         state->Cstack.lua2C = savedState->readLESint32();
00547         state->Cstack.num = savedState->readLESint32();
00548 
00549         state->numCblocks = savedState->readLESint32();
00550         for (i = 0; i < state->numCblocks; i++) {
00551             state->Cblocks[i].base = savedState->readLESint32();
00552             state->Cblocks[i].lua2C = savedState->readLESint32();
00553             state->Cblocks[i].num = savedState->readLESint32();
00554         }
00555 
00556         if (savedState->saveMinorVersion() >= 3) {
00557             state->sleepFor = savedState->readLEUint32();
00558         }
00559         state->id = savedState->readLEUint32();
00560         restoreObjectValue(&state->taskFunc, savedState);
00561         if (state->taskFunc.ttype == LUA_T_PROTO || state->taskFunc.ttype == LUA_T_CPROTO)
00562             recreateObj(&state->taskFunc);
00563     }
00564 
00565     for (; currentState; currentState--)
00566         lua_state = lua_state->next;
00567 
00568     arraysAllreadySort = false;
00569     arrayStringsCount = 0;
00570     arrayHashTablesCount = 0;
00571     arrayClosuresCount = 0;
00572     arrayProtoFuncsCount = 0;
00573     luaM_free(arrayClosures);
00574     luaM_free(arrayStrings);
00575     luaM_free(arrayHashTables);
00576     luaM_free(arrayProtoFuncs);
00577     arrayHashTables = nullptr;
00578     arrayClosures = nullptr;
00579     arrayProtoFuncs = nullptr;
00580     arrayStrings = nullptr;
00581 
00582     savedState->endSection();
00583 }
00584 
00585 } // end of namespace Grim


Generated on Sat Oct 12 2019 05:00:50 for ResidualVM by doxygen 1.7.1
curved edge   curved edge