Browse Source

Update Angelscript to 2.30.2, resolves #892 in Urho3D master

JSandusky 10 years ago
parent
commit
928c08d22e
35 changed files with 2141 additions and 921 deletions
  1. 7 7
      Source/ThirdParty/AngelScript/include/angelscript.h
  2. 127 32
      Source/ThirdParty/AngelScript/source/as_builder.cpp
  3. 2 1
      Source/ThirdParty/AngelScript/source/as_builder.h
  4. 45 4
      Source/ThirdParty/AngelScript/source/as_bytecode.cpp
  5. 3 1
      Source/ThirdParty/AngelScript/source/as_bytecode.h
  6. 15 4
      Source/ThirdParty/AngelScript/source/as_callfunc.cpp
  7. 42 12
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  8. 45 40
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_vita.S
  9. 6 1
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_xcode.S
  10. 319 26
      Source/ThirdParty/AngelScript/source/as_callfunc_mips.cpp
  11. 12 4
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  12. 9 9
      Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  13. 20 20
      Source/ThirdParty/AngelScript/source/as_callfunc_xenon.cpp
  14. 429 200
      Source/ThirdParty/AngelScript/source/as_compiler.cpp
  15. 87 36
      Source/ThirdParty/AngelScript/source/as_compiler.h
  16. 47 35
      Source/ThirdParty/AngelScript/source/as_config.h
  17. 20 4
      Source/ThirdParty/AngelScript/source/as_context.cpp
  18. 12 18
      Source/ThirdParty/AngelScript/source/as_debug.h
  19. 3 8
      Source/ThirdParty/AngelScript/source/as_gc.cpp
  20. 29 40
      Source/ThirdParty/AngelScript/source/as_module.cpp
  21. 15 7
      Source/ThirdParty/AngelScript/source/as_objecttype.cpp
  22. 2 1
      Source/ThirdParty/AngelScript/source/as_objecttype.h
  23. 185 98
      Source/ThirdParty/AngelScript/source/as_parser.cpp
  24. 4 2
      Source/ThirdParty/AngelScript/source/as_parser.h
  25. 419 162
      Source/ThirdParty/AngelScript/source/as_restore.cpp
  26. 159 86
      Source/ThirdParty/AngelScript/source/as_scriptengine.cpp
  27. 5 4
      Source/ThirdParty/AngelScript/source/as_scriptengine.h
  28. 16 13
      Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp
  29. 8 8
      Source/ThirdParty/AngelScript/source/as_scriptfunction.h
  30. 20 20
      Source/ThirdParty/AngelScript/source/as_scriptobject.cpp
  31. 1 4
      Source/ThirdParty/AngelScript/source/as_scriptobject.h
  32. 1 0
      Source/ThirdParty/AngelScript/source/as_texts.h
  33. 2 1
      Source/ThirdParty/AngelScript/source/as_tokendef.h
  34. 20 8
      Source/ThirdParty/AngelScript/source/as_typeinfo.cpp
  35. 5 5
      Source/ThirdParty/AngelScript/source/as_typeinfo.h

+ 7 - 7
Source/ThirdParty/AngelScript/include/angelscript.h

@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 // AngelScript version
 
-#define ANGELSCRIPT_VERSION        23001
-#define ANGELSCRIPT_VERSION_STRING "2.30.1 WIP"
+#define ANGELSCRIPT_VERSION        23002
+#define ANGELSCRIPT_VERSION_STRING "2.30.2"
 
 // Data types
 
@@ -547,7 +547,7 @@ struct asSMessageInfo
 extern "C"
 {
 	// Engine
-	AS_API asIScriptEngine *asCreateScriptEngine(asDWORD version);
+	AS_API asIScriptEngine *asCreateScriptEngine(asDWORD version = ANGELSCRIPT_VERSION);
 	AS_API const char      *asGetLibraryVersion();
 	AS_API const char      *asGetLibraryOptions();
 
@@ -588,21 +588,21 @@ BEGIN_AS_NAMESPACE
 template<typename T>
 asUINT asGetTypeTraits()
 {
-#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS)
-	// MSVC & XCode/Clang
+#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5)
+	// MSVC, XCode/Clang, and gnuc 5+
 	// C++11 compliant code
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
 	bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::is_trivially_copy_assignable<T>::value;
 	bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::is_trivially_copy_constructible<T>::value;
 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
-	// gnuc 4.8+
-	// gnuc is using a mix of C++11 standard and pre-standard templates
+	// gnuc 4.8 is using a mix of C++11 standard and pre-standard templates
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
 	bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::has_trivial_copy_assign<T>::value;
 	bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::has_trivial_copy_constructor<T>::value;
 #else
+	// All other compilers and versions are assumed to use non C++11 compliant code until proven otherwise
 	// Not fully C++11 compliant. The has_trivial checks were used while the standard was still
 	// being elaborated, but were then removed in favor of the above is_trivially checks
 	// http://stackoverflow.com/questions/12702103/writing-code-that-works-when-has-trivial-destructor-is-defined-instead-of-is

+ 127 - 32
Source/ThirdParty/AngelScript/source/as_builder.cpp

@@ -364,9 +364,35 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
 
 	CompileGlobalVariables();
 
+	// It is possible that the global variable initialization included anonymous functions that must be compiled too
+	for( asUINT n = 0; n < functions.GetLength(); n++ )
+	{
+		asCCompiler compiler(engine);
+		asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
+		int r = compiler.CompileFunction(this, functions[n]->script, func->parameterNames, functions[n]->node, func, 0);
+		if( r < 0 )
+			break;
+	}
+
 	if( numWarnings > 0 && engine->ep.compilerWarnings == 2 )
 		WriteError(TXT_WARNINGS_TREATED_AS_ERROR, 0, 0);
 
+	// None of the functions should be added to the module if any error occurred, 
+	// or it was requested that the functions wouldn't be added to the scope
+	if( numErrors > 0 )
+	{
+		for( asUINT n = 0; n < functions.GetLength(); n++ )
+		{
+			asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
+			if( module->globalFunctions.GetIndex(func) >= 0 )
+			{
+				module->globalFunctions.Erase(module->globalFunctions.GetIndex(func));
+				module->scriptFunctions.RemoveValue(func);
+				func->ReleaseInternal();
+			}
+		}
+	}
+
 	if( numErrors > 0 )
 	{
 		// Remove the variable from the module, if it was registered
@@ -550,22 +576,38 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	funcDesc->paramNames        = func->parameterNames;
 	funcDesc->isExistingShared  = false;
 
-	asCCompiler compiler(engine);
-	compiler.CompileFunction(this, functions[0]->script, func->parameterNames, functions[0]->node, func, 0);
+	// This must be done in a loop, as it is possible that additional functions get declared as lambda's in the code
+	for( asUINT n = 0; n < functions.GetLength(); n++ )
+	{
+		asCCompiler compiler(engine);
+		asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
+		int r = compiler.CompileFunction(this, functions[n]->script, func->parameterNames, functions[n]->node, func, 0);
+		if( r < 0 )
+			break;
+	}
 
 	if( numWarnings > 0 && engine->ep.compilerWarnings == 2 )
 		WriteError(TXT_WARNINGS_TREATED_AS_ERROR, 0, 0);
 
-	if( numErrors > 0 )
+	// None of the functions should be added to the module if any error occurred, 
+	// or it was requested that the functions wouldn't be added to the scope
+	if( !(compileFlags & asCOMP_ADD_TO_MODULE) || numErrors > 0 )
 	{
-		// If the function was added to the module then remove it again
-		if( compileFlags & asCOMP_ADD_TO_MODULE )
+		for( asUINT n = 0; n < functions.GetLength(); n++ )
 		{
-			module->globalFunctions.Erase(module->globalFunctions.GetIndex(func));
-			module->scriptFunctions.RemoveValue(func);
-			func->ReleaseInternal();
+			asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
+			if( module->globalFunctions.GetIndex(func) >= 0 )
+			{
+				module->globalFunctions.Erase(module->globalFunctions.GetIndex(func));
+				module->scriptFunctions.RemoveValue(func);
+				func->ReleaseInternal();
+			}
 		}
+	}
 
+	if( numErrors > 0 )
+	{
+		// Release the function pointer that would otherwise be returned if no errors occured
 		func->ReleaseInternal();
 
 		return asERROR;
@@ -1464,9 +1506,9 @@ sMixinClass *asCBuilder::GetMixinClass(const char *name, asSNameSpace *ns)
 
 int asCBuilder::RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns)
 {
-	// TODO: 2.30.0: redesign: Allow funcdefs to be explicitly declared as 'shared'. In this case
-	//                         an error should be given if any of the arguments/return type is not
-	//                         shared.
+	// TODO: redesign: Allow funcdefs to be explicitly declared as 'shared'. In this case
+	//                 an error should be given if any of the arguments/return type is not
+	//                 shared.
 
 	// Find the name
 	asASSERT( node->firstChild->nodeType == snDataType );
@@ -1522,6 +1564,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 	asCScriptFunction *func = module->funcDefs[funcDef->idx];
 	asASSERT( func );
 
+	// TODO: It should be possible to declare funcdef as shared. In this case a compiler error will be given if any of the types it uses are not shared
 	GetParsedFunctionDetails(funcDef->node, funcDef->script, 0, funcDef->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, defaultArgs, isConstMethod, isConstructor, isDestructor, isPrivate, isProtected, isOverride, isFinal, isShared, func->nameSpace);
 
 	// There should not be any defaultArgs, but if there are any we need to delete them to avoid leaks
@@ -1529,27 +1572,47 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 		if( defaultArgs[n] )
 			asDELETE(defaultArgs[n], asCString);
 
-	// TODO: Should we force the use of 'shared' for this check to be done?
-	// Check if there is another identical funcdef from another module and if so reuse that instead
-	for( asUINT n = 0; n < engine->funcDefs.GetLength(); n++ )
+	// All funcdefs are shared, unless one of the parameter types or return type is not shared
+	isShared = true;
+	if( func->returnType.GetObjectType() && !func->returnType.GetObjectType()->IsShared() )
+		isShared = false;
+	if( func->returnType.GetFuncDef() && !func->returnType.GetFuncDef()->IsShared() )
+		isShared = false;
+	for( asUINT n = 0; isShared && n < func->parameterTypes.GetLength(); n++ )
 	{
-		asCScriptFunction *f2 = engine->funcDefs[n];
-		if( f2 == 0 || func == f2 )
-			continue;
+		if( func->parameterTypes[n].GetObjectType() && !func->parameterTypes[n].GetObjectType()->IsShared() )
+			isShared = false;
+		if( func->parameterTypes[n].GetFuncDef() && !func->parameterTypes[n].GetFuncDef()->IsShared() )
+			isShared = false;
+	}
+	func->isShared = isShared;
 
-		if( f2->name == func->name &&
-			f2->nameSpace == func->nameSpace &&
-			f2->IsSignatureExceptNameEqual(func) )
+	// Check if there is another identical funcdef from another module and if so reuse that instead
+	if( func->isShared )
+	{
+		for( asUINT n = 0; n < engine->funcDefs.GetLength(); n++ )
 		{
-			// Replace our funcdef for the existing one
-			funcDef->idx = f2->id;
-			module->funcDefs[module->funcDefs.IndexOf(func)] = f2;
-			f2->AddRefInternal();
+			asCScriptFunction *f2 = engine->funcDefs[n];
+			if( f2 == 0 || func == f2 )
+				continue;
 
-			engine->funcDefs.RemoveValue(func);
+			if( !f2->isShared )
+				continue;
 
-			func->ReleaseInternal();
-			break;
+			if( f2->name == func->name &&
+				f2->nameSpace == func->nameSpace &&
+				f2->IsSignatureExceptNameEqual(func) )
+			{
+				// Replace our funcdef for the existing one
+				funcDef->idx = f2->id;
+				module->funcDefs[module->funcDefs.IndexOf(func)] = f2;
+				f2->AddRefInternal();
+
+				engine->funcDefs.RemoveValue(func);
+
+				func->ReleaseInternal();
+				break;
+			}
 		}
 	}
 }
@@ -2469,7 +2532,7 @@ void asCBuilder::CompileInterfaces()
 		sClassDeclaration *intfDecl = interfaceDeclarations[n];
 		asCObjectType *intfType = intfDecl->objType;
 
-		// TODO: 2.28.1: Is this really at the correct place? Hasn't the vfTableIdx already been set here?
+		// TODO: Is this really at the correct place? Hasn't the vfTableIdx already been set here?
 		// Co-opt the vfTableIdx value in our own methods to indicate the
 		// index the function should have in the table chunk for this interface.
 		for( asUINT d = 0; d < intfType->methods.GetLength(); d++ )
@@ -4132,6 +4195,34 @@ int asCBuilder::RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCod
 	return RegisterScriptFunction(node, file, objType, isInterface, isGlobalFunction, ns, isExistingShared, isMixin, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, isConstMethod, isConstructor, isDestructor, isPrivate, isProtected, isOverride, isFinal, isShared);
 }
 
+asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns)
+{
+	// Get the parameter names from the node
+	asCArray<asCString> parameterNames;
+	asCArray<asCString*> defaultArgs;
+	asCScriptNode *args = node->firstChild;
+	while( args && args->nodeType == snIdentifier )
+	{
+		asCString argName;
+		argName.Assign(&file->code[args->tokenPos], args->tokenLength);
+		parameterNames.PushLast(argName);
+		defaultArgs.PushLast(0);
+		args = args->next;
+	}
+
+	// The statement block for the function must be disconnected, as the builder is going to be the owner of it
+	args->DisconnectParent();
+
+	// Get the return and parameter types from the funcDef
+	asCString funcName = name;
+	int r = RegisterScriptFunction(args, file, 0, 0, true, ns, false, false, funcName, funcDef->returnType, parameterNames, funcDef->parameterTypes, funcDef->inOutFlags, defaultArgs, false, false, false, false, false, false, false, false);
+	if( r < 0 )
+		return 0;
+
+	// Return the function that was just created (but that will be compiled later)
+	return engine->scriptFunctions[functions[functions.GetLength()-1]->funcId];
+}
+
 int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isProtected, bool isOverride, bool isFinal, bool isShared)
 {
 	// Determine default namespace if not specified
@@ -4742,11 +4833,15 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
 		// If searching with a scope informed, then the node and script must also be informed for potential error reporting
 		asASSERT( errNode && script );
 
-		// If the scope contains ::identifier, then use the last identifier as the class name and the rest of is as the namespace
+		// If the scope contains ::identifier, then use the last identifier as the class name and the rest of it as the namespace
 		int n = scope.FindLast("::");
 		asCString className = n >= 0 ? scope.SubString(n+2) : scope;
 		asCString nsName = n >= 0 ? scope.SubString(0, n) : "";
-		asSNameSpace *ns = GetNameSpaceByString(nsName, objectType->nameSpace, errNode, script);
+
+		// Check if the namespace actually exist, if not return silently as this cannot be the referring to a base class
+		asSNameSpace *ns = GetNameSpaceByString(nsName, objectType->nameSpace, errNode, script, false);
+		if( ns == 0 )
+			return;
 
 		// Find the base class with the specified scope
 		while( objectType && (objectType->name != className || objectType->nameSpace != ns) )
@@ -4902,7 +4997,7 @@ asSNameSpace *asCBuilder::GetNameSpaceFromNode(asCScriptNode *node, asCScriptCod
 	return GetNameSpaceByString(scope, implicitNs, node, script);
 }
 
-asSNameSpace *asCBuilder::GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script)
+asSNameSpace *asCBuilder::GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script, bool isRequired)
 {
 	asSNameSpace *ns = implicitNs;
 	if( nsName == "::" )
@@ -4910,7 +5005,7 @@ asSNameSpace *asCBuilder::GetNameSpaceByString(const asCString &nsName, asSNameS
 	else if( nsName != "" )
 	{
 		ns = engine->FindNameSpace(nsName.AddressOf());
-		if( ns == 0 )
+		if( ns == 0 && isRequired )
 		{
 			asCString msg;
 			msg.Format(TXT_NAMESPACE_s_DOESNT_EXIST, nsName.AddressOf());

+ 2 - 1
Source/ThirdParty/AngelScript/source/as_builder.h

@@ -174,7 +174,7 @@ protected:
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
 
 	asSNameSpace      *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next);
-	asSNameSpace      *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script);
+	asSNameSpace      *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script, bool isRequired = true);
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 
 	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns);
@@ -213,6 +213,7 @@ protected:
 	int                RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
+	asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns);
 	void               CompleteFuncDef(sFuncDef *funcDef);
 	void               CompileInterfaces();
 	void               CompileClasses(asUINT originalNumTempl);

+ 45 - 4
Source/ThirdParty/AngelScript/source/as_bytecode.cpp

@@ -1015,6 +1015,21 @@ void asCByteCode::OptimizeLocally(const asCArray<int> &tempVariableOffsets)
 				ChangeFirstDeleteNext(curr, asBC_PSF);
 				instr = GoForward(curr);
 			}
+			// VAR a, GETOBJREF 0 -> PshVPtr a
+			else if( curr->next && curr->next->op == asBC_GETOBJREF && curr->next->wArg[0] == 0 )
+			{
+				ChangeFirstDeleteNext(curr, asBC_PshVPtr);
+				instr = GoForward(curr);
+			}
+			// VAR, PSF, GETREF {PTR_SIZE} -> PSF, PSF
+			if( curr->next && curr->next->op == asBC_PSF &&
+				curr->next->next && curr->next->next->op == asBC_GETREF &&
+				curr->next->next->wArg[0] == AS_PTR_SIZE )
+			{
+				curr->op = asBC_PSF;
+				DeleteInstruction(curr->next->next);
+				instr = GoForward(curr);
+			}
 		}
 	}
 
@@ -2220,6 +2235,13 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 				}
 				break;
 
+			case asBC_FuncPtr:
+				{
+					asCScriptFunction *func = *(asCScriptFunction**)ARG_DW(instr->arg);
+					fprintf(file, "   %-8s 0x%x          (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), func->GetDeclaration());
+				}
+				break;
+
 			case asBC_PshC4:
 			case asBC_Cast:
 				fprintf(file, "   %-8s 0x%x          (i:%d, f:%g)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), *((int*) ARG_DW(instr->arg)), *((float*) ARG_DW(instr->arg)));
@@ -2269,10 +2291,17 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			{
 			case asBC_OBJTYPE:
 				{
-					asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
+					asCObjectType *ot = *(asCObjectType**)ARG_QW(instr->arg);
 					fprintf(file, "   %-8s 0x%x          (type:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), ot->GetName());
 				}
 				break;
+
+			case asBC_FuncPtr:
+				{
+					asCScriptFunction *func = *(asCScriptFunction**)ARG_QW(instr->arg);
+					fprintf(file, "   %-8s 0x%x          (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), func->GetDeclaration());
+				}
+				break;
 	
 			default:
 #ifdef __GNUC__
@@ -2289,15 +2318,27 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 
 		case asBCTYPE_wW_QW_ARG:
 		case asBCTYPE_rW_QW_ARG:
+			switch( instr->op )
+			{
+			case asBC_RefCpyV:
+			case asBC_FREE:
+				{
+					asCObjectType *ot = *(asCObjectType**)ARG_QW(instr->arg);
+					fprintf(file, "   %-8s v%d, 0x%x          (type:%s)\n", asBCInfo[instr->op].name, instr->wArg[0], (asUINT)*ARG_QW(instr->arg), ot->GetName());
+				}
+				break;
+
+			default:
 #ifdef __GNUC__
 #ifdef _LP64
-			fprintf(file, "   %-8s v%d, 0x%lx           (i:%ld, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
+				fprintf(file, "   %-8s v%d, 0x%lx           (i:%ld, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
 #else
-			fprintf(file, "   %-8s v%d, 0x%llx           (i:%lld, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
+				fprintf(file, "   %-8s v%d, 0x%llx           (i:%lld, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
 #endif
 #else
-			fprintf(file, "   %-8s v%d, 0x%I64x          (i:%I64d, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
+				fprintf(file, "   %-8s v%d, 0x%I64x          (i:%I64d, f:%g)\n", asBCInfo[instr->op].name, instr->wArg[0], *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
 #endif
+			}
 			break;
 
 		case asBCTYPE_DW_DW_ARG:

+ 3 - 1
Source/ThirdParty/AngelScript/source/as_bytecode.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -130,6 +130,8 @@ public:
 	int InstrW_W(asEBCInstr bc, int w, int b);
 	int InstrSHORT_DW_DW(asEBCInstr bc, short a, asDWORD b, asDWORD c);
 
+	asCScriptEngine *GetEngine() const { return engine; };
+
 	asCArray<int> lineNumbers;
 	asCArray<int> sectionIdxs;
 	int largestStackUsed;

+ 15 - 4
Source/ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -130,10 +130,11 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
 			internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
-#if defined(AS_ARM) && (defined(__GNUC__) || defined(AS_PSVITA))
+#if (defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
 			// As the least significant bit in func is used to switch to THUMB mode
 			// on ARM processors, the LSB in the __delta variable is used instead of
 			// the one in __pfn on ARM processors.
+			// MIPS also appear to use the base offset to indicate virtual method.
 			if( (size_t(internal->baseOffset) & 1) )
 				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
@@ -577,10 +578,11 @@ int CallSystemFunction(int id, asCContext *context)
 			}
 
 			// Add the base offset for multiple inheritance
-#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
+#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
 			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
 			// and the whole offset is thus shifted one bit left to keep the original
 			// offset resolution
+			// MIPS also work like ARM in this regard
 			obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
 #else
 			obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
@@ -634,10 +636,11 @@ int CallSystemFunction(int id, asCContext *context)
 			}
 
 			// Add the base offset for multiple inheritance
-#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
+#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
 			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
 			// and the whole offset is thus shifted one bit left to keep the original
 			// offset resolution
+			// MIPS also work like ARM in this regard
 			tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
 #else
 			tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
@@ -822,7 +825,15 @@ int CallSystemFunction(int id, asCContext *context)
 	if( cleanCount )
 	{
 		args = context->m_regs.stackPointer;
-		if( callConv >= ICC_THISCALL )
+
+		// Skip the hidden argument for the return pointer
+		// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
+		if( descr->DoesReturnOnStack() )
+			args += AS_PTR_SIZE;
+
+		// Skip the object pointer on the stack
+		// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
+		if( callConv >= ICC_THISCALL && sysFunc->objForThiscall == 0 )
 			args += AS_PTR_SIZE;
 
 		asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();

+ 42 - 12
Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S

@@ -1,6 +1,6 @@
 /*
   AngelCode Scripting Library
-  Copyright (c) 2003-2014 Andreas Jonsson
+  Copyright (c) 2003-2015 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
@@ -39,11 +39,13 @@
    The assembler routines for Linux were written by Carlos Luna in December 2012
 */
 
+#if !defined(AS_MAX_PORTABILITY)
+
 #if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
 
 #if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__)
 
-/* iOS, Android, and Marmalade goes here */
+/* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
 
 .global armFunc
 .global armFuncR0
@@ -85,7 +87,12 @@ stackargsloop:
     bne     stackargsloop
     mov     sp, r12
 nomoreargs:
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
+    mov    pc, r4
+#else
     blx     r4
+#endif
     add     sp, sp, r8
     ldmia   sp!, {r4-r8, pc}
 
@@ -133,7 +140,12 @@ stackargslooparmFuncObjLast:
     bne     stackargslooparmFuncObjLast
     mov     sp, r12
 nomoreargsarmFuncObjLast:
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
+    mov    pc, r4
+#else
     blx     r4
+#endif
     add     sp, sp, r8
     ldmia   sp!, {r4-r8, pc}
 
@@ -180,7 +192,12 @@ stackargslooparmFuncR0ObjLast:
     bne     stackargslooparmFuncR0ObjLast
     mov     sp, r12
 nomoreargsarmFuncR0ObjLast:
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
+    mov    pc, r4
+#else
     blx     r4
+#endif
     add     sp, sp, r8
     ldmia   sp!, {r4-r8, pc}
 
@@ -218,7 +235,12 @@ stackargslooparmFuncR0:
     bne     stackargslooparmFuncR0
     mov     sp, r12
 nomoreargsarmFuncR0:
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
+    mov    pc, r4
+#else
     blx     r4
+#endif
     add     sp, sp, r8
     ldmia   sp!, {r4-r8, pc}
 
@@ -255,14 +277,19 @@ stackargslooparmFuncR0R1:
     bne     stackargslooparmFuncR0R1
     mov     sp, r12
 nomoreargsarmFuncR0R1:
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
+    mov    pc, r4
+#else
     blx     r4
+#endif
     add     sp, sp, r8
     ldmia   sp!, {r4-r8, pc}
 
 /* --------------------------------------------------------------------------------------------*/
 #elif defined(__linux__) && !defined(__SOFTFP__)
 
-/* The Linux code goes here */
+/* The Linux with hard-float ABI code goes here */
 
 
 /* These codes are suitable for armeabi + vfp  / armeabihf */
@@ -340,7 +367,7 @@ stackargsloop:
     mov     sp, r12
 
 nomoreargs:
-#if defined (___ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
     mov    lr, pc   /* older ARM didn't support blx */
     mov    pc, r4
 #else
@@ -427,8 +454,8 @@ stackargslooparmFuncObjLast:
     mov     sp, r12
 
 nomoreargsarmFuncObjLast:
-#if defined (___ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
-    mov    lr, pc
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
     mov    pc, r4
 #else
     blx     r4
@@ -521,8 +548,8 @@ stackargslooparmFuncR0ObjLast:
     mov     sp, r12
 
 nomoreargsarmFuncR0ObjLast:
-#if defined (___ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
-    mov    lr, pc
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
     mov    pc, r4
 #else
     blx     r4
@@ -597,8 +624,8 @@ stackargslooparmFuncR0:
     mov     sp, r12
 
 nomoreargsarmFuncR0:
-#if defined (___ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
-    mov    lr, pc
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
     mov    pc, r4
 #else
     blx     r4
@@ -677,8 +704,8 @@ stackargslooparmFuncR0R1:
     mov     sp, r12
 
 nomoreargsarmFuncR0R1:
-#if defined (___ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
-    mov    lr, pc
+#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
+    mov    lr, pc   /* older ARM didn't support blx */
     mov    pc, r4
 #else
     blx     r4
@@ -697,3 +724,6 @@ nomoreargsarmFuncR0R1:
 
 #endif /* arm */
 
+#endif /* !AS_MAX_PORTABILITY */
+
+

+ 45 - 40
Source/ThirdParty/AngelScript/source/as_callfunc_arm_vita.S

@@ -1,6 +1,6 @@
 /*
   AngelCode Scripting Library
-  Copyright (c) 2003-2013 Andreas Jonsson
+  Copyright (c) 2003-2015 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
@@ -34,6 +34,8 @@
    This code was adapted from as_callfunc_arm_gcc (ARM, Linux hard float) by Brandon Bare on October 2014.
 */
 
+#if !defined(AS_MAX_PORTABILITY)
+
 #ifdef __psp2__
 
 .syntax unified
@@ -61,7 +63,7 @@
 
 /* --------------------------------------------------------------------------------------------*/
 armFunc:
-	.fnstart
+    .fnstart
 
     push    {r4-r8, r10, r11, lr}   /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
 
@@ -81,19 +83,19 @@ armFunc:
     /* Load the first 4 arguments into r0-r3 */
     cmp     r7, #4
 
-	it ge
+    it ge
     ldrge   r0, [r6]
     cmp     r7, #8
 
-	it ge
+    it ge
     ldrge   r1, [r6, #4]
     cmp     r7, #12
 
-	it ge
+    it ge
     ldrge   r2, [r6, #8]
     cmp     r7, #16
 
-	it ge
+    it ge
     ldrge   r3, [r6, #12]
 
 stackargs:
@@ -128,11 +130,11 @@ nomoreargs:
 
     pop {r4-r8, r10, r11, pc}
 
-	.fnend
+    .fnend
 
 /* --------------------------------------------------------------------------------------------*/
 armFuncObjLast:
-	.fnstart
+    .fnstart
 
     push {r4-r8, r10, r11, lr}  /* We´re storing r11 just to keep the stack aligned to an 8 byte boundary */
 
@@ -157,28 +159,28 @@ armFuncObjLast:
     /* Load the first 4 arguments into r0-r3 */
     cmp     r7, #4
 
-	it ge
+    it ge
     ldrge   r0, [r6]
     cmp     r7, #8
 
-	it ge
+    it ge
     ldrge   r1, [r6,#4]
 
-	it lt
+    it lt
     movlt   r1, r5
     cmp     r7, #12
 
-	it ge
+    it ge
     ldrge   r2, [r6,#8]
 
-	it lt
+    it lt
     movlt   r2, r5
     cmp     r7, #16
 
-	it ge
+    it ge
     ldrge   r3, [r6,#12]
 
-	ittt lt
+    ittt lt
     movlt   r3, r5
     movlt   r5, #0                  /* If objlast got placed into a register, r5 = 0 */
     blt     stackargsFuncObjLast    /* If objlast got placed into a register, go to stackargsFuncObjLast */
@@ -220,11 +222,11 @@ nomoreargsarmFuncObjLast:
 
     pop   {r4-r8, r10,r11, pc}
 
-	.fnend
+    .fnend
 
 /* --------------------------------------------------------------------------------------------*/
 armFuncR0ObjLast:
-	.fnstart
+    .fnstart
 
     push    {r4-r8, r10, r11, lr}
 
@@ -252,35 +254,35 @@ armFuncR0ObjLast:
     /* Load the first 3 arguments into r1-r3 */
     cmp     r7, #4
 
-	it ge
+    it ge
     ldrge   r1, [r6]
     cmp     r7, #8
 
-	it ge
+    it ge
     ldrge   r2, [r6,#4]
 
-	it lt
+    it lt
     movlt   r2, r5
     cmp     r7, #12
 
-	it ge
+    it ge
     ldrge   r3, [r6,#8]
 
-	ittt lt
+    ittt lt
     movlt   r3, r5
     movlt   r5, #0                  /* If objlast got placed into a register, r5 = 0 */
     blt     stackargsFuncR0ObjLast  /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
 
     cmp     r7, #16                 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
 
-	itt ge
+    itt ge
     ldrge   r7, [r6, #12]
     strge   r7, [r6, #8]
 
     str     r5, [r6, #12]           /* Put objlast in r6 + 12 */
-	mov     r5, #0
+    mov     r5, #0
 
-	it ge
+    it ge
     movge   r5, #4                  /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
     add     r5, r5, #4              /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
 
@@ -318,11 +320,11 @@ nomoreargsarmFuncR0ObjLast:
 
     pop {r4-r8, r10, r11, pc}
 
-	.fnend
+    .fnend
 
 /* --------------------------------------------------------------------------------------------*/
 armFuncR0:
-	.fnstart
+    .fnstart
 
     push {r4-r8, r10, r11, lr}
 
@@ -344,19 +346,19 @@ armFuncR0:
     /* Load the first 3 arguments into r1-r3 */
     cmp     r7, #4
 
-	it ge
+    it ge
     ldrge   r1, [r6]
     cmp     r7, #8
 
-	it ge
+    it ge
     ldrge   r2, [r6, #4]
     cmp     r7, #12
 
-	it ge
+    it ge
     ldrge   r3, [r6, #8]
     cmp     r7, #16
 
-	it ge
+    it ge
     movge   r11, #4         /* If there is still one arg to be placed, set the offset in r11 to #4 */
 
 stackargsarmFuncR0:
@@ -393,11 +395,11 @@ nomoreargsarmFuncR0:
 
     pop {r4-r8, r10, r11, pc}
 
-	.fnend
+    .fnend
 
 /* --------------------------------------------------------------------------------------------*/
 armFuncR0R1:
-	.fnstart
+    .fnstart
 
     push {r4-r8, r10, r11, lr}
 
@@ -421,23 +423,23 @@ armFuncR0R1:
     /* Load the first 2 arguments into r2-r3 */
     cmp     r7, #4
 
-	it ge
+    it ge
     ldrge   r2, [r6]
     cmp     r7, #8
 
-	it ge
+    it ge
     ldrge   r3, [r6, #4]
     cmp     r7, #12
 
-	it ge
+    it ge
     movge   r11, #4         /* If there is a third arg to be placed, set the offset in r11 to #4 */
 
     cmp     r7, #16
 
-	it ge
+    it ge
     movge   r11, #8         /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
 
-	itt lt
+    itt lt
     ldrlt   r7, [r6, #8]    /* Else copy the third arg to the correct place in the array */
     strlt   r7, [r6, #12]
 
@@ -475,6 +477,9 @@ nomoreargsarmFuncR0R1:
 
     pop {r4-r8, r10, r11, pc}
 
-	.fnend
+    .fnend
+
+#endif
+
+#endif /* !AS_MAX_PORTABILITY */
 
-#endif

+ 6 - 1
Source/ThirdParty/AngelScript/source/as_callfunc_arm_xcode.S

@@ -1,6 +1,6 @@
 /*
   AngelCode Scripting Library
-  Copyright (c) 2003-2009 Andreas Jonsson
+  Copyright (c) 2003-2015 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
@@ -35,6 +35,8 @@
 // Adapted to GNUC by darktemplar216 in September 2009
 // Small fixed to work under XCode GCC by Gilad Novik in October 2009
 
+#if !defined(AS_MAX_PORTABILITY)
+
 #if defined(__arm__) || defined(__ARM__)
 
 .align 2
@@ -235,3 +237,6 @@ nomoreargsarmFuncR0R1:
     ldmia   sp!, {r4-r8, pc}
 
 #endif
+
+#endif /* !AS_MAX_PORTABILITY */
+

+ 319 - 26
Source/ThirdParty/AngelScript/source/as_callfunc_mips.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -35,7 +35,9 @@
 // These functions handle the actual calling of system functions
 //
 // This version is MIPS specific and was originally written
-// by Manu Evans in April, 2006
+// by Manu Evans in April, 2006 for Playstation Portable (PSP)
+//
+// Support for Linux with MIPS was added by Andreas Jonsson in April, 2015
 //
 
 
@@ -52,10 +54,320 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#if !defined(AS_ANDROID)
 #include <regdef.h>
+#endif
 
 BEGIN_AS_NAMESPACE
 
+#if defined(__linux__) && defined(_ABIO32)
+
+// The MIPS ABI used by Linux is implemented here
+// (Tested on CI20 MIPS Creator with Debian Linux)
+//
+// ref: SYSTEM V 
+//      APPLICATION BINARY INTERFACE
+//      MIPS RISC Processor
+//      http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf
+//
+// ref: MIPS Instruction Reference
+//      http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
+
+union SFloatRegs
+{
+	union { double d0; struct { float f0; asDWORD dummy0; };};
+	union { double d1; struct { float f1; asDWORD dummy1; };};
+} ;
+
+extern "C" asQWORD mipsFunc(asUINT argSize, asDWORD *argBuffer, void *func, SFloatRegs &floatRegs);
+asDWORD GetReturnedFloat();
+asQWORD GetReturnedDouble();
+
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
+{
+	asCScriptEngine *engine = context->m_engine;
+	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
+	int callConv = sysFunc->callConv;
+
+	asQWORD retQW = 0;
+
+	void *func = (void*)sysFunc->func;
+	void **vftable;
+
+	asDWORD argBuffer[128]; // Ought to be big enough
+	asASSERT( sysFunc->paramSize < 128 );
+	
+	asDWORD argOffset = 0;
+	
+	SFloatRegs floatRegs;
+	asDWORD floatOffset = 0;
+	
+	// If the application function returns the value in memory then
+	// the first argument must be the pointer to that memory
+	if( sysFunc->hostReturnInMemory )
+	{
+		asASSERT( retPointer );
+		argBuffer[argOffset++] = (asPWORD)retPointer;
+	}
+	
+	if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM ||
+		callConv == ICC_THISCALL || callConv == ICC_THISCALL_RETURNINMEM ||
+		callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
+		callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
+		callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM || 
+		callConv == ICC_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
+		callConv == ICC_THISCALL_OBJLAST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
+	{
+		// Add the object pointer as the first argument
+		argBuffer[argOffset++] = (asPWORD)obj;
+	}
+	
+	if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
+		callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
+	{
+		// Add the second object pointer 
+		argBuffer[argOffset++] = (asPWORD)secondObject;
+	}
+	
+	int spos = 0;
+	for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
+	{
+		asCDataType &paramType = descr->parameterTypes[n];
+		if( paramType.IsObject() && !paramType.IsObjectHandle() && !paramType.IsReference() )
+		{
+			if( paramType.GetObjectType()->flags & COMPLEX_MASK )
+			{
+				// The object is passed by reference
+				argBuffer[argOffset++] = args[spos++];
+			}
+			else
+			{
+				// Ensure 8byte alignment for classes that need it
+				if( (paramType.GetObjectType()->flags & asOBJ_APP_CLASS_ALIGN8) && (argOffset & 1) )
+					argOffset++;
+			
+				// Copy the object's memory to the buffer
+				memcpy(&argBuffer[argOffset], *(void**)(args+spos), paramType.GetSizeInMemoryBytes());
+				// Delete the original memory
+				engine->CallFree(*(char**)(args+spos));
+				spos++;
+				argOffset += paramType.GetSizeInMemoryDWords();
+			}
+		}
+		else if( paramType.GetTokenType() == ttQuestion )
+		{
+			// Copy both pointer and type id
+			argBuffer[argOffset++] = args[spos++];
+			argBuffer[argOffset++] = args[spos++];
+		}
+		else
+		{
+			// The first 2 floats or doubles are loaded into the float registers.
+			// Actually this is only done if they are the first arguments to the function, 
+			// but it doesn't cause any harm to load them into the registers even if they 
+			// won't be used so we don't need to check if they really are the first args.
+			if( floatOffset == 0 )
+			{
+				if( paramType.GetTokenType() == ttFloat )
+					floatRegs.f0 = *reinterpret_cast<float*>(&args[spos]);
+				else if( paramType.GetTokenType() == ttDouble )
+					floatRegs.d0 = *reinterpret_cast<double*>(&args[spos]);
+				floatOffset++;
+			}
+			else if( floatOffset == 1 )
+			{
+				if( paramType.GetTokenType() == ttFloat )
+					floatRegs.f1 = *reinterpret_cast<float*>(&args[spos]);
+				else if( paramType.GetTokenType() == ttDouble )
+					floatRegs.d1 = *reinterpret_cast<double*>(&args[spos]);
+				floatOffset++;
+			}
+		
+			// Copy the value directly
+			if( paramType.GetSizeOnStackDWords() > 1 )
+			{
+				// Make sure the argument is 8byte aligned
+				if( argOffset & 1 )
+					argOffset++;
+				*reinterpret_cast<asQWORD*>(&argBuffer[argOffset]) = *reinterpret_cast<asQWORD*>(&args[spos]);
+				argOffset += 2;
+				spos += 2;
+			}
+			else
+				argBuffer[argOffset++] = args[spos++];
+		}
+	}
+	
+	if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
+	{
+		// Add the object pointer as the last argument
+		argBuffer[argOffset++] = (asPWORD)obj;
+	}
+
+	if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
+		callConv == ICC_THISCALL_OBJLAST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
+	{
+		// Add the second object pointer 
+		argBuffer[argOffset++] = (asPWORD)secondObject;
+	}
+
+	switch( callConv )
+	{
+	case ICC_CDECL:
+	case ICC_CDECL_RETURNINMEM:
+	case ICC_STDCALL:
+	case ICC_STDCALL_RETURNINMEM:
+	case ICC_CDECL_OBJLAST:
+	case ICC_CDECL_OBJLAST_RETURNINMEM:
+	case ICC_CDECL_OBJFIRST:
+	case ICC_CDECL_OBJFIRST_RETURNINMEM:
+	case ICC_THISCALL:
+	case ICC_THISCALL_RETURNINMEM:
+	case ICC_THISCALL_OBJFIRST:
+	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_THISCALL_OBJLAST:
+	case ICC_THISCALL_OBJLAST_RETURNINMEM:
+		retQW = mipsFunc(argOffset*4, argBuffer, func, floatRegs);
+		break;
+
+	case ICC_VIRTUAL_THISCALL:
+	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+	case ICC_VIRTUAL_THISCALL_OBJFIRST:
+	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_VIRTUAL_THISCALL_OBJLAST:
+	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+		// Get virtual function table from the object pointer
+		vftable = *(void***)obj;
+		retQW = mipsFunc(argOffset*4, argBuffer, vftable[asPWORD(func)>>2], floatRegs);
+		break;
+	default:
+		context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
+	}
+
+	// If the return is a float value we need to get the value from the FP register
+	if( sysFunc->hostReturnFloat )
+	{
+		if( sysFunc->hostReturnSize == 1 )
+			*(asDWORD*)&retQW = GetReturnedFloat();
+		else
+			retQW = GetReturnedDouble();
+	}
+
+	return retQW;
+}
+
+asDWORD GetReturnedFloat()
+{
+	asDWORD f;
+
+	asm("swc1 $f0, %0\n" : "=m"(f));
+
+	return f;
+}
+
+asQWORD GetReturnedDouble()
+{
+	asQWORD d = 0;
+
+	asm("sdc1 $f0, %0\n" : "=m"(d));
+
+	return d;
+}
+
+// asQWORD mipsFunc(asUINT argSize, asDWORD *argBuffer, void *func, SFloatRegs &floatRegs);
+// $2,$3                   $4                $5               $6                $7
+asm(
+"	.text\n"
+//"	.align 2\n"
+"	.cfi_startproc\n"
+"	.global mipsFunc\n"
+"	.ent	mipsFunc\n"
+"mipsFunc:\n"
+//"	.frame	$fp,64,$31		# vars= 0, regs= 0/0, args= 0, gp= 0\n"
+//"	.mask	0x00000000,0\n"
+//"	.fmask	0x00000000,0\n"
+"	.set	noreorder\n"
+"	.set	nomacro\n"
+
+// align the stack frame to 8 bytes
+"	addiu	$12, $4, 7\n"		// t4 ($12) = argSize ($4) + 7
+"	li		$13, -8\n"			// t5 ($13) = 0xfffffffffffffff8
+"	and		$12, $12, $13\n"	// t4 ($12) &= t5 ($13). t4 holds the size of the argument block
+// It is required that the caller reserves space for at least 16 bytes even if there are less than 4 arguments
+// and add 8 bytes for the return pointer and s0 ($16) backup
+"	addiu	$13, $12, 24\n"		// t5 = t4 + 24. t5 ($13) holds the total size of the stack frame (including return pointer)
+// save the s0 register (so we can use it to remember where our return pointer is lives)
+"	sw		$16, -4($sp)\n"		// store the s0 register (so we can use it to remember how big our stack frame is)
+"	.cfi_offset 16, -4\n"
+// store the return pointer
+"	sw		$31, -8($sp)\n"
+"	.cfi_offset 31, -8\n"
+// keep original stack pointer
+"	move	$16, $sp\n"
+"	.cfi_def_cfa_register 16\n"
+// push the stack
+"	subu	$sp, $sp, $13\n"
+
+// store the argument in temporary registers
+"	addiu	$25, $6, 0\n"		// t9 ($25) holds the function pointer (must be t9 for position independent code)
+"	addiu	$3, $4, 0\n"		// v1 ($3) holds the size of the argument buffer
+"	move	$15, $5\n"			// t7 ($15) holds the pointer to the argBuffer
+"	move	$14, $7\n"			// t6 ($14) holds the values for the float registers
+
+// load integer registers
+"	lw		$4, 0($15)\n"		// a0 ($4)
+"	lw		$5, 4($15)\n"		// a1 ($5)
+"	lw		$6, 8($15)\n"		// a2 ($6)
+"	lw		$7, 12($15)\n"		// a3 ($7)
+
+// load float registers
+"	ldc1	$f12, 8($14)\n"
+"	ldc1	$f14, 0($14)\n"
+
+// skip stack parameters if there are 4 or less as they are moved into the registers
+"	addi	$14, $3, -16\n"		// The first 4 args were already loaded into registers
+"	blez	$14, andCall\n"
+"	nop\n"
+
+// push stack parameters
+"pushArgs:\n"
+"	addi	$3, -4\n"
+// load from $15 + stack bytes ($3)
+"	addu	$14, $15, $3\n"
+"	lw		$14, 0($14)\n"
+// store to $sp + stack bytes ($3)
+"	addu	$13, $sp, $3\n"
+"	sw		$14, 0($13)\n"
+// if there are more, loop...
+"	bne		$3, $0, pushArgs\n"
+"	nop\n"
+
+// and call the function
+"andCall:\n"
+"	jalr	$25\n"
+"	nop\n"
+
+// restore original stack pointer
+"	move	$sp, $16\n"
+// restore the return pointer
+"	lw		$31, -8($sp)\n"
+// restore the original value of $16
+"	lw		$16, -4($sp)\n"
+// and return from the function
+"	jr		$31\n"
+"	nop\n"
+
+"	.set	macro\n"
+"	.set	reorder\n"
+"	.end	mipsFunc\n"
+"	.cfi_endproc\n"
+"	.size	mipsFunc, .-mipsFunc\n"
+);
+
+#else // !(defined(__linux__) && defined(_ABIO32))
+
+// The MIPS ABI used by PSP and PS2 is implemented here
+
 #define AS_MIPS_MAX_ARGS 32
 #define AS_NUM_REG_FLOATS 8
 #define AS_NUM_REG_INTS 8
@@ -191,33 +503,12 @@ asDWORD GetReturnedFloat()
 	return f;
 }
 
-/*
-asDWORD GetReturnedFloat();
-
-asm(
-"	.align 4\n"
-"	.global GetReturnedFloat\n"
-"GetReturnedFloat:\n"
-"	.set	noreorder\n"
-"	.set	nomacro\n"
-"	j	$ra\n"
-"	mfc1 $v0, $f0\n"
-"	.set	macro\n"
-"	.set	reorder\n"
-"	.end	Func\n"
-*/
-
-
-// sizeof(double) == 4 with sh-elf-gcc (3.4.0) -m4
-// so this isn't really used...
 asQWORD GetReturnedDouble()
 {
 	asQWORD d = 0;
 
-	printf("Broken!!!");
-/*
-	asm("sw $v0, %0\n" : "=m"(d));
-*/
+	asm("sdc1 $f0, %0\n" : "=m"(d));
+
 	return d;
 }
 
@@ -352,7 +643,7 @@ asm(
 "	.set	nomacro\n"
 // align the stack frame to 8 bytes
 "	addiu	$12, $6, 7\n"
-"	li		$13, -8\n"			// 0xfffffffffffffffc
+"	li		$13, -8\n"			// 0xfffffffffffffff8
 "	and		$12, $12, $13\n"	// t4 holds the size of the argument block
 // and add 8 bytes for the return pointer and s0 backup
 "	addiu	$13, $12, 8\n"		// t5 holds the total size of the stack frame (including return pointer)
@@ -432,6 +723,8 @@ asm(
 "	.size	mipsFunc, .-mipsFunc\n"
 );
 
+#endif // PSP and PS2 MIPS ABI
+	
 END_AS_NAMESPACE
 
 #endif // AS_MIPS

+ 12 - 4
Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -73,14 +73,18 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
 
 	__asm__ __volatile__ (
 
-		"  movq %0, %%rcx \n" 	// rcx = cnt
+		"  movq %0, %%rcx \n"	// rcx = cnt
 		"  movq %1, %%r10 \n"	// r10 = args
 		"  movq %2, %%r11 \n"	// r11 = func
 
 	// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
 		"  movq %%rsp, %%r15 \n"
+#ifdef __OPTIMIZE__
 	// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
+	// This should only be done if any optimization is done. If no optimization (-O0) is used,
+	// then the compiler already backups the rsp before entering the inline assembler code
 		" .cfi_def_cfa_register r15 \n"
+#endif
 
 	// Skip the first 128 bytes on the stack frame, called "red zone",  
 	// that might be used by the compiler to store temporary values
@@ -100,7 +104,7 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
 		"  jle endstack \n"
 		"  subl $1, %%esi \n"
 		"  xorl %%edx, %%edx \n"
-		"  leaq	8(, %%rsi, 8), %%rcx \n"
+		"  leaq 8(, %%rsi, 8), %%rcx \n"
 		"loopstack: \n"
 		"  movq 112(%%r10, %%rdx), %%rax \n"
 		"  pushq %%rax \n"
@@ -128,12 +132,16 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
 		"  movsd 56(%%rax), %%xmm7 \n"
 
 	// Call the function
-		"  call	*%%r11 \n"
+		"  call *%%r11 \n"
 
 	// Restore stack pointer
 		"  mov %%r15, %%rsp \n"
+#ifdef __OPTIMIZE__
 	// Inform the stack unwind logic that the stack pointer has been restored
+	// This should only be done if any optimization is done. If no optimization (-O0) is used,
+	// then the compiler already backups the rsp before entering the inline assembler code
 		" .cfi_def_cfa_register rsp \n"
+#endif
 
 	// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
 		"  movl %5, %%ecx \n"

+ 9 - 9
Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -1263,13 +1263,13 @@ endcopy:
 		"subl  $4, %%ecx       \n"
 		"jne   copyloop3       \n"
 		"endcopy3:             \n"
-#if defined(__MINGW32__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4)
-        // MinGW made some strange choices with 4.7, and the thiscall calling convention
-        // when returning an object in memory is completely different from when not returning
-        // in memory
-        "pushl 0(%%ebx)        \n" // push obj on the stack
-        "movl 16(%%ebx), %%ecx \n" // move the return pointer into ECX
-        "call  *12(%%ebx)      \n" // call the function
+#ifdef AS_MINGW47
+		// MinGW made some strange choices with 4.7 and the thiscall calling convention,
+		// returning an object in memory is completely different from when not returning
+		// in memory
+		"pushl 0(%%ebx)        \n" // push obj on the stack
+		"movl 16(%%ebx), %%ecx \n" // move the return pointer into ECX
+		"call  *12(%%ebx)      \n" // call the function
 #else
 		"movl  0(%%ebx), %%ecx \n" // move obj into ECX
 #ifdef THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
@@ -1286,7 +1286,7 @@ endcopy:
 		"addl  $4, %%esp       \n" // pop the object pointer
 #endif
 #endif
-#endif // MINGW
+#endif // AS_MINGW47
 		// Pop the alignment bytes
 		"popl  %%esp           \n"
 		"popl  %%ebx           \n"

+ 20 - 20
Source/ThirdParty/AngelScript/source/as_callfunc_xenon.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -43,7 +43,9 @@
 // various fixes in asm ppcFunc
 // fix for variable arguments
 //
-
+// Modified by Anthony Clark May 2015
+// Fixed the issue where int64 and uint64 could not be passed nativly
+// few minor fixes within asm ppcFunc to handle int64 and uint64
 
 
 // XBox 360 calling convention
@@ -87,7 +89,6 @@
 // References:
 // https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF77852569970071B0D6/$file/eabi_app.pdf
 //
-// TODO: The code doesn't handle int64 and uint64 parameters
 // TODO: The code doesn't handle objects passed by value (unless they are max 4 bytes in size)
 
 
@@ -128,7 +129,7 @@ enum argTypes
 // pArgs     is the array of the argument values
 // pArgTypes is an array containing a byte indicating the type (enum argTypes) for each argument.
 // dwFunc    is the address of the function that will be called
-asQWORD __declspec( naked ) ppcFunc(const asDWORD* pArgs, asDWORD dwFunc, const asBYTE* pArgTypes)
+asQWORD __declspec( naked ) ppcFunc(const asQWORD* pArgs, asDWORD dwFunc, const asBYTE* pArgTypes)
 {
 	__asm
 	{
@@ -202,7 +203,7 @@ ppcNextArg:
 //////////////////////////////////////////////////////////////////////////
 ppcArgIsInteger:
 		// Get the arg from the stack
-		lwz r12, 0(r26)
+		ld  r12, 0(r26)
 
 		// r23 holds the integer arg count so far
 		cmplwi cr6, r23, 0
@@ -251,11 +252,11 @@ ppcArgIsInteger:
 		b ppcLoadIntRegUpd
 
 		ppcLoadIntRegUpd:
-		stw	    r12, 0(r31)			// push on the stack
+		std	    r12, 0(r31)			// push on the stack
 		addi	r31, r31, 8			// inc stack by 1 reg
 
 		addi r23, r23, 1			// Increment used int register count
-		addi r26, r26, 4			// Increment pArgs
+		addi r26, r26, 8			// Increment pArgs
 		b ppcNextArg				// Call next arg
 
 //////////////////////////////////////////////////////////////////////////
@@ -511,7 +512,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 	// Pack the arguments into an array that ppcFunc() can use to load each CPU register properly
 	asBYTE  ppcArgsType[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG + AS_PPC_ENDOFARGS];
-	asDWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
+	asQWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
 	int     argsCnt = 0;
 
 	// If the function returns an object in memory, we allocate the memory and put the ptr to the front (will go to r3)
@@ -625,35 +626,34 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		}
 		else
 		{
-			// TODO: How should int64 and uint64 be passed natively? 
-			//       Currently the code doesn't handle these types
-
 			// TODO: The code also ignore the fact that large objects
 			//       passed by value has been copied to the stack
 			//       in the above loop.
 
 			*pCurArgType++ = ppcINTARG;
 
-			*((int*) pCurFixedArgValue) = *((int*) pCurStackArgValue);
+			*((asQWORD*) pCurFixedArgValue) = *((asUINT*) pCurStackArgValue);
 
 			if( !descr->parameterTypes[n].IsReference() )
 			{
-				// If the arg is less that 4 bytes, then move the  
-				// bytes to the higher bytes within the dword
+				// If the arg is not 4 bytes which we coppied, lets do it again the right way
 				asUINT numBytes = descr->parameterTypes[n].GetSizeInMemoryBytes();
 				if( numBytes == 1 )
 				{
-					pCurFixedArgValue[3] = pCurFixedArgValue[0];
-					pCurFixedArgValue[0] = 0;
+					*((asQWORD*) pCurFixedArgValue) = *((asBYTE*) pCurStackArgValue);
 				}
 				else if( numBytes == 2 )
 				{
-					*(asWORD*)&pCurFixedArgValue[2] = *(asWORD*)&pCurFixedArgValue[0];
-					*(asWORD*)&pCurFixedArgValue[0] = 0;
+					*((asQWORD*) pCurFixedArgValue) = *((asWORD*) pCurStackArgValue);
+				}
+				else if( numBytes == 8 )
+				{
+					*((asQWORD*) pCurFixedArgValue) = *((asQWORD*) pCurStackArgValue);
+					pCurStackArgValue += 4; // Increase our cur stack arg value by 4 bytes to = 8 total later
 				}
 			}
 
-			pCurFixedArgValue += 4;
+			pCurFixedArgValue += 8;
 			pCurStackArgValue += 4;
 
 			// if it is a variable argument, account for the typeId
@@ -703,7 +703,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the last argument
 		ppcArgsType[argsCnt++] = ppcINTARG;
 		ppcArgsType[argsCnt] = ppcENDARG;
-		*((asPWORD*)pCurFixedArgValue) = (asPWORD)obj;
+		*((asQWORD*)pCurFixedArgValue) = (asPWORD)obj;
 		retQW = ppcFunc( ppcArgs, (asDWORD)func, ppcArgsType );
 		break;
 	}

File diff suppressed because it is too large
+ 429 - 200
Source/ThirdParty/AngelScript/source/as_compiler.cpp


+ 87 - 36
Source/ThirdParty/AngelScript/source/as_compiler.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -73,14 +73,9 @@ struct asSExprContext
 {
 	asSExprContext(asCScriptEngine *engine) : bc(engine) 
 	{
-		exprNode        = 0; 
-		origExpr        = 0; 
-		property_get    = 0; 
-		property_set    = 0; 
-		property_const  = false;
-		property_handle = false;
-		property_ref    = false;
-		property_arg    = 0;
+		property_arg     = 0;
+
+		Clear();
 	}
 	~asSExprContext() 
 	{
@@ -90,43 +85,95 @@ struct asSExprContext
 	void Clear()
 	{
 		bc.ClearAll();
-		type.SetDummy();
+		type.Set(asCDataType());
+		deferredParams.SetLength(0);
 		if( property_arg )
 			asDELETE(property_arg, asSExprContext);
-		property_arg = 0;
-		deferredParams.SetLength(0);
-		exprNode        = 0; 
-		origExpr        = 0; 
-		property_get    = 0; 
-		property_set    = 0; 
-		property_const  = false;
-		property_handle = false;
-		property_ref    = false;
-		methodName      = "";
-		enumValue       = "";
+		property_arg     = 0;
+		exprNode         = 0; 
+		origExpr         = 0; 
+		property_get     = 0; 
+		property_set     = 0; 
+		property_const   = false;
+		property_handle  = false;
+		property_ref     = false;
+		methodName       = "";
+		enumValue        = "";
+		isVoidExpression = false;
+		isCleanArg       = false;
 	}
-	bool IsClassMethod()
+	bool IsClassMethod() const
 	{
 		if( type.dataType.GetObjectType() == 0 ) return false;
 		if( methodName == "" ) return false;
 		if( type.dataType.GetObjectType() == &type.dataType.GetObjectType()->engine->functionBehaviours ) return false;
 		return true;
 	}
-	bool IsGlobalFunc()
+	bool IsGlobalFunc() const
 	{
 		if( type.dataType.GetObjectType() == 0 ) return false;
 		if( methodName == "" ) return false;
 		if( type.dataType.GetObjectType() != &type.dataType.GetObjectType()->engine->functionBehaviours ) return false;
 		return true;
 	}
+	void SetLambda(asCScriptNode *funcDecl)
+	{
+		asASSERT( funcDecl && funcDecl->nodeType == snFunction );
+		asASSERT( bc.GetLastInstr() == -1 );
+
+		Clear();
+		type.SetUndefinedFuncHandle(bc.GetEngine());
+		exprNode = funcDecl;
+	}
+	bool IsLambda() const
+	{
+		if( type.IsUndefinedFuncHandle() && exprNode && exprNode->nodeType == snFunction )
+			return true;
+
+		return false;
+	}
+	void SetVoidExpression()
+	{
+		Clear();
+		type.SetVoid();
+		isVoidExpression = true;
+	}
+	bool IsVoidExpression() const
+	{
+		if( isVoidExpression && type.IsVoid() && exprNode == 0 )
+			return true;
+
+		return false;
+	}
+	void Merge(asSExprContext *after)
+	{
+		type             = after->type;
+		property_get     = after->property_get;
+		property_set     = after->property_set;
+		property_const   = after->property_const;
+		property_handle  = after->property_handle;
+		property_ref     = after->property_ref;
+		property_arg     = after->property_arg;
+		exprNode         = after->exprNode;
+		methodName       = after->methodName;
+		enumValue        = after->enumValue;
+		isVoidExpression = after->isVoidExpression;
+		isCleanArg       = after->isCleanArg;
+
+		after->property_arg = 0;
+
+		// Do not copy the origExpr member
+	}
 
 	asCByteCode bc;
 	asCTypeInfo type;
 	int  property_get;
 	int  property_set;
-	bool property_const;  // If the object that is being accessed through property accessor is read-only
-	bool property_handle; // If the property accessor is called on an object stored in a handle
-	bool property_ref;    // If the property accessor is called on a reference
+	bool property_const;   // If the object that is being accessed through property accessor is read-only
+	bool property_handle;  // If the property accessor is called on an object stored in a handle
+	bool property_ref;     // If the property accessor is called on a reference
+	bool isVoidExpression; // Set to true if the expression is an explicit 'void', e.g. used to ignore out parameters in func calls
+	bool isCleanArg;       // Set to true if the expression has only been initialized with default constructor
 	asSExprContext *property_arg;
 	asCArray<asSDeferredParam> deferredParams;
 	asCScriptNode  *exprNode;
@@ -212,8 +259,8 @@ protected:
 	int  CompileExpressionPostOp(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionValue(asCScriptNode *node, asSExprContext *out);
 	int  CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
-	void CompileConstructCall(asCScriptNode *node, asSExprContext *out);
-	void CompileConversion(asCScriptNode *node, asSExprContext *out);
+	int  CompileConstructCall(asCScriptNode *node, asSExprContext *out);
+	int  CompileConversion(asCScriptNode *node, asSExprContext *out);
 	int  CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
 	void CompileOperatorOnHandles(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
 	void CompileMathOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
@@ -239,6 +286,7 @@ protected:
 	void CompileInitAsCopy(asCDataType &type, int offset, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool derefDestination);
 
 	// Helper functions
+	void ConvertToPostFix(asCScriptNode *expr, asCArray<asCScriptNode *> &postfix);
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
 	int  ProcessPropertyGetSetAccessor(asSExprContext *ctx, asSExprContext *lctx, asSExprContext *rctx, eTokenType op, asCScriptNode *errNode);
@@ -288,6 +336,7 @@ protected:
 	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   ImplicitConvObjectToBestMathType(asSExprContext *ctx, asCScriptNode *node);
+	asUINT ImplicitConvLambdaToFunc(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
 
 	void LineInstr(asCByteCode *bc, size_t pos);
 
@@ -307,16 +356,18 @@ protected:
 	bool hasCompileErrors;
 
 	int nextLabel;
+	int numLambdas;
 
-	asCVariableScope *variables;
-	asCBuilder *builder;
-	asCScriptEngine *engine;
-	asCScriptCode *script;
+	asCVariableScope  *variables;
+	asCBuilder        *builder;
+	asCScriptEngine   *engine;
+	asCScriptCode     *script;
 	asCScriptFunction *outFunc;
 
-	bool               m_isConstructor;
-	bool               m_isConstructorCalled;
-	sClassDeclaration *m_classDecl;
+	bool                        m_isConstructor;
+	bool                        m_isConstructorCalled;
+	sClassDeclaration          *m_classDecl;
+	sGlobalVariableDescription *m_globalVar;
 
 	asCArray<int> breakLabels;
 	asCArray<int> continueLabels;
@@ -353,7 +404,7 @@ protected:
 
 	bool isCompilingDefaultArg;
 	bool isProcessingDeferredParams;
-	int noCodeOutput;
+	int  noCodeOutput;
 };
 
 END_AS_NAMESPACE

+ 47 - 35
Source/ThirdParty/AngelScript/source/as_config.h

@@ -28,7 +28,6 @@
    [email protected]
 */
 
-// Modified by Yao Wei Tjong and Skrylar for Urho3D
 
 
 //
@@ -587,6 +586,7 @@
 		#define AS_NO_MEMORY_H
 		#define AS_MIPS
 		#define AS_PSP
+		#define AS_USE_DOUBLE_AS_FLOAT
 	// PSVita
 	#elif defined(__psp2__)
 		#define AS_PSVITA
@@ -798,18 +798,16 @@
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 
 			// As of version 4.7 MinGW changed the ABI, presumably
-
 			// to be better aligned with how MSVC works
-			// Urho3D: also check for Clang version and use the same workaround 
 			#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4
-			    #define AS_MINGW47_WORKAROUND
+				#define AS_MINGW47
 			#endif
-
-			#if (__clang_major__ == 3 && __clang_minor__ > 4)
-			    #define AS_MINGW47_WORKAROUND
+		
+			#if (__clang_major__ == 3 && __clang_minor__ > 4) || __clang_major > 3
+				#define AS_MINGW47
 			#endif
 
-			#ifdef AS_MINGW47_WORKAROUND
+			#ifdef AS_MINGW47
 				#undef  CALLEE_POPS_HIDDEN_RETURN_POINTER
 				#define THISCALL_CALLEE_POPS_ARGUMENTS
 			#else
@@ -856,7 +854,7 @@
 			// STDCALL is not available on 64bit Linux
 			#undef STDCALL
 			#define STDCALL
-		#elif defined(__ARMEL__) || defined(__arm__)
+		#elif (defined(__ARMEL__) || defined(__arm__)) && !(defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__))
 			#define AS_ARM
 
 			// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
@@ -895,11 +893,24 @@
 
 		#elif defined(__mips__)
 			#define AS_MIPS
-			#define AS_BIG_ENDIAN
-			#define AS_USE_DOUBLE_AS_FLOAT
+			#undef STDCALL
+			#define STDCALL
 
-			// Native calling conventions for Linux/Mips do not work yet.
-			#define AS_MAX_PORTABILITY
+			#ifdef _ABIO32
+				#define AS_MIPS
+
+				// All structures are returned in memory regardless of size or complexity
+				#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+				#define	THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#undef AS_NO_THISCALL_FUNCTOR_METHOD
+			#else
+				// For other ABIs the native calling convention is not available (yet)
+				#define AS_MAX_PORTABILITY
+			#endif
 		#else
 			#define AS_MAX_PORTABILITY
 		#endif
@@ -947,6 +958,7 @@
 		// Support native calling conventions on MIPS architecture
 		#if (defined(_MIPS_ARCH) || defined(_mips) || defined(__MIPSEL__)) && !defined(__LP64__)
 			#define AS_MIPS
+			#define AS_USE_DOUBLE_AS_FLOAT
 		#else
 			#define AS_MAX_PORTABILITY
 		#endif
@@ -999,6 +1011,9 @@
 		#if (defined(_ARM_) || defined(__arm__))
 			// Android ARM
 
+			// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
+			#define AS_NO_EXCEPTIONS
+
 			#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
 			#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
 			#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
@@ -1024,24 +1039,26 @@
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
-// Urho3D - Add support for Android Intel x86_64 and Android ARM 64bit
-		#elif defined(__LP64__) && !defined(__aarch64__)
-			// Android Intel x86_64 (same config as Linux x86_64). Tested with Intel x86_64 Atom System Image.
-			#define AS_X64_GCC
-			#undef AS_NO_THISCALL_FUNCTOR_METHOD
-			#define HAS_128_BIT_PRIMITIVES
-			#define SPLIT_OBJS_BY_MEMBER_TYPES
-			#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
-        #elif defined(__aarch64__)
-			// Doesn't support native calling for Android ARM 64bit yet
-			#define AS_MAX_PORTABILITY
-			// STDCALL is not available on ARM
+		#elif defined(__mips__)
+			#define AS_MIPS
 			#undef STDCALL
 			#define STDCALL
+
+			#ifdef _ABIO32
+				#define AS_MIPS
+
+				// All structures are returned in memory regardless of size or complexity
+				#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+				#define	THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
+				#undef AS_NO_THISCALL_FUNCTOR_METHOD
+			#else
+				// For other ABIs the native calling convention is not available (yet)
+				#define AS_MAX_PORTABILITY
+			#endif
 		#endif
 
 	// Haiku OS
@@ -1076,7 +1093,7 @@
 			// Support native calling conventions on Intel 32bit CPU
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
-		#elif defined(__LP64__)
+		#elif defined(__x86_64__)
 			#define AS_X64_GCC
 			#define HAS_128_BIT_PRIMITIVES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
@@ -1141,11 +1158,6 @@
 	// Nothing special here
 #endif
 
-// MIPS architecture (generally PS2 and PSP consoles, potentially supports N64 as well)
-#if defined(_MIPS_ARCH) || defined(_mips) || defined(__MIPSEL__) || defined(__PSP__) || defined(__psp__) || defined(_EE_) || defined(_PSP) || defined(_PS2)
-	#define AS_USE_DOUBLE_AS_FLOAT	// use 32bit floats instead of doubles
-#endif
-
 // PowerPC, e.g. Mac, GameCube, PS3, XBox 360, Wii
 #if defined(__PPC__) || defined(__ppc__) || defined(_PPC_) || defined(EPPC)
 	#define AS_BIG_ENDIAN

+ 20 - 4
Source/ThirdParty/AngelScript/source/as_context.cpp

@@ -134,17 +134,32 @@ public:
 
 #endif
 
+// interface
 AS_API asIScriptContext *asGetActiveContext()
 {
 	asCThreadLocalData *tld = asCThreadManager::GetLocalData();
-	if( tld->activeContexts.GetLength() == 0 )
+
+	// tld can be 0 if asGetActiveContext is called before any engine has been created.
+
+	// Observe! I've seen a case where an application linked with the library twice
+	// and thus ended up with two separate instances of the code and global variables.
+	// The application somehow mixed the two instances so that a function called from
+	// a script ended up calling asGetActiveContext from the other instance that had
+	// never been initialized.
+
+	if( tld == 0 || tld->activeContexts.GetLength() == 0 )
 		return 0;
 	return tld->activeContexts[tld->activeContexts.GetLength()-1];
 }
 
+// internal
+// Note: There is no asPopActiveContext(), just call tld->activeContexts.PopLast() instead
 asCThreadLocalData *asPushActiveContext(asIScriptContext *ctx)
 {
 	asCThreadLocalData *tld = asCThreadManager::GetLocalData();
+	asASSERT( tld );
+	if( tld == 0 )
+		return 0;
 	tld->activeContexts.PushLast(ctx);
 	return tld;
 }
@@ -1304,8 +1319,9 @@ int asCContext::Execute()
 	}
 
 	// Pop the active context
-	asASSERT(tld->activeContexts[tld->activeContexts.GetLength()-1] == this);
-	tld->activeContexts.PopLast();
+	asASSERT(tld && tld->activeContexts[tld->activeContexts.GetLength()-1] == this);
+	if( tld )
+		tld->activeContexts.PopLast();
 
 	if( m_status == asEXECUTION_FINISHED )
 	{
@@ -4948,7 +4964,7 @@ int asCContext::GetExceptionLineNumber(int *column, const char **sectionName)
 
 	if( sectionName )
 	{
-		// The section index can be -1 if the exception was raised in a generated function, e.g. factstub for templates
+		// The section index can be -1 if the exception was raised in a generated function, e.g. $fact for templates
 		if( m_exceptionSectionIdx >= 0 )
 			*sectionName = m_engine->scriptSectionNames[m_exceptionSectionIdx]->AddressOf();
 		else

+ 12 - 18
Source/ThirdParty/AngelScript/source/as_debug.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -74,11 +74,19 @@ typedef double float64_t;
 #include <direct.h>
 #endif
 
+#endif // AS_PSVITA
+#endif // _WIN32_WCE
+#endif // AS_WII
+
+#endif // !defined(AS_DEBUG)
+
+
 
 #if defined(_MSC_VER) && defined(AS_PROFILE)
 // Currently only do profiling with MSVC++
 
 #include <mmsystem.h>
+#include <direct.h>
 #include "as_string.h"
 #include "as_map.h"
 #include "as_string_util.h"
@@ -144,7 +152,7 @@ public:
 		return time;
 	}
 
-	void End(const char *name, double beginTime)
+	void End(const char * /*name*/, double beginTime)
 	{
 		double time = GetTime();
 
@@ -247,7 +255,7 @@ protected:
 
 END_AS_NAMESPACE
 
-#else // _MSC_VER && AS_PROFILE
+#else // !(_MSC_VER && AS_PROFILE)
 
 // Define it so nothing is done
 #define TimeIt(x) 
@@ -257,20 +265,6 @@ END_AS_NAMESPACE
 
 
 
-
-
-
-#endif // AS_PSVITA
-#endif // _WIN32_WCE
-#endif // AS_WII
-
-#else // !defined(AS_DEBUG)
-
-// Define it so nothing is done
-#define TimeIt(x) 
-
-#endif // !defined(AS_DEBUG)
-
-#endif
+#endif // defined(AS_DEBUG_H)
 
 

+ 3 - 8
Source/ThirdParty/AngelScript/source/as_gc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -486,23 +486,18 @@ int asCGarbageCollector::ReportAndReleaseUndestroyedObjects()
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
 
 		// Add additional info for builtin types
-		if( gcObj.type->name == "_builtin_function_" )
+		if( gcObj.type->name == "$func" )
 		{
 			// Unfortunately we can't show the function declaration here, because the engine may have released the parameter list already so the declaration would only be misleading
 			// We need to show the function type too as for example delegates do not have a name
 			msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, reinterpret_cast<asCScriptFunction*>(gcObj.obj)->GetName(), reinterpret_cast<asCScriptFunction*>(gcObj.obj)->GetFuncType());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
 		}
-		else if( gcObj.type->name == "_builtin_objecttype_" )
+		else if( gcObj.type->name == "$obj" )
 		{
 			msg.Format(TXT_PREV_TYPE_IS_NAMED_s, reinterpret_cast<asCObjectType*>(gcObj.obj)->GetName());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
 		}
-		else if( gcObj.type->name == "_builtin_globalprop_" )
-		{
-			msg.Format(TXT_PREV_TYPE_IS_NAMED_s, reinterpret_cast<asCGlobalProperty*>(gcObj.obj)->name.AddressOf());
-			engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
-		}
 
 		// Release the reference that the GC holds if the release functions is still available
 		if( gcObj.type->beh.release && engine->scriptFunctions[gcObj.type->beh.release] )

+ 29 - 40
Source/ThirdParty/AngelScript/source/as_module.cpp

@@ -46,32 +46,6 @@
 
 BEGIN_AS_NAMESPACE
 
-// TODO: 2.30.0: redesign: Improved method for discarding modules (faster clean-up, less abuse of garbage collector)
-//
-// I need to separate the reference counter for internal references and outside references:
-//
-//  - Internal references are for example, when the module refers to a function or object since it is declared in the module, or when
-//    a function refers to another function since it is being called in the code.
-//  - Outside references are for example object instances holding a reference to the object type, or a context currently
-//    executing a function.
-//
-// If no object instances are alive or no contexts are alive it is known that functions from a discarded module
-// can be called, so they can be destroyed without any need to execute the complex garbage collection routines.
-//
-// If there are live objects, the entire module should be kept for safe keeping, though no longer visible.
-//
-// TODO: It may not be necessary to keep track of internal references. Without keeping track of internal references, can I still
-//       handle RemoveFunction and RemoveGlobalVariable correctly?
-//
-// TODO: How to avoid global variables keeping code alive? For example a script object, or a funcdef?
-//       Can I do a quick check of the object types and functions to count number of outside references, and then do another
-//       check over the global variables to subtract the outside references coming from these? What if the outside reference
-//       is added by an application type in a global variable that the engine doesn't know about? Example, a global dictionary 
-//       holding object instances. Should discarding a module immediately destroy the content of the global variables? What if
-//       a live object tries to access the global variable after it has been discarded? Throwing a script exception is acceptable?
-//       Perhaps I need to allow the user to provide a clean-up routine that will be executed before destroying the objects. 
-//       Or I might just put that responsibility on the application.
-
 
 // internal
 asCModule::asCModule(const char *name, asCScriptEngine *engine)
@@ -315,7 +289,7 @@ int asCModule::Build()
 
 	// Don't allow the module to be rebuilt if there are still 
 	// external references that will need the previous code
-	// TODO: 2.30.0: interface: The asIScriptModule must have a method for querying if the module is used
+	// TODO: interface: The asIScriptModule must have a method for querying if the module is used
 	if( HasExternalReferences(false) )
 	{
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_MODULE_IS_IN_USE);
@@ -944,9 +918,6 @@ int asCModule::GetGlobalVarIndexByName(const char *name) const
 // interface
 int asCModule::RemoveGlobalVar(asUINT index)
 {
-	// TODO: 2.30.0: redesign: Before removing the variable, clear it to free the object
-	//                         The property shouldn't be orphaned.
-
 	asCGlobalProperty *prop = scriptGlobals.Get(index);
 	if( !prop )
 		return asINVALID_ARG;
@@ -1273,6 +1244,33 @@ int asCModule::AddScriptFunction(asCScriptFunction *func)
 	func->AddRefInternal();
 	engine->AddScriptFunction(func);
 
+	// If the function that is being added is an already compiled shared function
+	// then it is necessary to look for anonymous functions that may be declared
+	// within it and add those as well
+	if( func->isShared && func->funcType == asFUNC_SCRIPT )
+	{
+		// Loop through the byte code and check all the 
+		// asBC_FuncPtr instructions for anonymous functions
+		asDWORD *bc = func->scriptData->byteCode.AddressOf();
+		asUINT bcLength = (asUINT)func->scriptData->byteCode.GetLength();
+		for( asUINT n = 0; n < bcLength; )
+		{
+			int c = *(asBYTE*)&bc[n];
+			if( c == asBC_FuncPtr )
+			{
+				asCScriptFunction *f = reinterpret_cast<asCScriptFunction*>(asBC_PTRARG(&bc[n]));
+				// Anonymous functions start with $
+				// There are never two equal anonymous functions so it is not necessary to look for duplicates
+				if( f && f->name[0] == '$' )
+				{
+					AddScriptFunction(f);
+					globalFunctions.Put(f);
+				}
+			}
+			n += asBCTypeSize[asBCInfo[c].type];
+		}
+	}
+
 	return 0;
 }
 
@@ -1700,16 +1698,6 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
 // interface
 int asCModule::RemoveFunction(asIScriptFunction *func)
 {
-	// TODO: 2.30.0: redesign: Check if there are any references before removing the function
-	//                         if there are, just hide it from the visible but do not destroy or 
-	//                         remove it from the module.
-	//
-	//                         Only if the function has no live references, nor internal references
-	//                         can it be immediately removed, and its internal references released.
-	//
-	//                         Check if any previously hidden functions are without references,
-	//                         if so they should removed too.
-
 	// Find the global function
 	asCScriptFunction *f = static_cast<asCScriptFunction*>(func);
 	int idx = globalFunctions.GetIndex(f);
@@ -1734,6 +1722,7 @@ int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
 
 	func->name      = name;
 	func->nameSpace = ns;
+	func->module    = this;
 
 	funcDefs.PushLast(func);
 

+ 15 - 7
Source/ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -53,6 +53,7 @@ asCObjectType::asCObjectType()
 	module      = 0;
 	derivedFrom = 0;
 	size        = 0;
+	typeId      = -1; // start as -1 to signal that it hasn't been defined
 
 	acceptValueSubType = true;
 	acceptRefSubType   = true;
@@ -74,6 +75,7 @@ asCObjectType::asCObjectType(asCScriptEngine *engine)
 	this->engine = engine; 
 	module       = 0;
 	derivedFrom  = 0;
+	typeId      = -1; // start as -1 to signal that it hasn't been defined
 
 	acceptValueSubType = true;
 	acceptRefSubType   = true;
@@ -241,7 +243,8 @@ void asCObjectType::DestroyInternal()
 	userData.SetLength(0);
 
 	// Remove the type from the engine
-	engine->RemoveFromTypeIdMap(this);
+	if( typeId != -1 )
+		engine->RemoveFromTypeIdMap(this);
 
 	// Clear the engine pointer to mark the object type as invalid
 	engine = 0;
@@ -252,7 +255,6 @@ asCObjectType::~asCObjectType()
 	if( engine == 0 )
 		return;
 
-	// TODO: 2.30.0: redesign: Shouldn't this have been done already?
 	DestroyInternal();
 }
 
@@ -322,12 +324,18 @@ asUINT asCObjectType::GetSize() const
 // interface
 int asCObjectType::GetTypeId() const
 {
-	// We need a non const pointer to create the asCDataType object.
-	// We're not breaking anything here because this function is not
-	// modifying the object, so this const cast is safe.
-	asCObjectType *ot = const_cast<asCObjectType*>(this);
+	if( typeId == -1 )
+	{
+		// We need a non const pointer to create the asCDataType object.
+		// We're not breaking anything here because this function is not
+		// modifying the object, so this const cast is safe.
+		asCObjectType *ot = const_cast<asCObjectType*>(this);
+
+		// The engine will define the typeId for this object type
+		engine->GetTypeIdFromDataType(asCDataType::CreateObject(ot, false));
+	}
 
-	return engine->GetTypeIdFromDataType(asCDataType::CreateObject(ot, false));
+	return typeId;
 }
 
 // interface

+ 2 - 1
Source/ThirdParty/AngelScript/source/as_objecttype.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -191,6 +191,7 @@ public:
 #ifdef WIP_16BYTE_ALIGN
 	int                          alignment;
 #endif
+	mutable int                  typeId;
 	asCArray<asCObjectProperty*> properties;
 	asCArray<int>                methods;
 	asCArray<asCObjectType*>     interfaces;

+ 185 - 98
Source/ThirdParty/AngelScript/source/as_parser.cpp

@@ -610,7 +610,7 @@ asCScriptNode *asCParser::ParseIdentifier()
 	return node;
 }
 
-// BNF: PARAMLIST ::= '(' ('void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]}) ')'
+// BNF: PARAMLIST ::= '(' ['void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]})] ')'
 asCScriptNode *asCParser::ParseParameterList()
 {
 	asCScriptNode *node = CreateNode(snParameterList);
@@ -1243,7 +1243,7 @@ asCScriptNode *asCParser::ParseCast()
 	return node;
 }
 
-// BNF: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')'
+// BNF: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')' | LAMBDA
 asCScriptNode *asCParser::ParseExprValue()
 {
 	asCScriptNode *node = CreateNode(snExprValue);
@@ -1261,44 +1261,54 @@ asCScriptNode *asCParser::ParseExprValue()
 		node->AddChildLast(ParseConstructCall());
 	else if( t1.type == ttIdentifier || t1.type == ttScope )
 	{
-		// Determine the last identifier in order to check if it is a type
-		sToken t;
-		if( t1.type == ttScope ) t = t2; else t = t1;
-		RewindTo(&t);
-		GetToken(&t2);
-		while( t.type == ttIdentifier )
+		// Check if the expression is an anonymous function
+		if( IsLambda() )
 		{
-			t2 = t;
-			GetToken(&t);
-			if( t.type == ttScope )
-				GetToken(&t);
-			else 
-				break;
+			node->AddChildLast(ParseLambda());
 		}
-
-		bool isDataType = IsDataType(t2);
-		bool isTemplateType = false;
-		if( isDataType )
+		else
 		{
-			// Is this a template type?
-			tempString.Assign(&script->code[t2.pos], t2.length);
-			if( engine->IsTemplateType(tempString.AddressOf()) )
-				isTemplateType = true;
-		}
+			// Determine the last identifier in order to check if it is a type
+			sToken t;
+			if( t1.type == ttScope ) t = t2; else t = t1;
+			RewindTo(&t);
+			GetToken(&t2);
+			while( t.type == ttIdentifier )
+			{
+				t2 = t;
+				GetToken(&t);
+				if( t.type == ttScope )
+					GetToken(&t);
+				else 
+					break;
+			}
+
+			bool isDataType = IsDataType(t2);
+			bool isTemplateType = false;
+			if( isDataType )
+			{
+				// Is this a template type?
+				tempString.Assign(&script->code[t2.pos], t2.length);
+				if( engine->IsTemplateType(tempString.AddressOf()) )
+					isTemplateType = true;
+			}
+
+			GetToken(&t2);
 		
-		// Rewind so the real parsing can be done, after deciding what to parse
-		RewindTo(&t1);
+			// Rewind so the real parsing can be done, after deciding what to parse
+			RewindTo(&t1);
 
-		// Check if this is a construct call
-		if( isDataType && (t.type == ttOpenParanthesis ||  // type()
-			               t.type == ttOpenBracket) )      // type[]()
-			node->AddChildLast(ParseConstructCall());
-		else if( isTemplateType && t.type == ttLessThan )  // type<t>()
-			node->AddChildLast(ParseConstructCall());
-		else if( IsFunctionCall() )
-			node->AddChildLast(ParseFunctionCall());
-		else
-			node->AddChildLast(ParseVariableAccess());
+			// Check if this is a construct call
+			if( isDataType && (t.type == ttOpenParanthesis ||  // type()
+							   (t.type == ttOpenBracket && t2.type == ttCloseBracket)) )      // type[]()
+				node->AddChildLast(ParseConstructCall());
+			else if( isTemplateType && t.type == ttLessThan )  // type<t>()
+				node->AddChildLast(ParseConstructCall());
+			else if( IsFunctionCall() )
+				node->AddChildLast(ParseFunctionCall());
+			else
+				node->AddChildLast(ParseVariableAccess());
+		}
 	}
 	else if( t1.type == ttCast )
 		node->AddChildLast(ParseCast());
@@ -1366,6 +1376,83 @@ asCScriptNode *asCParser::ParseConstant()
 	return node;
 }
 
+bool asCParser::IsLambda()
+{
+	bool isLambda = false;
+	sToken t;
+	GetToken(&t);
+	if( t.type == ttIdentifier && IdentifierIs(t, FUNCTION_TOKEN) )
+	{
+		sToken t2;
+		GetToken(&t2);
+		if( t2.type == ttOpenParanthesis )
+		{
+			// Skip until )
+			while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
+				GetToken(&t2);
+
+			// The next token must be a {
+			GetToken(&t2);
+			if( t2.type == ttStartStatementBlock )
+				isLambda = true;
+		}
+	}
+
+	RewindTo(&t);
+	return isLambda;
+}
+
+// BNF: LAMBDA ::= 'function' '(' [IDENTIFIER {',' IDENTIFIER}] ')' STATBLOCK
+asCScriptNode *asCParser::ParseLambda()
+{
+	asCScriptNode *node = CreateNode(snFunction);
+	if( node == 0 ) return 0;
+
+	sToken t;
+	GetToken(&t);
+
+	if( t.type != ttIdentifier || !IdentifierIs(t, FUNCTION_TOKEN) )
+	{
+		Error(ExpectedToken("function"), &t);
+		return node;
+	}
+
+	GetToken(&t);
+	if( t.type != ttOpenParanthesis )
+	{
+		Error(ExpectedToken("("), &t);
+		return node;
+	}
+
+	GetToken(&t);
+	if( t.type == ttIdentifier )
+	{
+		RewindTo(&t);
+		node->AddChildLast(ParseIdentifier());
+
+		GetToken(&t);
+		while( t.type == ttListSeparator )
+		{
+			node->AddChildLast(ParseIdentifier());
+			if( isSyntaxError ) return node;
+
+			GetToken(&t);
+		}
+	}
+
+	if( t.type != ttCloseParanthesis )
+	{
+		Error(ExpectedToken(")"), &t);
+		return node;
+	}
+
+	// We should just find the end of the statement block here. The statements 
+	// will be parsed on request by the compiler once it starts the compilation.
+	node->AddChildLast(SuperficiallyParseStatementBlock());
+
+	return node;
+}
+
 asCScriptNode *asCParser::ParseStringConstant()
 {
 	asCScriptNode *node = CreateNode(snConstant);
@@ -1629,7 +1716,7 @@ asCScriptNode *asCParser::ParseCondition()
 	return node;
 }
 
-// BNF: EXPR ::= (TYPE '=' INILIST) | (EXPRTERM {EXPROP EXPRTERM})
+// BNF: EXPR ::= (TYPE '=' INITLIST) | (EXPRTERM {EXPROP EXPRTERM})
 asCScriptNode *asCParser::ParseExpression()
 {
 	asCScriptNode *node = CreateNode(snExpression);
@@ -2470,7 +2557,22 @@ bool asCParser::IsVirtualPropertyDecl()
 	// as it may wrongly identify the statement as a non-declaration if the user typed
 	// the name incorrectly. The real type is validated in ParseDeclaration where a
 	// proper error message can be given.
-	if( !IsRealType(t1.type) && t1.type != ttIdentifier )
+	if( t1.type == ttScope )
+		GetToken(&t1);
+
+	if( t1.type == ttIdentifier )
+	{
+		sToken t2;
+		GetToken(&t2);
+		while( t1.type == ttIdentifier && t2.type == ttScope )
+		{
+			GetToken(&t1);
+			GetToken(&t2);
+		}
+
+		RewindTo(&t2);
+	}
+	else if( !IsRealType(t1.type) )
 	{
 		RewindTo(&t);
 		return false;
@@ -3212,61 +3314,37 @@ asCScriptNode *asCParser::SuperficiallyParseVarInit()
 	if( t.type == ttAssignment )
 	{
 		GetToken(&t);
-		if( t.type == ttStartStatementBlock )
-		{
-			sToken start = t;
+		sToken start = t;
 
-			// Find the end of the initialization list
-			int indent = 1;
-			while( indent )
+		// Find the end of the expression
+		int indentParan = 0;
+		int indentBrace = 0;
+		while( indentParan || indentBrace || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
+		{
+			if( t.type == ttOpenParanthesis )
+				indentParan++;
+			else if( t.type == ttCloseParanthesis )
+				indentParan--;
+			else if( t.type == ttStartStatementBlock )
+				indentBrace++;
+			else if( t.type == ttEndStatementBlock )
+				indentBrace--;
+			else if( t.type == ttNonTerminatedStringConstant )
 			{
-				GetToken(&t);
-				if( t.type == ttStartStatementBlock )
-					indent++;
-				else if( t.type == ttEndStatementBlock )
-					indent--;
-				else if( t.type == ttNonTerminatedStringConstant )
-				{
-					Error(TXT_NONTERMINATED_STRING, &t);
-					break;
-				}
-				else if( t.type == ttEnd )
-				{
-					Error(TXT_UNEXPECTED_END_OF_FILE, &t);
-					Info(TXT_WHILE_PARSING_INIT_LIST, &start);
-					break;
-				}
+				Error(TXT_NONTERMINATED_STRING, &t);
+				break;
 			}
-		}
-		else
-		{
-			sToken start = t;
-
-			// Find the end of the expression
-			int indent = 0;
-			while( indent || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
+			else if( t.type == ttEnd )
 			{
-				if( t.type == ttOpenParanthesis )
-					indent++;
-				else if( t.type == ttCloseParanthesis )
-					indent--;
-				else if( t.type == ttNonTerminatedStringConstant )
-				{
-					Error(TXT_NONTERMINATED_STRING, &t);
-					break;
-				}
-				else if( t.type == ttEnd )
-				{
-					Error(TXT_UNEXPECTED_END_OF_FILE, &t);
-					Info(TXT_WHILE_PARSING_EXPRESSION, &start);
-					break;
-				}
-				GetToken(&t);
+				Error(TXT_UNEXPECTED_END_OF_FILE, &t);
+				Info(TXT_WHILE_PARSING_EXPRESSION, &start);
+				break;
 			}
-
-			// Rewind so that the next token read is the list separator, end statement, or end statement block
-			RewindTo(&t);
+			GetToken(&t);
 		}
+
+		// Rewind so that the next token read is the list separator, end statement, or end statement block
+		RewindTo(&t);
 	}
 	else if( t.type == ttOpenParanthesis )
 	{
@@ -3883,7 +3961,7 @@ asCScriptNode *asCParser::ParseIf()
 	return node;
 }
 
-// BNF: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN] ')' STATEMENT
+// BNF: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN {',' ASSIGN}] ')' STATEMENT
 asCScriptNode *asCParser::ParseFor()
 {
 	asCScriptNode *node = CreateNode(snFor);
@@ -3922,18 +4000,27 @@ asCScriptNode *asCParser::ParseFor()
 	{
 		RewindTo(&t);
 
-		asCScriptNode *n = CreateNode(snExpressionStatement);
-		if( n == 0 ) return 0;
-		node->AddChildLast(n);
-		n->AddChildLast(ParseAssignment());
-		if( isSyntaxError ) return node;
-
-		GetToken(&t);
-		if( t.type != ttCloseParanthesis )
+		// Parse N increment statements separated by ,
+		for(;;)
 		{
-			Error(ExpectedToken(")"), &t);
-			Error(InsteadFound(t), &t);
-			return node;
+			asCScriptNode *n = CreateNode(snExpressionStatement);
+			if( n == 0 ) return 0;
+			node->AddChildLast(n);
+			n->AddChildLast(ParseAssignment());
+			if( isSyntaxError ) return node;
+
+			GetToken(&t);
+			if( t.type == ttListSeparator )
+				continue;
+			else if( t.type == ttCloseParanthesis )
+				break;
+			else
+			{
+				const char *tokens[] = {",", ")"};
+				Error(ExpectedOneOf(tokens, 2), &t);
+				Error(InsteadFound(t), &t);
+				return node;
+			}
 		}
 	}
 

+ 4 - 2
Source/ThirdParty/AngelScript/source/as_parser.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -133,6 +133,8 @@ protected:
 	bool IsVarDecl();
 	bool IsVirtualPropertyDecl();
 	bool IsFuncDecl(bool isMethod);
+	bool IsLambda();
+	bool IsFunctionCall();
 
 	// Expressions
 	asCScriptNode *ParseAssignment();
@@ -151,13 +153,13 @@ protected:
 	asCScriptNode *ParseCast();
 	asCScriptNode *ParseConstant();
 	asCScriptNode *ParseStringConstant();
+	asCScriptNode *ParseLambda();
 
 	bool IsConstant(int tokenType);
 	bool IsOperator(int tokenType);
 	bool IsPreOperator(int tokenType);
 	bool IsPostOperator(int tokenType);
 	bool IsAssignOperator(int tokenType);
-	bool IsFunctionCall();
 
 	bool CheckTemplateType(sToken &t);
 #endif

+ 419 - 162
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -40,6 +40,7 @@
 #include "as_bytecode.h"
 #include "as_scriptobject.h"
 #include "as_texts.h"
+#include "as_debug.h"
 
 BEGIN_AS_NAMESPACE
 
@@ -65,6 +66,8 @@ void asCReader::ReadData(void *data, asUINT size)
 
 int asCReader::Read(bool *wasDebugInfoStripped)
 {
+	TimeIt("asCReader::Read");
+
 	// Before starting the load, make sure that 
 	// any existing resources have been freed
 	module->InternalReset();
@@ -124,6 +127,8 @@ int asCReader::Error(const char *msg)
 
 int asCReader::ReadInner() 
 {
+	TimeIt("asCReader::ReadInner");
+
 	// This function will load each entity one by one from the stream.
 	// If any error occurs, it will return to the caller who is 
 	// responsible for cleaning up the partially loaded entities.
@@ -258,31 +263,38 @@ int asCReader::ReadInner()
 		asCScriptFunction *func = ReadFunction(isNew, false, true);
 		if( func )
 		{
+			func->module = module;
 			module->funcDefs.PushLast(func);
 			engine->funcDefs.PushLast(func);
 
 			// TODO: clean up: This is also done by the builder. It should probably be moved to a method in the module
 			// Check if there is another identical funcdef from another module and if so reuse that instead
-			for( asUINT n = 0; n < engine->funcDefs.GetLength(); n++ )
+			if( func->isShared )
 			{
-				asCScriptFunction *f2 = engine->funcDefs[n];
-				if( f2 == 0 || func == f2 )
-					continue;
-
-				if( f2->name == func->name &&
-					f2->nameSpace == func->nameSpace &&
-					f2->IsSignatureExceptNameEqual(func) )
+				for( asUINT n = 0; n < engine->funcDefs.GetLength(); n++ )
 				{
-					// Replace our funcdef for the existing one
-					module->funcDefs[module->funcDefs.IndexOf(func)] = f2;
-					f2->AddRefInternal();
+					asCScriptFunction *f2 = engine->funcDefs[n];
+					if( f2 == 0 || func == f2 )
+						continue;
 
-					engine->funcDefs.RemoveValue(func);
+					if( !f2->isShared )
+						continue;
 
-					savedFunctions[savedFunctions.IndexOf(func)] = f2;
+					if( f2->name == func->name &&
+						f2->nameSpace == func->nameSpace &&
+						f2->IsSignatureExceptNameEqual(func) )
+					{
+						// Replace our funcdef for the existing one
+						module->funcDefs[module->funcDefs.IndexOf(func)] = f2;
+						f2->AddRefInternal();
 
-					func->ReleaseInternal();
-					break;
+						engine->funcDefs.RemoveValue(func);
+
+						savedFunctions[savedFunctions.IndexOf(func)] = f2;
+
+						func->ReleaseInternal();
+						break;
+					}
 				}
 			}
 		}
@@ -549,6 +561,8 @@ int asCReader::ReadInner()
 
 void asCReader::ReadUsedStringConstants()
 {
+	TimeIt("asCReader::ReadUsedStringConstants");
+
 	asCString str;
 
 	asUINT count;
@@ -563,6 +577,8 @@ void asCReader::ReadUsedStringConstants()
 
 void asCReader::ReadUsedFunctions()
 {
+	TimeIt("asCReader::ReadUsedFunctions");
+
 	asUINT count;
 	count = ReadEncodedUInt();
 	usedFunctions.SetLength(count);
@@ -606,25 +622,44 @@ void asCReader::ReadUsedFunctions()
 					for( asUINT i = 0; i < module->bindInformations.GetLength(); i++ )
 					{
 						asCScriptFunction *f = module->bindInformations[i]->importedFunctionSignature;
-						if( !func.IsSignatureEqual(f) ||
-							func.objectType != f->objectType ||
+						if( func.objectType != f->objectType ||
 							func.funcType != f->funcType || 
-							func.nameSpace != f->nameSpace )
+							func.nameSpace != f->nameSpace ||
+							!func.IsSignatureEqual(f) )
 							continue;
 
 						usedFunctions[n] = f;
 						break;
 					}
 				}
+				else if( func.funcType == asFUNC_FUNCDEF )
+				{
+					const asCArray<asCScriptFunction *> &funcs = module->funcDefs;
+					for( asUINT i = 0; i < funcs.GetLength(); i++ )
+					{
+						asCScriptFunction *f = funcs[i];
+						if( f == 0 || func.name != f->name || !func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+							continue;
+
+						// Funcdefs are always global so there is no need to compare object type
+						asASSERT( f->objectType == 0 );
+
+						usedFunctions[n] = f;
+						break;
+					}
+				}
 				else
 				{
+					// TODO: optimize: Global functions should be searched for in module->globalFunctions
+					// TODO: optimize: funcdefs should be searched for in module->funcDefs
+					// TODO: optimize: object methods should be searched for directly in the object type
 					for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
 					{
 						asCScriptFunction *f = module->scriptFunctions[i];
-						if( !func.IsSignatureEqual(f) ||
-							func.objectType != f->objectType ||
+						if( func.objectType != f->objectType ||
 							func.funcType != f->funcType || 
-							func.nameSpace != f->nameSpace )
+							func.nameSpace != f->nameSpace ||
+							!func.IsSignatureEqual(f) )
 							continue;
 
 						usedFunctions[n] = f;
@@ -634,17 +669,157 @@ void asCReader::ReadUsedFunctions()
 			}
 			else
 			{
-				for( asUINT i = 0; i < engine->scriptFunctions.GetLength(); i++ )
+				if( func.funcType == asFUNC_FUNCDEF )
 				{
-					asCScriptFunction *f = engine->scriptFunctions[i];
-					if( f == 0 ||
-						!func.IsSignatureEqual(f) ||
-						func.objectType != f->objectType ||
-						func.nameSpace != f->nameSpace )
-						continue;
+					// This is a funcdef (registered or shared)
+					const asCArray<asCScriptFunction *> &funcs = engine->funcDefs;
+					for( asUINT i = 0; i < funcs.GetLength(); i++ )
+					{
+						asCScriptFunction *f = funcs[i];
+						if( f == 0 || func.name != f->name || !func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+							continue;
 
-					usedFunctions[n] = f;
-					break;
+						// Funcdefs are always global so there is no need to compare object type
+						asASSERT( f->objectType == 0 );
+
+						usedFunctions[n] = f;
+						break;
+					}
+				}
+				else if( func.name[0] == '$' )
+				{
+					// This is a special function
+
+					// Check for string factory
+					if( func.name == "$str" && engine->stringFactory &&
+						func.IsSignatureExceptNameAndObjectTypeEqual(engine->stringFactory) )
+						usedFunctions[n] = engine->stringFactory;
+					else if( func.name == "$beh0" && func.objectType )
+					{
+						// This is a class constructor, so we can search directly in the object type's constructors
+						for( asUINT i = 0; i < func.objectType->beh.constructors.GetLength(); i++ )
+						{
+							asCScriptFunction *f = engine->scriptFunctions[func.objectType->beh.constructors[i]];
+							if( f == 0 ||
+								!func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+								continue;
+
+							usedFunctions[n] = f;
+							break;
+						}
+					}
+					else if( func.name == "$fact" || func.name == "$beh3" )
+					{
+						// This is a factory (or stub), so look for the function in the return type's factories
+						asCObjectType *objType = func.returnType.GetObjectType();
+						if( objType )
+						{
+							for( asUINT i = 0; i < objType->beh.factories.GetLength(); i++ )
+							{
+								asCScriptFunction *f = engine->scriptFunctions[objType->beh.factories[i]];
+								if( f == 0 ||
+									!func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+									continue;
+
+								usedFunctions[n] = f;
+								break;
+							}
+						}
+					}
+					else if( func.name == "$list" )
+					{
+						// listFactory is used for both factory is global and returns a handle and constructor that is a method
+						asCObjectType *objType = func.objectType ? func.objectType : func.returnType.GetObjectType();
+						if( objType )
+						{
+							asCScriptFunction *f = engine->scriptFunctions[objType->beh.listFactory];
+							if( f && func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+								usedFunctions[n] = f;
+						}
+					}
+					else if( func.name == "$beh2" )
+					{
+						// This is a destructor, so check the object type's destructor
+						asCObjectType *objType = func.objectType;
+						if( objType )
+						{
+							asCScriptFunction *f = engine->scriptFunctions[objType->beh.destruct];
+							if( f && func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+								usedFunctions[n] = f;
+						}
+					}
+					else if( func.name == "$beh4" )
+					{
+						// This is a list factory, so check the return type's list factory
+						asCObjectType *objType = func.returnType.GetObjectType();
+						if( objType )
+						{
+							asCScriptFunction *f = engine->scriptFunctions[objType->beh.listFactory];
+							if( f && func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+								usedFunctions[n] = f;
+						}
+					}
+					else if( func.name == "$dlgte" )
+					{
+						// This is the delegate factory
+						asCScriptFunction *f = engine->registeredGlobalFuncs.GetFirst(engine->nameSpaces[0], DELEGATE_FACTORY);
+						asASSERT( f && func.IsSignatureEqual(f) );
+						usedFunctions[n] = f;
+					}
+				}
+				else if( func.objectType == 0 )
+				{
+					// This is a global function
+					const asCArray<asUINT> &funcs = engine->registeredGlobalFuncs.GetIndexes(func.nameSpace, func.name);
+					for( asUINT i = 0; i < funcs.GetLength(); i++ )
+					{
+						asCScriptFunction *f = engine->registeredGlobalFuncs.Get(funcs[i]);
+						if( f == 0 ||
+							!func.IsSignatureExceptNameAndObjectTypeEqual(f) )
+							continue;
+
+						usedFunctions[n] = f;
+						break;
+					}
+				}
+				else if( func.objectType )
+				{
+					// It is a class member, so we can search directly in the object type's members
+					// TODO: virtual function is different that implemented method
+					for( asUINT i = 0; i < func.objectType->methods.GetLength(); i++ )
+					{
+						asCScriptFunction *f = engine->scriptFunctions[func.objectType->methods[i]];
+						if( f == 0 ||
+							!func.IsSignatureEqual(f) )
+							continue;
+
+						usedFunctions[n] = f;
+						break;
+					}
+				}
+
+				if( usedFunctions[n] == 0 )
+				{
+					// TODO: clean up: This part of the code should never happen. All functions should 
+					//                 be found in the above logic. The only valid reason to come here 
+					//                 is if the bytecode is wrong and the function doesn't exist anyway.
+					//                 This loop is kept temporarily until we can be certain all scenarios 
+					//                 are covered.
+					for( asUINT i = 0; i < engine->scriptFunctions.GetLength(); i++ )
+					{
+						asCScriptFunction *f = engine->scriptFunctions[i];
+						if( f == 0 ||
+							func.objectType != f->objectType ||
+							func.nameSpace != f->nameSpace ||
+							!func.IsSignatureEqual(f) )
+							continue;
+
+						usedFunctions[n] = f;
+						break;
+					}
+
+					// No function is expected to be found
+					asASSERT(usedFunctions[n] == 0);
 				}
 			}
 
@@ -973,6 +1148,13 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	{
 		func->vfTableIdx = ReadEncodedUInt();
 	}
+	else if( func->funcType == asFUNC_FUNCDEF )
+	{
+		asBYTE bits;
+		ReadData(&bits, 1);
+		if( bits )
+			func->isShared = true;
+	}
 
 	if( addToModule )
 	{
@@ -1520,28 +1702,25 @@ asQWORD asCReader::ReadEncodedUInt64()
 
 void asCReader::ReadString(asCString* str) 
 {
-	char b;
-	ReadData(&b, 1);
-	if( b == '\0' )
+	asUINT len = ReadEncodedUInt();
+	if( len & 1 )
 	{
-		str->SetLength(0);
+		asUINT idx = len/2;
+		if( idx < savedStrings.GetLength() )
+			*str = savedStrings[idx];
+		else
+			Error(TXT_INVALID_BYTECODE_d);
 	}
-	else if( b == 'n' )
+	else if( len > 0 )
 	{
-		asUINT len = ReadEncodedUInt();
+		len /= 2;
 		str->SetLength(len);
 		stream->Read(str->AddressOf(), len);
 
 		savedStrings.PushLast(*str);
 	}
 	else
-	{
-		asUINT n = ReadEncodedUInt();
-		if( n < savedStrings.GetLength() )
-			*str = savedStrings[n];
-		else
-			Error(TXT_INVALID_BYTECODE_d);
-	}
+		str->SetLength(0);
 }
 
 void asCReader::ReadGlobalProperty() 
@@ -1625,7 +1804,7 @@ void asCReader::ReadDataType(asCDataType *dt)
 	ReadData(&bits, 1);
 
 	asCScriptFunction *funcDef = 0;
-	if( tokenType == ttIdentifier && objType && objType->name == "_builtin_function_" )
+	if( tokenType == ttIdentifier && objType && objType->name == "$func" )
 	{
 		asCScriptFunction func(engine, module, asFUNC_DUMMY);
 		ReadFunctionSignature(&func);
@@ -1790,7 +1969,7 @@ asCObjectType* asCReader::ReadObjectType()
 		ReadString(&ns);
 		asSNameSpace *nameSpace = engine->AddNameSpace(ns.AddressOf());
 
-		if( typeName.GetLength() && typeName != "_builtin_object_" && typeName != "_builtin_function_" )
+		if( typeName.GetLength() && typeName != "$obj" && typeName != "$func" )
 		{
 			// Find the object type
 			ot = module->GetObjectType(typeName.AddressOf(), nameSpace);
@@ -1806,11 +1985,11 @@ asCObjectType* asCReader::ReadObjectType()
 				return 0;
 			}
 		}
-		else if( typeName == "_builtin_object_" )
+		else if( typeName == "$obj" )
 		{
 			ot = &engine->scriptTypeBehaviours;
 		}
-		else if( typeName == "_builtin_function_" )
+		else if( typeName == "$func" )
 		{
 			ot = &engine->functionBehaviours;
 		}
@@ -2073,6 +2252,8 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
 
 void asCReader::ReadUsedTypeIds()
 {
+	TimeIt("asCReader::ReadUsedTypeIds");
+
 	asUINT count = ReadEncodedUInt();
 	usedTypeIds.Allocate(count, false);
 	for( asUINT n = 0; n < count; n++ )
@@ -2085,6 +2266,8 @@ void asCReader::ReadUsedTypeIds()
 
 void asCReader::ReadUsedGlobalProps()
 {
+	TimeIt("asCReader::ReadUsedGlobalProps");
+
 	int c = ReadEncodedUInt();
 
 	usedGlobalProperties.Allocate(c, false);
@@ -2124,6 +2307,8 @@ void asCReader::ReadUsedGlobalProps()
 
 void asCReader::ReadUsedObjectProps()
 {
+	TimeIt("asCReader::ReadUsedObjectProps");
+
 	asUINT c = ReadEncodedUInt();
 
 	usedObjectProperties.SetLength(c);
@@ -3088,6 +3273,7 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 
 	// Find out which function that will be called
 	asCScriptFunction *calledFunc = 0;
+	int stackDelta = 0;
 	for( asUINT n = programPos; func->scriptData->byteCode.GetLength(); )
 	{
 		asBYTE bc = *(asBYTE*)&func->scriptData->byteCode[n];
@@ -3110,6 +3296,10 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 			return offset - (1 - AS_PTR_SIZE);
 		}
 
+		// Keep track of the stack size between the 
+		// instruction that needs to be adjusted and the call
+		stackDelta += asBCInfo[bc].stackInc;
+
 		n += asBCTypeSize[asBCInfo[bc].type];
 	}
 
@@ -3122,16 +3312,30 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 	// Count the number of pointers pushed on the stack above the 
 	// current offset, and then adjust the offset accordingly
 	asUINT numPtrs = 0;
-	int currOffset = 0;
+	int currOffset = -stackDelta;
 	if( offset > currOffset && calledFunc->GetObjectType() )
 	{
-		numPtrs++;
 		currOffset++;
+		if( currOffset > 0 )
+			numPtrs++;
+#if AS_PTR_SIZE == 2
+		// For 64bit platforms it is necessary to increment the currOffset by one more 
+		// DWORD since the stackDelta was counting the full 64bit size of the pointer
+		else if( stackDelta )
+			currOffset++;
+#endif
 	}
 	if( offset > currOffset && calledFunc->DoesReturnOnStack() )
 	{
-		numPtrs++;
 		currOffset++;
+		if( currOffset > 0 )
+			numPtrs++;
+#if AS_PTR_SIZE == 2
+		// For 64bit platforms it is necessary to increment the currOffset by one more 
+		// DWORD since the stackDelta was counting the full 64bit size of the pointer
+		else if( stackDelta )
+			currOffset++;
+#endif
 	}
 	for( asUINT p = 0; p < calledFunc->parameterTypes.GetLength(); p++ )
 	{
@@ -3140,8 +3344,15 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 		if( !calledFunc->parameterTypes[p].IsPrimitive() ||
 			calledFunc->parameterTypes[p].IsReference() )
 		{
-			numPtrs++;
 			currOffset++;
+			if( currOffset > 0 )
+				numPtrs++;
+#if AS_PTR_SIZE == 2
+			// For 64bit platforms it is necessary to increment the currOffset by one more 
+			// DWORD since the stackDelta was counting the full 64bit size of the pointer
+			else if( stackDelta )
+				currOffset++;
+#endif
 
 			// The variable arg ? has an additiona 32bit integer with the typeid
 			if( calledFunc->parameterTypes[p].IsAnyType() )
@@ -3201,6 +3412,8 @@ void asCWriter::WriteData(const void *data, asUINT size)
 
 int asCWriter::Write() 
 {
+	TimeIt("asCWriter::Write");
+
 	unsigned long i, count;
 
 	// Store everything in the same order that the builder parses scripts
@@ -3211,101 +3424,149 @@ int asCWriter::Write()
 	WriteData(&stripDebugInfo, sizeof(stripDebugInfo));
 
 	// Store enums
-	count = (asUINT)module->enumTypes.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; i++ )
 	{
-		WriteObjectTypeDeclaration(module->enumTypes[i], 1);
-		WriteObjectTypeDeclaration(module->enumTypes[i], 2);
+		TimeIt("store enums");
+
+		count = (asUINT)module->enumTypes.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; i++ )
+		{
+			WriteObjectTypeDeclaration(module->enumTypes[i], 1);
+			WriteObjectTypeDeclaration(module->enumTypes[i], 2);
+		}
 	}
 
 	// Store type declarations first
-	count = (asUINT)module->classTypes.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; i++ )
 	{
-		// Store only the name of the class/interface types
-		WriteObjectTypeDeclaration(module->classTypes[i], 1);
+		TimeIt("type declarations");
+
+		count = (asUINT)module->classTypes.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; i++ )
+		{
+			// Store only the name of the class/interface types
+			WriteObjectTypeDeclaration(module->classTypes[i], 1);
+		}
 	}
 
 	// Store func defs
-	count = (asUINT)module->funcDefs.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; i++ )
-		WriteFunction(module->funcDefs[i]);
+	{
+		TimeIt("func defs");
+
+		count = (asUINT)module->funcDefs.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; i++ )
+			WriteFunction(module->funcDefs[i]);
+	}
 
 	// Now store all interface methods
-	count = (asUINT)module->classTypes.GetLength();
-	for( i = 0; i < count; i++ )
 	{
-		if( module->classTypes[i]->IsInterface() )
-			WriteObjectTypeDeclaration(module->classTypes[i], 2);
+		TimeIt("interface methods");
+
+		count = (asUINT)module->classTypes.GetLength();
+		for( i = 0; i < count; i++ )
+		{
+			if( module->classTypes[i]->IsInterface() )
+				WriteObjectTypeDeclaration(module->classTypes[i], 2);
+		}
 	}
 
 	// Then store the class methods and behaviours
-	for( i = 0; i < count; ++i )
 	{
-		if( !module->classTypes[i]->IsInterface() )
-			WriteObjectTypeDeclaration(module->classTypes[i], 2);
+		TimeIt("class methods and behaviours");
+
+		for( i = 0; i < count; ++i )
+		{
+			if( !module->classTypes[i]->IsInterface() )
+				WriteObjectTypeDeclaration(module->classTypes[i], 2);
+		}
 	}
 
 	// Then store the class properties
-	for( i = 0; i < count; ++i )
 	{
-		if( !module->classTypes[i]->IsInterface() )
-			WriteObjectTypeDeclaration(module->classTypes[i], 3);
+		TimeIt("class properties");
+
+		for( i = 0; i < count; ++i )
+		{
+			if( !module->classTypes[i]->IsInterface() )
+				WriteObjectTypeDeclaration(module->classTypes[i], 3);
+		}
 	}
 
 	// Store typedefs
-	count = (asUINT)module->typeDefs.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; i++ )
 	{
-		WriteObjectTypeDeclaration(module->typeDefs[i], 1);
-		WriteObjectTypeDeclaration(module->typeDefs[i], 2);
+		TimeIt("type defs");
+
+		count = (asUINT)module->typeDefs.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; i++ )
+		{
+			WriteObjectTypeDeclaration(module->typeDefs[i], 1);
+			WriteObjectTypeDeclaration(module->typeDefs[i], 2);
+		}
 	}
 
 	// scriptGlobals[]
-	count = (asUINT)module->scriptGlobals.GetSize();
-	WriteEncodedInt64(count);
-	asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
-	for( ; it; it++ )
-		WriteGlobalProperty(*it);
+	{
+		TimeIt("script globals");
+
+		count = (asUINT)module->scriptGlobals.GetSize();
+		WriteEncodedInt64(count);
+		asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
+		for( ; it; it++ )
+			WriteGlobalProperty(*it);
+	}
 
 	// scriptFunctions[]
-	count = 0;
-	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-		if( module->scriptFunctions[i]->objectType == 0 )
-			count++;
-	WriteEncodedInt64(count);
-	for( i = 0; i < module->scriptFunctions.GetLength(); ++i )
-		if( module->scriptFunctions[i]->objectType == 0 )
-			WriteFunction(module->scriptFunctions[i]);
+	{
+		TimeIt("scriptFunctions");
+
+		count = 0;
+		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
+			if( module->scriptFunctions[i]->objectType == 0 )
+				count++;
+		WriteEncodedInt64(count);
+		for( i = 0; i < module->scriptFunctions.GetLength(); ++i )
+			if( module->scriptFunctions[i]->objectType == 0 )
+				WriteFunction(module->scriptFunctions[i]);
+	}
 
 	// globalFunctions[]
-	count = (int)module->globalFunctions.GetSize();
-	asCSymbolTable<asCScriptFunction>::iterator funcIt = module->globalFunctions.List();
-	WriteEncodedInt64(count);
-	while( funcIt )
 	{
-		WriteFunction(*funcIt);
-		funcIt++;
+		TimeIt("globalFunctions");
+
+		count = (int)module->globalFunctions.GetSize();
+		asCSymbolTable<asCScriptFunction>::iterator funcIt = module->globalFunctions.List();
+		WriteEncodedInt64(count);
+		while( funcIt )
+		{
+			WriteFunction(*funcIt);
+			funcIt++;
+		}
 	}
 
 	// bindInformations[]
-	count = (asUINT)module->bindInformations.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; ++i )
 	{
-		WriteFunction(module->bindInformations[i]->importedFunctionSignature);
-		WriteString(&module->bindInformations[i]->importFromModule);
+		TimeIt("bindInformations");
+
+		count = (asUINT)module->bindInformations.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; ++i )
+		{
+			WriteFunction(module->bindInformations[i]->importedFunctionSignature);
+			WriteString(&module->bindInformations[i]->importFromModule);
+		}
 	}
 
 	// usedTypes[]
-	count = (asUINT)usedTypes.GetLength();
-	WriteEncodedInt64(count);
-	for( i = 0; i < count; ++i )
-		WriteObjectType(usedTypes[i]);
+	{
+		TimeIt("usedTypes");
+
+		count = (asUINT)usedTypes.GetLength();
+		WriteEncodedInt64(count);
+		for( i = 0; i < count; ++i )
+			WriteObjectType(usedTypes[i]);
+	}
 
 	// usedTypeIds[]
 	WriteUsedTypeIds();
@@ -3339,6 +3600,8 @@ int asCWriter::FindStringConstantIndex(int id)
 
 void asCWriter::WriteUsedStringConstants()
 {
+	TimeIt("asCWriter::WriteUsedStringConstants");
+
 	asUINT count = (asUINT)usedStringConstants.GetLength();
 	WriteEncodedInt64(count);
 	for( asUINT i = 0; i < count; ++i )
@@ -3347,6 +3610,8 @@ void asCWriter::WriteUsedStringConstants()
 
 void asCWriter::WriteUsedFunctions()
 {
+	TimeIt("asCWriter::WriteUsedFunctions");
+
 	asUINT count = (asUINT)usedFunctions.GetLength();
 	WriteEncodedInt64(count);
 
@@ -3576,6 +3841,12 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 		// TODO: Do we really need to store this? It can probably be reconstructed by the reader
 		WriteEncodedInt64(func->vfTableIdx);
 	}
+	else if( func->funcType == asFUNC_FUNCDEF )
+	{
+		char bits = 0;
+		bits += func->isShared ? 1 : 0;
+		WriteData(&bits,1);
+	}
 }
 
 void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
@@ -3759,39 +4030,28 @@ void asCWriter::WriteEncodedInt64(asINT64 i)
 
 void asCWriter::WriteString(asCString* str) 
 {
-	// TODO: All strings should be stored in a separate section, and when
-	//       they are used an offset into that section should be stored.
-	//       This will make it unnecessary to store the extra byte to 
-	//       identify new versus old strings.
-
-	if( str->GetLength() == 0 )
-	{
-		char z = '\0';
-		WriteData(&z, 1);
-		return;
-	}
-
 	// First check if the string hasn't been saved already
 	asSMapNode<asCStringPointer, int> *cursor = 0;
 	if (stringToIdMap.MoveTo(&cursor, asCStringPointer(str)))
 	{
 		// Save a reference to the existing string
-		char b = 'r';
-		WriteData(&b, 1);
-		WriteEncodedInt64(cursor->value);
+		// The lowest bit is set to 1 to indicate a reference
+		WriteEncodedInt64(cursor->value*2+1);
 		return;
 	}
 
 	// Save a new string
-	char b = 'n';
-	WriteData(&b, 1);
-
+	// The lowest bit is set to 0 to indicate a new string
 	asUINT len = (asUINT)str->GetLength();
-	WriteEncodedInt64(len);
-	stream->Write(str->AddressOf(), (asUINT)len);
+	WriteEncodedInt64(len*2);
+
+	if( len > 0 )
+	{
+		stream->Write(str->AddressOf(), (asUINT)len);
 
-	savedStrings.PushLast(*str);
-	stringToIdMap.Insert(asCStringPointer(str), int(savedStrings.GetLength()) - 1);
+		savedStrings.PushLast(*str);
+		stringToIdMap.Insert(asCStringPointer(str), int(savedStrings.GetLength()) - 1);
+	}
 }
 
 void asCWriter::WriteGlobalProperty(asCGlobalProperty* prop) 
@@ -3855,7 +4115,7 @@ void asCWriter::WriteDataType(const asCDataType *dt)
 	bits.isReadOnly      = dt->IsReadOnly();
 	WriteData(&bits, 1);
 
-	if( t == ttIdentifier && dt->GetObjectType()->name == "_builtin_function_" )
+	if( t == ttIdentifier && dt->GetObjectType()->name == "$func" )
 	{
 		WriteFunctionSignature(dt->GetFuncDef());
 	}
@@ -3887,17 +4147,17 @@ void asCWriter::WriteObjectType(asCObjectType* ot)
 				WriteEncodedInt64(ot->templateSubTypes.GetLength());
 				for( asUINT n = 0; n < ot->templateSubTypes.GetLength(); n++ )
 				{
-					if( ot->templateSubTypes[0].IsObject() || ot->templateSubTypes[0].IsEnumType() )
+					if( ot->templateSubTypes[n].IsObject() || ot->templateSubTypes[n].IsEnumType() )
 					{
 						ch = 's';
 						WriteData(&ch, 1);
-						WriteDataType(&ot->templateSubTypes[0]);
+						WriteDataType(&ot->templateSubTypes[n]);
 					}
 					else
 					{
 						ch = 't';
 						WriteData(&ch, 1);
-						eTokenType t = ot->templateSubTypes[0].GetTokenType();
+						eTokenType t = ot->templateSubTypes[n].GetTokenType();
 						WriteEncodedInt64(t);
 					}
 				}
@@ -4057,6 +4317,7 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 
 	// Find out which function that will be called
 	asCScriptFunction *calledFunc = 0;
+	int stackDelta = 0;
 	for( asUINT n = programPos; n < func->scriptData->byteCode.GetLength(); )
 	{
 		asBYTE bc = *(asBYTE*)&func->scriptData->byteCode[n];
@@ -4125,6 +4386,10 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 			return offset + (1 - AS_PTR_SIZE);
 		}
 
+		// Keep track of the stack size between the 
+		// instruction that needs to be adjusted and the call
+		stackDelta += asBCInfo[bc].stackInc;
+
 		n += asBCTypeSize[asBCInfo[bc].type];
 	}
 
@@ -4133,16 +4398,18 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 	// Count the number of pointers pushed on the stack above the 
 	// current offset, and then adjust the offset accordingly
 	asUINT numPtrs = 0;
-	int currOffset = 0;
+	int currOffset = -stackDelta;
 	if( offset > currOffset && calledFunc->GetObjectType() )
 	{
-		numPtrs++;
 		currOffset += AS_PTR_SIZE;
+		if( currOffset > 0 )
+			numPtrs++;
 	}
 	if( offset > currOffset && calledFunc->DoesReturnOnStack() )
 	{
-		numPtrs++;
 		currOffset += AS_PTR_SIZE;
+		if( currOffset > 0 )
+			numPtrs++;
 	}
 	for( asUINT p = 0; p < calledFunc->parameterTypes.GetLength(); p++ )
 	{
@@ -4152,8 +4419,9 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 			calledFunc->parameterTypes[p].IsReference() )
 		{
 			// objects and references are passed by pointer
-			numPtrs++;
 			currOffset += AS_PTR_SIZE;
+			if( currOffset > 0 )
+				numPtrs++;
 
 			// The variable arg ? has an additional 32bit int with the typeid
 			if( calledFunc->parameterTypes[p].IsAnyType() )
@@ -4778,6 +5046,8 @@ void asCWriter::SListAdjuster::SetNextType(int typeId)
 
 void asCWriter::WriteUsedTypeIds()
 {
+	TimeIt("asCWriter::WriteUsedTypeIds");
+
 	asUINT count = (asUINT)usedTypeIds.GetLength();
 	WriteEncodedInt64(count);
 	for( asUINT n = 0; n < count; n++ )
@@ -4798,6 +5068,8 @@ int asCWriter::FindGlobalPropPtrIndex(void *ptr)
 
 void asCWriter::WriteUsedGlobalProps()
 {
+	TimeIt("asCWriter::WriteUsedGlobalProps");
+	
 	int c = (int)usedGlobalProperties.GetLength();
 	WriteEncodedInt64(c);
 
@@ -4805,32 +5077,12 @@ void asCWriter::WriteUsedGlobalProps()
 	{
 		asPWORD *p = (asPWORD*)usedGlobalProperties[n];
 		
-		// First search for the global in the module
-		char moduleProp = 0;
+		// Find the property descriptor from the address
 		asCGlobalProperty *prop = 0;
-		asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
-		for( ; it; it++ )
-		{
-			if( p == (*it)->GetAddressOfValue() )
-			{
-				prop = (*it);
-				moduleProp = 1;
-				break;
-			}
-		}
-
-		// If it is not in the module, it must be an application registered property
-		if( !prop )
+		asSMapNode<void*, asCGlobalProperty*> *cursor;
+		if( engine->varAddressMap.MoveTo(&cursor, p) )
 		{
-			asCSymbolTable<asCGlobalProperty>::iterator it = engine->registeredGlobalProps.List();
-			for( ; it; it++ )
-			{
-				if( it->GetAddressOfValue() == p )
-				{
-					prop = *it;
-					break;
-				}
-			}
+			prop = engine->varAddressMap.GetValue(cursor);
 		}
 
 		asASSERT(prop);
@@ -4841,12 +5093,17 @@ void asCWriter::WriteUsedGlobalProps()
 		WriteDataType(&prop->type);
 
 		// Also store whether the property is a module property or a registered property
+		char moduleProp = 0;
+		if( prop->realAddress == 0 )
+			moduleProp = 1;
 		WriteData(&moduleProp, 1);
 	}
 }
 
 void asCWriter::WriteUsedObjectProps()
 {
+	TimeIt("asCWriter::WriteUsedObjectProps");
+
 	int c = (int)usedObjectProperties.GetLength();
 	WriteEncodedInt64(c);
 

+ 159 - 86
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -118,6 +118,9 @@ AS_API const char * asGetLibraryOptions()
 #ifdef WIP_16BYTE_ALIGN
 		"WIP_16BYTE_ALIGN "
 #endif
+#ifdef AS_BIG_ENDIAN
+		"AS_BIG_ENDIAN "
+#endif
 
 	// Target system
 #ifdef AS_WIN
@@ -584,21 +587,22 @@ asCScriptEngine::asCScriptEngine()
 	// Reserve function id 0 for no function
 	scriptFunctions.PushLast(0);
 
+	// Reserve the first typeIds for the primitive types
+	typeIdSeqNbr = asTYPEID_DOUBLE + 1;
+
 	// Make sure typeId for the built-in primitives are defined according to asETypeIdFlags
-	int id = 0;
-	UNUSED_VAR(id); // It is only used in debug mode
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttVoid,   false)); asASSERT( id == asTYPEID_VOID   );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttBool,   false)); asASSERT( id == asTYPEID_BOOL   );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt8,   false)); asASSERT( id == asTYPEID_INT8   );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt16,  false)); asASSERT( id == asTYPEID_INT16  );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt,    false)); asASSERT( id == asTYPEID_INT32  );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt64,  false)); asASSERT( id == asTYPEID_INT64  );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt8,  false)); asASSERT( id == asTYPEID_UINT8  );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt16, false)); asASSERT( id == asTYPEID_UINT16 );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt,   false)); asASSERT( id == asTYPEID_UINT32 );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt64, false)); asASSERT( id == asTYPEID_UINT64 );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttFloat,  false)); asASSERT( id == asTYPEID_FLOAT  );
-	id = GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttDouble, false)); asASSERT( id == asTYPEID_DOUBLE );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttVoid,   false)) == asTYPEID_VOID   );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttBool,   false)) == asTYPEID_BOOL   );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt8,   false)) == asTYPEID_INT8   );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt16,  false)) == asTYPEID_INT16  );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt,    false)) == asTYPEID_INT32  );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttInt64,  false)) == asTYPEID_INT64  );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt8,  false)) == asTYPEID_UINT8  );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt16, false)) == asTYPEID_UINT16 );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt,   false)) == asTYPEID_UINT32 );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttUInt64, false)) == asTYPEID_UINT64 );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttFloat,  false)) == asTYPEID_FLOAT  );
+	asASSERT( GetTypeIdFromDataType(asCDataType::CreatePrimitive(ttDouble, false)) == asTYPEID_DOUBLE );
 
 	defaultArrayObjectType = 0;
 
@@ -608,9 +612,9 @@ asCScriptEngine::asCScriptEngine()
 
 void asCScriptEngine::DeleteDiscardedModules()
 {
-	// TODO: 2.30.0: redesign: Prevent more than one thread from entering this function at the same time. 
-	//                         If a thread is already doing the work for the clean-up the other thread should
-	//                         simply return, as the first thread will continue.
+	// TODO: redesign: Prevent more than one thread from entering this function at the same time. 
+	//                 If a thread is already doing the work for the clean-up the other thread should
+	//                 simply return, as the first thread will continue.
 
 	ACQUIRESHARED(engineRWLock);
 	asUINT maxCount = discardedModules.GetLength();
@@ -646,7 +650,7 @@ void asCScriptEngine::DeleteDiscardedModules()
 
 asCScriptEngine::~asCScriptEngine()
 {
-	// TODO: 2.30.0: redesign: Clean up redundant code
+	// TODO: clean-up: Clean up redundant code
 
 	asUINT n = 0;
 	inDestructor = true;
@@ -690,12 +694,8 @@ asCScriptEngine::~asCScriptEngine()
 	if( refCount.get() > 0 )
 		WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_ENGINE_REF_COUNT_ERROR_DURING_SHUTDOWN);
 
-	asSMapNode<int,asCDataType*> *cursor = 0;
-	while( mapTypeIdToDataType.MoveFirst(&cursor) )
-	{
-		asDELETE(mapTypeIdToDataType.GetValue(cursor),asCDataType);
-		mapTypeIdToDataType.Erase(cursor);
-	}
+	mapTypeIdToObjectType.EraseAll();
+	mapTypeIdToFunction.EraseAll();
 
 	// First remove what is not used, so that other groups can be deleted safely
 	defaultGroup.RemoveConfiguration(this, true);
@@ -1976,7 +1976,7 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 			listPattern->Destroy(this);
 		return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 	}
-	func.name.Format("_beh_%d_", behaviour);
+	func.name.Format("$beh%d", behaviour);
 
 	if( behaviour != asBEHAVE_FACTORY && behaviour != asBEHAVE_LIST_FACTORY )
 	{
@@ -3229,7 +3229,7 @@ int asCScriptEngine::RegisterStringFactory(const char *datatype, const asSFuncPt
 		return ConfigError(asOUT_OF_MEMORY, "RegisterStringFactory", datatype, 0);
 	}
 
-	func->name        = "_string_factory_";
+	func->name        = "$str";
 	func->sysFuncIntf = newInterface;
 
 	asCBuilder bld(this, 0);
@@ -3590,6 +3590,9 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	if( templateType->beh.listFactory )
 	{
 		asCScriptFunction *func = GenerateTemplateFactoryStub(templateType, ot, templateType->beh.listFactory);
+		
+		// Rename the function to easily identify it in LoadByteCode
+		func->name = "$list";
 
 		ot->beh.listFactory = func->id;
 	}
@@ -3787,7 +3790,7 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
 
 	func->funcType         = asFUNC_SCRIPT;
 	func->AllocateScriptFunctionData();
-	func->name             = "factstub";
+	func->name             = "$fact";
 	func->id               = GetNextScriptFunctionId();
 	AddScriptFunction(func);
 
@@ -4269,8 +4272,7 @@ void *asCScriptEngine::CallObjectMethodRetPtr(void *obj, int param1, asCScriptFu
 #endif
 	if( i->callConv == ICC_GENERIC_METHOD )
 	{
-		asASSERT(false); // TODO: Implement this
-		asCGeneric gen(const_cast<asCScriptEngine*>(this), func, obj, 0);
+		asCGeneric gen(const_cast<asCScriptEngine*>(this), func, obj, reinterpret_cast<asDWORD*>(&param1));
 		void (*f)(asIScriptGeneric *) = (void (*)(asIScriptGeneric *))(i->func);
 		f(&gen);
 		return *(void **)gen.GetReturnPointer();
@@ -4553,82 +4555,154 @@ void asCScriptEngine::GCEnumCallback(void *reference)
 }
 
 
-// TODO: multithread: The mapTypeIdToDataType must be protected with critical sections in all functions that access it
 int asCScriptEngine::GetTypeIdFromDataType(const asCDataType &dtIn) const
 {
-	if( dtIn.IsNullHandle() ) return 0;
+	if( dtIn.IsNullHandle() ) return asTYPEID_VOID;
 
-	// Register the base form
-	asCDataType dt(dtIn);
-	if( dt.GetObjectType() )
-		dt.MakeHandle(false);
+	if( dtIn.GetObjectType() == 0 )
+	{
+		// Primitives have pre-fixed typeIds
+		switch( dtIn.GetTokenType() )
+		{
+		case ttVoid:   return asTYPEID_VOID;
+		case ttBool:   return asTYPEID_BOOL;
+		case ttInt8:   return asTYPEID_INT8;
+		case ttInt16:  return asTYPEID_INT16;
+		case ttInt:    return asTYPEID_INT32;
+		case ttInt64:  return asTYPEID_INT64;
+		case ttUInt8:  return asTYPEID_UINT8;
+		case ttUInt16: return asTYPEID_UINT16;
+		case ttUInt:   return asTYPEID_UINT32;
+		case ttUInt64: return asTYPEID_UINT64;
+		case ttFloat:  return asTYPEID_FLOAT;
+		case ttDouble: return asTYPEID_DOUBLE;
+		default:
+			// All types should be covered by the above. The variable type is not really a type
+			asASSERT(dtIn.GetTokenType() == ttQuestion);
+			return -1;
+		}
+	}
 
-	// Find the existing type id
-	asSMapNode<int,asCDataType*> *cursor = 0;
-	mapTypeIdToDataType.MoveFirst(&cursor);
-	while( cursor )
+	int typeId = -1;
+	asCObjectType *ot = dtIn.GetObjectType();
+	if( ot != &functionBehaviours )
 	{
-		if( mapTypeIdToDataType.GetValue(cursor)->IsEqualExceptRefAndConst(dt) )
+		// Object's hold the typeId themselves
+		typeId = ot->typeId;
+
+		if( typeId == -1 )
 		{
-			int typeId = mapTypeIdToDataType.GetKey(cursor);
-			if( dtIn.GetObjectType() && !(dtIn.GetObjectType()->flags & asOBJ_ASHANDLE) )
+			ACQUIREEXCLUSIVE(engineRWLock);
+			// Make sure another thread didn't determine the typeId while we were waiting for the lock
+			if( ot->typeId == -1 )
 			{
-				// The ASHANDLE types behave like handles, but are really
-				// value types so the typeId is never returned as a handle
-				if( dtIn.IsObjectHandle() )
-					typeId |= asTYPEID_OBJHANDLE;
-				if( dtIn.IsHandleToConst() )
-					typeId |= asTYPEID_HANDLETOCONST;
-			}
+				typeId = typeIdSeqNbr++;
+				if( ot->flags & asOBJ_SCRIPT_OBJECT ) typeId |= asTYPEID_SCRIPTOBJECT;
+				else if( ot->flags & asOBJ_TEMPLATE ) typeId |= asTYPEID_TEMPLATE;
+				else if( ot->flags & asOBJ_ENUM ) {} // TODO: Should we have a specific bit for this?
+				else typeId |= asTYPEID_APPOBJECT;
 
-			return typeId;
-		}
+				ot->typeId = typeId;
 
-		mapTypeIdToDataType.MoveNext(&cursor, cursor);
+				mapTypeIdToObjectType.Insert(typeId, ot);
+			}
+			RELEASEEXCLUSIVE(engineRWLock);
+		}
 	}
+	else
+	{
+		// This a funcdef, so we'll need to look in the map for the funcdef
 
-	// The type id doesn't exist, create it
+		// TODO: optimize: It shouldn't be necessary to exclusive lock when the typeId already exists
+		ACQUIREEXCLUSIVE(engineRWLock);
 
-	// Setup the basic type id
-	int typeId = typeIdSeqNbr++;
-	if( dt.GetObjectType() )
-	{
-		if( dt.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT ) typeId |= asTYPEID_SCRIPTOBJECT;
-		else if( dt.GetObjectType()->flags & asOBJ_TEMPLATE ) typeId |= asTYPEID_TEMPLATE;
-		else if( dt.GetObjectType()->flags & asOBJ_ENUM ) {} // TODO: Should we have a specific bit for this?
-		else typeId |= asTYPEID_APPOBJECT;
+		// Find the existing type id
+		asCScriptFunction *func = dtIn.GetFuncDef();
+		asASSERT(func);
+		asSMapNode<int,asCScriptFunction*> *cursor = 0;
+		mapTypeIdToFunction.MoveFirst(&cursor);
+		while( cursor )
+		{
+			if( mapTypeIdToFunction.GetValue(cursor) == func )
+			{
+				typeId = mapTypeIdToFunction.GetKey(cursor);
+				break;
+			}
+
+			mapTypeIdToFunction.MoveNext(&cursor, cursor);
+		}
+
+		// The type id doesn't exist, create it
+		if( typeId == -1 )
+		{
+			// Setup the type id for the funcdef
+			typeId = typeIdSeqNbr++;
+			typeId |= asTYPEID_APPOBJECT;
+			mapTypeIdToFunction.Insert(typeId, func);
+		}
+
+		RELEASEEXCLUSIVE(engineRWLock);
 	}
 
-	// Insert the basic object type
-	asCDataType *newDt = asNEW(asCDataType)(dt);
-	if( newDt == 0 )
+	// Add flags according to the requested type
+	if( dtIn.GetObjectType() && !(dtIn.GetObjectType()->flags & asOBJ_ASHANDLE) )
 	{
-		// Out of memory
-		return 0;
+		// The ASHANDLE types behave like handles, but are really
+		// value types so the typeId is never returned as a handle
+		if( dtIn.IsObjectHandle() )
+			typeId |= asTYPEID_OBJHANDLE;
+		if( dtIn.IsHandleToConst() )
+			typeId |= asTYPEID_HANDLETOCONST;
 	}
 
-	newDt->MakeReference(false);
-	newDt->MakeReadOnly(false);
-	newDt->MakeHandle(false);
-
-	mapTypeIdToDataType.Insert(typeId, newDt);
-
-	// Call recursively to get the correct typeId
-	return GetTypeIdFromDataType(dtIn);
+	return typeId;
 }
 
 asCDataType asCScriptEngine::GetDataTypeFromTypeId(int typeId) const
 {
 	int baseId = typeId & (asTYPEID_MASK_OBJECT | asTYPEID_MASK_SEQNBR);
 
-	asSMapNode<int,asCDataType*> *cursor = 0;
-	if( mapTypeIdToDataType.MoveTo(&cursor, baseId) )
+	if( typeId <= asTYPEID_DOUBLE )
 	{
-		asCDataType dt(*mapTypeIdToDataType.GetValue(cursor));
+		eTokenType type[] = {ttVoid, ttBool, ttInt8, ttInt16, ttInt, ttInt64, ttUInt8, ttUInt16, ttUInt, ttUInt64, ttFloat, ttDouble};
+		return asCDataType::CreatePrimitive(type[typeId], false);
+	}
+
+	// First check if the typeId is an object type
+	asCObjectType *ot = 0;
+	ACQUIRESHARED(engineRWLock);
+	asSMapNode<int,asCObjectType*> *cursor = 0;
+	if( mapTypeIdToObjectType.MoveTo(&cursor, baseId) )
+		ot = mapTypeIdToObjectType.GetValue(cursor);
+	RELEASESHARED(engineRWLock);
+
+	if( ot )
+	{
+		asCDataType dt = asCDataType::CreateObject(ot, false);
 		if( typeId & asTYPEID_OBJHANDLE )
 			dt.MakeHandle(true, true);
 		if( typeId & asTYPEID_HANDLETOCONST )
 			dt.MakeHandleToConst(true);
+
+		return dt;
+	}
+
+	// Then check if it is a funcdef
+	asCScriptFunction *func = 0;
+	ACQUIRESHARED(engineRWLock);
+	asSMapNode<int,asCScriptFunction*> *cursor2 = 0;
+	if( mapTypeIdToFunction.MoveTo(&cursor2, baseId) )
+		func = mapTypeIdToFunction.GetValue(cursor2);
+	RELEASESHARED(engineRWLock);
+
+	if( func )
+	{
+		asCDataType dt = asCDataType::CreateFuncDef(func);
+		if( typeId & asTYPEID_OBJHANDLE )
+			dt.MakeHandle(true, true);
+		if( typeId & asTYPEID_HANDLETOCONST )
+			dt.MakeHandleToConst(true);
+
 		return dt;
 	}
 
@@ -4643,19 +4717,19 @@ asCObjectType *asCScriptEngine::GetObjectTypeFromTypeId(int typeId) const
 
 void asCScriptEngine::RemoveFromTypeIdMap(asCObjectType *type)
 {
-	asSMapNode<int,asCDataType*> *cursor = 0;
-	mapTypeIdToDataType.MoveFirst(&cursor);
+	ACQUIREEXCLUSIVE(engineRWLock);
+	asSMapNode<int,asCObjectType*> *cursor = 0;
+	mapTypeIdToObjectType.MoveFirst(&cursor);
 	while( cursor )
 	{
-		asCDataType *dt = mapTypeIdToDataType.GetValue(cursor);
-		asSMapNode<int,asCDataType*> *old = cursor;
-		mapTypeIdToDataType.MoveNext(&cursor, cursor);
-		if( dt->GetObjectType() == type )
+		if( mapTypeIdToObjectType.GetValue(cursor) == type )
 		{
-			asDELETE(dt,asCDataType);
-			mapTypeIdToDataType.Erase(old);
+			mapTypeIdToObjectType.Erase(cursor);
+			break;
 		}
+		mapTypeIdToObjectType.MoveNext(&cursor, cursor);
 	}
+	RELEASEEXCLUSIVE(engineRWLock);
 }
 
 // interface
@@ -5375,7 +5449,6 @@ void asCScriptEngine::RemoveScriptFunction(asCScriptFunction *func)
 // internal
 void asCScriptEngine::RemoveFuncdef(asCScriptFunction *funcdef)
 {
-	// TODO: 2.30.0: redesign: How to avoid removing a funcdef that is shared by multiple modules?
 	funcDefs.RemoveValue(funcdef);
 }
 

+ 5 - 4
Source/ThirdParty/AngelScript/source/as_scriptengine.h

@@ -401,16 +401,17 @@ public:
 	// This array stores the template instances types that have been automatically generated from template types
 	asCArray<asCObjectType *> generatedTemplateTypes;
 	// Stores the funcdefs
-	// TODO: 2.30.0: redesign: Only shared funcdefs should be stored here
-	//                         a funcdef becomes shared if all arguments and the return type are shared (or application registered)
+	// TODO: redesign: Only shared funcdefs should be stored here
+	//                 a funcdef becomes shared if all arguments and the return type are shared (or application registered)
 	asCArray<asCScriptFunction *> funcDefs; // doesn't increase ref count
 
 	// Stores the names of the script sections for debugging purposes
 	asCArray<asCString *> scriptSectionNames;
 
 	// Type identifiers
-	mutable int                       typeIdSeqNbr;
-	mutable asCMap<int, asCDataType*> mapTypeIdToDataType;
+	mutable int                             typeIdSeqNbr;
+	mutable asCMap<int, asCObjectType*>     mapTypeIdToObjectType;
+	mutable asCMap<int, asCScriptFunction*> mapTypeIdToFunction;
 
 	// Garbage collector
 	asCGarbageCollector gc;

+ 16 - 13
Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -105,7 +105,7 @@ static void ScriptFunction_CreateDelegate_Generic(asIScriptGeneric *gen)
 	gen->SetReturnAddress(CreateDelegate(func, obj));
 }
 
-// TODO: 2.29.0: operator==
+// TODO: operator==
 /*static void ScriptFunction_opEquals_Generic(asIScriptGeneric *gen)
 {
 	asCScriptFunction *funcSelf = (asCScriptFunction*)gen->GetObject();
@@ -124,7 +124,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	UNUSED_VAR(r); // It is only used in debug mode
 	engine->functionBehaviours.engine = engine;
 	engine->functionBehaviours.flags = asOBJ_REF | asOBJ_GC | asOBJ_SCRIPT_FUNCTION;
-	engine->functionBehaviours.name = "_builtin_function_";
+	engine->functionBehaviours.name = "$func";
 #ifndef AS_MAX_PORTABILITY
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCScriptFunction,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASE, "void f()", asMETHOD(asCScriptFunction,Release), asCALL_THISCALL, 0); asASSERT( r >= 0 );
@@ -133,7 +133,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCScriptFunction,GetFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCScriptFunction,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCScriptFunction,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	// TODO: 2.29.0: Need some way to allow the arg type to adapt when the funcdefs are instantiated
+	// TODO: Need some way to allow the arg type to adapt when the funcdefs are instantiated
 //	r = engine->RegisterMethodToObjectType(&engine->functionBehaviours, "bool opEquals(const int &in)", asMETHOD(asCScriptFunction,operator==), asCALL_THISCALL); asASSERT( r >= 0 );
 #else
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptFunction_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
@@ -226,7 +226,7 @@ asIScriptFunction *asCScriptFunction::GetDelegateFunction() const
 	return funcForDelegate;
 }
 
-// TODO: 2.29.0: operator==
+// TODO: operator==
 /*
 // internal
 bool asCScriptFunction::operator==(const asCScriptFunction &other) const
@@ -419,7 +419,6 @@ asCScriptFunction::~asCScriptFunction()
 	// If the engine pointer is 0, then DestroyInternal has already been called and there is nothing more to do
 	if( engine == 0 ) return;
 
-	// TODO: 2.30.0: redesign: Shouldn't this have been done already?
 	DestroyInternal();
 
 	// Finally set the engine pointer to 0 because it must not be accessed again
@@ -678,7 +677,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 	if( !(returnType.GetTokenType() == ttVoid &&
 		  objectType &&
 		  (name == objectType->name || (name.GetLength() > 0 && name[0] == '~') ||
-		   name == "_beh_0_" || name == "_beh_2_")) )
+		   name == "$beh0" || name == "$beh2")) )
 	{
 		str = returnType.Format(nameSpace, includeNamespace);
 		str += " ";
@@ -699,13 +698,13 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 	}
 	if( name == "" )
 		str += "_unnamed_function_(";
-	else if( name.SubString(0,5) == "_beh_" && name.GetLength() == 7 )
+	else if( name.SubString(0,4) == "$beh" && name.GetLength() == 5 )
 	{
-		if( name[5] == '0' + asBEHAVE_CONSTRUCT )
+		if( name[4] == '0' + asBEHAVE_CONSTRUCT )
 			str += objectType->name + "(";
-		else if( name[5] == '0' + asBEHAVE_FACTORY )
+		else if( name[4] == '0' + asBEHAVE_FACTORY )
 			str += returnType.GetObjectType()->name + "(";
-		else if( name[5] == '0' + asBEHAVE_DESTRUCT )
+		else if( name[4] == '0' + asBEHAVE_DESTRUCT )
 			str += "~" + objectType->name + "(";
 		else
 			str += name + "(";
@@ -1008,7 +1007,7 @@ void asCScriptFunction::ComputeSignatureId()
 // internal
 bool asCScriptFunction::IsSignatureEqual(const asCScriptFunction *func) const
 {
-	if( !IsSignatureExceptNameEqual(func) || name != func->name ) return false;
+	if( name != func->name || !IsSignatureExceptNameEqual(func) ) return false;
 
 	return true;
 }
@@ -1043,9 +1042,9 @@ bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCScriptF
 bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &paramInOut, const asCObjectType *objType, bool readOnly) const
 {
 	if( this->isReadOnly        != readOnly       ) return false;
+	if( (this->objectType != 0) != (objType != 0) ) return false;
 	if( this->inOutFlags        != paramInOut     ) return false;
 	if( this->parameterTypes    != paramTypes     ) return false;
-	if( (this->objectType != 0) != (objType != 0) ) return false;
 
 	return true;
 }
@@ -1299,7 +1298,11 @@ void asCScriptFunction::ReleaseReferences()
 					if( group != 0 ) group->Release();
 
 					if( funcId )
-						engine->scriptFunctions[funcId]->ReleaseInternal();
+					{
+						asCScriptFunction *fptr = engine->scriptFunctions[funcId];
+						if( fptr )
+							fptr->ReleaseInternal();
+					}
 				}
 				break;
 

+ 8 - 8
Source/ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -186,12 +186,12 @@ public:
 
 	void     DestroyHalfCreated();
 
-	// TODO: 2.29.0: operator==
-	// TODO: 2.29.0: The asIScriptFunction should provide operator== and operator!= that should do a
-	//               a value comparison. Two delegate objects that point to the same object and class method should compare as equal
-	// TODO: 2.29.0: The operator== should also be provided in script as opEquals to allow the same comparison in script
-	//               To do this we'll need some way to adapt the argtype for opEquals for each funcdef, preferrably without instantiating lots of different methods
-	//               Perhaps reusing 'auto' to mean the same type as the object
+	// TODO: operator==
+	// TODO: The asIScriptFunction should provide operator== and operator!= that should do a
+	//       a value comparison. Two delegate objects that point to the same object and class method should compare as equal
+	// TODO: The operator== should also be provided in script as opEquals to allow the same comparison in script
+	//       To do this we'll need some way to adapt the argtype for opEquals for each funcdef, preferrably without instantiating lots of different methods
+	//       Perhaps reusing 'auto' to mean the same type as the object
 	//bool      operator==(const asCScriptFunction &other) const;
 
 	void      DestroyInternal();
@@ -329,7 +329,7 @@ public:
 	asSSystemFunctionInterface  *sysFuncIntf;
 };
 
-const char * const DELEGATE_FACTORY = "%delegate_factory";
+const char * const DELEGATE_FACTORY = "$dlgte";
 asCScriptFunction *CreateDelegate(asCScriptFunction *func, void *obj);
 
 END_AS_NAMESPACE

+ 20 - 20
Source/ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -173,6 +173,24 @@ static void ScriptObject_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
 	self->ReleaseAllHandles(engine);
 }
 
+static void ScriptObject_Assignment_Generic(asIScriptGeneric *gen)
+{
+	asCScriptObject *other = *(asCScriptObject**)gen->GetAddressOfArg(0);
+	asCScriptObject *self = (asCScriptObject*)gen->GetObject();
+
+	*self = *other;
+
+	*(asCScriptObject**)gen->GetAddressOfReturnLocation() = self;
+}
+
+static void ScriptObject_Construct_Generic(asIScriptGeneric *gen)
+{
+	asCObjectType *objType = *(asCObjectType**)gen->GetAddressOfArg(0);
+	asCScriptObject *self = (asCScriptObject*)gen->GetObject();
+
+	ScriptObject_Construct(objType, self);
+}
+
 #endif
 
 void RegisterScriptObject(asCScriptEngine *engine)
@@ -182,7 +200,7 @@ void RegisterScriptObject(asCScriptEngine *engine)
 	UNUSED_VAR(r); // It is only used in debug mode
 	engine->scriptTypeBehaviours.engine = engine;
 	engine->scriptTypeBehaviours.flags = asOBJ_SCRIPT_OBJECT | asOBJ_REF | asOBJ_GC;
-	engine->scriptTypeBehaviours.name = "_builtin_object_";
+	engine->scriptTypeBehaviours.name = "$obj";
 #ifndef AS_MAX_PORTABILITY
 	r = engine->RegisterBehaviourToObjectType(&engine->scriptTypeBehaviours, asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptObject_Construct), asCALL_CDECL_OBJLAST, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->scriptTypeBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCScriptObject,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
@@ -216,14 +234,6 @@ void RegisterScriptObject(asCScriptEngine *engine)
 #endif
 }
 
-void ScriptObject_Construct_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *objType = *(asCObjectType**)gen->GetAddressOfArg(0);
-	asCScriptObject *self = (asCScriptObject*)gen->GetObject();
-
-	ScriptObject_Construct(objType, self);
-}
-
 void ScriptObject_Construct(asCObjectType *objType, asCScriptObject *self)
 {
 	new(self) asCScriptObject(objType);
@@ -744,16 +754,6 @@ void asCScriptObject::ReleaseAllHandles(asIScriptEngine *engine)
 	}
 }
 
-void ScriptObject_Assignment_Generic(asIScriptGeneric *gen)
-{
-	asCScriptObject *other = *(asCScriptObject**)gen->GetAddressOfArg(0);
-	asCScriptObject *self = (asCScriptObject*)gen->GetObject();
-
-	*self = *other;
-
-	*(asCScriptObject**)gen->GetAddressOfReturnLocation() = self;
-}
-
 asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject *self)
 {
 	return (*self = *other);

+ 1 - 4
Source/ThirdParty/AngelScript/source/as_scriptobject.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -154,9 +154,6 @@ asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject
 
 void ScriptObject_ConstructUnitialized(asCObjectType *objType, asCScriptObject *self);
 
-void ScriptObject_Construct_Generic(asIScriptGeneric *gen);
-void ScriptObject_Assignment_Generic(asIScriptGeneric *gen);
-
 void RegisterScriptObject(asCScriptEngine *engine);
 
 asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine);

+ 1 - 0
Source/ThirdParty/AngelScript/source/as_texts.h

@@ -142,6 +142,7 @@
 #define TXT_INVALID_CONTINUE                       "Invalid 'continue'"
 #define TXT_INVALID_ESCAPE_SEQUENCE                "Invalid escape sequence"
 #define TXT_INVALID_EXPRESSION_AMBIGUOUS_NAME      "Invalid expression: ambiguous name"
+#define TXT_INVALID_EXPRESSION_LAMBDA              "Invalid expression: stand-alone anonymous function"
 #define TXT_INVALID_OP_ON_METHOD                   "Invalid operation on method"
 #define TXT_INVALID_REF_PROP_ACCESS                "Invalid reference. Property accessors cannot be used in combined read/write operations"
 #define TXT_INVALID_SCOPE                          "Invalid scope resolution"

+ 2 - 1
Source/ThirdParty/AngelScript/source/as_tokendef.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -311,6 +311,7 @@ const char * const OVERRIDE_TOKEN = "override";
 const char * const GET_TOKEN      = "get";
 const char * const SET_TOKEN      = "set";
 const char * const ABSTRACT_TOKEN = "abstract";
+const char * const FUNCTION_TOKEN = "function";
 
 END_AS_NAMESPACE
 

+ 20 - 8
Source/ThirdParty/AngelScript/source/as_typeinfo.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -53,7 +53,6 @@ asCTypeInfo::asCTypeInfo()
 	isExplicitHandle      = false;
 	qwordValue            = 0;
 	isLValue              = false;
-	isVoidExpression      = false;
 	isRefToLocal          = false;
 }
 
@@ -68,7 +67,6 @@ void asCTypeInfo::Set(const asCDataType &dt)
 	isExplicitHandle = false;
 	qwordValue       = 0;
 	isLValue         = false;
-	isVoidExpression = false;
 	isRefToLocal     = false;
 }
 
@@ -135,6 +133,18 @@ void asCTypeInfo::SetUndefinedFuncHandle(asCScriptEngine *engine)
 	isLValue         = false;
 }
 
+bool asCTypeInfo::IsUndefinedFuncHandle() const
+{
+	if( isConstant == false ) return false;
+	if( qwordValue == 0 ) return false;
+	if( isLValue ) return false;
+	if( dataType.GetObjectType() == 0 ) return false;
+	if( dataType.GetObjectType()->name != "$func" ) return false;
+	if( dataType.GetFuncDef() ) return false;
+
+	return true;
+}
+
 void asCTypeInfo::SetNullConstant()
 {
 	Set(asCDataType::CreateNullHandle());
@@ -153,17 +163,19 @@ bool asCTypeInfo::IsNullConstant() const
 	return false;
 }
 
-void asCTypeInfo::SetVoidExpression()
+void asCTypeInfo::SetVoid()
 {
 	Set(asCDataType::CreatePrimitive(ttVoid, false));
 	isLValue = false;
-	isConstant = false;
-	isVoidExpression = true;
+	isConstant = true;
 }
 
-bool asCTypeInfo::IsVoidExpression() const
+bool asCTypeInfo::IsVoid() const
 {
-	return isVoidExpression;
+	if( dataType.GetTokenType() == ttVoid )
+		return true;
+
+	return false;
 }
 
 void asCTypeInfo::SetDummy()

+ 5 - 5
Source/ThirdParty/AngelScript/source/as_typeinfo.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -61,11 +61,12 @@ struct asCTypeInfo
 	void SetConstantD(const asCDataType &dataType, double value);
 	void SetNullConstant();
 	void SetUndefinedFuncHandle(asCScriptEngine *engine);
-	void SetVoidExpression();
+	void SetVoid();
 	void SetDummy();
 
+	bool IsUndefinedFuncHandle() const;
 	bool IsNullConstant() const;
-	bool IsVoidExpression() const;
+	bool IsVoid() const;
 
 	asCDataType dataType;
 	bool  isLValue         :  1; // Can this value be updated in assignment, or increment operators, etc
@@ -73,9 +74,8 @@ struct asCTypeInfo
 	bool  isConstant       :  1;
 	bool  isVariable       :  1;
 	bool  isExplicitHandle :  1;
-	bool  isVoidExpression :  1;
 	bool  isRefToLocal     :  1; // The reference may be to a local variable
-	short dummy            :  9;
+	short dummy            :  10;
 	short stackOffset;
 	union
 	{

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