2004-12-25 18:23:07 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <search.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "ltask.h"
|
|
|
|
#include "lauxlib.h"
|
|
|
|
#include "lmem.h"
|
|
|
|
#include "ldo.h"
|
|
|
|
#include "ltm.h"
|
|
|
|
#include "ltable.h"
|
|
|
|
#include "lvm.h"
|
|
|
|
#include "lopcodes.h"
|
|
|
|
#include "lstring.h"
|
|
|
|
|
|
|
|
SaveRestoreCallback saveCallback = NULL;
|
|
|
|
|
2004-12-30 08:04:55 +00:00
|
|
|
static void saveObjectValue(TObject *object, SaveRestoreFunc saveFunc) {
|
|
|
|
saveFunc(&object->ttype, sizeof(lua_Type));
|
|
|
|
if (object->ttype == LUA_T_CPROTO) {
|
|
|
|
luaL_libList *list = list_of_libs;
|
|
|
|
unsigned int idObj = 0;
|
|
|
|
while (list != NULL) {
|
|
|
|
for (int l = 0; l < list->number; l++) {
|
|
|
|
if (list->list[l].func == object->value.f) {
|
|
|
|
idObj = (idObj << 16) | l;
|
|
|
|
saveFunc(&idObj, sizeof(unsigned int));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
idObj++;
|
|
|
|
}
|
|
|
|
assert(0);
|
|
|
|
} else {
|
|
|
|
saveFunc(&object->value, sizeof(Value));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int opcodeSizeTable[] = {
|
|
|
|
1, 2, 1, 2, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1,
|
|
|
|
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3,
|
|
|
|
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
3, 2, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
|
|
|
|
1, 1, 1, 3, 1, 2, 3, 2, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
1, 1, 1, 1, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 1, 1,
|
|
|
|
3, 2, 2, 2, 2, 3, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 3, 2, 1, 1,
|
|
|
|
1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3,
|
|
|
|
2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 1, 1, 1,
|
|
|
|
1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 3, 2, 4, 2, 1,
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 3, 2, 3,
|
|
|
|
2, 3, 2, 3, 2, 3, 2, 1, 1, 3, 2, 2, 2, 2, 3, 2, 1, 1
|
|
|
|
};
|
|
|
|
|
2004-12-25 18:23:07 +00:00
|
|
|
void lua_Save(SaveRestoreFunc saveFunc) {
|
2005-01-14 10:51:20 +00:00
|
|
|
printf("lua_Save() started.\n");
|
2004-12-30 08:04:55 +00:00
|
|
|
|
|
|
|
lua_collectgarbage(0);
|
|
|
|
int i, l;
|
|
|
|
int countElements = 0;
|
|
|
|
int maxStringLength = 0;
|
|
|
|
for (i = 0; i < NUM_HASHS; i++) {
|
|
|
|
stringtable *tempStringTable = &L->string_root[i];
|
|
|
|
for (int l = 0; l < tempStringTable->size; l++) {
|
|
|
|
if ((tempStringTable->hash[l] != NULL) && (tempStringTable->hash[l] != &EMPTY)) {
|
|
|
|
countElements++;
|
|
|
|
if (tempStringTable->hash[l]->constindex != -1) {
|
|
|
|
if (maxStringLength < tempStringTable->hash[l]->u.s.len) {
|
|
|
|
maxStringLength = tempStringTable->hash[l]->u.s.len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
saveFunc(&countElements, sizeof(int));
|
|
|
|
countElements = 0;
|
|
|
|
|
|
|
|
GCnode *tempNode;
|
|
|
|
tempNode = L->rootcl.next;
|
|
|
|
while (tempNode != NULL) {
|
|
|
|
countElements++;
|
|
|
|
tempNode = tempNode->next;
|
|
|
|
}
|
|
|
|
saveFunc(&countElements, sizeof(int));
|
|
|
|
countElements = 0;
|
|
|
|
|
|
|
|
tempNode = L->roottable.next;
|
|
|
|
while (tempNode != NULL) {
|
|
|
|
countElements++;
|
|
|
|
tempNode = tempNode->next;
|
|
|
|
}
|
|
|
|
saveFunc(&countElements, sizeof(int));
|
|
|
|
countElements = 0;
|
|
|
|
|
|
|
|
tempNode = L->rootproto.next;
|
|
|
|
while (tempNode != NULL) {
|
|
|
|
countElements++;
|
|
|
|
tempNode = tempNode->next;
|
|
|
|
}
|
|
|
|
saveFunc(&countElements, sizeof(int));
|
|
|
|
countElements = 0;
|
|
|
|
|
|
|
|
tempNode = L->rootglobal.next;
|
|
|
|
while (tempNode != NULL) {
|
|
|
|
countElements++;
|
|
|
|
tempNode = tempNode->next;
|
|
|
|
}
|
|
|
|
saveFunc(&countElements, sizeof(int));
|
|
|
|
|
|
|
|
saveFunc(&maxStringLength, sizeof(int));
|
|
|
|
|
|
|
|
TaggedString *tempString;
|
|
|
|
for (i = 0; i < NUM_HASHS; i++) {
|
|
|
|
stringtable *tempStringTable = &L->string_root[i];
|
|
|
|
for (l = 0; l < tempStringTable->size; l++) {
|
|
|
|
if ((tempStringTable->hash[l] != NULL) && (tempStringTable->hash[l] != &EMPTY)) {
|
|
|
|
tempString = tempStringTable->hash[l];
|
|
|
|
saveFunc(&tempString, sizeof(TaggedString *));
|
|
|
|
saveFunc(&tempString->constindex, sizeof(int));
|
|
|
|
if (tempString->constindex != -1) {
|
|
|
|
saveObjectValue(&tempString->u.s.globalval, saveFunc);
|
|
|
|
saveFunc(&tempString->u.s.len, sizeof(long));
|
|
|
|
saveFunc(tempString->str, tempString->u.s.len);
|
|
|
|
} else {
|
|
|
|
if (saveCallback != NULL) {
|
|
|
|
tempString->u.s.globalval.value.ts = (TaggedString *)saveCallback(tempString->u.s.globalval.ttype, (int)tempString->u.s.globalval.value.ts, saveFunc);
|
|
|
|
}
|
|
|
|
saveObjectValue(&tempString->u.s.globalval, saveFunc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-04 22:42:47 +00:00
|
|
|
Closure *tempClosure = (Closure *)L->rootcl.next;
|
2004-12-30 08:04:55 +00:00
|
|
|
while (tempClosure != NULL) {
|
|
|
|
saveFunc(&tempClosure, sizeof(Closure *));
|
|
|
|
saveFunc(&tempClosure->nelems, sizeof(int));
|
|
|
|
for(i = 0; i <= tempClosure->nelems; i++) {
|
|
|
|
saveObjectValue(&tempClosure->consts[i], saveFunc);
|
|
|
|
}
|
|
|
|
tempClosure = (Closure *)tempClosure->head.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
Hash *tempHash = (Hash *)L->roottable.next;
|
|
|
|
while (tempHash != NULL) {
|
|
|
|
saveFunc(&tempHash, sizeof(Hash *));
|
|
|
|
saveFunc(&tempHash->nhash, sizeof(unsigned int));
|
|
|
|
int countUsedHash = 0;
|
|
|
|
for(i = 0; i < tempHash->nhash; i++) {
|
|
|
|
Node *newNode = &tempHash->node[i];
|
|
|
|
if ((newNode->ref.ttype != LUA_T_NIL) && (newNode->val.ttype != LUA_T_NIL)) {
|
|
|
|
countUsedHash++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
saveFunc(&countUsedHash, sizeof(int));
|
|
|
|
saveFunc(&tempHash->htag, sizeof(int));
|
|
|
|
for (i = 0; i < tempHash->nhash; i++) {
|
|
|
|
Node *newNode = &tempHash->node[i];
|
|
|
|
if ((newNode->val.ttype != LUA_T_NIL) && (newNode->ref.ttype != LUA_T_NIL)) {
|
|
|
|
saveObjectValue(&tempHash->node[i].ref, saveFunc);
|
|
|
|
saveObjectValue(&tempHash->node[i].val, saveFunc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tempHash = (Hash *)tempHash->head.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
TProtoFunc *tempProtoFunc = (TProtoFunc *)L->rootproto.next;
|
|
|
|
while (tempProtoFunc != NULL) {
|
|
|
|
saveFunc(&tempProtoFunc, sizeof(TProtoFunc *));
|
|
|
|
saveFunc(&tempProtoFunc->fileName, sizeof(TaggedString *));
|
|
|
|
saveFunc(&tempProtoFunc->lineDefined, sizeof(unsigned int));
|
|
|
|
saveFunc(&tempProtoFunc->nconsts, sizeof(unsigned int));
|
|
|
|
for (i = 0; i < tempProtoFunc->nconsts; i++) {
|
|
|
|
saveObjectValue(&tempProtoFunc->consts[i], saveFunc);
|
|
|
|
}
|
|
|
|
int countVariables = 0;
|
|
|
|
if (tempProtoFunc->locvars) {
|
|
|
|
for (; tempProtoFunc->locvars[countVariables++].line != -1;) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
saveFunc(&countVariables, sizeof(int));
|
|
|
|
for (i = 0; i < countVariables; i++) {
|
|
|
|
saveFunc(&tempProtoFunc->locvars[i].varname, sizeof(TaggedString *));
|
|
|
|
saveFunc(&tempProtoFunc->locvars[i].line, sizeof(int));
|
|
|
|
}
|
|
|
|
|
|
|
|
Byte *codePtr = tempProtoFunc->code + 2;
|
|
|
|
Byte *tmpPtr = codePtr;
|
|
|
|
int opcodeId;
|
|
|
|
do {
|
|
|
|
opcodeId = *tmpPtr;
|
|
|
|
tmpPtr += opcodeSizeTable[opcodeId];
|
|
|
|
} while (opcodeId != ENDCODE);
|
|
|
|
int codeSize = (tmpPtr - codePtr) + 2;
|
|
|
|
saveFunc(&codeSize, sizeof(int));
|
|
|
|
saveFunc(tempProtoFunc->code, codeSize);
|
|
|
|
tempProtoFunc = (TProtoFunc *)tempProtoFunc->head.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
tempString = (TaggedString *)L->rootglobal.next;
|
|
|
|
while (tempString != NULL) {
|
|
|
|
saveFunc(&tempString, sizeof(TaggedString *));
|
|
|
|
tempString = (TaggedString *)tempString->head.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
saveObjectValue(&L->errorim, saveFunc);
|
|
|
|
|
|
|
|
IM *tempIm = L->IMtable;
|
|
|
|
saveFunc(&L->IMtable_size, sizeof(int));
|
|
|
|
for (i = 0; i < L->IMtable_size; i++) {
|
|
|
|
for (l = 0; l < IM_N; l++) {
|
|
|
|
saveObjectValue(&tempIm->int_method[l], saveFunc);
|
|
|
|
}
|
|
|
|
tempIm++;
|
|
|
|
}
|
|
|
|
|
|
|
|
saveFunc(&L->last_tag, sizeof(int));
|
|
|
|
saveFunc(&L->refSize, sizeof(int));
|
|
|
|
for (i = 0 ; i < L->refSize; i++) {
|
|
|
|
saveObjectValue(&L->refArray[i].o, saveFunc);
|
|
|
|
saveFunc(&L->refArray[i].status, sizeof(Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
saveFunc(&L->GCthreshold, sizeof(unsigned long));
|
|
|
|
saveFunc(&L->nblocks, sizeof(unsigned long));
|
|
|
|
|
|
|
|
saveFunc(&L->Mbuffsize, sizeof(int));
|
|
|
|
saveFunc(L->Mbuffer, L->Mbuffsize);
|
|
|
|
int MbaseOffset = L->Mbuffbase - L->Mbuffer;
|
|
|
|
saveFunc(&MbaseOffset, sizeof(int));
|
|
|
|
saveFunc(&L->Mbuffnext, sizeof(int));
|
|
|
|
|
|
|
|
int countTasks = 0;
|
|
|
|
lua_Task *tempTask = L->root_task->next;
|
|
|
|
while (tempTask != NULL) {
|
|
|
|
countTasks++;
|
|
|
|
tempTask = tempTask->next;
|
|
|
|
}
|
|
|
|
saveFunc(&countTasks, sizeof(int));
|
|
|
|
|
|
|
|
tempTask = L->root_task->next;
|
|
|
|
while (tempTask != NULL) {
|
|
|
|
int stackLastSize = (tempTask->stack.last - tempTask->stack.stack) + 1;
|
|
|
|
saveFunc(&stackLastSize, sizeof(int));
|
|
|
|
int stackTopSize = tempTask->stack.top - tempTask->stack.stack;
|
|
|
|
saveFunc(&stackTopSize, sizeof(int));
|
|
|
|
for (i = 0; i < stackTopSize; i++) {
|
|
|
|
saveObjectValue(&tempTask->stack.stack[i], saveFunc);
|
|
|
|
}
|
|
|
|
|
|
|
|
saveFunc(&tempTask->Cstack.base, sizeof(StkId));
|
|
|
|
saveFunc(&tempTask->Cstack.lua2C, sizeof(StkId));
|
|
|
|
saveFunc(&tempTask->Cstack.num, sizeof(int));
|
|
|
|
|
|
|
|
saveFunc(&tempTask->numCblocks, sizeof(int));
|
|
|
|
for (i = 0; i < tempTask->numCblocks; i++) {
|
|
|
|
saveFunc(&tempTask->Cblocks[i].base, sizeof(StkId));
|
|
|
|
saveFunc(&tempTask->Cblocks[i].lua2C, sizeof(StkId));
|
|
|
|
saveFunc(&tempTask->Cblocks[i].num, sizeof(int));
|
|
|
|
}
|
|
|
|
|
|
|
|
int pcOffset, taskCi = -1;
|
|
|
|
saveFunc(&tempTask->base_ci_size, sizeof(int));
|
|
|
|
assert(tempTask->base_ci);
|
|
|
|
CallInfo *tempCi = tempTask->base_ci;
|
|
|
|
int countCi = tempTask->base_ci_size / sizeof(CallInfo);
|
|
|
|
for (i = 0; i < countCi; i++) {
|
|
|
|
saveFunc(&tempCi->c, sizeof(Closure *));
|
|
|
|
saveFunc(&tempCi->tf, sizeof(TProtoFunc *));
|
|
|
|
if ((tempCi->pc != NULL) && (tempTask->ci->tf != NULL))
|
|
|
|
pcOffset = tempCi->pc - tempCi->tf->code;
|
|
|
|
else
|
|
|
|
pcOffset = 0;
|
|
|
|
saveFunc(&pcOffset, sizeof(int));
|
|
|
|
saveFunc(&tempCi->base, sizeof(StkId));
|
|
|
|
saveFunc(&tempCi->nResults, sizeof(int));
|
|
|
|
if (tempCi == tempTask->ci)
|
|
|
|
taskCi = i;
|
|
|
|
tempCi++;
|
|
|
|
}
|
|
|
|
assert(taskCi != -1);
|
|
|
|
saveFunc(&taskCi, sizeof(int));
|
|
|
|
|
|
|
|
MbaseOffset = tempTask->Mbuffbase - tempTask->Mbuffer;
|
|
|
|
saveFunc(&MbaseOffset, sizeof(int));
|
|
|
|
saveFunc(&tempTask->Mbuffnext, sizeof(int));
|
|
|
|
|
|
|
|
saveFunc(&tempTask->Tstate, sizeof(TaskState));
|
|
|
|
saveFunc(&tempTask->auto_delete, sizeof(int));
|
|
|
|
|
|
|
|
tempTask = tempTask->next;
|
|
|
|
}
|
|
|
|
|
2005-01-14 10:51:20 +00:00
|
|
|
printf("lua_Save() finished.\n");
|
2004-12-25 18:23:07 +00:00
|
|
|
}
|