Browse Source

Updated to newest AngelScript SVN version.

Lasse Öörni 14 years ago
parent
commit
9f4d5d0410

+ 1 - 1
Engine/Script/ScriptFile.cpp

@@ -524,7 +524,7 @@ void ScriptFile::ReleaseModule()
 {
     if (scriptModule_)
     {
-        // Clear search caches, event handlers and function-to-file mappings
+        // Clear search caches and event handlers
         includeFiles_.Clear();
         checkedClasses_.Clear();
         functions_.Clear();

+ 25 - 7
ThirdParty/AngelScript/source/as_builder.cpp

@@ -593,9 +593,29 @@ void asCBuilder::CompileFunctions()
 		}
 		else if( current->name == current->objType->name )
 		{
+			asCScriptNode *node = 0;
+			for( asUINT n = 0; n < classDeclarations.GetLength(); n++ )
+			{
+				if( classDeclarations[n]->name == current->name )
+				{
+					node = classDeclarations[n]->node;
+					break;
+				}
+			}
+
+			int r = 0, c = 0;
+			if( node )
+				current->script->ConvertPosToRowCol(node->tokenPos, &r, &c);
+
+			asCString str = func->GetDeclarationStr();
+			str.Format(TXT_COMPILING_s, str.AddressOf());
+			WriteInfo(current->script->name.AddressOf(), str.AddressOf(), r, c, true);
+
 			// This is the default constructor, that is generated
 			// automatically if not implemented by the user.
-			compiler.CompileDefaultConstructor(this, current->script, func);
+			compiler.CompileDefaultConstructor(this, current->script, node, func);
+
+			preMessage.isSet = false;
 		}
 		else
 		{
@@ -2387,6 +2407,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file)
 
 		module->enumTypes.PushLast(st);
 		st->AddRef();
+
+		// TODO: cleanup: Should the enum type really be stored in the engine->classTypes? 
+		//                http://www.gamedev.net/topic/616912-c-header-file-shared-with-scripts/page__gopid__4895940
 		engine->classTypes.PushLast(st);
 
 		// Store the location of this declaration for reference in name collisions
@@ -2517,12 +2540,7 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file)
 
 	node->Destroy(engine);
 
-	if( r < 0 )
-	{
-		engine->ConfigError(r);
-	}
-
-	return 0;
+	return r;
 }
 
 void asCBuilder::GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isOverride, bool &isFinal)

+ 11 - 6
ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -156,7 +156,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			asCString str;
 			str.Format(TXT_CANNOT_RET_TYPE_s_BY_VAL, func->returnType.GetObjectType()->name.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-			engine->ConfigError(asINVALID_CONFIGURATION);
+			engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 		}
 		else if( objType & asOBJ_APP_CLASS )
 		{
@@ -223,14 +223,14 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			// Ref: http://www.agner.org/optimize/calling_conventions.pdf
 			// If the application informs that the class should be treated as all integers, then we allow it
 			if( !internal->hostReturnInMemory &&
-				!(func->returnType.GetObjectType()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )	
+			    !(func->returnType.GetObjectType()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )	
 			{
 				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
 
 				asCString str;
 				str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format().AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				engine->ConfigError(asINVALID_CONFIGURATION);
+				engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 			}
 #endif
 		}
@@ -306,7 +306,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 				asCString str;
 				str.Format(TXT_CANNOT_PASS_TYPE_s_BY_VAL, func->parameterTypes[n].GetObjectType()->name.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				engine->ConfigError(asINVALID_CONFIGURATION);
+				engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 			}
 
 
@@ -315,16 +315,21 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			// will be used depending on the memory layout of the object
 			// Ref: http://www.x86-64.org/documentation/abi.pdf
 			// Ref: http://www.agner.org/optimize/calling_conventions.pdf
+			if( 
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
-			if( !(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )	
+			    !(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) &&	
 #endif
+#ifdef LARGE_OBJS_PASS_BY_REF
+			    func->parameterTypes[n].GetSizeInMemoryDWords() < AS_LARGE_OBJ_MIN_SIZE &&
+#endif
+			    !(func->parameterTypes[n].GetObjectType()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
 			{
 				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
 
 				asCString str;
 				str.Format(TXT_DONT_SUPPORT_TYPE_s_BY_VAL, func->parameterTypes[n].GetObjectType()->name.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				engine->ConfigError(asINVALID_CONFIGURATION);
+				engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 			}
 #endif
 			break;

+ 64 - 7
ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -149,7 +149,7 @@ static asQWORD __attribute__((noinline)) X64_CallFunction( const asQWORD *args,
 		: "%rax", "%r15", "%rsp");
 
 	// Push the stack parameters
-	for ( i = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS; cnt-- > 0; i++ )
+	for( i = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS; cnt-- > 0; i++ )
 		PUSH_LONG( args[i] );
 
 	// Populate integer and floating point parameters
@@ -170,9 +170,12 @@ static asQWORD __attribute__((noinline)) X64_CallFunction( const asQWORD *args,
 		"  movsd 48(%%rax), %%xmm6 \n"
 		"  movsd 56(%%rax), %%xmm7 \n"
 		: 
-		: "a" (args) 
+		: "a" (args) // Pass args in rax
 		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 
-		  "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%9");
+		  "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9", 
+		  // rsp and r15 is added too so the compiler doesn't try to use
+		  // them to store anything over this piece of assembly
+		  "%rsp", "%r15"); 
 		
 	// call the function with the arguments
 	retval = call();
@@ -191,6 +194,7 @@ static inline bool IsVariableArgument( asCDataType type )
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
 {
+	asCScriptEngine            *engine             = context->engine;
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	int                         callConv           = sysFunc->callConv;
 	asQWORD                     retQW              = 0;
@@ -273,21 +277,21 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	int argumentCount = ( int )descr->parameterTypes.GetLength();
 	for( int a = 0; a < argumentCount; ++a ) 
 	{
-		if ( descr->parameterTypes[a].IsFloatType() && !descr->parameterTypes[a].IsReference() ) 
+		if( descr->parameterTypes[a].IsFloatType() && !descr->parameterTypes[a].IsReference() ) 
 		{
 			argsType[argIndex] = x64FLOATARG;
 			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(float));
 			argIndex++;
 			stack_pointer++;
 		}
-		else if ( descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() ) 
+		else if( descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() ) 
 		{
 			argsType[argIndex] = x64FLOATARG;
 			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(double));
 			argIndex++;
 			stack_pointer += 2;
 		}
-		else if ( IsVariableArgument( descr->parameterTypes[a] ) ) 
+		else if( IsVariableArgument( descr->parameterTypes[a] ) ) 
 		{
 			// The variable args are really two, one pointer and one type id
 			argsType[argIndex] = x64INTARG;
@@ -297,7 +301,9 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			argIndex += 2;
 			stack_pointer += 3;
 		}
-		else
+		else if( descr->parameterTypes[a].IsPrimitive() ||
+		         descr->parameterTypes[a].IsReference() || 
+		         descr->parameterTypes[a].IsObjectHandle() )
 		{
 			argsType[argIndex] = x64INTARG;
 			if( descr->parameterTypes[a].GetSizeOnStackDWords() == 1 )
@@ -312,6 +318,57 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			}
 			argIndex++;
 		}
+		else
+		{
+			// An object is being passed by value
+			if( (descr->parameterTypes[a].GetObjectType()->flags & COMPLEX_MASK) ||
+			    descr->parameterTypes[a].GetSizeInMemoryDWords() > 4 )
+			{
+				// Copy the address of the object
+				argsType[argIndex] = x64INTARG;
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
+				argIndex++;
+			}
+			else if( descr->parameterTypes[a].GetObjectType()->flags & asOBJ_APP_CLASS_ALLINTS )
+			{
+				// Copy the value of the object
+				if( descr->parameterTypes[a].GetSizeInMemoryDWords() > 2 )
+				{
+					argsType[argIndex] = x64INTARG;
+					argsType[argIndex+1] = x64INTARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, descr->parameterTypes[a].GetSizeInMemoryBytes());
+					argIndex += 2;
+				}
+				else
+				{
+					argsType[argIndex] = x64INTARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, descr->parameterTypes[a].GetSizeInMemoryBytes());
+					argIndex++;
+				}
+				// Delete the original memory
+				engine->CallFree(*(void**)stack_pointer);
+			}
+			else if( descr->parameterTypes[a].GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS )
+			{
+				// Copy the value of the object
+				if( descr->parameterTypes[a].GetSizeInMemoryDWords() > 2 )
+				{
+					argsType[argIndex] = x64FLOATARG;
+					argsType[argIndex+1] = x64FLOATARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, descr->parameterTypes[a].GetSizeInMemoryBytes());
+					argIndex += 2;
+				}
+				else
+				{
+					argsType[argIndex] = x64FLOATARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, descr->parameterTypes[a].GetSizeInMemoryBytes());
+					argIndex++;
+				}
+				// Delete the original memory
+				engine->CallFree(*(void**)stack_pointer);
+			}
+			stack_pointer += 2;
+		}
 	}
 
 	// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument

+ 251 - 169
ThirdParty/AngelScript/source/as_compiler.cpp

@@ -97,9 +97,26 @@ void asCCompiler::Reset(asCBuilder *builder, asCScriptCode *script, asCScriptFun
 	byteCode.ClearAll();
 }
 
-int asCCompiler::CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc)
+int asCCompiler::CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, asCScriptFunction *outFunc)
 {
 	Reset(builder, script, outFunc);
+	
+	// Make sure all the class members can be initialized with default constructors
+	for( asUINT n = 0; n < outFunc->objectType->properties.GetLength(); n++ )
+	{
+		asCDataType &dt = outFunc->objectType->properties[n]->type;
+		if( dt.IsObject() && !dt.IsObjectHandle() &&
+			(((dt.GetObjectType()->flags & asOBJ_REF) && dt.GetObjectType()->beh.factory == 0) ||
+			 ((dt.GetObjectType()->flags & asOBJ_VALUE) && !(dt.GetObjectType()->flags & asOBJ_POD) && dt.GetObjectType()->beh.construct == 0)) )
+		{
+			asCString str;
+			if( dt.GetFuncDef() )
+				str.Format(TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s, dt.GetFuncDef()->GetName());
+			else
+				str.Format(TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s, dt.GetObjectType()->GetName());
+			Error(str.AddressOf(), node);
+		}
+	}
 
 	// If the class is derived from another, then the base class' default constructor must be called
 	if( outFunc->objectType->derivedFrom )
@@ -515,7 +532,7 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 		return 0;
 
 	// CallCopyConstructor should not be called for object handles.
-	asASSERT(!type.IsObjectHandle() || (type.GetObjectType() && (type.GetObjectType()->flags & asOBJ_ASHANDLE)) );
+	asASSERT( !type.IsObjectHandle() );
 
 	asCArray<asSExprContext*> args;
 	args.PushLast(arg);
@@ -620,8 +637,7 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 
 int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar, bool deferDest)
 {
-	if( !type.IsObject() ||
-		(type.IsObjectHandle() && !(type.GetObjectType()->flags & asOBJ_ASHANDLE)) )
+	if( !type.IsObject() || type.IsObjectHandle() )
 		return 0;
 
 	if( type.GetObjectType()->flags & asOBJ_REF )
@@ -725,8 +741,7 @@ void asCCompiler::CallDestructor(asCDataType &type, int offset, bool isObjectOnH
 		// Call destructor for the data type
 		if( type.IsObject() )
 		{
-			// ASHANDLE is really a value type and shouldn't be deallocated. Just the destructor should be called
-			if( isObjectOnHeap || (type.IsObjectHandle() && !(type.GetObjectType()->flags & asOBJ_ASHANDLE)) )
+			if( isObjectOnHeap || type.IsObjectHandle() )
 			{
 				// Free the memory
 				bc->InstrW_PTR(asBC_FREE, (short)offset, type.GetObjectType());
@@ -973,7 +988,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 			//                 just the copy constructor. Only if no appropriate constructor is
 			//                 available should the assignment operator be used.
 
-			if( (!gvar->datatype.IsObjectHandle() || gvar->datatype.GetObjectType()->flags & asOBJ_ASHANDLE) )
+			if( !gvar->datatype.IsObjectHandle() )
 			{
 				// Call the default constructor to have a valid object for the assignment
 				CallDefaultConstructor(gvar->datatype, gvar->index, true, &ctx.bc, gvar->idNode, true);
@@ -997,6 +1012,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 			// the default action is a direct copy if it is the same type
 			// and a simple assignment.
 			bool assigned = false;
+			// Even though an ASHANDLE can be an explicit handle the assignment needs to be treated by the overloaded operator
 			if( lexpr.type.dataType.IsObject() && (!lexpr.type.isExplicitHandle || (lexpr.type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE)) )
 			{
 				assigned = CompileOverloadedDualOperator(node, &lexpr, &expr, &ctx);
@@ -1038,7 +1054,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 			}
 		}
 	}
-	else if( gvar->datatype.IsObject() && (!gvar->datatype.IsObjectHandle() || gvar->datatype.GetObjectType()->flags & asOBJ_ASHANDLE) )
+	else if( gvar->datatype.IsObject() && !gvar->datatype.IsObjectHandle() )
 	{
 		// Call the default constructor in case no explicit initialization is given
 		CallDefaultConstructor(gvar->datatype, gvar->index, true, &ctx.bc, gvar->idNode, true);
@@ -1540,13 +1556,7 @@ void asCCompiler::MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprC
 				}
 				else
 				{
-					if( args[n]->type.dataType.GetObjectType() &&
-						(args[n]->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE) &&
-						args[n]->type.isVariable &&
-						IsVariableOnHeap(args[n]->type.stackOffset) )
-						bc->InstrWORD(asBC_GETOBJREF, (asWORD)offset);
-					else
-						bc->InstrWORD(asBC_GETREF, (asWORD)offset);
+					bc->InstrWORD(asBC_GETREF, (asWORD)offset);
 				}
 			}
 		}
@@ -1685,10 +1695,12 @@ int asCCompiler::CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext
 	return anyErrors ? -1 : 0;
 }
 
-void asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType, bool isConstMethod, bool silent, bool allowObjectConstruct, const asCString &scope)
+asUINT asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType, bool isConstMethod, bool silent, bool allowObjectConstruct, const asCString &scope)
 {
 	asCArray<int> origFuncs = funcs; // Keep the original list for error message
 
+	asUINT cost = 0;
+
 	asUINT n;
 	if( funcs.GetLength() > 0 )
 	{
@@ -1730,7 +1742,7 @@ void asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*>
 		for( n = 0; n < args.GetLength(); ++n )
 		{
 			asCArray<int> tempFuncs;
-			MatchArgument(funcs, tempFuncs, &args[n]->type, n, allowObjectConstruct);
+			cost += MatchArgument(funcs, tempFuncs, &args[n]->type, n, allowObjectConstruct);
 
 			// Intersect the found functions with the list of matching functions
 			for( asUINT f = 0; f < matchingFuncs.GetLength(); f++ )
@@ -1809,6 +1821,8 @@ void asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*>
 			PrintMatchingFuncs(funcs, node);
 		}
 	}
+
+	return cost;
 }
 
 void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
@@ -2038,6 +2052,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 					// the default action is a direct copy if it is the same type
 					// and a simple assignment.
 					bool assigned = false;
+					// Even though an ASHANDLE can be an explicit handle the overloaded operator needs to be called
 					if( lexpr.type.dataType.IsObject() && (!lexpr.type.isExplicitHandle || (lexpr.type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE)) )
 					{
 						assigned = CompileOverloadedDualOperator(node, &lexpr, &expr, &ctx);
@@ -3097,7 +3112,7 @@ void asCCompiler::PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ct
 	lvalue.isVariable = true;
 	lvalue.isExplicitHandle = ctx->type.isExplicitHandle;
 
-	if( (!dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_ASHANDLE))) &&
+	if( !dt.IsObjectHandle() &&
 		dt.GetObjectType() && (dt.GetBehaviour()->copyconstruct || dt.GetBehaviour()->copyfactory) )
 	{
 		PrepareForAssignment(&lvalue.dataType, ctx, node, true);
@@ -3259,7 +3274,7 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 			// need to load it into the register
 			if( !expr.type.dataType.IsPrimitive() )
 			{
-				if( (!expr.type.dataType.IsObjectHandle() || (expr.type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE)) &&
+				if( !expr.type.dataType.IsObjectHandle() &&
 					expr.type.dataType.IsReference() )
 					expr.bc.Instr(asBC_RDSPTR);
 
@@ -4142,25 +4157,46 @@ bool asCCompiler::CompileRefCast(asSExprContext *ctx, const asCDataType &to, boo
 }
 
 
-void asCCompiler::ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const asCDataType &toOrig, asCScriptNode *node, EImplicitConv convType, bool generateCode)
+asUINT asCCompiler::ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const asCDataType &toOrig, asCScriptNode *node, EImplicitConv convType, bool generateCode)
 {
 	asCDataType to = toOrig;
 	to.MakeReference(false);
 	asASSERT( !ctx->type.dataType.IsReference() );
 
+	// Maybe no conversion is needed
+	if( to.IsEqualExceptConst(ctx->type.dataType) )
+	{
+		// A primitive is const or not
+		ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
+		return asCC_NO_CONV;
+	}
+
+	// Determine the cost of this conversion
+	asUINT cost = asCC_NO_CONV;
+	if( (to.IsIntegerType() || to.IsUnsignedType()) && (ctx->type.dataType.IsFloatType() || ctx->type.dataType.IsDoubleType()) )
+		cost = asCC_INT_FLOAT_CONV;
+	else if( (to.IsFloatType() || to.IsDoubleType()) && (ctx->type.dataType.IsIntegerType() || ctx->type.dataType.IsUnsignedType() || ctx->type.dataType.IsEnumType()) )
+		cost = asCC_INT_FLOAT_CONV;
+	else if( to.IsUnsignedType() && ctx->type.dataType.IsIntegerType() )
+		cost = asCC_SIGNED_CONV;
+	else if( to.IsIntegerType() && (ctx->type.dataType.IsUnsignedType() || ctx->type.dataType.IsEnumType()) )
+		cost = asCC_SIGNED_CONV;
+	else if( to.GetSizeInMemoryBytes() || ctx->type.dataType.GetSizeInMemoryBytes() )
+		cost = asCC_PRIMITIVE_SIZE_CONV;
+
 	// Start by implicitly converting constant values
 	if( ctx->type.isConstant )
+	{
 		ImplicitConversionConstant(ctx, to, node, convType);
-
-	// A primitive is const or not
-	ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
-
-	if( to == ctx->type.dataType )
-		return;
+		ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
+		return cost;
+	}
 
 	// Allow implicit conversion between numbers
 	if( generateCode )
 	{
+		// When generating the code the decision has already been made, so we don't bother determining the cost
+
 		// Convert smaller types to 32bit first
 		int s = ctx->type.dataType.GetSizeInMemoryBytes();
 		if( s < 4 )
@@ -4456,16 +4492,17 @@ void asCCompiler::ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const as
 
 	// Primitive types on the stack, can be const or non-const
 	ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
+	return cost;
 }
 
-void asCCompiler::ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode, bool allowObjectConstruct)
+asUINT asCCompiler::ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode, bool allowObjectConstruct)
 {
 	asASSERT( ctx->type.dataType.GetTokenType() != ttUnrecognizedToken ||
 		      ctx->type.dataType.IsNullHandle() );
 
 	// No conversion from void to any other type
 	if( ctx->type.dataType.GetTokenType() == ttVoid )
-		return;
+		return asCC_NO_CONV;
 
 	// Do we want a var type?
 	if( to.GetTokenType() == ttQuestion )
@@ -4475,26 +4512,28 @@ void asCCompiler::ImplicitConversion(asSExprContext *ctx, const asCDataType &to,
 
 		ctx->type.dataType = to;
 
-		return;
+		return asCC_VARIABLE_CONV;
 	}
 	// Do we want a primitive?
 	else if( to.IsPrimitive() )
 	{
 		if( !ctx->type.dataType.IsPrimitive() )
-			ImplicitConvObjectToPrimitive(ctx, to, node, convType, generateCode);
+			return ImplicitConvObjectToPrimitive(ctx, to, node, convType, generateCode);
 		else
-			ImplicitConvPrimitiveToPrimitive(ctx, to, node, convType, generateCode);
+			return ImplicitConvPrimitiveToPrimitive(ctx, to, node, convType, generateCode);
 	}
 	else // The target is a complex type
 	{
 		if( ctx->type.dataType.IsPrimitive() )
-			ImplicitConvPrimitiveToObject(ctx, to, node, convType, generateCode, allowObjectConstruct);
+			return ImplicitConvPrimitiveToObject(ctx, to, node, convType, generateCode, allowObjectConstruct);
 		else if( ctx->type.IsNullConstant() || ctx->type.dataType.GetObjectType() )
-			ImplicitConvObjectToObject(ctx, to, node, convType, generateCode, allowObjectConstruct);
+			return ImplicitConvObjectToObject(ctx, to, node, convType, generateCode, allowObjectConstruct);
 	}
+
+	return asCC_NO_CONV;
 }
 
-void asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode)
+asUINT asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode)
 {
 	if( ctx->type.isExplicitHandle )
 	{
@@ -4505,7 +4544,7 @@ void asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDa
 			str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, ctx->type.dataType.Format().AddressOf(), to.Format().AddressOf());
 			Error(str.AddressOf(), node);
 		}
-		return;
+		return asCC_NO_CONV;
 	}
 
 	// TODO: Must use the const cast behaviour if the object is read-only
@@ -4606,7 +4645,7 @@ void asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDa
 			ctx->type.Set(descr->returnType);
 
 		// Allow one more implicit conversion to another primitive type
-		ImplicitConversion(ctx, to, node, convType, generateCode, false);
+		return asCC_OBJ_TO_PRIMITIVE_CONV + ImplicitConversion(ctx, to, node, convType, generateCode, false);
 	}
 	else
 	{
@@ -4617,19 +4656,22 @@ void asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDa
 			Error(str.AddressOf(), node);
 		}
 	}
-}
 
+	return asCC_NO_CONV;
+}
 
 
-void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode, bool allowObjectConstruct)
+asUINT asCCompiler::ImplicitConvObjectRef(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode)
 {
 	// Convert null to any object type handle, but not to a non-handle type
 	if( ctx->type.IsNullConstant() )
 	{
 		if( to.IsObjectHandle() )
+		{
 			ctx->type.dataType = to;
-
-		return;
+			return asCC_REF_CONV;
+		}
+		return asCC_NO_CONV;
 	}
 
 	asASSERT(ctx->type.dataType.GetObjectType());
@@ -4641,16 +4683,16 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 		if( ctx->type.dataType.GetObjectType()->Implements(to.GetObjectType()) )
 		{
 			ctx->type.dataType.SetObjectType(to.GetObjectType());
+			return asCC_REF_CONV;
 		}
-
 		// If the to type is a class and the from type derives from it, then we can convert it immediately
-		if( ctx->type.dataType.GetObjectType()->DerivesFrom(to.GetObjectType()) )
+		else if( ctx->type.dataType.GetObjectType()->DerivesFrom(to.GetObjectType()) )
 		{
 			ctx->type.dataType.SetObjectType(to.GetObjectType());
+			return asCC_REF_CONV;
 		}
-
 		// If the types are not equal yet, then we may still be able to find a reference cast
-		if( ctx->type.dataType.GetObjectType() != to.GetObjectType() )
+		else if( ctx->type.dataType.GetObjectType() != to.GetObjectType() )
 		{
 			// A ref cast must not remove the constness
 			bool isConst = false;
@@ -4662,12 +4704,36 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 			CompileRefCast(ctx, to, convType == asIC_EXPLICIT_REF_CAST, node, generateCode);
 
 			ctx->type.dataType.MakeHandleToConst(isConst);
+
+			// Was the conversion done?
+			if( ctx->type.dataType.GetObjectType() == to.GetObjectType() )
+				return asCC_REF_CONV;
 		}
 	}
 
+	// Convert matching function types
+	if( to.GetFuncDef() && ctx->type.dataType.GetFuncDef() &&
+		to.GetFuncDef() != ctx->type.dataType.GetFuncDef() )
+	{
+		asCScriptFunction *toFunc = to.GetFuncDef();
+		asCScriptFunction *fromFunc = ctx->type.dataType.GetFuncDef();
+		if( toFunc->IsSignatureExceptNameEqual(fromFunc) )
+		{
+			ctx->type.dataType.SetFuncDef(toFunc);
+			return asCC_REF_CONV;
+		}
+	}
+
+	return asCC_NO_CONV;
+}
+
+asUINT asCCompiler::ImplicitConvObjectValue(asSExprContext *ctx, const asCDataType &to, asCScriptNode * /*node*/, EImplicitConv convType, bool generateCode)
+{
+	asUINT cost = asCC_NO_CONV;
+
 	// If the base type is still different, and we are allowed to instance
 	// another object then we can try an implicit value cast
-	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() && allowObjectConstruct )
+	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() )
 	{
 		// TODO: Implement support for implicit constructor/factory
 
@@ -4734,28 +4800,111 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 			}
 			else
 				ctx->type.Set(f->returnType);
+
+			cost = asCC_TO_OBJECT_CONV;
 		}
 	}
 
-	// If we still haven't converted the base type to the correct type, then there is no need to continue
-	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() )
-		return;
+	return cost;
+}
 
-	// Convert matching function types
-	if( to.GetFuncDef() && ctx->type.dataType.GetFuncDef() &&
-		to.GetFuncDef() != ctx->type.dataType.GetFuncDef() )
+asUINT asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode, bool allowObjectConstruct)
+{
+	// First try a ref cast
+	asUINT cost = ImplicitConvObjectRef(ctx, to, node, convType, generateCode);
+
+	// If the desired type is an asOBJ_ASHANDLE then we'll assume it is allowed to implicitly 
+	// construct the object through any of the available constructors
+	if( to.GetObjectType() && (to.GetObjectType()->flags & asOBJ_ASHANDLE) && to.GetObjectType() != ctx->type.dataType.GetObjectType() && allowObjectConstruct )
 	{
-		asCScriptFunction *toFunc = to.GetFuncDef();
-		asCScriptFunction *fromFunc = ctx->type.dataType.GetFuncDef();
-		if( toFunc->IsSignatureExceptNameEqual(fromFunc) )
+		asCArray<int> funcs;
+		funcs = to.GetObjectType()->beh.constructors;
+
+		asCArray<asSExprContext *> args;
+		args.PushLast(ctx);
+
+		cost = asCC_TO_OBJECT_CONV + MatchFunctions(funcs, args, node, 0, 0, false, true, false);
+
+		// Did we find a matching constructor?
+		if( funcs.GetLength() == 1 )
 		{
-			ctx->type.dataType.SetFuncDef(toFunc);
+			if( generateCode )
+			{
+				// TODO: This should really reuse the code from CompileConstructCall
+
+				// Allocate the new object
+				asCTypeInfo tempObj;
+				tempObj.dataType = to;
+				tempObj.dataType.MakeReference(false);
+				tempObj.stackOffset = (short)AllocateVariable(tempObj.dataType, true);
+				tempObj.dataType.MakeReference(true);
+				tempObj.isTemporary = true;
+				tempObj.isVariable = true;
+
+				bool onHeap = IsVariableOnHeap(tempObj.stackOffset);
+
+				// Push the address of the object on the stack
+				asSExprContext e(engine);
+				if( onHeap )
+					e.bc.InstrSHORT(asBC_VAR, tempObj.stackOffset);
+
+				PrepareFunctionCall(funcs[0], &e.bc, args);
+				MoveArgsToStack(funcs[0], &e.bc, args, false);
+
+				// If the object is allocated on the stack, then call the constructor as a normal function
+				if( onHeap )
+				{
+					int offset = 0;
+					asCScriptFunction *descr = builder->GetFunctionDescription(funcs[0]);
+					offset = descr->parameterTypes[0].GetSizeOnStackDWords();
+
+					e.bc.InstrWORD(asBC_GETREF, (asWORD)offset);
+				}		
+				else
+					e.bc.InstrSHORT(asBC_PSF, tempObj.stackOffset);
+
+				PerformFunctionCall(funcs[0], &e, onHeap, &args, tempObj.dataType.GetObjectType());
+
+				// Add tag that the object has been initialized
+				e.bc.ObjInfo(tempObj.stackOffset, asOBJ_INIT);
+
+				// The constructor doesn't return anything,
+				// so we have to manually inform the type of
+				// the return value
+				e.type = tempObj;
+				if( !onHeap )
+					e.type.dataType.MakeReference(false);
+
+				// Push the address of the object on the stack again
+				e.bc.InstrSHORT(asBC_PSF, tempObj.stackOffset);
+
+				MergeExprBytecodeAndType(ctx, &e);
+			}
+			else
+			{
+				ctx->type.Set(asCDataType::CreateObject(to.GetObjectType(), false));
+			}
 		}
 	}
 
+	// If the base type is still different, and we are allowed to instance
+	// another object then we can try an implicit value cast
+	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() && allowObjectConstruct )
+	{
+		// Attempt implicit value cast
+		cost = ImplicitConvObjectValue(ctx, to, node, convType, generateCode);
+	}
+
+	// If we still haven't converted the base type to the correct type, then there is
+	//  no need to continue as it is not possible to do the conversion
+	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() )
+		return asCC_NO_CONV;
+
 
 	if( to.IsObjectHandle() )
 	{
+		// There is no extra cost in converting to a handle
+
 		// reference to handle -> handle
 		// reference           -> handle
 		// object              -> handle
@@ -4808,6 +4957,8 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 		{
 			if( generateCode )
 			{
+				asASSERT( ctx->type.dataType.IsObjectHandle() );
+
 				// If the input type is a handle, then a simple ref copy is enough
 				bool isExplicitHandle = ctx->type.isExplicitHandle;
 				ctx->type.isExplicitHandle = ctx->type.dataType.IsObjectHandle();
@@ -4834,13 +4985,7 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 		}
 		else if( !to.IsReference() && ctx->type.dataType.IsReference() )
 		{
-			// ASHANDLE is really a value type, even though it looks
-			// like a handle, so we shouldn't dereference it
-			if( !(ctx->type.dataType.GetObjectType() && (ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE)) ||
-				(ctx->type.isVariable && IsVariableOnHeap(ctx->type.stackOffset)) )
-				Dereference(ctx, generateCode);
-			else
-				ctx->type.dataType.MakeReference(false);
+			Dereference(ctx, generateCode);
 		}
 	}
 	else
@@ -4876,14 +5021,22 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 					// In case the object was already in a temporary variable, then the function
 					// didn't really do anything so we need to remove the constness here
 					ctx->type.dataType.MakeReadOnly(false);
+
+					// Add the cost for the copy
+					cost += asCC_TO_OBJECT_CONV;
 				}
 			}
 
 			if( ctx->type.dataType.IsReference() )
 			{
-				Dereference(ctx, generateCode);
-
-				// TODO: Can't this leave unhandled deferred output params?
+				// This may look strange, but a value type allocated on the stack is already 
+				// correct, so nothing should be done other than remove the mark as reference.
+				// For types allocated on the heap, it is necessary to dereference the pointer
+				// that is currently on the stack
+				if( IsVariableOnHeap(ctx->type.stackOffset) )
+					Dereference(ctx, generateCode);
+				else
+					ctx->type.dataType.MakeReference(false);
 			}
 
 			// A non-const object can be converted to a const object directly
@@ -4931,6 +5084,9 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 						// doesn't have to be made as it is already a unique object
 						PrepareTemporaryObject(node, ctx);
 					}
+
+					// Add the cost for the copy
+					cost += asCC_TO_OBJECT_CONV;
 				}
 			}
 			else
@@ -4960,6 +5116,9 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 					PrepareTemporaryObject(node, ctx);
 
 					ctx->type.dataType.MakeReadOnly(typeIsReadOnly);
+
+					// Add the cost for the copy
+					cost += asCC_TO_OBJECT_CONV;
 				}
 
 				// A handle can be converted to a reference, by checking for a null pointer
@@ -4980,18 +5139,21 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 					ctx->type.dataType.MakeReference(IsVariableOnHeap(ctx->type.stackOffset));
 				}
 
-				// TODO: If the variable is an object allocated on the stack, this is not true
+				// TODO: If the variable is an object allocated on the stack the following is not true as the copy may not have been made
 				// Since it is a new temporary variable it doesn't have to be const
 				ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
 			}
 		}
 	}
+
+	return cost;
 }
 
-void asCCompiler::ImplicitConvPrimitiveToObject(asSExprContext * /*ctx*/, const asCDataType & /*to*/, asCScriptNode * /*node*/, EImplicitConv /*isExplicit*/, bool /*generateCode*/, bool /*allowObjectConstruct*/)
+asUINT asCCompiler::ImplicitConvPrimitiveToObject(asSExprContext * /*ctx*/, const asCDataType & /*to*/, asCScriptNode * /*node*/, EImplicitConv /*isExplicit*/, bool /*generateCode*/, bool /*allowObjectConstruct*/)
 {
 	// TODO: This function should call the constructor/factory that has been marked as available
 	//       for implicit conversions. The code will likely be similar to CallCopyConstructor()
+	return asCC_NO_CONV;
 }
 
 void asCCompiler::ImplicitConversionConstant(asSExprContext *from, const asCDataType &to, asCScriptNode *node, EImplicitConv convType)
@@ -7157,13 +7319,7 @@ void asCCompiler::CompileConversion(asCScriptNode *node, asSExprContext *ctx)
 	if( expr.type.dataType.IsReference() )
 	{
 		if( expr.type.dataType.IsObject() )
-		{
-			// ASHANDLE is actually a value type, even though it looks like a handle
-			// For this reason we shouldn't dereference it, unless it is on the heap
-			if( !(expr.type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE) ||
-				(expr.type.isVariable && IsVariableOnHeap(expr.type.stackOffset)) )
-				Dereference(&expr, true);
-		}
+			Dereference(&expr, true);
 		else
 			ConvertToVariable(&expr);
 	}
@@ -7327,8 +7483,8 @@ void asCCompiler::ProcessDeferredParams(asSExprContext *ctx)
 				if( !expr->type.isConstant || expr->type.IsNullConstant() )
 					ctx->bc.Pop(expr->type.dataType.GetSizeOnStackDWords());
 
-				// Give a warning, except if the argument is null which indicate the argument is really to be ignored
-				if( !expr->type.IsNullConstant() )
+				// Give a warning, except if the argument is null or 0 which indicate the argument is really to be ignored
+				if( !expr->type.IsNullConstant() && !(expr->type.isConstant && expr->type.qwordValue == 0) )
 					Warning(TXT_ARG_NOT_LVALUE, outParam.argNode);
 
 				ReleaseTemporaryVariable(outParam.argType, &ctx->bc);
@@ -7703,21 +7859,25 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx
 		// Verify that the type allow its handle to be taken
 		if( ctx->type.isExplicitHandle ||
 			!ctx->type.dataType.IsObject() ||
-			!((ctx->type.dataType.GetObjectType()->beh.addref && ctx->type.dataType.GetObjectType()->beh.release) || ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE) )
+			!((ctx->type.dataType.GetObjectType()->beh.addref && ctx->type.dataType.GetObjectType()->beh.release) || 
+			  (ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE)) )
 		{
 			Error(TXT_OBJECT_HANDLE_NOT_SUPPORTED, node);
 			return -1;
 		}
 
 		// Objects that are not local variables are not references
-		if( !ctx->type.dataType.IsReference() && !(ctx->type.dataType.IsObject() && !ctx->type.isVariable) )
+		// Objects allocated on the stack are also not marked as references
+		if( !ctx->type.dataType.IsReference() && 
+			!(ctx->type.dataType.IsObject() && !ctx->type.isVariable) &&
+			!(ctx->type.isVariable && !IsVariableOnHeap(ctx->type.stackOffset)) )
 		{
 			Error(TXT_NOT_VALID_REFERENCE, node);
 			return -1;
 		}
 
 		// If this is really an object then the handle created is a const handle
-		bool makeConst = !ctx->type.dataType.IsObjectHandle();
+		bool makeConst = !ctx->type.dataType.IsObjectHandle() && !(ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE);
 
 		// Mark the type as an object handle
 		ctx->type.dataType.MakeHandle(true);
@@ -8873,19 +9033,12 @@ int asCCompiler::GetPrecedence(asCScriptNode *op)
 	return 0;
 }
 
-int asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct)
+asUINT asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct)
 {
-	bool isExactMatch        = false;
-	bool isMatchExceptConst  = false;
-	bool isMatchWithBaseType = false;
-	bool isMatchExceptSign   = false;
-	bool isMatchNotVarType   = false;
-
-	asUINT n;
-
+	asUINT bestCost = asUINT(-1);
 	matches.SetLength(0);
 
-	for( n = 0; n < funcs.GetLength(); n++ )
+	for( asUINT n = 0; n < funcs.GetLength(); n++ )
 	{
 		asCScriptFunction *desc = builder->GetFunctionDescription(funcs[n]);
 
@@ -8897,7 +9050,7 @@ int asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, con
 		asSExprContext ti(engine);
 		ti.type = *argType;
 		if( argType->dataType.IsPrimitive() ) ti.type.dataType.MakeReference(false);
-		ImplicitConversion(&ti, desc->parameterTypes[paramNum], 0, asIC_IMPLICIT_CONV, false, allowObjectConstruct);
+		asUINT cost = ImplicitConversion(&ti, desc->parameterTypes[paramNum], 0, asIC_IMPLICIT_CONV, false, allowObjectConstruct);
 
 		// If the function parameter is an inout-reference then it must not be possible to call the
 		// function with an incorrect argument type, even though the type can normally be converted.
@@ -8917,85 +9070,18 @@ int asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, con
 		// How well does the argument match the function parameter?
 		if( desc->parameterTypes[paramNum].IsEqualExceptRef(ti.type.dataType) )
 		{
-			// Is it an exact match?
-			if( argType->dataType.IsEqualExceptRef(ti.type.dataType) )
+			if( cost < bestCost )
 			{
-				if( !isExactMatch ) matches.SetLength(0);
-
-				isExactMatch = true;
-
-				matches.PushLast(funcs[n]);
-				continue;
+				matches.SetLength(0);
+				bestCost = cost;
 			}
 
-			if( !isExactMatch )
-			{
-				// Is it a match except const?
-				if( argType->dataType.IsEqualExceptRefAndConst(ti.type.dataType) )
-				{
-					if( !isMatchExceptConst ) matches.SetLength(0);
-
-					isMatchExceptConst = true;
-
-					matches.PushLast(funcs[n]);
-					continue;
-				}
-
-				if( !isMatchExceptConst )
-				{
-					// Is it a size promotion, e.g. int8 -> int?
-					if( argType->dataType.IsSamePrimitiveBaseType(ti.type.dataType) ||
-						(argType->dataType.IsEnumType() && ti.type.dataType.IsIntegerType()) )
-					{
-						if( !isMatchWithBaseType ) matches.SetLength(0);
-
-						isMatchWithBaseType = true;
-
-						matches.PushLast(funcs[n]);
-						continue;
-					}
-
-					if( !isMatchWithBaseType )
-					{
-						// Conversion between signed and unsigned integer is better than between integer and float
-
-						// Is it a match except for sign?
-						if( (argType->dataType.IsIntegerType() && ti.type.dataType.IsUnsignedType()) ||
-							(argType->dataType.IsUnsignedType() && ti.type.dataType.IsIntegerType()) ||
-							(argType->dataType.IsEnumType() && ti.type.dataType.IsUnsignedType()) )
-						{
-							if( !isMatchExceptSign ) matches.SetLength(0);
-
-							isMatchExceptSign = true;
-
-							matches.PushLast(funcs[n]);
-							continue;
-						}
-
-						if( !isMatchExceptSign )
-						{
-							// If there was any match without a var type it has higher priority
-							if( desc->parameterTypes[paramNum].GetTokenType() != ttQuestion )
-							{
-								if( !isMatchNotVarType ) matches.SetLength(0);
-
-								isMatchNotVarType = true;
-
-								matches.PushLast(funcs[n]);
-								continue;
-							}
-
-							// Implicit conversion to ?& has the smallest priority
-							if( !isMatchNotVarType )
-								matches.PushLast(funcs[n]);
-						}
-					}
-				}
-			}
+			if( cost == bestCost )
+				matches.PushLast(funcs[n]);
 		}
 	}
 
-	return (int)matches.GetLength();
+	return bestCost;
 }
 
 void asCCompiler::PrepareArgument2(asSExprContext *ctx, asSExprContext *arg, asCDataType *paramType, bool isFunction, int refType, bool isMakingCopy)
@@ -9303,11 +9389,7 @@ void asCCompiler::MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectTyp
 {
 	if( objectType )
 	{
-		// The ASHANDLE type is really a value type, so if it is a
-		// local variable on the stack it must not be dereferenced
-		if( !(objectType->flags & asOBJ_ASHANDLE) ||
-			!(ctx->type.isVariable && !IsVariableOnHeap(ctx->type.stackOffset)) )
-			Dereference(ctx, true);
+		Dereference(ctx, true);
 
 		// This following warning was removed as there may be valid reasons
 		// for calling non-const methods on temporary objects, and we shouldn't
@@ -10998,7 +11080,7 @@ void asCCompiler::PerformFunctionCall(int funcId, asSExprContext *ctx, bool isCo
 		{
 			ctx->bc.Instr(asBC_PshRPtr);
 			if( descr->returnType.IsObject() &&
-				(!descr->returnType.IsObjectHandle() || (descr->returnType.GetObjectType()->flags & asOBJ_ASHANDLE)) )
+				!descr->returnType.IsObjectHandle() )
 			{
 				// We are getting the pointer to the object
 				// not a pointer to a object variable

+ 25 - 9
ThirdParty/AngelScript/source/as_compiler.h

@@ -102,6 +102,19 @@ enum EImplicitConv
 	asIC_EXPLICIT_VAL_CAST
 };
 
+enum EConvCost
+{
+	asCC_NO_CONV               = 0,
+	asCC_CONST_CONV            = 1,
+	asCC_PRIMITIVE_SIZE_CONV   = 2,
+	asCC_SIGNED_CONV           = 3,
+	asCC_INT_FLOAT_CONV        = 4,
+	asCC_REF_CONV              = 5,
+	asCC_OBJ_TO_PRIMITIVE_CONV = 6,
+	asCC_TO_OBJECT_CONV        = 7,
+	asCC_VARIABLE_CONV         = 8
+};
+
 class asCCompiler
 {
 public:
@@ -109,7 +122,7 @@ public:
 	~asCCompiler();
 
 	int CompileFunction(asCBuilder *builder, asCScriptCode *script, sExplicitSignature *signature, asCScriptNode *func, asCScriptFunction *outFunc);
-	int CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
+	int CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, asCScriptFunction *outFunc);
 	int CompileFactory(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
 	int CompileTemplateFactoryStub(asCBuilder *builder, int trueFactoryId, asCObjectType *objType, asCScriptFunction *outFunc);
 	int CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *expr, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc);
@@ -162,7 +175,7 @@ protected:
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
-	void MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
+	asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
 	int  CompileVariableAccess(const asCString &name, const asCString &scope, asSExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, bool noFunction = false, asCObjectType *objType = 0);
 
 	// Helper functions
@@ -178,7 +191,7 @@ protected:
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	void Dereference(asSExprContext *ctx, bool generateCode);
 	bool CompileRefCast(asSExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
-	int  MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct = true);
+	asUINT MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct = true);
 	void PerformFunctionCall(int funcId, asSExprContext *out, bool isConstructor = false, asCArray<asSExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset);
 	void MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asSExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
@@ -201,12 +214,15 @@ protected:
 	asCString GetScopeFromNode(asCScriptNode *node);
 	void DestroyVariables(asCByteCode *bc);
 
-	void ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
-	void ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
-	void ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
-	void ImplicitConvPrimitiveToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
-	void ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
-	void ImplicitConversionConstant(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType);
+	// Returns the cost of the conversion (the sum of the EConvCost performed)
+	asUINT ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
+	asUINT ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
+	asUINT ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
+	asUINT ImplicitConvPrimitiveToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
+	asUINT ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
+	asUINT ImplicitConvObjectRef(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
+	asUINT ImplicitConvObjectValue(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
+	void   ImplicitConversionConstant(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType);
 
 	void LineInstr(asCByteCode *bc, size_t pos);
 

+ 6 - 0
ThirdParty/AngelScript/source/as_config.h

@@ -576,6 +576,8 @@
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#undef COMPLEX_RETURN_MASK
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#define AS_LARGE_OBJS_PASSED_BY_REF
+			#define AS_LARGE_OBJ_MIN_SIZE 5
 			// STDCALL is not available on 64bit Mac
 			#undef STDCALL
 			#define STDCALL
@@ -670,6 +672,8 @@
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#undef COMPLEX_RETURN_MASK
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#define AS_LARGE_OBJS_PASSED_BY_REF
+			#define AS_LARGE_OBJ_MIN_SIZE 5
 			// STDCALL is not available on 64bit Linux
 			#undef STDCALL
 			#define STDCALL
@@ -718,6 +722,8 @@
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#undef COMPLEX_RETURN_MASK
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#define AS_LARGE_OBJS_PASSED_BY_REF
+			#define AS_LARGE_OBJ_MIN_SIZE 5
 			#undef STDCALL
 			#define STDCALL
 		#else

+ 16 - 6
ThirdParty/AngelScript/source/as_datatype.cpp

@@ -75,6 +75,15 @@ asCDataType::~asCDataType()
 {
 }
 
+bool asCDataType::IsValid() const
+{
+	if( tokenType == ttUnrecognizedToken &&
+		!isObjectHandle )
+		return false;
+
+	return true;
+}
+
 asCDataType asCDataType::CreateObject(asCObjectType *ot, bool isConst)
 {
 	asCDataType dt;
@@ -220,8 +229,9 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 	else if( b && !isObjectHandle )
 	{
 		// Only reference types are allowed to be handles, 
-		// but not nohandle reference types, and not scoped references (except when returned from registered function)
-		// funcdefs are special reference types, and support handles
+		// but not nohandle reference types, and not scoped references 
+		// (except when returned from registered function)
+		// funcdefs are special reference types and support handles
 		// value types with asOBJ_ASHANDLE are treated as a handle
 		if( !funcDef && 
 			(!objectType || 
@@ -232,6 +242,10 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 
 		isObjectHandle = b;
 		isConstHandle = false;
+
+		// ASHANDLE supports being handle, but as it really is a value type it will not be marked as a handle
+		if( (objectType->flags & asOBJ_ASHANDLE) )
+			isObjectHandle = false;
 	}
 
 	return 0;
@@ -316,10 +330,6 @@ bool asCDataType::CanBeInstanciated() const
 		   objectType->beh.factories.GetLength() == 0))) ) // the ref type cannot be instanciated
 		return false;
 
-	// An ASHANDLE type can only be declared as a handle, even though it is a value type
-	if( IsObject() && (objectType->flags & asOBJ_ASHANDLE) && !IsObjectHandle() )
-		return false;
-
 	return true;
 }
 

+ 3 - 1
ThirdParty/AngelScript/source/as_datatype.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -58,6 +58,8 @@ public:
 	asCDataType(const asCDataType &);
 	~asCDataType();
 
+	bool IsValid() const;
+
 	asCString Format() const;
 
 	static asCDataType CreatePrimitive(eTokenType tt, bool isConst);

+ 5 - 6
ThirdParty/AngelScript/source/as_module.cpp

@@ -619,8 +619,7 @@ void *asCModule::GetAddressOfGlobalVar(asUINT index)
 
 	// For object variables it's necessary to dereference the pointer to get the address of the value
 	if( scriptGlobals[index]->type.IsObject() && 
-		(!scriptGlobals[index]->type.IsObjectHandle() || 
-		 (scriptGlobals[index]->type.GetObjectType()->flags & asOBJ_ASHANDLE)) )
+		!scriptGlobals[index]->type.IsObjectHandle() )
 		return *(void**)(scriptGlobals[index]->GetAddressOfValue());
 
 	return (void*)(scriptGlobals[index]->GetAddressOfValue());
@@ -708,8 +707,8 @@ const char *asCModule::GetEnumByIndex(asUINT index, int *enumTypeId) const
 // interface
 int asCModule::GetEnumValueCount(int enumTypeId) const
 {
-	const asCDataType *dt = engine->GetDataTypeFromTypeId(enumTypeId);
-	asCObjectType *t = dt->GetObjectType();
+	asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
+	asCObjectType *t = dt.GetObjectType();
 	if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) ) 
 		return asINVALID_TYPE;
 
@@ -719,8 +718,8 @@ int asCModule::GetEnumValueCount(int enumTypeId) const
 // interface
 const char *asCModule::GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const
 {
-	const asCDataType *dt = engine->GetDataTypeFromTypeId(enumTypeId);
-	asCObjectType *t = dt->GetObjectType();
+	asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
+	asCObjectType *t = dt.GetObjectType();
 	if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) ) 
 		return 0;
 

+ 38 - 4
ThirdParty/AngelScript/source/as_restore.cpp

@@ -223,6 +223,8 @@ int asCRestore::Save()
 
 int asCRestore::Restore() 
 {
+	engine->deferValidationOfTemplateTypes = true;
+
 	// Before starting the load, make sure that 
 	// any existing resources have been freed
 	module->InternalReset();
@@ -451,6 +453,25 @@ int asCRestore::Restore()
 	// usedObjectProperties
 	ReadUsedObjectProps();
 
+	// Validate the template types
+	for( i = 0; i < usedTypes.GetLength(); i++ )
+	{
+		if( (usedTypes[i]->flags & asOBJ_TEMPLATE) && 
+			usedTypes[i]->templateSubType.IsValid() &&
+			usedTypes[i]->beh.templateCallback )
+		{
+			asCScriptFunction *callback = engine->scriptFunctions[usedTypes[i]->beh.templateCallback];
+			if( !engine->CallGlobalFunctionRetBool(usedTypes[i], 0, callback->sysFuncIntf, callback) )
+			{
+				asCString str;
+				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), usedTypes[i]->templateSubType.Format().AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+				error = true;
+			}
+		}
+	}
+	engine->deferValidationOfTemplateTypes = false;
+
 	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
 		TranslateFunction(module->scriptFunctions[i]);
 	for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
@@ -476,6 +497,16 @@ int asCRestore::Restore()
 			if( r < 0 ) error = true;
 		}
 	}
+	else
+	{
+		// Make sure none of the loaded functions attempt to release references that have not yet been increased
+		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
+			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
+				module->scriptFunctions[i]->byteCode.SetLength(0);
+		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
+			if( module->scriptGlobals[i]->GetInitFunc() )
+				module->scriptGlobals[i]->GetInitFunc()->byteCode.SetLength(0);
+	}
 
 	return error ? asERROR : asSUCCESS;
 }
@@ -2325,7 +2356,10 @@ void asCRestore::WriteUsedTypeIds()
 	asUINT count = (asUINT)usedTypeIds.GetLength();
 	WriteEncodedUInt(count);
 	for( asUINT n = 0; n < count; n++ )
-		WriteDataType(engine->GetDataTypeFromTypeId(usedTypeIds[n]));
+	{
+		asCDataType dt = engine->GetDataTypeFromTypeId(usedTypeIds[n]);
+		WriteDataType(&dt);
+	}
 }
 
 void asCRestore::ReadUsedTypeIds()
@@ -2619,14 +2653,14 @@ void asCRestore::TranslateFunction(asCScriptFunction *func)
 
 			// COPY is used to copy POD types that don't have the opAssign method
 			// Update the number of dwords to copy as it may be different on the target platform
-			const asCDataType *dt = engine->GetDataTypeFromTypeId(*tid);
-			if( dt == 0 )
+			asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
+			if( !dt.IsValid() )
 			{
 				// TODO: Write error to message
 				error = true;
 			}
 			else
-				asBC_SWORDARG0(&bc[n]) = (short)dt->GetSizeInMemoryDWords();
+				asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
 		}
 		else if( c == asBC_CALL ||
 				 c == asBC_CALLINTF ||

File diff suppressed because it is too large
+ 186 - 175
ThirdParty/AngelScript/source/as_scriptengine.cpp


+ 3 - 2
ThirdParty/AngelScript/source/as_scriptengine.h

@@ -273,10 +273,10 @@ public:
 	void SetScriptFunction(asCScriptFunction *func);
 	void FreeScriptFunctionId(int id);
 
-	int ConfigError(int err);
+	int ConfigError(int err, const char *funcName, const char *arg1, const char *arg2);
 
 	int                GetTypeIdFromDataType(const asCDataType &dt) const;
-	const asCDataType *GetDataTypeFromTypeId(int typeId) const;
+	asCDataType        GetDataTypeFromTypeId(int typeId) const;
 	asCObjectType     *GetObjectTypeFromTypeId(int typeId) const;
 	void               RemoveFromTypeIdMap(asCObjectType *type);
 
@@ -345,6 +345,7 @@ public:
 	asCArray<asCModule *>  scriptModules;
 	asCModule             *lastModule;
 	bool                   isBuilding;
+	bool                   deferValidationOfTemplateTypes;
 
 	// Tokenizer is instanciated once to share resources
 	asCTokenizer tok;

+ 2 - 2
ThirdParty/AngelScript/source/as_string_util.cpp

@@ -86,7 +86,7 @@ double asStringScanDouble(const char *string, size_t *numScanned)
     // locale is ",".
 #if !defined(_WIN32_WCE) && !defined(ANDROID)
 	// Set the locale to C so that we are guaranteed to parse the float value correctly
-	asCString orig = setlocale(LC_NUMERIC, 0);
+	char *orig = setlocale(LC_NUMERIC, 0);
 	setlocale(LC_NUMERIC, "C");
 #endif
 
@@ -94,7 +94,7 @@ double asStringScanDouble(const char *string, size_t *numScanned)
 
 #if !defined(_WIN32_WCE) && !defined(ANDROID)
 	// Restore the locale
-	setlocale(LC_NUMERIC, orig.AddressOf());
+	setlocale(LC_NUMERIC, orig);
 #endif
 
 	if( numScanned )

+ 8 - 3
ThirdParty/AngelScript/source/as_texts.h

@@ -215,7 +215,7 @@
 
 // Engine message
 
-#define TXT_INVALID_CONFIGURATION                  "Invalid configuration"
+#define TXT_INVALID_CONFIGURATION                  "Invalid configuration. Verify the registered application interface."
 #define TXT_VALUE_TYPE_MUST_HAVE_SIZE              "A value type must be registered with a non-zero size"
 #define TXT_TYPE_s_IS_MISSING_BEHAVIOURS           "Type '%s' is missing behaviours"
 #define TXT_ILLEGAL_BEHAVIOUR_FOR_TYPE             "The behaviour is not compatible with the type"
@@ -225,14 +225,19 @@
 #define TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR "A non-pod value type must have the default constructor and destructor behaviours"
 #define TXT_CANNOT_PASS_TYPE_s_BY_VAL              "Can't pass type '%s' by value unless the application type is informed in the registration"
 #define TXT_CANNOT_RET_TYPE_s_BY_VAL               "Can't return type '%s' by value unless the application type is informed in the registration"
-#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL             "Don't support passing type '%s' by value to application. Use generic calling convention instead"
-#define TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL         "Don't support returning type '%s' by value from application. Use generic calling convention instead"
+// TODO: Should be something like "This platform requires that AngelScript knows the exact content of the type '%s' in order to pass by value to application in native calling convention"
+#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL             "Don't support passing type '%s' by value to application in native calling convention on this platform"
+// TODO: Should be something like "This platform requires that AngelScript knows the exact content of the type '%s' in order to return by value from application in native calling convention"
+#define TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL         "Don't support returning type '%s' by value from application in native calling convention on this platform"
 #define TXT_GC_CANNOT_FREE_OBJ_OF_TYPE_s           "GC cannot free an object of type '%s'. Make sure all types that can form circular references have the GC behaviours"
 #define TXT_OBJECT_TYPE_s_DOESNT_EXIST             "Object type '%s' doesn't exist"
 #define TXT_TEMPLATE_TYPE_s_DOESNT_EXIST           "Template type '%s' doesn't exist"
 #define TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST        "Template subtype '%s' doesn't exist"
 #define TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s      "Failed to read subtype of template type '%s'"
 #define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s         "Attempting to instanciate invalid template type '%s<%s>'"
+#define TXT_FAILED_IN_FUNC_s                       "Failed in call to function '%s'"
+#define TXT_FAILED_IN_FUNC_s_WITH_s                "Failed in call to function '%s' with '%s'"
+#define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s          "Failed in call to function '%s' with '%s' and '%s'"
 
 // Internal names
 

Some files were not shown because too many files changed in this diff