// NEXT: Must go through the bytecode and set the correct objecttype pointer where used int asCRestore::Restore() { // Before starting the load, make sure that // any existing resources have been freed module->Reset(); unsigned long i, count; asCScriptFunction* func; asCProperty* prop; asCString *cstr; // structTypes[] READ_NUM(count); module->structTypes.Allocate(count, 0); for( i = 0; i < count; ++i ) { asCObjectType *ot = new asCObjectType(engine); ReadObjectTypeDeclaration(ot); engine->structTypes.PushLast(ot); module->structTypes.PushLast(ot); ot->refCount++; } // usedTypes[] READ_NUM(count); module->usedTypes.Allocate(count, 0); for( i = 0; i < count; ++i ) { asCObjectType *ot = ReadObjectType(); module->usedTypes.PushLast(ot); ot->refCount++; } // scriptGlobals[] READ_NUM(count); module->scriptGlobals.Allocate(count, 0); for( i = 0; i < count; ++i ) { prop = new asCProperty; ReadProperty(prop); module->scriptGlobals.PushLast(prop); } // globalMem size READ_NUM(count); module->globalMem.SetLength(count); // globalVarPointers[] ReadGlobalVarPointers(); // initFunction ReadFunction(&module->initFunction); // scriptFunctions[] READ_NUM(count); module->scriptFunctions.Allocate(count, 0); for( i = 0; i < count; ++i ) { func = new asCScriptFunction; ReadFunction(func); module->scriptFunctions.PushLast(func); } // stringConstants[] READ_NUM(count); module->stringConstants.Allocate(count, 0); for(i=0;i<count;++i) { cstr = new asCString(); ReadString(cstr); module->stringConstants.PushLast(cstr); } // importedFunctions[] and bindInformations[] READ_NUM(count); module->importedFunctions.Allocate(count, 0); module->bindInformations.SetLength(count); for(i=0;i<count;++i) { func = new asCScriptFunction; ReadFunction(func); module->importedFunctions.PushLast(func); READ_NUM(module->bindInformations[i].importFrom); module->bindInformations[i].importedFunction = -1; } // usedTypeIds[] ReadUsedTypeIds(); // Fake building module->isBuildWithoutErrors = true; // Init system functions properly engine->PrepareEngine(); module->CallInit(); return 0; }
asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine) { char c; READ_NUM(c); if( c == '\0' ) { // There is no function, so return a null pointer return 0; } if( c == 'r' ) { // This is a reference to a previously saved function int index; READ_NUM(index); return savedFunctions[index]; } // Load the new function asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,-1); savedFunctions.PushLast(func); int i, count; asCDataType dt; int num; ReadFunctionSignature(func); if( func->funcType == asFUNC_SCRIPT ) engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours); func->id = engine->GetNextScriptFunctionId(); READ_NUM(count); func->byteCode.Allocate(count, 0); ReadByteCode(func->byteCode.AddressOf(), count); func->byteCode.SetLength(count); READ_NUM(count); func->objVariablePos.Allocate(count, 0); func->objVariableTypes.Allocate(count, 0); for( i = 0; i < count; ++i ) { func->objVariableTypes.PushLast(ReadObjectType()); READ_NUM(num); func->objVariablePos.PushLast(num); } READ_NUM(func->stackNeeded); int length; READ_NUM(length); func->lineNumbers.SetLength(length); for( i = 0; i < length; ++i ) READ_NUM(func->lineNumbers[i]); READ_NUM(func->vfTableIdx); if( addToModule ) { // The refCount is already 1 module->scriptFunctions.PushLast(func); } if( addToEngine ) engine->SetScriptFunction(func); if( func->objectType ) func->ComputeSignatureId(); ReadGlobalVarPointers(func); return func; }
int asCRestore::Restore() { // Before starting the load, make sure that // any existing resources have been freed module->InternalReset(); unsigned long i, count; asCScriptFunction* func; asCString *cstr; // Read enums READ_NUM(count); module->enumTypes.Allocate(count, 0); for( i = 0; i < count; i++ ) { asCObjectType *ot = asNEW(asCObjectType)(engine); ReadObjectTypeDeclaration(ot, false); engine->classTypes.PushLast(ot); module->enumTypes.PushLast(ot); ot->AddRef(); ReadObjectTypeDeclaration(ot, true); } // structTypes[] // First restore the structure names, then the properties READ_NUM(count); module->classTypes.Allocate(count, 0); for( i = 0; i < count; ++i ) { asCObjectType *ot = asNEW(asCObjectType)(engine); ReadObjectTypeDeclaration(ot, false); engine->classTypes.PushLast(ot); module->classTypes.PushLast(ot); ot->AddRef(); } // Read interface methods for( i = 0; i < module->classTypes.GetLength(); i++ ) { if( module->classTypes[i]->IsInterface() ) ReadObjectTypeDeclaration(module->classTypes[i], true); } module->ResolveInterfaceIds(); // Read class methods, properties, and behaviours for( i = 0; i < module->classTypes.GetLength(); ++i ) { if( !module->classTypes[i]->IsInterface() ) ReadObjectTypeDeclaration(module->classTypes[i], true); } // Read typedefs READ_NUM(count); module->typeDefs.Allocate(count, 0); for( i = 0; i < count; i++ ) { asCObjectType *ot = asNEW(asCObjectType)(engine); ReadObjectTypeDeclaration(ot, false); engine->classTypes.PushLast(ot); module->typeDefs.PushLast(ot); ot->AddRef(); ReadObjectTypeDeclaration(ot, true); } // scriptGlobals[] READ_NUM(count); module->scriptGlobals.Allocate(count, 0); for( i = 0; i < count; ++i ) { ReadGlobalProperty(); } // globalVarPointers[] ReadGlobalVarPointers(); // scriptFunctions[] READ_NUM(count); for( i = 0; i < count; ++i ) { func = ReadFunction(); } // globalFunctions[] READ_NUM(count); for( i = 0; i < count; ++i ) { func = ReadFunction(false, false); module->globalFunctions.PushLast(func); } // initFunction READ_NUM(count); if( count ) { module->initFunction = ReadFunction(false, true); } // stringConstants[] READ_NUM(count); module->stringConstants.Allocate(count, 0); for( i = 0; i < count; ++i ) { cstr = asNEW(asCString)(); ReadString(cstr); module->stringConstants.PushLast(cstr); } // importedFunctions[] and bindInformations[] READ_NUM(count); module->importedFunctions.Allocate(count, 0); module->bindInformations.SetLength(count); for(i=0;i<count;++i) { func = ReadFunction(false, false); module->importedFunctions.PushLast(func); sBindInfo *info = asNEW(sBindInfo); ReadString(&info->importFromModule); info->importedFunction = -1; module->bindInformations[i] = info; } // usedTypes[] READ_NUM(count); usedTypes.Allocate(count, 0); for( i = 0; i < count; ++i ) { asCObjectType *ot = ReadObjectType(); usedTypes.PushLast(ot); } // usedTypeIds[] ReadUsedTypeIds(); // usedFunctions[] ReadUsedFunctions(); // usedGlobalProperties[] ReadUsedGlobalProps(); // TODO: global: The module won't have a globalVarPointers anymore, instead each script // function has its own array so this should be moved into TranslateFunction // Translate the module->globalVarPointers for( i = 0; i < module->globalVarPointers.GetLength(); i++ ) { module->globalVarPointers[i] = usedGlobalProperties[(int)(size_t)module->globalVarPointers[i]]; } if( module->initFunction ) TranslateFunction(module->initFunction); for( i = 0; i < module->scriptFunctions.GetLength(); i++ ) TranslateFunction(module->scriptFunctions[i]); // Fake building module->isBuildWithoutErrors = true; // Init system functions properly engine->PrepareEngine(); // Add references for all functions if( module->initFunction ) module->initFunction->AddReferences(); for( i = 0; i < module->scriptFunctions.GetLength(); i++ ) { module->scriptFunctions[i]->AddReferences(); } module->CallInit(); return 0; }