void asCRestore::ReadDataType(asCDataType *dt) 
{
	eTokenType tokenType;
	READ_NUM(tokenType);
	asCObjectType *objType = ReadObjectType();
	bool isObjectHandle;
	READ_NUM(isObjectHandle);
	bool isReadOnly;
	READ_NUM(isReadOnly);
	bool isHandleToConst;
	READ_NUM(isHandleToConst);
	bool isReference;
	READ_NUM(isReference);

	if( tokenType == ttIdentifier )
		*dt = asCDataType::CreateObject(objType, false);
	else
		*dt = asCDataType::CreatePrimitive(tokenType, false);
	if( isObjectHandle )
	{
		dt->MakeReadOnly(isHandleToConst);
		dt->MakeHandle(true);
	}
	dt->MakeReadOnly(isReadOnly);
	dt->MakeReference(isReference);
}
Beispiel #2
0
void asCRestore::ReadFunctionSignature(asCScriptFunction *func)
{
	int i, count;
	asCDataType dt;
	int num;

	ReadString(&func->name);
	ReadDataType(&func->returnType);
	READ_NUM(count);
	func->parameterTypes.Allocate(count, 0);
	for( i = 0; i < count; ++i ) 
	{
		ReadDataType(&dt);
		func->parameterTypes.PushLast(dt);
	}

	READ_NUM(count);
	func->inOutFlags.Allocate(count, 0);
	for( i = 0; i < count; ++i )
	{
		READ_NUM(num);
		func->inOutFlags.PushLast(static_cast<asETypeModifiers>(num));
	}

	READ_NUM(func->funcType);

	func->objectType = ReadObjectType();

	READ_NUM(func->isReadOnly);
}
Beispiel #3
0
void asCRestore::ReadFunction(asCScriptFunction* func) 
{
	int i, count;
	asCDataType dt;
	int num;

	ReadString(&func->name);

	ReadDataType(&func->returnType);

	READ_NUM(count);
	func->parameterTypes.Allocate(count, 0);
	for( i = 0; i < count; ++i ) 
	{
		ReadDataType(&dt);
		func->parameterTypes.PushLast(dt);
	}

	READ_NUM(func->id);
	
	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);

	func->objectType = ReadObjectType();

	int length;
	READ_NUM(length);
	func->lineNumbers.SetLength(length);
	for( i = 0; i < length; ++i )
		READ_NUM(func->lineNumbers[i]);
}
Beispiel #4
0
asCObjectType* asCRestore::ReadObjectType() 
{
	asCObjectType *ot;
	char ch;
	READ_NUM(ch);
	if( ch == 'a' )
	{
		READ_NUM(ch);
		if( ch == 's' )
		{
			ot = ReadObjectType();
			asCDataType dt = asCDataType::CreateObject(ot, false);

			READ_NUM(ch);
			if( ch == 'h' )
				dt.MakeHandle(true);

			dt.MakeArray(engine);
			ot = dt.GetObjectType();
		}
		else
		{
			eTokenType tokenType;
			READ_NUM(tokenType);
			asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
			dt.MakeArray(engine);
			ot = dt.GetObjectType();
		}
	}
	else
	{
		// Read the object type name
		asCString typeName;
		ReadString(&typeName);

		// Find the object type
		ot = module->GetObjectType(typeName.AddressOf());
		if( !ot )
			ot = engine->GetObjectType(typeName.AddressOf());
	}

	return ot;
}
Beispiel #5
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;
}
Beispiel #6
0
int asCRestore::Restore() 
{
	// Before starting the load, make sure that 
	// any existing resources have been freed
	module->InternalReset();

	unsigned long i, count;

	asCScriptFunction* func;

	// 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();

		// Add script classes to the GC
		if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && ot->GetSize() > 0 )
			engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
	}

	// 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();
	}

	// 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);
		func->AddRef();
	}

	// bindInformations[]
	READ_NUM(count);
	module->bindInformations.SetLength(count);
	for(i=0;i<count;++i)
	{
		sBindInfo *info = asNEW(sBindInfo);
		info->importedFunctionSignature = ReadFunction(false, false);
		info->importedFunctionSignature->id = int(FUNC_IMPORTED + engine->importedFunctions.GetLength());
		engine->importedFunctions.PushLast(info);
		ReadString(&info->importFromModule);
		info->boundFunctionId = -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();

	// usedStringConstants[]
	ReadUsedStringConstants();

	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
		TranslateFunction(module->scriptFunctions[i]);
	for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
		if( module->scriptGlobals[i]->initFunc )
			TranslateFunction(module->scriptGlobals[i]->initFunc);

	// Init system functions properly
	engine->PrepareEngine();

	// Add references for all functions
	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
		module->scriptFunctions[i]->AddReferences();
	for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
		if( module->scriptGlobals[i]->initFunc )
			module->scriptGlobals[i]->initFunc->AddReferences();

	module->CallInit();

	return 0;
}
Beispiel #7
0
// 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;
}
asCObjectType* asCRestore::ReadObjectType() 
{
	asCObjectType *ot;
	char ch;
	READ_NUM(ch);
	if( ch == 'a' )
	{
		READ_NUM(ch);
		if( ch == 's' )
		{
			ot = ReadObjectType();
			asCDataType dt = asCDataType::CreateObject(ot, false);

			READ_NUM(ch);
			if( ch == 'h' )
				dt.MakeHandle(true);

			dt.MakeArray(engine);
			ot = dt.GetObjectType();
			
			asASSERT(ot);
		}
		else
		{
			eTokenType tokenType;
			READ_NUM(tokenType);
			asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
			dt.MakeArray(engine);
			ot = dt.GetObjectType();
			
			asASSERT(ot);
		}
	}
	else if( ch == 's' )
	{
		// Read the name of the template subtype
		asCString typeName;
		ReadString(&typeName);

		// Find the template subtype
		for( asUINT n = 0; n < engine->templateSubTypes.GetLength(); n++ )
		{
			if( engine->templateSubTypes[n] && engine->templateSubTypes[n]->name == typeName )
			{
				ot = engine->templateSubTypes[n];
				break;
			}
		}

		// TODO: Should give a friendly error in case the template type isn't found
		asASSERT(ot);
	}
	else
	{
		// Read the object type name
		asCString typeName;
		ReadString(&typeName);

		if( typeName.GetLength() && typeName != "_builtin_object_" )
		{
			// Find the object type
			ot = module->GetObjectType(typeName.AddressOf());
			if( !ot )
				ot = engine->GetObjectType(typeName.AddressOf());
			
			asASSERT(ot);
		}
		else if( typeName == "_builtin_object_" )
		{
			ot = &engine->scriptTypeBehaviours;
		}
		else
			ot = 0;
	}

	return ot;
}
void asCRestore::ReadObjectTypeDeclaration(asCObjectType *ot, bool readProperties)
{
	if( !readProperties )
	{
		// name
		ReadString(&ot->name);
		// size
		int size;
		READ_NUM(size);
		ot->size = size;
		// flags
		asDWORD flags;
		READ_NUM(flags);
		ot->flags = flags;

		// Use the default script class behaviours
		ot->beh = engine->scriptTypeBehaviours.beh;
	}
	else
	{	
		if( ot->flags & asOBJ_ENUM )
		{
			int count;
			READ_NUM(count);
			ot->enumValues.Allocate(count, 0);
			for( int n = 0; n < count; n++ )
			{
				asSEnumValue *e = asNEW(asSEnumValue);
				ReadString(&e->name);
				READ_NUM(e->value);
				ot->enumValues.PushLast(e);
			}
		}
		else if( ot->flags & asOBJ_TYPEDEF )
		{
			eTokenType t;
			READ_NUM(t);
			ot->templateSubType = asCDataType::CreatePrimitive(t, false);
		}
		else
		{
			ot->derivedFrom = ReadObjectType();
			if( ot->derivedFrom )
				ot->derivedFrom->AddRef();

			// interfaces[]
			int size;
			READ_NUM(size);
			ot->interfaces.Allocate(size,0);
			int n;
			for( n = 0; n < size; n++ )
			{
				asCObjectType *intf = ReadObjectType();
				ot->interfaces.PushLast(intf);
			}

			// properties[]
			READ_NUM(size);
			ot->properties.Allocate(size,0);
			for( n = 0; n < size; n++ )
			{
				asCObjectProperty *prop = asNEW(asCObjectProperty);
				ReadObjectProperty(prop);
				ot->properties.PushLast(prop);
			}

			// behaviours
			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
			{
				asCScriptFunction *func = ReadFunction();
				ot->beh.construct = func->id;
				ot->beh.constructors[0] = func->id;

				func = ReadFunction();
				if( func )
					ot->beh.destruct = func->id;

				func = ReadFunction();
				ot->beh.factory = func->id;
				ot->beh.factories[0] = func->id;

				READ_NUM(size);
				for( n = 0; n < size; n++ )
				{
					asCScriptFunction *func = ReadFunction();
					ot->beh.constructors.PushLast(func->id);

					func = ReadFunction();
					ot->beh.factories.PushLast(func->id);
				}
			}

			// methods[]
			READ_NUM(size);
			for( n = 0; n < size; n++ ) 
			{
				asCScriptFunction *func = ReadFunction();
				ot->methods.PushLast(func->id);
			}

			// virtualFunctionTable[]
			READ_NUM(size);
			for( n = 0; n < size; n++ )
			{
				asCScriptFunction *func = ReadFunction();
				ot->virtualFunctionTable.PushLast(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;
}