Browse Source

Update AngelScript to 2.28.1.

Lasse Öörni 12 years ago
parent
commit
d50403798a
36 changed files with 2268 additions and 926 deletions
  1. 1 1
      Docs/Urho3D.dox
  2. 1 1
      Readme.txt
  3. 56 47
      Source/ThirdParty/AngelScript/include/angelscript.h
  4. 258 118
      Source/ThirdParty/AngelScript/source/as_builder.cpp
  5. 11 9
      Source/ThirdParty/AngelScript/source/as_builder.h
  6. 7 2
      Source/ThirdParty/AngelScript/source/as_callfunc.cpp
  7. 13 10
      Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp
  8. 2 2
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  9. 12 5
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm
  10. 381 87
      Source/ThirdParty/AngelScript/source/as_compiler.cpp
  11. 2 0
      Source/ThirdParty/AngelScript/source/as_compiler.h
  12. 34 6
      Source/ThirdParty/AngelScript/source/as_config.h
  13. 33 7
      Source/ThirdParty/AngelScript/source/as_configgroup.cpp
  14. 551 43
      Source/ThirdParty/AngelScript/source/as_context.cpp
  15. 30 1
      Source/ThirdParty/AngelScript/source/as_context.h
  16. 2 2
      Source/ThirdParty/AngelScript/source/as_criticalsection.h
  17. 23 14
      Source/ThirdParty/AngelScript/source/as_gc.cpp
  18. 0 1
      Source/ThirdParty/AngelScript/source/as_gc.h
  19. 29 29
      Source/ThirdParty/AngelScript/source/as_map.h
  20. 23 2
      Source/ThirdParty/AngelScript/source/as_module.cpp
  21. 1 0
      Source/ThirdParty/AngelScript/source/as_module.h
  22. 76 0
      Source/ThirdParty/AngelScript/source/as_namespace.h
  23. 12 3
      Source/ThirdParty/AngelScript/source/as_objecttype.cpp
  24. 1 0
      Source/ThirdParty/AngelScript/source/as_objecttype.h
  25. 12 1
      Source/ThirdParty/AngelScript/source/as_parser.cpp
  26. 170 112
      Source/ThirdParty/AngelScript/source/as_restore.cpp
  27. 4 1
      Source/ThirdParty/AngelScript/source/as_restore.h
  28. 204 166
      Source/ThirdParty/AngelScript/source/as_scriptengine.cpp
  29. 20 17
      Source/ThirdParty/AngelScript/source/as_scriptengine.h
  30. 6 1
      Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp
  31. 64 40
      Source/ThirdParty/AngelScript/source/as_scriptobject.cpp
  32. 96 116
      Source/ThirdParty/AngelScript/source/as_symboltable.h
  33. 42 36
      Source/ThirdParty/AngelScript/source/as_texts.h
  34. 65 33
      Source/ThirdParty/AngelScript/source/as_thread.cpp
  35. 18 9
      Source/ThirdParty/AngelScript/source/as_thread.h
  36. 8 4
      Source/ThirdParty/AngelScript/source/as_tokendef.h

+ 1 - 1
Docs/Urho3D.dox

@@ -100,7 +100,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 
 Urho3D uses the following third-party libraries:
 
-- AngelScript 2.28.0 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.28.1 (http://www.angelcode.com/angelscript/)
 - Bullet 2.81 (http://www.bulletphysics.org/)
 - Civetweb (http://sourceforge.net/projects/civetweb/)
 - FreeType 2.5.0 (http://www.freetype.org/)

+ 1 - 1
Readme.txt

@@ -67,7 +67,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org) and Horde3D
   http://timothylottes.blogspot.com/2011/04/nvidia-fxaa-ii-for-console.html
 
 Urho3D uses the following third-party libraries:
-- AngelScript 2.28.0 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.28.1 (http://www.angelcode.com/angelscript/)
 - Bullet 2.81 (http://www.bulletphysics.org/)
 - Civetweb (http://sourceforge.net/projects/civetweb/)
 - FreeType 2.5.0 (http://www.freetype.org/)

+ 56 - 47
Source/ThirdParty/AngelScript/include/angelscript.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 // AngelScript version
 
-#define ANGELSCRIPT_VERSION        22800
-#define ANGELSCRIPT_VERSION_STRING "2.28.0"
+#define ANGELSCRIPT_VERSION        22801
+#define ANGELSCRIPT_VERSION_STRING "2.28.1"
 
 // Data types
 
@@ -78,6 +78,39 @@ class asILockableSharedBool;
 
 // Enumerations and constants
 
+// Return codes
+enum asERetCodes
+{
+	asSUCCESS                              =  0,
+	asERROR                                = -1,
+	asCONTEXT_ACTIVE                       = -2,
+	asCONTEXT_NOT_FINISHED                 = -3,
+	asCONTEXT_NOT_PREPARED                 = -4,
+	asINVALID_ARG                          = -5,
+	asNO_FUNCTION                          = -6,
+	asNOT_SUPPORTED                        = -7,
+	asINVALID_NAME                         = -8,
+	asNAME_TAKEN                           = -9,
+	asINVALID_DECLARATION                  = -10,
+	asINVALID_OBJECT                       = -11,
+	asINVALID_TYPE                         = -12,
+	asALREADY_REGISTERED                   = -13,
+	asMULTIPLE_FUNCTIONS                   = -14,
+	asNO_MODULE                            = -15,
+	asNO_GLOBAL_VAR                        = -16,
+	asINVALID_CONFIGURATION                = -17,
+	asINVALID_INTERFACE                    = -18,
+	asCANT_BIND_ALL_FUNCTIONS              = -19,
+	asLOWER_ARRAY_DIMENSION_NOT_REGISTERED = -20,
+	asWRONG_CONFIG_GROUP                   = -21,
+	asCONFIG_GROUP_IS_IN_USE               = -22,
+	asILLEGAL_BEHAVIOUR_FOR_TYPE           = -23,
+	asWRONG_CALLING_CONV                   = -24,
+	asBUILD_IN_PROGRESS                    = -25,
+	asINIT_GLOBAL_VARS_FAILED              = -26,
+	asOUT_OF_MEMORY                        = -27
+};
+
 // Engine properties
 enum asEEngineProp
 {
@@ -100,7 +133,9 @@ enum asEEngineProp
 	asEP_DISALLOW_GLOBAL_VARS               = 17,
 	asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT      = 18,
 	asEP_COMPILER_WARNINGS                  = 19,
-	asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE = 20
+	asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE = 20,
+
+	asEP_LAST_PROPERTY
 };
 
 // Calling conventions
@@ -193,39 +228,6 @@ enum asEBehaviours
 	asBEHAVE_MAX
 };
 
-// Return codes
-enum asERetCodes
-{
-	asSUCCESS                              =  0,
-	asERROR                                = -1,
-	asCONTEXT_ACTIVE                       = -2,
-	asCONTEXT_NOT_FINISHED                 = -3,
-	asCONTEXT_NOT_PREPARED                 = -4,
-	asINVALID_ARG                          = -5,
-	asNO_FUNCTION                          = -6,
-	asNOT_SUPPORTED                        = -7,
-	asINVALID_NAME                         = -8,
-	asNAME_TAKEN                           = -9,
-	asINVALID_DECLARATION                  = -10,
-	asINVALID_OBJECT                       = -11,
-	asINVALID_TYPE                         = -12,
-	asALREADY_REGISTERED                   = -13,
-	asMULTIPLE_FUNCTIONS                   = -14,
-	asNO_MODULE                            = -15,
-	asNO_GLOBAL_VAR                        = -16,
-	asINVALID_CONFIGURATION                = -17,
-	asINVALID_INTERFACE                    = -18,
-	asCANT_BIND_ALL_FUNCTIONS              = -19,
-	asLOWER_ARRAY_DIMENSION_NOT_REGISTERED = -20,
-	asWRONG_CONFIG_GROUP                   = -21,
-	asCONFIG_GROUP_IS_IN_USE               = -22,
-	asILLEGAL_BEHAVIOUR_FOR_TYPE           = -23,
-	asWRONG_CALLING_CONV                   = -24,
-	asBUILD_IN_PROGRESS                    = -25,
-	asINIT_GLOBAL_VARS_FAILED              = -26,
-	asOUT_OF_MEMORY                        = -27
-};
-
 // Context states
 enum asEContextState
 {
@@ -400,7 +402,7 @@ typedef void (asCUnknownClass::*asMETHOD_t)();
 
 struct asSFuncPtr
 {
-	asSFuncPtr(asBYTE f)
+	asSFuncPtr(asBYTE f = 0)
 	{
 		for( size_t n = 0; n < sizeof(ptr.dummy); n++ )
 			ptr.dummy[n] = 0;
@@ -624,7 +626,7 @@ public:
 
 	// Script functions
 	virtual asIScriptFunction *GetFunctionById(int funcId) const = 0;
-    virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const = 0;
+	virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const = 0;
 
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const = 0;
@@ -1431,8 +1433,15 @@ enum asEBCInstr
 	asBC_SetListSize	= 190,
 	asBC_PshListElmnt	= 191,
 	asBC_SetListType	= 192,
+	asBC_POWi			= 193,
+	asBC_POWu			= 194,
+	asBC_POWf			= 195,
+	asBC_POWd			= 196,
+	asBC_POWdi			= 197,
+	asBC_POWi64			= 198,
+	asBC_POWu64			= 199,
 
-	asBC_MAXBYTECODE	= 193,
+	asBC_MAXBYTECODE	= 200,
 
 	// Temporary tokens. Can't be output to the final program
 	asBC_VarDecl		= 251,
@@ -1719,14 +1728,14 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO(SetListSize, rW_DW_DW_ARG,	0),
 	asBCINFO(PshListElmnt, rW_DW_ARG,	AS_PTR_SIZE),
 	asBCINFO(SetListType, rW_DW_DW_ARG,	0),
+	asBCINFO(POWi,		wW_rW_rW_ARG,	0),
+	asBCINFO(POWu,		wW_rW_rW_ARG,	0),
+	asBCINFO(POWf,		wW_rW_rW_ARG,	0),
+	asBCINFO(POWd,		wW_rW_rW_ARG,	0),
+	asBCINFO(POWdi,		wW_rW_rW_ARG,	0),
+	asBCINFO(POWi64,	wW_rW_rW_ARG,	0),
+	asBCINFO(POWu64,	wW_rW_rW_ARG,	0),
 
-	asBCINFO_DUMMY(193),
-	asBCINFO_DUMMY(194),
-	asBCINFO_DUMMY(195),
-	asBCINFO_DUMMY(196),
-	asBCINFO_DUMMY(197),
-	asBCINFO_DUMMY(198),
-	asBCINFO_DUMMY(199),
 	asBCINFO_DUMMY(200),
 	asBCINFO_DUMMY(201),
 	asBCINFO_DUMMY(202),

+ 258 - 118
Source/ThirdParty/AngelScript/source/as_builder.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -54,12 +54,11 @@ BEGIN_AS_NAMESPACE
 
 // asCSymbolTable template specializations for sGlobalVariableDescription entries
 template<>
-void asCSymbolTable<sGlobalVariableDescription>::GetKey(const sGlobalVariableDescription *entry, asCString &key) const
+void asCSymbolTable<sGlobalVariableDescription>::GetKey(const sGlobalVariableDescription *entry, asSNameSpaceNamePair &key) const
 {
-	// TODO: optimize: The key should be a struct, composed of namespace pointer and the name string
 	asSNameSpace *ns = entry->property->nameSpace;
 	asCString name = entry->property->name;
-	key = ns->name + "::" + name;
+	key = asSNameSpaceNamePair(ns, name);
 }
 
 // Comparator for exact variable search
@@ -114,8 +113,10 @@ asCBuilder::~asCBuilder()
 	asCSymbolTable<sGlobalVariableDescription>::iterator it = globVariables.List();
 	while( it )
 	{
-		if( (*it)->nextNode )
-			(*it)->nextNode->Destroy(engine);
+		if( (*it)->declaredAtNode )
+			(*it)->declaredAtNode->Destroy(engine);
+		if( (*it)->initializationNode )
+			(*it)->initializationNode->Destroy(engine);
 		asDELETE((*it),sGlobalVariableDescription);
 		it++;
 	}
@@ -207,6 +208,12 @@ void asCBuilder::Reset()
 	numErrors = 0;
 	numWarnings = 0;
 	preMessage.isSet = false;
+
+#ifndef AS_NO_COMPILER
+	// Clear the cache of known types
+	hasCachedKnownTypes = false;
+	knownTypes.EraseAll();
+#endif
 }
 
 #ifndef AS_NO_COMPILER
@@ -217,11 +224,17 @@ int asCBuilder::AddCode(const char *name, const char *code, int codeLength, int
 		return asOUT_OF_MEMORY;
 
 	int r = script->SetCode(name, code, codeLength, makeCopy);
+	if( r < 0 )
+	{
+		asDELETE(script, asCScriptCode);
+		return r;
+	}
+
 	script->lineOffset = lineOffset;
 	script->idx = sectionIdx;
 	scripts.PushLast(script);
 
-	return r;
+	return 0;
 }
 
 int asCBuilder::Build()
@@ -246,6 +259,13 @@ int asCBuilder::Build()
 	if( numErrors > 0 )
 		return asERROR;
 
+	// Make sure something was compiled, otherwise return an error
+	if( module->IsEmpty() )
+	{
+		WriteError(TXT_NOTHING_WAS_BUILT, 0, 0);
+		return asERROR;
+	}
+
 	return asSUCCESS;
 }
 
@@ -556,7 +576,8 @@ void asCBuilder::ParseScripts()
 						decl->objType->beh.factory = 0;
 						decl->objType->beh.factories.RemoveIndex(0);
 					}
-					if( decl->objType->beh.copy )
+					// Only remove the opAssign method if the script hasn't provided one
+					if( decl->objType->beh.copy == engine->scriptTypeBehaviours.beh.copy )
 					{
 						engine->scriptFunctions[decl->objType->beh.copy]->Release();
 						decl->objType->beh.copy = 0;
@@ -709,6 +730,8 @@ void asCBuilder::CompileFunctions()
 					break;
 				}
 			}
+
+			asASSERT( classDecl );
 		}
 
 		if( current->node )
@@ -725,7 +748,7 @@ void asCBuilder::CompileFunctions()
 
 			preMessage.isSet = false;
 		}
-		else if( current->name == current->objType->name )
+		else if( current->objType && current->name == current->objType->name )
 		{
 			asCScriptNode *node = classDecl->node;
 
@@ -743,6 +766,10 @@ void asCBuilder::CompileFunctions()
 
 			preMessage.isSet = false;
 		}
+		else
+		{
+			asASSERT( false );
+		}
 	}
 }
 #endif
@@ -864,6 +891,7 @@ int asCBuilder::VerifyProperty(asCDataType *dt, const char *decl, asCString &nam
 	return asSUCCESS;
 }
 
+#ifndef AS_NO_COMPILER
 asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *prop)
 {
 	asASSERT(obj.GetObjectType() != 0);
@@ -883,6 +911,7 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
 
 	return 0;
 }
+#endif
 
 asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp)
 {
@@ -1173,7 +1202,8 @@ int asCBuilder::CheckNameConflictMember(asCObjectType *t, const char *name, asCS
 int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns)
 {
 	// Check against registered object types
-	if( engine->GetObjectType(name, ns) != 0 )
+	// TODO: Must check against registered funcdefs too
+	if( engine->GetRegisteredObjectType(name, ns) != 0 )
 	{
 		if( code )
 		{
@@ -1420,23 +1450,25 @@ int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSN
 		// TODO: Give error message if wrong
 		asASSERT(!gvar->datatype.IsReference());
 
-		gvar->idNode = n;
-		gvar->nextNode = 0;
-		if( n->next &&
-			(n->next->nodeType == snAssignment ||
-			 n->next->nodeType == snArgList    ||
-			 n->next->nodeType == snInitList     ) )
-		{
-			gvar->nextNode = n->next;
-			n->next->DisconnectParent();
-		}
-
 		gvar->property = module->AllocateGlobalProperty(name.AddressOf(), gvar->datatype, ns);
 		gvar->index    = gvar->property->id;
 
 		globVariables.Put(gvar);
 
+
+		gvar->declaredAtNode = n;
 		n = n->next;
+		gvar->declaredAtNode->DisconnectParent();
+		gvar->initializationNode = 0;
+		if( n &&
+			( n->nodeType == snAssignment ||
+			  n->nodeType == snArgList    ||
+			  n->nodeType == snInitList     ) )
+		{
+			gvar->initializationNode = n;
+			n = n->next;
+			gvar->initializationNode->DisconnectParent();
+		}
 	}
 
 	node->Destroy(engine);
@@ -1758,10 +1790,10 @@ void asCBuilder::CompileGlobalVariables()
 			if( compilingPrimitives && !gvar->datatype.IsPrimitive() )
 				continue;
 
-			if( gvar->nextNode )
+			if( gvar->declaredAtNode )
 			{
 				int r, c;
-				gvar->script->ConvertPosToRowCol(gvar->nextNode->tokenPos, &r, &c);
+				gvar->script->ConvertPosToRowCol(gvar->declaredAtNode->tokenPos, &r, &c);
 				asCString str = gvar->datatype.Format();
 				str += " " + gvar->name;
 				str.Format(TXT_COMPILING_s, str.AddressOf());
@@ -1771,7 +1803,7 @@ void asCBuilder::CompileGlobalVariables()
 			if( gvar->isEnumValue )
 			{
 				int r;
-				if( gvar->nextNode )
+				if( gvar->initializationNode )
 				{
 					asCCompiler comp(engine);
 					asCScriptFunction func(engine, module, asFUNC_SCRIPT);
@@ -1783,7 +1815,7 @@ void asCBuilder::CompileGlobalVariables()
 					asCDataType saveType;
 					saveType = gvar->datatype;
 					gvar->datatype = asCDataType::CreatePrimitive(ttInt, true);
-					r = comp.CompileGlobalVariable(this, gvar->script, gvar->nextNode, gvar, &func);
+					r = comp.CompileGlobalVariable(this, gvar->script, gvar->initializationNode, gvar, &func);
 					gvar->datatype = saveType;
 
 					// Make the function a dummy so it doesn't try to release objects while destroying the function
@@ -1807,9 +1839,8 @@ void asCBuilder::CompileGlobalVariables()
 
 							if( !gvar2->isCompiled )
 							{
-								// TODO: Need to get the correct script position
 								int row, col;
-								gvar->script->ConvertPosToRowCol(0, &row, &col);
+								gvar->script->ConvertPosToRowCol(gvar->declaredAtNode->tokenPos, &row, &col);
 
 								asCString str = gvar->datatype.Format();
 								str += " " + gvar->name;
@@ -1848,7 +1879,7 @@ void asCBuilder::CompileGlobalVariables()
 				initFunc->nameSpace = gvar->property->nameSpace;
 
 				asCCompiler comp(engine);
-				int r = comp.CompileGlobalVariable(this, gvar->script, gvar->nextNode, gvar, initFunc);
+				int r = comp.CompileGlobalVariable(this, gvar->script, gvar->initializationNode, gvar, initFunc);
 				if( r >= 0 )
 				{
 					// Compilation succeeded
@@ -1888,10 +1919,10 @@ void asCBuilder::CompileGlobalVariables()
 					// Finalize the init function for this variable
 					initFunc->returnType = asCDataType::CreatePrimitive(ttVoid, false);
 					initFunc->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(gvar->script->name.AddressOf());
-					if( gvar->nextNode )
+					if( gvar->declaredAtNode )
 					{
 						int row, col;
-						gvar->script->ConvertPosToRowCol(gvar->nextNode->tokenPos, &row, &col);
+						gvar->script->ConvertPosToRowCol(gvar->declaredAtNode->tokenPos, &row, &col);
 						initFunc->scriptData->declaredAt = (row & 0xFFFFF)|((col & 0xFFF)<<20);
 					}
 
@@ -1989,10 +2020,15 @@ void asCBuilder::CompileGlobalVariables()
 			globVariables.Erase(it.GetIndex());
 
 			// Destroy the gvar property
-			if( gvar->nextNode )
+			if( gvar->declaredAtNode )
 			{
-				gvar->nextNode->Destroy(engine);
-				gvar->nextNode = 0;
+				gvar->declaredAtNode->Destroy(engine);
+				gvar->declaredAtNode = 0;
+			}
+			if( gvar->initializationNode )
+			{
+				gvar->initializationNode->Destroy(engine);
+				gvar->initializationNode = 0;
 			}
 			if( gvar->property )
 			{
@@ -2146,7 +2182,14 @@ void asCBuilder::CompileInterfaces()
 			}
 
 			// Find the object type for the interface
-			asCObjectType *objType = GetObjectType(name.AddressOf(), ns);
+			asCObjectType *objType = 0;
+			while( ns )
+			{
+				objType = GetObjectType(name.AddressOf(), ns);
+				if( objType ) break;
+
+				ns = GetParentNameSpace(ns);
+			}
 
 			// Check that the object type is an interface
 			bool ok = true;
@@ -2229,6 +2272,17 @@ 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?
+		// 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++ )
+		{
+			asCScriptFunction *func = GetFunctionDescription(intfType->methods[d]);
+			func->vfTableIdx = d;
+
+			asASSERT(func->objectType == intfType);
+		}
+
 		// As new interfaces will be added to the end of the list, all
 		// interfaces will be traversed the same as recursively
 		for( asUINT m = 0; m < intfType->interfaces.GetLength(); m++ )
@@ -2310,20 +2364,29 @@ void asCBuilder::CompileClasses()
 			}
 
 			// Find the object type for the interface
-			asCObjectType *objType = GetObjectType(name.AddressOf(), ns);
+			asCObjectType *objType = 0;
+			sMixinClass *mixin = 0;
+			while( ns )
+			{
+				objType = GetObjectType(name.AddressOf(), ns);
+				if( objType == 0 )
+					mixin = GetMixinClass(name.AddressOf(), ns);
+
+				if( objType || mixin )
+					break;
 
-			if( objType == 0 )
+				ns = GetParentNameSpace(ns);
+			}
+
+			if( objType == 0 && mixin == 0 )
 			{
-				// Check if the name is a mixin class
-				sMixinClass *mixin = GetMixinClass(name.AddressOf(), ns);
-				if( !mixin )
-				{
-					asCString str;
-					str.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, name.AddressOf());
-					WriteError(str, file, node);
-				}
-				else
-					AddInterfaceFromMixinToClass(decl, node, mixin);
+				asCString str;
+				str.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, name.AddressOf());
+				WriteError(str, file, node);
+			}
+			else if( mixin )
+			{
+				AddInterfaceFromMixinToClass(decl, node, mixin);
 			}
 			else if( !(objType->flags & asOBJ_SCRIPT_OBJECT) ||
 					 objType->flags & asOBJ_NOINHERIT )
@@ -2520,9 +2583,9 @@ void asCBuilder::CompileClasses()
 			}
 		}
 
-		// Move this class' methods into the virtual function table
 		if( !decl->isExistingShared )
 		{
+			// Move this class' methods into the virtual function table
 			for( asUINT m = 0; m < decl->objType->methods.GetLength(); m++ )
 			{
 				asCScriptFunction *func = GetFunctionDescription(decl->objType->methods[m]);
@@ -2538,6 +2601,55 @@ void asCBuilder::CompileClasses()
 					m--;
 				}
 			}
+
+			// Make virtual function table chunks for each implemented interface
+			for( asUINT n = 0; n < decl->objType->interfaces.GetLength(); n++ )
+			{
+				asCObjectType *intf = decl->objType->interfaces[n];
+
+				// Add all the interface's functions to the virtual function table
+				asUINT offset = asUINT(decl->objType->virtualFunctionTable.GetLength());
+				decl->objType->interfaceVFTOffsets.PushLast(offset);
+
+				for( asUINT j = 0; j < intf->methods.GetLength(); j++ )
+				{
+					asCScriptFunction *intfFunc = GetFunctionDescription(intf->methods[j]);
+
+					// Only create the table for functions that are explicitly from this interface,
+					// inherited interface methods will be put in that interface's table.
+					if( intfFunc->objectType != intf )
+						continue;
+
+					asASSERT((asUINT)intfFunc->vfTableIdx == j);
+
+					//Find the interface function in the list of methods
+					asCScriptFunction *realFunc = 0;
+					for( asUINT p = 0; p < decl->objType->methods.GetLength(); p++ )
+					{
+						asCScriptFunction *func = GetFunctionDescription(decl->objType->methods[p]);
+
+						if( func->signatureId == intfFunc->signatureId )
+						{
+							if( func->funcType == asFUNC_VIRTUAL )
+							{
+								realFunc = decl->objType->virtualFunctionTable[func->vfTableIdx];
+							}
+							else
+							{
+								// This should not happen, all methods were moved into the virtual table
+								asASSERT(false);
+							}
+							break;
+						}
+					}
+
+					// If realFunc is still null, the interface was not
+					// implemented and we error out later in the checks.
+					decl->objType->virtualFunctionTable.PushLast(realFunc);
+					if( realFunc )
+						realFunc->AddRef();
+				}
+			}
 		}
 
 		// Enumerate each of the declared properties
@@ -3081,12 +3193,8 @@ int asCBuilder::CreateVirtualFunction(asCScriptFunction *func, int idx)
 	vf->isFinal          = func->isFinal;
 	vf->isOverride       = func->isOverride;
 	vf->vfTableIdx       = idx;
-	vf->defaultArgs      = func->defaultArgs;
 
-	// Copy the default arg strings to avoid multiple deletes on the same object
-	for( asUINT n = 0; n < vf->defaultArgs.GetLength(); n++ )
-		if( vf->defaultArgs[n] )
-			vf->defaultArgs[n] = asNEW(asCString)(*vf->defaultArgs[n]);
+	// It is not necessary to copy the default args, as they have no meaning in the virtual function
 
 	module->AddScriptFunction(vf);
 
@@ -3349,22 +3457,24 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
 				if( gvar == 0 )
 					return asOUT_OF_MEMORY;
 
-				gvar->script		  = file;
-				gvar->idNode          = 0;
-				gvar->nextNode		  = asnNode;
-				gvar->name			  = name;
-				gvar->datatype		  = type;
+				gvar->script             = file;
+				gvar->declaredAtNode     = tmp;
+				tmp = tmp->next;
+				gvar->declaredAtNode->DisconnectParent();
+				gvar->initializationNode = asnNode;
+				gvar->name               = name;
+				gvar->datatype           = type;
 				// No need to allocate space on the global memory stack since the values are stored in the asCObjectType
 				// Set the index to a negative to allow compiler to diferentiate from ordinary global var when compiling the initialization
-				gvar->index			  = -1; 
-				gvar->isCompiled	  = false;
-				gvar->isPureConstant  = true;
-				gvar->isEnumValue     = true;
-				gvar->constantValue   = 0xdeadbeef;
+				gvar->index              = -1; 
+				gvar->isCompiled         = false;
+				gvar->isPureConstant     = true;
+				gvar->isEnumValue        = true;
+				gvar->constantValue      = 0xdeadbeef;
 
 				// Allocate dummy property so we can compile the value.
 				// This will be removed later on so we don't add it to the engine.
-				gvar->property            = asNEW(asCGlobalProperty);
+				gvar->property = asNEW(asCGlobalProperty);
 				if( gvar->property == 0 )
 					return asOUT_OF_MEMORY;
 
@@ -3374,7 +3484,6 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
 				gvar->property->id        = 0;
 
 				globVariables.Put(gvar);
-				tmp = tmp->next;
 			}
 		}
 	}
@@ -4163,7 +4272,6 @@ int asCBuilder::RegisterImportedFunction(int importID, asCScriptNode *node, asCS
 
 	return 0;
 }
-#endif
 
 asCScriptFunction *asCBuilder::GetFunctionDescription(int id)
 {
@@ -4178,6 +4286,8 @@ asCScriptFunction *asCBuilder::GetFunctionDescription(int id)
 void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns)
 {
 	asUINT n;
+
+	// Get the script declared global functions
 	const asCArray<unsigned int> &idxs = module->globalFunctions.GetIndexes(ns, name);
 	for( n = 0; n < idxs.GetLength(); n++ )
 	{
@@ -4186,6 +4296,7 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
 		funcs.PushLast(f->id);
 	}
 
+	// Add the imported functions
 	// TODO: optimize: Linear search: This is probably not that critial. Also bindInformation will probably be removed in near future
 	for( n = 0; n < module->bindInformations.GetLength(); n++ )
 	{
@@ -4193,21 +4304,16 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
 			funcs.PushLast(module->bindInformations[n]->importedFunctionSignature->id);
 	}
 
-	// TODO: optimize: Linear search. The registered global functions should be stored in a symbol table too
-	for( n = 0; n < engine->registeredGlobalFuncs.GetLength(); n++ )
+	// Add the registered global functions
+	const asCArray<unsigned int> &idxs2 = engine->registeredGlobalFuncs.GetIndexes(ns, name);
+	for( n = 0; n < idxs2.GetLength(); n++ )
 	{
-		asCScriptFunction *f = engine->registeredGlobalFuncs[n];
-		if( f &&
-			f->funcType == asFUNC_SYSTEM &&
-			f->objectType == 0 &&
-			f->nameSpace == ns &&
-			f->name == name )
+		asCScriptFunction *f = engine->registeredGlobalFuncs.Get(idxs2[n]);
+
+		// Verify if the module has access to the function
+		if( module->accessMask & f->accessMask )
 		{
-			// Verify if the module has access to the function
-			if( module->accessMask & f->accessMask )
-			{
-				funcs.PushLast(f->id);
-			}
+			funcs.PushLast(f->id);
 		}
 	}
 }
@@ -4266,6 +4372,7 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
 		}
 	}
 }
+#endif
 
 void asCBuilder::WriteInfo(const asCString &scriptname, const asCString &message, int r, int c, bool pre)
 {
@@ -4478,14 +4585,13 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 							// orderwise it is a template instance.
 							// Only do this for application registered interface, as the
 							// scripts cannot implement templates.
-							// TODO: namespace: Use correct implicit namespace
 							asCArray<asCDataType> subTypes;
 							asUINT subtypeIndex;
 							while( n && n->next && n->next->nodeType == snDataType )
 							{
 								n = n->next;
 
-								asCDataType subType = CreateDataTypeFromNode(n, file, engine->nameSpaces[0], false, module ? 0 : ot);
+								asCDataType subType = CreateDataTypeFromNode(n, file, implicitNamespace, false, module ? 0 : ot);
 								subTypes.PushLast(subType);
 
 								if( subType.IsReadOnly() )
@@ -4697,53 +4803,73 @@ asCDataType asCBuilder::ModifyDataTypeFromNode(const asCDataType &type, asCScrip
 
 asCObjectType *asCBuilder::GetObjectType(const char *type, asSNameSpace *ns)
 {
-	asCObjectType *ot = engine->GetObjectType(type, ns);
+	asCObjectType *ot = engine->GetRegisteredObjectType(type, ns);
 	if( !ot && module )
 		ot = module->GetObjectType(type, ns);
 
 	return ot;
 }
 
+#ifndef AS_NO_COMPILER
 // This function will return true if there are any types in the engine or module
 // with the given name. The namespace is ignored in this verification.
 bool asCBuilder::DoesTypeExist(const asCString &type)
 {
 	asUINT n;
 
-	// TODO: optimize: Improve linear searches
-
-	// Check if it is a registered type
-	for( n = 0; n < engine->objectTypes.GetLength(); n++ )
-		if( engine->objectTypes[n] &&
-			engine->objectTypes[n]->name == type ) // TODO: template: Should we check the subtype in case of template instances?
-			return true;
-
-	for( n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
-		if( engine->registeredFuncDefs[n]->name == type )
-			return true;
-
-	// Check if it is a script type
-	if( module )
+	// This function is only used when parsing expressions for building bytecode
+	// and this is only done after all types are known. For this reason the types
+	// can be safely cached in a map for quick lookup. Once the builder is released
+	// the cache will also be destroyed thus avoiding unnecessary memory consumption.
+	if( !hasCachedKnownTypes )
 	{
-		for( n = 0; n < module->classTypes.GetLength(); n++ )
-			if( module->classTypes[n]->name == type )
-				return true;
+		// Only do this once
+		hasCachedKnownTypes = true;
 
-		for( n = 0; n < module->enumTypes.GetLength(); n++ )
-			if( module->enumTypes[n]->name == type )
-				return true;
+		// Add registered object types
+		asSMapNode<asSNameSpaceNamePair, asCObjectType*> *cursor;
+		engine->allRegisteredTypes.MoveFirst(&cursor);
+		while( cursor )
+		{
+			if( !knownTypes.MoveTo(0, cursor->key.name) )
+				knownTypes.Insert(cursor->key.name, true);
 
-		for( n = 0; n < module->typeDefs.GetLength(); n++ )
-			if( module->typeDefs[n]->name == type )
-				return true;
+			engine->allRegisteredTypes.MoveNext(&cursor, cursor);
+		}
 
-		for( asUINT n = 0; n < module->funcDefs.GetLength(); n++ )
-			if( module->funcDefs[n]->name == type )
-				return true;
+		// Add registered funcdefs
+		for( n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
+			if( !knownTypes.MoveTo(0, engine->registeredFuncDefs[n]->name) )
+				knownTypes.Insert(engine->registeredFuncDefs[n]->name, true);
+
+		if( module )
+		{
+			// Add script classes and interfaces
+			for( n = 0; n < module->classTypes.GetLength(); n++ )
+				if( !knownTypes.MoveTo(0, module->classTypes[n]->name) )
+					knownTypes.Insert(module->classTypes[n]->name, true);
+
+			// Add script enums
+			for( n = 0; n < module->enumTypes.GetLength(); n++ )
+				if( !knownTypes.MoveTo(0, module->enumTypes[n]->name) )
+					knownTypes.Insert(module->enumTypes[n]->name, true);
+
+			// Add script typedefs
+			for( n = 0; n < module->typeDefs.GetLength(); n++ )
+				if( !knownTypes.MoveTo(0, module->typeDefs[n]->name) )
+					knownTypes.Insert(module->typeDefs[n]->name, true);
+
+			// Add script funcdefs
+			for( n = 0; n < module->funcDefs.GetLength(); n++ )
+				if( !knownTypes.MoveTo(0, module->funcDefs[n]->name) )
+					knownTypes.Insert(module->funcDefs[n]->name, true);
+		}
 	}
 
-	return false;
+	// Check if the type is known
+	return knownTypes.MoveTo(0, type);
 }
+#endif
 
 asCObjectType *asCBuilder::GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType)
 {
@@ -4752,25 +4878,35 @@ asCObjectType *asCBuilder::GetObjectTypeFromTypesKnownByObject(const char *type,
 
 	asUINT n;
 
-	for( n = 0; n < currentType->properties.GetLength(); n++ )
+	asCObjectType *found = 0;
+
+	for( n = 0; found == 0 && n < currentType->properties.GetLength(); n++ )
 		if( currentType->properties[n]->type.GetObjectType() &&
 			currentType->properties[n]->type.GetObjectType()->name == type )
-			return currentType->properties[n]->type.GetObjectType();
+			found = currentType->properties[n]->type.GetObjectType();
 
-	for( n = 0; n < currentType->methods.GetLength(); n++ )
+	for( n = 0; found == 0 && n < currentType->methods.GetLength(); n++ )
 	{
 		asCScriptFunction *func = engine->scriptFunctions[currentType->methods[n]];
 		if( func->returnType.GetObjectType() &&
 			func->returnType.GetObjectType()->name == type )
-			return func->returnType.GetObjectType();
-
-		for( asUINT f = 0; f < func->parameterTypes.GetLength(); f++ )
+			found = func->returnType.GetObjectType();
+		
+		for( asUINT f = 0; found == 0 && f < func->parameterTypes.GetLength(); f++ )
 			if( func->parameterTypes[f].GetObjectType() &&
 				func->parameterTypes[f].GetObjectType()->name == type )
-				return func->parameterTypes[f].GetObjectType();
+				found = func->parameterTypes[f].GetObjectType();
 	}
 
-	return 0;
+	if( found )
+	{
+		// In case we find a template instance it mustn't be returned
+		// because it is not known if the subtype is really matching
+		if( found->flags & asOBJ_TEMPLATE )
+			return 0;
+	}
+
+	return found;
 }
 
 asCScriptFunction *asCBuilder::GetFuncDef(const char *type)
@@ -4816,11 +4952,15 @@ int asCBuilder::GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outV
 
 	// Search all available enum types
 	asUINT t;
-	for( t = 0; t < engine->objectTypes.GetLength(); t++ )
+	for( t = 0; t < engine->registeredEnums.GetLength(); t++ )
 	{
-		asCObjectType *ot = engine->objectTypes[t];
+		asCObjectType *ot = engine->registeredEnums[t];
 		if( ns != ot->nameSpace ) continue;
 
+		// Don't bother with types the module doesn't have access to
+		if( (ot->accessMask & module->accessMask) == 0 )
+			continue;
+
 		if( GetEnumValueFromObjectType(ot, name, outDt, outValue) )
 		{
 			if( !found )

+ 11 - 9
Source/ThirdParty/AngelScript/source/as_builder.h

@@ -67,8 +67,8 @@ struct sFunctionDescription
 struct sGlobalVariableDescription
 {
 	asCScriptCode     *script;
-	asCScriptNode     *idNode;
-	asCScriptNode     *nextNode;
+	asCScriptNode     *declaredAtNode;
+	asCScriptNode     *initializationNode;
 	asCString          name;
 	asCGlobalProperty *property;
 	asCDataType        datatype;
@@ -161,13 +161,7 @@ protected:
 	void               WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
 	void               WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
 
-	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
 	asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
-
-	asCScriptFunction *GetFunctionDescription(int funcId);
-	void               GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
-	void               GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
-
 	int                ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
 
@@ -175,7 +169,6 @@ protected:
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 	asSNameSpace      *GetParentNameSpace(asSNameSpace *ns);
 
-	bool               DoesTypeExist(const asCString &type);
 	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns);
 	asCScriptFunction *GetFuncDef(const char *type);
 	asCObjectType     *GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);
@@ -235,6 +228,11 @@ protected:
 	void               CompileGlobalVariables();
 	int                GetEnumValueFromObjectType(asCObjectType *objType, const char *name, asCDataType &outDt, asDWORD &outValue);
 	int                GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outValue, asSNameSpace *ns);
+	bool               DoesTypeExist(const asCString &type);
+	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
+	asCScriptFunction *GetFunctionDescription(int funcId);
+	void               GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
+	void               GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
 
 	asCArray<asCScriptCode *>                  scripts;
 	asCArray<sFunctionDescription *>           functions;
@@ -244,6 +242,10 @@ protected:
 	asCArray<sClassDeclaration *>              namedTypeDeclarations;
 	asCArray<sFuncDef *>                       funcDefs;
 	asCArray<sMixinClass *>                    mixinClasses;
+
+	// For use with the DoesTypeExists() method
+	bool                    hasCachedKnownTypes;
+	asCMap<asCString, bool> knownTypes;
 #endif
 };
 

+ 7 - 2
Source/ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -76,13 +76,18 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 				return asINVALID_ARG;
 			internal->objForThiscall = objForThiscall;
 			internal->callConv       = ICC_THISCALL;
+
+			// This is really a thiscall, so it is necessary to check for virtual method pointers
+			base = asCALL_THISCALL;
+			isMethod = true;
 		}
 		else if( base == asCALL_GENERIC )
 			internal->callConv = ICC_GENERIC_FUNC;
 		else
 			return asNOT_SUPPORTED;
 	}
-	else
+	
+	if( isMethod )
 	{
 #ifndef AS_NO_CLASS_METHODS
 		if( base == asCALL_THISCALL )

+ 13 - 10
Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp

@@ -57,8 +57,10 @@
 #include "as_tokendef.h"
 #include "as_context.h"
 
-#if !defined(AS_LINUX)
+#if defined(AS_SOFTFP)
 
+// This code supports the soft-float ABI, i.e. g++ -mfloat-abi=softfp
+//
 // The code for iOS, Android, Marmalade and Windows Phone goes here
 
 BEGIN_AS_NAMESPACE
@@ -87,14 +89,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	}
 
 	asDWORD paramBuffer[64+2];
-	// Android needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
+	// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
 	// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this 
 	//                         doesn't have to be done for functions that don't have any 64bit types
-#if !defined(AS_ANDROID)
+#if !defined(AS_ANDROID) && !defined(AS_LINUX)
 	if( sysFunc->takesObjByVal )
 #endif
 	{
-#if defined(AS_ANDROID)
+#if defined(AS_ANDROID) || defined(AS_LINUX)
 		// mask is used as a toggler to skip uneven registers.
 		int mask = 1;
 
@@ -134,7 +136,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 				else
 #endif
 				{
-#if defined(AS_ANDROID)
+#if defined(AS_ANDROID) || defined(AS_LINUX)
 					if( (descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_CLASS_ALIGN8) &&
 						((dpos & 1) == mask) )
 					{
@@ -155,7 +157,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			}
 			else
 			{
-#if defined(AS_ANDROID)
+#if defined(AS_ANDROID) || defined(AS_LINUX)
 				// Should an alignment be performed?
 				if( !descr->parameterTypes[n].IsObjectHandle() && 
 					!descr->parameterTypes[n].IsReference() && 
@@ -236,9 +238,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 END_AS_NAMESPACE
 
-#elif defined(AS_LINUX)
+#elif !defined(AS_SOFTFP)
 
-// The Linux code goes here
+// This code supports the hard-float ABI, i.e. g++ -mfloat-abi=hard
+// The main difference is that the floating point values are passed in the fpu registers
 
 #define VFP_OFFSET 70
 #define STACK_OFFSET 6
@@ -466,7 +469,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 					{
 						// 64 bit value align
 						dpos++;
-						paramSize++;						
+						paramSize++;
 					}
 
 					paramBuffer[dpos++] = args[spos++];
@@ -486,7 +489,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 					paramBuffer[stackPos++] = args[spos++];
 					stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
-				}				
+				}
 
 				if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
 				{

+ 2 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S

@@ -41,7 +41,7 @@
 
 #if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
 
-#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID)
+#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__)
 
 /* iOS, Android, and Marmalade goes here */
 
@@ -260,7 +260,7 @@ nomoreargsarmFuncR0R1:
     ldmia   sp!, {r4-r8, pc}
 
 /* --------------------------------------------------------------------------------------------*/
-#elif defined(__linux__)
+#elif defined(__linux__) && !defined(__SOFTFP__)
 
 /* The Linux code goes here */
 

+ 12 - 5
Source/ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm

@@ -1,6 +1,6 @@
 ;
 ;  AngelCode Scripting Library
-;  Copyright (c) 2003-2009 Andreas Jonsson
+;  Copyright (c) 2003-2013 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,18 +35,21 @@
 ; MSVC currently doesn't support inline assembly for the ARM platform
 ; so this separate file is needed.
 
+; Compile with Microsoft ARM assembler (armasm)
+; http://msdn.microsoft.com/en-us/library/hh873190.aspx
+
 
     AREA	|.rdata|, DATA, READONLY
-    EXPORT |armFunc|
+    EXPORT armFunc
     EXPORT armFuncR0
     EXPORT armFuncR0R1
     EXPORT armFuncObjLast
     EXPORT armFuncR0ObjLast
-    
 
-    AREA	|.text|, CODE, ARM
+    AREA	|.text|, CODE, ARM, ALIGN=3
 
-|armFunc| PROC
+    ALIGN   8
+armFunc PROC
     stmdb   sp!, {r4-r8, lr}
     mov     r6, r0  ; arg table
     movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
@@ -82,6 +85,7 @@
     ldmia   sp!, {r4-r8, pc}
     ENDP
 
+    ALIGN   8
 armFuncObjLast PROC
     stmdb   sp!, {r4-r8, lr}
     mov     r6, r0  ; arg table
@@ -125,6 +129,7 @@ armFuncObjLast PROC
     ldmia   sp!, {r4-r8, pc}
     ENDP
 
+    ALIGN   8
 armFuncR0ObjLast PROC
     stmdb   sp!, {r4-r8, lr}
     ldr     r7, [sp,#6*4]
@@ -168,6 +173,7 @@ armFuncR0ObjLast PROC
     ldmia   sp!, {r4-r8, pc}
     ENDP
 
+    ALIGN   8
 armFuncR0 PROC
     stmdb   sp!, {r4-r8, lr}
     mov     r6, r0  ; arg table
@@ -204,6 +210,7 @@ armFuncR0 PROC
     ldmia   sp!, {r4-r8, pc}
     ENDP
 
+    ALIGN   8
 armFuncR0R1 PROC
     stmdb   sp!, {r4-r8, lr}
     mov     r6, r0  ; arg table

+ 381 - 87
Source/ThirdParty/AngelScript/source/as_compiler.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -36,7 +36,7 @@
 // The class that does the actual compilation of the functions
 //
 
-#include <math.h> // fmodf()
+#include <math.h> // fmodf() pow()
 
 #include "as_config.h"
 
@@ -49,6 +49,7 @@
 #include "as_texts.h"
 #include "as_parser.h"
 #include "as_debug.h"
+#include "as_context.h"  // as_powi()
 
 BEGIN_AS_NAMESPACE
 
@@ -363,7 +364,7 @@ int asCCompiler::SetupParametersAndReturnVariable(asCArray<asCString> &parameter
 	{
 		// Get the parameter type
 		asCDataType &type = outFunc->parameterTypes[n];
-		asETypeModifiers inoutFlag = outFunc->inOutFlags[n];
+		asETypeModifiers inoutFlag = n < outFunc->inOutFlags.GetLength() ? outFunc->inOutFlags[n] : asTM_NONE;
 
 		// Is the data type allowed?
 		// TODO: Hasn't this been validated by the builder already?
@@ -820,14 +821,44 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 
 		int func = 0;
 		asSTypeBehaviour *beh = type.GetBehaviour();
-		if( beh ) func = beh->factory;
+		if( beh ) 
+		{
+			func = beh->factory;
+
+			// If no trivial default factory is found, look for a factory where all params have default args
+			if( func == 0 )
+			{
+				for( asUINT n = 0; n < beh->factories.GetLength(); n++ )
+				{
+					asCScriptFunction *f = engine->scriptFunctions[beh->factories[n]];
+					if( f->defaultArgs.GetLength() == f->parameterTypes.GetLength() &&
+						f->defaultArgs[0] != 0 )
+					{
+						func = beh->factories[n];
+						break;
+					}
+				}
+			}
+		}
 
 		if( func > 0 )
 		{
+			asCArray<asSExprContext *> args;
+			asCScriptFunction *f = engine->scriptFunctions[func];
+			if( f->parameterTypes.GetLength() )
+			{
+				// Add the default values for arguments not explicitly supplied
+				CompileDefaultArgs(node, args, f);
+
+				PrepareFunctionCall(func, &ctx.bc, args);
+
+				MoveArgsToStack(func, &ctx.bc, args, false);
+			}
+
 			if( isVarGlobOrMem == 0 )
 			{
 				// Call factory and store the handle in the given variable
-				PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType(), true, offset);
+				PerformFunctionCall(func, &ctx, false, &args, type.GetObjectType(), true, offset);
 
 				// Pop the reference left by the function call
 				ctx.bc.Instr(asBC_PopPtr);
@@ -835,7 +866,7 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 			else
 			{
 				// Call factory
-				PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
+				PerformFunctionCall(func, &ctx, false, &args, type.GetObjectType());
 
 				// TODO: runtime optimize: Should have a way of storing the object pointer directly to the destination
 				//                         instead of first storing it in a local variable and then copying it to the
@@ -879,38 +910,101 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 
 			bc->AddCode(&ctx.bc);
 
+			// Cleanup
+			for( asUINT n = 0; n < args.GetLength(); n++ )
+				if( args[n] )
+				{
+					asDELETE(args[n],asSExprContext);
+				}
+
 			return 0;
 		}
 	}
 	else
 	{
+		asSExprContext ctx(engine);
+		ctx.exprNode = node;
+
 		asSTypeBehaviour *beh = type.GetBehaviour();
 
 		int func = 0;
-		if( beh ) func = beh->construct;
+		if( beh ) 
+		{
+			func = beh->construct;
+
+			// If no trivial default constructor is found, look for a constructor where all params have default args
+			if( func == 0 )
+			{
+				for( asUINT n = 0; n < beh->constructors.GetLength(); n++ )
+				{
+					asCScriptFunction *f = engine->scriptFunctions[beh->constructors[n]];
+					if( f->defaultArgs.GetLength() == f->parameterTypes.GetLength() &&
+						f->defaultArgs[0] != 0 )
+					{
+						func = beh->constructors[n];
+						break;
+					}
+				}
+			}
+		}
 
 		// Allocate and initialize with the default constructor
 		if( func != 0 || (type.GetObjectType()->flags & asOBJ_POD) )
 		{
+			asCArray<asSExprContext *> args;
+			asCScriptFunction *f = engine->scriptFunctions[func];
+			if( f && f->parameterTypes.GetLength() )
+			{
+				// Add the default values for arguments not explicitly supplied
+				CompileDefaultArgs(node, args, f);
+
+				PrepareFunctionCall(func, &ctx.bc, args);
+
+				MoveArgsToStack(func, &ctx.bc, args, false);
+			}
+
 			if( !isObjectOnHeap )
 			{
-				asASSERT( isVarGlobOrMem == 0 );
+				if( isVarGlobOrMem == 0 )
+				{
+					// There is nothing to do if there is no function,
+					// as the memory is already allocated on the stack
+					if( func )
+					{
+						// Call the constructor as a normal function
+						bc->InstrSHORT(asBC_PSF, (short)offset);
+						if( derefDest )
+							bc->Instr(asBC_RDSPtr);
 
-				// There is nothing to do if there is no function,
-				// as the memory is already allocated on the stack
-				if( func )
+						asSExprContext ctx(engine);
+						PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
+						bc->AddCode(&ctx.bc);
+
+						// TODO: value on stack: This probably needs to be done in PerformFunctionCall
+						// Mark the object as initialized
+						bc->ObjInfo(offset, asOBJ_INIT);
+					}
+				}
+				else if( isVarGlobOrMem == 2 )
 				{
-					// Call the constructor as a normal function
-					bc->InstrSHORT(asBC_PSF, (short)offset);
-					if( derefDest )
+					// Only POD types can be allocated inline in script classes
+					asASSERT( type.GetObjectType()->flags & asOBJ_POD );
+
+					if( func )
+					{
+						// Call the constructor as a normal function
+						bc->InstrSHORT(asBC_PSF, 0);
 						bc->Instr(asBC_RDSPtr);
-					asSExprContext ctx(engine);
-					PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
-					bc->AddCode(&ctx.bc);
+						bc->InstrSHORT_DW(asBC_ADDSi, (short)offset, engine->GetTypeIdFromDataType(asCDataType::CreateObject(outFunc->objectType, false)));
 
-					// TODO: value on stack: This probably needs to be done in PerformFunctionCall
-					// Mark the object as initialized
-					bc->ObjInfo(offset, asOBJ_INIT);
+						asSExprContext ctx(engine);
+						PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
+						bc->AddCode(&ctx.bc);
+					}
+				}
+				else 
+				{
+					asASSERT( false );
 				}
 			}
 			else
@@ -929,6 +1023,13 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 				bc->Alloc(asBC_ALLOC, type.GetObjectType(), func, AS_PTR_SIZE);
 			}
 
+			// Cleanup
+			for( asUINT n = 0; n < args.GetLength(); n++ )
+				if( args[n] )
+				{
+					asDELETE(args[n],asSExprContext);
+				}
+
 			return 0;
 		}
 	}
@@ -1091,7 +1192,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 	// Compile the expression
 	asSExprContext ctx(engine);
 	asQWORD constantValue;
-	if( CompileInitialization(node, &ctx.bc, gvar->datatype, gvar->idNode, gvar->index, &constantValue, 1) )
+	if( CompileInitialization(node, &ctx.bc, gvar->datatype, gvar->declaredAtNode, gvar->index, &constantValue, 1) )
 	{
 		// Should the variable be marked as pure constant?
 		if( gvar->datatype.IsPrimitive() && gvar->datatype.IsReadOnly() )
@@ -1106,10 +1207,10 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 
 	// Add information on the line number for the global variable
 	size_t pos = 0;
-	if( gvar->idNode )
-		pos = gvar->idNode->tokenPos;
-	else if( gvar->nextNode )
-		pos = gvar->nextNode->tokenPos;
+	if( gvar->declaredAtNode )
+		pos = gvar->declaredAtNode->tokenPos;
+	else if( gvar->initializationNode )
+		pos = gvar->initializationNode->tokenPos;
 	LineInstr(&byteCode, pos);
 
 	// Reserve space for all local variables
@@ -1305,6 +1406,8 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 				// variable then it is not necessary to make a copy either
 				if( !ctx->type.isTemporary && !(param.IsReadOnly() && ctx->type.isVariable) && !isMakingCopy )
 				{
+					// TODO: 2.28.1: Need to reserve variables, as the default constructor may need 
+					//               to allocate temporary variables to compute default args
 					// Make sure the variable is not used in the expression
 					offset = AllocateVariableNotIn(dt, true, false, ctx);
 
@@ -1388,6 +1491,9 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 			}
 			else
 			{
+				// TODO: 2.28.1: Need to reserve variables, as the default constructor may need 
+				//               to allocate temporary variables to compute default args
+
 				// Allocate and construct the temporary object
 				asCByteCode tmpBC(engine);
 				CallDefaultConstructor(dt, offset, IsVariableOnHeap(offset), &tmpBC, node);
@@ -1882,6 +1988,10 @@ asUINT asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext
 				bool noMatch = true;
 				if( args.GetLength() < desc->parameterTypes.GetLength() )
 				{
+					// For virtual functions, the default args are defined in the real function of the object
+					if( desc->funcType == asFUNC_VIRTUAL )
+						desc = objectType->virtualFunctionTable[desc->vfTableIdx];
+
 					// Count the number of default args
 					asUINT defaultArgs = 0;
 					for( asUINT d = 0; d < desc->defaultArgs.GetLength(); d++ )
@@ -2068,7 +2178,8 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 
 		// Verify that the name isn't used by a dynamic data type
-		if( engine->GetObjectType(name.AddressOf(), outFunc->nameSpace) != 0 )
+		// TODO: Must check against registered funcdefs too
+		if( engine->GetRegisteredObjectType(name.AddressOf(), outFunc->nameSpace) != 0 )
 		{
 			asCString str;
 			str.Format(TXT_ILLEGAL_VARIABLE_NAME_s, name.AddressOf());
@@ -2207,14 +2318,18 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, as
 								if( onHeap )
 									ctx.bc.InstrSHORT(asBC_PSF, (short)offset);
 							}
-							else
+							else if( isVarGlobOrMem == 1 )
 							{
 								// Push the address of the location where the variable will be stored on the stack.
 								// This reference is safe, because the addresses of the global variables cannot change.
 								onHeap = true;
-								if( isVarGlobOrMem == 1 )
-									ctx.bc.InstrPTR(asBC_PGA, engine->globalProperties[offset]->GetAddressOfValue());
-								else
+								ctx.bc.InstrPTR(asBC_PGA, engine->globalProperties[offset]->GetAddressOfValue());
+							}
+							else
+							{
+								// Value types may be allocated inline if they are POD types
+								onHeap = !type.IsObject() || type.IsReference() || (type.GetObjectType()->flags & asOBJ_REF);
+								if( onHeap )
 								{
 									ctx.bc.InstrSHORT(asBC_PSF, 0);
 									ctx.bc.Instr(asBC_RDSPtr);
@@ -2228,7 +2343,18 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, as
 							// When the object is allocated on the stack, the address to the
 							// object is pushed on the stack after the arguments as the object pointer
 							if( !onHeap )
-								ctx.bc.InstrSHORT(asBC_PSF, (short)offset);
+							{
+								if( isVarGlobOrMem == 2 )
+								{
+									ctx.bc.InstrSHORT(asBC_PSF, 0);
+									ctx.bc.Instr(asBC_RDSPtr);
+									ctx.bc.InstrSHORT_DW(asBC_ADDSi, (short)offset, engine->GetTypeIdFromDataType(asCDataType::CreateObject(outFunc->objectType, false)));
+								}
+								else
+								{
+									ctx.bc.InstrSHORT(asBC_PSF, (short)offset);
+								}
+							}
 
 							PerformFunctionCall(funcs[0], &ctx, onHeap, &args, type.GetObjectType());
 
@@ -2273,8 +2399,10 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, as
 		// Call the default constructor here
 		if( isVarGlobOrMem == 0 )
 			CallDefaultConstructor(type, offset, IsVariableOnHeap(offset), &ctx.bc, errNode);
-		else
+		else if( isVarGlobOrMem == 1 )
 			CallDefaultConstructor(type, offset, true, &ctx.bc, errNode, isVarGlobOrMem);
+		else if( isVarGlobOrMem == 2 )
+			CallDefaultConstructor(type, offset, type.IsReference(), &ctx.bc, errNode, isVarGlobOrMem);
 
 		// Compile the expression
 		asSExprContext expr(engine);
@@ -2333,8 +2461,14 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, as
 				lexpr.type.Set(type);
 				if( isVarGlobOrMem == 0 )
 					lexpr.type.dataType.MakeReference(IsVariableOnHeap(offset));
-				else
+				else if( isVarGlobOrMem == 1 )
 					lexpr.type.dataType.MakeReference(true);
+				else if( isVarGlobOrMem == 2 )
+				{
+					if( !lexpr.type.dataType.IsObject() || (lexpr.type.dataType.GetObjectType()->flags & asOBJ_REF) )
+						lexpr.type.dataType.MakeReference(true);
+				}
+
 				// Allow initialization of constant variables
 				lexpr.type.dataType.MakeReadOnly(false);
 
@@ -2425,8 +2559,15 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, as
 		// Call the default constructor here, as no explicit initialization is done
 		if( isVarGlobOrMem == 0 )
 			CallDefaultConstructor(type, offset, IsVariableOnHeap(offset), bc, errNode);
-		else
+		else if( isVarGlobOrMem == 1 )
 			CallDefaultConstructor(type, offset, true, bc, errNode, isVarGlobOrMem);
+		else if( isVarGlobOrMem == 2 )
+		{
+			if( !type.IsObject() || type.IsReference() || (type.GetObjectType()->flags & asOBJ_REF) )
+				CallDefaultConstructor(type, offset, true, bc, errNode, isVarGlobOrMem);
+			else
+				CallDefaultConstructor(type, offset, false, bc, errNode, isVarGlobOrMem);
+		}
 	}
 
 	bc->OptimizeLocally(tempVariableOffsets);
@@ -2554,21 +2695,34 @@ void asCCompiler::CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByte
 		}
 		else
 		{
+			bool onHeap = true;
+
 			// Put the address where the object pointer will be placed on the stack
 			if( isVarGlobOrMem == 1 )
 				ctx.bc.InstrPTR(asBC_PGA, engine->globalProperties[var->stackOffset]->GetAddressOfValue());
 			else
 			{
-				ctx.bc.InstrSHORT(asBC_PSF, 0);
-				ctx.bc.Instr(asBC_RDSPtr);
-				ctx.bc.InstrSHORT_DW(asBC_ADDSi, (short)var->stackOffset, engine->GetTypeIdFromDataType(asCDataType::CreateObject(outFunc->objectType, false)));
+				onHeap = !var->dataType.IsObject() || var->dataType.IsReference() || (var->dataType.GetObjectType()->flags & asOBJ_REF);
+				if( onHeap )
+				{
+					ctx.bc.InstrSHORT(asBC_PSF, 0);
+					ctx.bc.Instr(asBC_RDSPtr);
+					ctx.bc.InstrSHORT_DW(asBC_ADDSi, (short)var->stackOffset, engine->GetTypeIdFromDataType(asCDataType::CreateObject(outFunc->objectType, false)));
+				}
 			}
 
 			// Add the address of the list buffer as the argument
 			ctx.bc.AddCode(&arg1.bc);
 
+			if( !onHeap )
+			{
+				ctx.bc.InstrSHORT(asBC_PSF, 0);
+				ctx.bc.Instr(asBC_RDSPtr);
+				ctx.bc.InstrSHORT_DW(asBC_ADDSi, (short)var->stackOffset, engine->GetTypeIdFromDataType(asCDataType::CreateObject(outFunc->objectType, false)));
+			}
+
 			// Call the ALLOC instruction to allocate memory and invoke constructor
-			PerformFunctionCall(funcId, &ctx, true, &args, var->dataType.GetObjectType());
+			PerformFunctionCall(funcId, &ctx, onHeap, &args, var->dataType.GetObjectType());
 		}
 	}
 
@@ -2671,6 +2825,7 @@ int asCCompiler::CompileInitListElement(asSListPatternNode *&patternNode, asCScr
 					// We now know the type
 					dt = rctx.type.dataType;
 					dt.MakeReadOnly(false);
+					dt.MakeReference(false);
 
 					// Values on the list must be aligned to 32bit boundaries, except if the type is smaller than 32bit.
 					if( bufferSize & 0x3 )
@@ -4229,7 +4384,11 @@ int asCCompiler::AllocateVariable(const asCDataType &type, bool isTemporary, boo
 int asCCompiler::GetVariableOffset(int varIndex)
 {
 	// Return offset to the last dword on the stack
+
+	// Start at 1 as offset 0 is reserved for the this pointer (or first argument for global functions)
 	int varOffset = 1;
+
+	// Skip lower variables
 	for( int n = 0; n < varIndex; n++ )
 	{
 		if( !variableIsOnHeap[n] && variableAllocations[n].IsObject() )
@@ -4240,6 +4399,7 @@ int asCCompiler::GetVariableOffset(int varIndex)
 
 	if( varIndex < (int)variableAllocations.GetLength() )
 	{
+		// For variables larger than 1 dword the returned offset should be to the last dword
 		int size;
 		if( !variableIsOnHeap[varIndex] && variableAllocations[varIndex].IsObject() )
 			size = variableAllocations[varIndex].GetSizeInMemoryDWords();
@@ -4836,6 +4996,32 @@ asUINT asCCompiler::ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const
 		return asCC_NO_CONV;
 	}
 
+	// Is the conversion an ambiguous enum value?
+	if( ctx->enumValue != "" )
+	{
+		if( to.IsEnumType() )
+		{
+			// Attempt to resolve an ambiguous enum value
+			asCDataType out;
+			asDWORD value;
+			if( builder->GetEnumValueFromObjectType(to.GetObjectType(), ctx->enumValue.AddressOf(), out, value) )
+			{
+				ctx->type.SetConstantDW(out, value);
+				ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
+
+				// It wasn't really a conversion. The compiler just resolved the ambiguity (or not)
+				return asCC_NO_CONV;
+			}
+		}
+
+		// The enum value is ambiguous
+		if( node && generateCode )
+			Error(TXT_FOUND_MULTIPLE_ENUM_VALUES, node);
+
+		// Set a dummy to allow the compiler to try to continue the conversion
+		ctx->type.SetDummy();
+	}
+
 	// Determine the cost of this conversion
 	asUINT cost = asCC_NO_CONV;
 	if( (to.IsIntegerType() || to.IsUnsignedType()) && (ctx->type.dataType.IsFloatType() || ctx->type.dataType.IsDoubleType()) )
@@ -5302,7 +5488,7 @@ asUINT asCCompiler::ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asC
 			for( unsigned int n = 0; n < funcs.GetLength(); n++ )
 			{
 				asCScriptFunction *descr = builder->GetFunctionDescription(funcs[n]);
-				if( descr->returnType.IsEqualExceptConst(target) )
+				if( descr->returnType.IsEqualExceptRefAndConst(target) )
 				{
 					funcId = funcs[n];
 					break;
@@ -6975,6 +7161,13 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asSExprContext *ctx)
 				ImplicitConversion(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
 			}
 
+			// Allow either case to be converted to const @ if the other is const @
+			if( (le.type.dataType.IsHandleToConst() && !le.type.IsNullConstant()) || (re.type.dataType.IsHandleToConst() && !re.type.dataType.IsNullHandle()) )
+			{
+				le.type.dataType.MakeHandleToConst(true);
+				re.type.dataType.MakeHandleToConst(true);
+			}
+
 			//---------------------------------
 			// Output the byte code
 			int afterLabel = nextLabel++;
@@ -7639,7 +7832,15 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 					found = true;
 					if( e == 2 )
 					{
-						Error(TXT_FOUND_MULTIPLE_ENUM_VALUES, errNode);
+						// Ambiguous enum value: Save the name for resolution later.
+						// The ambiguity could be resolved now, but I hesitate
+						// to store too much information in the context.
+						ctx->enumValue = name.AddressOf();
+						
+						// We cannot set a dummy value because it will pass through
+						// cleanly as an integer.
+						ctx->type.SetConstantDW(asCDataType::CreatePrimitive(ttIdentifier, true), 0);
+						return 0;
 					}
 				}
 			}
@@ -8680,6 +8881,8 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 		{
 			int r = asSUCCESS;
 
+			// TODO: 2.28.1: Merge this with MakeFunctionCall
+
 			// Add the default values for arguments not explicitly supplied
 			asCScriptFunction *func = (funcs[0] & FUNC_IMPORTED) == 0 ? engine->scriptFunctions[funcs[0]] : 0;
 			if( func && args.GetLength() < (asUINT)func->GetParamCount() )
@@ -8897,7 +9100,6 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, a
 
 	// Compile the arguments
 	asCArray<asSExprContext *> args;
-	asCArray<asCTypeInfo> temporaryVariables;
 
 	if( CompileArgumentList(node->lastChild, args) >= 0 )
 	{
@@ -8926,7 +9128,14 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, a
 			// Add the default values for arguments not explicitly supplied
 			asCScriptFunction *func = builder->GetFunctionDescription(funcs[0]);
 			if( func && args.GetLength() < (asUINT)func->GetParamCount() )
-				r = CompileDefaultArgs(node, args, func);
+			{
+				// Make sure to use the real function for virtual functions
+				asCScriptFunction *realFunc = func;
+				if( realFunc->funcType == asFUNC_VIRTUAL )
+					realFunc = objectType->virtualFunctionTable[realFunc->vfTableIdx];
+
+				r = CompileDefaultArgs(node, args, realFunc);
+			}
 
 			// TODO: funcdef: Do we have to make sure the handle is stored in a temporary variable, or
 			//                is it enough to make sure it is in a local variable?
@@ -10390,6 +10599,7 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 
 int asCCompiler::GetPrecedence(asCScriptNode *op)
 {
+	// x ** y
 	// x * y, x / y, x % y
 	// x + y, x - y
 	// x <= y, x < y, x >= y, x > y
@@ -10408,40 +10618,43 @@ int asCCompiler::GetPrecedence(asCScriptNode *op)
 
 	// Evaluate operators by token
 	int tokenType = op->tokenType;
-	if( tokenType == ttStar || tokenType == ttSlash || tokenType == ttPercent )
+	if( tokenType == ttStarStar )
 		return 0;
 
-	if( tokenType == ttPlus || tokenType == ttMinus )
+	if( tokenType == ttStar || tokenType == ttSlash || tokenType == ttPercent )
 		return -1;
 
+	if( tokenType == ttPlus || tokenType == ttMinus )
+		return -2;
+
 	if( tokenType == ttBitShiftLeft ||
 		tokenType == ttBitShiftRight ||
 		tokenType == ttBitShiftRightArith )
-		return -2;
+		return -3;
 
 	if( tokenType == ttAmp )
-		return -3;
+		return -4;
 
 	if( tokenType == ttBitXor )
-		return -4;
+		return -5;
 
 	if( tokenType == ttBitOr )
-		return -5;
+		return -6;
 
 	if( tokenType == ttLessThanOrEqual ||
 		tokenType == ttLessThan ||
 		tokenType == ttGreaterThanOrEqual ||
 		tokenType == ttGreaterThan )
-		return -6;
+		return -7;
 
 	if( tokenType == ttEqual || tokenType == ttNotEqual || tokenType == ttXor || tokenType == ttIs || tokenType == ttNotIs )
-		return -7;
+		return -8;
 
 	if( tokenType == ttAnd )
-		return -8;
+		return -9;
 
 	if( tokenType == ttOr )
-		return -9;
+		return -10;
 
 	// Unknown operator
 	asASSERT(false);
@@ -10473,6 +10686,7 @@ asUINT asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<asSOverloadCand
 		asSExprContext ti(engine);
 		ti.type = argExpr->type;
 		ti.methodName = argExpr->methodName;
+		ti.enumValue = argExpr->enumValue;
 		if( argExpr->type.dataType.IsPrimitive() ) ti.type.dataType.MakeReference(false);
 		asUINT cost = ImplicitConversion(&ti, desc->parameterTypes[paramNum], 0, asIC_IMPLICIT_CONV, false, allowObjectConstruct);
 
@@ -10669,6 +10883,7 @@ bool asCCompiler::CompileOverloadedDualOperator(asCScriptNode *node, asSExprCont
 	case ttStar:               op = "opMul";  op_r = "opMul_r";  break;
 	case ttSlash:              op = "opDiv";  op_r = "opDiv_r";  break;
 	case ttPercent:            op = "opMod";  op_r = "opMod_r";  break;
+	case ttStarStar:           op = "opPow";  op_r = "opPow_r";  break;
 	case ttBitOr:              op = "opOr";   op_r = "opOr_r";   break;
 	case ttAmp:                op = "opAnd";  op_r = "opAnd_r";  break;
 	case ttBitXor:             op = "opXor";  op_r = "opXor_r";  break;
@@ -10713,6 +10928,7 @@ bool asCCompiler::CompileOverloadedDualOperator(asCScriptNode *node, asSExprCont
 	case ttMulAssign:         op = "opMulAssign";  break;
 	case ttDivAssign:         op = "opDivAssign";  break;
 	case ttModAssign:         op = "opModAssign";  break;
+	case ttPowAssign:         op = "opPowAssign";  break;
 	case ttOrAssign:          op = "opOrAssign";   break;
 	case ttAndAssign:         op = "opAndAssign";  break;
 	case ttXorAssign:         op = "opXorAssign";  break;
@@ -10995,13 +11211,14 @@ int asCCompiler::CompileOperator(asCScriptNode *node, asSExprContext *lctx, asSE
 		}
 
 		// Math operators
-		// + - * / % += -= *= /= %=
+		// + - * / % ** += -= *= /= %= **=
 		int op = node->tokenType;
-		if( op == ttPlus    || op == ttAddAssign ||
-			op == ttMinus   || op == ttSubAssign ||
-			op == ttStar    || op == ttMulAssign ||
-			op == ttSlash   || op == ttDivAssign ||
-			op == ttPercent || op == ttModAssign )
+		if( op == ttPlus     || op == ttAddAssign ||
+			op == ttMinus    || op == ttSubAssign ||
+			op == ttStar     || op == ttMulAssign ||
+			op == ttSlash    || op == ttDivAssign ||
+			op == ttPercent  || op == ttModAssign ||
+			op == ttStarStar || op == ttPowAssign )
 		{
 			CompileMathOperator(node, lctx, rctx, ctx);
 			return 0;
@@ -11213,10 +11430,25 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 	if( rctx->type.dataType.IsReference() )
 		ConvertToVariable(rctx);
 
+	int op = node->tokenType;
 	if( to.IsPrimitive() )
 	{
-		ImplicitConversion(lctx, to, node, asIC_IMPLICIT_CONV, true);
-		ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true);
+		// ttStarStar allows an integer, right-hand operand and a double
+		// left-hand operand.
+		if( (op == ttStarStar || op == ttPowAssign) &&
+			lctx->type.dataType.IsDoubleType() &&
+			(rctx->type.dataType.IsIntegerType() ||
+			    rctx->type.dataType.IsUnsignedType()) )
+		{
+			to.SetTokenType(ttInt);
+			ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true);
+			to.SetTokenType(ttDouble);
+		}
+		else
+		{
+			ImplicitConversion(lctx, to, node, asIC_IMPLICIT_CONV, true);
+			ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true);
+		}
 	}
 	reservedVariables.SetLength(l);
 
@@ -11250,7 +11482,6 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 	bool isConstant = lctx->type.isConstant && rctx->type.isConstant;
 
 	// Verify if we are dividing with a constant zero
-	int op = node->tokenType;
 	if( rctx->type.isConstant && rctx->type.qwordValue == 0 &&
 		(op == ttSlash   || op == ttDivAssign ||
 		 op == ttPercent || op == ttModAssign) )
@@ -11267,7 +11498,7 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 
 		if( op == ttAddAssign || op == ttSubAssign ||
 			op == ttMulAssign || op == ttDivAssign ||
-			op == ttModAssign )
+			op == ttModAssign || op == ttPowAssign )
 		{
 			// Merge the operands in the different order so that they are evaluated correctly
 			MergeExprBytecode(ctx, rctx);
@@ -11310,6 +11541,13 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 					else
 						instruction = asBC_MODu;
 				}
+				else if( op == ttStarStar || op == ttPowAssign )
+				{
+					if( lctx->type.dataType.IsIntegerType() )
+						instruction = asBC_POWi;
+					else
+						instruction = asBC_POWu;
+				}
 			}
 			else
 			{
@@ -11333,6 +11571,13 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 					else
 						instruction = asBC_MODu64;
 				}
+				else if( op == ttStarStar || op == ttPowAssign )
+				{
+					if( lctx->type.dataType.IsIntegerType() )
+						instruction = asBC_POWi64;
+					else
+						instruction = asBC_POWu64;
+				}
 			}
 		}
 		else if( lctx->type.dataType.IsFloatType() )
@@ -11347,19 +11592,35 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 				instruction = asBC_DIVf;
 			else if( op == ttPercent || op == ttModAssign )
 				instruction = asBC_MODf;
+			else if( op == ttStarStar || op == ttPowAssign )
+				instruction = asBC_POWf;
 		}
 		else if( lctx->type.dataType.IsDoubleType() )
 		{
-			if( op == ttPlus || op == ttAddAssign )
-				instruction = asBC_ADDd;
-			else if( op == ttMinus || op == ttSubAssign )
-				instruction = asBC_SUBd;
-			else if( op == ttStar || op == ttMulAssign )
-				instruction = asBC_MULd;
-			else if( op == ttSlash || op == ttDivAssign )
-				instruction = asBC_DIVd;
-			else if( op == ttPercent || op == ttModAssign )
-				instruction = asBC_MODd;
+			if( rctx->type.dataType.IsIntegerType() )
+			{
+				asASSERT(rctx->type.dataType.GetSizeInMemoryDWords() == 1);
+
+				if( op == ttStarStar || op == ttPowAssign )
+					instruction = asBC_POWdi;
+				else
+					asASSERT(false);  // Should not be possible
+			}
+			else
+			{
+				if( op == ttPlus || op == ttAddAssign )
+					instruction = asBC_ADDd;
+				else if( op == ttMinus || op == ttSubAssign )
+					instruction = asBC_SUBd;
+				else if( op == ttStar || op == ttMulAssign )
+					instruction = asBC_MULd;
+				else if( op == ttSlash || op == ttDivAssign )
+					instruction = asBC_DIVd;
+				else if( op == ttPercent || op == ttModAssign )
+					instruction = asBC_MODd;
+				else if( op == ttStarStar || op == ttPowAssign )
+					instruction = asBC_POWd;
+			}
 		}
 		else
 		{
@@ -11413,6 +11674,14 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 						else
 							v = lctx->type.dwordValue % rctx->type.dwordValue;
 				}
+				else if( op == ttStarStar )
+				{
+					bool isOverflow;
+					if( lctx->type.dataType.IsIntegerType() )
+						v = as_powi(lctx->type.intValue, rctx->type.intValue, isOverflow);
+					else
+						v = as_powu(lctx->type.dwordValue, rctx->type.dwordValue, isOverflow);
+				}
 
 				ctx->type.SetConstantDW(lctx->type.dataType, v);
 
@@ -11451,6 +11720,14 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 						else
 							v = lctx->type.qwordValue % rctx->type.qwordValue;
 				}
+				else if( op == ttStarStar )
+				{
+					bool isOverflow;
+					if( lctx->type.dataType.IsIntegerType() )
+						v = as_powi64(asINT64(lctx->type.qwordValue), asINT64(rctx->type.qwordValue), isOverflow);
+					else
+						v = as_powu64(lctx->type.qwordValue, rctx->type.qwordValue, isOverflow);
+				}
 
 				ctx->type.SetConstantQW(lctx->type.dataType, v);
 
@@ -11482,31 +11759,47 @@ void asCCompiler::CompileMathOperator(asCScriptNode *node, asSExprContext *lctx,
 				else
 					v = fmodf(lctx->type.floatValue, rctx->type.floatValue);
 			}
+			else if( op == ttStarStar )
+				v = pow(lctx->type.floatValue, rctx->type.floatValue);
 
 			ctx->type.SetConstantF(lctx->type.dataType, v);
 		}
 		else if( lctx->type.dataType.IsDoubleType() )
 		{
 			double v = 0.0;
-			if( op == ttPlus )
-				v = lctx->type.doubleValue + rctx->type.doubleValue;
-			else if( op == ttMinus )
-				v = lctx->type.doubleValue - rctx->type.doubleValue;
-			else if( op == ttStar )
-				v = lctx->type.doubleValue * rctx->type.doubleValue;
-			else if( op == ttSlash )
+			if( rctx->type.dataType.IsIntegerType() )
 			{
-				if( rctx->type.doubleValue == 0 )
-					v = 0;
+				asASSERT(rctx->type.dataType.GetSizeInMemoryDWords() == 1);
+
+				if( op == ttStarStar || op == ttPowAssign )
+					v = pow(lctx->type.doubleValue, rctx->type.intValue);
 				else
-					v = lctx->type.doubleValue / rctx->type.doubleValue;
+					asASSERT(false);  // Should not be possible
 			}
-			else if( op == ttPercent )
+			else
 			{
-				if( rctx->type.doubleValue == 0 )
-					v = 0;
-				else
-					v = fmod(lctx->type.doubleValue, rctx->type.doubleValue);
+				if( op == ttPlus )
+					v = lctx->type.doubleValue + rctx->type.doubleValue;
+				else if( op == ttMinus )
+					v = lctx->type.doubleValue - rctx->type.doubleValue;
+				else if( op == ttStar )
+					v = lctx->type.doubleValue * rctx->type.doubleValue;
+				else if( op == ttSlash )
+				{
+					if( rctx->type.doubleValue == 0 )
+						v = 0;
+					else
+						v = lctx->type.doubleValue / rctx->type.doubleValue;
+				}
+				else if( op == ttPercent )
+				{
+					if( rctx->type.doubleValue == 0 )
+						v = 0;
+					else
+						v = fmod(lctx->type.doubleValue, rctx->type.doubleValue);
+				}
+				else if( op == ttStarStar )
+					v = pow(lctx->type.doubleValue, rctx->type.doubleValue);
 			}
 
 			ctx->type.SetConstantD(lctx->type.dataType, v);
@@ -12693,6 +12986,7 @@ void asCCompiler::MergeExprBytecodeAndType(asSExprContext *before, asSExprContex
 	before->property_arg    = after->property_arg;
 	before->exprNode        = after->exprNode;
 	before->methodName      = after->methodName;
+	before->enumValue       = after->enumValue;
 
 	after->property_arg = 0;
 

+ 2 - 0
Source/ThirdParty/AngelScript/source/as_compiler.h

@@ -130,7 +130,9 @@ struct asSExprContext
 	asCArray<asSDeferredParam> deferredParams;
 	asCScriptNode  *exprNode;
 	asSExprContext *origExpr;
+	// TODO: cleanup: use ambiguousName and an enum to say if it is a method, global func, or enum value
 	asCString methodName;
+	asCString enumValue;
 };
 
 struct asSOverloadCandidate

+ 34 - 6
Source/ThirdParty/AngelScript/source/as_config.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -29,6 +29,7 @@
 */
 
 
+
 //
 // as_config.h
 //
@@ -196,6 +197,10 @@
 // AS_ARM
 // Use assembler code for the ARM CPU family
 
+// AS_SOFTFP
+// Use to tell compiler that ARM soft-float ABI
+// should be used instead of ARM hard-float ABI
+
 // AS_X64_GCC
 // Use GCC assembler code for the X64 AMD/Intel CPU family
 
@@ -377,6 +382,7 @@
 #endif
 
 // Microsoft Visual C++
+// Ref: http://msdn.microsoft.com/en-us/library/b0084kay.aspx
 #if defined(_MSC_VER) && !defined(__MWERKS__)
 
 	#if _MSC_VER <= 1200 // MSVC6
@@ -457,7 +463,7 @@
 		#endif
 	#endif
 
-	#ifdef _ARM_
+	#if defined(_ARM_) || defined(_M_ARM)
 		#define AS_ARM
 		#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#define CDECL_RETURN_SIMPLE_IN_MEMORY
@@ -465,6 +471,7 @@
 		#define COMPLEX_OBJS_PASSED_BY_REF
 		#define COMPLEX_MASK asOBJ_APP_CLASS_ASSIGNMENT
 		#define COMPLEX_RETURN_MASK asOBJ_APP_CLASS_ASSIGNMENT
+		#define AS_SOFTFP
 	#endif
 
 	#ifndef COMPLEX_MASK
@@ -545,7 +552,7 @@
 #endif
 
 // GNU C (and MinGW or Cygwin on Windows)
-// Use the following command to determine predefined macros: echo . | mingw32-g++ -dM -E -
+// Use the following command to determine predefined macros: echo . | g++ -dM -E -
 #if (defined(__GNUC__) && !defined(__SNC__)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
 	#define GNU_STYLE_VIRTUAL_METHOD
 #if !defined( __amd64__ )
@@ -592,6 +599,8 @@
 		#elif defined(I3D_ARCH_ARM)
 			#define AS_ARM
 
+			#define AS_SOFTFP
+
 			// Marmalade appear to use the same ABI as Android when built for ARM
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -640,9 +649,8 @@
 		#endif
 
 		#if (defined(_ARM_) || defined(__arm__))
-			// The IPhone use an ARM processor
+			// iOS use ARM processor
 			#define AS_ARM
-			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
@@ -662,6 +670,9 @@
 			#undef COMPLEX_RETURN_MASK
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 
+			// iOS uses soft-float ABI
+			#define AS_SOFTFP
+
 			// STDCALL is not available on ARM
 			#undef STDCALL
 			#define STDCALL
@@ -785,7 +796,9 @@
 			#define STDCALL
 		#elif defined(__ARMEL__) || defined(__arm__)
 			#define AS_ARM
-			#define AS_NO_ATOMIC
+
+			#undef STDCALL
+			#define STDCALL
 
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -798,6 +811,20 @@
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+
+			#ifndef AS_MAX_PORTABILITY
+			// Make a few checks against incompatible ABI combinations
+			#if defined(__FAST_MATH__) && __FAST_MATH__ == 1
+				#error -ffast-math is not supported with native calling conventions
+			#endif
+			#endif
+
+			// Verify if soft-float or hard-float ABI is used
+			#if defined(__SOFTFP__) && __SOFTFP__ == 1
+				// -ffloat-abi=softfp or -ffloat-abi=soft
+				#define AS_SOFTFP	
+			#endif
+
 		#elif defined(__mips__)
 			#define AS_MIPS
 			#define AS_BIG_ENDIAN
@@ -916,6 +943,7 @@
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 
 			#define AS_ARM
+			#define AS_SOFTFP
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#endif
 

+ 33 - 7
Source/ThirdParty/AngelScript/source/as_configgroup.cpp

@@ -120,8 +120,10 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 	// Remove global functions
 	for( n = 0; n < scriptFunctions.GetLength(); n++ )
 	{
+		int index = engine->registeredGlobalFuncs.GetIndex(scriptFunctions[n]);
+		if( index >= 0 )
+			engine->registeredGlobalFuncs.Erase(index);
 		scriptFunctions[n]->Release();
-		engine->registeredGlobalFuncs.RemoveValue(scriptFunctions[n]);
 		if( engine->stringFactory == scriptFunctions[n] )
 			engine->stringFactory = 0;
 	}
@@ -143,20 +145,23 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 	}
 	funcDefs.SetLength(0);
 
+	engine->ClearUnusedTypes();
+
 	// Remove object types (skip this if it is possible other groups are still using the types)
 	if( !notUsed )
 	{
 		for( n = 0; n < objTypes.GetLength(); n++ )
 		{
 			asCObjectType *t = objTypes[n];
-			int idx = engine->objectTypes.IndexOf(t);
-			if( idx >= 0 )
+			asSMapNode<asSNameSpaceNamePair, asCObjectType*> *cursor;
+			if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
+				cursor->value == t )
 			{
 #ifdef AS_DEBUG
 				ValidateNoUsage(engine, t);
 #endif
 
-				engine->objectTypes.RemoveIndex(idx);
+				engine->allRegisteredTypes.Erase(cursor);
 				if( engine->defaultArrayObjectType == t )
 					engine->defaultArrayObjectType = 0;
 
@@ -164,11 +169,28 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 					engine->registeredTypeDefs.RemoveValue(t);
 				else if( t->flags & asOBJ_ENUM )
 					engine->registeredEnums.RemoveValue(t);
+				else if( t->flags & asOBJ_TEMPLATE )
+					engine->registeredTemplateTypes.RemoveValue(t);
 				else
 					engine->registeredObjTypes.RemoveValue(t);
 
 				asDELETE(t, asCObjectType);
 			}
+			else
+			{
+				int idx = engine->templateInstanceTypes.IndexOf(t);
+				if( idx >= 0 )
+				{
+#ifdef AS_DEBUG
+					ValidateNoUsage(engine, t);
+#endif
+
+					engine->templateInstanceTypes.RemoveIndexUnordered(idx);
+					t->templateSubTypes.SetLength(0);
+
+					asDELETE(t, asCObjectType);
+				}
+			}
 		}
 		objTypes.SetLength(0);
 	}
@@ -188,18 +210,22 @@ void asCConfigGroup::ValidateNoUsage(asCScriptEngine *engine, asCObjectType *typ
 		if( func == 0 ) continue;
 
 		// Ignore factory, list factory, and members
-		if( func->name == "_beh_2_" || func->name == "_beh_3_" || func->objectType == type )
+		if( func->name == "_beh_3_" || func->name == "_beh_4_" || func->objectType == type )
 			continue;
 
 		// Ignore function definitions too, as they aren't released until the engine is destroyed
 		if( func->funcType == asFUNC_FUNCDEF )
 			continue;
 
+		// Ignore functions whose object type has already reached refCount 0 as they are to be removed
+		if( func->objectType && func->objectType->GetRefCount() == 0 )
+			continue;
+
 		if( func->returnType.GetObjectType() == type )
 		{
 			asCString msg;
 			// We can only use the function name here, because the types used by the function may have been deleted already
-			msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetName());
+			msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
 		}
 		else
@@ -210,7 +236,7 @@ void asCConfigGroup::ValidateNoUsage(asCScriptEngine *engine, asCObjectType *typ
 				{
 					asCString msg;
 					// We can only use the function name here, because the types used by the function may have been deleted already
-					msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetName());
+					msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
 					engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
 					break;
 				}

+ 551 - 43
Source/ThirdParty/AngelScript/source/as_context.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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,7 @@
 // This class handles the execution of the byte code
 //
 
-#include <math.h> // fmodf()
+#include <math.h> // fmodf() pow()
 
 #include "as_config.h"
 #include "as_context.h"
@@ -310,7 +310,7 @@ int asCContext::Prepare(asIScriptFunction *func)
 	if( m_status == asEXECUTION_ACTIVE || m_status == asEXECUTION_SUSPENDED )
 	{
 		asCString str;
-		str.Format(TXT_FAILED_IN_FUNC_s_d, "Prepare", asCONTEXT_ACTIVE);
+		str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_d, "Prepare", func->GetDeclaration(true, true), asCONTEXT_ACTIVE);
 		m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 		return asCONTEXT_ACTIVE;
 	}
@@ -338,6 +338,15 @@ int asCContext::Prepare(asIScriptFunction *func)
 	{
 		asASSERT( m_engine );
 
+		// Make sure the function is from the same engine as the context to avoid mixups
+		if( m_engine != func->GetEngine() )
+		{
+			asCString str;
+			str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_d, "Prepare", func->GetDeclaration(true, true), asINVALID_ARG);
+			m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+			return asINVALID_ARG;
+		}
+
 		if( m_initialFunction )
 		{
 			m_initialFunction->Release();
@@ -1104,13 +1113,10 @@ int asCContext::Execute()
 					}
 				}
 
-				if( realFunc )
-				{
-					if( realFunc->signatureId != m_currentFunction->signatureId )
-						SetInternalException(TXT_NULL_POINTER_ACCESS);
-					else
-						m_currentFunction = realFunc;
-				}
+				if( realFunc && realFunc->signatureId == m_currentFunction->signatureId )
+					m_currentFunction = realFunc;
+				else
+					SetInternalException(TXT_NULL_POINTER_ACCESS);
 			}
 		}
 
@@ -1136,8 +1142,9 @@ int asCContext::Execute()
 		}
 		else
 		{
-			// This shouldn't happen
-			asASSERT(false);
+			// This shouldn't happen unless there was an error in which
+			// case an exception should have been raised already
+			asASSERT( m_status == asEXECUTION_EXCEPTION );
 		}
 	}
 
@@ -1565,39 +1572,44 @@ void asCContext::CallInterfaceMethod(asCScriptFunction *func)
 
 	asCObjectType *objType = obj->objType;
 
-	// TODO: runtime optimize: The object type should have a list of only those methods that
-	//                         implement interface methods. This list should be ordered by
-	//                         the signatureId so that a binary search can be made, instead
-	//                         of a linear search.
-	//
-	//                         When this is done, we must also make sure the signatureId of a
-	//                         function never changes, e.g. when if the signature functions are
-	//                         released.
-
 	// Search the object type for a function that matches the interface function
 	asCScriptFunction *realFunc = 0;
 	if( func->funcType == asFUNC_INTERFACE )
 	{
-		for( asUINT n = 0; n < objType->methods.GetLength(); n++ )
+		// Find the offset for the interface's virtual function table chunk
+		asUINT offset = 0;
+		bool found = false;
+		asCObjectType *findInterface = func->objectType;
+
+		// TODO: runtime optimize: The list of interfaces should be ordered by the address
+		//                         Then a binary search pattern can be used.
+		asUINT intfCount = asUINT(objType->interfaces.GetLength());
+		for( asUINT n = 0; n < intfCount; n++ )
 		{
-			asCScriptFunction *f2 = m_engine->scriptFunctions[objType->methods[n]];
-			if( f2->signatureId == func->signatureId )
+			if( objType->interfaces[n] == findInterface )
 			{
-				if( f2->funcType == asFUNC_VIRTUAL )
-					realFunc = objType->virtualFunctionTable[f2->vfTableIdx];
-				else
-					realFunc = f2;
+				offset = objType->interfaceVFTOffsets[n];
+				found = true;
 				break;
 			}
 		}
 
-		if( realFunc == 0 )
+		if( !found )
 		{
 			// Tell the exception handler to clean up the arguments to this method
 			m_needToCleanupArgs = true;
 			SetInternalException(TXT_NULL_POINTER_ACCESS);
 			return;
 		}
+
+		// Find the real function in the virtual table chunk with the found offset
+		realFunc = objType->virtualFunctionTable[func->vfTableIdx + offset];
+
+		// Since the interface was implemented by the class, it shouldn't
+		// be possible that the real function isn't found
+		asASSERT( realFunc );
+
+		asASSERT( realFunc->signatureId == func->signatureId );
 	}
 	else // if( func->funcType == asFUNC_VIRTUAL )
 	{
@@ -3634,7 +3646,7 @@ void asCContext::ExecuteNext()
 				}
 				else if( func->funcType == asFUNC_DELEGATE )
 				{
-					// Push the object pointer on the stack. There is always a reserved space for this so 
+					// Push the object pointer on the stack. There is always a reserved space for this so
 					// we don't don't need to worry about overflowing the allocated memory buffer
 					asASSERT( m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex] );
 					m_regs.stackPointer -= AS_PTR_SIZE;
@@ -3904,7 +3916,7 @@ void asCContext::ExecuteNext()
 
 	case asBC_SetListSize:
 		{
-			// Set the size element in the buffer 
+			// Set the size element in the buffer
 			asBYTE *var = *(asBYTE**)(l_fp - asBC_SWORDARG0(l_bc));
 			asUINT off  = asBC_DWORDARG(l_bc);
 			asUINT size = asBC_DWORDARG(l_bc+1);
@@ -3924,7 +3936,7 @@ void asCContext::ExecuteNext()
 			asUINT off = asBC_DWORDARG(l_bc);
 
 			asASSERT( var );
-			
+
 			l_sp -= AS_PTR_SIZE;
 			*(asPWORD*)l_sp = asPWORD(var+off);
 		}
@@ -3933,7 +3945,7 @@ void asCContext::ExecuteNext()
 
 	case asBC_SetListType:
 		{
-			// Set the type id in the buffer 
+			// Set the type id in the buffer
 			asBYTE *var = *(asBYTE**)(l_fp - asBC_SWORDARG0(l_bc));
 			asUINT off  = asBC_DWORDARG(l_bc);
 			asUINT type = asBC_DWORDARG(l_bc+1);
@@ -3945,16 +3957,143 @@ void asCContext::ExecuteNext()
 		l_bc += 3;
 		break;
 
+	//------------------------------
+	// Exponent operations
+	case asBC_POWi:
+		{
+			bool isOverflow;
+			*(int*)(l_fp - asBC_SWORDARG0(l_bc)) = as_powi(*(int*)(l_fp - asBC_SWORDARG1(l_bc)), *(int*)(l_fp - asBC_SWORDARG2(l_bc)), isOverflow);
+			if( isOverflow )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
+	case asBC_POWu:
+		{
+			bool isOverflow;
+			*(asDWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = as_powu(*(asDWORD*)(l_fp - asBC_SWORDARG1(l_bc)), *(asDWORD*)(l_fp - asBC_SWORDARG2(l_bc)), isOverflow);
+			if( isOverflow )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
+	case asBC_POWf:
+		{
+			float r = powf(*(float*)(l_fp - asBC_SWORDARG1(l_bc)), *(float*)(l_fp - asBC_SWORDARG2(l_bc)));
+			*(float*)(l_fp - asBC_SWORDARG0(l_bc)) = r;
+			if( r == float(HUGE_VAL) )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
+	case asBC_POWd:
+		{
+			double r = pow(*(double*)(l_fp - asBC_SWORDARG1(l_bc)), *(double*)(l_fp - asBC_SWORDARG2(l_bc)));
+			*(double*)(l_fp - asBC_SWORDARG0(l_bc)) = r;
+			if( r == HUGE_VAL )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
+	case asBC_POWdi:
+		{
+			double r = pow(*(double*)(l_fp - asBC_SWORDARG1(l_bc)), *(int*)(l_fp - asBC_SWORDARG2(l_bc)));
+			*(double*)(l_fp - asBC_SWORDARG0(l_bc)) = r;
+			if( r == HUGE_VAL )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+			l_bc += 2;
+		}
+		break;
+
+	case asBC_POWi64:
+		{
+			bool isOverflow;
+			*(asINT64*)(l_fp - asBC_SWORDARG0(l_bc)) = as_powi64(*(asINT64*)(l_fp - asBC_SWORDARG1(l_bc)), *(asINT64*)(l_fp - asBC_SWORDARG2(l_bc)), isOverflow);
+			if( isOverflow )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
+	case asBC_POWu64:
+		{
+			bool isOverflow;
+			*(asQWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = as_powu64(*(asQWORD*)(l_fp - asBC_SWORDARG1(l_bc)), *(asQWORD*)(l_fp - asBC_SWORDARG2(l_bc)), isOverflow);
+			if( isOverflow )
+			{
+				// Need to move the values back to the context
+				m_regs.programPointer    = l_bc;
+				m_regs.stackPointer      = l_sp;
+				m_regs.stackFramePointer = l_fp;
+
+				// Raise exception
+				SetInternalException(TXT_POW_OVERFLOW);
+				return;
+			}
+		}
+		l_bc += 2;
+		break;
+
 	// Don't let the optimizer optimize for size,
 	// since it requires extra conditions and jumps
-	case 193: l_bc = (asDWORD*)193; break;
-	case 194: l_bc = (asDWORD*)194; break;
-	case 195: l_bc = (asDWORD*)195; break;
-	case 196: l_bc = (asDWORD*)196; break;
-	case 197: l_bc = (asDWORD*)197; break;
-	case 198: l_bc = (asDWORD*)198; break;
-	case 199: l_bc = (asDWORD*)199; break;
-	case 200: l_bc = (asDWORD*)200; break;
 	case 201: l_bc = (asDWORD*)201; break;
 	case 202: l_bc = (asDWORD*)202; break;
 	case 203: l_bc = (asDWORD*)203; break;
@@ -4553,7 +4692,7 @@ int asCContext::GetExceptionLineNumber(int *column, const char **sectionName)
 
 	if( column ) *column = m_exceptionColumn;
 
-	if( sectionName ) 
+	if( sectionName )
 	{
 		// The section index can be -1 if the exception was raised in a generated function, e.g. factstub for templates
 		if( m_exceptionSectionIdx >= 0 )
@@ -4826,7 +4965,7 @@ void *asCContext::GetAddressOfVar(asUINT varIndex, asUINT stackLevel)
 	if( func == 0 )
 		return 0;
 
-	if( func->scriptData == 0 ) 
+	if( func->scriptData == 0 )
 		return 0;
 
 	if( varIndex >= func->scriptData->variables.GetLength() )
@@ -4956,6 +5095,375 @@ void *asCContext::GetThisPointer(asUINT stackLevel)
 	return thisPointer;
 }
 
+
+
+
+
+
+
+// TODO: Move these to as_utils.cpp
+
+struct POW_INFO
+{
+	asQWORD MaxBaseu64;
+	asDWORD MaxBasei64;
+	asWORD  MaxBaseu32;
+	asWORD  MaxBasei32;
+	char    HighBit;
+};
+
+const POW_INFO pow_info[] =
+{
+	{          0ULL,          0UL,     0,     0, 0 },  // 0 is a special case
+	{          0ULL,          0UL,     0,     0, 1 },  // 1 is a special case
+    { 3037000499ULL, 2147483647UL, 65535, 46340, 2 },  // 2
+    {    2097152ULL,    1664510UL,  1625,  1290, 2 },  // 3
+    {      55108ULL,      46340UL,   255,   215, 3 },  // 4
+    {       6208ULL,       5404UL,    84,    73, 3 },  // 5
+    {       1448ULL,       1290UL,    40,    35, 3 },  // 6
+    {        511ULL,        463UL,    23,    21, 3 },  // 7
+    {        234ULL,        215UL,    15,    14, 4 },  // 8
+    {        128ULL,        118UL,    11,    10, 4 },  // 9
+    {         78ULL,         73UL,     9,     8, 4 },  // 10
+    {         52ULL,         49UL,     7,     7, 4 },  // 11
+    {         38ULL,         35UL,     6,     5, 4 },  // 12
+    {         28ULL,         27UL,     5,     5, 4 },  // 13
+    {         22ULL,         21UL,     4,     4, 4 },  // 14
+    {         18ULL,         17UL,     4,     4, 4 },  // 15
+    {         15ULL,         14UL,     3,     3, 5 },  // 16
+    {         13ULL,         12UL,     3,     3, 5 },  // 17
+    {         11ULL,         10UL,     3,     3, 5 },  // 18
+    {          9ULL,          9UL,     3,     3, 5 },  // 19
+    {          8ULL,          8UL,     3,     2, 5 },  // 20
+    {          8ULL,          7UL,     2,     2, 5 },  // 21
+    {          7ULL,          7UL,     2,     2, 5 },  // 22
+    {          6ULL,          6UL,     2,     2, 5 },  // 23
+    {          6ULL,          5UL,     2,     2, 5 },  // 24
+    {          5ULL,          5UL,     2,     2, 5 },  // 25
+    {          5ULL,          5UL,     2,     2, 5 },  // 26
+    {          5ULL,          4UL,     2,     2, 5 },  // 27
+    {          4ULL,          4UL,     2,     2, 5 },  // 28
+    {          4ULL,          4UL,     2,     2, 5 },  // 29
+    {          4ULL,          4UL,     2,     2, 5 },  // 30
+    {          4ULL,          4UL,     2,     1, 5 },  // 31
+    {          3ULL,          3UL,     1,     1, 6 },  // 32
+    {          3ULL,          3UL,     1,     1, 6 },  // 33
+    {          3ULL,          3UL,     1,     1, 6 },  // 34
+    {          3ULL,          3UL,     1,     1, 6 },  // 35
+    {          3ULL,          3UL,     1,     1, 6 },  // 36
+    {          3ULL,          3UL,     1,     1, 6 },  // 37
+    {          3ULL,          3UL,     1,     1, 6 },  // 38
+    {          3ULL,          3UL,     1,     1, 6 },  // 39
+    {          2ULL,          2UL,     1,     1, 6 },  // 40
+    {          2ULL,          2UL,     1,     1, 6 },  // 41
+    {          2ULL,          2UL,     1,     1, 6 },  // 42
+    {          2ULL,          2UL,     1,     1, 6 },  // 43
+    {          2ULL,          2UL,     1,     1, 6 },  // 44
+    {          2ULL,          2UL,     1,     1, 6 },  // 45
+    {          2ULL,          2UL,     1,     1, 6 },  // 46
+    {          2ULL,          2UL,     1,     1, 6 },  // 47
+    {          2ULL,          2UL,     1,     1, 6 },  // 48
+    {          2ULL,          2UL,     1,     1, 6 },  // 49
+    {          2ULL,          2UL,     1,     1, 6 },  // 50
+    {          2ULL,          2UL,     1,     1, 6 },  // 51
+    {          2ULL,          2UL,     1,     1, 6 },  // 52
+    {          2ULL,          2UL,     1,     1, 6 },  // 53
+    {          2ULL,          2UL,     1,     1, 6 },  // 54
+    {          2ULL,          2UL,     1,     1, 6 },  // 55
+    {          2ULL,          2UL,     1,     1, 6 },  // 56
+    {          2ULL,          2UL,     1,     1, 6 },  // 57
+    {          2ULL,          2UL,     1,     1, 6 },  // 58
+    {          2ULL,          2UL,     1,     1, 6 },  // 59
+    {          2ULL,          2UL,     1,     1, 6 },  // 60
+    {          2ULL,          2UL,     1,     1, 6 },  // 61
+    {          2ULL,          2UL,     1,     1, 6 },  // 62
+	{          2ULL,          1UL,     1,     1, 6 },  // 63
+};
+
+int as_powi(int base, int exponent, bool& isOverflow)
+{
+	if( exponent < 0 )
+	{
+		if( base == 0 )
+			// Divide by zero
+			isOverflow = true;
+		else
+			// Result is less than 1, so it truncates to 0
+			isOverflow = false;
+
+		return 0;
+	}
+	else if( exponent == 0 && base == 0 )
+	{
+		// Domain error
+		isOverflow = true;
+		return 0;
+	}
+	else if( exponent >= 31 )
+	{
+		switch( base )
+		{
+		case -1:
+			isOverflow = false;
+			return exponent & 1 ? -1 : 1;
+		case 0:
+			isOverflow = false;
+			break;
+		case 1:
+			isOverflow = false;
+			return 1;
+		default:
+			isOverflow = true;
+			break;
+		}
+		return 0;
+	}
+	else
+	{
+		const asWORD max_base = pow_info[exponent].MaxBasei32;
+		const char high_bit = pow_info[exponent].HighBit;
+		if( max_base != 0 && max_base < (base < 0 ? -base : base) )
+		{
+			isOverflow = true;
+			return 0;  // overflow
+		}
+
+		int result = 1;
+		switch( high_bit )
+		{
+		case 5:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 4:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 3:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 2:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 1:
+			if( exponent ) result *= base;
+		default:
+			isOverflow = false;
+			return result;
+		}
+	}
+}
+
+asDWORD as_powu(asDWORD base, asDWORD exponent, bool& isOverflow)
+{
+	if( exponent == 0 && base == 0 )
+	{
+		// Domain error
+		isOverflow = true;
+		return 0;
+	}
+	else if( exponent >= 32 )
+	{
+		switch( base )
+		{
+		case 0:
+			isOverflow = false;
+			break;
+		case 1:
+			isOverflow = false;
+			return 1;
+		default:
+			isOverflow = true;
+			break;
+		}
+		return 0;
+	}
+	else
+	{
+		const asWORD max_base = pow_info[exponent].MaxBaseu32;
+		const char high_bit = pow_info[exponent].HighBit;
+		if( max_base != 0 && max_base < base )
+		{
+			isOverflow = true;
+			return 0;  // overflow
+		}
+
+		asDWORD result = 1;
+		switch( high_bit )
+		{
+		case 5:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 4:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 3:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 2:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 1:
+			if( exponent ) result *= base;
+		default:
+			isOverflow = false;
+			return result;
+		}
+	}
+}
+
+asINT64 as_powi64(asINT64 base, asINT64 exponent, bool& isOverflow)
+{
+	if( exponent < 0 )
+	{
+		if( base == 0 )
+			// Divide by zero
+			isOverflow = true;
+		else
+			// Result is less than 1, so it truncates to 0
+			isOverflow = false;
+
+		return 0;
+	}
+	else if( exponent == 0 && base == 0 )
+	{
+		// Domain error
+		isOverflow = true;
+		return 0;
+	}
+	else if( exponent >= 63 )
+	{
+		switch( base )
+		{
+		case -1:
+			isOverflow = false;
+			return exponent & 1 ? -1 : 1;
+		case 0:
+			isOverflow = false;
+			break;
+		case 1:
+			isOverflow = false;
+			return 1;
+		default:
+			isOverflow = true;
+			break;
+		}
+		return 0;
+	}
+	else
+	{
+		const asDWORD max_base = pow_info[exponent].MaxBasei64;
+		const char high_bit = pow_info[exponent].HighBit;
+		if( max_base != 0 && max_base < (base < 0 ? -base : base) )
+		{
+			isOverflow = true;
+			return 0;  // overflow
+		}
+
+		asINT64 result = 1;
+		switch( high_bit )
+		{
+		case 6:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 5:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 4:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 3:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 2:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 1:
+			if( exponent ) result *= base;
+		default:
+			isOverflow = false;
+			return result;
+		}
+	}
+}
+
+asQWORD as_powu64(asQWORD base, asQWORD exponent, bool& isOverflow)
+{
+	if( exponent == 0 && base == 0 )
+	{
+		// Domain error
+		isOverflow = true;
+		return 0;
+	}
+	else if( exponent >= 64 )
+	{
+		switch( base )
+		{
+		case 0:
+			isOverflow = false;
+			break;
+		case 1:
+			isOverflow = false;
+			return 1;
+		default:
+			isOverflow = true;
+			break;
+		}
+		return 0;
+	}
+	else
+	{
+		const asQWORD max_base = pow_info[exponent].MaxBaseu64;
+		const char high_bit = pow_info[exponent].HighBit;
+		if( max_base != 0 && max_base < base )
+		{
+			isOverflow = true;
+			return 0;  // overflow
+		}
+
+		asQWORD result = 1;
+		switch( high_bit )
+		{
+		case 6:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 5:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 4:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 3:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 2:
+			if( exponent & 1 ) result *= base;
+			exponent >>= 1;
+			base *= base;
+		case 1:
+			if( exponent ) result *= base;
+		default:
+			isOverflow = false;
+			return result;
+		}
+	}
+}
+
 END_AS_NAMESPACE
 
 

+ 30 - 1
Source/ThirdParty/AngelScript/source/as_context.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -210,6 +210,35 @@ public:
 	asSVMRegisters m_regs;
 };
 
+// TODO: Move these to as_utils.h
+int     as_powi(int base, int exponent, bool& isOverflow);
+asDWORD as_powu(asDWORD base, asDWORD exponent, bool& isOverflow);
+asINT64 as_powi64(asINT64 base, asINT64 exponent, bool& isOverflow);
+asQWORD as_powu64(asQWORD base, asQWORD exponent, bool& isOverflow);
+
+// Optional template version of powi if overflow detection is not used.
+#if 0
+template <class T>
+T as_powi(T base, T exponent)
+{
+	// Test for sign bit (huge number is OK)
+	if( exponent & (T(1)<<(sizeof(T)*8-1)) )
+		return 0;
+	else
+	{
+		int result = 1;
+		while( exponent )
+		{
+			if( exponent & 1 )
+				result *= base;
+			exponent >>= 1;
+			base *= base;
+		}
+		return result;
+	}
+}
+#endif
+
 END_AS_NAMESPACE
 
 #endif

+ 2 - 2
Source/ThirdParty/AngelScript/source/as_criticalsection.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -117,7 +117,7 @@ END_AS_NAMESPACE
 #else
 #define WIN32_LEAN_AND_MEAN
 #ifndef _WIN32_WINNT
-  #define _WIN32_WINNT 0x0400 // We need this to get the declaration for TryEnterCriticalSection
+  #define _WIN32_WINNT 0x0600 // We need this to get the declaration for Windows Phone compatible Ex functions
 #endif
 #include <windows.h>
 #endif

+ 23 - 14
Source/ThirdParty/AngelScript/source/as_gc.cpp

@@ -72,19 +72,6 @@ asCGarbageCollector::~asCGarbageCollector()
 	freeNodes.SetLength(0);
 }
 
-bool asCGarbageCollector::IsObjectInGC(void *obj)
-{
-	asUINT n;
-	for( n = 0; n < gcNewObjects.GetLength(); n++ )
-		if( gcNewObjects[n].obj == obj )
-			return true;
-	for( n = 0; n < gcOldObjects.GetLength(); n++ )
-		if( gcOldObjects[n].obj == obj )
-			return true;
-
-	return false;
-}
-
 int asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 {
 	if( obj == 0 || objType == 0 )
@@ -343,6 +330,9 @@ void asCGarbageCollector::MoveObjectToOldList(int idx)
 
 int asCGarbageCollector::DestroyNewGarbage()
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	for(;;)
 	{
 		switch( destroyNewState )
@@ -452,6 +442,8 @@ int asCGarbageCollector::DestroyNewGarbage()
 
 int asCGarbageCollector::ReportAndReleaseUndestroyedObjects()
 {
+	// This function will only be called as the engine is shutting down
+
 	int items = 0;
 	for( asUINT n = 0; n < gcOldObjects.GetLength(); n++ )
 	{
@@ -469,7 +461,9 @@ int asCGarbageCollector::ReportAndReleaseUndestroyedObjects()
 		// Add additional info for builtin types
 		if( gcObj.type->name == "_builtin_function_" )
 		{
-			msg.Format(TXT_PREV_TYPE_IS_NAMED_s, reinterpret_cast<asCScriptFunction*>(gcObj.obj)->GetName());
+			// 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_" )
@@ -494,6 +488,9 @@ int asCGarbageCollector::ReportAndReleaseUndestroyedObjects()
 
 int asCGarbageCollector::DestroyOldGarbage()
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	for(;;)
 	{
 		switch( destroyOldState )
@@ -603,6 +600,9 @@ int asCGarbageCollector::DestroyOldGarbage()
 
 int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	for(;;)
 	{
 		switch( detectState )
@@ -893,6 +893,9 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 
 asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIntTypePair it)
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	asSMapNode_t *node;
 	if( freeNodes.GetLength() )
 		node = freeNodes.PopLast();
@@ -905,12 +908,18 @@ asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIn
 
 void asCGarbageCollector::ReturnNode(asSMapNode_t *node)
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	if( node )
 		freeNodes.PushLast(node);
 }
 
 void asCGarbageCollector::GCEnumCallback(void *reference)
 {
+	// This function will only be called within the critical section gcCollecting
+	asASSERT(isProcessing);
+
 	if( detectState == countReferences_loop )
 	{
 		// Find the reference in the map

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

@@ -61,7 +61,6 @@ public:
 	void   GCEnumCallback(void *reference);
 	int    AddScriptObjectToGC(void *obj, asCObjectType *objType);
 	int    GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asIObjectType **type);
-	bool   IsObjectInGC(void *obj);
 
 	int    ReportAndReleaseUndestroyedObjects();
 

+ 29 - 29
Source/ThirdParty/AngelScript/source/as_map.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 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 
@@ -264,10 +264,10 @@ void asCMap<KEY, VAL>::BalanceInsert(asSMapNode<KEY, VAL> *node)
 
 				if( node == node->parent->right ) 
 				{
-                    // Make the node a left child
-                    node = node->parent;
-                    RotateLeft(node);
-                }
+					// Make the node a left child
+					node = node->parent;
+					RotateLeft(node);
+				}
 
 				// Change color on parent and grand parent
 				// Then rotate grand parent to the right
@@ -300,10 +300,10 @@ void asCMap<KEY, VAL>::BalanceInsert(asSMapNode<KEY, VAL> *node)
 
 				if( node == node->parent->left ) 
 				{
-                    // Make the node a right child
-                    node = node->parent;
-                    RotateRight(node);
-                }
+					// Make the node a right child
+					node = node->parent;
+					RotateRight(node);
+				}
 				
 				// Change color on parent and grand parent
 				// Then rotate grand parent to the right
@@ -405,15 +405,15 @@ asSMapNode<KEY,VAL> *asCMap<KEY, VAL>::Remove(asSMapNode<KEY,VAL> *cursor)
 		child = remove->right;
 
 	if( child ) child->parent = remove->parent;
-    if( remove->parent )
+	if( remove->parent )
 	{
-        if( remove == remove->parent->left )
-            remove->parent->left = child;
-        else
-            remove->parent->right = child;
+		if( remove == remove->parent->left )
+			remove->parent->left = child;
+		else
+			remove->parent->right = child;
 	}
 	else
-        root = child;
+		root = child;
 
 	// If we remove a black node we must make sure the tree is balanced
 	if( ISBLACK(remove) )
@@ -516,17 +516,17 @@ void asCMap<KEY, VAL>::BalanceErase(asSMapNode<KEY, VAL> *child, asSMapNode<KEY,
 				if( ISBLACK(brother->right) )
 				{
 					brother->left->isRed = false;
-                    brother->isRed = true;
-                    RotateRight(brother);
-                    brother = parent->right;
+					brother->isRed = true;
+					RotateRight(brother);
+					brother = parent->right;
 				}
 
 				// Case 4
 				brother->isRed = parent->isRed;
-                parent->isRed = false;
-                brother->right->isRed = false;
-                RotateLeft(parent);
-                break;
+				parent->isRed = false;
+				brother->right->isRed = false;
+				RotateLeft(parent);
+				break;
 			}
 		}
 		else
@@ -564,17 +564,17 @@ void asCMap<KEY, VAL>::BalanceErase(asSMapNode<KEY, VAL> *child, asSMapNode<KEY,
 				if( ISBLACK(brother->left) )
 				{
 					brother->right->isRed = false;
-                    brother->isRed = true;
-                    RotateLeft(brother);
-                    brother = parent->left;
+					brother->isRed = true;
+					RotateLeft(brother);
+					brother = parent->left;
 				}
 
 				// Case 4
 				brother->isRed = parent->isRed;
-                parent->isRed = false;
-                brother->left->isRed = false;
-                RotateRight(parent);
-                break;
+				parent->isRed = false;
+				brother->left->isRed = false;
+				RotateRight(parent);
+				break;
 			}
 		}
 	}

+ 23 - 2
Source/ThirdParty/AngelScript/source/as_module.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -469,6 +469,8 @@ void asCModule::InternalReset()
 
 	// Allow the engine to clean up what is not used
 	engine->CleanupAfterDiscardModule();
+
+	asASSERT( IsEmpty() );
 }
 
 // interface
@@ -1125,6 +1127,21 @@ asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asC
 	return prop;
 }
 
+// internal
+bool asCModule::IsEmpty() const
+{
+	if( scriptFunctions.GetLength()  ) return false;
+	if( globalFunctions.GetSize()    ) return false;
+	if( bindInformations.GetLength() ) return false;
+	if( scriptGlobals.GetSize()      ) return false;
+	if( classTypes.GetLength()       ) return false;
+	if( enumTypes.GetLength()        ) return false;
+	if( typeDefs.GetLength()         ) return false;
+	if( funcDefs.GetLength()         ) return false;
+
+	return true;
+}
+
 // interface
 int asCModule::SaveByteCode(asIBinaryStream *out, bool stripDebugInfo) const
 {
@@ -1135,6 +1152,10 @@ int asCModule::SaveByteCode(asIBinaryStream *out, bool stripDebugInfo) const
 #else
 	if( out == 0 ) return asINVALID_ARG;
 
+	// Make sure there is actually something to save
+	if( IsEmpty() )
+		return asERROR;
+
 	asCWriter write(const_cast<asCModule*>(this), out, engine, stripDebugInfo);
 	return write.Write();
 #endif
@@ -1154,7 +1175,7 @@ int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
 	asCReader read(this, in, engine);
 	r = read.Read(wasDebugInfoStripped);
 
-    JITCompile();
+	JITCompile();
 
 #ifdef AS_DEBUG
 	// Verify that there are no unwanted gaps in the scriptFunctions array.

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

@@ -176,6 +176,7 @@ public:
 	friend class asCRestore;
 
 	void InternalReset();
+	bool IsEmpty() const;
 
 	int  CallInit(asIScriptContext *ctx);
 	void CallExit();

+ 76 - 0
Source/ThirdParty/AngelScript/source/as_namespace.h

@@ -0,0 +1,76 @@
+/*
+   AngelCode Scripting Library
+   Copyright (c) 2013 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 
+   damages arising from the use of this software.
+
+   Permission is granted to anyone to use this software for any 
+   purpose, including commercial applications, and to alter it and 
+   redistribute it freely, subject to the following restrictions:
+
+   1. The origin of this software must not be misrepresented; you 
+      must not claim that you wrote the original software. If you use
+      this software in a product, an acknowledgment in the product 
+      documentation would be appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and 
+      must not be misrepresented as being the original software.
+
+   3. This notice may not be removed or altered from any source 
+      distribution.
+
+   The original version of this library can be located at:
+   http://www.angelcode.com/angelscript/
+
+   Andreas Jonsson
+   [email protected]
+*/
+
+
+#ifndef AS_NAMESPACE_H
+#define AS_NAMESPACE_H
+
+#include "as_string.h"
+
+BEGIN_AS_NAMESPACE
+
+struct asSNameSpace
+{
+	asCString name;
+
+	// TODO: namespace: A namespace should have access masks. The application should be
+	//                  able to restrict specific namespaces from access to specific modules
+};
+
+
+struct asSNameSpaceNamePair
+{
+	const asSNameSpace *ns;
+	asCString           name;
+
+	asSNameSpaceNamePair() : ns(0) {}
+	asSNameSpaceNamePair(const asSNameSpace *_ns, const asCString &_name) : ns(_ns), name(_name) {}
+
+	asSNameSpaceNamePair &operator=(const asSNameSpaceNamePair &other)
+	{
+		ns   = other.ns;
+		name = other.name;
+		return *this;
+	}
+
+	bool operator==(const asSNameSpaceNamePair &other) const
+	{
+		return (ns == other.ns && name == other.name);
+	}
+
+	bool operator<(const asSNameSpaceNamePair &other) const
+	{
+		return (ns < other.ns || (ns == other.ns && name < other.name));
+	}
+};
+
+END_AS_NAMESPACE
+
+#endif

+ 12 - 3
Source/ThirdParty/AngelScript/source/as_objecttype.cpp

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

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

@@ -217,6 +217,7 @@ public:
 	asCArray<asCObjectProperty*> properties;
 	asCArray<int>                methods;
 	asCArray<asCObjectType*>     interfaces;
+	asCArray<asUINT>             interfaceVFTOffsets;
 	asCArray<asSEnumValue*>      enumValues;
 	asCObjectType *              derivedFrom;
 	asCArray<asCScriptFunction*> virtualFunctionTable;

+ 12 - 1
Source/ThirdParty/AngelScript/source/as_parser.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -865,6 +865,7 @@ bool asCParser::IsDataType(const sToken &token)
 {
 	if( token.type == ttIdentifier )
 	{
+#ifndef AS_NO_COMPILER
 		if( checkValidTypes )
 		{
 			// Check if this is an existing type, regardless of namespace
@@ -872,6 +873,7 @@ bool asCParser::IsDataType(const sToken &token)
 			if( !builder->DoesTypeExist(tempString.AddressOf()) )
 				return false;
 		}
+#endif
 		return true;
 	}
 
@@ -1633,6 +1635,7 @@ bool asCParser::IsOperator(int tokenType)
 		tokenType == ttStar ||
 		tokenType == ttSlash ||
 		tokenType == ttPercent ||
+		tokenType == ttStarStar ||
 		tokenType == ttAnd ||
 		tokenType == ttOr ||
 		tokenType == ttXor ||
@@ -1663,6 +1666,7 @@ bool asCParser::IsAssignOperator(int tokenType)
 		tokenType == ttMulAssign ||
 		tokenType == ttDivAssign ||
 		tokenType == ttModAssign ||
+		tokenType == ttPowAssign ||
 		tokenType == ttAndAssign ||
 		tokenType == ttOrAssign ||
 		tokenType == ttXorAssign ||
@@ -1726,6 +1730,13 @@ int asCParser::ParseScript(asCScriptCode *script)
 	if( errorWhileParsing )
 		return -1;
 
+	// Warn in case there isn't anything in the script
+	if( scriptNode->firstChild == 0 )
+	{
+		if( builder )
+			builder->WriteWarning(script->name, TXT_SECTION_IS_EMPTY, 1, 1);
+	}
+
 	return 0;
 }
 

+ 170 - 112
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -47,6 +47,7 @@ asCReader::asCReader(asCModule* _module, asIBinaryStream* _stream, asCScriptEngi
  : module(_module), stream(_stream), engine(_engine)
 {
 	error = false;
+	bytesRead = 0;
 }
 
 void asCReader::ReadData(void *data, asUINT size)
@@ -59,6 +60,7 @@ void asCReader::ReadData(void *data, asUINT size)
 	for( int n = size-1; n >= 0; n-- )
 		stream->Read(((asBYTE*)data)+n, 1);
 #endif
+	bytesRead += size;
 }
 
 int asCReader::Read(bool *wasDebugInfoStripped)
@@ -106,6 +108,20 @@ int asCReader::Read(bool *wasDebugInfoStripped)
 	return r;
 }
 
+int asCReader::Error(const char *msg)
+{
+	// Don't write if it has already been reported an error earlier
+	if( !error )
+	{
+		asCString str;
+		str.Format(msg, bytesRead);
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+		error = true;
+	}
+
+	return -1;
+}
+
 int asCReader::ReadInner() 
 {
 	// This function will load each entity one by one from the stream.
@@ -121,12 +137,15 @@ int asCReader::ReadInner()
 
 	// Read enums
 	count = ReadEncodedUInt();
-	module->enumTypes.Allocate(count, 0);
+	module->enumTypes.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		if( ot == 0 )
+		{
+			error = true;
 			return asOUT_OF_MEMORY;
+		}
 
 		ReadObjectTypeDeclaration(ot, 1);
 
@@ -165,12 +184,15 @@ int asCReader::ReadInner()
 	// classTypes[]
 	// First restore the structure names, then the properties
 	count = ReadEncodedUInt();
-	module->classTypes.Allocate(count, 0);
+	module->classTypes.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		if( ot == 0 )
+		{
+			error = true;
 			return asOUT_OF_MEMORY;
+		}
 
 		ReadObjectTypeDeclaration(ot, 1);
 
@@ -212,7 +234,7 @@ int asCReader::ReadInner()
 
 	// Read func defs
 	count = ReadEncodedUInt();
-	module->funcDefs.Allocate(count, 0);
+	module->funcDefs.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	{
 		bool isNew;
@@ -251,7 +273,7 @@ int asCReader::ReadInner()
 			}
 		}
 		else
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 	}
 
 	// Read interface methods
@@ -279,12 +301,15 @@ int asCReader::ReadInner()
 
 	// Read typedefs
 	count = ReadEncodedUInt();
-	module->typeDefs.Allocate(count, 0);
+	module->typeDefs.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		if( ot == 0 )
+		{
+			error = true;
 			return asOUT_OF_MEMORY;
+		}
 
 		ReadObjectTypeDeclaration(ot, 1);
 		engine->classTypes.PushLast(ot);
@@ -300,9 +325,9 @@ int asCReader::ReadInner()
 	if( count && engine->ep.disallowGlobalVars )
 	{
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 	}
-	module->scriptGlobals.Allocate(count, 0);
+	module->scriptGlobals.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i ) 
 	{
 		ReadGlobalProperty();
@@ -317,7 +342,7 @@ int asCReader::ReadInner()
 		func = ReadFunction(isNew);
 		if( func == 0 )
 		{
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			break;
 		}
 		
@@ -365,25 +390,28 @@ int asCReader::ReadInner()
 			func->AddRef();
 		}
 		else
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 	}
 
 	if( error ) return asERROR;
 
 	// bindInformations[]
 	count = ReadEncodedUInt();
-	module->bindInformations.Allocate(count, 0);
+	module->bindInformations.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	{
 		sBindInfo *info = asNEW(sBindInfo);
 		if( info == 0 )
+		{
+			error = true;
 			return asOUT_OF_MEMORY;
+		}
 
 		bool isNew;
 		info->importedFunctionSignature = ReadFunction(isNew, false, false);
 		if( info->importedFunctionSignature == 0 )
 		{
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			break;
 		}
 
@@ -407,7 +435,7 @@ int asCReader::ReadInner()
 
 	// usedTypes[]
 	count = ReadEncodedUInt();
-	usedTypes.Allocate(count, 0);
+	usedTypes.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	{
 		asCObjectType *ot = ReadObjectType();
@@ -456,7 +484,7 @@ int asCReader::ReadInner()
 				asCString str;
 				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), sub.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 			}
 		}
 	}
@@ -503,7 +531,7 @@ void asCReader::ReadUsedStringConstants()
 
 	asUINT count;
 	count = ReadEncodedUInt();
-	usedStringConstants.Allocate(count, 0);
+	usedStringConstants.Allocate(count, false);
 	for( asUINT i = 0; i < count; ++i ) 
 	{
 		ReadString(&str);
@@ -536,6 +564,11 @@ void asCReader::ReadUsedFunctions()
 		{
 			asCScriptFunction func(engine, c == 'm' ? module : 0, asFUNC_DUMMY);
 			ReadFunctionSignature(&func);
+			if( error )
+			{
+				func.funcType = asFUNC_DUMMY;
+				return;
+			}
 
 			// Find the correct function
 			if( c == 'm' )
@@ -571,13 +604,19 @@ void asCReader::ReadUsedFunctions()
 
 			// Set the type to dummy so it won't try to release the id
 			func.funcType = asFUNC_DUMMY;
+
+			if( usedFunctions[n] == 0 )
+			{
+				Error(TXT_INVALID_BYTECODE_d);
+				return;
+			}
 		}
 	}
 }
 
 void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 {
-	int i, count;
+	asUINT i, count;
 	asCDataType dt;
 	int num;
 
@@ -585,50 +624,62 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	if( func->name == DELEGATE_FACTORY )
 	{
 		// It's not necessary to read anymore, everything is known 
-		for( asUINT n = 0; n < engine->registeredGlobalFuncs.GetLength(); n++ )
-		{
-			asCScriptFunction *f = engine->registeredGlobalFuncs[n];
-			if( f->name == DELEGATE_FACTORY )
-			{
-				func->returnType     = f->returnType;
-				func->parameterTypes = f->parameterTypes;
-				func->inOutFlags     = f->inOutFlags;
-				func->funcType       = f->funcType;
-				func->defaultArgs    = f->defaultArgs;
-				func->nameSpace      = f->nameSpace;
-				return;
-			}
-		}
-		asASSERT( false );
+		asCScriptFunction *f = engine->registeredGlobalFuncs.GetFirst(engine->nameSpaces[0], DELEGATE_FACTORY);
+		asASSERT( f );
+		func->returnType     = f->returnType;
+		func->parameterTypes = f->parameterTypes;
+		func->inOutFlags     = f->inOutFlags;
+		func->funcType       = f->funcType;
+		func->defaultArgs    = f->defaultArgs;
+		func->nameSpace      = f->nameSpace;
 		return;
 	}
 
 	ReadDataType(&func->returnType);
 
 	count = ReadEncodedUInt();
-	func->parameterTypes.Allocate(count, 0);
+	if( count > 256 )
+	{
+		// Too many arguments, must be something wrong in the file
+		Error(TXT_INVALID_BYTECODE_d);
+		return;
+	}
+	func->parameterTypes.Allocate(count, false);
 	for( i = 0; i < count; ++i ) 
 	{
 		ReadDataType(&dt);
 		func->parameterTypes.PushLast(dt);
 	}
 
+	func->inOutFlags.SetLength(func->parameterTypes.GetLength());
+	memset(func->inOutFlags.AddressOf(), 0, sizeof(asETypeModifiers)*func->inOutFlags.GetLength());
 	count = ReadEncodedUInt();
-	func->inOutFlags.Allocate(count, 0);
+	if( count > func->parameterTypes.GetLength() )
+	{
+		// Cannot be more than the number of arguments
+		Error(TXT_INVALID_BYTECODE_d);
+		return;
+	}
 	for( i = 0; i < count; ++i )
 	{
 		num = ReadEncodedUInt();
-		func->inOutFlags.PushLast(static_cast<asETypeModifiers>(num));
+		func->inOutFlags[i] = static_cast<asETypeModifiers>(num);
 	}
 
 	func->funcType = (asEFuncType)ReadEncodedUInt();
 
 	// Read the default args, from last to first
 	count = ReadEncodedUInt();
+	if( count > func->parameterTypes.GetLength() )
+	{
+		// Cannot be more than the number of arguments
+		Error(TXT_INVALID_BYTECODE_d);
+		return;
+	}
 	if( count )
 	{
 		func->defaultArgs.SetLength(func->parameterTypes.GetLength());
-		memset(func->defaultArgs.AddressOf(), 0, sizeof(asCString*)*func->parameterTypes.GetLength());
+		memset(func->defaultArgs.AddressOf(), 0, sizeof(asCString*)*func->defaultArgs.GetLength());
 		for( i = 0; i < count; i++ )
 		{
 			asCString *str = asNEW(asCString);
@@ -682,7 +733,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			return savedFunctions[index];
 		else
 		{
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return 0;
 		}
 	}
@@ -703,6 +754,11 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	int num;
 
 	ReadFunctionSignature(func);
+	if( error )
+	{
+		asDELETE(func, asCScriptFunction);
+		return 0;
+	}
 
 	if( func->funcType == asFUNC_SCRIPT )
 	{
@@ -716,9 +772,9 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 		func->scriptData->variableSpace = ReadEncodedUInt();
 
 		count = ReadEncodedUInt();
-		func->scriptData->objVariablePos.Allocate(count, 0);
-		func->scriptData->objVariableTypes.Allocate(count, 0);
-		func->scriptData->funcVariableTypes.Allocate(count, 0);
+		func->scriptData->objVariablePos.Allocate(count, false);
+		func->scriptData->objVariableTypes.Allocate(count, false);
+		func->scriptData->funcVariableTypes.Allocate(count, false);
 		for( i = 0; i < count; ++i )
 		{
 			func->scriptData->objVariableTypes.PushLast(ReadObjectType());
@@ -770,7 +826,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 		if( !noDebugInfo )
 		{
 			length = ReadEncodedUInt();
-			func->scriptData->variables.Allocate(length, 0);
+			func->scriptData->variables.Allocate(length, false);
 			for( i = 0; i < length; i++ )
 			{
 				asSScriptVariable *var = asNEW(asSScriptVariable);
@@ -778,6 +834,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 				{
 					// Out of memory
 					error = true;
+					asDELETE(func, asCScriptFunction);
 					return 0;
 				}
 				func->scriptData->variables.PushLast(var);
@@ -800,7 +857,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			func->scriptData->declaredAt = ReadEncodedUInt();
 		}
 	}
-	else if( func->funcType == asFUNC_VIRTUAL )
+	else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
 	{
 		func->vfTableIdx = ReadEncodedUInt();
 	}
@@ -864,7 +921,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			bool sharedExists = existingShared.MoveTo(0, ot);
 			if( !sharedExists )
 			{
-				ot->enumValues.Allocate(count, 0);
+				ot->enumValues.Allocate(count, false);
 				for( int n = 0; n < count; n++ )
 				{
 					asSEnumValue *e = asNEW(asSEnumValue);
@@ -903,7 +960,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 						asCString str;
 						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-						error = true;
+						Error(TXT_INVALID_BYTECODE_d);
 					}
 				}
 			}
@@ -926,7 +983,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					asCString str;
 					str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 					engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 				}
 			}
 			else
@@ -936,29 +993,35 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					ot->derivedFrom->AddRef();
 			}
 
-			// interfaces[]
+			// interfaces[] / interfaceVFTOffsets[]
 			int size = ReadEncodedUInt();
 			if( sharedExists )
 			{
 				for( int n = 0; n < size; n++ )
 				{
 					asCObjectType *intf = ReadObjectType();
+					ReadEncodedUInt();
+
 					if( !ot->Implements(intf) )
 					{
 						asCString str;
 						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-						error = true;
+						Error(TXT_INVALID_BYTECODE_d);
 					}
 				}
 			}
 			else
 			{
-				ot->interfaces.Allocate(size,0);
+				ot->interfaces.Allocate(size, false);
+				ot->interfaceVFTOffsets.Allocate(size, false);
 				for( int n = 0; n < size; n++ )
 				{
 					asCObjectType *intf = ReadObjectType();
 					ot->interfaces.PushLast(intf);
+
+					asUINT offset = ReadEncodedUInt();
+					ot->interfaceVFTOffsets.PushLast(offset);
 				}
 			}
 
@@ -982,7 +1045,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 						asCString str;
 						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-						error = true;
+						Error(TXT_INVALID_BYTECODE_d);
 					}
 					if( func )
 					{
@@ -1040,7 +1103,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 								asCString str;
 								str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 								engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-								error = true;
+								Error(TXT_INVALID_BYTECODE_d);
 							}
 							if( isNew )
 							{
@@ -1061,8 +1124,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					}
 					else
 					{
-						// TODO: Write message
-						error = true;
+						Error(TXT_INVALID_BYTECODE_d);
 					}
 
 					func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
@@ -1092,7 +1154,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 								asCString str;
 								str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 								engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-								error = true;
+								Error(TXT_INVALID_BYTECODE_d);
 							}
 							if( isNew )
 							{
@@ -1113,8 +1175,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					}
 					else
 					{
-						// TODO: Write message
-						error = true;
+						Error(TXT_INVALID_BYTECODE_d);
 					}
 				}
 			}
@@ -1152,7 +1213,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							asCString str;
 							str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 							engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-							error = true;
+							Error(TXT_INVALID_BYTECODE_d);
 						}
 						if( isNew )
 						{
@@ -1181,8 +1242,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 				}
 				else
 				{
-					// TODO: Write message
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 				}
 			}
 
@@ -1218,7 +1278,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							asCString str;
 							str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
 							engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-							error = true;
+							Error(TXT_INVALID_BYTECODE_d);
 						}
 						if( isNew )
 						{
@@ -1237,8 +1297,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 				}
 				else
 				{
-					// TODO: Write message
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 				}
 			}
 		}
@@ -1257,8 +1316,7 @@ asWORD asCReader::ReadEncodedUInt16()
 	asDWORD dw = ReadEncodedUInt();
 	if( (dw>>16) != 0 && (dw>>16) != 0xFFFF )
 	{
-		// TODO: Write message
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 	}
 
 	return asWORD(dw & 0xFFFF);
@@ -1269,8 +1327,7 @@ asUINT asCReader::ReadEncodedUInt()
 	asQWORD qw = ReadEncodedUInt64();
 	if( (qw>>32) != 0 && (qw>>32) != 0xFFFFFFFF )
 	{
-		// TODO: Write message
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 	}
 
 	return asUINT(qw & 0xFFFFFFFFu);
@@ -1372,7 +1429,7 @@ void asCReader::ReadString(asCString* str)
 		if( n < savedStrings.GetLength() )
 			*str = savedStrings[n];
 		else
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 	}
 }
 
@@ -1406,7 +1463,7 @@ void asCReader::ReadGlobalProperty()
 			func->Release();
 		}
 		else
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 	}
 }
 
@@ -1463,6 +1520,7 @@ void asCReader::ReadDataType(asCDataType *dt)
 	{
 		asCScriptFunction func(engine, module, asFUNC_DUMMY);
 		ReadFunctionSignature(&func);
+		if( error ) return;
 		for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 		{
 			// TODO: access: Only return the definitions that the module has access to
@@ -1522,13 +1580,13 @@ asCObjectType* asCReader::ReadObjectType()
 		// Read the name of the template type
 		asCString typeName;
 		ReadString(&typeName);
-		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf(), engine->nameSpaces[0]);
+		asCObjectType *tmpl = engine->GetRegisteredObjectType(typeName.AddressOf(), engine->nameSpaces[0]);
 		if( tmpl == 0 )
 		{
 			asCString str;
 			str.Format(TXT_TEMPLATE_TYPE_s_DOESNT_EXIST, typeName.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return 0;
 		}
 
@@ -1572,7 +1630,7 @@ asCObjectType* asCReader::ReadObjectType()
 			asCString str;
 			str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), sub.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return 0;
 		}
 	}
@@ -1581,8 +1639,7 @@ asCObjectType* asCReader::ReadObjectType()
 		asCObjectType *st = ReadObjectType();
 		if( st == 0 || st->beh.listFactory == 0 )
 		{
-			// TODO: Write approprate error
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return 0;
 		}
 		ot = engine->GetListPatternType(st->beh.listFactory);
@@ -1609,7 +1666,7 @@ asCObjectType* asCReader::ReadObjectType()
 			asCString str;
 			str.Format(TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST, typeName.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return 0;
 		}
 	}
@@ -1626,14 +1683,14 @@ asCObjectType* asCReader::ReadObjectType()
 			// Find the object type
 			ot = module->GetObjectType(typeName.AddressOf(), nameSpace);
 			if( !ot )
-				ot = engine->GetObjectType(typeName.AddressOf(), nameSpace);
+				ot = engine->GetRegisteredObjectType(typeName.AddressOf(), nameSpace);
 			
 			if( ot == 0 )
 			{
 				asCString str;
 				str.Format(TXT_OBJECT_TYPE_s_DOESNT_EXIST, typeName.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 				return 0;
 			}
 		}
@@ -1905,7 +1962,7 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
 void asCReader::ReadUsedTypeIds()
 {
 	asUINT count = ReadEncodedUInt();
-	usedTypeIds.Allocate(count, 0);
+	usedTypeIds.Allocate(count, false);
 	for( asUINT n = 0; n < count; n++ )
 	{
 		asCDataType dt;
@@ -1918,7 +1975,7 @@ void asCReader::ReadUsedGlobalProps()
 {
 	int c = ReadEncodedUInt();
 
-	usedGlobalProperties.Allocate(c, 0);
+	usedGlobalProperties.Allocate(c, false);
 
 	for( int n = 0; n < c; n++ )
 	{
@@ -1948,8 +2005,7 @@ void asCReader::ReadUsedGlobalProps()
 
 		if( prop == 0 )
 		{
-			// TODO: Write error message to the callback
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 		}
 	}
 }
@@ -1964,8 +2020,7 @@ void asCReader::ReadUsedObjectProps()
 		asCObjectType *objType = ReadObjectType();
 		if( objType == 0 )
 		{
-			// TODO: Write error message to callback
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			break;
 		}
 
@@ -1987,8 +2042,7 @@ void asCReader::ReadUsedObjectProps()
 
 		if( !found )
 		{
-			// TODO: Write error message to callback
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return;
 		}
 	}
@@ -1998,9 +2052,7 @@ short asCReader::FindObjectPropOffset(asWORD index)
 {
 	if( index >= usedObjectProperties.GetLength() )
 	{
-		// TODO: Write to message callback
-		asASSERT(false);
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 		return 0;
 	}
 
@@ -2013,8 +2065,7 @@ asCScriptFunction *asCReader::FindFunction(int idx)
 		return usedFunctions[idx];
 	else
 	{
-		// TODO: Write to message callback
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 		return 0;
 	}
 }
@@ -2037,7 +2088,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 		asUINT size = asBCTypeSize[asBCInfo[c].type];
 		if( size == 0 )
 		{
-			error = true;
+			Error(TXT_INVALID_BYTECODE_d);
 			return;
 		}
 		bcSizes.PushLast(size);
@@ -2113,8 +2164,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 				asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
 				if( !dt.IsValid() )
 				{
-					// TODO: Write error to message
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 				}
 				else
 					asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
@@ -2139,8 +2189,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 				*fid = f->id;
 			else
 			{
-				// TODO: Write to message callback
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 				return;
 			}
 		}
@@ -2166,8 +2215,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 					*fid = f->id;
 				else
 				{
-					// TODO: Write to message callback
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 					return;
 				}
 			}
@@ -2181,8 +2229,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 				*arg = (asWORD)usedStringConstants[*arg];
 			else
 			{
-				// TODO: Write to message callback
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 				return;
 			}
 		}
@@ -2197,15 +2244,13 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 					*fid = bi->importedFunctionSignature->id;
 				else
 				{
-					// TODO: Write to message callback
-					error = true;
+					Error(TXT_INVALID_BYTECODE_d);
 					return;
 				}
 			}
 			else
 			{
-				// TODO: Write to message callback
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 				return;
 			}
 		}
@@ -2224,8 +2269,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 				*(void**)index = usedGlobalProperties[*(asUINT*)index];
 			else
 			{
-				// TODO: Write to message callback
-				error = true;
+				Error(TXT_INVALID_BYTECODE_d);
 				return;
 			}
 		}
@@ -2841,7 +2885,7 @@ int asCReader::AdjustStackPosition(int pos)
 	else if( pos >= 0 ) 
 		pos += (short)adjustByPos[pos];
 	else if( -pos >= (int)adjustNegativeStackByPos.GetLength() )
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 	else
 		pos += (short)adjustNegativeStackByPos[-pos];
 
@@ -2935,8 +2979,7 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 
 	if( calledFunc == 0 )
 	{
-		// TODO: Report error
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 		return offset;
 	}
 
@@ -2985,8 +3028,7 @@ int asCReader::FindTypeId(int idx)
 		return usedTypeIds[idx];
 	else
 	{
-		// TODO: Write to message callback
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 		return 0;
 	}
 }
@@ -2995,8 +3037,7 @@ asCObjectType *asCReader::FindObjectType(int idx)
 {
 	if( idx < 0 || idx >= (int)usedTypes.GetLength() )
 	{
-		// TODO: Write to message callback
-		error = true;
+		Error(TXT_INVALID_BYTECODE_d);
 		return 0;
 	}
 
@@ -3213,7 +3254,14 @@ void asCWriter::WriteFunctionSignature(asCScriptFunction *func)
 	for( i = 0; i < count; ++i ) 
 		WriteDataType(&func->parameterTypes[i]);
 	
-	count = (asUINT)func->inOutFlags.GetLength();
+	// Only write the inout flags if any of them are set
+	count = 0;
+	for( i = asUINT(func->inOutFlags.GetLength()); i > 0; i-- )
+		if( func->inOutFlags[i-1] != asTM_NONE )
+		{
+			count = i;
+			break;
+		}
 	WriteEncodedInt64(count);
 	for( i = 0; i < count; ++i )
 		WriteEncodedInt64(func->inOutFlags[i]);
@@ -3376,8 +3424,9 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 			WriteEncodedInt64(func->scriptData->declaredAt);
 		}
 	}
-	else if( func->funcType == asFUNC_VIRTUAL )
+	else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
 	{
+		// TODO: Do we really need to store this? It can probably be reconstructed by the reader
 		WriteEncodedInt64(func->vfTableIdx);
 	}
 }
@@ -3392,6 +3441,8 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 		WriteData(&ot->flags, 4);
 
 		// size
+		// TODO: Do we really need to store this? The reader should be able to 
+		//       determine the correct size from the object type's flags
 		if( (ot->flags & asOBJ_SCRIPT_OBJECT) && ot->size > 0 )
 		{
 			// The size for script objects may vary from platform to platform so 
@@ -3431,16 +3482,20 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 		{
 			WriteObjectType(ot->derivedFrom);
 
-			// interfaces[]
+			// interfaces[] / interfaceVFTOffsets[]
+			// TOOD: Is it really necessary to store the VFTOffsets? Can't the reader calculate those?
 			int size = (asUINT)ot->interfaces.GetLength();
 			WriteEncodedInt64(size);
 			asUINT n;
 			for( n = 0; n < ot->interfaces.GetLength(); n++ )
 			{
 				WriteObjectType(ot->interfaces[n]);
+				WriteEncodedInt64(ot->interfaceVFTOffsets[n]);
 			}
 
 			// behaviours
+			// TODO: Default behaviours should just be stored as a indicator  
+			//       to avoid storing the actual function object
 			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
 			{
 				WriteFunction(engine->scriptFunctions[ot->beh.destruct]);
@@ -3454,6 +3509,8 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 			}
 
 			// methods[]
+			// TODO: Avoid storing inherited methods in interfaces, as the reader
+			//       can add those directly from the base interface
 			size = (int)ot->methods.GetLength();
 			WriteEncodedInt64(size);
 			for( n = 0; n < ot->methods.GetLength(); n++ )
@@ -3462,6 +3519,7 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 			}
 
 			// virtualFunctionTable[]
+			// TODO: Is it really necessary to store this? Can't it be easily rebuilt by the reader
 			size = (int)ot->virtualFunctionTable.GetLength();
 			WriteEncodedInt64(size);
 			for( n = 0; n < (asUINT)size; n++ )

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -58,6 +58,9 @@ protected:
 	asCScriptEngine *engine;
 	bool             noDebugInfo;
 	bool             error;
+	asUINT           bytesRead;
+
+	int                Error(const char *msg);
 
 	int                ReadInner();
 

+ 204 - 166
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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
@@ -189,6 +189,9 @@ AS_API const char * asGetLibraryOptions()
 #ifdef AS_ARM
 		"AS_ARM "
 #endif
+#ifdef AS_SOFTFP
+		"AS_SOFTFP "
+#endif
 #ifdef AS_X64_GCC
 		"AS_X64_GCC "
 #endif
@@ -425,6 +428,9 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 
 	case asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE:
 		return ep.disallowValueAssignForRefType;
+
+	default:
+		return 0;
 	}
 
 	return 0;
@@ -564,39 +570,40 @@ asCScriptEngine::~asCScriptEngine()
 	GarbageCollect();
 
 	// Delete the functions for template types that may references object types
-	for( n = 0; n < templateTypes.GetLength(); n++ )
+	for( n = 0; n < templateInstanceTypes.GetLength(); n++ )
 	{
-		if( templateTypes[n] )
+		if( templateInstanceTypes[n] )
 		{
 			asUINT f;
+			asCObjectType *templateType = templateInstanceTypes[n];
 
 			// Delete the factory stubs first
-			for( f = 0; f < templateTypes[n]->beh.factories.GetLength(); f++ )
-				scriptFunctions[templateTypes[n]->beh.factories[f]]->Release();
-			templateTypes[n]->beh.factories.Allocate(0, false);
+			for( f = 0; f < templateType->beh.factories.GetLength(); f++ )
+				scriptFunctions[templateType->beh.factories[f]]->Release();
+			templateType->beh.factories.Allocate(0, false);
 
 			// The list factory is not stored in the list with the rest of the factories
-			if( templateTypes[n]->beh.listFactory )
+			if( templateType->beh.listFactory )
 			{
-				scriptFunctions[templateTypes[n]->beh.listFactory]->Release();
-				templateTypes[n]->beh.listFactory = 0;
+				scriptFunctions[templateType->beh.listFactory]->Release();
+				templateType->beh.listFactory = 0;
 			}
 
 			// Delete the specialized functions
-			for( f = 1; f < templateTypes[n]->beh.operators.GetLength(); f += 2 )
+			for( f = 1; f < templateType->beh.operators.GetLength(); f += 2 )
 			{
-				if( scriptFunctions[templateTypes[n]->beh.operators[f]]->objectType == templateTypes[n] )
+				if( scriptFunctions[templateType->beh.operators[f]]->objectType == templateType )
 				{
-					scriptFunctions[templateTypes[n]->beh.operators[f]]->Release();
-					templateTypes[n]->beh.operators[f] = 0;
+					scriptFunctions[templateType->beh.operators[f]]->Release();
+					templateType->beh.operators[f] = 0;
 				}
 			}
-			for( f = 0; f < templateTypes[n]->methods.GetLength(); f++ )
+			for( f = 0; f < templateType->methods.GetLength(); f++ )
 			{
-				if( scriptFunctions[templateTypes[n]->methods[f]]->objectType == templateTypes[n] )
+				if( scriptFunctions[templateType->methods[f]]->objectType == templateType )
 				{
-					scriptFunctions[templateTypes[n]->methods[f]]->Release();
-					templateTypes[n]->methods[f] = 0;
+					scriptFunctions[templateType->methods[f]]->Release();
+					templateType->methods[f] = 0;
 				}
 			}
 		}
@@ -674,27 +681,28 @@ asCScriptEngine::~asCScriptEngine()
 	registeredGlobalProps.Clear();
 	FreeUnusedGlobalProperties();
 
-	for( n = 0; n < templateTypes.GetLength(); n++ )
+	for( n = 0; n < templateInstanceTypes.GetLength(); n++ )
 	{
-		if( templateTypes[n] )
+		if( templateInstanceTypes[n] )
 		{
 			// Clear the sub types before deleting the template type so that the sub types aren't freed to soon
-			templateTypes[n]->templateSubTypes.SetLength(0);
-			asDELETE(templateTypes[n],asCObjectType);
+			templateInstanceTypes[n]->templateSubTypes.SetLength(0);
+			asDELETE(templateInstanceTypes[n],asCObjectType);
 		}
 	}
-	templateTypes.SetLength(0);
+	templateInstanceTypes.SetLength(0);
 
-	for( n = 0; n < objectTypes.GetLength(); n++ )
+	asSMapNode<asSNameSpaceNamePair, asCObjectType *> *cursor2;
+	allRegisteredTypes.MoveFirst(&cursor2);
+	while( cursor2 )
 	{
-		if( objectTypes[n] )
-		{
-			// Clear the sub types before deleting the template type so that the sub types aren't freed to soon
-			objectTypes[n]->templateSubTypes.SetLength(0);
-			asDELETE(objectTypes[n],asCObjectType);
-		}
+		// Clear the sub types before deleting the template type so that the sub types aren't freed to soon
+		cursor2->value->templateSubTypes.SetLength(0);
+		asDELETE(cursor2->value, asCObjectType);
+
+		allRegisteredTypes.MoveNext(&cursor2, cursor2);
 	}
-	objectTypes.SetLength(0);
+	allRegisteredTypes.EraseAll();
 	for( n = 0; n < templateSubTypes.GetLength(); n++ )
 	{
 		if( templateSubTypes[n] )
@@ -705,12 +713,10 @@ asCScriptEngine::~asCScriptEngine()
 	registeredEnums.SetLength(0);
 	registeredObjTypes.SetLength(0);
 
-	for( n = 0; n < registeredGlobalFuncs.GetLength(); n++ )
-	{
-		if( registeredGlobalFuncs[n] )
-			registeredGlobalFuncs[n]->Release();
-	}
-	registeredGlobalFuncs.SetLength(0);
+	asCSymbolTable<asCScriptFunction>::iterator funcIt = registeredGlobalFuncs.List();
+	for( ; funcIt; funcIt++ )
+		(*funcIt)->Release();
+	registeredGlobalFuncs.Clear();
 
 	scriptTypeBehaviours.ReleaseAllFunctions();
 	functionBehaviours.ReleaseAllFunctions();
@@ -1360,6 +1366,16 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 
 	dt.GetObjectType()->properties.PushLast(prop);
 
+	// Add references to template instances so they are not released too early
+	if( type.GetObjectType() && (type.GetObjectType()->flags & asOBJ_TEMPLATE) )
+	{
+		if( !currentGroup->objTypes.Exists(type.GetObjectType()) )
+		{
+			type.GetObjectType()->AddRef();
+			currentGroup->objTypes.PushLast(type.GetObjectType());
+		}
+	}
+
 	currentGroup->RefConfigGroup(FindConfigGroupForObjectType(type.GetObjectType()));
 
 	return asSUCCESS;
@@ -1371,12 +1387,9 @@ int asCScriptEngine::RegisterInterface(const char *name)
 	if( name == 0 ) return ConfigError(asINVALID_NAME, "RegisterInterface", 0, 0);
 
 	// Verify if the name has been registered as a type already
-	asUINT n;
-	for( n = 0; n < objectTypes.GetLength(); n++ )
-	{
-		if( objectTypes[n] && objectTypes[n]->name == name && objectTypes[n]->nameSpace == defaultNamespace )
-			return asALREADY_REGISTERED;
-	}
+	// TODO: Must check against registered funcdefs too
+	if( GetRegisteredObjectType(name, defaultNamespace) )
+		return asALREADY_REGISTERED;
 
 	// Use builder to parse the datatype
 	asCDataType dt;
@@ -1417,7 +1430,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
 	scriptFunctions[st->beh.release]->AddRef();
 	st->beh.copy = 0;
 
-	objectTypes.PushLast(st);
+	allRegisteredTypes.Insert(asSNameSpaceNamePair(st->nameSpace, st->name), st);
 	registeredObjTypes.PushLast(st);
 
 	currentGroup->objTypes.PushLast(st);
@@ -1461,8 +1474,12 @@ int asCScriptEngine::RegisterInterfaceMethod(const char *intf, const char *decla
 
 	func->id = GetNextScriptFunctionId();
 	SetScriptFunction(func);
+
+	// The index into the interface's vftable chunk should be
+	// its index in the methods array.
+	func->vfTableIdx = int(func->objectType->methods.GetLength());
+
 	func->objectType->methods.PushLast(func->id);
-	// The refCount was already set to 1
 
 	func->ComputeSignatureId();
 
@@ -1493,7 +1510,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 	isPrepared = false;
 
 	// Verify flags
-	//   Must have either asOBJ_REF or asOBJ_VALUE
+	// Must have either asOBJ_REF or asOBJ_VALUE
 	if( flags & asOBJ_REF )
 	{
 		// Can optionally have the asOBJ_GC, asOBJ_NOHANDLE, asOBJ_SCOPED, or asOBJ_TEMPLATE flag set, but nothing else
@@ -1593,13 +1610,10 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 			return ConfigError(r, "RegisterObjectType", name, 0);
 
 		// Verify that the template name hasn't been registered as a type already
-		asUINT n;
-		for( n = 0; n < objectTypes.GetLength(); n++ )
-		{
-			if( objectTypes[n] && objectTypes[n]->name == typeName && objectTypes[n]->nameSpace == defaultNamespace )
-				// This is not an irrepairable error, as it may just be that the same type is registered twice
-				return asALREADY_REGISTERED;
-		}
+		// TODO: Must check against registered funcdefs too
+		if( GetRegisteredObjectType(typeName, defaultNamespace) )
+			// This is not an irrepairable error, as it may just be that the same type is registered twice
+			return asALREADY_REGISTERED;
 
 		asCObjectType *type = asNEW(asCObjectType)(this);
 		if( type == 0 )
@@ -1612,15 +1626,16 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		type->accessMask = defaultAccessMask;
 
 		// Store it in the object types
-		objectTypes.PushLast(type);
+		allRegisteredTypes.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
 		currentGroup->objTypes.PushLast(type);
 		registeredObjTypes.PushLast(type);
+		registeredTemplateTypes.PushLast(type);
 
 		// Define the template subtypes
 		for( asUINT subTypeIdx = 0; subTypeIdx < subtypeNames.GetLength(); subTypeIdx++ )
 		{
 			asCObjectType *subtype = 0;
-			for( n = 0; n < templateSubTypes.GetLength(); n++ )
+			for( asUINT n = 0; n < templateSubTypes.GetLength(); n++ )
 			{
 				if( templateSubTypes[n]->name == subtypeNames[subTypeIdx] )
 				{
@@ -1650,21 +1665,17 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		typeName = name;
 
 		// Verify if the name has been registered as a type already
-		asUINT n;
-		for( n = 0; n < objectTypes.GetLength(); n++ )
-		{
-			if( objectTypes[n] &&
-				objectTypes[n]->name == typeName &&
-				objectTypes[n]->nameSpace == defaultNamespace )
-				// This is not an irrepairable error, as it may just be that the same type is registered twice
-				return asALREADY_REGISTERED;
-		}
+		// TODO: Must check against registered funcdefs too
+		if( GetRegisteredObjectType(typeName, defaultNamespace) )
+			// This is not an irrepairable error, as it may just be that the same type is registered twice
+			return asALREADY_REGISTERED;
 
-		for( n = 0; n < templateTypes.GetLength(); n++ )
+		// TODO: clean up: Is it really necessary to check here?
+		for( asUINT n = 0; n < templateInstanceTypes.GetLength(); n++ )
 		{
-			if( templateTypes[n] &&
-				templateTypes[n]->name == typeName &&
-				templateTypes[n]->nameSpace == defaultNamespace )
+			if( templateInstanceTypes[n] &&
+				templateInstanceTypes[n]->name == typeName &&
+				templateInstanceTypes[n]->nameSpace == defaultNamespace )
 				// This is not an irrepairable error, as it may just be that the same type is registered twice
 				return asALREADY_REGISTERED;
 		}
@@ -1708,7 +1719,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 			type->flags      = flags;
 			type->accessMask = defaultAccessMask;
 
-			objectTypes.PushLast(type);
+			allRegisteredTypes.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
 			registeredObjTypes.PushLast(type);
 
 			currentGroup->objTypes.PushLast(type);
@@ -1760,7 +1771,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 			type->flags      = flags;
 			type->accessMask = defaultAccessMask;
 
-			templateTypes.PushLast(type);
+			templateInstanceTypes.PushLast(type);
 
 			currentGroup->objTypes.PushLast(type);
 
@@ -1989,6 +2000,15 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 		}
 
+		// Don't accept duplicates
+		if( beh->listFactory )
+		{
+			if( listPattern )
+				listPattern->Destroy(this);
+
+			return ConfigError(asALREADY_REGISTERED, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+		}
+
 		// Add the function
 		func.id = AddBehaviourFunction(func, internal);
 
@@ -2023,8 +2043,6 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 		}
 
-		// TODO: Verify that the same factory function hasn't been registered already
-
 		// The templates take a hidden parameter with the object type
 		if( (objectType->flags & asOBJ_TEMPLATE) &&
 			(func.parameterTypes.GetLength() == 0 ||
@@ -2037,6 +2055,17 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 		}
 
+		// TODO: Verify that the same factory function hasn't been registered already
+
+		// Don't accept duplicates
+		if( behaviour == asBEHAVE_LIST_FACTORY && beh->listFactory )
+		{
+			if( listPattern )
+				listPattern->Destroy(this);
+
+			return ConfigError(asALREADY_REGISTERED, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+		}
+
 		// Store all factory functions in a list
 		func.id = AddBehaviourFunction(func, internal);
 
@@ -2707,6 +2736,9 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 	if( func->name == "opAssign" && func->parameterTypes.GetLength() == 1 && func->isReadOnly == false &&
 		(objectType->flags & asOBJ_SCRIPT_OBJECT || func->parameterTypes[0].IsEqualExceptRefAndConst(asCDataType::CreateObject(func->objectType, false))) )
 	{
+		if( func->objectType->beh.copy != 0 )
+			return ConfigError(asALREADY_REGISTERED, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
+
 		func->objectType->beh.copy = func->id;
 		func->AddRef();
 	}
@@ -2775,12 +2807,11 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 
 	// Make sure the function is not identical to a previously registered function
 	asUINT n;
-	for( n = 0; n < registeredGlobalFuncs.GetLength(); n++ )
+	const asCArray<unsigned int> &idxs = registeredGlobalFuncs.GetIndexes(func->nameSpace, func->name);
+	for( n = 0; n < idxs.GetLength(); n++ )
 	{
-		asCScriptFunction *f = registeredGlobalFuncs[n];
-		if( f->name == func->name &&
-			f->nameSpace == func->nameSpace &&
-			f->IsSignatureExceptNameAndReturnTypeEqual(func) )
+		asCScriptFunction *f = registeredGlobalFuncs.Get(idxs[n]);
+		if( f->IsSignatureExceptNameAndReturnTypeEqual(func) )
 		{
 			func->funcType = asFUNC_DUMMY;
 			asDELETE(func,asCScriptFunction);
@@ -2793,7 +2824,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 
 	currentGroup->scriptFunctions.PushLast(func);
 	func->accessMask = defaultAccessMask;
-	registeredGlobalFuncs.PushLast(func);
+	registeredGlobalFuncs.Put(func);
 
 	// If parameter type from other groups are used, add references
 	if( func->returnType.GetObjectType() )
@@ -2818,7 +2849,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 asUINT asCScriptEngine::GetGlobalFunctionCount() const
 {
 	// Don't count the builtin delegate factory
-	return asUINT(registeredGlobalFuncs.GetLength()-1);
+	return asUINT(registeredGlobalFuncs.GetSize()-1);
 }
 
 // interface
@@ -2827,10 +2858,10 @@ asIScriptFunction *asCScriptEngine::GetGlobalFunctionByIndex(asUINT index) const
 	// Don't count the builtin delegate factory
 	index++;
 
-	if( index >= registeredGlobalFuncs.GetLength() )
+	if( index >= registeredGlobalFuncs.GetSize() )
 		return 0;
 
-	return registeredGlobalFuncs[index];
+	return static_cast<asIScriptFunction*>(const_cast<asCScriptFunction*>(registeredGlobalFuncs.Get(index)));
 }
 
 // interface
@@ -2846,20 +2877,21 @@ asIScriptFunction *asCScriptEngine::GetGlobalFunctionByDecl(const char *decl) co
 	if( r < 0 )
 		return 0;
 
-	// TODO: optimize: Improve linear search
-	// Search registered functions for matching interface
-	int id = -1;
-	for( size_t n = 0; n < registeredGlobalFuncs.GetLength(); ++n )
-	{
-		if( registeredGlobalFuncs[n]->objectType == 0 &&
-			func.name == registeredGlobalFuncs[n]->name &&
-			func.returnType == registeredGlobalFuncs[n]->returnType &&
-			func.parameterTypes.GetLength() == registeredGlobalFuncs[n]->parameterTypes.GetLength() )
+	// Search script functions for matching interface
+	asIScriptFunction *f = 0;
+	const asCArray<unsigned int> &idxs = registeredGlobalFuncs.GetIndexes(defaultNamespace, func.name);
+	for( unsigned int n = 0; n < idxs.GetLength(); n++ )
+	{
+		const asCScriptFunction *funcPtr = registeredGlobalFuncs.Get(idxs[n]);
+		if( funcPtr->objectType == 0 &&
+			func.returnType                 == funcPtr->returnType &&
+			func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
+			)
 		{
 			bool match = true;
 			for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
 			{
-				if( func.parameterTypes[p] != registeredGlobalFuncs[n]->parameterTypes[p] )
+				if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
 				{
 					match = false;
 					break;
@@ -2868,28 +2900,24 @@ asIScriptFunction *asCScriptEngine::GetGlobalFunctionByDecl(const char *decl) co
 
 			if( match )
 			{
-				if( id == -1 )
-					id = registeredGlobalFuncs[n]->id;
+				if( f == 0 )
+					f = const_cast<asCScriptFunction*>(funcPtr);
 				else
-					return 0; // Multiple matches
+					// Multiple functions
+					return 0;
 			}
 		}
 	}
 
-	if( id < 0 ) return 0; // No matches
-
-	return scriptFunctions[id];
+	return f;
 }
 
 
-asCObjectType *asCScriptEngine::GetObjectType(const char *type, asSNameSpace *ns) const
+asCObjectType *asCScriptEngine::GetRegisteredObjectType(const asCString &type, asSNameSpace *ns) const
 {
-	// TODO: optimize: Improve linear search
-	for( asUINT n = 0; n < objectTypes.GetLength(); n++ )
-		if( objectTypes[n] &&
-			objectTypes[n]->name == type &&
-			objectTypes[n]->nameSpace == ns ) // TODO: template: Should we check the subtype in case of template instances?
-			return objectTypes[n];
+	asSMapNode<asSNameSpaceNamePair, asCObjectType *> *cursor;
+	if( allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(ns, type)) )
+		return cursor->value;
 
 	return 0;
 }
@@ -2917,55 +2945,56 @@ void asCScriptEngine::PrepareEngine()
 	}
 
 	// Validate object type registrations
-	for( n = 0; n < objectTypes.GetLength(); n++ )
+	for( n = 0; n < registeredObjTypes.GetLength(); n++ )
 	{
-		if( objectTypes[n] && !(objectTypes[n]->flags & asOBJ_SCRIPT_OBJECT) )
+		asCObjectType *type = registeredObjTypes[n];
+		if( type && !(type->flags & asOBJ_SCRIPT_OBJECT) )
 		{
 			bool missingBehaviour = false;
 			const char *infoMsg = 0;
 
 			// Verify that GC types have all behaviours
-			if( objectTypes[n]->flags & asOBJ_GC )
+			if( type->flags & asOBJ_GC )
 			{
-				if( objectTypes[n]->beh.addref                 == 0 ||
-					objectTypes[n]->beh.release                == 0 ||
-					objectTypes[n]->beh.gcGetRefCount          == 0 ||
-					objectTypes[n]->beh.gcSetFlag              == 0 ||
-					objectTypes[n]->beh.gcGetFlag              == 0 ||
-					objectTypes[n]->beh.gcEnumReferences       == 0 ||
-					objectTypes[n]->beh.gcReleaseAllReferences == 0 )
+				if( type->beh.addref                 == 0 ||
+					type->beh.release                == 0 ||
+					type->beh.gcGetRefCount          == 0 ||
+					type->beh.gcSetFlag              == 0 ||
+					type->beh.gcGetFlag              == 0 ||
+					type->beh.gcEnumReferences       == 0 ||
+					type->beh.gcReleaseAllReferences == 0 )
 				{
 					infoMsg = TXT_GC_REQUIRE_ADD_REL_GC_BEHAVIOUR;
 					missingBehaviour = true;
 				}
 			}
 			// Verify that scoped ref types have the release behaviour
-			else if( objectTypes[n]->flags & asOBJ_SCOPED )
+			else if( type->flags & asOBJ_SCOPED )
 			{
-				if( objectTypes[n]->beh.release == 0 )
+				if( type->beh.release == 0 )
 				{
 					infoMsg = TXT_SCOPE_REQUIRE_REL_BEHAVIOUR;
 					missingBehaviour = true;
 				}
 			}
 			// Verify that ref types have add ref and release behaviours
-			else if( (objectTypes[n]->flags & asOBJ_REF) &&
-				     !(objectTypes[n]->flags & asOBJ_NOHANDLE) &&
-					 !(objectTypes[n]->flags & asOBJ_NOCOUNT) )
+			else if( (type->flags & asOBJ_REF) &&
+				     !(type->flags & asOBJ_NOHANDLE) &&
+					 !(type->flags & asOBJ_NOCOUNT) )
 			{
-				if( objectTypes[n]->beh.addref  == 0 ||
-					objectTypes[n]->beh.release == 0 )
+				if( type->beh.addref  == 0 ||
+					type->beh.release == 0 )
 				{
 					infoMsg = TXT_REF_REQUIRE_ADD_REL_BEHAVIOUR;
 					missingBehaviour = true;
 				}
 			}
 			// Verify that non-pod value types have the constructor and destructor registered
-			else if( (objectTypes[n]->flags & asOBJ_VALUE) &&
-				     !(objectTypes[n]->flags & asOBJ_POD) )
+			else if( (type->flags & asOBJ_VALUE) &&
+				     !(type->flags & asOBJ_POD) )
 			{
-				if( objectTypes[n]->beh.construct == 0 ||
-					objectTypes[n]->beh.destruct  == 0 )
+				if( type->beh.construct == 0 ||
+					type->beh.destruct  == 0 )
 				{
 					infoMsg = TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR;
 					missingBehaviour = true;
@@ -2975,7 +3004,7 @@ void asCScriptEngine::PrepareEngine()
 			if( missingBehaviour )
 			{
 				asCString str;
-				str.Format(TXT_TYPE_s_IS_MISSING_BEHAVIOURS, objectTypes[n]->name.AddressOf());
+				str.Format(TXT_TYPE_s_IS_MISSING_BEHAVIOURS, type->name.AddressOf());
 				WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, infoMsg);
 				ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
@@ -3082,9 +3111,11 @@ int asCScriptEngine::RegisterStringFactory(const char *datatype, const asSFuncPt
 
 	func->returnType = dt;
 	func->parameterTypes.PushLast(asCDataType::CreatePrimitive(ttInt, true));
+	func->inOutFlags.PushLast(asTM_NONE);
 	asCDataType parm1 = asCDataType::CreatePrimitive(ttUInt8, true);
 	parm1.MakeReference(true);
 	func->parameterTypes.PushLast(parm1);
+	func->inOutFlags.PushLast(asTM_INREF);
 	func->id = GetNextScriptFunctionId();
 	SetScriptFunction(func);
 
@@ -3213,14 +3244,14 @@ void asCScriptEngine::RemoveTemplateInstanceType(asCObjectType *t)
 
 	// Start searching from the end of the list, as most of
 	// the time it will be the last two types
-	for( n = (int)templateTypes.GetLength()-1; n >= 0; n-- )
+	for( n = (int)templateInstanceTypes.GetLength()-1; n >= 0; n-- )
 	{
-		if( templateTypes[n] == t )
+		if( templateInstanceTypes[n] == t )
 		{
-			if( n == (signed)templateTypes.GetLength()-1 )
-				templateTypes.PopLast();
+			if( n == (signed)templateInstanceTypes.GetLength()-1 )
+				templateInstanceTypes.PopLast();
 			else
-				templateTypes[n] = templateTypes.PopLast();
+				templateInstanceTypes[n] = templateInstanceTypes.PopLast();
 		}
 	}
 
@@ -3241,28 +3272,30 @@ void asCScriptEngine::RemoveTemplateInstanceType(asCObjectType *t)
 // internal
 void asCScriptEngine::OrphanTemplateInstances(asCObjectType *subType)
 {
-	for( asUINT n = 0; n < templateTypes.GetLength(); n++ )
+	for( asUINT n = 0; n < templateInstanceTypes.GetLength(); n++ )
 	{
-		if( templateTypes[n] == 0 )
+		asCObjectType *type = templateInstanceTypes[n];
+		
+		if( type == 0 )
 			continue;
-
+		
 		// If the template type isn't owned by any module it can't be orphaned
-		if( templateTypes[n]->module == 0 )
+		if( type->module == 0 )
 			continue;
 
-		for( asUINT subTypeIdx = 0; subTypeIdx < templateTypes[n]->templateSubTypes.GetLength(); subTypeIdx++ )
+		for( asUINT subTypeIdx = 0; subTypeIdx < type->templateSubTypes.GetLength(); subTypeIdx++ )
 		{
-			if( templateTypes[n]->templateSubTypes[subTypeIdx].GetObjectType() == subType )
+			if( type->templateSubTypes[subTypeIdx].GetObjectType() == subType )
 			{
 				// Tell the GC that the template type exists so it can resolve potential circular references
-				gc.AddScriptObjectToGC(templateTypes[n], &objectTypeBehaviours);
+				gc.AddScriptObjectToGC(type, &objectTypeBehaviours);
 
 				// Clear the module
-				templateTypes[n]->module = 0;
-				templateTypes[n]->Release();
+				type->module = 0;
+				type->Release();
 
 				// Do a recursive check for other template instances
-				OrphanTemplateInstances(templateTypes[n]);
+				OrphanTemplateInstances(type);
 
 				// Break out so we don't add the same template to
 				// the gc again if another subtype matches this one
@@ -3278,12 +3311,12 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	asUINT n;
 
 	// Is there any template instance type or template specialization already with this subtype?
-	for( n = 0; n < templateTypes.GetLength(); n++ )
+	for( n = 0; n < templateInstanceTypes.GetLength(); n++ )
 	{
-		if( templateTypes[n] &&
-			templateTypes[n]->name == templateType->name &&
-			templateTypes[n]->templateSubTypes == subTypes )
-			return templateTypes[n];
+		if( templateInstanceTypes[n] &&
+			templateInstanceTypes[n]->name == templateType->name &&
+			templateInstanceTypes[n]->templateSubTypes == subTypes )
+			return templateInstanceTypes[n];
 	}
 
 	// No previous template instance exists
@@ -3463,10 +3496,10 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 		if( ot->templateSubTypes[n].GetObjectType() )
 			ot->templateSubTypes[n].GetObjectType()->AddRef();
 
-	templateTypes.PushLast(ot);
+	templateInstanceTypes.PushLast(ot);
 
 	// Store the template instance types that have been created automatically by the engine from a template type
-	// The object types in templateTypes that are not also in generatedTemplateTypes are registered template specializations
+	// The object types in templateInstanceTypes that are not also in generatedTemplateTypes are registered template specializations
 	generatedTemplateTypes.PushLast(ot);
 
 	return ot;
@@ -4978,13 +5011,10 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 	if( type == 0 ) return ConfigError(asINVALID_NAME, "RegisterTypedef", type, decl);
 
 	// Verify if the name has been registered as a type already
-	asUINT n;
-	for( n = 0; n < objectTypes.GetLength(); n++ )
-	{
-		if( objectTypes[n] && objectTypes[n]->name == type && objectTypes[n]->nameSpace == defaultNamespace )
-			// Let the application recover from this error, for example if the same typedef is registered twice
-			return asALREADY_REGISTERED;
-	}
+	// TODO: Must check against registered funcdefs too
+	if( GetRegisteredObjectType(type, defaultNamespace) )
+		// Let the application recover from this error, for example if the same typedef is registered twice
+		return asALREADY_REGISTERED;
 
 	// Grab the data type
 	size_t tokenLen;
@@ -5042,7 +5072,7 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 	object->nameSpace       = defaultNamespace;
 	object->templateSubTypes.PushLast(dataType);
 
-	objectTypes.PushLast(object);
+	allRegisteredTypes.Insert(asSNameSpaceNamePair(object->nameSpace, object->name), object);
 	registeredTypeDefs.PushLast(object);
 
 	currentGroup->objTypes.PushLast(object);
@@ -5091,10 +5121,9 @@ int asCScriptEngine::RegisterEnum(const char *name)
 		return ConfigError(asINVALID_NAME, "RegisterEnum", name, 0);
 
 	// Verify if the name has been registered as a type already
-	asUINT n;
-	for( n = 0; n < objectTypes.GetLength(); n++ )
-		if( objectTypes[n] && objectTypes[n]->name == name && objectTypes[n]->nameSpace == defaultNamespace )
-			return asALREADY_REGISTERED;
+	// TODO: Must check for registered funcdefs too
+	if( GetRegisteredObjectType(name, defaultNamespace) )
+		return asALREADY_REGISTERED;
 
 	// Use builder to parse the datatype
 	asCDataType dt;
@@ -5127,7 +5156,7 @@ int asCScriptEngine::RegisterEnum(const char *name)
 	st->name = name;
 	st->nameSpace = defaultNamespace;
 
-	objectTypes.PushLast(st);
+	allRegisteredTypes.Insert(asSNameSpaceNamePair(st->nameSpace, st->name), st);
 	registeredEnums.PushLast(st);
 
 	currentGroup->objTypes.PushLast(st);
@@ -5260,6 +5289,7 @@ asIObjectType *asCScriptEngine::GetObjectTypeByIndex(asUINT index) const
 // interface
 asIObjectType *asCScriptEngine::GetObjectTypeByName(const char *name) const
 {
+	// Check the object types
 	for( asUINT n = 0; n < registeredObjTypes.GetLength(); n++ )
 	{
 		if( registeredObjTypes[n]->name == name &&
@@ -5267,6 +5297,15 @@ asIObjectType *asCScriptEngine::GetObjectTypeByName(const char *name) const
 			return registeredObjTypes[n];
 	}
 
+	// Perhaps it is a template type? In this case
+	// the returned type will be the generic type
+	for( asUINT n = 0; n < registeredTemplateTypes.GetLength(); n++ )
+	{
+		if( registeredTemplateTypes[n]->name == name &&
+			registeredTemplateTypes[n]->nameSpace == defaultNamespace )
+			return registeredTemplateTypes[n];
+	}
+
 	return 0;
 }
 
@@ -5300,13 +5339,12 @@ asIScriptFunction *asCScriptEngine::GetFuncDefFromTypeId(int typeId) const
 // internal
 bool asCScriptEngine::IsTemplateType(const char *name) const
 {
-	// TODO: optimize: Improve linear search
-	for( unsigned int n = 0; n < objectTypes.GetLength(); n++ )
+	// Only look in the list of template types (not instance types)
+	for( unsigned int n = 0; n < registeredTemplateTypes.GetLength(); n++ )
 	{
-		if( objectTypes[n] && objectTypes[n]->name == name )
-		{
-			return objectTypes[n]->flags & asOBJ_TEMPLATE ? true : false;
-		}
+		asCObjectType *type = registeredTemplateTypes[n];
+		if( type && type->name == name )
+			return true;
 	}
 
 	return false;

+ 20 - 17
Source/ThirdParty/AngelScript/source/as_scriptengine.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -80,9 +80,9 @@ public:
 	virtual int ClearMessageCallback();
 	virtual int WriteMessage(const char *section, int row, int col, asEMsgType type, const char *message);
 
-    // JIT Compiler
-    virtual int SetJITCompiler(asIJITCompiler *compiler);
-    virtual asIJITCompiler *GetJITCompiler() const;
+	// JIT Compiler
+	virtual int SetJITCompiler(asIJITCompiler *compiler);
+	virtual asIJITCompiler *GetJITCompiler() const;
 
 	// Global functions
 	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
@@ -151,7 +151,7 @@ public:
 
 	// Script functions
 	virtual asIScriptFunction *GetFunctionById(int funcId) const;
-    virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const;
+	virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const;
 
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const;
@@ -263,7 +263,7 @@ public:
 
 	int CreateContext(asIScriptContext **context, bool isInternal);
 
-	asCObjectType *GetObjectType(const char *type, asSNameSpace *ns) const;
+	asCObjectType *GetRegisteredObjectType(const asCString &name, asSNameSpace *ns) const;
 
 	asCObjectType *GetListPatternType(int listPatternFuncId);
 	void DestroyList(asBYTE *buffer, const asCObjectType *listPatternType);
@@ -328,23 +328,26 @@ public:
 	asCObjectType    globalPropertyBehaviours;
 
 	// Registered interface
-	asCArray<asCObjectType *>          registeredObjTypes;
-	asCArray<asCObjectType *>          registeredTypeDefs;
-	asCArray<asCObjectType *>          registeredEnums;
-	asCSymbolTable<asCGlobalProperty>  registeredGlobalProps;
-	asCArray<asCScriptFunction *>      registeredGlobalFuncs;
-	asCArray<asCScriptFunction *>      registeredFuncDefs;
-	asCScriptFunction                 *stringFactory;
+	asCArray<asCObjectType *>         registeredObjTypes;
+	asCArray<asCObjectType *>         registeredTypeDefs;
+	asCArray<asCObjectType *>         registeredEnums;
+	asCSymbolTable<asCGlobalProperty> registeredGlobalProps; // TODO: memory savings: Since there can be only one property with the same name a simpler symbol table should be used
+	asCSymbolTable<asCScriptFunction> registeredGlobalFuncs;
+	asCArray<asCScriptFunction *>     registeredFuncDefs;
+	asCArray<asCObjectType *>         registeredTemplateTypes;
+	asCScriptFunction                *stringFactory;
 	bool configFailed;
 
-	// Stores all known object types, both application registered, and script declared
-	asCArray<asCObjectType *>      objectTypes;
+	// Stores all registered types except funcdefs
+	asCMap<asSNameSpaceNamePair, asCObjectType*> allRegisteredTypes;  
+
+	// Dummy types used to name the subtypes in the template objects 
 	asCArray<asCObjectType *>      templateSubTypes;
 
 	// Store information about template types
 	// This list will contain all instances of templates, both registered specialized 
 	// types and those automacially instanciated from scripts
-	asCArray<asCObjectType *>      templateTypes;
+	asCArray<asCObjectType *>      templateInstanceTypes;
 
 	// Store information about list patterns
 	asCArray<asCObjectType *>      listPatternTypes;
@@ -407,7 +410,7 @@ public:
 	asSSystemFunctionInterface  msgCallbackFunc;
 	void                       *msgCallbackObj;
 
-    asIJITCompiler              *jitCompiler;
+	asIJITCompiler             *jitCompiler;
 
 	// Namespaces
 	// These are shared between all entities and are 

+ 6 - 1
Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -144,8 +144,13 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	r = engine->RegisterGlobalFunction("void f(int &in, int &in)", asFUNCTION(ScriptFunction_CreateDelegate_Generic), asCALL_GENERIC); asASSERT( r >= 0 );
 #endif
 
-	// Change the return type so the VM will know the function really returns a handle
+	// Rename the function so that it cannot be called manually by the script
+	int idx = engine->registeredGlobalFuncs.GetIndex(engine->scriptFunctions[r]);
+	engine->registeredGlobalFuncs.Erase(idx);
 	engine->scriptFunctions[r]->name = DELEGATE_FACTORY;
+	engine->registeredGlobalFuncs.Put(engine->scriptFunctions[r]);
+
+	// Change the return type so the VM will know the function really returns a handle
 	engine->scriptFunctions[r]->returnType = asCDataType::CreateObject(&engine->functionBehaviours, false);
 	engine->scriptFunctions[r]->returnType.MakeHandle(true);
 }

+ 64 - 40
Source/ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -54,11 +54,9 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 	ctx = asGetActiveContext();
 	if( ctx )
 	{
-		r = ctx->PushState();
-
 		// It may not always be possible to reuse the current context, 
 		// in which case we'll have to create a new one any way.
-		if( r == asSUCCESS )
+		if( ctx->GetEngine() == objType->GetEngine() && ctx->PushState() == asSUCCESS )
 			isNested = true;
 		else
 			ctx = 0;
@@ -251,34 +249,23 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 	if( objType->flags & asOBJ_GC )
 		objType->engine->gc.AddScriptObjectToGC(this, objType);
 
+	// Initialize members to zero. Technically we only need to zero the pointer
+	// members, but just the memset is faster than having to loop and check the datatypes
+	memset(this+1, 0, objType->size - sizeof(asCScriptObject));
+
 	if( doInitialize )
 	{
-#ifndef AS_NO_MEMBER_INIT
-		// The actual initialization will be done by the bytecode, so here we should just clear the
-		// memory to guarantee that no pointers with have scratch values in case of an exception
-		// TODO: runtime optimize: Is it quicker to just do a memset on the entire object? 
-		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
-		{
-			asCObjectProperty *prop = objType->properties[n];
-			if( prop->type.IsObject() )
-			{
-				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
-				*ptr = 0;
-			}
-		}
-#else
+#ifdef AS_NO_MEMBER_INIT
 		// When member initialization is disabled the constructor must make sure
 		// to allocate and initialize all members with the default constructor
 		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
 		{
 			asCObjectProperty *prop = objType->properties[n];
-			if( prop->type.IsObject() )
+			if( prop->type.IsObject() && !prop->type.IsObjectHandle() )
 			{
-				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
-				if( prop->type.IsObjectHandle() )
-					*ptr = 0;
-				else
+				if( prop->type.IsReference() || prop->type.GetObjectType()->flags & asOBJ_REF )
 				{
+					asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
 					if( prop->type.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT )
 						*ptr = (asPWORD)ScriptObjectFactory(prop->type.GetObjectType(), ot->engine);
 					else
@@ -295,13 +282,13 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
 		{
 			asCObjectProperty *prop = objType->properties[n];
-			if( prop->type.IsObject() )
+			if( prop->type.IsObject() && !prop->type.IsObjectHandle() )
 			{
-				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
-				if( prop->type.IsObjectHandle() )
-					*ptr = 0;
-				else
+				if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
+				{
+					asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
 					*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), engine);
+				}
 			}
 		}
 	}
@@ -342,11 +329,26 @@ asCScriptObject::~asCScriptObject()
 		if( prop->type.IsObject() )
 		{
 			// Destroy the object
-			void **ptr = (void**)(((char*)this) + prop->byteOffset);
-			if( *ptr )
+			asCObjectType *propType = prop->type.GetObjectType();
+			if( prop->type.IsReference() || propType->flags & asOBJ_REF )
+			{
+				void **ptr = (void**)(((char*)this) + prop->byteOffset);
+				if( *ptr )
+				{
+					FreeObject(*ptr, propType, engine);
+					*(asDWORD*)ptr = 0;
+				}
+			}
+			else
 			{
-				FreeObject(*ptr, prop->type.GetObjectType(), engine);
-				*(asDWORD*)ptr = 0;
+				// The object is allocated inline. As only POD objects may be allocated inline
+				// it is not a problem to call the destructor even if the object may never have
+				// been initialized, e.g. if an exception interrupted the constructor.
+				asASSERT( propType->flags & asOBJ_POD );
+
+				void *ptr = (void**)(((char*)this) + prop->byteOffset);
+				if( propType->beh.destruct )
+					engine->CallObjectMethod(ptr, propType->beh.destruct);
 			}
 		}
 	}
@@ -485,8 +487,7 @@ void asCScriptObject::CallDestructor()
 				ctx = asGetActiveContext();
 				if( ctx )
 				{
-					int r = ctx->PushState();
-					if( r == asSUCCESS )
+					if( ctx->GetEngine() == objType->GetEngine() && ctx->PushState() == asSUCCESS )
 						isNested = true;
 					else
 						ctx = 0;
@@ -614,7 +615,8 @@ void *asCScriptObject::GetAddressOfProperty(asUINT prop)
 
 	// Objects are stored by reference, so this must be dereferenced
 	asCDataType *dt = &objType->properties[prop]->type;
-	if( dt->IsObject() && !dt->IsObjectHandle() )
+	if( dt->IsObject() && !dt->IsObjectHandle() &&
+		(dt->IsReference() || dt->GetObjectType()->flags & asOBJ_REF) )
 		return *(void**)(((char*)this) + objType->properties[prop]->byteOffset);
 
 	return (void*)(((char*)this) + objType->properties[prop]->byteOffset);
@@ -628,7 +630,14 @@ void asCScriptObject::EnumReferences(asIScriptEngine *engine)
 		asCObjectProperty *prop = objType->properties[n];
 		if( prop->type.IsObject() )
 		{
-			void *ptr = *(void**)(((char*)this) + prop->byteOffset);
+			// TODO: gc: The members of the value type needs to be enumerated
+			//           too, since the value type may be holding a reference.
+			void *ptr;
+			if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
+				ptr = *(void**)(((char*)this) + prop->byteOffset);
+			else
+				ptr = (void*)(((char*)this) + prop->byteOffset);
+
 			if( ptr )
 				((asCScriptEngine*)engine)->GCEnumCallback(ptr);
 		}
@@ -640,6 +649,10 @@ void asCScriptObject::ReleaseAllHandles(asIScriptEngine *engine)
 	for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
 	{
 		asCObjectProperty *prop = objType->properties[n];
+
+		// TODO: gc: The members of the members needs to be released
+		//           too, since they may be holding a reference. Even
+		//           if the member is a value type.
 		if( prop->type.IsObject() && prop->type.IsObjectHandle() )
 		{
 			void **ptr = (void**)(((char*)this) + prop->byteOffset);
@@ -673,7 +686,14 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 {
 	if( &other != this )
 	{
-		asASSERT( other.objType->DerivesFrom(objType) );
+		if( !other.objType->DerivesFrom(objType) )
+		{
+			// We cannot allow a value assignment from a type that isn't the same or 
+			// derives from this type as the member properties may not have the same layout
+			asIScriptContext *ctx = asGetActiveContext();
+			ctx->SetException(TXT_MISMATCH_IN_VALUE_ASSIGN);
+			return *this;
+		}
 
 		// If the script class implements the opAssign method, it should be called
 		asCScriptEngine *engine = objType->engine;
@@ -689,7 +709,12 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 					void **dst = (void**)(((char*)this) + prop->byteOffset);
 					void **src = (void**)(((char*)&other) + prop->byteOffset);
 					if( !prop->type.IsObjectHandle() )
-						CopyObject(*src, *dst, prop->type.GetObjectType(), engine);
+					{
+						if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
+							CopyObject(*src, *dst, prop->type.GetObjectType(), engine);
+						else
+							CopyObject(src, dst, prop->type.GetObjectType(), engine);
+					}
 					else
 						CopyHandle((asPWORD*)src, (asPWORD*)dst, prop->type.GetObjectType(), engine);
 				}
@@ -711,8 +736,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 			ctx = asGetActiveContext();
 			if( ctx )
 			{
-				r = ctx->PushState();
-				if( r == asSUCCESS )
+				if( ctx->GetEngine() == engine && ctx->PushState() == asSUCCESS )
 					isNested = true;
 				else
 					ctx = 0;

+ 96 - 116
Source/ThirdParty/AngelScript/source/as_symboltable.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2012 Andreas Jonsson
+   Copyright (c) 2012-2013 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
@@ -46,19 +46,11 @@
 #include "as_string.h"
 #include "as_map.h"
 #include "as_datatype.h"
+#include "as_namespace.h"
 
 
 BEGIN_AS_NAMESPACE
 
-// TODO: cleanup: This should be in its own header. It is only here because it is
-//                needed for the template and cannot be resolved with a forward declaration
-struct asSNameSpace
-{
-	asCString name;
-
-	// TODO: namespace: A namespace should have access masks. The application should be
-	//                  able to restrict specific namespaces from access to specific modules
-};
 
 
 
@@ -84,34 +76,36 @@ template<class T, class T2 = T>
 class asCSymbolTableIterator
 {
 public:
-    T2* operator*() const;
-    T2* operator->() const;
-    asCSymbolTableIterator<T, T2>& operator++(int);
-    asCSymbolTableIterator<T, T2>& operator--(int);
-    operator bool() const;
-    int GetIndex() const { return m_idx; }
+	T2* operator*() const;
+	T2* operator->() const;
+	asCSymbolTableIterator<T, T2>& operator++(int);
+	asCSymbolTableIterator<T, T2>& operator--(int);
+	operator bool() const;
+	int GetIndex() const { return m_idx; }
 
 private:
-    friend class asCSymbolTable<T>;
-    asCSymbolTableIterator<T, T2>(asCSymbolTable<T> *table);
+	friend class asCSymbolTable<T>;
+	asCSymbolTableIterator<T, T2>(asCSymbolTable<T> *table);
 
-    void Next();
-    void Previous();
+	void Next();
+	void Previous();
 
-    asCSymbolTable<T>* m_table;
-    unsigned int       m_idx;
+	asCSymbolTable<T>* m_table;
+	unsigned int       m_idx;
 };
 
 
 
 
 // Symbol table mapping namespace + name to symbols
+// The structure keeps the entries indexed in an array so the indices will not change
+// There is also a map for a quick lookup. The map supports multiple entries with the same name
 template<class T>
 class asCSymbolTable
 {
 public:
-    typedef asCSymbolTableIterator<T, T> iterator;
-    typedef asCSymbolTableIterator<T, const T> const_iterator;
+	typedef asCSymbolTableIterator<T, T> iterator;
+	typedef asCSymbolTableIterator<T, const T> const_iterator;
 
 	asCSymbolTable(unsigned int initialCapacity = 0);
 
@@ -125,11 +119,11 @@ public:
 	T*       GetFirst(const asSNameSpace *ns, const asCString &name);
 	const T* GetFirst(const asSNameSpace *ns, const asCString &name) const;
 	T*       Get(unsigned int index);
-    const T* Get(unsigned int index) const;
+	const T* Get(unsigned int index) const;
 	T*       GetLast();
-    const T* GetLast() const;
+	const T* GetLast() const;
 
-    const asCArray<unsigned int> &GetIndexes(const asSNameSpace *ns, const asCString &name) const;
+	const asCArray<unsigned int> &GetIndexes(const asSNameSpace *ns, const asCString &name) const;
 
 	int          Put(T* entry);
 
@@ -148,16 +142,15 @@ private:
 	// Don't allow assignment
 	asCSymbolTable<T>& operator=(const asCSymbolTable<T> &other) { return *this; }
 
-    friend class asCSymbolTableIterator<T, T>;
-    friend class asCSymbolTableIterator<T, const T>;
+	friend class asCSymbolTableIterator<T, T>;
+	friend class asCSymbolTableIterator<T, const T>;
 
-	void GetKey(const T *entry, asCString &key) const;
-	void BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const;
+	void GetKey(const T *entry, asSNameSpaceNamePair &key) const;
 	bool CheckIdx(unsigned idx) const;
 
-	asCMap<asCString, asCArray<unsigned int> > m_map;
-	asCArray<T*>                               m_entries;
-	unsigned int                               m_size;
+	asCMap<asSNameSpaceNamePair, asCArray<unsigned int> > m_map;
+	asCArray<T*>                                          m_entries;
+	unsigned int                                          m_size;
 };
 
 
@@ -193,10 +186,9 @@ int asCSymbolTable<T>::GetFirstIndex(
         const asCString &name,
         const asIFilter &filter) const
 {
-	asCString key;
-	BuildKey(ns, name, key);
+	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asCString, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 	{
 		const asCArray<unsigned int> &arr = m_map.GetValue(cursor);
@@ -216,10 +208,9 @@ int asCSymbolTable<T>::GetFirstIndex(
 template<class T>
 const asCArray<unsigned int> &asCSymbolTable<T>::GetIndexes(const asSNameSpace *ns, const asCString &name) const
 {
-	asCString key;
-	BuildKey(ns, name, key);
+	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asCString, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 		return m_map.GetValue(cursor);
 
@@ -233,9 +224,9 @@ const asCArray<unsigned int> &asCSymbolTable<T>::GetIndexes(const asSNameSpace *
 template<class T>
 T* asCSymbolTable<T>::GetFirst(const asSNameSpace *ns, const asCString &name, const asIFilter &comp) const
 {
-    int idx = GetFirstIndex(ns, name, comp);
-    if (idx != -1) return m_entries[idx];
-    return 0;
+	int idx = GetFirstIndex(ns, name, comp);
+	if (idx != -1) return m_entries[idx];
+	return 0;
 }
 
 
@@ -244,14 +235,13 @@ T* asCSymbolTable<T>::GetFirst(const asSNameSpace *ns, const asCString &name, co
 template<class T>
 int asCSymbolTable<T>::GetFirstIndex(const asSNameSpace *ns, const asCString &name) const
 {
-    asCString key;
-    BuildKey(ns, name, key);
+	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asCString, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
-        return m_map.GetValue(cursor)[0];
+		return m_map.GetValue(cursor)[0];
 
-    return -1;
+	return -1;
 }
 
 
@@ -277,16 +267,16 @@ int asCSymbolTable<T>::GetIndex(const T* entry) const
 template<class T>
 T* asCSymbolTable<T>::Get(unsigned idx)
 {
-    if( !CheckIdx(idx) )
-        return 0;
+	if( !CheckIdx(idx) )
+		return 0;
 
-    return m_entries[idx];
+	return m_entries[idx];
 }
 
 template<class T>
 const T* asCSymbolTable<T>::Get(unsigned idx) const
 {
-    return const_cast< asCSymbolTable<T>* >(this)->Get(idx);
+	return const_cast< asCSymbolTable<T>* >(this)->Get(idx);
 }
 
 
@@ -296,14 +286,14 @@ const T* asCSymbolTable<T>::Get(unsigned idx) const
 template<class T>
 T* asCSymbolTable<T>::GetFirst(const asSNameSpace *ns, const asCString &name)
 {
-    int idx = GetFirstIndex(ns, name);
-    return Get(idx);
+	int idx = GetFirstIndex(ns, name);
+	return Get(idx);
 }
 
 template<class T>
 const T* asCSymbolTable<T>::GetFirst(const asSNameSpace *ns, const asCString &name) const
 {
-    return const_cast< asCSymbolTable<T>* >(this)->GetFirst(ns, name);
+	return const_cast< asCSymbolTable<T>* >(this)->GetFirst(ns, name);
 }
 
 
@@ -313,13 +303,13 @@ const T* asCSymbolTable<T>::GetFirst(const asSNameSpace *ns, const asCString &na
 template<class T>
 T* asCSymbolTable<T>::GetLast()
 {
-    return Get(GetLastIndex());
+	return Get(GetLastIndex());
 }
 
 template<class T>
 const T* asCSymbolTable<T>::GetLast() const
 {
-    return const_cast< asCSymbolTable<T>* >(this)->GetLast();
+	return const_cast< asCSymbolTable<T>* >(this)->GetLast();
 }
 
 
@@ -331,8 +321,8 @@ const T* asCSymbolTable<T>::GetLast() const
 template<class T>
 void asCSymbolTable<T>::Clear()
 {
-    m_entries.SetLength(0);
-    m_map.EraseAll();
+	m_entries.SetLength(0);
+	m_map.EraseAll();
 	m_size = 0;
 }
 
@@ -344,9 +334,9 @@ template<class T>
 void asCSymbolTable<T>::Allocate(unsigned elemCnt, bool keepData)
 {
 	asASSERT( elemCnt >= m_entries.GetLength() );
-    m_entries.Allocate(elemCnt, keepData);
-    if( !keepData )
-        m_map.EraseAll();
+	m_entries.Allocate(elemCnt, keepData);
+	if( !keepData )
+		m_map.EraseAll();
 }
 
 
@@ -354,15 +344,15 @@ void asCSymbolTable<T>::Allocate(unsigned elemCnt, bool keepData)
 template<class T>
 bool asCSymbolTable<T>::Erase(unsigned idx)
 {
-    if( !CheckIdx(idx) )
-    {
-        asASSERT(false);
-        return false;
-    }
+	if( !CheckIdx(idx) )
+	{
+		asASSERT(false);
+		return false;
+	}
 
-    T *entry = m_entries[idx];
-    asASSERT(entry);
-    if( !entry )
+	T *entry = m_entries[idx];
+	asASSERT(entry);
+	if( !entry )
 		return false;
 
 	if( idx == m_entries.GetLength() - 1 )
@@ -372,13 +362,16 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 		// TODO: Should remove all trailing empty slots
 	}
 	else
+	{
+		// TODO: Must pack or reuse empty slots
 		m_entries[idx] = 0;
+	}
 	m_size--;
 
-    asCString key;
-    GetKey(entry, key);
+	asSNameSpaceNamePair key;
+	GetKey(entry, key);
 
-	asSMapNode<asCString, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 	{
 		asCArray<unsigned int> &arr = m_map.GetValue(cursor);
@@ -399,10 +392,10 @@ template<class T>
 int asCSymbolTable<T>::Put(T *entry)
 {
 	unsigned int idx = (unsigned int)(m_entries.GetLength());
-	asCString key;
+	asSNameSpaceNamePair key;
 	GetKey(entry, key);
 
-	asSMapNode<asCString, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 		m_map.GetValue(cursor).PushLast(idx);
 	else
@@ -419,25 +412,12 @@ int asCSymbolTable<T>::Put(T *entry)
 
 
 
-template<class T>
-void asCSymbolTable<T>::BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const
-{
-	// TODO: optimize: The key shouldn't be just an asCString. It should keep the
-	//                 namespace as a pointer, so it can be compared as pointer.
-	//                 Which should be compared first, the namespace or the name? There is likely
-	//                 going to be many symbols with the same namespace, so it is probably best to
-	//                 compare the name first
-    key = ns->name + "::" + name;
-}
-
-
-
 
 // Return key for specified symbol (namespace and name are used to generate the key)
 template<class T>
-void asCSymbolTable<T>::GetKey(const T *entry, asCString &key) const
+void asCSymbolTable<T>::GetKey(const T *entry, asSNameSpaceNamePair &key) const
 {
-	BuildKey(entry->nameSpace, entry->name, key);
+	key = asSNameSpaceNamePair(entry->nameSpace, entry->name);
 }
 
 
@@ -455,7 +435,7 @@ unsigned int asCSymbolTable<T>::GetSize() const
 template<class T>
 bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 {
-    return idx < m_entries.GetLength();
+	return idx < m_entries.GetLength();
 }
 
 
@@ -464,9 +444,9 @@ bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 template<class T>
 int asCSymbolTable<T>::GetLastIndex() const
 {
-    unsigned int idx = (unsigned int)(m_entries.GetLength()) - 1;
+	unsigned int idx = (unsigned int)(m_entries.GetLength()) - 1;
 	asASSERT( idx == asUINT(-1) || m_entries[idx] );
-    return int(idx);
+	return int(idx);
 }
 
 
@@ -475,7 +455,7 @@ int asCSymbolTable<T>::GetLastIndex() const
 template<class T>
 asCSymbolTableIterator<T, T> asCSymbolTable<T>::List()
 {
-    return asCSymbolTableIterator<T, T>(this);
+	return asCSymbolTableIterator<T, T>(this);
 }
 
 
@@ -484,7 +464,7 @@ asCSymbolTableIterator<T, T> asCSymbolTable<T>::List()
 template<class T>
 typename asCSymbolTable<T>::const_iterator asCSymbolTable<T>::List() const
 {
-    return asCSymbolTableIterator<T, const T>(const_cast< asCSymbolTable<T> *>(this));
+	return asCSymbolTableIterator<T, const T>(const_cast< asCSymbolTable<T> *>(this));
 }
 
 
@@ -495,9 +475,9 @@ typename asCSymbolTable<T>::const_iterator asCSymbolTable<T>::List() const
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>::asCSymbolTableIterator(asCSymbolTable<T> *table) : m_table(table), m_idx(0)
 {
-    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
-    while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
-        m_idx++;
+	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
+		m_idx++;
 }
 
 
@@ -505,8 +485,8 @@ asCSymbolTableIterator<T, T2>::asCSymbolTableIterator(asCSymbolTable<T> *table)
 template<class T, class T2>
 T2* asCSymbolTableIterator<T, T2>::operator*() const
 {
-    asASSERT(m_table->CheckIdx(m_idx));
-    return m_table->m_entries[m_idx];
+	asASSERT(m_table->CheckIdx(m_idx));
+	return m_table->m_entries[m_idx];
 }
 
 
@@ -514,8 +494,8 @@ T2* asCSymbolTableIterator<T, T2>::operator*() const
 template<class T, class T2>
 T2* asCSymbolTableIterator<T, T2>::operator->() const
 {
-    asASSERT(m_table->CheckIdx(m_idx));
-    return m_table->m_entries[m_idx];
+	asASSERT(m_table->CheckIdx(m_idx));
+	return m_table->m_entries[m_idx];
 }
 
 
@@ -523,8 +503,8 @@ T2* asCSymbolTableIterator<T, T2>::operator->() const
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>& asCSymbolTableIterator<T, T2>::operator++(int)
 {
-    Next();
-    return *this;
+	Next();
+	return *this;
 }
 
 
@@ -535,7 +515,7 @@ asCSymbolTableIterator<T, T2>& asCSymbolTableIterator<T, T2>::operator++(int)
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>::operator bool() const
 {
-    return m_idx < m_table->m_entries.GetLength() && m_table->m_entries[m_idx] != 0;
+	return m_idx < m_table->m_entries.GetLength() && m_table->m_entries[m_idx] != 0;
 }
 
 
@@ -543,10 +523,10 @@ asCSymbolTableIterator<T, T2>::operator bool() const
 template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Next()
 {
-    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
-    m_idx++;
-    while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
-        m_idx++;
+	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	m_idx++;
+	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
+		m_idx++;
 }
 
 
@@ -554,11 +534,11 @@ void asCSymbolTableIterator<T, T2>::Next()
 template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Previous()
 {
-    // overflow on stepping over first element
-    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
-    m_idx--;
-    while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
-        m_idx--;
+	// overflow on stepping over first element
+	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	m_idx--;
+	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
+		m_idx--;
 }
 
 
@@ -566,8 +546,8 @@ void asCSymbolTableIterator<T, T2>::Previous()
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>& asCSymbolTableIterator<T, T2>::operator--(int)
 {
-    Previous();
-    return *this;
+	Previous();
+	return *this;
 }
 
 

+ 42 - 36
Source/ThirdParty/AngelScript/source/as_texts.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -96,11 +96,11 @@
 #define TXT_EXPR_MUST_BE_BOOL             "Expression must be of boolean type"
 
 #define TXT_FAILED_TO_COMPILE_DEF_ARG_d_IN_FUNC_s "Failed while compiling default arg for parameter %d in function '%s'"
-#define TXT_FAILED_TO_CREATE_TEMP_OBJ     "Previous error occurred while attempting to create a temporary copy of object"
-#define TXT_FLOAT_CONV_TO_INT_CAUSE_TRUNC "Float value truncated in implicit conversion to integer"
-#define TXT_FOUND_MULTIPLE_ENUM_VALUES    "Found multiple matching enum values"
-#define TXT_FUNCTION_ALREADY_EXIST        "A function with the same name and parameters already exists"
-#define TXT_FUNCTION_s_NOT_FOUND          "Function '%s' not found"
+#define TXT_FAILED_TO_CREATE_TEMP_OBJ             "Previous error occurred while attempting to create a temporary copy of object"
+#define TXT_FLOAT_CONV_TO_INT_CAUSE_TRUNC         "Float value truncated in implicit conversion to integer"
+#define TXT_FOUND_MULTIPLE_ENUM_VALUES            "Found multiple matching enum values"
+#define TXT_FUNCTION_ALREADY_EXIST                "A function with the same name and parameters already exists"
+#define TXT_FUNCTION_s_NOT_FOUND                  "Function '%s' not found"
 
 #define TXT_GET_SET_ACCESSOR_TYPE_MISMATCH_FOR_s "The property '%s' has mismatching types for the get and set accessors"
 #define TXT_GLOBAL_VARS_NOT_ALLOWED              "Global variables have been disabled by the application"
@@ -179,6 +179,7 @@
 #define TXT_s_NOT_MEMBER_OF_s                      "'%s' is not a member of '%s'"
 #define TXT_NOT_VALID_REFERENCE                    "Not a valid reference"
 #define TXT_NOT_VALID_LVALUE                       "Not a valid lvalue"
+#define TXT_NOTHING_WAS_BUILT                      "Nothing was built in the module"
 
 #define TXT_OBJECT_DOESNT_SUPPORT_INDEX_OP "Type '%s' doesn't support the indexing operator"
 #define TXT_OBJECT_HANDLE_NOT_SUPPORTED    "Object handle is not supported for this type"
@@ -213,6 +214,7 @@
 #define TXT_SHARED_CANNOT_INHERIT_FROM_NON_SHARED_s    "Shared class cannot inherit from non-shared class '%s'"
 #define TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s        "Shared code cannot use non-shared type '%s'"
 #define TXT_SHARED_s_DOESNT_MATCH_ORIGINAL             "Shared type '%s' doesn't match the original declaration in other module"
+#define TXT_SECTION_IS_EMPTY                           "The script section is empty"
 #define TXT_SIGNED_UNSIGNED_MISMATCH                   "Signed/Unsigned mismatch"
 #define TXT_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #define TXT_SWITCH_CASE_MUST_BE_CONSTANT               "Case expressions must be constants"
@@ -250,39 +252,41 @@
 
 // Engine message
 
-#define TXT_AUTOHANDLE_CANNOT_BE_USED_FOR_NOCOUNT     "Autohandles cannot be used with types that have been registered with NOCOUNT"
+#define TXT_AUTOHANDLE_CANNOT_BE_USED_FOR_NOCOUNT        "Autohandles cannot be used with types that have been registered with NOCOUNT"
 #define TXT_FIRST_PARAM_MUST_BE_REF_FOR_TEMPLATE_FACTORY "First parameter to template factory must be a reference. This will be used to pass the object type of the template"
-#define TXT_INVALID_CONFIGURATION                     "Invalid configuration. Verify the registered application interface."
-#define TXT_VALUE_TYPE_MUST_HAVE_SIZE                 "A value type must be registered with a non-zero size"
-#define TXT_TYPE_s_IS_MISSING_BEHAVIOURS              "Type '%s' is missing behaviours"
-#define TXT_ILLEGAL_BEHAVIOUR_FOR_TYPE                "The behaviour is not compatible with the type"
-#define TXT_GC_REQUIRE_ADD_REL_GC_BEHAVIOUR           "A garbage collected type must have the addref, release, and all gc behaviours"
-#define TXT_SCOPE_REQUIRE_REL_BEHAVIOUR               "A scoped reference type must have the release behaviour"
-#define TXT_REF_REQUIRE_ADD_REL_BEHAVIOUR             "A reference type must have the addref and release behaviours"
-#define TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR    "A non-pod value type must have the default constructor and destructor behaviours"
-#define TXT_CANNOT_PASS_TYPE_s_BY_VAL                 "Can't pass type '%s' by value unless the application type is informed in the registration"
-#define TXT_CANNOT_RET_TYPE_s_BY_VAL                  "Can't return type '%s' by value unless the application type is informed in the registration"
+#define TXT_INVALID_CONFIGURATION                        "Invalid configuration. Verify the registered application interface."
+#define TXT_VALUE_TYPE_MUST_HAVE_SIZE                    "A value type must be registered with a non-zero size"
+#define TXT_TYPE_s_IS_MISSING_BEHAVIOURS                 "Type '%s' is missing behaviours"
+#define TXT_ILLEGAL_BEHAVIOUR_FOR_TYPE                   "The behaviour is not compatible with the type"
+#define TXT_GC_REQUIRE_ADD_REL_GC_BEHAVIOUR              "A garbage collected type must have the addref, release, and all gc behaviours"
+#define TXT_SCOPE_REQUIRE_REL_BEHAVIOUR                  "A scoped reference type must have the release behaviour"
+#define TXT_REF_REQUIRE_ADD_REL_BEHAVIOUR                "A reference type must have the addref and release behaviours"
+#define TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR       "A non-pod value type must have the default constructor and destructor behaviours"
+#define TXT_CANNOT_PASS_TYPE_s_BY_VAL                    "Can't pass type '%s' by value unless the application type is informed in the registration"
+#define TXT_CANNOT_RET_TYPE_s_BY_VAL                     "Can't return type '%s' by value unless the application type is informed in the registration"
 // TODO: Should be something like "This platform requires that AngelScript knows the exact content of the type '%s' in order to pass by value to application in native calling convention"
-#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL                "Don't support passing type '%s' by value to application in native calling convention on this platform"
+#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL                   "Don't support passing type '%s' by value to application in native calling convention on this platform"
 // TODO: Should be something like "This platform requires that AngelScript knows the exact content of the type '%s' in order to return by value from application in native calling convention"
-#define TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL            "Don't support returning type '%s' by value from application in native calling convention on this platform"
-#define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s              "Object {%d}. GC cannot destroy an object of type '%s' as it doesn't know how many references to there are."
-#define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s_REF_COUNT_d  "Object {%d}. GC cannot destroy an object of type '%s' as it can't see all references. Current ref count is %d."
-#define TXT_OBJECT_TYPE_s_DOESNT_EXIST                "Object type '%s' doesn't exist"
-#define TXT_TEMPLATE_TYPE_s_DOESNT_EXIST              "Template type '%s' doesn't exist"
-#define TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST           "Template subtype '%s' doesn't exist"
-#define TXT_TEMPLATE_LIST_FACTORY_EXPECTS_2_REF_PARAMS "Template list factory expects two reference parameters. The last is the pointer to the initialization buffer"
-#define TXT_LIST_FACTORY_EXPECTS_1_REF_PARAM          "List factory expects only one reference parameter. The pointer to the initialization buffer will be passed in this parameter"
-#define TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s         "Failed to read subtype of template type '%s'"
-#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s            "Attempting to instanciate invalid template type '%s<%s>'"
-#define TXT_FAILED_IN_FUNC_s_d                        "Failed in call to function '%s' (Code: %d)"
-#define TXT_FAILED_IN_FUNC_s_WITH_s_d                 "Failed in call to function '%s' with '%s' (Code: %d)"
-#define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s_d           "Failed in call to function '%s' with '%s' and '%s' (Code: %d)"
-#define TXT_GC_RECEIVED_NULL_PTR                      "AddScriptObjectToGC called with null pointer"
-#define TXT_EXCEPTION_IN_NESTED_CALL                  "An exception occurred in a nested call"
-#define TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s            "Type '%s' is still used by function '%s'"
-#define TXT_PREV_TYPE_IS_NAMED_s                      "The builtin type in previous message is named '%s'"
-#define TXT_RESURRECTING_SCRIPTOBJECT_s               "The script object of type '%s' is being resurrected illegally during destruction"
+#define TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL               "Don't support returning type '%s' by value from application in native calling convention on this platform"
+#define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s               "Object {%d}. GC cannot destroy an object of type '%s' as it doesn't know how many references to there are."
+#define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s_REF_COUNT_d   "Object {%d}. GC cannot destroy an object of type '%s' as it can't see all references. Current ref count is %d."
+#define TXT_OBJECT_TYPE_s_DOESNT_EXIST                   "Object type '%s' doesn't exist"
+#define TXT_TEMPLATE_TYPE_s_DOESNT_EXIST                 "Template type '%s' doesn't exist"
+#define TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST              "Template subtype '%s' doesn't exist"
+#define TXT_TEMPLATE_LIST_FACTORY_EXPECTS_2_REF_PARAMS   "Template list factory expects two reference parameters. The last is the pointer to the initialization buffer"
+#define TXT_LIST_FACTORY_EXPECTS_1_REF_PARAM             "List factory expects only one reference parameter. The pointer to the initialization buffer will be passed in this parameter"
+#define TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s            "Failed to read subtype of template type '%s'"
+#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s               "Attempting to instanciate invalid template type '%s<%s>'"
+#define TXT_FAILED_IN_FUNC_s_d                           "Failed in call to function '%s' (Code: %d)"
+#define TXT_FAILED_IN_FUNC_s_WITH_s_d                    "Failed in call to function '%s' with '%s' (Code: %d)"
+#define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s_d              "Failed in call to function '%s' with '%s' and '%s' (Code: %d)"
+#define TXT_GC_RECEIVED_NULL_PTR                         "AddScriptObjectToGC called with null pointer"
+#define TXT_EXCEPTION_IN_NESTED_CALL                     "An exception occurred in a nested call"
+#define TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s               "Type '%s' is still used by function '%s'"
+#define TXT_PREV_TYPE_IS_NAMED_s                         "The builtin type in previous message is named '%s'"
+#define TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d               "The function in previous message is named '%s'. The func type is %d"
+#define TXT_RESURRECTING_SCRIPTOBJECT_s                  "The script object of type '%s' is being resurrected illegally during destruction"
+#define TXT_INVALID_BYTECODE_d                           "LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: %d"
 
 // Internal names
 
@@ -296,10 +300,12 @@
 #define TXT_NULL_POINTER_ACCESS           "Null pointer access"
 #define TXT_DIVIDE_BY_ZERO                "Divide by zero"
 #define TXT_DIVIDE_OVERFLOW               "Overflow in integer division"
+#define TXT_POW_OVERFLOW                  "Overflow in exponent operation"
 #define TXT_UNRECOGNIZED_BYTE_CODE        "Unrecognized byte code"
 #define TXT_INVALID_CALLING_CONVENTION    "Invalid calling convention"
 #define TXT_UNBOUND_FUNCTION              "Unbound function called"
 #define TXT_OUT_OF_BOUNDS                 "Out of range"
 #define TXT_EXCEPTION_CAUGHT              "Caught an exception from the application"
+#define TXT_MISMATCH_IN_VALUE_ASSIGN      "Mismatching types in value assignment"
 
 #endif

+ 65 - 33
Source/ThirdParty/AngelScript/source/as_thread.cpp

@@ -1,24 +1,24 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
+   This software is provided 'as-is', without any express or implied
+   warranty. In no event will the authors be held liable for any
    damages arising from the use of this software.
 
-   Permission is granted to anyone to use this software for any 
-   purpose, including commercial applications, and to alter it and 
+   Permission is granted to anyone to use this software for any
+   purpose, including commercial applications, and to alter it and
    redistribute it freely, subject to the following restrictions:
 
-   1. The origin of this software must not be misrepresented; you 
+   1. The origin of this software must not be misrepresented; you
       must not claim that you wrote the original software. If you use
-      this software in a product, an acknowledgment in the product 
+      this software in a product, an acknowledgment in the product
       documentation would be appreciated but is not required.
 
-   2. Altered source versions must be plainly marked as such, and 
+   2. Altered source versions must be plainly marked as such, and
       must not be misrepresented as being the original software.
 
-   3. This notice may not be removed or altered from any source 
+   3. This notice may not be removed or altered from any source
       distribution.
 
    The original version of this library can be located at:
@@ -109,6 +109,10 @@ AS_API void asReleaseSharedLock()
 
 //======================================================================
 
+#if !defined(AS_NO_THREADS) && defined(_MSC_VER) && defined(AS_WINDOWS_THREADS) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+__declspec(thread) asCThreadLocalData *asCThreadManager::tld = 0;
+#endif
+
 asCThreadManager::asCThreadManager()
 {
 	// We're already in the critical section when this function is called
@@ -122,7 +126,11 @@ asCThreadManager::asCThreadManager()
 		pthread_key_create(&pKey, 0);
 		tlsKey = (asDWORD)pKey;
 	#elif defined AS_WINDOWS_THREADS
-		tlsKey = (asDWORD)TlsAlloc();
+		#if defined(_MSC_VER) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+			tld = 0;
+		#else
+			tlsKey = (asDWORD)TlsAlloc();
+		#endif
 	#endif
 #endif
 	refCount = 1;
@@ -130,7 +138,7 @@ asCThreadManager::asCThreadManager()
 
 int asCThreadManager::Prepare(asIThreadManager *externalThreadMgr)
 {
-	// Don't allow an external thread manager if there 
+	// Don't allow an external thread manager if there
 	// is already a thread manager defined
 	if( externalThreadMgr && threadManager )
 		return asINVALID_ARG;
@@ -139,18 +147,18 @@ int asCThreadManager::Prepare(asIThreadManager *externalThreadMgr)
 	// guarantee for the order in which global variables are initialized
 	// or uninitialized.
 
-	// For this reason it's not possible to prevent two threads from calling 
+	// For this reason it's not possible to prevent two threads from calling
 	// AddRef at the same time, so there is a chance for a race condition here.
 
-	// To avoid the race condition when the thread manager is first created, 
+	// To avoid the race condition when the thread manager is first created,
 	// the application must make sure to call the global asPrepareForMultiThread()
-	// in the main thread before any other thread creates a script engine. 
+	// in the main thread before any other thread creates a script engine.
 	if( threadManager == 0 && externalThreadMgr == 0 )
 		threadManager = asNEW(asCThreadManager);
 	else
 	{
 		// If an application uses different dlls each dll will get it's own memory
-		// space for global variables. If multiple dlls then uses AngelScript's 
+		// space for global variables. If multiple dlls then uses AngelScript's
 		// global thread support functions it is then best to share the thread
 		// manager to make sure all dlls use the same critical section.
 		if( externalThreadMgr )
@@ -181,7 +189,7 @@ void asCThreadManager::Unprepare()
 		// Make sure the local data is destroyed, at least for the current thread
 		CleanupLocalData();
 
-		// As the critical section will be destroyed together 
+		// As the critical section will be destroyed together
 		// with the thread manager we must first clear the global
 		// variable in case a new thread manager needs to be created;
 		asCThreadManager *mgr = threadManager;
@@ -203,10 +211,14 @@ asCThreadManager::~asCThreadManager()
 	#if defined AS_POSIX_THREADS
 		pthread_key_delete((pthread_key_t)tlsKey);
 	#elif defined AS_WINDOWS_THREADS
-		TlsFree((DWORD)tlsKey);
+		#if defined(_MSC_VER) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+			tld = 0;
+		#else
+			TlsFree((DWORD)tlsKey);
+		#endif
 	#endif
 #else
-	if( tld ) 
+	if( tld )
 	{
 		asDELETE(tld,asCThreadLocalData);
 	}
@@ -223,23 +235,29 @@ int asCThreadManager::CleanupLocalData()
 #if defined AS_POSIX_THREADS
 	asCThreadLocalData *tld = (asCThreadLocalData*)pthread_getspecific((pthread_key_t)threadManager->tlsKey);
 #elif defined AS_WINDOWS_THREADS
-	asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey);
+	#if !defined(_MSC_VER) || (WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+		asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey);
+	#endif
 #endif
 
-	if( tld == 0 ) 
+	if( tld == 0 )
 		return 0;
 
-	if( tld->activeContexts.GetLength() == 0 ) 
+	if( tld->activeContexts.GetLength() == 0 )
 	{
 		asDELETE(tld,asCThreadLocalData);
 		#if defined AS_POSIX_THREADS
 			pthread_setspecific((pthread_key_t)threadManager->tlsKey, 0);
 		#elif defined AS_WINDOWS_THREADS
-			TlsSetValue((DWORD)threadManager->tlsKey, 0);
+			#if defined(_MSC_VER) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+				tld = 0;
+			#else
+				TlsSetValue((DWORD)threadManager->tlsKey, 0);
+			#endif
 		#endif
 		return 0;
 	}
-	else 
+	else
 		return asCONTEXT_ACTIVE;
 
 #else
@@ -271,12 +289,17 @@ asCThreadLocalData *asCThreadManager::GetLocalData()
 		pthread_setspecific((pthread_key_t)threadManager->tlsKey, tld);
 	}
 #elif defined AS_WINDOWS_THREADS
-	asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey);
-	if( tld == 0 ) 
-	{
- 		tld = asNEW(asCThreadLocalData)();
-		TlsSetValue((DWORD)threadManager->tlsKey, tld);
- 	}
+	#if defined(_MSC_VER) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+		if( tld == 0 )
+			tld = asNEW(asCThreadLocalData)();
+	#else
+		asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey);
+		if( tld == 0 )
+		{
+ 			tld = asNEW(asCThreadLocalData)();
+			TlsSetValue((DWORD)threadManager->tlsKey, tld);
+ 		}
+	#endif
 #endif
 
 	return tld;
@@ -306,7 +329,11 @@ asCThreadCriticalSection::asCThreadCriticalSection()
 #if defined AS_POSIX_THREADS
 	pthread_mutex_init(&cs, 0);
 #elif defined AS_WINDOWS_THREADS
-	InitializeCriticalSection(&cs);
+#ifdef _MSC_VER
+	InitializeCriticalSectionEx(&cs, 4000, 0);
+#else
+    InitializeCriticalSection(&cs);
+#endif
 #endif
 }
 
@@ -355,11 +382,16 @@ asCThreadReadWriteLock::asCThreadReadWriteLock()
 	asASSERT( r == 0 );
 	UNUSED_VAR(r);
 #elif defined AS_WINDOWS_THREADS
+#ifdef _MSC_VER
 	// Create a semaphore to allow up to maxReaders simultaneous readers
-	readLocks = CreateSemaphore(NULL, maxReaders, maxReaders, 0);
+	readLocks = CreateSemaphoreExW(NULL, maxReaders, maxReaders, 0, 0, 0);
 	// Create a critical section to synchronize writers
+	InitializeCriticalSectionEx(&writeLock, 4000, 0);
+#else
+	readLocks = CreateSemaphoreW(NULL, maxReaders, maxReaders, 0);
 	InitializeCriticalSection(&writeLock);
 #endif
+#endif
 }
 
 asCThreadReadWriteLock::~asCThreadReadWriteLock()
@@ -385,7 +417,7 @@ void asCThreadReadWriteLock::AcquireExclusive()
 	// If we try to lock all at once it is quite possible the writer will
 	// never succeed.
 	for( asUINT n = 0; n < maxReaders; n++ )
-		WaitForSingleObject(readLocks, INFINITE);
+		WaitForSingleObjectEx(readLocks, INFINITE, FALSE);
 
 	// Allow another writer to lock. It will only be able to
 	// lock the readers when this writer releases them anyway.
@@ -409,7 +441,7 @@ void asCThreadReadWriteLock::AcquireShared()
 	pthread_rwlock_rdlock(&lock);
 #elif defined AS_WINDOWS_THREADS
 	// Lock a reader slot
-	WaitForSingleObject(readLocks, INFINITE);
+	WaitForSingleObjectEx(readLocks, INFINITE, FALSE);
 #endif
 }
 

+ 18 - 9
Source/ThirdParty/AngelScript/source/as_thread.h

@@ -1,24 +1,24 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
+   This software is provided 'as-is', without any express or implied
+   warranty. In no event will the authors be held liable for any
    damages arising from the use of this software.
 
-   Permission is granted to anyone to use this software for any 
-   purpose, including commercial applications, and to alter it and 
+   Permission is granted to anyone to use this software for any
+   purpose, including commercial applications, and to alter it and
    redistribute it freely, subject to the following restrictions:
 
-   1. The origin of this software must not be misrepresented; you 
+   1. The origin of this software must not be misrepresented; you
       must not claim that you wrote the original software. If you use
-      this software in a product, an acknowledgment in the product 
+      this software in a product, an acknowledgment in the product
       documentation would be appreciated but is not required.
 
-   2. Altered source versions must be plainly marked as such, and 
+   2. Altered source versions must be plainly marked as such, and
       must not be misrepresented as being the original software.
 
-   3. This notice may not be removed or altered from any source 
+   3. This notice may not be removed or altered from any source
       distribution.
 
    The original version of this library can be located at:
@@ -70,7 +70,16 @@ protected:
 	int refCount;
 
 #ifndef AS_NO_THREADS
+#if defined(_MSC_VER) && defined(AS_WINDOWS_THREADS) && !(WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP)
+	// On Windows Store we must use MSVC specific thread variables for thread
+	// local storage, as the TLS API isn't available. On desktop we can't use
+	// this as it may cause problems if the library is used in a dll.
+	// ref: http://msdn.microsoft.com/en-us/library/2s9wt68x.aspx
+	// ref: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+	__declspec(thread) static asCThreadLocalData *tld;
+#else
 	asDWORD tlsKey;
+#endif
 	DECLARECRITICALSECTION(criticalSection);
 #else
 	asCThreadLocalData *tld;

+ 8 - 4
Source/ThirdParty/AngelScript/source/as_tokendef.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 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 
@@ -71,6 +71,7 @@ enum eTokenType
 	ttStar,                // *
 	ttSlash,               // /
 	ttPercent,             // %
+	ttStarStar,            // **
 
 	ttHandle,              // @
 
@@ -79,6 +80,7 @@ enum eTokenType
 	ttMulAssign,           // *=
 	ttDivAssign,           // /=
 	ttModAssign,           // %=
+	ttPowAssign,           // **=
 
 	ttOrAssign,            // |=
 	ttAndAssign,           // &=
@@ -149,9 +151,9 @@ enum eTokenType
 	ttFalse,               // false
 	ttReturn,              // return
 	ttNot,                 // not
-	ttAnd,                 // and
-	ttOr,                  // or
-	ttXor,                 // xor
+	ttAnd,                 // and, &&
+	ttOr,                  // or, ||
+	ttXor,                 // xor, ^^
 	ttBreak,               // break
 	ttContinue,            // continue
 	ttConst,               // const
@@ -196,6 +198,8 @@ sTokenWord const tokenWords[] =
 	asTokenDef("/="        , ttDivAssign),
 	asTokenDef("%"         , ttPercent),
 	asTokenDef("%="        , ttModAssign),
+	asTokenDef("**"        , ttStarStar),
+	asTokenDef("**="       , ttPowAssign),
 	asTokenDef("="         , ttAssignment),
 	asTokenDef("=="        , ttEqual),
 	asTokenDef("."         , ttDot),