Beispiel #1
0
asCThreadLocalData *asCThreadManager::GetLocalData()
{
	if( threadManager == 0 )
		return 0;

#ifndef AS_NO_THREADS
#if defined AS_POSIX_THREADS
	asCThreadLocalData *tld = (asCThreadLocalData*)pthread_getspecific((pthread_key_t)threadManager->tlsKey);
	if( tld == 0 )
	{
		tld = asNEW(asCThreadLocalData)();
		pthread_setspecific((pthread_key_t)threadManager->tlsKey, tld);
	}
#elif defined AS_WINDOWS_THREADS
	#if defined(_MSC_VER) && (WINAPI_FAMILY & WINAPI_FAMILY_PHONE_APP)
		if( tld == 0 )
			tld = asNEW(asCThreadLocalData)();
	#else
		asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey);
		if( tld == 0 )
		{
 			tld = asNEW(asCThreadLocalData)();
			TlsSetValue((DWORD)threadManager->tlsKey, tld);
 		}
	#endif
#endif

	return tld;
#else
	if( threadManager->tld == 0 )
		threadManager->tld = asNEW(asCThreadLocalData)();

	return threadManager->tld;
#endif
}
Beispiel #2
0
asCThreadLocalData *asCThreadManager::GetLocalData()
{
	if( threadManager == 0 )
		return 0;

#ifndef AS_NO_THREADS
#if defined AS_POSIX_THREADS
	asPWORD id = (asPWORD)pthread_self();
#elif defined AS_WINDOWS_THREADS
	asPWORD id = (asPWORD)GetCurrentThreadId();
#endif

	ENTERCRITICALSECTION(threadManager->criticalSection);

	asCThreadLocalData *tld = threadManager->GetLocalData(id);
	if( tld == 0 )
	{
		// Create a new tld
		tld = asNEW(asCThreadLocalData)();
		if( tld )
			threadManager->SetLocalData(id, tld);
	}

	LEAVECRITICALSECTION(threadManager->criticalSection);

	return tld;
#else
	if( threadManager->tld == 0 )
		threadManager->tld = asNEW(asCThreadLocalData)();

	return threadManager->tld;
#endif
}
Beispiel #3
0
asILockableSharedBool *asCScriptObject::GetWeakRefFlag() const
{
	// If the object's refCount has already reached zero then the object is already
	// about to be destroyed so it's ok to return null if the weakRefFlag doesn't already
	// exist
	if( (extra && extra->weakRefFlag) || hasRefCountReachedZero )
		return extra->weakRefFlag;

	// Lock globally so no other thread can attempt
	// to create a shared bool at the same time.
	// TODO: runtime optimize: Instead of locking globally, it would be possible to have 
	//                         a critical section per object type. This would reduce the 
	//                         chances of two threads lock on the same critical section.
	asAcquireExclusiveLock();

	// Make sure another thread didn't create the 
	// flag while we waited for the lock
	if( !extra )
		extra = asNEW(SExtra);
	if( !extra->weakRefFlag )
		extra->weakRefFlag = asNEW(asCLockableSharedBool);

	asReleaseExclusiveLock();

	return extra->weakRefFlag;
}
Beispiel #4
0
// internal
int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, int paramCount, const asCString &moduleName)
{
	asASSERT(id >= 0);

	// Store the function information
	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, asFUNC_IMPORTED);
	func->name       = name;
	func->id         = id;
	func->returnType = returnType;
	for( int n = 0; n < paramCount; n++ )
	{
		func->parameterTypes.PushLast(params[n]);
		func->inOutFlags.PushLast(inOutFlags[n]);
	}
	func->objectType = 0;

	sBindInfo *info = asNEW(sBindInfo);
	info->importedFunctionSignature = func;
	info->boundFunctionId = -1;
	info->importFromModule = moduleName;
	bindInformations.PushLast(info);

	// Add the info to the array in the engine
	engine->importedFunctions.PushLast(info);

	return 0;
}
// internal
int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char *decl, asCScriptNode *listNodes)
{
	asSListPatternNode *node = target;

	listNodes = listNodes->firstChild;
	while( listNodes )
	{
		if( listNodes->nodeType == snIdentifier )
		{
			node->next = asNEW(asSListPatternNode)(asLPT_REPEAT);
			node = node->next;
		}
		else if( listNodes->nodeType == snDataType )
		{
			asCDataType dt;
			asCBuilder builder(engine, 0);
			asCScriptCode code;
			code.SetCode("", decl, 0, false);
			dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, returnType.GetObjectType());

			node->next = asNEW(asSListPatternDataTypeNode)(dt);
			node = node->next;
		}
		else if( listNodes->nodeType == snListPattern )
		{
			node->next = asNEW(asSListPatternNode)(asLPT_START);
			node = node->next;

			// Recursively parse the child
			int r = ParseListPattern(node, decl, listNodes);
			if( r < 0 )
				return r;

			node->next = asNEW(asSListPatternNode)(asLPT_END);
			node = node->next;
		}
		else
		{
			// Unexpected token in the list, the parser shouldn't have allowed
			asASSERT( false );
			return -1;
		}

		listNodes = listNodes->next;
	}

	target = node;
	return 0;
}
Beispiel #6
0
int asCVariableScope::DeclareVariable(const char *name, const asCDataType &type, int stackOffset)
{
	// TODO: optimize: Improve linear search
	// See if the variable is already declared
	if( strcmp(name, "") != 0 )
	{
		for( asUINT n = 0; n < variables.GetLength(); n++ )
		{
			if( variables[n]->name == name )
				return -1;
		}
	}

	sVariable *var = asNEW(sVariable);
	var->name = name;
	var->type = type;
	var->stackOffset = stackOffset;
	var->isInitialized = false;
	var->isPureConstant = false;

	// Parameters are initialized
	if( stackOffset <= 0 )
		var->isInitialized = true;

	variables.PushLast(var);

	return 0;
}
// internal
int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, int paramCount, int moduleNameStringID)
{
	asASSERT(id >= 0);

	// Store the function information
	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this);
	func->funcType   = asFUNC_IMPORTED;
	func->name       = name;
	func->id         = id;
	func->returnType = returnType;
	for( int n = 0; n < paramCount; n++ )
	{
		func->parameterTypes.PushLast(params[n]);
		func->inOutFlags.PushLast(inOutFlags[n]);
	}
	func->objectType = 0;

	importedFunctions.PushLast(func);

	sBindInfo info;
	info.importedFunction = -1;
	info.importFrom = moduleNameStringID;
	bindInformations.PushLast(info);

	return 0;
}
Beispiel #8
0
// internal
int asCModule::AddScriptFunction(int sectionIdx, int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, int paramCount, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction)
{
	asASSERT(id >= 0);

	// Store the function information
	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, isInterface ? asFUNC_INTERFACE : asFUNC_SCRIPT);
	func->name       = name;
	func->id         = id;
	func->returnType = returnType;
	func->scriptSectionIdx = sectionIdx;
	for( int n = 0; n < paramCount; n++ )
	{
		func->parameterTypes.PushLast(params[n]);
		func->inOutFlags.PushLast(inOutFlags[n]);
	}
	func->objectType = objType;
	func->isReadOnly = isConstMethod;

	// The script function's refCount was initialized to 1
	scriptFunctions.PushLast(func);
	engine->SetScriptFunction(func);

	// Compute the signature id
	if( objType )
		func->ComputeSignatureId();

	// Add reference
	if( isGlobalFunction )
	{
		globalFunctions.PushLast(func);
		func->AddRef();
	}

	return 0;
}
// interface
int asCModule::Build()
{
	asASSERT( contextCount.get() == 0 );
	
	// Only one thread may build at one time
	int r = engine->RequestBuild();
	if( r < 0 )
		return r;

	engine->PrepareEngine();
	if( engine->configFailed )
	{
		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
		engine->BuildCompleted();
		return asINVALID_CONFIGURATION;
	}

 	InternalReset();

	if( !builder )
	{
		engine->BuildCompleted();
		return asSUCCESS;
	}

	// Store the section names
	for( size_t n = 0; n < builder->scripts.GetLength(); n++ )
	{
		asCString *sectionName = asNEW(asCString)(builder->scripts[n]->name);
		scriptSections.PushLast(sectionName);
	}

	// Compile the script
	r = builder->Build();
	asDELETE(builder,asCBuilder);
	builder = 0;
	
	if( r < 0 )
	{
		// Reset module again
		InternalReset();

		isBuildWithoutErrors = false;
		engine->BuildCompleted();
		return r;
	}

	isBuildWithoutErrors = true;

    JITCompile();

 	engine->PrepareEngine();
	engine->BuildCompleted();

	// Initialize global variables
	if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
		r = ResetGlobalVars();

	return r;
}
// internal
int asCScriptFunction::RegisterListPattern(const char *decl, asCScriptNode *listNodes)
{
	if( listNodes == 0 )
		return asINVALID_ARG;

	// Build the representation of the list pattern from the script nodes
	asSListPatternNode *node;
	listPattern = asNEW(asSListPatternNode)(asLPT_START);
	node = listPattern;

	// Recursively parse the child
	int r = ParseListPattern(node, decl, listNodes);

	node->next = asNEW(asSListPatternNode)(asLPT_END);

	return r;
}
Beispiel #11
0
// interface
int asCModule::AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset)
{
	if( !builder )
		builder = asNEW(asCBuilder)(engine, this);

	builder->AddCode(name, code, (int)codeLength, lineOffset, (int)engine->GetScriptSectionNameIndex(name ? name : ""), engine->ep.copyScriptSections);

	return asSUCCESS;
}
// internal
void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
{
    asSScriptVariable *var = asNEW(asSScriptVariable);
    var->name                 = name;
    var->type                 = type;
    var->stackOffset          = stackOffset;
    var->declaredAtProgramPos = 0;
    variables.PushLast(var);
}
void asCScriptFunction::AllocateScriptFunctionData()
{
	if( scriptData ) return;

	scriptData = asNEW(ScriptFunctionData);

	scriptData->stackNeeded      = 0;
	scriptData->variableSpace    = 0;
	scriptData->scriptSectionIdx = -1;
	scriptData->jitFunction      = 0;
}
Beispiel #14
0
asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIntTypePair it)
{
	asSMapNode_t *node;
	if( freeNodes.GetLength() )
		node = freeNodes.PopLast();
	else
		node = asNEW(asSMapNode_t);

	node->Init(obj, it);
	return node;
}
// interface
int asCModule::AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset)
{
	if( IsUsed() )
		return asMODULE_IS_IN_USE;

	if( !builder )
		builder = asNEW(asCBuilder)(engine, this);

	builder->AddCode(name, code, (int)codeLength, lineOffset, (int)builder->scripts.GetLength(), engine->ep.copyScriptSections);

	return asSUCCESS;
}
// internal
int asCModule::AddFuncDef(const char *name)
{
	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
	func->name = name;

	funcDefs.PushLast(func);

	engine->funcDefs.PushLast(func);
	func->id = engine->GetNextScriptFunctionId();
	engine->SetScriptFunction(func);

	return (int)funcDefs.GetLength()-1;
}
Beispiel #17
0
asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIntTypePair it)
{
	// This function will only be called within the critical section gcCollecting
	asASSERT(isProcessing);

	asSMapNode_t *node;
	if( freeNodes.GetLength() )
		node = freeNodes.PopLast();
	else
		node = asNEW(asSMapNode_t);

	node->Init(obj, it);
	return node;
}
Beispiel #18
0
void asCOutputBuffer::Callback(asSMessageInfo *msg)
{
	message_t *msgInfo = asNEW(message_t);
	if( msgInfo == 0 )
		return;

	msgInfo->section = msg->section;
	msgInfo->row = msg->row;
	msgInfo->col = msg->col;
	msgInfo->type = msg->type;
	msgInfo->msg = msg->message;

	messages.PushLast(msgInfo);
}
// internal
void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
{
	asASSERT( scriptData );
	asSScriptVariable *var = asNEW(asSScriptVariable);
	if( var == 0 )
	{
		// Out of memory
		return;
	}
	var->name                 = name;
	var->type                 = type;
	var->stackOffset          = stackOffset;
	var->declaredAtProgramPos = 0;
	scriptData->variables.PushLast(var);
}
Beispiel #20
0
// internal
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
{
	asASSERT( flags & asOBJ_SCRIPT_OBJECT );
	asASSERT( dt.CanBeInstanciated() );
	asASSERT( !IsInterface() );

	// Store the properties in the object type descriptor
	asCObjectProperty *prop = asNEW(asCObjectProperty);
	if( prop == 0 )
	{
		// Out of memory
		return 0;
	}

	prop->name      = name;
	prop->type      = dt;
	prop->isPrivate = isPrivate;

	int propSize;
	if( dt.IsObject() )
	{
		propSize = dt.GetSizeOnStackDWords()*4;
		if( !dt.IsObjectHandle() )
			prop->type.MakeReference(true);
	}
	else
		propSize = dt.GetSizeInMemoryBytes();

	// Add extra bytes so that the property will be properly aligned
	if( propSize == 2 && (size & 1) ) size += 1;
	if( propSize > 2 && (size & 3) ) size += 4 - (size & 3);

	prop->byteOffset = size;
	size += propSize;

	properties.PushLast(prop);

	// Make sure the struct holds a reference to the config group where the object is registered
	asCConfigGroup *group = engine->FindConfigGroupForObjectType(prop->type.GetObjectType());
	if( group != 0 ) group->AddRef();

	// Add reference to object types
	asCObjectType *type = prop->type.GetObjectType();
	if( type )
		type->AddRef();

	return prop;
}
Beispiel #21
0
asCScriptFunction *CreateDelegate(asCScriptFunction *func, void *obj)
{
	if( func == 0 || obj == 0 )
	{
		// TODO: delegate: Should set script exception
		return 0;
	}

	// Create an instance of a asCScriptFunction with the type asFUNC_DELEGATE
	// The delegate shouldn't have a function id and is not added to the engine->scriptFunctions
	asCScriptFunction *delegate = asNEW(asCScriptFunction)(static_cast<asCScriptEngine*>(func->GetEngine()), 0, asFUNC_DELEGATE);
	if( delegate )
		delegate->MakeDelegate(func, obj);

	return delegate;
}
Beispiel #22
0
// internal
asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asCDataType &dt)
{
	asCGlobalProperty *prop = asNEW(asCGlobalProperty);
	prop->index      = (int)scriptGlobals.GetLength();
	prop->name       = name;
	prop->type       = dt;
	scriptGlobals.PushLast(prop);

	// Allocate the memory for this property
	if( dt.GetSizeOnStackDWords() > 2 )
	{
		prop->SetAddressOfValue(asNEWARRAY(asDWORD, dt.GetSizeOnStackDWords()));
		prop->memoryAllocated = true;
	}

	return prop;
}
asILockableSharedBool *asCScriptObject::GetWeakRefFlag() const
{
	if( weakRefFlag )
		return weakRefFlag;

	// Lock globally so no other thread can attempt
	// to create a shared bool at the same time.
	// TODO: runtime optimize: Instead of locking globally, it would be possible to have 
	//                         a critical section per object type. This would reduce the 
	//                         chances of two threads lock on the same critical section.
	asAcquireExclusiveLock();

	// Make sure another thread didn't create the 
	// flag while we waited for the lock
	if( !weakRefFlag )
		weakRefFlag = asNEW(asCLockableSharedBool);

	asReleaseExclusiveLock();

	return weakRefFlag;
}
Beispiel #24
0
void asCThreadManager::Prepare()
{
	// The critical section cannot be declared globally, as there is no
	// guarantee for the order in which global variables are initialized
	// or uninitialized.

	// For this reason it's not possible to prevent two threads from calling 
	// AddRef at the same time, so there is a chance for a race condition here.

	// To avoid the race condition when the thread manager is first created, 
	// the application must make sure to call the global asPrepareForMultiThread()
	// in the main thread before any other thread creates a script engine. 
	if( threadManager == 0 )
		threadManager = asNEW(asCThreadManager);
	else
	{
		ENTERCRITICALSECTION(threadManager->criticalSection);
		threadManager->refCount++;
		LEAVECRITICALSECTION(threadManager->criticalSection);
	}
}
// internal
int asCModule::AddConstantString(const char *str, size_t len)
{
	//  The str may contain null chars, so we cannot use strlen, or strcmp, or strcpy
	asCString *cstr = asNEW(asCString)(str, len);

	// TODO: optimize: Improve linear search
	// Has the string been registered before?
	for( size_t n = 0; n < stringConstants.GetLength(); n++ )
	{
		if( *stringConstants[n] == *cstr )
		{
			asDELETE(cstr,asCString);
			return (int)n;
		}
	}

	// No match was found, add the string
	stringConstants.PushLast(cstr);

	return (int)stringConstants.GetLength() - 1;
}
Beispiel #26
0
void *asCScriptObject::SetUserData(void *data, asPWORD type)
{
	// Lock globally so no other thread can attempt
	// to manipulate the extra data at the same time.
	// TODO: runtime optimize: Instead of locking globally, it would be possible to have 
	//                         a critical section per object type. This would reduce the 
	//                         chances of two threads lock on the same critical section.
	asAcquireExclusiveLock();

	// Make sure another thread didn't create the 
	// flag while we waited for the lock
	if( !extra )
		extra = asNEW(SExtra);

	// It is not intended to store a lot of different types of userdata,
	// so a more complex structure like a associative map would just have
	// more overhead than a simple array.
	for( asUINT n = 0; n < extra->userData.GetLength(); n += 2 )
	{
		if( extra->userData[n] == type )
		{
			void *oldData = reinterpret_cast<void*>(extra->userData[n+1]);
			extra->userData[n+1] = reinterpret_cast<asPWORD>(data);

			asReleaseExclusiveLock();

			return oldData;
		}
	}

	extra->userData.PushLast(type);
	extra->userData.PushLast(reinterpret_cast<asPWORD>(data));

	asReleaseExclusiveLock();

	return 0;
}
Beispiel #27
0
int asCThreadManager::Prepare(asIThreadManager *externalThreadMgr)
{
	// Don't allow an external thread manager if there
	// is already a thread manager defined
	if( externalThreadMgr && threadManager )
		return asINVALID_ARG;

	// The critical section cannot be declared globally, as there is no
	// guarantee for the order in which global variables are initialized
	// or uninitialized.

	// For this reason it's not possible to prevent two threads from calling
	// AddRef at the same time, so there is a chance for a race condition here.

	// To avoid the race condition when the thread manager is first created,
	// the application must make sure to call the global asPrepareForMultiThread()
	// in the main thread before any other thread creates a script engine.
	if( threadManager == 0 && externalThreadMgr == 0 )
		threadManager = asNEW(asCThreadManager);
	else
	{
		// If an application uses different dlls each dll will get it's own memory
		// space for global variables. If multiple dlls then uses AngelScript's
		// global thread support functions it is then best to share the thread
		// manager to make sure all dlls use the same critical section.
		if( externalThreadMgr )
			threadManager = reinterpret_cast<asCThreadManager*>(externalThreadMgr);

		ENTERCRITICALSECTION(threadManager->criticalSection);
		threadManager->refCount++;
		LEAVECRITICALSECTION(threadManager->criticalSection);
	}

	// Success
	return 0;
}
Beispiel #28
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 #29
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 #30
0
// internal
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
{
	asASSERT( flags & asOBJ_SCRIPT_OBJECT );
	asASSERT( dt.CanBeInstantiated() );
	asASSERT( !IsInterface() );

	// Store the properties in the object type descriptor
	asCObjectProperty *prop = asNEW(asCObjectProperty);
	if( prop == 0 )
	{
		// Out of memory
		return 0;
	}

	prop->name      = name;
	prop->type      = dt;
	prop->isPrivate = isPrivate;

	int propSize;
	if( dt.IsObject() )
	{
		// Non-POD value types can't be allocated inline,
		// because there is a risk that the script might
		// try to access the content without knowing that
		// it hasn't been initialized yet.
		if( dt.GetObjectType()->flags & asOBJ_POD )
			propSize = dt.GetSizeInMemoryBytes();
		else
		{
			propSize = dt.GetSizeOnStackDWords()*4;
			if( !dt.IsObjectHandle() )
				prop->type.MakeReference(true);
		}
	}
	else
		propSize = dt.GetSizeInMemoryBytes();

	// Add extra bytes so that the property will be properly aligned
#ifndef WIP_16BYTE_ALIGN
	if( propSize == 2 && (size & 1) ) size += 1;
	if( propSize > 2 && (size & 3) ) size += 4 - (size & 3);
#else
	asUINT alignment = dt.GetAlignment();
	const asUINT propSizeAlignmentDifference = size & (alignment-1);
	if( propSizeAlignmentDifference != 0 )
	{
		size += (alignment - propSizeAlignmentDifference);
	}

	asASSERT((size % alignment) == 0);
#endif

	prop->byteOffset = size;
	size += propSize;

	properties.PushLast(prop);

	// Make sure the struct holds a reference to the config group where the object is registered
	asCConfigGroup *group = engine->FindConfigGroupForObjectType(prop->type.GetObjectType());
	if( group != 0 ) group->AddRef();

	// Add reference to object types
	asCObjectType *type = prop->type.GetObjectType();
	if( type )
		type->AddRef();

	return prop;
}