Browse Source

Update AngelScript library (#2756)

1vanK 5 năm trước cách đây
mục cha
commit
03882e8943
33 tập tin đã thay đổi với 2277 bổ sung776 xóa
  1. 1 1
      Docs/Urho3D.dox
  2. 1 1
      README.md
  3. 3 0
      Source/ThirdParty/AngelScript/Urho3DNotes.txt
  4. 20 8
      Source/ThirdParty/AngelScript/include/angelscript.h
  5. 350 110
      Source/ThirdParty/AngelScript/source/as_builder.cpp
  6. 4 3
      Source/ThirdParty/AngelScript/source/as_builder.h
  7. 29 16
      Source/ThirdParty/AngelScript/source/as_callfunc.cpp
  8. 2 4
      Source/ThirdParty/AngelScript/source/as_callfunc.h
  9. 329 0
      Source/ThirdParty/AngelScript/source/as_callfunc_arm64.cpp
  10. 219 0
      Source/ThirdParty/AngelScript/source/as_callfunc_arm64_gcc.S
  11. 205 0
      Source/ThirdParty/AngelScript/source/as_callfunc_arm64_msvc.asm
  12. 3 3
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  13. 1 1
      Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  14. 244 126
      Source/ThirdParty/AngelScript/source/as_compiler.cpp
  15. 8 4
      Source/ThirdParty/AngelScript/source/as_compiler.h
  16. 75 41
      Source/ThirdParty/AngelScript/source/as_config.h
  17. 1 2
      Source/ThirdParty/AngelScript/source/as_configgroup.cpp
  18. 21 2
      Source/ThirdParty/AngelScript/source/as_context.cpp
  19. 14 2
      Source/ThirdParty/AngelScript/source/as_memory.cpp
  20. 249 203
      Source/ThirdParty/AngelScript/source/as_module.cpp
  21. 39 24
      Source/ThirdParty/AngelScript/source/as_module.h
  22. 50 29
      Source/ThirdParty/AngelScript/source/as_parser.cpp
  23. 202 116
      Source/ThirdParty/AngelScript/source/as_restore.cpp
  24. 142 39
      Source/ThirdParty/AngelScript/source/as_scriptengine.cpp
  25. 3 1
      Source/ThirdParty/AngelScript/source/as_scriptengine.h
  26. 8 4
      Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp
  27. 5 2
      Source/ThirdParty/AngelScript/source/as_scriptfunction.h
  28. 36 27
      Source/ThirdParty/AngelScript/source/as_scriptobject.cpp
  29. 4 3
      Source/ThirdParty/AngelScript/source/as_scriptobject.h
  30. 3 1
      Source/ThirdParty/AngelScript/source/as_texts.h
  31. 2 1
      Source/ThirdParty/AngelScript/source/as_tokendef.h
  32. 3 2
      Source/ThirdParty/AngelScript/source/as_typeinfo.cpp
  33. 1 0
      Source/Urho3D/AngelScript/Script.cpp

+ 1 - 1
Docs/Urho3D.dox

@@ -76,7 +76,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
 
 
-- AngelScript 2.33.0+ (http://www.angelcode.com/angelscript)
+- AngelScript 2.35.1 WIP (http://www.angelcode.com/angelscript)
 - Boost 1.64.0 (http://www.boost.org) - only used for AngelScript generic bindings
 - Boost 1.64.0 (http://www.boost.org) - only used for AngelScript generic bindings
 - Box2D 2.3.2 WIP (http://box2d.org)
 - Box2D 2.3.2 WIP (http://box2d.org)
 - Bullet 3.06+ (http://www.bulletphysics.org)
 - Bullet 3.06+ (http://www.bulletphysics.org)

+ 1 - 1
README.md

@@ -40,7 +40,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org) and Horde3D
   http://warp.povusers.org/SortComparison/
   http://warp.povusers.org/SortComparison/
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
-- AngelScript 2.33.0+ (http://www.angelcode.com/angelscript)
+- AngelScript 2.35.1 WIP (http://www.angelcode.com/angelscript)
 - Boost 1.64.0 (http://www.boost.org) - only used for AngelScript generic bindings
 - Boost 1.64.0 (http://www.boost.org) - only used for AngelScript generic bindings
 - Box2D 2.3.2 WIP (http://box2d.org)
 - Box2D 2.3.2 WIP (http://box2d.org)
 - Bullet 3.06+ (http://www.bulletphysics.org)
 - Bullet 3.06+ (http://www.bulletphysics.org)

+ 3 - 0
Source/ThirdParty/AngelScript/Urho3DNotes.txt

@@ -0,0 +1,3 @@
+URL: https://github.com/codecat/angelscript-mirror
+Date: 10.01.2021
+Latest commit: https://github.com/codecat/angelscript-mirror/commit/19b93c08ee75fbff808eba3349987277e5cbef1b

+ 20 - 8
Source/ThirdParty/AngelScript/include/angelscript.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -28,7 +28,7 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni, Nathanial Lydick, Yao Wei Tjong and Ramil Sattarov for Urho3D
+// Modified for Urho3D
 
 
 //
 //
 // angelscript.h
 // angelscript.h
@@ -64,8 +64,8 @@ BEGIN_AS_NAMESPACE
 
 
 // AngelScript version
 // AngelScript version
 
 
-#define ANGELSCRIPT_VERSION        23300
-#define ANGELSCRIPT_VERSION_STRING "2.33.0"
+#define ANGELSCRIPT_VERSION        23500
+#define ANGELSCRIPT_VERSION_STRING "2.35.0"
 
 
 // Data types
 // Data types
 
 
@@ -201,6 +201,7 @@ enum asEObjTypeFlags
 	asOBJ_APP_CLASS_A                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT),
 	asOBJ_APP_CLASS_A                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT),
 	asOBJ_APP_CLASS_AK               = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_CLASS_AK               = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_CLASS_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_CLASS_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
+	asOBJ_APP_CLASS_MORE_CONSTRUCTORS = (1<<31),
 	asOBJ_APP_PRIMITIVE              = (1<<13),
 	asOBJ_APP_PRIMITIVE              = (1<<13),
 	asOBJ_APP_FLOAT                  = (1<<14),
 	asOBJ_APP_FLOAT                  = (1<<14),
 	asOBJ_APP_ARRAY                  = (1<<15),
 	asOBJ_APP_ARRAY                  = (1<<15),
@@ -209,7 +210,7 @@ enum asEObjTypeFlags
 	asOBJ_NOCOUNT                    = (1<<18),
 	asOBJ_NOCOUNT                    = (1<<18),
 	asOBJ_APP_CLASS_ALIGN8           = (1<<19),
 	asOBJ_APP_CLASS_ALIGN8           = (1<<19),
 	asOBJ_IMPLICIT_HANDLE            = (1<<20),
 	asOBJ_IMPLICIT_HANDLE            = (1<<20),
-	asOBJ_MASK_VALID_FLAGS           = 0x1FFFFF,
+	asOBJ_MASK_VALID_FLAGS           = 0x801FFFFF,
 	// Internal flags
 	// Internal flags
 	asOBJ_SCRIPT_OBJECT              = (1<<21),
 	asOBJ_SCRIPT_OBJECT              = (1<<21),
 	asOBJ_SHARED                     = (1<<22),
 	asOBJ_SHARED                     = (1<<22),
@@ -391,7 +392,7 @@ typedef unsigned int   asUINT;
 #endif
 #endif
 
 
 // Is the target a 64bit system?
 // Is the target a 64bit system?
-#if defined(__LP64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)
+#if defined(__LP64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64)
 	#ifndef AS_64BIT_PTR
 	#ifndef AS_64BIT_PTR
 		#define AS_64BIT_PTR
 		#define AS_64BIT_PTR
 	#endif
 	#endif
@@ -593,15 +594,25 @@ BEGIN_AS_NAMESPACE
 template<typename T>
 template<typename T>
 asUINT asGetTypeTraits()
 asUINT asGetTypeTraits()
 {
 {
-// Urho3D - Clang compiler built with old GCC's libstdc++ suffers the same pre-standard templates problem as old GCC compiler
+// Urho3D: commented out original
+//#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5) || defined(__clang__)
+
+// Urho3D: Clang compiler built with old GCC's libstdc++ suffers the same pre-standard templates problem as old GCC compiler
 #if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5) || (defined(__clang__) && !defined(CLANG_PRE_STANDARD))
 #if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5) || (defined(__clang__) && !defined(CLANG_PRE_STANDARD))
+
 	// MSVC, XCode/Clang, and gnuc 5+
 	// MSVC, XCode/Clang, and gnuc 5+
 	// C++11 compliant code
 	// C++11 compliant code
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
 	bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::is_trivially_copy_assignable<T>::value;
 	bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::is_trivially_copy_assignable<T>::value;
 	bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::is_trivially_copy_constructible<T>::value;
 	bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::is_trivially_copy_constructible<T>::value;
+
+// Urho3D: commented out original
+//#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+
+// Urho3D
 #elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
 #elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
+
 	// gnuc 4.8 is using a mix of C++11 standard and pre-standard templates
 	// gnuc 4.8 is using a mix of C++11 standard and pre-standard templates
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
 	bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
 	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
@@ -1022,7 +1033,7 @@ public:
 
 
 	// Miscellaneous
 	// Miscellaneous
 	virtual asIScriptEngine *GetEngine() const = 0;
 	virtual asIScriptEngine *GetEngine() const = 0;
-	virtual int              CopyFrom(asIScriptObject *other) = 0;
+	virtual int              CopyFrom(const asIScriptObject *other) = 0;
 
 
 	// User data
 	// User data
 	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
 	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
@@ -1137,6 +1148,7 @@ public:
 	virtual bool             IsOverride() const = 0;
 	virtual bool             IsOverride() const = 0;
 	virtual bool             IsShared() const = 0;
 	virtual bool             IsShared() const = 0;
 	virtual bool             IsExplicit() const = 0;
 	virtual bool             IsExplicit() const = 0;
+	virtual bool             IsProperty() const = 0;
 	virtual asUINT           GetParamCount() const = 0;
 	virtual asUINT           GetParamCount() const = 0;
 	virtual int              GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const = 0;
 	virtual int              GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const = 0;
 	virtual int              GetReturnTypeId(asDWORD *flags = 0) const = 0;
 	virtual int              GetReturnTypeId(asDWORD *flags = 0) const = 0;

+ 350 - 110
Source/ThirdParty/AngelScript/source/as_builder.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -28,7 +28,7 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
+// Modified for Urho3D
 
 
 //
 //
 // as_builder.cpp
 // as_builder.cpp
@@ -228,7 +228,7 @@ int asCBuilder::AddCode(const char *name, const char *code, int codeLength, int
 	return 0;
 	return 0;
 }
 }
 
 
-asCScriptCode *asCBuilder::FindOrAddCode(const char *name, const char *code, asUINT length)
+asCScriptCode *asCBuilder::FindOrAddCode(const char *name, const char *code, size_t length)
 {
 {
 	for (asUINT n = 0; n < scripts.GetLength(); n++)
 	for (asUINT n = 0; n < scripts.GetLength(); n++)
 		if( scripts[n]->name == name && scripts[n]->codeLength == length && memcmp(scripts[n]->code, code, length) == 0 )
 		if( scripts[n]->name == name && scripts[n]->codeLength == length && memcmp(scripts[n]->code, code, length) == 0 )
@@ -238,7 +238,7 @@ asCScriptCode *asCBuilder::FindOrAddCode(const char *name, const char *code, asU
 	if (script == 0)
 	if (script == 0)
 		return 0;
 		return 0;
 
 
-	int r = script->SetCode(name, code, 0, true);
+	int r = script->SetCode(name, code, length, true);
 	if (r < 0)
 	if (r < 0)
 	{
 	{
 		asDELETE(script, asCScriptCode);
 		asDELETE(script, asCScriptCode);
@@ -387,7 +387,7 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
 
 
 	node = node->firstChild;
 	node = node->firstChild;
 	node->DisconnectParent();
 	node->DisconnectParent();
-	RegisterGlobalVar(node, script, module->defaultNamespace);
+	RegisterGlobalVar(node, script, module->m_defaultNamespace);
 
 
 	CompileGlobalVariables();
 	CompileGlobalVariables();
 
 
@@ -411,10 +411,10 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
 		for( asUINT n = 0; n < functions.GetLength(); n++ )
 		for( asUINT n = 0; n < functions.GetLength(); n++ )
 		{
 		{
 			asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
 			asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
-			if( module->globalFunctions.GetIndex(func) >= 0 )
+			if( module->m_globalFunctions.GetIndex(func) >= 0 )
 			{
 			{
-				module->globalFunctions.Erase(module->globalFunctions.GetIndex(func));
-				module->scriptFunctions.RemoveValue(func);
+				module->m_globalFunctions.Erase(module->m_globalFunctions.GetIndex(func));
+				module->m_scriptFunctions.RemoveValue(func);
 				func->ReleaseInternal();
 				func->ReleaseInternal();
 			}
 			}
 		}
 		}
@@ -553,13 +553,13 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	if( func == 0 )
 	if( func == 0 )
 		return asOUT_OF_MEMORY;
 		return asOUT_OF_MEMORY;
 
 
-	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, funcTraits, module->defaultNamespace);
+	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, funcTraits, module->m_defaultNamespace);
 	func->id                           = engine->GetNextScriptFunctionId();
 	func->id                           = engine->GetNextScriptFunctionId();
 	func->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
 	func->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
 	int row, col;
 	int row, col;
 	scripts[0]->ConvertPosToRowCol(node->tokenPos, &row, &col);
 	scripts[0]->ConvertPosToRowCol(node->tokenPos, &row, &col);
 	func->scriptData->declaredAt       = (row & 0xFFFFF)|((col & 0xFFF)<<20);
 	func->scriptData->declaredAt       = (row & 0xFFFFF)|((col & 0xFFF)<<20);
-	func->nameSpace                    = module->defaultNamespace;
+	func->nameSpace                    = module->m_defaultNamespace;
 
 
 	// Make sure the default args are declared correctly
 	// Make sure the default args are declared correctly
 	int r = ValidateDefaultArgs(script, node, func);
 	int r = ValidateDefaultArgs(script, node, func);
@@ -572,14 +572,14 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	// Tell the engine that the function exists already so the compiler can access it
 	// Tell the engine that the function exists already so the compiler can access it
 	if( compileFlags & asCOMP_ADD_TO_MODULE )
 	if( compileFlags & asCOMP_ADD_TO_MODULE )
 	{
 	{
-		r = CheckNameConflict(func->name.AddressOf(), node, scripts[0], module->defaultNamespace, false);
+		r = CheckNameConflict(func->name.AddressOf(), node, scripts[0], module->m_defaultNamespace, false, false);
 		if( r < 0 )
 		if( r < 0 )
 		{
 		{
 			func->ReleaseInternal();
 			func->ReleaseInternal();
 			return asERROR;
 			return asERROR;
 		}
 		}
 
 
-		module->globalFunctions.Put(func);
+		module->m_globalFunctions.Put(func);
 
 
 		module->AddScriptFunction(func);
 		module->AddScriptFunction(func);
 	}
 	}
@@ -623,10 +623,10 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 		for( asUINT n = 0; n < functions.GetLength(); n++ )
 		for( asUINT n = 0; n < functions.GetLength(); n++ )
 		{
 		{
 			asCScriptFunction *f = engine->scriptFunctions[functions[n]->funcId];
 			asCScriptFunction *f = engine->scriptFunctions[functions[n]->funcId];
-			if( module->globalFunctions.GetIndex(f) >= 0 )
+			if( module->m_globalFunctions.GetIndex(f) >= 0 )
 			{
 			{
-				module->globalFunctions.Erase(module->globalFunctions.GetIndex(f));
-				module->scriptFunctions.RemoveValue(f);
+				module->m_globalFunctions.Erase(module->m_globalFunctions.GetIndex(f));
+				module->m_scriptFunctions.RemoveValue(f);
 				f->ReleaseInternal();
 				f->ReleaseInternal();
 			}
 			}
 		}
 		}
@@ -1071,12 +1071,12 @@ int asCBuilder::VerifyProperty(asCDataType *dt, const char *decl, asCString &nam
 	// Verify property name
 	// Verify property name
 	if( dt )
 	if( dt )
 	{
 	{
-		if( CheckNameConflictMember(dt->GetTypeInfo(), name.AddressOf(), nameNode, &source, true) < 0 )
+		if( CheckNameConflictMember(dt->GetTypeInfo(), name.AddressOf(), nameNode, &source, true, false) < 0 )
 			return asNAME_TAKEN;
 			return asNAME_TAKEN;
 	}
 	}
 	else
 	else
 	{
 	{
-		if( CheckNameConflict(name.AddressOf(), nameNode, &source, ns, true) < 0 )
+		if( CheckNameConflict(name.AddressOf(), nameNode, &source, ns, true, false) < 0 )
 			return asNAME_TAKEN;
 			return asNAME_TAKEN;
 	}
 	}
 
 
@@ -1097,7 +1097,7 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
 	{
 	{
 		if( props[n]->name == prop )
 		if( props[n]->name == prop )
 		{
 		{
-			if( module->accessMask & props[n]->accessMask )
+			if( module->m_accessMask & props[n]->accessMask )
 				return props[n];
 				return props[n];
 			else
 			else
 				return 0;
 				return 0;
@@ -1138,7 +1138,7 @@ bool asCBuilder::DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asC
 	// Check previously compiled global variables
 	// Check previously compiled global variables
 	if( module )
 	if( module )
 	{
 	{
-		globProp = module->scriptGlobals.GetFirst(ns, prop);
+		globProp = module->m_scriptGlobals.GetFirst(ns, prop);
 		if( globProp )
 		if( globProp )
 		{
 		{
 			if( outProp ) *outProp = globProp;
 			if( outProp ) *outProp = globProp;
@@ -1173,7 +1173,7 @@ asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace
 		if( isAppProp )
 		if( isAppProp )
 		{
 		{
 			// Don't return the property if the module doesn't have access to it
 			// Don't return the property if the module doesn't have access to it
-			if( !(module->accessMask & globProp->accessMask) )
+			if( !(module->m_accessMask & globProp->accessMask) )
 				globProp = 0;
 				globProp = 0;
 		}
 		}
 		return globProp;
 		return globProp;
@@ -1337,6 +1337,10 @@ int asCBuilder::ParseFunctionDeclaration(asCObjectType *objType, const char *dec
 	{
 	{
 		if (source.TokenEquals(n->tokenPos, n->tokenLength, EXPLICIT_TOKEN))
 		if (source.TokenEquals(n->tokenPos, n->tokenLength, EXPLICIT_TOKEN))
 			func->SetExplicit(true);
 			func->SetExplicit(true);
+		else if( source.TokenEquals(n->tokenPos, n->tokenLength, PROPERTY_TOKEN))
+			func->SetProperty(true);
+		else
+			return asINVALID_DECLARATION;
 
 
 		n = n->next;
 		n = n->next;
 	}
 	}
@@ -1402,7 +1406,7 @@ int asCBuilder::ParseVariableDeclaration(const char *decl, asSNameSpace *implici
 }
 }
 
 
 // TODO: This should use SymbolLookupMember, which should be available in the TypeInfo class
 // TODO: This should use SymbolLookupMember, which should be available in the TypeInfo class
-int asCBuilder::CheckNameConflictMember(asCTypeInfo *t, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty)
+int asCBuilder::CheckNameConflictMember(asCTypeInfo *t, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty, bool isVirtualProperty)
 {
 {
 	// It's not necessary to check against object types
 	// It's not necessary to check against object types
 
 
@@ -1410,23 +1414,52 @@ int asCBuilder::CheckNameConflictMember(asCTypeInfo *t, const char *name, asCScr
 	if (!ot)
 	if (!ot)
 		return 0;
 		return 0;
 
 
+	// Check against properties
 	// TODO: optimize: Improve linear search
 	// TODO: optimize: Improve linear search
-	asCArray<asCObjectProperty *> &props = ot->properties;
-	for( asUINT n = 0; n < props.GetLength(); n++ )
+	// Properties are allowed to have the same name as virtual properties
+	if( !isVirtualProperty )
 	{
 	{
-		if( props[n]->name == name )
+		asCArray<asCObjectProperty *> &props = ot->properties;
+		for( asUINT n = 0; n < props.GetLength(); n++ )
 		{
 		{
-			if( code )
+			if( props[n]->name == name )
 			{
 			{
-				asCString str;
-				str.Format(TXT_NAME_CONFLICT_s_OBJ_PROPERTY, name);
-				WriteError(str, code, node);
+				if( code )
+				{
+					asCString str;
+					str.Format(TXT_NAME_CONFLICT_s_OBJ_PROPERTY, name);
+					WriteError(str, code, node);
+				}
+
+				return -1;
 			}
 			}
+		}
+	}
 
 
-			return -1;
+	// Check against virtual properties
+	// Don't do this when the check is for a virtual property, as it is allowed to have multiple overloads for virtual properties
+	// Properties are allowed to have the same name as virtual properties
+	if( !isProperty && !isVirtualProperty )
+	{
+		asCArray<int> methods = ot->methods;
+		for( asUINT n = 0; n < methods.GetLength(); n++ )
+		{
+			asCScriptFunction *func = engine->scriptFunctions[methods[n]];
+			if( func->IsProperty() && func->name.SubString(4) == name )
+			{
+				if( code )
+				{
+					asCString str;
+					str.Format(TXT_NAME_CONFLICT_s_OBJ_PROPERTY, name);
+					WriteError(str, code, node);
+				}
+
+				return -1;
+			}
 		}
 		}
 	}
 	}
 
 
+	// Check against child types
 	asCArray<asCFuncdefType*> &funcdefs = ot->childFuncDefs;
 	asCArray<asCFuncdefType*> &funcdefs = ot->childFuncDefs;
 	for (asUINT n = 0; n < funcdefs.GetLength(); n++)
 	for (asUINT n = 0; n < funcdefs.GetLength(); n++)
 	{
 	{
@@ -1474,14 +1507,14 @@ int asCBuilder::CheckNameConflictMember(asCTypeInfo *t, const char *name, asCScr
 	if (ns)
 	if (ns)
 	{
 	{
 		// Check as if not a function as it doesn't matter the function signature
 		// Check as if not a function as it doesn't matter the function signature
-		return CheckNameConflict(name, node, code, ns, true);
+		return CheckNameConflict(name, node, code, ns, true, isVirtualProperty);
 	}
 	}
 	
 	
 	return 0;
 	return 0;
 }
 }
 
 
 // TODO: This should use SymbolLookup
 // TODO: This should use SymbolLookup
-int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isProperty)
+int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isProperty, bool isVirtualProperty)
 {
 {
 	// Check against registered object types
 	// Check against registered object types
 	if( engine->GetRegisteredType(name, ns) != 0 )
 	if( engine->GetRegisteredType(name, ns) != 0 )
@@ -1501,7 +1534,8 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 	}
 	}
 
 
 	// Check against global properties
 	// Check against global properties
-	if( DoesGlobalPropertyExist(name, ns) )
+	// Virtual properties are allowed to have the same name as a real property
+	if( !isVirtualProperty && DoesGlobalPropertyExist(name, ns) )
 	{
 	{
 		if( code )
 		if( code )
 		{
 		{
@@ -1516,6 +1550,33 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 
 
 		return -1;
 		return -1;
 	}
 	}
+	
+	// Check against registered global virtual properties
+	// Don't do this when the check is for a virtual property, as it is allowed to have multiple overloads for virtual properties
+	if( !isProperty || !isVirtualProperty )
+	{
+		for (asUINT n = 0; n < engine->registeredGlobalFuncs.GetSize(); n++)
+		{
+			asCScriptFunction *func = engine->registeredGlobalFuncs.Get(n);
+			if (func->IsProperty() &&
+				func->nameSpace == ns &&
+				func->name.SubString(4) == name)
+			{
+				if (code)
+				{
+					asCString str;
+					if (ns->name != "")
+						str = ns->name + "::" + name;
+					else
+						str = name;
+					str.Format(TXT_NAME_CONFLICT_s_IS_VIRTPROP, str.AddressOf());
+					WriteError(str, code, node);
+				}
+
+				return -1;
+			}
+		}
+	}
 
 
 	// Property names must be checked against function names
 	// Property names must be checked against function names
 	if (isProperty)
 	if (isProperty)
@@ -1589,7 +1650,7 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 	for( n = 0; n < funcDefs.GetLength(); n++ )
 	for( n = 0; n < funcDefs.GetLength(); n++ )
 	{
 	{
 		if( funcDefs[n]->name == name &&
 		if( funcDefs[n]->name == name &&
-			module->funcDefs[funcDefs[n]->idx]->nameSpace == ns )
+			module->m_funcDefs[funcDefs[n]->idx]->nameSpace == ns )
 		{
 		{
 			if( code )
 			if( code )
 			{
 			{
@@ -1623,6 +1684,35 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 		return -1;
 		return -1;
 	}
 	}
 
 
+	// Check against virtual properties
+	// Don't do this when the check is for a virtual property, as it is allowed to have multiple overloads for virtual properties
+	if( !isProperty && !isVirtualProperty )
+	{
+		for (n = 0; n < functions.GetLength(); n++)
+		{
+			asCScriptFunction *func = engine->scriptFunctions[functions[n] ? functions[n]->funcId : 0];
+			if (func && 
+				func->IsProperty() &&
+				func->objectType == 0 && 
+				func->nameSpace == ns &&
+				func->name.SubString(4) == name)
+			{
+				if (code)
+				{
+					asCString str;
+					if (ns->name != "")
+						str = ns->name + "::" + name;
+					else
+						str = name;
+					str.Format(TXT_NAME_CONFLICT_s_IS_VIRTPROP, str.AddressOf());
+					WriteError(str, code, node);
+				}
+
+				return -1;
+			}
+		}
+	}
+	
 	// Property names must be checked against function names
 	// Property names must be checked against function names
 	if (isProperty)
 	if (isProperty)
 	{
 	{
@@ -1653,6 +1743,102 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 	return 0;
 	return 0;
 }
 }
 
 
+// Returns a negative value on invalid property
+// -2 incorrect prefix
+// -3 invalid signature
+// -4 mismatching type for get/set
+// -5 name conflict
+int asCBuilder::ValidateVirtualProperty(asCScriptFunction *func)
+{
+	asASSERT( func->IsProperty() );
+	
+	// A virtual property must have the prefix "get_" or "set_"
+	asCString prefix = func->name.SubString(0, 4);
+	if( prefix != "get_" && prefix != "set_" )
+		return -2;
+	
+	// A getter must return a non-void type and have at most 1 argument (indexed property)
+	if( prefix == "get_" && (func->returnType == asCDataType::CreatePrimitive(ttVoid, false) || func->parameterTypes.GetLength() > 1) )
+		return -3;
+	
+	// A setter must return a void and have 1 or 2 arguments (indexed property)
+	if( prefix == "set_" && (func->returnType != asCDataType::CreatePrimitive(ttVoid, false) || func->parameterTypes.GetLength() < 1 || func->parameterTypes.GetLength() > 2) )
+		return -3;
+	
+	// Check matching getter/setter
+	asCDataType getType, setType;
+	bool found = false;
+	if( prefix == "get_" )
+	{
+		getType = func->returnType;
+		
+		// Find if there is a set accessor in the same scope, and then validate the type of it
+		// TODO: optimize search
+		asCString setName = "set_" + func->name.SubString(4);
+		for( asUINT n = 0; n < engine->scriptFunctions.GetLength(); n++ )
+		{
+			asCScriptFunction *setFunc = engine->scriptFunctions[n];
+			if( setFunc == 0 || setFunc->name != setName || !setFunc->IsProperty() )
+				continue;
+			
+			// Is it the same scope?
+			if( func->module != setFunc->module || func->nameSpace != setFunc->nameSpace || func->objectType != setFunc->objectType )
+				continue;
+			
+			setType = setFunc->parameterTypes[setFunc->parameterTypes.GetLength() - 1];
+			found = true;
+			break;
+		}
+	}
+	else
+	{
+		setType = func->parameterTypes[func->parameterTypes.GetLength() - 1];
+		
+		// Find if there is a get accessor in the same scope and then validate the type of it
+		// TODO: optimize search
+		asCString getName = "get_" + func->name.SubString(4);
+		for( asUINT n = 0; n < engine->scriptFunctions.GetLength(); n++ )
+		{
+			asCScriptFunction *getFunc = engine->scriptFunctions[n];
+			if( getFunc == 0 || getFunc->name != getName || !getFunc->IsProperty() )
+				continue;
+			
+			// Is it the same scope?
+			if( func->module != getFunc->module || func->nameSpace != getFunc->nameSpace || func->objectType != getFunc->objectType )
+				continue;
+			
+			getType = getFunc->returnType;
+			found = true;
+			break;
+		}
+	}
+	
+	if( found )
+	{
+		// Check that the type matches
+		// It is permitted for a getter to return a handle and the setter to take a reference
+		if( !getType.IsEqualExceptRefAndConst(setType) &&
+			!((getType.IsObjectHandle() && !setType.IsObjectHandle()) &&
+			  (getType.GetTypeInfo() == setType.GetTypeInfo())) )
+		{
+			return -4;
+		}
+	}
+	
+	// Check name conflict with other entities in the same scope
+	// It is allowed to have a real property of the same name, in which case the virtual property hides the real one.
+	int r;
+	if( func->objectType )
+		r = CheckNameConflictMember(func->objectType, func->name.SubString(4).AddressOf(), 0, 0, true, true);
+	else
+		r = CheckNameConflict(func->name.SubString(4).AddressOf(), 0, 0, func->nameSpace, true, true);
+	if( r < 0 )
+		return -5;
+	
+	// Everything is OK
+	return 0;
+}
+
 #ifndef AS_NO_COMPILER
 #ifndef AS_NO_COMPILER
 sMixinClass *asCBuilder::GetMixinClass(const char *name, asSNameSpace *ns)
 sMixinClass *asCBuilder::GetMixinClass(const char *name, asSNameSpace *ns)
 {
 {
@@ -1684,7 +1870,7 @@ int asCBuilder::RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNam
 	// Check for name conflict with other types
 	// Check for name conflict with other types
 	if (ns)
 	if (ns)
 	{
 	{
-		int r = CheckNameConflict(name.AddressOf(), node, file, ns, true);
+		int r = CheckNameConflict(name.AddressOf(), node, file, ns, true, false);
 		if (asSUCCESS != r)
 		if (asSUCCESS != r)
 		{
 		{
 			node->Destroy(engine);
 			node->Destroy(engine);
@@ -1693,7 +1879,7 @@ int asCBuilder::RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNam
 	}
 	}
 	else
 	else
 	{
 	{
-		int r = CheckNameConflictMember(parent, name.AddressOf(), node, file, false);
+		int r = CheckNameConflictMember(parent, name.AddressOf(), node, file, false, false);
 		if (asSUCCESS != r)
 		if (asSUCCESS != r)
 		{
 		{
 			node->Destroy(engine);
 			node->Destroy(engine);
@@ -1730,7 +1916,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 	asCArray<asCString *>      defaultArgs;
 	asCArray<asCString *>      defaultArgs;
 	asSFunctionTraits          funcTraits;
 	asSFunctionTraits          funcTraits;
 
 
-	asCFuncdefType *fdt = module->funcDefs[funcDef->idx];
+	asCFuncdefType *fdt = module->m_funcDefs[funcDef->idx];
 	asASSERT( fdt );
 	asASSERT( fdt );
 	asCScriptFunction *func = fdt->funcdef;
 	asCScriptFunction *func = fdt->funcdef;
 
 
@@ -1787,7 +1973,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 			{
 			{
 				// Replace our funcdef for the existing one
 				// Replace our funcdef for the existing one
 				funcDef->idx = fdt2->funcdef->id;
 				funcDef->idx = fdt2->funcdef->id;
-				module->funcDefs[module->funcDefs.IndexOf(fdt)] = fdt2;
+				module->ReplaceFuncDef(fdt, fdt2);
 				fdt2->AddRefInternal();
 				fdt2->AddRefInternal();
 
 
 				engine->funcDefs.RemoveValue(fdt);
 				engine->funcDefs.RemoveValue(fdt);
@@ -1809,7 +1995,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 
 
 	// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
 	// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
 	if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && found)
 	if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && found)
-		module->externalTypes.PushLast(engine->scriptFunctions[funcDef->idx]->funcdefType);
+		module->m_externalTypes.PushLast(engine->scriptFunctions[funcDef->idx]->funcdefType);
 }
 }
 
 
 int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns)
 int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns)
@@ -1841,7 +2027,7 @@ int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSN
 	{
 	{
 		// Verify that the name isn't taken
 		// Verify that the name isn't taken
 		asCString name(&file->code[n->tokenPos], n->tokenLength);
 		asCString name(&file->code[n->tokenPos], n->tokenLength);
-		CheckNameConflict(name.AddressOf(), n, file, ns, true);
+		CheckNameConflict(name.AddressOf(), n, file, ns, true, false);
 
 
 		// Register the global variable
 		// Register the global variable
 		sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
 		sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
@@ -1918,7 +2104,7 @@ int asCBuilder::RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asS
 	int r, c;
 	int r, c;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
 
-	CheckNameConflict(name.AddressOf(), n, file, ns, true);
+	CheckNameConflict(name.AddressOf(), n, file, ns, true, false);
 
 
 	sMixinClass *decl = asNEW(sMixinClass);
 	sMixinClass *decl = asNEW(sMixinClass);
 	if( decl == 0 )
 	if( decl == 0 )
@@ -2028,7 +2214,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 	int r, c;
 	int r, c;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
 
-	CheckNameConflict(name.AddressOf(), n, file, ns, true);
+	CheckNameConflict(name.AddressOf(), n, file, ns, true, false);
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	if( decl == 0 )
 	if( decl == 0 )
@@ -2074,7 +2260,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 				// We'll use the existing type
 				// We'll use the existing type
 				decl->isExistingShared = true;
 				decl->isExistingShared = true;
 				decl->typeInfo         = st;
 				decl->typeInfo         = st;
-				module->classTypes.PushLast(st);
+				module->AddClassType(st);
 				st->AddRefInternal();
 				st->AddRefInternal();
 				break;
 				break;
 			}
 			}
@@ -2091,7 +2277,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 
 
 	// Remember if the class was declared as external so the saved bytecode can be flagged accordingly
 	// Remember if the class was declared as external so the saved bytecode can be flagged accordingly
 	if (isExternal)
 	if (isExternal)
-		module->externalTypes.PushLast(st);
+		module->m_externalTypes.PushLast(st);
 
 
 	if (!decl->isExistingShared)
 	if (!decl->isExistingShared)
 	{
 	{
@@ -2125,7 +2311,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 		st->name = name;
 		st->name = name;
 		st->nameSpace = ns;
 		st->nameSpace = ns;
 		st->module = module;
 		st->module = module;
-		module->classTypes.PushLast(st);
+		module->AddClassType(st);
 		if (isShared)
 		if (isShared)
 		{
 		{
 			engine->sharedScriptTypes.PushLast(st);
 			engine->sharedScriptTypes.PushLast(st);
@@ -2199,7 +2385,7 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
 
 
 	asCString name;
 	asCString name;
 	name.Assign(&file->code[n->tokenPos], n->tokenLength);
 	name.Assign(&file->code[n->tokenPos], n->tokenLength);
-	CheckNameConflict(name.AddressOf(), n, file, ns, true);
+	CheckNameConflict(name.AddressOf(), n, file, ns, true, false);
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	if( decl == 0 )
 	if( decl == 0 )
@@ -2244,12 +2430,12 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
 				// We'll use the existing type
 				// We'll use the existing type
 				decl->isExistingShared = true;
 				decl->isExistingShared = true;
 				decl->typeInfo = st;
 				decl->typeInfo = st;
-				module->classTypes.PushLast(st);
+				module->AddClassType(st);
 				st->AddRefInternal();
 				st->AddRefInternal();
 
 
 				// Remember if the interface was declared as external so the saved bytecode can be flagged accordingly
 				// Remember if the interface was declared as external so the saved bytecode can be flagged accordingly
 				if (isExternal)
 				if (isExternal)
-					module->externalTypes.PushLast(st);
+					module->m_externalTypes.PushLast(st);
 
 
 				return 0;
 				return 0;
 			}
 			}
@@ -2278,7 +2464,7 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
 	st->name = name;
 	st->name = name;
 	st->nameSpace = ns;
 	st->nameSpace = ns;
 	st->module = module;
 	st->module = module;
-	module->classTypes.PushLast(st);
+	module->AddClassType(st);
 	if( isShared )
 	if( isShared )
 	{
 	{
 		engine->sharedScriptTypes.PushLast(st);
 		engine->sharedScriptTypes.PushLast(st);
@@ -2566,8 +2752,8 @@ void asCBuilder::CompileGlobalVariables()
 		// If the length of the arrays are not the same, then this is the compilation
 		// If the length of the arrays are not the same, then this is the compilation
 		// of a single variable, in which case the initialization order of the previous
 		// of a single variable, in which case the initialization order of the previous
 		// variables must be preserved.
 		// variables must be preserved.
-		if( module->scriptGlobals.GetSize() == initOrder.GetSize() )
-			module->scriptGlobals.SwapWith(initOrder);
+		if( module->m_scriptGlobals.GetSize() == initOrder.GetSize() )
+			module->m_scriptGlobals.SwapWith(initOrder);
 	}
 	}
 
 
 	CleanupEnumValues();
 	CleanupEnumValues();
@@ -3310,7 +3496,7 @@ void asCBuilder::CompileClasses(asUINT numTempl)
 
 
 				if( !decl->isExistingShared )
 				if( !decl->isExistingShared )
 				{
 				{
-					CheckNameConflictMember(ot, name.AddressOf(), nd, file, true);
+					CheckNameConflictMember(ot, name.AddressOf(), nd, file, true, false);
 					AddPropertyToClass(decl, name, dt, isPrivate, isProtected, false, file, nd);
 					AddPropertyToClass(decl, name, dt, isPrivate, isProtected, false, file, nd);
 				}
 				}
 				else
 				else
@@ -3515,9 +3701,10 @@ void asCBuilder::CompileClasses(asUINT numTempl)
 	//                         allow incremental builds, i.e. allow application to add or replace classes in an
 	//                         allow incremental builds, i.e. allow application to add or replace classes in an
 	//                         existing module. However, the applications that want to use that should use a special
 	//                         existing module. However, the applications that want to use that should use a special
 	//                         build flag to not finalize the module.
 	//                         build flag to not finalize the module.
+    
+    // Urho3D: disable garbage collection from script classes
+    /*
 
 
-	// Urho3D: disable garbage collection from script classes
-	/*
 	asCArray<asCObjectType*> typesToValidate;
 	asCArray<asCObjectType*> typesToValidate;
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 	{
@@ -3703,7 +3890,9 @@ void asCBuilder::CompileClasses(asUINT numTempl)
 		// Reset the counter
 		// Reset the counter
 		numReevaluations = 0;
 		numReevaluations = 0;
 	}
 	}
-	*/
+    
+    // Urho3D: end
+    */
 }
 }
 
 
 void asCBuilder::IncludeMethodsFromMixins(sClassDeclaration *decl)
 void asCBuilder::IncludeMethodsFromMixins(sClassDeclaration *decl)
@@ -3879,7 +4068,7 @@ void asCBuilder::IncludePropertiesFromMixins(sClassDeclaration *decl)
 							if( !decl->isExistingShared )
 							if( !decl->isExistingShared )
 							{
 							{
 								// It must not conflict with the name of methods
 								// It must not conflict with the name of methods
-								int r = CheckNameConflictMember(ot, name.AddressOf(), n2, file, true);
+								int r = CheckNameConflictMember(ot, name.AddressOf(), n2, file, true, false);
 								if( r < 0 )
 								if( r < 0 )
 									WriteInfo(TXT_WHILE_INCLUDING_MIXIN, decl->script, node);
 									WriteInfo(TXT_WHILE_INCLUDING_MIXIN, decl->script, node);
 
 
@@ -4138,10 +4327,10 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
 
 
 	// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
 	// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
 	if (isExternal && existingSharedType)
 	if (isExternal && existingSharedType)
-		module->externalTypes.PushLast(existingSharedType);
+		module->m_externalTypes.PushLast(existingSharedType);
 
 
 	// Check the name and add the enum
 	// Check the name and add the enum
-	int r = CheckNameConflict(name.AddressOf(), tmp->firstChild, file, ns, true);
+	int r = CheckNameConflict(name.AddressOf(), tmp->firstChild, file, ns, true, false);
 	if( asSUCCESS == r )
 	if( asSUCCESS == r )
 	{
 	{
 		asCEnumType *st;
 		asCEnumType *st;
@@ -4165,7 +4354,7 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
 			st->nameSpace = ns;
 			st->nameSpace = ns;
 			st->module    = module;
 			st->module    = module;
 		}
 		}
-		module->enumTypes.PushLast(st);
+		module->AddEnumType(st);
 
 
 		if( !existingSharedType && isShared )
 		if( !existingSharedType && isShared )
 		{
 		{
@@ -4311,7 +4500,7 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNam
 	name.Assign(&file->code[tmp->tokenPos], tmp->tokenLength);
 	name.Assign(&file->code[tmp->tokenPos], tmp->tokenLength);
 
 
 	// If the name is not already in use add it
 	// If the name is not already in use add it
- 	int r = CheckNameConflict(name.AddressOf(), tmp, file, ns, true);
+ 	int r = CheckNameConflict(name.AddressOf(), tmp, file, ns, true, false);
 
 
 	asCTypedefType *st = 0;
 	asCTypedefType *st = 0;
 	if( asSUCCESS == r )
 	if( asSUCCESS == r )
@@ -4331,7 +4520,7 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNam
 		st->aliasForType    = dataType;
 		st->aliasForType    = dataType;
 		st->module          = module;
 		st->module          = module;
 
 
-		module->typeDefs.PushLast(st);
+		module->AddTypeDef(st);
 
 
 		// Store the location of this declaration for reference in name collisions
 		// Store the location of this declaration for reference in name collisions
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
@@ -4427,27 +4616,36 @@ void asCBuilder::GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *fi
 	funcTraits.SetTrait(asTRAIT_FINAL, false);
 	funcTraits.SetTrait(asTRAIT_FINAL, false);
 	funcTraits.SetTrait(asTRAIT_OVERRIDE, false);
 	funcTraits.SetTrait(asTRAIT_OVERRIDE, false);
 	funcTraits.SetTrait(asTRAIT_EXPLICIT, false);
 	funcTraits.SetTrait(asTRAIT_EXPLICIT, false);
+	funcTraits.SetTrait(asTRAIT_PROPERTY, false);
 
 
-	if( objType && n->next->next )
+	if( n->next->next )
 	{
 	{
 		asCScriptNode *decorator = n->next->next;
 		asCScriptNode *decorator = n->next->next;
 
 
 		// Is this a const method?
 		// Is this a const method?
-		if( decorator->tokenType == ttConst )
+		if( objType && decorator->tokenType == ttConst )
 		{
 		{
 			funcTraits.SetTrait(asTRAIT_CONST, true);
 			funcTraits.SetTrait(asTRAIT_CONST, true);
 			decorator = decorator->next;
 			decorator = decorator->next;
 		}
 		}
 
 
-		while( decorator )
+		while( decorator && decorator->tokenType == ttIdentifier )
 		{
 		{
-			if (decorator->tokenType == ttIdentifier && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, FINAL_TOKEN))
+			if (objType && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, FINAL_TOKEN))
 				funcTraits.SetTrait(asTRAIT_FINAL, true);
 				funcTraits.SetTrait(asTRAIT_FINAL, true);
-			else if (decorator->tokenType == ttIdentifier && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, OVERRIDE_TOKEN))
+			else if (objType && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, OVERRIDE_TOKEN))
 				funcTraits.SetTrait(asTRAIT_OVERRIDE, true);
 				funcTraits.SetTrait(asTRAIT_OVERRIDE, true);
-			else if (decorator->tokenType == ttIdentifier && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, EXPLICIT_TOKEN))
+			else if (objType && file->TokenEquals(decorator->tokenPos, decorator->tokenLength, EXPLICIT_TOKEN))
 				funcTraits.SetTrait(asTRAIT_EXPLICIT, true);
 				funcTraits.SetTrait(asTRAIT_EXPLICIT, true);
-
+			else if (file->TokenEquals(decorator->tokenPos, decorator->tokenLength, PROPERTY_TOKEN))
+				funcTraits.SetTrait(asTRAIT_PROPERTY, true);
+			else
+			{
+				asCString msg(&file->code[decorator->tokenPos], decorator->tokenLength);
+				msg.Format(TXT_UNEXPECTED_TOKEN_s, msg.AddressOf());
+				WriteError(msg.AddressOf(), file, decorator);
+			}			
+			
 			decorator = decorator->next;
 			decorator = decorator->next;
 		}
 		}
 	}
 	}
@@ -4662,13 +4860,13 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 	{
 	{
 		if( objType )
 		if( objType )
 		{
 		{
-			CheckNameConflictMember(objType, name.AddressOf(), node, file, false);
+			CheckNameConflictMember(objType, name.AddressOf(), node, file, false, false);
 
 
 			if( name == objType->name )
 			if( name == objType->name )
 				WriteError(TXT_METHOD_CANT_HAVE_NAME_OF_CLASS, file, node);
 				WriteError(TXT_METHOD_CANT_HAVE_NAME_OF_CLASS, file, node);
 		}
 		}
 		else
 		else
-			CheckNameConflict(name.AddressOf(), node, file, ns, false);
+			CheckNameConflict(name.AddressOf(), node, file, ns, false, false);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -4701,6 +4899,35 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 			name = "~" + name;
 			name = "~" + name;
 	}
 	}
 
 
+	// Validate virtual properties signature
+	if( funcTraits.GetTrait(asTRAIT_PROPERTY) )
+	{
+		asCScriptFunction func(engine, module, asFUNC_SCRIPT);
+		func.name           = name;
+		func.nameSpace      = ns;
+		func.objectType     = objType;
+		if( objType )
+			objType->AddRefInternal();
+		func.traits         = funcTraits;
+		func.returnType     = returnType;
+		func.parameterTypes = parameterTypes;
+		
+		int r = ValidateVirtualProperty(&func);
+		if( r < 0 )
+		{
+			asCString str;
+			if( r == -2 || r == -3 )
+				str.Format(TXT_INVALID_SIG_FOR_VIRTPROP);
+			else if( r == -4 )
+				str.Format(TXT_GET_SET_ACCESSOR_TYPE_MISMATCH_FOR_s, name.SubString(4).AddressOf());
+			else if( r == -5 )
+				str.Format(TXT_NAME_CONFLICT_s_ALREADY_USED, name.SubString(4).AddressOf());
+			WriteError(str, file, node);
+		}
+		
+		func.funcType = asFUNC_DUMMY;
+	}
+	
 	isExistingShared = false;
 	isExistingShared = false;
 	int funcId = engine->GetNextScriptFunctionId();
 	int funcId = engine->GetNextScriptFunctionId();
 	if( !isInterface )
 	if( !isInterface )
@@ -4748,7 +4975,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 
 
 		// Remember if the function was declared as external so the saved bytecode can be flagged accordingly
 		// Remember if the function was declared as external so the saved bytecode can be flagged accordingly
 		if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && func->isExistingShared)
 		if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && func->isExistingShared)
-			module->externalFunctions.PushLast(engine->scriptFunctions[func->funcId]);
+			module->m_externalFunctions.PushLast(engine->scriptFunctions[func->funcId]);
 
 
 		if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && !func->isExistingShared)
 		if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && !func->isExistingShared)
 		{
 		{
@@ -4879,7 +5106,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 		module->AddScriptFunction(f);
 		module->AddScriptFunction(f);
 
 
 		// TODO: clean up: This should be done by AddScriptFunction() itself
 		// TODO: clean up: This should be done by AddScriptFunction() itself
-		module->globalFunctions.Put(f);
+		module->m_globalFunctions.Put(f);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -4916,7 +5143,9 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 			else
 			else
 			{
 			{
 				// The copy constructor needs to be marked for easy finding
 				// The copy constructor needs to be marked for easy finding
-				if (parameterTypes.GetLength() == 1 && parameterTypes[0].GetTypeInfo() == objType)
+				if( parameterTypes.GetLength() == 1 && 
+				    parameterTypes[0].GetTypeInfo() == objType && 
+					(parameterTypes[0].IsReference() || parameterTypes[0].IsObjectHandle()) )
 				{
 				{
 					// Verify that there are not multiple options matching the copy constructor
 					// Verify that there are not multiple options matching the copy constructor
 					// TODO: Need a better message, since the parameters can be slightly different, e.g. & vs @
 					// TODO: Need a better message, since the parameters can be slightly different, e.g. & vs @
@@ -4982,7 +5211,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 
 
 int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared)
 int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared)
 {
 {
-	if( engine->ep.propertyAccessorMode != 2 )
+	if( engine->ep.propertyAccessorMode < 2 )
 	{
 	{
 		WriteError(TXT_PROPERTY_ACCESSOR_DISABLED, file, node);
 		WriteError(TXT_PROPERTY_ACCESSOR_DISABLED, file, node);
 		node->Destroy(engine);
 		node->Destroy(engine);
@@ -5041,9 +5270,7 @@ int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file
 
 
 		funcTraits.SetTrait(asTRAIT_PRIVATE, isPrivate);
 		funcTraits.SetTrait(asTRAIT_PRIVATE, isPrivate);
 		funcTraits.SetTrait(asTRAIT_PROTECTED, isProtected);
 		funcTraits.SetTrait(asTRAIT_PROTECTED, isProtected);
-
-		// TODO: getset: Allow private for individual property accessors
-		// TODO: getset: If the accessor uses its own name, then the property should be automatically declared
+		funcTraits.SetTrait(asTRAIT_PROPERTY, true);
 
 
 		if (node->firstChild->nodeType == snIdentifier && file->TokenEquals(node->firstChild->tokenPos, node->firstChild->tokenLength, GET_TOKEN))
 		if (node->firstChild->nodeType == snIdentifier && file->TokenEquals(node->firstChild->tokenPos, node->firstChild->tokenLength, GET_TOKEN))
 			name = "get_";
 			name = "get_";
@@ -5069,6 +5296,12 @@ int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file
 					funcTraits.SetTrait(asTRAIT_FINAL, true);
 					funcTraits.SetTrait(asTRAIT_FINAL, true);
 				else if (funcNode->tokenType == ttIdentifier && file->TokenEquals(funcNode->tokenPos, funcNode->tokenLength, OVERRIDE_TOKEN))
 				else if (funcNode->tokenType == ttIdentifier && file->TokenEquals(funcNode->tokenPos, funcNode->tokenLength, OVERRIDE_TOKEN))
 					funcTraits.SetTrait(asTRAIT_OVERRIDE, true);
 					funcTraits.SetTrait(asTRAIT_OVERRIDE, true);
+				else
+				{
+					asCString msg(&file->code[funcNode->tokenPos], funcNode->tokenLength);;
+					msg.Format(TXT_UNEXPECTED_TOKEN_s, msg.AddressOf());
+					WriteError(msg.AddressOf(), file, node);
+				}
 
 
 				funcNode = funcNode->next;
 				funcNode = funcNode->next;
 			}
 			}
@@ -5155,7 +5388,7 @@ int asCBuilder::RegisterImportedFunction(int importID, asCScriptNode *node, asCS
 		ns = engine->nameSpaces[0];
 		ns = engine->nameSpaces[0];
 
 
 	GetParsedFunctionDetails(node->firstChild, file, 0, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, funcTraits, ns);
 	GetParsedFunctionDetails(node->firstChild, file, 0, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, funcTraits, ns);
-	CheckNameConflict(name.AddressOf(), node, file, ns, false);
+	CheckNameConflict(name.AddressOf(), node, file, ns, false, false);
 
 
 	// Check that the same function hasn't been registered already in the namespace
 	// Check that the same function hasn't been registered already in the namespace
 	asCArray<int> funcs;
 	asCArray<int> funcs;
@@ -5179,7 +5412,7 @@ int asCBuilder::RegisterImportedFunction(int importID, asCScriptNode *node, asCS
 	node->Destroy(engine);
 	node->Destroy(engine);
 
 
 	// Register the function
 	// Register the function
-	module->AddImportedFunction(importID, name, returnType, parameterTypes, inOutFlags, defaultArgs, ns, moduleName);
+	module->AddImportedFunction(importID, name, returnType, parameterTypes, inOutFlags, defaultArgs, funcTraits, ns, moduleName);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -5199,21 +5432,21 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
 	asUINT n;
 	asUINT n;
 
 
 	// Get the script declared global functions
 	// Get the script declared global functions
-	const asCArray<unsigned int> &idxs = module->globalFunctions.GetIndexes(ns, name);
+	const asCArray<unsigned int> &idxs = module->m_globalFunctions.GetIndexes(ns, name);
 	for( n = 0; n < idxs.GetLength(); n++ )
 	for( n = 0; n < idxs.GetLength(); n++ )
 	{
 	{
-		const asCScriptFunction *f = module->globalFunctions.Get(idxs[n]);
+		const asCScriptFunction *f = module->m_globalFunctions.Get(idxs[n]);
 		asASSERT( f->objectType == 0 );
 		asASSERT( f->objectType == 0 );
 		funcs.PushLast(f->id);
 		funcs.PushLast(f->id);
 	}
 	}
 
 
 	// Add the imported functions
 	// Add the imported functions
 	// TODO: optimize: Linear search: This is probably not that critial. Also bindInformation will probably be removed in near future
 	// 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++ )
+	for( n = 0; n < module->m_bindInformations.GetLength(); n++ )
 	{
 	{
-		if( module->bindInformations[n]->importedFunctionSignature->name == name &&
-			module->bindInformations[n]->importedFunctionSignature->nameSpace == ns )
-			funcs.PushLast(module->bindInformations[n]->importedFunctionSignature->id);
+		if( module->m_bindInformations[n]->importedFunctionSignature->name == name &&
+			module->m_bindInformations[n]->importedFunctionSignature->nameSpace == ns )
+			funcs.PushLast(module->m_bindInformations[n]->importedFunctionSignature->id);
 	}
 	}
 
 
 	// Add the registered global functions
 	// Add the registered global functions
@@ -5223,7 +5456,7 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
 		asCScriptFunction *f = engine->registeredGlobalFuncs.Get(idxs2[n]);
 		asCScriptFunction *f = engine->registeredGlobalFuncs.Get(idxs2[n]);
 
 
 		// Verify if the module has access to the function
 		// Verify if the module has access to the function
-		if( module->accessMask & f->accessMask )
+		if( module->m_accessMask & f->accessMask )
 		{
 		{
 			funcs.PushLast(f->id);
 			funcs.PushLast(f->id);
 		}
 		}
@@ -5284,7 +5517,7 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
 		asCScriptFunction *func = engine->scriptFunctions[objectType->methods[n]];
 		asCScriptFunction *func = engine->scriptFunctions[objectType->methods[n]];
 		if( func->name == name &&
 		if( func->name == name &&
 			(!objIsConst || func->IsReadOnly()) &&
 			(!objIsConst || func->IsReadOnly()) &&
-			(func->accessMask & module->accessMask) )
+			(func->accessMask & module->m_accessMask) )
 		{
 		{
 			// When the scope is defined the returned methods should be the true methods, not the virtual method stubs
 			// When the scope is defined the returned methods should be the true methods, not the virtual method stubs
 			if( scope == "" )
 			if( scope == "" )
@@ -5621,7 +5854,7 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 					isImplicitHandle = true;
 					isImplicitHandle = true;
 
 
 				// Make sure the module has access to the object type
 				// Make sure the module has access to the object type
-				if( !module || (module->accessMask & ti->accessMask) )
+				if( !module || (module->m_accessMask & ti->accessMask) )
 				{
 				{
 					if( asOBJ_TYPEDEF == (ti->flags & asOBJ_TYPEDEF) )
 					if( asOBJ_TYPEDEF == (ti->flags & asOBJ_TYPEDEF) )
 					{
 					{
@@ -5769,13 +6002,20 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 					*isValid = false;
 					*isValid = false;
 				break;
 				break;
 			}
 			}
-			else if( dt.MakeHandle(true, acceptHandleForScope) < 0 )
+			else
 			{
 			{
-				if( reportError )
-					WriteError(TXT_OBJECT_HANDLE_NOT_SUPPORTED, file, n);
-				if (isValid)
-					*isValid = false;
-				break;
+				if( dt.MakeHandle(true, acceptHandleForScope) < 0 )
+				{
+					if( reportError )
+						WriteError(TXT_OBJECT_HANDLE_NOT_SUPPORTED, file, n);
+					if (isValid)
+						*isValid = false;
+					break;
+				}
+				
+				// Check if the handle should be read-only
+				if( n && n->next && n->next->tokenType == ttConst )
+					dt.MakeReadOnly(true);
 			}
 			}
 		}
 		}
 		n = n->next;
 		n = n->next;
@@ -6035,24 +6275,24 @@ bool asCBuilder::DoesTypeExist(const asCString &type)
 		if (module)
 		if (module)
 		{
 		{
 			// Add script classes and interfaces
 			// 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);
+			for (n = 0; n < module->m_classTypes.GetLength(); n++)
+				if (!knownTypes.MoveTo(0, module->m_classTypes[n]->name))
+					knownTypes.Insert(module->m_classTypes[n]->name, true);
 
 
 			// Add script enums
 			// 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);
+			for (n = 0; n < module->m_enumTypes.GetLength(); n++)
+				if (!knownTypes.MoveTo(0, module->m_enumTypes[n]->name))
+					knownTypes.Insert(module->m_enumTypes[n]->name, true);
 
 
 			// Add script typedefs
 			// 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);
+			for (n = 0; n < module->m_typeDefs.GetLength(); n++)
+				if (!knownTypes.MoveTo(0, module->m_typeDefs[n]->name))
+					knownTypes.Insert(module->m_typeDefs[n]->name, true);
 
 
 			// Add script funcdefs
 			// 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);
+			for (n = 0; n < module->m_funcDefs.GetLength(); n++)
+				if (!knownTypes.MoveTo(0, module->m_funcDefs[n]->name))
+					knownTypes.Insert(module->m_funcDefs[n]->name, true);
 		}
 		}
 	}
 	}
 
 
@@ -6115,9 +6355,9 @@ asCFuncdefType *asCBuilder::GetFuncDef(const char *type, asSNameSpace *ns, asCOb
 
 
 		if (module)
 		if (module)
 		{
 		{
-			for (asUINT n = 0; n < module->funcDefs.GetLength(); n++)
+			for (asUINT n = 0; n < module->m_funcDefs.GetLength(); n++)
 			{
 			{
-				asCFuncdefType *funcDef = module->funcDefs[n];
+				asCFuncdefType *funcDef = module->m_funcDefs[n];
 				if (funcDef && funcDef->nameSpace == ns && funcDef->name == type)
 				if (funcDef && funcDef->nameSpace == ns && funcDef->name == type)
 					return funcDef;
 					return funcDef;
 			}
 			}
@@ -6174,7 +6414,7 @@ int asCBuilder::GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outV
 		if( ns != et->nameSpace ) continue;
 		if( ns != et->nameSpace ) continue;
 
 
 		// Don't bother with types the module doesn't have access to
 		// Don't bother with types the module doesn't have access to
-		if( (et->accessMask & module->accessMask) == 0 )
+		if( (et->accessMask & module->m_accessMask) == 0 )
 			continue;
 			continue;
 
 
 		if( GetEnumValueFromType(et, name, outDt, outValue) )
 		if( GetEnumValueFromType(et, name, outDt, outValue) )
@@ -6189,9 +6429,9 @@ int asCBuilder::GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outV
 		}
 		}
 	}
 	}
 
 
-	for( t = 0; t < module->enumTypes.GetLength(); t++ )
+	for( t = 0; t < module->m_enumTypes.GetLength(); t++ )
 	{
 	{
-		asCEnumType *et = module->enumTypes[t];
+		asCEnumType *et = module->m_enumTypes[t];
 		if( ns != et->nameSpace ) continue;
 		if( ns != et->nameSpace ) continue;
 
 
 		if( GetEnumValueFromType(et, name, outDt, outValue) )
 		if( GetEnumValueFromType(et, name, outDt, outValue) )

+ 4 - 3
Source/ThirdParty/AngelScript/source/as_builder.h

@@ -142,12 +142,13 @@ public:
 	int ParseTemplateDecl(const char *decl, asCString *name, asCArray<asCString> &subtypeNames);
 	int ParseTemplateDecl(const char *decl, asCString *name, asCArray<asCString> &subtypeNames);
 	int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0, asCScriptNode **outListPattern = 0, asCObjectType **outParentClass = 0);
 	int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0, asCScriptNode **outListPattern = 0, asCObjectType **outParentClass = 0);
 	int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
 	int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
-	int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isNotFunction);
-	int CheckNameConflictMember(asCTypeInfo *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty);
+	int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isProperty, bool isVirtualProperty);
+	int CheckNameConflictMember(asCTypeInfo *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty, bool isVirtualProperty);
+	int ValidateVirtualProperty(asCScriptFunction *func);
 
 
 #ifndef AS_NO_COMPILER
 #ifndef AS_NO_COMPILER
 	int AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy);
 	int AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy);
-	asCScriptCode *FindOrAddCode(const char *name, const char *code, asUINT length);
+	asCScriptCode *FindOrAddCode(const char *name, const char *code, size_t length);
 	int Build();
 	int Build();
 
 
 	int CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asCScriptFunction **outFunc);
 	int CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asCScriptFunction **outFunc);

+ 29 - 16
Source/ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -135,7 +135,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 				internal->callConv = (internalCallConv)(thisCallConv + 2);
 				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
 #endif
 			internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
 			internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
-#if (defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
+#if (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
 			// As the least significant bit in func is used to switch to THUMB mode
 			// As the least significant bit in func is used to switch to THUMB mode
 			// on ARM processors, the LSB in the __delta variable is used instead of
 			// on ARM processors, the LSB in the __delta variable is used instead of
 			// the one in __pfn on ARM processors.
 			// the one in __pfn on ARM processors.
@@ -594,7 +594,6 @@ int CallSystemFunction(int id, asCContext *context)
 	void *secondObj = 0;
 	void *secondObj = 0;
 
 
 #ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 #ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-
 	if( callConv >= ICC_THISCALL )
 	if( callConv >= ICC_THISCALL )
 	{
 	{
 		if(sysFunc->auxiliary)
 		if(sysFunc->auxiliary)
@@ -615,22 +614,22 @@ int CallSystemFunction(int id, asCContext *context)
 				return 0;
 				return 0;
 			}
 			}
 
 
-			// Add the base offset for multiple inheritance
-#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
-			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
-			// and the whole offset is thus shifted one bit left to keep the original
-			// offset resolution
-			// MIPS also work like ARM in this regard
-			obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
-#else
-			obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
-#endif
-
 			// Skip the object pointer
 			// Skip the object pointer
 			args += AS_PTR_SIZE;
 			args += AS_PTR_SIZE;
 		}
 		}
-	}
+		
+		// Add the base offset for multiple inheritance
+#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
+		// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
+		// and the whole offset is thus shifted one bit left to keep the original
+		// offset resolution
+		// MIPS also work like ARM in this regard
+		obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
 #else
 #else
+		obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
+#endif		
+	}
+#else // !defined(AS_NO_THISCALL_FUNCTOR_METHOD)
 
 
 	if( callConv >= ICC_THISCALL )
 	if( callConv >= ICC_THISCALL )
 	{
 	{
@@ -650,6 +649,20 @@ int CallSystemFunction(int id, asCContext *context)
 			obj = sysFunc->auxiliary;
 			obj = sysFunc->auxiliary;
 			continueCheck = false;
 			continueCheck = false;
 		}
 		}
+		
+		if( obj )
+		{
+			// Add the base offset for multiple inheritance
+#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
+			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
+			// and the whole offset is thus shifted one bit left to keep the original
+			// offset resolution
+			// MIPS also work like ARM in this regard
+			obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
+#else
+			obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
+#endif		
+		}
 
 
 		if( continueCheck )
 		if( continueCheck )
 		{
 		{
@@ -667,7 +680,7 @@ int CallSystemFunction(int id, asCContext *context)
 			}
 			}
 
 
 			// Add the base offset for multiple inheritance
 			// Add the base offset for multiple inheritance
-#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
+#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
 			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
 			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
 			// and the whole offset is thus shifted one bit left to keep the original
 			// and the whole offset is thus shifted one bit left to keep the original
 			// offset resolution
 			// offset resolution

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2017 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -100,7 +100,6 @@ struct asSSystemFunctionInterface
 	asFUNCTION_t         func;
 	asFUNCTION_t         func;
 	int                  baseOffset;
 	int                  baseOffset;
 	internalCallConv     callConv;
 	internalCallConv     callConv;
-	int                  scriptReturnSize;
 	bool                 hostReturnInMemory;
 	bool                 hostReturnInMemory;
 	bool                 hostReturnFloat;
 	bool                 hostReturnFloat;
 	int                  hostReturnSize;
 	int                  hostReturnSize;
@@ -120,7 +119,7 @@ struct asSSystemFunctionInterface
 	};
 	};
 	asCArray<SClean>     cleanArgs;
 	asCArray<SClean>     cleanArgs;
 
 
-	asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), scriptReturnSize(0), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
+	asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
 
 
 	asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
 	asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
 	{
 	{
@@ -132,7 +131,6 @@ struct asSSystemFunctionInterface
 		func                = in.func;
 		func                = in.func;
 		baseOffset          = in.baseOffset;
 		baseOffset          = in.baseOffset;
 		callConv            = in.callConv;
 		callConv            = in.callConv;
-		scriptReturnSize    = in.scriptReturnSize;
 		hostReturnInMemory  = in.hostReturnInMemory;
 		hostReturnInMemory  = in.hostReturnInMemory;
 		hostReturnFloat     = in.hostReturnFloat;
 		hostReturnFloat     = in.hostReturnFloat;
 		hostReturnSize      = in.hostReturnSize;
 		hostReturnSize      = in.hostReturnSize;

+ 329 - 0
Source/ThirdParty/AngelScript/source/as_callfunc_arm64.cpp

@@ -0,0 +1,329 @@
+/*
+   AngelCode Scripting Library
+   Copyright (c) 2020-2020 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]
+*/
+
+
+//
+// as_callfunc_arm64.cpp
+//
+// These functions handle the actual calling of system functions on the arm64 platform
+//
+// Written by Max Waine in July 2020, based on as_callfunc_arm.cpp
+//
+
+
+#include "as_config.h"
+
+#ifndef AS_MAX_PORTABILITY
+#ifdef AS_ARM64
+
+#include "as_callfunc.h"
+#include "as_scriptengine.h"
+#include "as_texts.h"
+#include "as_tokendef.h"
+#include "as_context.h"
+
+// ARM64 targets use has no software floating-point ABI, it's all hardware (or totally disabled)
+
+#define HFA_RET_REGISTERS   4 // s0-s3/d0-d3
+#define GP_ARG_REGISTERS    8 // x0-x7
+#define FLOAT_ARG_REGISTERS 8 // v0-v7
+
+BEGIN_AS_NAMESPACE
+
+// x0-7:   Argument registers (pass params or return results. OK as volatile local variables)
+// x8:     Indirect result register (e.g. address of large returned struct)
+// x9-15:  Volatile local variable registers
+// x16-17: Intra-procedure-call temporary registers
+// x18:    Platform register (reserved for use of platform ABIs)
+// x19-29: Non-volatile variable registers (must be saved and restored if modified)
+// x29:    Frame pointer register
+// x30:    Link register (where to return to)
+
+extern "C" void GetHFAReturnDouble(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
+extern "C" void GetHFAReturnFloat(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
+
+extern "C" asQWORD CallARM64RetInMemory(
+	const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+	const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+	const asQWORD *stackArgs,    asQWORD numStackArgs,
+	void *retPointer,            asFUNCTION_t func
+);
+extern "C" double CallARM64Double(
+	const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+	const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+	const asQWORD *stackArgs,    asQWORD numStackArgs,
+	asFUNCTION_t func
+);
+extern "C" float CallARM64Float(
+	const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+	const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+	const asQWORD *stackArgs,    asQWORD numStackArgs,
+	asFUNCTION_t func
+);
+extern "C" asQWORD CallARM64(
+	const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+	const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+	const asQWORD *stackArgs,    asQWORD numStackArgs,
+	asFUNCTION_t func
+);
+extern "C" asQWORD CallARM64Ret128(
+	const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+	const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+	const asQWORD *stackArgs,    asQWORD numStackArgs,
+	asQWORD *higherQWORD,        asFUNCTION_t func
+);
+
+//
+// If it's possible to fit in registers,
+// there may not be enough float register space even if true is returned
+//
+static inline bool IsRegisterHFA(const asCDataType &type)
+{
+	const asCTypeInfo *const typeInfo = type.GetTypeInfo();
+
+	if( typeInfo == nullptr ||
+		(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
+		type.IsObjectHandle() && type.IsReference() )
+		return false;
+
+	const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
+	const int maxAllowedSize = doubles ? sizeof(double) * HFA_RET_REGISTERS : sizeof(float) * HFA_RET_REGISTERS;
+
+	return type.GetSizeInMemoryBytes() <= maxAllowedSize;
+}
+
+//
+// If it's possible to fit it in registers,
+// if true is returned there is enough space to fit
+//
+static inline bool IsRegisterHFAParameter(const asCDataType &type, const asQWORD numFloatRegArgs)
+{
+	if( !IsRegisterHFA(type) )
+		return false;
+
+	const bool doubles = (type.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
+	const int registersUsed = type.GetSizeInMemoryDWords() / (doubles ? sizeof(double) : sizeof(float));
+
+	return numFloatRegArgs + registersUsed <= FLOAT_ARG_REGISTERS;
+}
+
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
+{
+	asCScriptEngine *engine = context->m_engine;
+	const asSSystemFunctionInterface *const sysFunc = descr->sysFuncIntf;
+	const asCDataType &retType = descr->returnType;
+	const asCTypeInfo *const retTypeInfo = retType.GetTypeInfo();
+	asFUNCTION_t func = sysFunc->func;
+	int callConv = sysFunc->callConv;
+	asQWORD       retQW     = 0;
+
+	asQWORD       gpRegArgs[GP_ARG_REGISTERS];
+	asQWORD       floatRegArgs[FLOAT_ARG_REGISTERS];
+	asQWORD       stackArgs[64]; // It's how many x64 users can have
+	asQWORD       numGPRegArgs    = 0;
+	asQWORD       numFloatRegArgs = 0;
+	asQWORD       numStackArgs    = 0;
+
+	asFUNCTION_t *vftable;
+
+	// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
+	if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
+		(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
+	{
+		// Add the object pointer as the first parameter
+		gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
+	}
+
+	if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
+	{
+		// Add the object pointer as the first parameter
+		gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
+	}
+	else if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
+	{
+		// Add the object pointer as the first parameter
+		gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
+	}
+
+	if( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
+	callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
+	{
+		// Get virtual function table from the object pointer
+		vftable = *(asFUNCTION_t**)obj;
+		func = vftable[FuncPtrToUInt(func)/sizeof(void*)];
+	}
+
+	asUINT argsPos = 0;
+	for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
+	{
+		const asCDataType &parmType = descr->parameterTypes[n];
+		const asCTypeInfo *const parmTypeInfo = parmType.GetTypeInfo();
+
+		if( parmType.IsObject() && !parmType.IsObjectHandle() && !parmType.IsReference() )
+		{
+			const asUINT parmDWords = parmType.GetSizeInMemoryDWords();
+			const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
+
+			const bool passedAsPointer = parmQWords <= 2;
+			const bool fitsInRegisters = passedAsPointer ? (numGPRegArgs < GP_ARG_REGISTERS) : (numGPRegArgs + parmQWords <= GP_ARG_REGISTERS);
+			asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
+			asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
+
+			if( (parmTypeInfo->flags & COMPLEX_MASK) )
+			{
+				argsArray[numArgs++] = *(asQWORD*)&args[argsPos];
+				argsPos += AS_PTR_SIZE;
+			}
+			else if( IsRegisterHFAParameter(parmType, numFloatRegArgs) )
+			{
+				if( (parmTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
+				{
+					const asQWORD *const contents = *(asQWORD**)&args[argsPos];
+					for( asUINT i = 0; i < parmQWords; i++ )
+						floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
+				}
+				else
+				{
+					const asDWORD *const contents = *(asDWORD**)&args[argsPos];
+					for( asUINT i = 0; i < parmDWords; i++ )
+						floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
+				}
+				engine->CallFree(*(char**)(args+argsPos));
+				argsPos += AS_PTR_SIZE;
+			}
+			else
+			{
+				// Copy the object's memory to the buffer
+				memcpy(&argsArray[numArgs], *(void**)(args+argsPos), parmType.GetSizeInMemoryBytes());
+
+				// Delete the original memory
+				engine->CallFree(*(char**)(args+argsPos));
+				argsPos += AS_PTR_SIZE;
+				numArgs += parmQWords;
+			}
+		}
+		else if( parmType.IsFloatType() && !parmType.IsReference() )
+		{
+			if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
+				stackArgs[numStackArgs++] = args[argsPos];
+			else
+				floatRegArgs[numFloatRegArgs++] = args[argsPos];
+			argsPos++;
+		}
+		else if( parmType.IsDoubleType() && !parmType.IsReference() )
+		{
+			if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
+				stackArgs[numStackArgs++] = *(asQWORD*)&args[argsPos];
+			else
+				floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&args[argsPos];
+			argsPos += 2;
+		}
+		else
+		{
+			// Copy the value directly
+			const asUINT parmDWords = parmType.GetSizeOnStackDWords();
+			const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
+
+			const bool fitsInRegisters = numGPRegArgs + parmQWords <= GP_ARG_REGISTERS;
+			asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
+			asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
+
+			memcpy(&argsArray[numArgs], (void*)(args+argsPos), parmDWords * 4);
+			argsPos += parmDWords;
+			numArgs += parmQWords;
+		}
+	}
+
+	if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
+	{
+		// Add the object pointer as the last parameter
+		if( numGPRegArgs < GP_ARG_REGISTERS )
+			gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
+		else
+			stackArgs[numStackArgs++] = (asQWORD)obj;
+	}
+	else if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
+	{
+		// Add the object pointer as the last parameter
+		if( numGPRegArgs < GP_ARG_REGISTERS )
+			gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
+		else
+			stackArgs[numStackArgs++] = (asQWORD)secondObject;
+	}
+
+	if( IsRegisterHFA(retType) && !(retTypeInfo->flags & COMPLEX_MASK) )
+	{
+		// This is to deal with HFAs (Homogeneous Floating-point Aggregates):
+		// ARM64 will place all-float composite types (of equal precision)
+		// with <= 4 members in the float return registers
+
+		const int structSize = retType.GetSizeInMemoryBytes();
+
+		CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
+		if( (retTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
+		{
+			if( structSize <= sizeof(double) * 2 )
+				GetHFAReturnDouble(&retQW, &retQW2, structSize);
+			else
+				GetHFAReturnDouble((asQWORD*)retPointer, ((asQWORD*)retPointer) + 1, structSize);
+		}
+		else
+			GetHFAReturnFloat(&retQW, &retQW2, structSize);
+	}
+	else if( sysFunc->hostReturnFloat )
+	{
+		if( sysFunc->hostReturnSize == 1 )
+			*(float*)&retQW = CallARM64Float(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
+		else
+			*(double*)&retQW = CallARM64Double(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
+	}
+	else if( sysFunc->hostReturnInMemory )
+		retQW = CallARM64RetInMemory(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, retPointer, func);
+	else
+	{
+		if( retType.GetSizeInMemoryBytes() > sizeof(asQWORD) )
+			retQW = CallARM64Ret128(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, &retQW2, func);
+		else
+			retQW = CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
+	}
+
+	return retQW;
+}
+
+END_AS_NAMESPACE
+
+#endif // AS_ARM64
+#endif // AS_MAX_PORTABILITY
+
+
+
+

+ 219 - 0
Source/ThirdParty/AngelScript/source/as_callfunc_arm64_gcc.S

@@ -0,0 +1,219 @@
+//
+//  AngelCode Scripting Library
+//  Copyright (c) 2020-2020 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]
+//
+
+
+// Assembly routines for the ARM64/AArch64 call convention used for Linux
+// Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm,
+// with assistance & guidance provided by Sir Kane
+
+// Compile with GCC/GAS
+
+.arch armv8-a
+.text
+
+.global GetHFAReturnDouble
+.global GetHFAReturnFloat
+.global CallARM64Ret128
+.global CallARM64RetInMemory
+.global CallARM64Double
+.global CallARM64Float
+.global CallARM64
+
+.type GetHFAReturnDouble, %function
+.type GetHFAReturnFloat, %function
+.type CallARM64Ret128, %function
+.type CallARM64RetInMemory, %function
+.type CallARM64Double, %function
+.type CallARM64Float, %function
+.type CallARM64, %function
+
+.align  2
+GetHFAReturnDouble:
+    adr     x9, populateDoubles
+    sub     x9, x9, x1, lsr 1 // x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
+    br      x9
+
+    str     d3, [x0, #0x18]
+    str     d2, [x0, #0x10]
+    str     d1, [x1]
+    str     d0, [x0]
+populateDoubles:
+
+    ret
+
+.align  2
+GetHFAReturnFloat:
+    adr     x9, populateFloats
+    sub     x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
+    br      x9
+
+    str     s3, [x1, #0x4]
+    str     s2, [x1]
+    str     s1, [x0, #0x4]
+    str     s0, [x0]
+populateFloats:
+
+    ret
+
+
+//[returnType] CallARM64[type](
+//    const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+//    const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+//    const asQWORD *stackArgs,    asQWORD numStackArgs,
+//    asFUNCTION_t func
+//)
+.align  2
+CallARM64Double:
+CallARM64Float:
+CallARM64:
+    .cfi_startproc
+    stp     fp, lr, [sp,#-0x20]!
+    str     x20, [sp,#0x10]
+    .cfi_def_cfa_offset 0x20
+    .cfi_offset 20,  0x10
+    .cfi_offset fp, -0x20
+    .cfi_offset lr, -0x18
+    mov     fp, sp
+
+    mov     x20, #0
+
+    cbz     x5, stackArgsLoopEnd
+
+    // Align count to 2, then multiply by 8, resulting in a size aligned to 16
+    add x20, x5,  #1
+    lsl x20, x20, #3
+    and x20, x20, #-0x10
+    // Multiply count by 8
+    lsl x10, x5, #3
+    sub sp, sp, x20
+stackArgsLoopStart:
+    ldp     x9,x11, [x4],#16
+    stp     x9,x11, [sp],#16
+    subs    x10, x10, #16
+    bgt     stackArgsLoopStart
+stackArgsLoopEnd:
+
+    // Calculate amount to jump forward, avoiding pointless instructions
+    adr     x9, populateFloatRegisterArgsEnd
+    sub     x9, x9, x3, lsl 2 // x9 -= numFloatRegArgs * 4
+    br      x9
+
+    ldr     d7, [x2, #0x38]
+    ldr     d6, [x2, #0x30]
+    ldr     d5, [x2, #0x28]
+    ldr     d4, [x2, #0x20]
+    ldr     d3, [x2, #0x18]
+    ldr     d2, [x2, #0x10]
+    ldr     d1, [x2, #0x08]
+    ldr     d0, [x2]
+populateFloatRegisterArgsEnd:
+
+    mov     x15, x6
+    // Calculate amount to jump forward, avoiding pointless instructions
+    adr     x9, populateGPRegisterArgsEnd
+    sub     x9, x9, x1, lsl 2 // x9 -= numGPRegArgs * 4
+    br      x9
+
+    ldr     x7, [x0, #0x38]
+    ldr     x6, [x0, #0x30]
+    ldr     x5, [x0, #0x28]
+    ldr     x4, [x0, #0x20]
+    ldr     x3, [x0, #0x18]
+    ldr     x2, [x0, #0x10]
+    ldr     x1, [x0, #0x08]
+    ldr     x0, [x0]
+populateGPRegisterArgsEnd:
+
+    // Actually call function
+    sub     sp, sp, x20
+    blr     x15
+    add     sp, sp, x20
+
+    ldr     x20, [sp,#0x10]
+    ldp     fp, lr, [sp],#0x20
+
+    .cfi_restore lr
+	.cfi_restore fp
+    .cfi_restore 20
+	.cfi_def_cfa_offset 0
+    ret
+    .cfi_endproc
+
+.align  2
+CallARM64Ret128:
+    .cfi_startproc
+    stp     fp, lr, [sp,#-0x20]!
+    str     x20, [sp,#0x10]
+    .cfi_def_cfa_offset 0x20
+    .cfi_offset 20,  0x10
+    .cfi_offset fp, -0x20
+    .cfi_offset lr, -0x18
+    mov     fp, sp
+
+    mov     x20, x6
+    mov     x6, x7
+    mov     x7, #0
+    bl      CallARM64
+
+    str     x1, [x20]
+
+    ldr     x20, [sp,#0x10]
+    ldp     fp, lr, [sp],#0x20
+
+    .cfi_restore lr
+	.cfi_restore fp
+    .cfi_restore 20
+	.cfi_def_cfa_offset 0
+    ret
+    .cfi_endproc
+
+.align  2
+CallARM64RetInMemory:
+    .cfi_startproc
+    stp     fp, lr, [sp,#-0x10]!
+    mov     fp, sp
+    .cfi_def_cfa_offset 0x10
+    .cfi_offset fp, -0x10
+    .cfi_offset lr, -0x08
+
+    mov     x8, x6
+    mov     x6, x7
+    mov     x7, #0
+    bl      CallARM64
+
+    mov     x0, x8
+
+    ldp     fp, lr, [sp],#0x10
+
+    .cfi_restore lr
+	.cfi_restore fp
+	.cfi_def_cfa_offset 0
+    ret
+    .cfi_endproc

+ 205 - 0
Source/ThirdParty/AngelScript/source/as_callfunc_arm64_msvc.asm

@@ -0,0 +1,205 @@
+;
+;  AngelCode Scripting Library
+;  Copyright (c) 2020-2020 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]
+;
+
+
+; Assembly routines for the ARM64/AArch64 call convention used for Windows 10 on ARM
+; Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm
+
+; MSVC currently doesn't support inline assembly for the ARM64 platform,
+; and if they're treating it like x64 /won't/ ever support inline assembly,
+; so this separate file is needed.
+
+; Compile with Microsoft ARM64 assembler (armasm64)
+; http://msdn.microsoft.com/en-us/library/hh873190.aspx
+
+    AREA    |.rdata|, DATA, READONLY
+    EXPORT  GetHFAReturnDouble
+    EXPORT  GetHFAReturnFloat
+    EXPORT  CallARM64Ret128
+    EXPORT  CallARM64RetInMemory
+    EXPORT  CallARM64Double
+    EXPORT  CallARM64Float
+    EXPORT  CallARM64
+
+    AREA    |.text|, CODE, ALIGN=2
+
+    ALIGN   4
+GetHFAReturnDouble PROC
+    adr     x9, |populateDoubles|
+    sub     x9, x9, x1, lsr 1 ; x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
+    br      x9
+
+    str     d3, [x0, #0x18]
+    str     d2, [x0, #0x10]
+    str     d1, [x1]
+    str     d0, [x0]
+|populateDoubles|
+
+    ret
+    ENDP ; GetHFAReturnDouble
+
+    ALIGN   4
+GetHFAReturnFloat PROC
+    adr     x9, |populateFloats|
+    sub     x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
+    br      x9
+
+    str     s3, [x1, #0x4]
+    str     s2, [x1]
+    str     s1, [x0, #0x4]
+    str     s0, [x0]
+|populateFloats|
+
+    ret
+    ENDP ; GetHFAReturnFloat
+
+
+;[returnType] CallARM64[type](
+;    const asQWORD *gpRegArgs,    asQWORD numGPRegArgs,
+;    const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
+;    const asQWORD *stackArgs,    asQWORD numStackArgs,
+;    asFUNCTION_t func
+;)
+    ALIGN   4
+CallARM64Double PROC
+    stp     fp, lr, [sp,#-0x10]!
+    bl      CallARM64
+    ldp     fp, lr, [sp,#-0x10]!
+    ret
+    ENDP ; CallARM64Double
+
+    ALIGN   4
+CallARM64Float PROC
+    stp     fp, lr, [sp,#-0x10]!
+    bl      CallARM64
+    ldp     fp, lr, [sp,#-0x10]!
+    ret
+    ENDP ; CallARM64Float
+
+    ALIGN   4
+CallARM64 PROC
+    stp     fp, lr, [sp,#-0x20]!
+    str     x20, [sp,#0x10]
+
+    mov     x20, #0;
+
+    cbz     x5, |stackArgsLoopEnd|
+
+    ; Align count to 2, then multiply by 8, resulting in a size aligned to 16
+    add x20, x5,  #1
+    lsl x20, x20, #3
+    and x20, x20, #-0x10
+    ; Multiply count by 8
+    lsl x10, x5, #3
+    sub sp, sp, x20
+|stackArgsLoopStart|
+    ldp     x9,x11, [x4],#16
+    stp     x9,x11, [sp],#16
+    subs    x10, x10, #16
+    bgt     |stackArgsLoopStart|
+|stackArgsLoopEnd|
+
+    ; Calculate amount to jump forward, avoiding pointless instructions
+    adr     x9, |populateFloatRegisterArgsEnd|
+    sub     x9, x9, x3, lsl 2 ; x9 -= numFloatRegArgs * 4
+    br      x9
+
+    ldr     d7, [x2, #0x38]
+    ldr     d6, [x2, #0x30]
+    ldr     d5, [x2, #0x28]
+    ldr     d4, [x2, #0x20]
+    ldr     d3, [x2, #0x18]
+    ldr     d2, [x2, #0x10]
+    ldr     d1, [x2, #0x08]
+    ldr     d0, [x2]
+|populateFloatRegisterArgsEnd|
+
+    mov     x15, x6
+    ; Calculate amount to jump forward, avoiding pointless instructions
+    adr     x9, |populateGPRegisterArgsEnd|
+    sub     x9, x9, x1, lsl 2 ; x9 -= numGPRegArgs * 4
+    br      x9
+
+    ldr     x7, [x0, #0x38]
+    ldr     x6, [x0, #0x30]
+    ldr     x5, [x0, #0x28]
+    ldr     x4, [x0, #0x20]
+    ldr     x3, [x0, #0x18]
+    ldr     x2, [x0, #0x10]
+    ldr     x1, [x0, #0x08]
+    ldr     x0, [x0]
+|populateGPRegisterArgsEnd|
+
+    ; Actually call function
+    sub     sp, sp, x20
+    blr     x15
+    add     sp, sp, x20
+
+    ldr     x20, [sp,#0x10]
+    ldp     fp, lr, [sp],#0x20
+
+    ret
+    ENDP ; CallARM64
+
+    ALIGN   4
+CallARM64Ret128 PROC
+    stp     fp, lr, [sp,#-0x20]!
+    str     x20, [sp,#0x10]
+    mov     fp, sp
+
+    mov     x20, x6
+    mov     x6, x7
+    mov     x7, #0
+    bl      CallARM64
+
+    str     x1, [x20]
+
+    ldr     x20, [sp,#0x10]
+    ldp     fp, lr, [sp],#0x20
+
+    ret ; CallARM64Ret128
+
+    ALIGN   4
+CallARM64RetInMemory PROC
+    stp     fp, lr, [sp,#-0x10]!
+    mov     fp, sp
+
+    mov     x8, x6
+    mov     x6, x7
+    mov     x7, #0
+    bl      CallARM64
+
+    mov     x0, x8
+
+    ldp     fp, lr, [sp],#0x10
+
+    ret ; CallARM64RetInMemory
+
+    END

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

@@ -1,6 +1,6 @@
 /*
 /*
   AngelCode Scripting Library
   AngelCode Scripting Library
-  Copyright (c) 2003-2016 Andreas Jonsson
+  Copyright (c) 2003-2020 Andreas Jonsson
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any
   warranty. In no event will the authors be held liable for any
@@ -43,7 +43,7 @@
 
 
 #if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
 #if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
 
 
-#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__)
+#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__) || defined(__ARM_PCS)
 
 
 /* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
 /* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
 
 
@@ -287,7 +287,7 @@ nomoreargsarmFuncR0R1:
     ldmia   sp!, {r4-r8, pc}
     ldmia   sp!, {r4-r8, pc}
 
 
 /* --------------------------------------------------------------------------------------------*/
 /* --------------------------------------------------------------------------------------------*/
-#elif defined(__linux__) && !defined(__SOFTFP__)
+#elif defined(__linux__) && !defined(__SOFTFP__) && !defined(__ARM_PCS)
 
 
 /* The Linux with hard-float ABI code goes here */
 /* The Linux with hard-float ABI code goes here */
 
 

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

@@ -28,7 +28,7 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
+// Modified for Urho3D
 
 
 //
 //
 // as_callfunc_x86.cpp
 // as_callfunc_x86.cpp

+ 244 - 126
Source/ThirdParty/AngelScript/source/as_compiler.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2019 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -28,7 +28,7 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
+// Modified for Urho3D
 
 
 //
 //
 // as_compiler.cpp
 // as_compiler.cpp
@@ -103,6 +103,10 @@ asCCompiler::~asCCompiler()
 	for (asUINT n = 0; n < usedStringConstants.GetLength(); n++)
 	for (asUINT n = 0; n < usedStringConstants.GetLength(); n++)
 		engine->stringFactory->ReleaseStringConstant(usedStringConstants[n]);
 		engine->stringFactory->ReleaseStringConstant(usedStringConstants[n]);
 	usedStringConstants.SetLength(0);
 	usedStringConstants.SetLength(0);
+
+	// Clean up the temporary script nodes that were allocated during compilation
+	for (asUINT n = 0; n < nodesToFreeUponComplete.GetLength(); n++)
+		nodesToFreeUponComplete[n]->Destroy(engine);
 }
 }
 
 
 void asCCompiler::Reset(asCBuilder *in_builder, asCScriptCode *in_script, asCScriptFunction *in_outFunc)
 void asCCompiler::Reset(asCBuilder *in_builder, asCScriptCode *in_script, asCScriptFunction *in_outFunc)
@@ -353,7 +357,9 @@ int asCCompiler::SetupParametersAndReturnVariable(asCArray<asCString> &parameter
 
 
 	// Is the return type allowed?
 	// Is the return type allowed?
 	if( returnType != asCDataType::CreatePrimitive(ttVoid, false) &&
 	if( returnType != asCDataType::CreatePrimitive(ttVoid, false) &&
-		!returnType.CanBeInstantiated() )
+		!returnType.CanBeInstantiated() &&
+		!returnType.IsReference() &&
+		!returnType.IsObjectHandle() )
 	{
 	{
 		// TODO: Hasn't this been validated by the builder already?
 		// TODO: Hasn't this been validated by the builder already?
 		asCString str;
 		asCString str;
@@ -432,6 +438,7 @@ void asCCompiler::CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults
 		asCObjectProperty *prop = outFunc->objectType->properties[n];
 		asCObjectProperty *prop = outFunc->objectType->properties[n];
 
 
 		// Check if the property has an initialization expression
 		// Check if the property has an initialization expression
+		asCParser parser(builder);
 		asCScriptNode *declNode = 0;
 		asCScriptNode *declNode = 0;
 		asCScriptNode *initNode = 0;
 		asCScriptNode *initNode = 0;
 		asCScriptCode *initScript = 0;
 		asCScriptCode *initScript = 0;
@@ -467,7 +474,6 @@ void asCCompiler::CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults
 				initScript = script;
 				initScript = script;
 #else
 #else
 				// Re-parse the initialization expression as the parser now knows the types, which it didn't earlier
 				// Re-parse the initialization expression as the parser now knows the types, which it didn't earlier
-				asCParser parser(builder);
 				int r = parser.ParseVarInit(initScript, initNode);
 				int r = parser.ParseVarInit(initScript, initNode);
 				if( r < 0 )
 				if( r < 0 )
 					continue;
 					continue;
@@ -1474,7 +1480,8 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
 		int offset;
 		int offset;
 		if( refType == asTM_INREF )
 		if( refType == asTM_INREF )
 		{
 		{
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// Add the type id as hidden arg if the parameter is a ? type
 			// Add the type id as hidden arg if the parameter is a ? type
 			if( paramType->GetTokenType() == ttQuestion )
 			if( paramType->GetTokenType() == ttQuestion )
@@ -1761,7 +1768,8 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
 		}
 		}
 		else if( refType == asTM_INOUTREF )
 		else if( refType == asTM_INOUTREF )
 		{
 		{
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// Add the type id as hidden arg if the parameter is a ? type
 			// Add the type id as hidden arg if the parameter is a ? type
 			if( paramType->GetTokenType() == ttQuestion )
 			if( paramType->GetTokenType() == ttQuestion )
@@ -1795,7 +1803,10 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
 				}
 				}
 			}
 			}
 
 
-			// Perform implicit ref cast if necessary, but don't allow the implicit conversion to create new objects
+			// Allow anonymous init lists to be converted to the arg type
+			if( ctx->IsAnonymousInitList() )
+				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, true);
+			
 			if( (ctx->type.dataType.IsObject() || ctx->type.dataType.IsFuncdef()) && ctx->type.dataType.GetTypeInfo() != dt.GetTypeInfo() )
 			if( (ctx->type.dataType.IsObject() || ctx->type.dataType.IsFuncdef()) && ctx->type.dataType.GetTypeInfo() != dt.GetTypeInfo() )
 				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, false);
 				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, false);
 
 
@@ -1857,7 +1868,8 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
 	}
 	}
 	else
 	else
 	{
 	{
-		ProcessPropertyGetAccessor(ctx, node);
+		if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+			return -1;
 
 
 		if( dt.IsPrimitive() )
 		if( dt.IsPrimitive() )
 		{
 		{
@@ -2317,6 +2329,12 @@ int asCCompiler::CompileDefaultAndNamedArgs(asCScriptNode *node, asCArray<asCExp
 		}
 		}
 
 
 		MergeExprBytecodeAndType(args[n], &expr);
 		MergeExprBytecodeAndType(args[n], &expr);
+		if (args[n]->exprNode)
+		{
+			// Disconnect the node from the parser, and tell the compiler to free it when complete
+			args[n]->exprNode->DisconnectParent();
+			nodesToFreeUponComplete.PushLast(args[n]->exprNode);
+		}
 	}
 	}
 
 
 	reservedVariables.SetLength(prevReservedVars);
 	reservedVariables.SetLength(prevReservedVars);
@@ -2650,6 +2668,8 @@ bool asCCompiler::CompileAutoType(asCDataType &type, asCExprContext &compiledCtx
 			// Handle const qualifier on auto
 			// Handle const qualifier on auto
 			if (type.IsReadOnly())
 			if (type.IsReadOnly())
 				newType.MakeReadOnly(true);
 				newType.MakeReadOnly(true);
+			else if (type.IsHandleToConst())
+				newType.MakeHandleToConst(true);
 			else if (newType.IsPrimitive())
 			else if (newType.IsPrimitive())
 				newType.MakeReadOnly(false);
 				newType.MakeReadOnly(false);
 
 
@@ -3990,7 +4010,8 @@ void asCCompiler::CompileSwitchStatement(asCScriptNode *snode, bool *, asCByteCo
 		return;
 		return;
 	}
 	}
 
 
-	ProcessPropertyGetAccessor(&expr, snode);
+	if( ProcessPropertyGetAccessor(&expr, snode) < 0 )
+		return;
 
 
 	// TODO: Need to support 64bit integers
 	// TODO: Need to support 64bit integers
 	// Convert the expression to a 32bit variable
 	// Convert the expression to a 32bit variable
@@ -4353,7 +4374,8 @@ void asCCompiler::CompileIfStatement(asCScriptNode *inode, bool *hasReturn, asCB
 		{
 		{
 			if( !expr.type.isConstant )
 			if( !expr.type.isConstant )
 			{
 			{
-				ProcessPropertyGetAccessor(&expr, inode);
+				if( ProcessPropertyGetAccessor(&expr, inode) < 0 )
+					return;
 				ConvertToVariable(&expr);
 				ConvertToVariable(&expr);
 				ProcessDeferredParams(&expr);
 				ProcessDeferredParams(&expr);
 
 
@@ -4505,7 +4527,8 @@ void asCCompiler::CompileForStatement(asCScriptNode *fnode, asCByteCode *bc)
 				Error(TXT_EXPR_MUST_BE_BOOL, second);
 				Error(TXT_EXPR_MUST_BE_BOOL, second);
 			else
 			else
 			{
 			{
-				ProcessPropertyGetAccessor(&expr, second);
+				if( ProcessPropertyGetAccessor(&expr, second) < 0 )
+					return;
 				ConvertToVariable(&expr);
 				ConvertToVariable(&expr);
 				ProcessDeferredParams(&expr);
 				ProcessDeferredParams(&expr);
 
 
@@ -4617,7 +4640,8 @@ void asCCompiler::CompileWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 			Error(TXT_EXPR_MUST_BE_BOOL, wnode->firstChild);
 			Error(TXT_EXPR_MUST_BE_BOOL, wnode->firstChild);
 		else
 		else
 		{
 		{
-			ProcessPropertyGetAccessor(&expr, wnode);
+			if( ProcessPropertyGetAccessor(&expr, wnode) < 0 )
+				return;
 			ConvertToVariable(&expr);
 			ConvertToVariable(&expr);
 			ProcessDeferredParams(&expr);
 			ProcessDeferredParams(&expr);
 
 
@@ -4706,7 +4730,8 @@ void asCCompiler::CompileDoWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 		Error(TXT_EXPR_MUST_BE_BOOL, wnode->firstChild);
 		Error(TXT_EXPR_MUST_BE_BOOL, wnode->firstChild);
 	else
 	else
 	{
 	{
-		ProcessPropertyGetAccessor(&expr, wnode);
+		if( ProcessPropertyGetAccessor(&expr, wnode) < 0 )
+			return;
 		ConvertToVariable(&expr);
 		ConvertToVariable(&expr);
 		ProcessDeferredParams(&expr);
 		ProcessDeferredParams(&expr);
 		
 		
@@ -4797,7 +4822,8 @@ void asCCompiler::CompileExpressionStatement(asCScriptNode *enode, asCByteCode *
 		// accessor, then process it as a get access. Don't call if there is
 		// accessor, then process it as a get access. Don't call if there is
 		// already a compile error, or we might report an error that is not valid
 		// already a compile error, or we might report an error that is not valid
 		if( !hasCompileErrors )
 		if( !hasCompileErrors )
-			ProcessPropertyGetAccessor(&expr, enode);
+			if( ProcessPropertyGetAccessor(&expr, enode) < 0 )
+				return;
 
 
 		// Pop the value from the stack
 		// Pop the value from the stack
 		if( !expr.type.dataType.IsPrimitive() )
 		if( !expr.type.dataType.IsPrimitive() )
@@ -4830,7 +4856,7 @@ void asCCompiler::PrepareTemporaryVariable(asCScriptNode *node, asCExprContext *
 		{
 		{
 			ctx->bc.Instr(asBC_PopPtr);
 			ctx->bc.Instr(asBC_PopPtr);
 			ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
 			ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
-			ctx->type.dataType.MakeReference(true);
+			ctx->type.dataType.MakeReference(IsVariableOnHeap(ctx->type.stackOffset));
 		}
 		}
 
 
 		return;
 		return;
@@ -4993,7 +5019,6 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 			// be done before the expression is evaluated.
 			// be done before the expression is evaluated.
 			DestroyVariables(bc);
 			DestroyVariables(bc);
 
 
-
 			// For primitives the reference is already in the register,
 			// For primitives the reference is already in the register,
 			// but for non-primitives the reference is on the stack so we
 			// but for non-primitives the reference is on the stack so we
 			// need to load it into the register
 			// need to load it into the register
@@ -5010,7 +5035,8 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 		}
 		}
 		else // if( !v->type.IsReference() )
 		else // if( !v->type.IsReference() )
 		{
 		{
-			ProcessPropertyGetAccessor(&expr, rnode);
+			if( ProcessPropertyGetAccessor(&expr, rnode) < 0 )
+				return;
 
 
 			// Prepare the value for assignment
 			// Prepare the value for assignment
 			IsVariableInitialized(&expr.type, rnode->firstChild);
 			IsVariableInitialized(&expr.type, rnode->firstChild);
@@ -5499,8 +5525,8 @@ void asCCompiler::PrepareForAssignment(asCDataType *lvalue, asCExprContext *rctx
 	int l = int(reservedVariables.GetLength());
 	int l = int(reservedVariables.GetLength());
 	if( lvalueExpr ) lvalueExpr->bc.GetVarsUsed(reservedVariables);
 	if( lvalueExpr ) lvalueExpr->bc.GetVarsUsed(reservedVariables);
 
 
-
-	ProcessPropertyGetAccessor(rctx, node);
+	if( ProcessPropertyGetAccessor(rctx, node) < 0 )
+		return;
 
 
 	// Make sure the rvalue is initialized if it is a variable
 	// Make sure the rvalue is initialized if it is a variable
 	IsVariableInitialized(&rctx->type, node);
 	IsVariableInitialized(&rctx->type, node);
@@ -8276,8 +8302,8 @@ int asCCompiler::DoAssignment(asCExprContext *ctx, asCExprContext *lctx, asCExpr
 		lctx->type.isExplicitHandle = true;
 		lctx->type.isExplicitHandle = true;
 	}
 	}
 
 
-    // Urho3D: if there is a handle type, and it does not have an overloaded assignment operator, convert to an explicit handle
-    // for scripting convenience. (For the Urho3D handle types, value assignment is not supported)
+	// Urho3D: if there is a handle type, and it does not have an overloaded assignment operator, convert to an explicit handle
+	// for scripting convenience. (For the Urho3D handle types, value assignment is not supported)
 	if (lctx->type.dataType.IsObjectHandle() && !lctx->type.dataType.IsTemplate() && !lctx->type.isExplicitHandle &&
 	if (lctx->type.dataType.IsObjectHandle() && !lctx->type.dataType.IsTemplate() && !lctx->type.isExplicitHandle &&
 		(!lctx->type.dataType.GetBehaviour() || !lctx->type.dataType.GetBehaviour()->copy))
 		(!lctx->type.dataType.GetBehaviour() || !lctx->type.dataType.GetBehaviour()->copy))
 		lctx->type.isExplicitHandle = true;
 		lctx->type.isExplicitHandle = true;
@@ -8319,7 +8345,8 @@ int asCCompiler::DoAssignment(asCExprContext *ctx, asCExprContext *lctx, asCExpr
 	else if( lctx->property_get && lctx->type.dataType.IsObjectHandle() && !lctx->type.isExplicitHandle )
 	else if( lctx->property_get && lctx->type.dataType.IsObjectHandle() && !lctx->type.isExplicitHandle )
 	{
 	{
 		// Get the handle to the object that will be used for the value assignment
 		// Get the handle to the object that will be used for the value assignment
-		ProcessPropertyGetAccessor(lctx, opNode);
+		if( ProcessPropertyGetAccessor(lctx, opNode) < 0 )
+			return -1;
 	}
 	}
 
 
 	if( lctx->type.dataType.IsPrimitive() )
 	if( lctx->type.dataType.IsPrimitive() )
@@ -8517,9 +8544,20 @@ int asCCompiler::DoAssignment(asCExprContext *ctx, asCExprContext *lctx, asCExpr
 		bool needConversion = false;
 		bool needConversion = false;
 		if( !lctx->type.dataType.IsEqualExceptRefAndConst(rctx->type.dataType) )
 		if( !lctx->type.dataType.IsEqualExceptRefAndConst(rctx->type.dataType) )
 			needConversion = true;
 			needConversion = true;
-
+		
 		if( !simpleExpr || needConversion )
 		if( !simpleExpr || needConversion )
 		{
 		{
+			if( rctx->type.dataType.IsObjectHandle() && !rctx->type.isExplicitHandle && 
+			    !lctx->type.dataType.IsObjectHandle() && rctx->type.dataType.GetTypeInfo() == lctx->type.dataType.GetTypeInfo() )
+			{
+				// Make the conversion from handle to non-handle without creating 
+				// a copy of the object (otherwise done by PrepareArgument)
+				asCDataType dt = rctx->type.dataType;
+				dt.MakeHandle(false);
+				ImplicitConversion(rctx, dt, rexpr, asIC_IMPLICIT_CONV);
+				needConversion = false;
+			}
+			
 			asCDataType dt = lctx->type.dataType;
 			asCDataType dt = lctx->type.dataType;
 			dt.MakeReference(true);
 			dt.MakeReference(true);
 			// A funcdef can be accessed by ref, but only as read-only
 			// A funcdef can be accessed by ref, but only as read-only
@@ -8539,7 +8577,8 @@ int asCCompiler::DoAssignment(asCExprContext *ctx, asCExprContext *lctx, asCExpr
 		else
 		else
 		{
 		{
 			// Process any property accessor first, before placing the final reference on the stack
 			// Process any property accessor first, before placing the final reference on the stack
-			ProcessPropertyGetAccessor(rctx, rexpr);
+			if( ProcessPropertyGetAccessor(rctx, rexpr) < 0 )
+				return -1;
 
 
 			if( rctx->type.dataType.IsReference() && (!(rctx->type.isVariable || rctx->type.isTemporary) || IsVariableOnHeap(rctx->type.stackOffset)) )
 			if( rctx->type.dataType.IsReference() && (!(rctx->type.isVariable || rctx->type.isTemporary) || IsVariableOnHeap(rctx->type.stackOffset)) )
 				rctx->bc.Instr(asBC_RDSPtr);
 				rctx->bc.Instr(asBC_RDSPtr);
@@ -8621,7 +8660,8 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
 		}
 		}
 		ctype = e.type;
 		ctype = e.type;
 
 
-		ProcessPropertyGetAccessor(&e, cexpr);
+		if( ProcessPropertyGetAccessor(&e, cexpr) < 0)
+			return -1;
 
 
 		if( e.type.dataType.IsReference() ) ConvertToVariable(&e);
 		if( e.type.dataType.IsReference() ) ConvertToVariable(&e);
 		ProcessDeferredParams(&e);
 		ProcessDeferredParams(&e);
@@ -8649,8 +8689,10 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
 				return -1;
 				return -1;
 			}
 			}
 
 
-			ProcessPropertyGetAccessor(&le, cexpr->next);
-			ProcessPropertyGetAccessor(&re, cexpr->next->next);
+			if( ProcessPropertyGetAccessor(&le, cexpr->next) < 0 )
+				return -1;
+			if( ProcessPropertyGetAccessor(&re, cexpr->next->next) < 0 )
+				return -1;
 
 
 			bool isExplicitHandle = le.type.isExplicitHandle || re.type.isExplicitHandle;
 			bool isExplicitHandle = le.type.isExplicitHandle || re.type.isExplicitHandle;
 
 
@@ -9131,13 +9173,17 @@ int asCCompiler::CompileExpressionTerm(asCScriptNode *node, asCExprContext *ctx)
 		vnode = vnode->next;
 		vnode = vnode->next;
 
 
 	asCExprContext v(engine);
 	asCExprContext v(engine);
-	int r = CompileExpressionValue(vnode, &v); if( r < 0 ) return r;
+	int r = CompileExpressionValue(vnode, &v); 
+	if( r < 0 ) 
+		return r;
 
 
 	// Compile post fix operators
 	// Compile post fix operators
 	asCScriptNode *pnode = vnode->next;
 	asCScriptNode *pnode = vnode->next;
 	while( pnode )
 	while( pnode )
 	{
 	{
-		r = CompileExpressionPostOp(pnode, &v); if( r < 0 ) return r;
+		r = CompileExpressionPostOp(pnode, &v); 
+		if( r < 0 ) 
+			return r;
 		pnode = pnode->next;
 		pnode = pnode->next;
 	}
 	}
 
 
@@ -9145,7 +9191,9 @@ int asCCompiler::CompileExpressionTerm(asCScriptNode *node, asCExprContext *ctx)
 	pnode = vnode->prev;
 	pnode = vnode->prev;
 	while( pnode )
 	while( pnode )
 	{
 	{
-		r = CompileExpressionPreOp(pnode, &v); if( r < 0 ) return r;
+		r = CompileExpressionPreOp(pnode, &v); 
+		if( r < 0 ) 
+			return r;
 		pnode = pnode->prev;
 		pnode = pnode->prev;
 	}
 	}
 
 
@@ -9201,9 +9249,10 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookupMember(const asCString &name, a
 		// Normal property access
 		// Normal property access
 		r = FindPropertyAccessor(name, &access, 0, 0, true);
 		r = FindPropertyAccessor(name, &access, 0, 0, true);
 	}
 	}
-	if (r < 0) return SL_ERROR;
-	if (access.property_get || access.property_set)
+	if (r <= -3) return SL_ERROR;
+	if (r != 0)
 	{
 	{
+		// The symbol matches getters/setters (though not necessarily a compilable match)
 		MergeExprBytecodeAndType(outResult, &access);
 		MergeExprBytecodeAndType(outResult, &access);
 		outResult->type.dataType.SetTypeInfo(objType);
 		outResult->type.dataType.SetTypeInfo(objType);
 		return SL_CLASSPROPACCESS;
 		return SL_CLASSPROPACCESS;
@@ -9225,7 +9274,7 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookupMember(const asCString &name, a
 	{
 	{
 		asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
 		asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
 		if (f->name == name &&
 		if (f->name == name &&
-			(builder->module->accessMask & f->accessMask))
+			(builder->module->m_accessMask & f->accessMask))
 		{
 		{
 			outResult->type.dataType.SetTypeInfo(objType);
 			outResult->type.dataType.SetTypeInfo(objType);
 			return SL_CLASSMETHOD;
 			return SL_CLASSMETHOD;
@@ -9281,10 +9330,10 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
 	}
 	}
 
 
 	// Is it a class member?
 	// Is it a class member?
-	// This is not accessible by default arg expressions
-	if (!isCompilingDefaultArg && scope == "" && ((objType) || (outFunc && outFunc->objectType)))
+	if (scope == "" && ((objType) || (outFunc && outFunc->objectType)))
 	{
 	{
-		if (name == THIS_TOKEN && !objType)
+		// 'this' is not accessible by default arg expressions
+		if (name == THIS_TOKEN && !objType && !isCompilingDefaultArg)
 		{
 		{
 			asCDataType dt = asCDataType::CreateType(outFunc->objectType, outFunc->IsReadOnly());
 			asCDataType dt = asCDataType::CreateType(outFunc->objectType, outFunc->IsReadOnly());
 
 
@@ -9293,7 +9342,8 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
 			return SL_THISPTR;
 			return SL_THISPTR;
 		}
 		}
 
 
-		if (m_isConstructor && name == SUPER_TOKEN && !objType)
+		// 'super' is not accessible by default arg expressions
+		if (m_isConstructor && name == SUPER_TOKEN && !objType && !isCompilingDefaultArg)
 		{
 		{
 			// If the class is derived from another class, then super can be used to call the base' class constructor
 			// If the class is derived from another class, then super can be used to call the base' class constructor
 			if (outFunc && outFunc->objectType->derivedFrom)
 			if (outFunc && outFunc->objectType->derivedFrom)
@@ -9304,9 +9354,13 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
 		}
 		}
 
 
 		// Look for members in the type
 		// Look for members in the type
-		SYMBOLTYPE r = SymbolLookupMember(name, objType ? objType : outFunc->objectType, outResult);
-		if (r != 0)
-			return r;
+		// class members are only accessible in default arg expressions as post op '.' 
+		if( !isCompilingDefaultArg || (isCompilingDefaultArg && objType) )
+		{
+			SYMBOLTYPE r = SymbolLookupMember(name, objType ? objType : outFunc->objectType, outResult);
+			if (r != 0)
+				return r;
+		}
 	}
 	}
 
 
 	// Recursively search parent namespaces for global entities
 	// Recursively search parent namespaces for global entities
@@ -9420,9 +9474,10 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
 				// Normal property access
 				// Normal property access
 				r = FindPropertyAccessor(name, &access, 0, ns);
 				r = FindPropertyAccessor(name, &access, 0, ns);
 			}
 			}
-			if (r < 0) return SL_ERROR;
-			if (access.property_get || access.property_set)
+			if (r <= -3) return SL_ERROR;
+			if (r != 0)
 			{
 			{
+				// The symbol matches getters/setters (though not necessarily a compilable match)
 				MergeExprBytecodeAndType(outResult, &access);
 				MergeExprBytecodeAndType(outResult, &access);
 				outResult->symbolNamespace = ns;
 				outResult->symbolNamespace = ns;
 				return SL_GLOBALPROPACCESS;
 				return SL_GLOBALPROPACCESS;
@@ -9801,7 +9856,7 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 			{
 			{
 				asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
 				asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
 				if (f->name == name &&
 				if (f->name == name &&
-					(builder->module->accessMask & f->accessMask))
+					(builder->module->m_accessMask & f->accessMask))
 				{
 				{
 					func = f;
 					func = f;
 					break;
 					break;
@@ -10631,7 +10686,8 @@ int asCCompiler::CompileConversion(asCScriptNode *node, asCExprContext *ctx)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	ProcessPropertyGetAccessor(&expr, node);
+	if( ProcessPropertyGetAccessor(&expr, node) < 0 )
+		return -1;
 
 
 	// Don't allow any operators on expressions that take address of class method
 	// Don't allow any operators on expressions that take address of class method
 	if( expr.IsClassMethod() )
 	if( expr.IsClassMethod() )
@@ -10866,7 +10922,7 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
 
 
 	// It is possible that the name is really a constructor
 	// It is possible that the name is really a constructor
 	asCDataType dt;
 	asCDataType dt;
-	dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace);
+	dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, outFunc->objectType);
 	if( dt.IsPrimitive() )
 	if( dt.IsPrimitive() )
 	{
 	{
 		// This is a cast to a primitive type
 		// This is a cast to a primitive type
@@ -10927,9 +10983,13 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
 		if( args.GetLength() == 1 )
 		if( args.GetLength() == 1 )
 		{
 		{
 			asCExprContext conv(engine);
 			asCExprContext conv(engine);
-			conv.type = args[0]->type;
+			conv.Copy(args[0]);
 			asUINT cost = ImplicitConversion(&conv, dt, node->lastChild, asIC_EXPLICIT_VAL_CAST, false);
 			asUINT cost = ImplicitConversion(&conv, dt, node->lastChild, asIC_EXPLICIT_VAL_CAST, false);
 
 
+			// Clean the property_arg in the temporary copy so 
+			// it isn't deleted when conv goes out of scope
+			conv.property_arg = 0;
+
 			// Don't use this if the cost is 0 because it would mean that nothing
 			// Don't use this if the cost is 0 because it would mean that nothing
 			// is done and the script wants a new value to be constructed
 			// is done and the script wants a new value to be constructed
 			if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
 			if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
@@ -10938,7 +10998,8 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
 				dt.MakeReference(true);
 				dt.MakeReference(true);
 
 
 				// Make sure any property accessor is already evaluated
 				// Make sure any property accessor is already evaluated
-				ProcessPropertyGetAccessor(args[0], args[0]->exprNode);
+				if( ProcessPropertyGetAccessor(args[0], args[0]->exprNode) < 0 )
+					return -1;
 
 
 				ImplicitConversion(args[0], dt, node->lastChild, asIC_EXPLICIT_VAL_CAST);
 				ImplicitConversion(args[0], dt, node->lastChild, asIC_EXPLICIT_VAL_CAST);
 
 
@@ -11218,19 +11279,10 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 		symbolType == SL_GLOBALPROPACCESS || symbolType == SL_GLOBALCONST || symbolType == SL_GLOBALVAR || symbolType == SL_ENUMVAL)
 		symbolType == SL_GLOBALPROPACCESS || symbolType == SL_GLOBALCONST || symbolType == SL_GLOBALVAR || symbolType == SL_ENUMVAL)
 	{
 	{
 		// Variables/properties can be used as functions if they have the opCall
 		// Variables/properties can be used as functions if they have the opCall
-		if (!(lookupResult.type.dataType.IsFuncdef() || lookupResult.type.dataType.IsObject()))
-		{
-			// The variable is not a function or object with opCall
-			asCString msg;
-			msg.Format(TXT_NOT_A_FUNC_s_IS_TYPE_s, name.AddressOf(), lookupResult.type.dataType.Format(outFunc->nameSpace).AddressOf());
-			Error(msg, node);
-			return -1;
-		}
-
+	
 		// Compile the variable
 		// Compile the variable
 		// TODO: Take advantage of the known symbol, so it doesn't have to be looked up again
 		// TODO: Take advantage of the known symbol, so it doesn't have to be looked up again
 		localVar = CompileVariableAccess(name, scope, &funcExpr, node, false, objectType);
 		localVar = CompileVariableAccess(name, scope, &funcExpr, node, false, objectType);
-		asASSERT(localVar >= 0);
 		if( localVar < 0 )
 		if( localVar < 0 )
 			return -1;
 			return -1;
 
 
@@ -11264,7 +11316,8 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 				funcExpr.property_ref = ctx->type.dataType.IsReference();
 				funcExpr.property_ref = ctx->type.dataType.IsReference();
 			}
 			}
 			MergeExprBytecodeAndType(ctx, &funcExpr);
 			MergeExprBytecodeAndType(ctx, &funcExpr);
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 			Dereference(ctx, true);
 			Dereference(ctx, true);
 
 
 			objectType = CastToObjectType(funcExpr.type.dataType.GetTypeInfo());
 			objectType = CastToObjectType(funcExpr.type.dataType.GetTypeInfo());
@@ -11277,6 +11330,14 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 
 
 			builder->GetObjectMethodDescriptions("opCall", CastToObjectType(funcExpr.type.dataType.GetTypeInfo()), funcs, objIsConst);
 			builder->GetObjectMethodDescriptions("opCall", CastToObjectType(funcExpr.type.dataType.GetTypeInfo()), funcs, objIsConst);
 		}
 		}
+		else
+		{
+			// The variable is not a function or object with opCall
+			asCString msg;
+			msg.Format(TXT_NOT_A_FUNC_s_IS_TYPE_s, name.AddressOf(), lookupResult.type.dataType.Format(outFunc->nameSpace).AddressOf());
+			Error(msg, node);
+			return -1;
+		}
 	}
 	}
 
 
 	// Is the symbol matching a class method?
 	// Is the symbol matching a class method?
@@ -11373,7 +11434,7 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 	if (symbolType == SL_CLASSTYPE || symbolType == SL_GLOBALTYPE)
 	if (symbolType == SL_CLASSTYPE || symbolType == SL_GLOBALTYPE)
 	{
 	{
 		bool isValid = false;
 		bool isValid = false;
-		asCDataType dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, 0, false, &isValid);
+		asCDataType dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, outFunc->objectType, false, &isValid);
 		if (isValid)
 		if (isValid)
 			return CompileConstructCall(node, ctx);
 			return CompileConstructCall(node, ctx);
 	}
 	}
@@ -11427,7 +11488,8 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 
 
 					if( funcExpr.property_get > 0 )
 					if( funcExpr.property_get > 0 )
 					{
 					{
-						ProcessPropertyGetAccessor(&funcExpr, node);
+						if( ProcessPropertyGetAccessor(&funcExpr, node) < 0 )
+							return -1;
 						Dereference(&funcExpr, true);
 						Dereference(&funcExpr, true);
 					}
 					}
 					else
 					else
@@ -11447,7 +11509,12 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
 					ReleaseTemporaryVariable(tmp, &ctx->bc);
 					ReleaseTemporaryVariable(tmp, &ctx->bc);
 				}
 				}
 
 
-				MakeFunctionCall(ctx, funcs[0], objectType, args, node, false, 0, funcExpr.type.stackOffset);
+				r = MakeFunctionCall(ctx, funcs[0], objectType, args, node, false, 0, funcExpr.type.stackOffset);
+				if( r < 0 )
+				{
+					ctx->type.SetDummy();
+					isOK = false;
+				}
 			}
 			}
 			else
 			else
 				isOK = false;
 				isOK = false;
@@ -11611,7 +11678,8 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asCExprContext *ctx
 		if( opName )
 		if( opName )
 		{
 		{
 			// TODO: Should convert this to something similar to CompileOverloadedDualOperator2
 			// TODO: Should convert this to something similar to CompileOverloadedDualOperator2
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// TODO: If the value isn't const, then first try to find the non const method, and if not found try to find the const method
 			// TODO: If the value isn't const, then first try to find the non const method, and if not found try to find the const method
 
 
@@ -11634,8 +11702,7 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asCExprContext *ctx
 			if( funcs.GetLength() == 1 )
 			if( funcs.GetLength() == 1 )
 			{
 			{
 				asCArray<asCExprContext *> args;
 				asCArray<asCExprContext *> args;
-				MakeFunctionCall(ctx, funcs[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node);
-				return 0;
+				return MakeFunctionCall(ctx, funcs[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node);
 			}
 			}
 			else if( funcs.GetLength() == 0 )
 			else if( funcs.GetLength() == 0 )
 			{
 			{
@@ -11679,7 +11746,8 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asCExprContext *ctx
 		}
 		}
 
 
 
 
-		ProcessPropertyGetAccessor(ctx, node);
+		if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+			return -1;
 
 
 		asCDataType to = ctx->type.dataType;
 		asCDataType to = ctx->type.dataType;
 
 
@@ -11776,7 +11844,8 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asCExprContext *ctx
 				return 0;
 				return 0;
 			}
 			}
 
 
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			ConvertToTempVariable(ctx);
 			ConvertToTempVariable(ctx);
 			asASSERT(!ctx->type.isLValue);
 			asASSERT(!ctx->type.isLValue);
@@ -11791,7 +11860,8 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asCExprContext *ctx
 	}
 	}
 	else if( op == ttBitNot )
 	else if( op == ttBitNot )
 	{
 	{
-		ProcessPropertyGetAccessor(ctx, node);
+		if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+			return -1;
 
 
 		asCDataType to = ctx->type.dataType;
 		asCDataType to = ctx->type.dataType;
 
 
@@ -11956,8 +12026,17 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 	return FindPropertyAccessor(name, ctx, 0, node, ns, isThisAccess);
 	return FindPropertyAccessor(name, ctx, 0, node, ns, isThisAccess);
 }
 }
 
 
+// Returns:
+//   1 = a valid match was found
+//   0 = no matching symbols (or feature disabled)
+//  -1 = ambiguous getters or setters, i.e. multiple methods match symbol name and signature
+//  -2 = mismatching type for getter and setter
+//  -3 = processing error, e.g. out of memory
 int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess)
 int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess)
 {
 {
+	// TODO: With asEP_PROPERTY_ACCESSOR_MODE == 3 this method doesn't need to validate the
+	//       getter/setter as it is done at the time of declaration. Should deprecate the other options
+	
 	if( engine->ep.propertyAccessorMode == 0 )
 	if( engine->ep.propertyAccessorMode == 0 )
 	{
 	{
 		// Property accessors have been disabled by the application
 		// Property accessors have been disabled by the application
@@ -11976,13 +12055,17 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 		// Don't look for property accessors in script classes if the script
 		// Don't look for property accessors in script classes if the script
 		// property accessors have been disabled by the application
 		// property accessors have been disabled by the application
 		if( !(ctx->type.dataType.GetTypeInfo()->flags & asOBJ_SCRIPT_OBJECT) ||
 		if( !(ctx->type.dataType.GetTypeInfo()->flags & asOBJ_SCRIPT_OBJECT) ||
-			engine->ep.propertyAccessorMode == 2 )
+			engine->ep.propertyAccessorMode >= 2 )
 		{
 		{
 			// Check if the object has any methods with the corresponding accessor name(s)
 			// Check if the object has any methods with the corresponding accessor name(s)
 			asCObjectType *ot = CastToObjectType(ctx->type.dataType.GetTypeInfo());
 			asCObjectType *ot = CastToObjectType(ctx->type.dataType.GetTypeInfo());
 			for( asUINT n = 0; n < ot->methods.GetLength(); n++ )
 			for( asUINT n = 0; n < ot->methods.GetLength(); n++ )
 			{
 			{
 				asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
 				asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
+				
+				if( engine->ep.propertyAccessorMode == 3 && !f->IsProperty() )
+					continue;
+				
 				// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 				// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 				if( f->name == getName && (int)f->parameterTypes.GetLength() == (arg?1:0) )
 				if( f->name == getName && (int)f->parameterTypes.GetLength() == (arg?1:0) )
 				{
 				{
@@ -12023,6 +12106,14 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 		for( n = 0; n < funcs.GetLength(); n++ )
 		for( n = 0; n < funcs.GetLength(); n++ )
 		{
 		{
 			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
 			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
+
+			if( engine->ep.propertyAccessorMode == 3 && !f->IsProperty() )
+				continue;
+			
+			// Ignore script functions, if the application has disabled script defined property accessors
+			if( engine->ep.propertyAccessorMode == 1 && f->funcType == asFUNC_SCRIPT )
+				continue;
+			
 			// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 			// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 			if( (int)f->parameterTypes.GetLength() == (arg?1:0) )
 			if( (int)f->parameterTypes.GetLength() == (arg?1:0) )
 			{
 			{
@@ -12043,6 +12134,14 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 		for( n = 0; n < funcs.GetLength(); n++ )
 		for( n = 0; n < funcs.GetLength(); n++ )
 		{
 		{
 			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
 			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
+
+			if( engine->ep.propertyAccessorMode == 3 && !f->IsProperty() )
+				continue;
+			
+			// Ignore script functions, if the application has disabled script defined property accessors
+			if( engine->ep.propertyAccessorMode == 1 && f->funcType == asFUNC_SCRIPT )
+				continue;
+			
 			// TODO: getset: If the parameter is a reference, it must not be an out reference. Should we allow inout ref?
 			// TODO: getset: If the parameter is a reference, it must not be an out reference. Should we allow inout ref?
 			if( (int)f->parameterTypes.GetLength() == (arg?2:1) )
 			if( (int)f->parameterTypes.GetLength() == (arg?2:1) )
 			{
 			{
@@ -12137,7 +12236,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 				PrintMatchingFuncs(funcs, node);
 				PrintMatchingFuncs(funcs, node);
 			}
 			}
 
 
-			return -1;
+			return -2;
 		}
 		}
 	}
 	}
 
 
@@ -12159,7 +12258,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 			realSetId = outFunc->objectType->virtualFunctionTable[setFunc->vfTableIdx]->id;
 			realSetId = outFunc->objectType->virtualFunctionTable[setFunc->vfTableIdx]->id;
 	}
 	}
 
 
-	// Avoid recursive call, by not treating this as a property accessor call.
+	// Avoid recursive call by not treating this as a property accessor call.
 	// This will also allow having the real property with the same name as the accessors.
 	// This will also allow having the real property with the same name as the accessors.
 	if( (isThisAccess || outFunc->objectType == 0) &&
 	if( (isThisAccess || outFunc->objectType == 0) &&
 		((realGetId && realGetId == outFunc->id) ||
 		((realGetId && realGetId == outFunc->id) ||
@@ -12169,15 +12268,6 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 		setId = 0;
 		setId = 0;
 	}
 	}
 
 
-	// Check if the application has disabled script written property accessors
-	if( engine->ep.propertyAccessorMode == 1 )
-	{
-		if( getId && builder->GetFunctionDescription(getId)->funcType != asFUNC_SYSTEM )
-		  getId = 0;
-		if( setId && builder->GetFunctionDescription(setId)->funcType != asFUNC_SYSTEM )
-		  setId = 0;
-	}
-
 	if( getId || setId )
 	if( getId || setId )
 	{
 	{
 		// Property accessors were found, but we don't know which is to be used yet, so
 		// Property accessors were found, but we don't know which is to be used yet, so
@@ -12230,7 +12320,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asCExprContext *ctx
 			if( ctx->property_arg == 0 )
 			if( ctx->property_arg == 0 )
 			{
 			{
 				// Out of memory
 				// Out of memory
-				return -1;
+				return -3;
 			}
 			}
 
 
 			MergeExprBytecodeAndType(ctx->property_arg, arg);
 			MergeExprBytecodeAndType(ctx->property_arg, arg);
@@ -12292,7 +12382,7 @@ int asCCompiler::ProcessPropertySetAccessor(asCExprContext *ctx, asCExprContext
 	}
 	}
 
 
 	// Call the accessor
 	// Call the accessor
-	MakeFunctionCall(ctx, ctx->property_set, func->objectType, args, node);
+	int r = MakeFunctionCall(ctx, ctx->property_set, func->objectType, args, node);
 
 
 	ctx->property_get = 0;
 	ctx->property_get = 0;
 	ctx->property_set = 0;
 	ctx->property_set = 0;
@@ -12302,7 +12392,7 @@ int asCCompiler::ProcessPropertySetAccessor(asCExprContext *ctx, asCExprContext
 		ctx->property_arg = 0;
 		ctx->property_arg = 0;
 	}
 	}
 
 
-	return 0;
+	return r;
 }
 }
 
 
 int asCCompiler::ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprContext *lctx, asCExprContext *rctx, eTokenType op, asCScriptNode *errNode)
 int asCCompiler::ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprContext *lctx, asCExprContext *rctx, eTokenType op, asCScriptNode *errNode)
@@ -12448,18 +12538,17 @@ int asCCompiler::ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprConte
 	return 0;
 	return 0;
 }
 }
 
 
-void asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode *node)
+int asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode *node)
 {
 {
 	// If no property accessor has been prepared then don't do anything
 	// If no property accessor has been prepared then don't do anything
 	if( !ctx->property_get && !ctx->property_set )
 	if( !ctx->property_get && !ctx->property_set )
-		return;
+		return 0;
 
 
 	if( !ctx->property_get )
 	if( !ctx->property_get )
 	{
 	{
 		// Raise error on missing accessor
 		// Raise error on missing accessor
 		Error(TXT_PROPERTY_HAS_NO_GET_ACCESSOR, node);
 		Error(TXT_PROPERTY_HAS_NO_GET_ACCESSOR, node);
-		ctx->type.SetDummy();
-		return;
+		return -1;
 	}
 	}
 
 
 	asCExprValue objType = ctx->type;
 	asCExprValue objType = ctx->type;
@@ -12480,8 +12569,7 @@ void asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode
 			asDELETE(ctx->property_arg, asCExprContext);
 			asDELETE(ctx->property_arg, asCExprContext);
 			ctx->property_arg = 0;
 			ctx->property_arg = 0;
 		}
 		}
-		ctx->type.SetDummy();
-		return;
+		return -1;
 	}
 	}
 
 
 	if( func->objectType )
 	if( func->objectType )
@@ -12498,6 +12586,7 @@ void asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode
 			asCArray<int> funcCandidates;
 			asCArray<int> funcCandidates;
 			funcCandidates.PushLast(ctx->property_get);
 			funcCandidates.PushLast(ctx->property_get);
 			PrintMatchingFuncs(funcCandidates, node);
 			PrintMatchingFuncs(funcCandidates, node);
+			return -1;
 		}
 		}
 	}
 	}
 
 
@@ -12505,7 +12594,7 @@ void asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode
 	bool isExplicitHandle = ctx->type.isExplicitHandle;
 	bool isExplicitHandle = ctx->type.isExplicitHandle;
 
 
 	// Call the accessor
 	// Call the accessor
-	MakeFunctionCall(ctx, ctx->property_get, func->objectType, args, node);
+	int r = MakeFunctionCall(ctx, ctx->property_get, func->objectType, args, node);
 	if( isExplicitHandle )
 	if( isExplicitHandle )
 		ctx->type.isExplicitHandle = true;
 		ctx->type.isExplicitHandle = true;
 
 
@@ -12517,6 +12606,8 @@ void asCCompiler::ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode
 		asDELETE(ctx->property_arg, asCExprContext);
 		asDELETE(ctx->property_arg, asCExprContext);
 		ctx->property_arg = 0;
 		ctx->property_arg = 0;
 	}
 	}
+	
+	return r;
 }
 }
 
 
 int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ctx)
 int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ctx)
@@ -12551,7 +12642,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 		if( opName )
 		if( opName )
 		{
 		{
 			// TODO: Should convert this to something similar to CompileOverloadedDualOperator2
 			// TODO: Should convert this to something similar to CompileOverloadedDualOperator2
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// TODO: If the value isn't const, then first try to find the non const method, and if not found try to find the const method
 			// TODO: If the value isn't const, then first try to find the non const method, and if not found try to find the const method
 
 
@@ -12574,8 +12666,7 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 			if( funcs.GetLength() == 1 )
 			if( funcs.GetLength() == 1 )
 			{
 			{
 				asCArray<asCExprContext *> args;
 				asCArray<asCExprContext *> args;
-				MakeFunctionCall(ctx, funcs[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node);
-				return 0;
+				return MakeFunctionCall(ctx, funcs[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node);
 			}
 			}
 			else if( funcs.GetLength() == 0 )
 			else if( funcs.GetLength() == 0 )
 			{
 			{
@@ -12679,7 +12770,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 	{
 	{
 		if( node->firstChild->nodeType == snIdentifier )
 		if( node->firstChild->nodeType == snIdentifier )
 		{
 		{
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// Get the property name
 			// Get the property name
 			asCString name(&script->code[node->firstChild->tokenPos], node->firstChild->tokenLength);
 			asCString name(&script->code[node->firstChild->tokenPos], node->firstChild->tokenLength);
@@ -12838,7 +12930,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 			}
 			}
 
 
 			// Process the get property accessor
 			// Process the get property accessor
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 
 
 			// Compile function call
 			// Compile function call
 			int r = CompileFunctionCall(node->firstChild, ctx, CastToObjectType(ctx->type.dataType.GetTypeInfo()), ctx->type.dataType.IsObjectConst());
 			int r = CompileFunctionCall(node->firstChild, ctx, CastToObjectType(ctx->type.dataType.GetTypeInfo()), ctx->type.dataType.IsObjectConst());
@@ -12898,7 +12991,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 				return -1;
 				return -1;
 			}
 			}
 
 
-			ProcessPropertyGetAccessor(ctx, node);
+			if( ProcessPropertyGetAccessor(ctx, node) < 0 )
+				return -1;
 		}
 		}
 
 
 		// Compile the expression
 		// Compile the expression
@@ -12934,9 +13028,9 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 						// Add the default values for arguments not explicitly supplied
 						// Add the default values for arguments not explicitly supplied
 						int r = CompileDefaultAndNamedArgs(node, args, funcs[0], objectType);
 						int r = CompileDefaultAndNamedArgs(node, args, funcs[0], objectType);
 
 
-						if( r == 0 )
-							MakeFunctionCall(ctx, funcs[0], objectType, args, node, false, 0, ctx->type.stackOffset);
-						else
+						if( r < 0 )
+							isOK = false;
+						else if( MakeFunctionCall(ctx, funcs[0], objectType, args, node, false, 0, ctx->type.stackOffset) < 0 )
 							isOK = false;
 							isOK = false;
 					}
 					}
 				}
 				}
@@ -12997,6 +13091,7 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 		}
 		}
 
 
 		// Compile arguments
 		// Compile arguments
+		bool isOK = true;
 		asCArray<asCExprContext *> args;
 		asCArray<asCExprContext *> args;
 		asCArray<asSNamedArgument> namedArgs;
 		asCArray<asSNamedArgument> namedArgs;
 		if( CompileArgumentList(node->lastChild, args, namedArgs) >= 0 )
 		if( CompileArgumentList(node->lastChild, args, namedArgs) >= 0 )
@@ -13045,8 +13140,12 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 						ctx->bc.Instr(asBC_PopPtr);
 						ctx->bc.Instr(asBC_PopPtr);
 					}
 					}
 
 
-					MakeFunctionCall(ctx, funcs[0], ctx->type.dataType.IsFuncdef() ? 0 : CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node, false, 0, ctx->type.stackOffset);
+					r = MakeFunctionCall(ctx, funcs[0], ctx->type.dataType.IsFuncdef() ? 0 : CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node, false, 0, ctx->type.stackOffset);
+					if( r < 0 )
+						isOK = false;
 				}
 				}
+				else
+					isOK = false;
 			}
 			}
 		}
 		}
 		else
 		else
@@ -13063,6 +13162,9 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asCExprContext *ct
 			{
 			{
 				asDELETE(namedArgs[n].ctx, asCExprContext);
 				asDELETE(namedArgs[n].ctx, asCExprContext);
 			}
 			}
+			
+		if( !isOK )
+			return -1;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -13166,9 +13268,9 @@ int asCCompiler::MatchArgument(asCScriptFunction *desc, const asCExprContext *ar
 	// Anonymous init lists can only match parameters that can be initialized with a list
 	// Anonymous init lists can only match parameters that can be initialized with a list
 	if (argExpr->IsAnonymousInitList())
 	if (argExpr->IsAnonymousInitList())
 	{
 	{
-		if ((desc->parameterTypes[paramNum].IsReference() && desc->inOutFlags[paramNum] != asTM_INREF) ||
+		if( (desc->parameterTypes[paramNum].IsReference() && (desc->inOutFlags[paramNum] & asTM_INREF) == 0) ||
 			desc->parameterTypes[paramNum].GetBehaviour() == 0 ||
 			desc->parameterTypes[paramNum].GetBehaviour() == 0 ||
-			desc->parameterTypes[paramNum].GetBehaviour()->listFactory == 0)
+			desc->parameterTypes[paramNum].GetBehaviour()->listFactory == 0 )
 		{
 		{
 			return -1;
 			return -1;
 		}
 		}
@@ -13524,7 +13626,7 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 				(!isConst || func->IsReadOnly()) )
 				(!isConst || func->IsReadOnly()) )
 			{
 			{
 				// Make sure the method is accessible by the module
 				// Make sure the method is accessible by the module
-				if( builder->module->accessMask & func->accessMask )
+				if( builder->module->m_accessMask & func->accessMask )
 				{
 				{
 					funcs.PushLast(func->id);
 					funcs.PushLast(func->id);
 				}
 				}
@@ -13563,7 +13665,8 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 			rctx->bc.GetVarsUsed(reservedVariables);
 			rctx->bc.GetVarsUsed(reservedVariables);
 
 
 			// Process the lctx expression as get accessor
 			// Process the lctx expression as get accessor
-			ProcessPropertyGetAccessor(lctx, node);
+			if( ProcessPropertyGetAccessor(lctx, node) < 0 )
+				return -1;
 
 
 			reservedVariables.SetLength(l);
 			reservedVariables.SetLength(l);
 
 
@@ -13655,7 +13758,8 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 			args.PushLast(rctx);
 			args.PushLast(rctx);
 			MergeExprBytecode(ctx, lctx);
 			MergeExprBytecode(ctx, lctx);
 			ctx->type = lctx->type;
 			ctx->type = lctx->type;
-			MakeFunctionCall(ctx, ops[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node);
+			if( MakeFunctionCall(ctx, ops[0], CastToObjectType(ctx->type.dataType.GetTypeInfo()), args, node) < 0 )
+				return -1;
 
 
 			// Rearrange the bytecode so the left argument is computed first
 			// Rearrange the bytecode so the left argument is computed first
 			if (leftToRight)
 			if (leftToRight)
@@ -13683,7 +13787,7 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 	return 0;
 	return 0;
 }
 }
 
 
-void asCCompiler::MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable, int stackOffset, int funcPtrVar)
+int asCCompiler::MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable, int stackOffset, int funcPtrVar)
 {
 {
 	if( objectType )
 	if( objectType )
 		Dereference(ctx, true);
 		Dereference(ctx, true);
@@ -13697,7 +13801,7 @@ void asCCompiler::MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectTyp
 
 
 	int r = PrepareFunctionCall(funcId, &ctx->bc, args);
 	int r = PrepareFunctionCall(funcId, &ctx->bc, args);
 	if (r < 0)
 	if (r < 0)
-		return;
+		return r;
 
 
 	// Verify if any of the args variable offsets are used in the other code.
 	// Verify if any of the args variable offsets are used in the other code.
 	// If they are exchange the offset for a new one
 	// If they are exchange the offset for a new one
@@ -13744,6 +13848,8 @@ void asCCompiler::MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectTyp
 	MoveArgsToStack(funcId, &ctx->bc, args, objectType ? true : false);
 	MoveArgsToStack(funcId, &ctx->bc, args, objectType ? true : false);
 
 
 	PerformFunctionCall(funcId, ctx, false, &args, 0, useVariable, stackOffset, funcPtrVar);
 	PerformFunctionCall(funcId, ctx, false, &args, 0, useVariable, stackOffset, funcPtrVar);
+	
+	return 0;
 }
 }
 
 
 int asCCompiler::CompileOperator(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType op, bool leftToRight)
 int asCCompiler::CompileOperator(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType op, bool leftToRight)
@@ -13792,8 +13898,10 @@ int asCCompiler::CompileOperator(asCScriptNode *node, asCExprContext *lctx, asCE
 		}
 		}
 
 
 		// Process the property get accessors (if any)
 		// Process the property get accessors (if any)
-		ProcessPropertyGetAccessor(lctx, node);
-		ProcessPropertyGetAccessor(rctx, node);
+		if( ProcessPropertyGetAccessor(lctx, node) < 0 )
+			return -1;
+		if( ProcessPropertyGetAccessor(rctx, node) < 0 )
+			return -1;
 
 
 		// Make sure we have two variables or constants
 		// Make sure we have two variables or constants
 		if( lctx->type.dataType.IsReference() ) ConvertToVariableNotIn(lctx, rctx);
 		if( lctx->type.dataType.IsReference() ) ConvertToVariableNotIn(lctx, rctx);
@@ -15367,8 +15475,10 @@ void asCCompiler::CompileBooleanOperator(asCScriptNode *node, asCExprContext *lc
 void asCCompiler::CompileOperatorOnHandles(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType opToken)
 void asCCompiler::CompileOperatorOnHandles(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType opToken)
 {
 {
 	// Process the property accessor as get
 	// Process the property accessor as get
-	ProcessPropertyGetAccessor(lctx, node);
-	ProcessPropertyGetAccessor(rctx, node);
+	if( ProcessPropertyGetAccessor(lctx, node) < 0 )
+		return;
+	if( ProcessPropertyGetAccessor(rctx, node) < 0 )
+		return;
 
 
 	DetermineSingleFunc(lctx, node);
 	DetermineSingleFunc(lctx, node);
 	DetermineSingleFunc(rctx, node);
 	DetermineSingleFunc(rctx, node);
@@ -16300,26 +16410,34 @@ bool asCExprContext::IsAnonymousInitList() const
 	return false;
 	return false;
 }
 }
 
 
+void asCExprContext::Copy(asCExprContext *other)
+{
+	type                = other->type;
+	property_get        = other->property_get;
+	property_set        = other->property_set;
+	property_const      = other->property_const;
+	property_handle     = other->property_handle;
+	property_ref        = other->property_ref;
+	property_arg        = other->property_arg;
+	exprNode            = other->exprNode;
+	methodName          = other->methodName;
+	enumValue           = other->enumValue;
+	isVoidExpression    = other->isVoidExpression;
+	isCleanArg          = other->isCleanArg;
+	isAnonymousInitList = other->isAnonymousInitList;
+	origCode            = other->origCode;
+
+	// Do not copy the origExpr member	
+}
+
 void asCExprContext::Merge(asCExprContext *after)
 void asCExprContext::Merge(asCExprContext *after)
 {
 {
-	type = after->type;
-	property_get = after->property_get;
-	property_set = after->property_set;
-	property_const = after->property_const;
-	property_handle = after->property_handle;
-	property_ref = after->property_ref;
-	property_arg = after->property_arg;
-	exprNode = after->exprNode;
-	methodName = after->methodName;
-	enumValue = after->enumValue;
-	isVoidExpression = after->isVoidExpression;
-	isCleanArg = after->isCleanArg;
-	isAnonymousInitList = after->isAnonymousInitList;
-	origCode = after->origCode;
+	// Overwrite properties with the expression that comes after
+	Copy(after);
 
 
+	// Clean the properties in 'after' that have now moved into 
+	// this structure so they are not cleaned up accidentally
 	after->property_arg = 0;
 	after->property_arg = 0;
-
-	// Do not copy the origExpr member
 }
 }
 
 
 
 

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -149,6 +149,7 @@ struct asCExprContext
 	void SetVoidExpression();
 	void SetVoidExpression();
 	bool IsVoidExpression() const;
 	bool IsVoidExpression() const;
 	void Merge(asCExprContext *after);
 	void Merge(asCExprContext *after);
+	void Copy(asCExprContext *other);
 	void SetAnonymousInitList(asCScriptNode *initList, asCScriptCode *script);
 	void SetAnonymousInitList(asCScriptNode *initList, asCScriptCode *script);
 	bool IsAnonymousInitList() const;
 	bool IsAnonymousInitList() const;
 
 
@@ -169,7 +170,7 @@ struct asCExprContext
 	// TODO: cleanup: use ambiguousName and an enum to say if it is a method, global func, or enum value
 	// TODO: cleanup: use ambiguousName and an enum to say if it is a method, global func, or enum value
 	asCString methodName;
 	asCString methodName;
 	asCString enumValue;
 	asCString enumValue;
-	asSNameSpace *symbolNamespace; // The namespace in which the ambigious symbol was found
+	asSNameSpace *symbolNamespace; // The namespace in which the ambiguous symbol was found
 	bool isAnonymousInitList; // Set to true if the expression is an init list for which the type has not yet been determined
 	bool isAnonymousInitList; // Set to true if the expression is an init list for which the type has not yet been determined
 };
 };
 
 
@@ -281,7 +282,7 @@ protected:
 
 
 	// Helper functions
 	// Helper functions
 	void ConvertToPostFix(asCScriptNode *expr, asCArray<asCScriptNode *> &postfix);
 	void ConvertToPostFix(asCScriptNode *expr, asCArray<asCScriptNode *> &postfix);
-	void ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode *node);
+	int  ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node);
 	int  ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprContext *lctx, asCExprContext *rctx, eTokenType op, asCScriptNode *errNode);
 	int  ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprContext *lctx, asCExprContext *rctx, eTokenType op, asCScriptNode *errNode);
 	int  FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
 	int  FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
@@ -297,7 +298,7 @@ protected:
 	int  MatchArgument(asCScriptFunction *desc, const asCExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
 	int  MatchArgument(asCScriptFunction *desc, const asCExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
 	void PerformFunctionCall(int funcId, asCExprContext *out, bool isConstructor = false, asCArray<asCExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void PerformFunctionCall(int funcId, asCExprContext *out, bool isConstructor = false, asCArray<asCExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args, bool addOneToOffset);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args, bool addOneToOffset);
-	void MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
+	int  MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
 	int  PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args);
 	int  PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args);
 	void AfterFunctionCall(int funcId, asCArray<asCExprContext*> &args, asCExprContext *ctx, bool deferAll);
 	void AfterFunctionCall(int funcId, asCArray<asCExprContext*> &args, asCExprContext *ctx, bool deferAll);
 	void ProcessDeferredParams(asCExprContext *ctx);
 	void ProcessDeferredParams(asCExprContext *ctx);
@@ -423,6 +424,9 @@ protected:
 	// so they can be released upon completion, whether the compilation was successful or not.
 	// so they can be released upon completion, whether the compilation was successful or not.
 	asCArray<void*>       usedStringConstants;
 	asCArray<void*>       usedStringConstants;
 
 
+	// This array holds the nodes that have been allocated temporarily
+	asCArray<asCScriptNode*> nodesToFreeUponComplete;
+
 	bool isCompilingDefaultArg;
 	bool isCompilingDefaultArg;
 	bool isProcessingDeferredParams;
 	bool isProcessingDeferredParams;
 	int  noCodeOutput;
 	int  noCodeOutput;

+ 75 - 41
Source/ThirdParty/AngelScript/source/as_config.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2016 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -28,8 +28,7 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Yao Wei Tjong, Skrylar and Ramil Sattarov for Urho3D
-
+// Modified for Urho3D
 
 
 //
 //
 // as_config.h
 // as_config.h
@@ -178,8 +177,6 @@
 // Oracle Solaris Studio (previously known as Sun CC compiler)
 // Oracle Solaris Studio (previously known as Sun CC compiler)
 // __SUNPRO_CC is defined
 // __SUNPRO_CC is defined
 
 
-// Urho3D: Added description of how to identify LCC and MCST lcc compilers
-
 // Local (or Little) C Compiler
 // Local (or Little) C Compiler
 // __LCC__ is defined
 // __LCC__ is defined
 // __e2k__ is not defined
 // __e2k__ is not defined
@@ -219,6 +216,9 @@
 // AS_ARM
 // AS_ARM
 // Use assembler code for the ARM CPU family
 // Use assembler code for the ARM CPU family
 
 
+// AS_ARM64
+// Use assembler code for the ARM64/AArch64 CPU family
+
 // AS_SOFTFP
 // AS_SOFTFP
 // Use to tell compiler that ARM soft-float ABI
 // Use to tell compiler that ARM soft-float ABI
 // should be used instead of ARM hard-float ABI
 // should be used instead of ARM hard-float ABI
@@ -238,13 +238,12 @@
 // AS_SPARC
 // AS_SPARC
 // Define this for SPARC CPU family
 // Define this for SPARC CPU family
 
 
-// Urho3D: Added identifier for definition e2k architecture
-
 // AS_E2K
 // AS_E2K
 // Define this for MCST Elbrus 2000 CPU family
 // Define this for MCST Elbrus 2000 CPU family
 
 
 
 
 
 
+
 //
 //
 // Target systems
 // Target systems
 //--------------------------------
 //--------------------------------
@@ -375,6 +374,14 @@
 #define AS_NO_THISCALL_FUNCTOR_METHOD
 #define AS_NO_THISCALL_FUNCTOR_METHOD
 
 
 
 
+// Emscripten compiler toolchain
+// ref: https://emscripten.org/
+#if defined(__EMSCRIPTEN__)
+  #define AS_MAX_PORTABILITY
+#endif
+
+
+
 // Embarcadero C++Builder
 // Embarcadero C++Builder
 #if defined(__BORLANDC__)
 #if defined(__BORLANDC__)
  #ifndef _Windows
  #ifndef _Windows
@@ -498,7 +505,7 @@
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJ_MIN_SIZE 3
 			#define AS_LARGE_OBJ_MIN_SIZE 3
-			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY | asOBJ_APP_CLASS_MORE_CONSTRUCTORS)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 		#endif
 		#endif
 	#endif
 	#endif
@@ -518,12 +525,18 @@
 		#endif
 		#endif
 	#endif
 	#endif
 
 
+	#if defined(_M_ARM64)
+		#define AS_ARM64
+
+		// TODO: MORE HERE
+	#endif
+
 	#ifndef COMPLEX_MASK
 	#ifndef COMPLEX_MASK
 		#define COMPLEX_MASK (asOBJ_APP_ARRAY)
 		#define COMPLEX_MASK (asOBJ_APP_ARRAY)
 	#endif
 	#endif
 
 
 	#ifndef COMPLEX_RETURN_MASK
 	#ifndef COMPLEX_RETURN_MASK
-		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY | asOBJ_APP_CLASS_MORE_CONSTRUCTORS)
 	#endif
 	#endif
 
 
 	#define UNREACHABLE_RETURN
 	#define UNREACHABLE_RETURN
@@ -823,7 +836,7 @@
 			#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4
 			#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4
 				#define AS_MINGW47
 				#define AS_MINGW47
 			#endif
 			#endif
-
+		
 			#if (__clang_major__ == 3 && __clang_minor__ > 4) || __clang_major > 3
 			#if (__clang_major__ == 3 && __clang_minor__ > 4) || __clang_major > 3
 				#define AS_MINGW47
 				#define AS_MINGW47
 			#endif
 			#endif
@@ -878,9 +891,9 @@
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
 		#elif defined(__ARMEL__) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__)
 		#elif defined(__ARMEL__) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__)
-			// arm
+			// arm 
 
 
-			// The assembler code currently doesn't support arm v4, nor 64bit (v8)
+			// The assembler code currently doesn't support arm v4
 			#if !defined(__ARM_ARCH_4__) && !defined(__ARM_ARCH_4T__) && !defined(__LP64__)
 			#if !defined(__ARM_ARCH_4__) && !defined(__ARM_ARCH_4T__) && !defined(__LP64__)
 				#define AS_ARM
 				#define AS_ARM
 
 
@@ -910,25 +923,35 @@
 				#endif
 				#endif
 
 
 				// Verify if soft-float or hard-float ABI is used
 				// Verify if soft-float or hard-float ABI is used
-				#if defined(__SOFTFP__) && __SOFTFP__ == 1
+				#if (defined(__SOFTFP__) && __SOFTFP__ == 1) || defined(__ARM_PCS)
 					// -ffloat-abi=softfp or -ffloat-abi=soft
 					// -ffloat-abi=softfp or -ffloat-abi=soft
 					#define AS_SOFTFP
 					#define AS_SOFTFP
 				#endif
 				#endif
 
 
 				// Tested with both hard float and soft float abi
 				// Tested with both hard float and soft float abi
 				#undef AS_NO_THISCALL_FUNCTOR_METHOD
 				#undef AS_NO_THISCALL_FUNCTOR_METHOD
+			#elif defined(__LP64__) || defined(__aarch64__)
+				#define AS_ARM64
+
+				#undef STDCALL
+				#define STDCALL
+
+				#undef GNU_STYLE_VIRTUAL_METHOD
+				#undef AS_NO_THISCALL_FUNCTOR_METHOD
+
+				#define HAS_128_BIT_PRIMITIVES
+
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY
+				#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+				#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+
+				#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+				#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+				#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
 
 
-            // Urho3D - Add support for aarch64-linux-gnu
-            #elif defined(__aarch64__)
-                // arm64
-
-                // AngelScript currently doesn't support native calling
-                // for 64bit ARM processors so it's necessary to turn on
-                // portability mode
-                #define AS_MAX_PORTABILITY
-                // STDCALL is not available on ARM
-                #undef STDCALL
-                #define STDCALL
+				#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
+				#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE    5
+				#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE  5
 			#endif
 			#endif
 
 
 		#elif defined(__mips__)
 		#elif defined(__mips__)
@@ -956,13 +979,13 @@
 		#elif defined(__PPC64__)
 		#elif defined(__PPC64__)
 			// PPC 64bit
 			// PPC 64bit
 
 
-			// The code in as_callfunc_ppc_64.cpp was built for PS3 and XBox 360, that
+			// The code in as_callfunc_ppc_64.cpp was built for PS3 and XBox 360, that 
 			// although use 64bit PPC only uses 32bit pointers.
 			// although use 64bit PPC only uses 32bit pointers.
 			// TODO: Add support for native calling conventions on Linux with PPC 64bit
 			// TODO: Add support for native calling conventions on Linux with PPC 64bit
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
-		// Urho3D - Add support for e2k-linux-gnu
 		#elif defined(__e2k__)
 		#elif defined(__e2k__)
 			// 64bit MCST Elbrus 2000
 			// 64bit MCST Elbrus 2000
+			// ref: https://en.wikipedia.org/wiki/Elbrus_2000
 			#define AS_E2K
 			#define AS_E2K
 			// AngelScript currently doesn't support native calling
 			// AngelScript currently doesn't support native calling
 			// for MCST Elbrus 2000 processor so it's necessary to turn on
 			// for MCST Elbrus 2000 processor so it's necessary to turn on
@@ -992,7 +1015,7 @@
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
-		#elif defined(__LP64__)
+		#elif defined(__x86_64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
 			#define HAS_128_BIT_PRIMITIVES
 			#define HAS_128_BIT_PRIMITIVES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
@@ -1099,7 +1122,8 @@
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
-// Urho3D - Add support for Android Intel x86_64 and Android ARM 64bit
+
+		// Urho3D: Add support for Android Intel x86_64 and Android ARM 64bit
 		#elif defined(__LP64__) && !defined(__aarch64__)
 		#elif defined(__LP64__) && !defined(__aarch64__)
 			// Android Intel x86_64 (same config as Linux x86_64). Tested with Intel x86_64 Atom System Image.
 			// Android Intel x86_64 (same config as Linux x86_64). Tested with Intel x86_64 Atom System Image.
 			#define AS_X64_GCC
 			#define AS_X64_GCC
@@ -1111,13 +1135,15 @@
 			// STDCALL is not available on 64bit Linux
 			// STDCALL is not available on 64bit Linux
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
-        #elif defined(__aarch64__)
+		#elif defined(__aarch64__)
 			// Doesn't support native calling for Android ARM 64bit yet
 			// Doesn't support native calling for Android ARM 64bit yet
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
 			// STDCALL is not available on ARM
 			// STDCALL is not available on ARM
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
-        #elif defined(__mips__)
+		// Urho3D: end
+
+		#elif defined(__mips__)
 			#define AS_MIPS
 			#define AS_MIPS
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
@@ -1142,25 +1168,28 @@
 	// Haiku OS
 	// Haiku OS
 	#elif __HAIKU__
 	#elif __HAIKU__
 		#define AS_HAIKU
 		#define AS_HAIKU
-		// Only x86-32 is currently supported by Haiku, but they do plan to support
-		// x86-64 and PowerPC in the future, so should go ahead and check the platform
-		// for future compatibility
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 			#define AS_X86
 			#define AS_X86
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+		#elif defined(__x86_64__)
+			#define AS_X64_GCC
+			#define HAS_128_BIT_PRIMITIVES
+			#define SPLIT_OBJS_BY_MEMBER_TYPES
+			#undef COMPLEX_MASK
+			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
+			#define AS_LARGE_OBJS_PASSED_BY_REF
+			#define AS_LARGE_OBJ_MIN_SIZE 5
+			#undef STDCALL
+			#define STDCALL
 		#else
 		#else
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
 		#endif
 		#endif
 
 
-		#define AS_POSIX_THREADS
-		#if !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
-			// Only with GCC 4.1 was the atomic instructions available
-			#define AS_NO_ATOMIC
-		#endif
-
 	// Illumos
 	// Illumos
 	#elif defined(__sun)
 	#elif defined(__sun)
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
@@ -1250,7 +1279,7 @@
 
 
 // If there are no current support for native calling
 // If there are no current support for native calling
 // conventions, then compile with AS_MAX_PORTABILITY
 // conventions, then compile with AS_MAX_PORTABILITY
-#if (!defined(AS_X86) && !defined(AS_SH4) && !defined(AS_MIPS) && !defined(AS_PPC) && !defined(AS_PPC_64) && !defined(AS_XENON) && !defined(AS_X64_GCC) && !defined(AS_X64_MSVC) && !defined(AS_ARM) && !defined(AS_X64_MINGW))
+#if (!defined(AS_X86) && !defined(AS_SH4) && !defined(AS_MIPS) && !defined(AS_PPC) && !defined(AS_PPC_64) && !defined(AS_XENON) && !defined(AS_X64_GCC) && !defined(AS_X64_MSVC) && !defined(AS_ARM) && !defined(AS_ARM64) && !defined(AS_X64_MINGW))
 	#ifndef AS_MAX_PORTABILITY
 	#ifndef AS_MAX_PORTABILITY
 		#define AS_MAX_PORTABILITY
 		#define AS_MAX_PORTABILITY
 	#endif
 	#endif
@@ -1271,8 +1300,13 @@
 
 
 
 
 // The assert macro
 // The assert macro
-// Urho3D - use __ANDROID__ define emitted by all Android compiler toolchains
+
+// Urho3D: commented out original
+//#if defined(ANDROID)
+
+// Urho3D: use __ANDROID__ define emitted by all Android compiler toolchains
 #if defined(ANDROID) || defined(__ANDROID__)
 #if defined(ANDROID) || defined(__ANDROID__)
+
 	#if defined(AS_DEBUG)
 	#if defined(AS_DEBUG)
 		#include <android/log.h>
 		#include <android/log.h>
 		#include <stdlib.h>
 		#include <stdlib.h>

+ 1 - 2
Source/ThirdParty/AngelScript/source/as_configgroup.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2017 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -130,7 +130,6 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 		{
 		{
 			globalProps[n]->Release();
 			globalProps[n]->Release();
 
 
-			// TODO: global: Should compact the registeredGlobalProps array
 			engine->registeredGlobalProps.Erase(index);
 			engine->registeredGlobalProps.Erase(index);
 		}
 		}
 	}
 	}

+ 21 - 2
Source/ThirdParty/AngelScript/source/as_context.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2019 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -4404,7 +4404,23 @@ void asCContext::ExecuteNext()
 
 
 				// Call the method
 				// Call the method
 				m_callingSystemFunction = m_engine->scriptFunctions[i];
 				m_callingSystemFunction = m_engine->scriptFunctions[i];
-				void *ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
+				void *ptr = 0;
+#ifdef AS_NO_EXCEPTIONS
+				ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
+#else
+				// This try/catch block is to catch potential exception that may 
+				// be thrown by the registered function. 
+				try
+				{
+					ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
+				}
+				catch (...)
+				{
+					// Convert the exception to a script exception so the VM can 
+					// properly report the error to the application and then clean up
+					HandleAppException();
+				}
+#endif
 				m_callingSystemFunction = 0;
 				m_callingSystemFunction = 0;
 				*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
 				*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
 			}
 			}
@@ -4816,6 +4832,9 @@ void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLe
 						}
 						}
 					}
 					}
 					break;
 					break;
+				case asOBJ_VARDECL: // A variable was declared
+					// We don't really care about the variable declarations at this moment
+					break;
 				}
 				}
 			}
 			}
 
 

+ 14 - 2
Source/ThirdParty/AngelScript/source/as_memory.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2016 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -38,7 +38,7 @@
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
+#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
 #include <malloc.h>
 #include <malloc.h>
 #endif
 #endif
 
 
@@ -241,6 +241,11 @@ void asCMemoryMgr::FreeScriptNode(void *ptr)
 		scriptNodePool.Allocate(100, 0);
 		scriptNodePool.Allocate(100, 0);
 
 
 	scriptNodePool.PushLast(ptr);
 	scriptNodePool.PushLast(ptr);
+	
+#ifdef AS_DEBUG
+	// clear the memory to facilitate identification of use after free
+	memset(ptr, 0xCDCDCDCD, sizeof(asCScriptNode));
+#endif
 
 
 	LEAVECRITICALSECTION(cs);
 	LEAVECRITICALSECTION(cs);
 }
 }
@@ -249,6 +254,8 @@ void asCMemoryMgr::FreeScriptNode(void *ptr)
 
 
 void *asCMemoryMgr::AllocByteInstruction()
 void *asCMemoryMgr::AllocByteInstruction()
 {
 {
+	// This doesn't need a critical section because, only one compilation is allowed at a time
+	
 	if( byteInstructionPool.GetLength() )
 	if( byteInstructionPool.GetLength() )
 		return byteInstructionPool.PopLast();
 		return byteInstructionPool.PopLast();
 
 
@@ -266,6 +273,11 @@ void asCMemoryMgr::FreeByteInstruction(void *ptr)
 		byteInstructionPool.Allocate(100, 0);
 		byteInstructionPool.Allocate(100, 0);
 
 
 	byteInstructionPool.PushLast(ptr);
 	byteInstructionPool.PushLast(ptr);
+	
+#ifdef AS_DEBUG
+	// clear the memory to facilitate identification of use after free
+	memset(ptr, 0xCDCDCDCD, sizeof(asCByteInstruction));
+#endif
 }
 }
 
 
 #endif // AS_NO_COMPILER
 #endif // AS_NO_COMPILER

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 249 - 203
Source/ThirdParty/AngelScript/source/as_module.cpp


+ 39 - 24
Source/ThirdParty/AngelScript/source/as_module.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2017 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -182,59 +182,74 @@ public:
 
 
 	int  CallInit(asIScriptContext *ctx);
 	int  CallInit(asIScriptContext *ctx);
 	void CallExit();
 	void CallExit();
+	int  InitGlobalProp(asCGlobalProperty *prop, asIScriptContext *ctx);
 
 
 	void JITCompile();
 	void JITCompile();
 
 
 #ifndef AS_NO_COMPILER
 #ifndef AS_NO_COMPILER
 	int  AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isGlobalFunction = false, asSFunctionTraits funcTraits = asSFunctionTraits(), asSNameSpace *ns = 0);
 	int  AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isGlobalFunction = false, asSFunctionTraits funcTraits = asSFunctionTraits(), asSNameSpace *ns = 0);
 	int  AddScriptFunction(asCScriptFunction *func);
 	int  AddScriptFunction(asCScriptFunction *func);
-	int  AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName);
+	int  AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSFunctionTraits funcTraits, asSNameSpace *ns, const asCString &moduleName);
 	int  AddFuncDef(const asCString &name, asSNameSpace *ns, asCObjectType *parent);
 	int  AddFuncDef(const asCString &name, asSNameSpace *ns, asCObjectType *parent);
 #endif
 #endif
 
 
 	int                GetNextImportedFunctionId();
 	int                GetNextImportedFunctionId();
 	asCScriptFunction *GetImportedFunction(int funcId) const;
 	asCScriptFunction *GetImportedFunction(int funcId) const;
-	asCTypeInfo       *GetType(const char *type, asSNameSpace *ns);
-	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns);
+	asCTypeInfo       *GetType(const asCString &type, asSNameSpace *ns) const;
+	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns) const;
 	asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
 	asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
 	void               UninitializeGlobalProp(asCGlobalProperty *prop);
 	void               UninitializeGlobalProp(asCGlobalProperty *prop);
-
-	asCString name;
-
-	asCScriptEngine  *engine;
-	asCBuilder       *builder;
-	asCArray<asPWORD> userData;
-	asDWORD           accessMask;
-	asSNameSpace     *defaultNamespace;
+	
+	// Adds the class type to the module. The module assumes ownership of the reference without increasing it
+	void               AddClassType(asCObjectType*);
+	// Adds the enum type to the module. The module assumes ownership of the reference without increasing it
+	void               AddEnumType(asCEnumType*);
+	// Adds the typedef to the module. The module assumes ownership of the reference without increasing it
+	void               AddTypeDef(asCTypedefType*);
+	// Adds the funcdef to the module. The module assumes ownership of the reference without increasing it
+	void               AddFuncDef(asCFuncdefType*);
+	// Replaces an existing funcdef with another (used for shared funcdefs). Doesn't add or release refCounts
+	void               ReplaceFuncDef(asCFuncdefType *oldType, asCFuncdefType *newType);
+
+	asCString         m_name;
+	asCScriptEngine  *m_engine;
+	asCBuilder       *m_builder;
+	asCArray<asPWORD> m_userData;
+	asDWORD           m_accessMask;
+	asSNameSpace     *m_defaultNamespace;
 
 
 	// This array holds all functions, class members, factories, etc that were compiled with the module.
 	// This array holds all functions, class members, factories, etc that were compiled with the module.
 	// These references hold an internal reference to the function object.
 	// These references hold an internal reference to the function object.
-	asCArray<asCScriptFunction *>     scriptFunctions; // increases ref count
+	asCArray<asCScriptFunction *>     m_scriptFunctions; // increases ref count
 	// This array holds global functions declared in the module. These references are not counted,
 	// This array holds global functions declared in the module. These references are not counted,
 	// as the same pointer is always present in the scriptFunctions array too.
 	// as the same pointer is always present in the scriptFunctions array too.
-	asCSymbolTable<asCScriptFunction> globalFunctions; // doesn't increase ref count
+	asCSymbolTable<asCScriptFunction> m_globalFunctions; // doesn't increase ref count
 	// This array holds imported functions in the module.
 	// This array holds imported functions in the module.
-	asCArray<sBindInfo *>             bindInformations; // increases ref count
+	asCArray<sBindInfo *>             m_bindInformations; // increases ref count
 	// This array holds template instance types created for the module's object types
 	// This array holds template instance types created for the module's object types
-	asCArray<asCObjectType*>          templateInstances; // increases ref count
+	asCArray<asCObjectType*>          m_templateInstances; // increases ref count
 
 
 	// This array holds the global variables declared in the script
 	// This array holds the global variables declared in the script
-	asCSymbolTable<asCGlobalProperty> scriptGlobals; // increases ref count
-	bool                              isGlobalVarInitialized;
+	asCSymbolTable<asCGlobalProperty> m_scriptGlobals; // increases ref count
+	bool                              m_isGlobalVarInitialized;
 
 
 	// This array holds class and interface types
 	// This array holds class and interface types
-	asCArray<asCObjectType*>       classTypes; // increases ref count
+	asCArray<asCObjectType*>       m_classTypes; // increases ref count
 	// This array holds enum types
 	// This array holds enum types
-	asCArray<asCEnumType*>         enumTypes; // increases ref count
+	asCArray<asCEnumType*>         m_enumTypes; // increases ref count
 	// This array holds typedefs
 	// This array holds typedefs
-	asCArray<asCTypedefType*>      typeDefs; // increases ref count
+	asCArray<asCTypedefType*>      m_typeDefs; // increases ref count
 	// This array holds the funcdefs declared in the module
 	// This array holds the funcdefs declared in the module
-	asCArray<asCFuncdefType*>      funcDefs; // increases ref count
+	asCArray<asCFuncdefType*>      m_funcDefs; // increases ref count
+
+	// This map contains all the types (also contained in the arrays above) for quick lookup
+	// TODO: memory: Can we eliminate the arrays above?
+	asCMap<asSNameSpaceNamePair, asCTypeInfo*> m_typeLookup; // doesn't increase ref count
 
 
 	// This array holds types that have been explicitly declared with 'external'
 	// This array holds types that have been explicitly declared with 'external'
-	asCArray<asCTypeInfo*>       externalTypes; // doesn't increase ref count
+	asCArray<asCTypeInfo*>       m_externalTypes; // doesn't increase ref count
 	// This array holds functions that have been explicitly declared with 'external'
 	// This array holds functions that have been explicitly declared with 'external'
-	asCArray<asCScriptFunction*> externalFunctions; // doesn't increase ref count
+	asCArray<asCScriptFunction*> m_externalFunctions; // doesn't increase ref count
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 50 - 29
Source/ThirdParty/AngelScript/source/as_parser.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -388,7 +388,7 @@ asCScriptNode *asCParser::ParseFunctionDefinition()
 	if( t1.type == ttConst )
 	if( t1.type == ttConst )
 		node->AddChildLast(ParseToken(ttConst));
 		node->AddChildLast(ParseToken(ttConst));
 
 
-	// Parse an optional 'explicit'
+	// Parse optional attributes
 	ParseMethodAttributes(node);
 	ParseMethodAttributes(node);
 
 
 	return node;
 	return node;
@@ -444,7 +444,7 @@ asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 	return node;
 	return node;
 }
 }
 
 
-// BNF:4: TYPE          ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | '@' }
+// BNF:4: TYPE          ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | ('@' ['const']) }
 asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, bool allowAuto)
 asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, bool allowAuto)
 {
 {
 	asCScriptNode *node = CreateNode(snDataType);
 	asCScriptNode *node = CreateNode(snDataType);
@@ -503,6 +503,14 @@ asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, boo
 		{
 		{
 			node->AddChildLast(ParseToken(ttHandle));
 			node->AddChildLast(ParseToken(ttHandle));
 			if( isSyntaxError ) return node;
 			if( isSyntaxError ) return node;
+
+			GetToken(&t);
+			RewindTo(&t);
+			if( t.type == ttConst )
+			{
+				node->AddChildLast(ParseToken(ttConst));
+				if( isSyntaxError ) return node;
+			}
 		}
 		}
 
 
 		GetToken(&t);
 		GetToken(&t);
@@ -1210,6 +1218,7 @@ bool asCParser::IdentifierIs(const sToken &t, const char *str)
 	return script->TokenEquals(t.pos, t.length, str);
 	return script->TokenEquals(t.pos, t.length, str);
 }
 }
 
 
+// BNF:6: FUNCATTR      ::= {'override' | 'final' | 'explicit' | 'property'}
 void asCParser::ParseMethodAttributes(asCScriptNode *funcNode)
 void asCParser::ParseMethodAttributes(asCScriptNode *funcNode)
 {
 {
 	sToken t1;
 	sToken t1;
@@ -1221,7 +1230,8 @@ void asCParser::ParseMethodAttributes(asCScriptNode *funcNode)
 
 
 		if( IdentifierIs(t1, FINAL_TOKEN) || 
 		if( IdentifierIs(t1, FINAL_TOKEN) || 
 			IdentifierIs(t1, OVERRIDE_TOKEN) || 
 			IdentifierIs(t1, OVERRIDE_TOKEN) || 
-			IdentifierIs(t1, EXPLICIT_TOKEN) )
+			IdentifierIs(t1, EXPLICIT_TOKEN) ||
+			IdentifierIs(t1, PROPERTY_TOKEN) )
 			funcNode->AddChildLast(ParseIdentifier());
 			funcNode->AddChildLast(ParseIdentifier());
 		else
 		else
 			break;
 			break;
@@ -1250,7 +1260,7 @@ bool asCParser::IsType(sToken &nextToken)
 		if (t1.type == ttScope)
 		if (t1.type == ttScope)
 			GetToken(&t1);
 			GetToken(&t1);
 
 
-		// The type may be preceeded with a multilevel scope
+		// The type may be preceded with a multilevel scope
 		GetToken(&t2);
 		GetToken(&t2);
 		while (t1.type == ttIdentifier)
 		while (t1.type == ttIdentifier)
 		{
 		{
@@ -1304,7 +1314,15 @@ bool asCParser::IsType(sToken &nextToken)
 	GetToken(&t2);
 	GetToken(&t2);
 	while (t2.type == ttHandle || t2.type == ttAmp || t2.type == ttOpenBracket)
 	while (t2.type == ttHandle || t2.type == ttAmp || t2.type == ttOpenBracket)
 	{
 	{
-		if (t2.type == ttOpenBracket)
+		if( t2.type == ttHandle )
+		{
+			// A handle can optionally be read-only
+			sToken t3;
+			GetToken(&t3);
+			if(t3.type != ttConst )
+				RewindTo(&t3);
+		}
+		else if (t2.type == ttOpenBracket)
 		{
 		{
 			GetToken(&t2);
 			GetToken(&t2);
 			if (t2.type != ttCloseBracket)
 			if (t2.type != ttCloseBracket)
@@ -2305,7 +2323,7 @@ int asCParser::ParseExpression(asCScriptCode *in_script)
 	return 0;
 	return 0;
 }
 }
 
 
-// BNF:1: IMPORT        ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST 'from' STRING ';'
+// BNF:1: IMPORT        ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST FUNCATTR 'from' STRING ';'
 asCScriptNode *asCParser::ParseImport()
 asCScriptNode *asCParser::ParseImport()
 {
 {
 	asCScriptNode *node = CreateNode(snImport);
 	asCScriptNode *node = CreateNode(snImport);
@@ -2721,10 +2739,10 @@ bool asCParser::IsVarDecl()
 	}
 	}
 	if( t1.type == ttOpenParanthesis )
 	if( t1.type == ttOpenParanthesis )
 	{
 	{
-		// If the closing paranthesis is followed by a statement
-		// block or end-of-file, then treat it as a function. A
-		// function decl may have nested paranthesis so we need to
-		// check for this too.
+		// If the closing parenthesis is followed by a statement block, 
+		// function decorator, or end-of-file, then treat it as a function. 
+		// A function decl may have nested parenthesis so we need to check 
+		// for this too.
 		int nest = 0;
 		int nest = 0;
 		while( t1.type != ttEnd )
 		while( t1.type != ttEnd )
 		{
 		{
@@ -2748,7 +2766,9 @@ bool asCParser::IsVarDecl()
 		{
 		{
 			GetToken(&t1);
 			GetToken(&t1);
 			RewindTo(&t);
 			RewindTo(&t);
-			if( t1.type == ttStartStatementBlock || t1.type == ttEnd )
+			if( t1.type == ttStartStatementBlock || 
+				t1.type == ttIdentifier || // function decorator
+				t1.type == ttEnd )
 				return false;
 				return false;
 		}
 		}
 
 
@@ -2884,21 +2904,22 @@ bool asCParser::IsFuncDecl(bool isMethod)
 				GetToken(&t1);
 				GetToken(&t1);
 				if( t1.type != ttConst )
 				if( t1.type != ttConst )
 					RewindTo(&t1);
 					RewindTo(&t1);
+			}
 
 
-				// A class method may also have any number of additional inheritance behavior specifiers
-				for( ; ; )
+			// A function may also have any number of additional attributes
+			for( ; ; )
+			{
+				GetToken(&t1);
+				if( !IdentifierIs(t1, FINAL_TOKEN) && 
+					!IdentifierIs(t1, OVERRIDE_TOKEN) &&
+					!IdentifierIs(t1, EXPLICIT_TOKEN) &&
+					!IdentifierIs(t1, PROPERTY_TOKEN) )
 				{
 				{
-					GetToken(&t1);
-					if( !IdentifierIs(t1, FINAL_TOKEN) && 
-						!IdentifierIs(t1, OVERRIDE_TOKEN) &&
-						!IdentifierIs(t1, EXPLICIT_TOKEN) )
-					{
-						RewindTo(&t1);
-						break;
-					}
+					RewindTo(&t1);
+					break;
 				}
 				}
 			}
 			}
-
+			
 			GetToken(&t1);
 			GetToken(&t1);
 			RewindTo(&t);
 			RewindTo(&t);
 			if( t1.type == ttStartStatementBlock )
 			if( t1.type == ttStartStatementBlock )
@@ -2965,7 +2986,7 @@ asCScriptNode *asCParser::ParseFuncDef()
 	return node;
 	return node;
 }
 }
 
 
-// BNF:1: FUNC          ::= {'shared' | 'external'} ['private' | 'protected'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] {'override' | 'final' | 'explicit'} (';' | STATBLOCK)
+// BNF:1: FUNC          ::= {'shared' | 'external'} ['private' | 'protected'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] FUNCATTR (';' | STATBLOCK)
 asCScriptNode *asCParser::ParseFunction(bool isMethod)
 asCScriptNode *asCParser::ParseFunction(bool isMethod)
 {
 {
 	asCScriptNode *node = CreateNode(snFunction);
 	asCScriptNode *node = CreateNode(snFunction);
@@ -3041,12 +3062,12 @@ asCScriptNode *asCParser::ParseFunction(bool isMethod)
 		// Is the method a const?
 		// Is the method a const?
 		if( t1.type == ttConst )
 		if( t1.type == ttConst )
 			node->AddChildLast(ParseToken(ttConst));
 			node->AddChildLast(ParseToken(ttConst));
-
-		// TODO: Should support abstract methods, in which case no statement block should be provided
-		ParseMethodAttributes(node);
-		if( isSyntaxError ) return node;
 	}
 	}
 
 
+	// TODO: Should support abstract methods, in which case no statement block should be provided
+	ParseMethodAttributes(node);
+	if( isSyntaxError ) return node;
+
 	// External shared functions must be ended with ';'
 	// External shared functions must be ended with ';'
 	GetToken(&t1);
 	GetToken(&t1);
 	RewindTo(&t1);
 	RewindTo(&t1);
@@ -3101,7 +3122,7 @@ asCScriptNode *asCParser::ParseInterfaceMethod()
 	return node;
 	return node;
 }
 }
 
 
-// BNF:1: VIRTPROP      ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] [('override' | 'final')] (STATBLOCK | ';')} '}'
+// BNF:1: VIRTPROP      ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] FUNCATTR (STATBLOCK | ';')} '}'
 asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
 asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
 {
 {
 	asCScriptNode *node = CreateNode(snVirtualProperty);
 	asCScriptNode *node = CreateNode(snVirtualProperty);

+ 202 - 116
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -90,12 +90,12 @@ int asCReader::Read(bool *wasDebugInfoStripped)
 		// Make sure none of the loaded functions attempt to release
 		// Make sure none of the loaded functions attempt to release
 		// references that have not yet been increased
 		// references that have not yet been increased
 		asUINT i;
 		asUINT i;
-		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
-				if( module->scriptFunctions[i]->scriptData )
-					module->scriptFunctions[i]->scriptData->byteCode.SetLength(0);
+		for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
+			if( !dontTranslate.MoveTo(0, module->m_scriptFunctions[i]) )
+				if( module->m_scriptFunctions[i]->scriptData )
+					module->m_scriptFunctions[i]->scriptData->byteCode.SetLength(0);
 
 
-		asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
+		asCSymbolTable<asCGlobalProperty>::iterator it = module->m_scriptGlobals.List();
 		for( ; it; it++ )
 		for( ; it; it++ )
 			if( (*it)->GetInitFunc() )
 			if( (*it)->GetInitFunc() )
 				if( (*it)->GetInitFunc()->scriptData )
 				if( (*it)->GetInitFunc()->scriptData )
@@ -156,7 +156,7 @@ int asCReader::ReadInner()
 
 
 	// Read enums
 	// Read enums
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->enumTypes.Allocate(count, false);
+	module->m_enumTypes.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		asCEnumType *et = asNEW(asCEnumType)(engine);
 		asCEnumType *et = asNEW(asCEnumType)(engine);
@@ -216,10 +216,10 @@ int asCReader::ReadInner()
 			// Set this module as the owner
 			// Set this module as the owner
 			et->module = module;
 			et->module = module;
 		}
 		}
-		module->enumTypes.PushLast(et);
+		module->AddEnumType(et);
 
 
 		if (isExternal)
 		if (isExternal)
-			module->externalTypes.PushLast(et);
+			module->m_externalTypes.PushLast(et);
 
 
 		ReadTypeDeclaration(et, 2);
 		ReadTypeDeclaration(et, 2);
 	}
 	}
@@ -229,7 +229,7 @@ int asCReader::ReadInner()
 	// classTypes[]
 	// classTypes[]
 	// First restore the structure names, then the properties
 	// First restore the structure names, then the properties
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->classTypes.Allocate(count, false);
+	module->m_classTypes.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
@@ -290,17 +290,17 @@ int asCReader::ReadInner()
 			// Set this module as the owner
 			// Set this module as the owner
 			ot->module = module;
 			ot->module = module;
 		}
 		}
-		module->classTypes.PushLast(ot);
+		module->AddClassType(ot);
 
 
 		if (isExternal)
 		if (isExternal)
-			module->externalTypes.PushLast(ot);
+			module->m_externalTypes.PushLast(ot);
 	}
 	}
 
 
 	if( error ) return asERROR;
 	if( error ) return asERROR;
 
 
 	// Read func defs
 	// Read func defs
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->funcDefs.Allocate(count, false);
+	module->m_funcDefs.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		bool isNew, isExternal;
 		bool isNew, isExternal;
@@ -312,7 +312,7 @@ int asCReader::ReadInner()
 			asCFuncdefType *fdt = funcDef->funcdefType;
 			asCFuncdefType *fdt = funcDef->funcdefType;
 			fdt->module = module;
 			fdt->module = module;
 
 
-			module->funcDefs.PushLast(fdt);
+			module->AddFuncDef(fdt);
 			engine->funcDefs.PushLast(fdt);
 			engine->funcDefs.PushLast(fdt);
 
 
 			// TODO: clean up: This is also done by the builder. It should probably be moved to a method in the module
 			// TODO: clean up: This is also done by the builder. It should probably be moved to a method in the module
@@ -334,11 +334,11 @@ int asCReader::ReadInner()
 						f2->funcdef->IsSignatureExceptNameEqual(funcDef) )
 						f2->funcdef->IsSignatureExceptNameEqual(funcDef) )
 					{
 					{
 						// Replace our funcdef for the existing one
 						// Replace our funcdef for the existing one
-						module->funcDefs[module->funcDefs.IndexOf(fdt)] = f2;
+						module->ReplaceFuncDef(fdt, f2);
 						f2->AddRefInternal();
 						f2->AddRefInternal();
 
 
 						if (isExternal)
 						if (isExternal)
-							module->externalTypes.PushLast(f2);
+							module->m_externalTypes.PushLast(f2);
 
 
 						engine->funcDefs.RemoveValue(fdt);
 						engine->funcDefs.RemoveValue(fdt);
 
 
@@ -378,31 +378,31 @@ int asCReader::ReadInner()
 	}
 	}
 
 
 	// Read interface methods
 	// Read interface methods
-	for( i = 0; i < module->classTypes.GetLength() && !error; i++ )
+	for( i = 0; i < module->m_classTypes.GetLength() && !error; i++ )
 	{
 	{
-		if( module->classTypes[i]->IsInterface() )
-			ReadTypeDeclaration(module->classTypes[i], 2);
+		if( module->m_classTypes[i]->IsInterface() )
+			ReadTypeDeclaration(module->m_classTypes[i], 2);
 	}
 	}
 
 
 	// Read class methods and behaviours
 	// Read class methods and behaviours
-	for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
+	for( i = 0; i < module->m_classTypes.GetLength() && !error; ++i )
 	{
 	{
-		if( !module->classTypes[i]->IsInterface() )
-			ReadTypeDeclaration(module->classTypes[i], 2);
+		if( !module->m_classTypes[i]->IsInterface() )
+			ReadTypeDeclaration(module->m_classTypes[i], 2);
 	}
 	}
 
 
 	// Read class properties
 	// Read class properties
-	for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
+	for( i = 0; i < module->m_classTypes.GetLength() && !error; ++i )
 	{
 	{
-		if( !module->classTypes[i]->IsInterface() )
-			ReadTypeDeclaration(module->classTypes[i], 3);
+		if( !module->m_classTypes[i]->IsInterface() )
+			ReadTypeDeclaration(module->m_classTypes[i], 3);
 	}
 	}
 
 
 	if( error ) return asERROR;
 	if( error ) return asERROR;
 
 
 	// Read typedefs
 	// Read typedefs
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->typeDefs.Allocate(count, false);
+	module->m_typeDefs.Allocate(count, false);
 	for( i = 0; i < count && !error; i++ )
 	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		asCTypedefType *td = asNEW(asCTypedefType)(engine);
 		asCTypedefType *td = asNEW(asCTypedefType)(engine);
@@ -415,7 +415,7 @@ int asCReader::ReadInner()
 		bool isExternal = false;
 		bool isExternal = false;
 		ReadTypeDeclaration(td, 1, &isExternal);
 		ReadTypeDeclaration(td, 1, &isExternal);
 		td->module = module;
 		td->module = module;
-		module->typeDefs.PushLast(td);
+		module->AddTypeDef(td);
 		ReadTypeDeclaration(td, 2);
 		ReadTypeDeclaration(td, 2);
 	}
 	}
 
 
@@ -428,7 +428,7 @@ int asCReader::ReadInner()
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
 		Error(TXT_INVALID_BYTECODE_d);
 		Error(TXT_INVALID_BYTECODE_d);
 	}
 	}
-	module->scriptGlobals.Allocate(count, false);
+	module->m_scriptGlobals.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		ReadGlobalProperty();
 		ReadGlobalProperty();
@@ -438,7 +438,7 @@ int asCReader::ReadInner()
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	for( i = 0; i < count && !error; ++i )
 	for( i = 0; i < count && !error; ++i )
 	{
 	{
-		size_t len = module->scriptFunctions.GetLength();
+		size_t len = module->m_scriptFunctions.GetLength();
 		bool isNew, isExternal;
 		bool isNew, isExternal;
 		func = ReadFunction(isNew, true, true, true, &isExternal);
 		func = ReadFunction(isNew, true, true, true, &isExternal);
 		if( func == 0 )
 		if( func == 0 )
@@ -448,7 +448,7 @@ int asCReader::ReadInner()
 		}
 		}
 
 
 		// Is the function shared and was it created now?
 		// Is the function shared and was it created now?
-		if( func->IsShared() && len != module->scriptFunctions.GetLength() )
+		if( func->IsShared() && len != module->m_scriptFunctions.GetLength() )
 		{
 		{
 			// If the function already existed in another module, then
 			// If the function already existed in another module, then
 			// we need to replace it with previously existing one
 			// we need to replace it with previously existing one
@@ -462,7 +462,7 @@ int asCReader::ReadInner()
 					realFunc->IsSignatureEqual(func) )
 					realFunc->IsSignatureEqual(func) )
 				{
 				{
 					// Replace the recently created function with the pre-existing function
 					// Replace the recently created function with the pre-existing function
-					module->scriptFunctions[module->scriptFunctions.GetLength()-1] = realFunc;
+					module->m_scriptFunctions[module->m_scriptFunctions.GetLength()-1] = realFunc;
 					realFunc->AddRefInternal();
 					realFunc->AddRefInternal();
 					savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 					savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 					engine->RemoveScriptFunction(func);
 					engine->RemoveScriptFunction(func);
@@ -471,7 +471,7 @@ int asCReader::ReadInner()
 					dontTranslate.Insert(realFunc, true);
 					dontTranslate.Insert(realFunc, true);
 
 
 					if (isExternal)
 					if (isExternal)
-						module->externalFunctions.PushLast(realFunc);
+						module->m_externalFunctions.PushLast(realFunc);
 
 
 					// Release the function, but make sure nothing else is released
 					// Release the function, but make sure nothing else is released
 					func->id = 0;
 					func->id = 0;
@@ -507,7 +507,7 @@ int asCReader::ReadInner()
 			// we're just re-reading the references to know which goes into the globalFunctions array
 			// we're just re-reading the references to know which goes into the globalFunctions array
 			asASSERT( !isNew );
 			asASSERT( !isNew );
 
 
-			module->globalFunctions.Put(func);
+			module->m_globalFunctions.Put(func);
 		}
 		}
 		else
 		else
 			Error(TXT_INVALID_BYTECODE_d);
 			Error(TXT_INVALID_BYTECODE_d);
@@ -517,7 +517,7 @@ int asCReader::ReadInner()
 
 
 	// bindInformations[]
 	// bindInformations[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->bindInformations.Allocate(count, false);
+	module->m_bindInformations.Allocate(count, false);
 	for( i = 0; i < count && !error; ++i )
 	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		sBindInfo *info = asNEW(sBindInfo);
 		sBindInfo *info = asNEW(sBindInfo);
@@ -548,7 +548,7 @@ int asCReader::ReadInner()
 		}
 		}
 		ReadString(&info->importFromModule);
 		ReadString(&info->importFromModule);
 		info->boundFunctionId = -1;
 		info->boundFunctionId = -1;
-		module->bindInformations.PushLast(info);
+		module->m_bindInformations.PushLast(info);
 	}
 	}
 
 
 	if( error ) return asERROR;
 	if( error ) return asERROR;
@@ -622,11 +622,11 @@ int asCReader::ReadInner()
 
 
 	// Update the loaded bytecode to point to the correct types, property offsets,
 	// Update the loaded bytecode to point to the correct types, property offsets,
 	// function ids, etc. This is basically a linking stage.
 	// function ids, etc. This is basically a linking stage.
-	for( i = 0; i < module->scriptFunctions.GetLength() && !error; i++ )
-		if( module->scriptFunctions[i]->funcType == asFUNC_SCRIPT )
-			TranslateFunction(module->scriptFunctions[i]);
+	for( i = 0; i < module->m_scriptFunctions.GetLength() && !error; i++ )
+		if( module->m_scriptFunctions[i]->funcType == asFUNC_SCRIPT )
+			TranslateFunction(module->m_scriptFunctions[i]);
 
 
-	asCSymbolTable<asCGlobalProperty>::iterator globIt = module->scriptGlobals.List();
+	asCSymbolTable<asCGlobalProperty>::iterator globIt = module->m_scriptGlobals.List();
 	while( globIt && !error )
 	while( globIt && !error )
 	{
 	{
 		asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
 		asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
@@ -638,11 +638,11 @@ int asCReader::ReadInner()
 	if( error ) return asERROR;
 	if( error ) return asERROR;
 
 
 	// Add references for all functions (except for the pre-existing shared code)
 	// Add references for all functions (except for the pre-existing shared code)
-	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-		if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
-			module->scriptFunctions[i]->AddReferences();
+	for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
+		if( !dontTranslate.MoveTo(0, module->m_scriptFunctions[i]) )
+			module->m_scriptFunctions[i]->AddReferences();
 
 
-	globIt = module->scriptGlobals.List();
+	globIt = module->m_scriptGlobals.List();
 	while( globIt )
 	while( globIt )
 	{
 	{
 		asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
 		asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
@@ -721,9 +721,9 @@ void asCReader::ReadUsedFunctions()
 			{
 			{
 				if( func.funcType == asFUNC_IMPORTED )
 				if( func.funcType == asFUNC_IMPORTED )
 				{
 				{
-					for( asUINT i = 0; i < module->bindInformations.GetLength(); i++ )
+					for( asUINT i = 0; i < module->m_bindInformations.GetLength(); i++ )
 					{
 					{
-						asCScriptFunction *f = module->bindInformations[i]->importedFunctionSignature;
+						asCScriptFunction *f = module->m_bindInformations[i]->importedFunctionSignature;
 						if( func.objectType != f->objectType ||
 						if( func.objectType != f->objectType ||
 							func.funcType != f->funcType ||
 							func.funcType != f->funcType ||
 							func.nameSpace != f->nameSpace ||
 							func.nameSpace != f->nameSpace ||
@@ -736,7 +736,7 @@ void asCReader::ReadUsedFunctions()
 				}
 				}
 				else if( func.funcType == asFUNC_FUNCDEF )
 				else if( func.funcType == asFUNC_FUNCDEF )
 				{
 				{
-					const asCArray<asCFuncdefType *> &funcs = module->funcDefs;
+					const asCArray<asCFuncdefType *> &funcs = module->m_funcDefs;
 					for( asUINT i = 0; i < funcs.GetLength(); i++ )
 					for( asUINT i = 0; i < funcs.GetLength(); i++ )
 					{
 					{
 						asCScriptFunction *f = funcs[i]->funcdef;
 						asCScriptFunction *f = funcs[i]->funcdef;
@@ -757,9 +757,9 @@ void asCReader::ReadUsedFunctions()
 					// TODO: optimize: Global functions should be searched for in module->globalFunctions
 					// TODO: optimize: Global functions should be searched for in module->globalFunctions
 					// TODO: optimize: funcdefs should be searched for in module->funcDefs
 					// TODO: optimize: funcdefs should be searched for in module->funcDefs
 					// TODO: optimize: object methods should be searched for directly in the object type
 					// TODO: optimize: object methods should be searched for directly in the object type
-					for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
+					for( asUINT i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
 					{
 					{
-						asCScriptFunction *f = module->scriptFunctions[i];
+						asCScriptFunction *f = module->m_scriptFunctions[i];
 						if( func.objectType != f->objectType ||
 						if( func.objectType != f->objectType ||
 							func.funcType != f->funcType ||
 							func.funcType != f->funcType ||
 							func.nameSpace != f->nameSpace ||
 							func.nameSpace != f->nameSpace ||
@@ -922,17 +922,6 @@ void asCReader::ReadUsedFunctions()
 								usedFunctions[n] = f;
 								usedFunctions[n] = f;
 						}
 						}
 					}
 					}
-					else if( func.name == "$beh4" )
-					{
-						// This is a list factory, so check the return type's list factory
-						asCObjectType *objType = CastToObjectType(func.returnType.GetTypeInfo());
-						if( objType )
-						{
-							asCScriptFunction *f = engine->scriptFunctions[objType->beh.listFactory];
-							if( f && func.IsSignatureExceptNameAndObjectTypeEqual(f) )
-								usedFunctions[n] = f;
-						}
-					}
 					else if( func.name == "$dlgte" )
 					else if( func.name == "$dlgte" )
 					{
 					{
 						// This is the delegate factory
 						// This is the delegate factory
@@ -940,6 +929,11 @@ void asCReader::ReadUsedFunctions()
 						asASSERT( f && func.IsSignatureEqual(f) );
 						asASSERT( f && func.IsSignatureEqual(f) );
 						usedFunctions[n] = f;
 						usedFunctions[n] = f;
 					}
 					}
+					else
+					{
+						// Must match one of the above cases
+						asASSERT(false);
+					}
 				}
 				}
 				else if( func.objectType == 0 )
 				else if( func.objectType == 0 )
 				{
 				{
@@ -1205,7 +1199,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	if( func->funcType == asFUNC_SCRIPT )
 	if( func->funcType == asFUNC_SCRIPT )
 	{
 	{
 		// Skip this for external shared entities
 		// Skip this for external shared entities
-		if (module->externalTypes.IndexOf(func->objectType) >= 0)
+		if (module->m_externalTypes.IndexOf(func->objectType) >= 0)
 		{
 		{
 			// Replace with the real function from the existing entity
 			// Replace with the real function from the existing entity
 			isNew = false;
 			isNew = false;
@@ -1429,10 +1423,110 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 		fdt->parentClass = parentClass;
 		fdt->parentClass = parentClass;
 	}
 	}
 
 
+	// Methods loaded for shared objects, owned by other modules should not be created as new functions
+	if( func->objectType && func->objectType->module != module )
+	{
+		// Return the real function from the object
+		asCScriptFunction *realFunc = 0;
+		bool found = false;
+		if( func->funcType == asFUNC_SCRIPT )
+		{
+			realFunc = engine->scriptFunctions[func->objectType->beh.destruct];
+			if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
+			{
+				found = true;
+			}
+			for( asUINT n = 0; !found && n < func->objectType->beh.constructors.GetLength(); n++ )
+			{
+				realFunc = engine->scriptFunctions[func->objectType->beh.constructors[n]];
+				if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
+				{
+					found = true;
+					break;
+				}
+			}	
+			for( asUINT n = 0; !found && n < func->objectType->beh.factories.GetLength(); n++ )
+			{
+				realFunc = engine->scriptFunctions[func->objectType->beh.factories[n]];
+				if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
+				{
+					found = true;
+					break;
+				}
+			}	
+			for( asUINT n = 0; !found && n < func->objectType->methods.GetLength(); n++ )
+			{
+				realFunc = engine->scriptFunctions[func->objectType->methods[n]];
+				if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
+				{
+					found = true;
+					break;
+				}
+			}
+			for( asUINT n = 0; !found && n < func->objectType->virtualFunctionTable.GetLength(); n++ )
+			{
+				realFunc = func->objectType->virtualFunctionTable[n];
+				if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
+				{
+					found = true;
+					break;
+				}
+			}
+		}
+		else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
+		{
+			// If the loaded function is a virtual function, then look for the identical virtual function in the methods array
+			for( asUINT n = 0; n < func->objectType->methods.GetLength(); n++ )
+			{
+				realFunc = engine->scriptFunctions[func->objectType->methods[n]];
+				if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
+				{
+					asASSERT( func->vfTableIdx == realFunc->vfTableIdx );
+					found = true;
+					break;
+				}
+			}
+		}
+
+		if( found )
+		{
+			// as this is an existing function it shouldn't be translated as if just loaded
+			dontTranslate.Insert(realFunc, true);
+
+			// update the saved functions for future references
+			savedFunctions[savedFunctions.GetLength() - 1] = realFunc;
+
+			if( realFunc->funcType == asFUNC_VIRTUAL && addToModule )
+			{
+				// Virtual methods must be added to the module's script functions array, 
+				// even if they are not owned by the module
+				module->m_scriptFunctions.PushLast(realFunc);
+				realFunc->AddRefInternal();		
+			}				
+		}
+		else
+		{
+			asCString str;
+			str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, func->objectType->GetName());
+			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+			
+			Error(TXT_INVALID_BYTECODE_d);
+			savedFunctions.PopLast();
+			realFunc = 0;
+		}
+
+		// Destroy the newly created function instance since it has been replaced by an existing function
+		isNew = false;
+		func->DestroyHalfCreated();
+		
+		// As it is an existing function it shouldn't be added to the module or the engine
+		return realFunc;
+	}	
+
 	if( addToModule )
 	if( addToModule )
 	{
 	{
 		// The refCount is already 1
 		// The refCount is already 1
-		module->scriptFunctions.PushLast(func);
+		module->m_scriptFunctions.PushLast(func);
 		func->module = module;
 		func->module = module;
 	}
 	}
 	if( addToEngine )
 	if( addToEngine )
@@ -1513,7 +1607,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 	else if( phase == 2 )
 	else if( phase == 2 )
 	{
 	{
 		// external shared types doesn't store this
 		// external shared types doesn't store this
-		if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
+		if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
 			return;
 			return;
 
 
 		if( type->flags & asOBJ_ENUM )
 		if( type->flags & asOBJ_ENUM )
@@ -1668,8 +1762,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 							func->scriptData->byteCode.SetLength(0);
 							func->scriptData->byteCode.SetLength(0);
 							func->ReleaseInternal();
 							func->ReleaseInternal();
 						}
 						}
-						module->scriptFunctions.PushLast(realFunc);
-						realFunc->AddRefInternal();
 						dontTranslate.Insert(realFunc, true);
 						dontTranslate.Insert(realFunc, true);
 					}
 					}
 				}
 				}
@@ -1703,8 +1795,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 									if( savedFunctions[savedFunctions.GetLength()-1] == func )
 									if( savedFunctions[savedFunctions.GetLength()-1] == func )
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									found = true;
 									found = true;
-									module->scriptFunctions.PushLast(realFunc);
-									realFunc->AddRefInternal();
 									dontTranslate.Insert(realFunc, true);
 									dontTranslate.Insert(realFunc, true);
 									break;
 									break;
 								}
 								}
@@ -1754,8 +1844,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 									if( savedFunctions[savedFunctions.GetLength()-1] == func )
 									if( savedFunctions[savedFunctions.GetLength()-1] == func )
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									found = true;
 									found = true;
-									module->scriptFunctions.PushLast(realFunc);
-									realFunc->AddRefInternal();
 									dontTranslate.Insert(realFunc, true);
 									dontTranslate.Insert(realFunc, true);
 									break;
 									break;
 								}
 								}
@@ -1813,8 +1901,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 								if( savedFunctions[savedFunctions.GetLength()-1] == func )
 								if( savedFunctions[savedFunctions.GetLength()-1] == func )
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 								found = true;
 								found = true;
-								module->scriptFunctions.PushLast(realFunc);
-								realFunc->AddRefInternal();
 								dontTranslate.Insert(realFunc, true);
 								dontTranslate.Insert(realFunc, true);
 								break;
 								break;
 							}
 							}
@@ -1829,6 +1915,8 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 						if( isNew )
 						if( isNew )
 						{
 						{
 							// Destroy the function without releasing any references
 							// Destroy the function without releasing any references
+							if( func->id == func->signatureId )
+								engine->signatureIds.RemoveValue(func);
 							func->id = 0;
 							func->id = 0;
 							if( func->scriptData )
 							if( func->scriptData )
 								func->scriptData->byteCode.SetLength(0);
 								func->scriptData->byteCode.SetLength(0);
@@ -1878,8 +1966,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 								if( savedFunctions[savedFunctions.GetLength()-1] == func )
 								if( savedFunctions[savedFunctions.GetLength()-1] == func )
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 								found = true;
 								found = true;
-								module->scriptFunctions.PushLast(realFunc);
-								realFunc->AddRefInternal();
 								dontTranslate.Insert(realFunc, true);
 								dontTranslate.Insert(realFunc, true);
 								break;
 								break;
 							}
 							}
@@ -1916,7 +2002,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
 	else if( phase == 3 )
 	else if( phase == 3 )
 	{
 	{
 		// external shared types doesn't store this
 		// external shared types doesn't store this
-		if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
+		if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
 			return;
 			return;
 
 
 		asCObjectType *ot = CastToObjectType(type);
 		asCObjectType *ot = CastToObjectType(type);
@@ -2612,7 +2698,7 @@ void asCReader::ReadUsedGlobalProps()
 		// Find the real property
 		// Find the real property
 		asCGlobalProperty *globProp = 0;
 		asCGlobalProperty *globProp = 0;
 		if( moduleProp )
 		if( moduleProp )
-			globProp = module->scriptGlobals.GetFirst(nameSpace, name);
+			globProp = module->m_scriptGlobals.GetFirst(nameSpace, name);
 		else
 		else
 			globProp = engine->registeredGlobalProps.GetFirst(nameSpace, name);
 			globProp = engine->registeredGlobalProps.GetFirst(nameSpace, name);
 
 
@@ -2871,9 +2957,9 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 		{
 		{
 			// Translate the function id
 			// Translate the function id
 			asUINT *fid = (asUINT*)&bc[n+1];
 			asUINT *fid = (asUINT*)&bc[n+1];
-			if( *fid < module->bindInformations.GetLength() )
+			if( *fid < module->m_bindInformations.GetLength() )
 			{
 			{
-				sBindInfo *bi = module->bindInformations[*fid];
+				sBindInfo *bi = module->m_bindInformations[*fid];
 				if( bi )
 				if( bi )
 					*fid = bi->importedFunctionSignature->id;
 					*fid = bi->importedFunctionSignature->id;
 				else
 				else
@@ -3817,12 +3903,12 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("store enums");
 		TimeIt("store enums");
 
 
-		count = (asUINT)module->enumTypes.GetLength();
+		count = (asUINT)module->m_enumTypes.GetLength();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
 		{
 		{
-			WriteTypeDeclaration(module->enumTypes[i], 1);
-			WriteTypeDeclaration(module->enumTypes[i], 2);
+			WriteTypeDeclaration(module->m_enumTypes[i], 1);
+			WriteTypeDeclaration(module->m_enumTypes[i], 2);
 		}
 		}
 	}
 	}
 
 
@@ -3830,12 +3916,12 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("type declarations");
 		TimeIt("type declarations");
 
 
-		count = (asUINT)module->classTypes.GetLength();
+		count = (asUINT)module->m_classTypes.GetLength();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
 		{
 		{
 			// Store only the name of the class/interface types
 			// Store only the name of the class/interface types
-			WriteTypeDeclaration(module->classTypes[i], 1);
+			WriteTypeDeclaration(module->m_classTypes[i], 1);
 		}
 		}
 	}
 	}
 
 
@@ -3843,21 +3929,21 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("func defs");
 		TimeIt("func defs");
 
 
-		count = (asUINT)module->funcDefs.GetLength();
+		count = (asUINT)module->m_funcDefs.GetLength();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
-			WriteFunction(module->funcDefs[i]->funcdef);
+			WriteFunction(module->m_funcDefs[i]->funcdef);
 	}
 	}
 
 
 	// Now store all interface methods
 	// Now store all interface methods
 	{
 	{
 		TimeIt("interface methods");
 		TimeIt("interface methods");
 
 
-		count = (asUINT)module->classTypes.GetLength();
+		count = (asUINT)module->m_classTypes.GetLength();
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
 		{
 		{
-			if( module->classTypes[i]->IsInterface() )
-				WriteTypeDeclaration(module->classTypes[i], 2);
+			if( module->m_classTypes[i]->IsInterface() )
+				WriteTypeDeclaration(module->m_classTypes[i], 2);
 		}
 		}
 	}
 	}
 
 
@@ -3867,8 +3953,8 @@ int asCWriter::Write()
 
 
 		for( i = 0; i < count; ++i )
 		for( i = 0; i < count; ++i )
 		{
 		{
-			if( !module->classTypes[i]->IsInterface() )
-				WriteTypeDeclaration(module->classTypes[i], 2);
+			if( !module->m_classTypes[i]->IsInterface() )
+				WriteTypeDeclaration(module->m_classTypes[i], 2);
 		}
 		}
 	}
 	}
 
 
@@ -3878,8 +3964,8 @@ int asCWriter::Write()
 
 
 		for( i = 0; i < count; ++i )
 		for( i = 0; i < count; ++i )
 		{
 		{
-			if( !module->classTypes[i]->IsInterface() )
-				WriteTypeDeclaration(module->classTypes[i], 3);
+			if( !module->m_classTypes[i]->IsInterface() )
+				WriteTypeDeclaration(module->m_classTypes[i], 3);
 		}
 		}
 	}
 	}
 
 
@@ -3887,12 +3973,12 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("type defs");
 		TimeIt("type defs");
 
 
-		count = (asUINT)module->typeDefs.GetLength();
+		count = (asUINT)module->m_typeDefs.GetLength();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
 		{
 		{
-			WriteTypeDeclaration(module->typeDefs[i], 1);
-			WriteTypeDeclaration(module->typeDefs[i], 2);
+			WriteTypeDeclaration(module->m_typeDefs[i], 1);
+			WriteTypeDeclaration(module->m_typeDefs[i], 2);
 		}
 		}
 	}
 	}
 
 
@@ -3900,9 +3986,9 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("script globals");
 		TimeIt("script globals");
 
 
-		count = (asUINT)module->scriptGlobals.GetSize();
+		count = (asUINT)module->m_scriptGlobals.GetSize();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
-		asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
+		asCSymbolTable<asCGlobalProperty>::iterator it = module->m_scriptGlobals.List();
 		for( ; it; it++ )
 		for( ; it; it++ )
 			WriteGlobalProperty(*it);
 			WriteGlobalProperty(*it);
 	}
 	}
@@ -3912,21 +3998,21 @@ int asCWriter::Write()
 		TimeIt("scriptFunctions");
 		TimeIt("scriptFunctions");
 
 
 		count = 0;
 		count = 0;
-		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-			if( module->scriptFunctions[i]->objectType == 0 )
+		for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
+			if( module->m_scriptFunctions[i]->objectType == 0 )
 				count++;
 				count++;
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
-		for( i = 0; i < module->scriptFunctions.GetLength(); ++i )
-			if( module->scriptFunctions[i]->objectType == 0 )
-				WriteFunction(module->scriptFunctions[i]);
+		for( i = 0; i < module->m_scriptFunctions.GetLength(); ++i )
+			if( module->m_scriptFunctions[i]->objectType == 0 )
+				WriteFunction(module->m_scriptFunctions[i]);
 	}
 	}
 
 
 	// globalFunctions[]
 	// globalFunctions[]
 	{
 	{
 		TimeIt("globalFunctions");
 		TimeIt("globalFunctions");
 
 
-		count = (int)module->globalFunctions.GetSize();
-		asCSymbolTable<asCScriptFunction>::iterator funcIt = module->globalFunctions.List();
+		count = (int)module->m_globalFunctions.GetSize();
+		asCSymbolTable<asCScriptFunction>::iterator funcIt = module->m_globalFunctions.List();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		while( funcIt )
 		while( funcIt )
 		{
 		{
@@ -3939,12 +4025,12 @@ int asCWriter::Write()
 	{
 	{
 		TimeIt("bindInformations");
 		TimeIt("bindInformations");
 
 
-		count = (asUINT)module->bindInformations.GetLength();
+		count = (asUINT)module->m_bindInformations.GetLength();
 		WriteEncodedInt64(count);
 		WriteEncodedInt64(count);
 		for( i = 0; i < count; ++i )
 		for( i = 0; i < count; ++i )
 		{
 		{
-			WriteFunction(module->bindInformations[i]->importedFunctionSignature);
-			WriteString(&module->bindInformations[i]->importFromModule);
+			WriteFunction(module->m_bindInformations[i]->importedFunctionSignature);
+			WriteString(&module->m_bindInformations[i]->importFromModule);
 		}
 		}
 	}
 	}
 
 
@@ -4024,9 +4110,9 @@ void asCWriter::WriteUsedFunctions()
 			// Is the function from the module or the application?
 			// Is the function from the module or the application?
 			c = func->module ? 'm' : 'a';
 			c = func->module ? 'm' : 'a';
 
 
-			// Functions and methods that are shared and not owned by the module can be
-			// stored as 's' to tell the reader that these are received from other modules.
-			if (c == 'm' && func->IsShared() && module->scriptFunctions.IndexOf(func) < 0 )
+			// Functions and methods that are shared should be stored as 's' as the bytecode
+			// may be imported from other modules (even if the current module have received ownership)
+			if (c == 'm' && func->IsShared() )
 				c = 's';
 				c = 's';
 
 
 			WriteData(&c, 1);
 			WriteData(&c, 1);
@@ -4162,13 +4248,13 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 	if( func->funcType == asFUNC_SCRIPT )
 	if( func->funcType == asFUNC_SCRIPT )
 	{
 	{
 		// Skip this for external shared entities
 		// Skip this for external shared entities
-		if (module->externalTypes.IndexOf(func->objectType) >= 0)
+		if (module->m_externalTypes.IndexOf(func->objectType) >= 0)
 			return;
 			return;
 
 
 		char bits = 0;
 		char bits = 0;
 		bits += func->IsShared() ? 1 : 0;
 		bits += func->IsShared() ? 1 : 0;
 		bits += func->dontCleanUpOnException ? 2 : 0;
 		bits += func->dontCleanUpOnException ? 2 : 0;
-		if (module->externalFunctions.IndexOf(func) >= 0)
+		if (module->m_externalFunctions.IndexOf(func) >= 0)
 			bits += 4;
 			bits += 4;
 		if (func->scriptData->objVariablePos.GetLength() || func->scriptData->objVariableInfo.GetLength())
 		if (func->scriptData->objVariablePos.GetLength() || func->scriptData->objVariableInfo.GetLength())
 			bits += 8;
 			bits += 8;
@@ -4303,7 +4389,7 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 	{
 	{
 		char bits = 0;
 		char bits = 0;
 		bits += func->IsShared() ? 1 : 0;
 		bits += func->IsShared() ? 1 : 0;
-		if (module->externalTypes.IndexOf(func->funcdefType) >= 0)
+		if (module->m_externalTypes.IndexOf(func->funcdefType) >= 0)
 			bits += 2;
 			bits += 2;
 		WriteData(&bits,1);
 		WriteData(&bits,1);
 	}
 	}
@@ -4341,7 +4427,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
 		if ((type->flags & asOBJ_SHARED))
 		if ((type->flags & asOBJ_SHARED))
 		{
 		{
 			char c = ' ';
 			char c = ' ';
-			if (module->externalTypes.IndexOf(type) >= 0)
+			if (module->m_externalTypes.IndexOf(type) >= 0)
 				c = 'e';
 				c = 'e';
 			WriteData(&c, 1);
 			WriteData(&c, 1);
 		}
 		}
@@ -4349,7 +4435,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
 	else if( phase == 2 )
 	else if( phase == 2 )
 	{
 	{
 		// external shared types doesn't need to save this
 		// external shared types doesn't need to save this
-		if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
+		if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
 			return;
 			return;
 
 
 		if(type->flags & asOBJ_ENUM )
 		if(type->flags & asOBJ_ENUM )
@@ -4427,7 +4513,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
 	else if( phase == 3 )
 	else if( phase == 3 )
 	{
 	{
 		// external shared types doesn't need to save this
 		// external shared types doesn't need to save this
-		if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
+		if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
 			return;
 			return;
 
 
 		// properties[]
 		// properties[]
@@ -5044,8 +5130,8 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
 		{
 		{
 			// Translate the function id
 			// Translate the function id
 			int funcId = tmpBC[1];
 			int funcId = tmpBC[1];
-			for( asUINT n = 0; n < module->bindInformations.GetLength(); n++ )
-				if( module->bindInformations[n]->importedFunctionSignature->id == funcId )
+			for( asUINT n = 0; n < module->m_bindInformations.GetLength(); n++ )
+				if( module->m_bindInformations[n]->importedFunctionSignature->id == funcId )
 				{
 				{
 					funcId = n;
 					funcId = n;
 					break;
 					break;

+ 142 - 39
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -218,6 +218,9 @@ AS_API const char * asGetLibraryOptions()
 #endif
 #endif
 #ifdef AS_SPARC
 #ifdef AS_SPARC
 		"AS_SPARC "
 		"AS_SPARC "
+#endif
+#ifdef AS_ARM64
+		"AS_ARM64 "
 #endif
 #endif
 	;
 	;
 
 
@@ -355,7 +358,7 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
 		break;
 		break;
 
 
 	case asEP_PROPERTY_ACCESSOR_MODE:
 	case asEP_PROPERTY_ACCESSOR_MODE:
-		if( value <= 2 )
+		if( value <= 3 )
 			ep.propertyAccessorMode = (int)value;
 			ep.propertyAccessorMode = (int)value;
 		else
 		else
 			return asINVALID_ARG;
 			return asINVALID_ARG;
@@ -596,7 +599,7 @@ asCScriptEngine::asCScriptEngine()
 		ep.scanner                       = 1;         // utf8. 0 = ascii
 		ep.scanner                       = 1;         // utf8. 0 = ascii
 		ep.includeJitInstructions        = false;
 		ep.includeJitInstructions        = false;
 		ep.stringEncoding                = 0;         // utf8. 1 = utf16
 		ep.stringEncoding                = 0;         // utf8. 1 = utf16
-		ep.propertyAccessorMode          = 2;         // 0 = disable, 1 = app registered only, 2 = app and script created
+		ep.propertyAccessorMode          = 3;         // 0 = disable, 1 = app registered only, 2 = app and script created, 3 = flag with 'property'
 		ep.expandDefaultArrayToTemplate  = false;
 		ep.expandDefaultArrayToTemplate  = false;
 		ep.autoGarbageCollect            = true;
 		ep.autoGarbageCollect            = true;
 		ep.disallowGlobalVars            = false;
 		ep.disallowGlobalVars            = false;
@@ -738,10 +741,10 @@ asCScriptEngine::~asCScriptEngine()
 	}
 	}
 
 
 	// Delete the functions for generated template types that may references object types
 	// Delete the functions for generated template types that may references object types
-	for( asUINT n = 0; n < templateInstanceTypes.GetLength(); n++ )
+	for( asUINT n = 0; n < generatedTemplateTypes.GetLength(); n++ )
 	{
 	{
-		asCObjectType *templateType = templateInstanceTypes[n];
-		if( templateInstanceTypes[n] )
+		asCObjectType *templateType = generatedTemplateTypes[n];
+		if( templateType )
 			templateType->DestroyInternal();
 			templateType->DestroyInternal();
 	}
 	}
 	for( asUINT n = 0; n < listPatternTypes.GetLength(); n++ )
 	for( asUINT n = 0; n < listPatternTypes.GetLength(); n++ )
@@ -919,15 +922,15 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedType(asCTypeInfo *in_type, asCM
 		asCModule *mod = scriptModules[n];
 		asCModule *mod = scriptModules[n];
 		if( mod == in_type->module ) continue;
 		if( mod == in_type->module ) continue;
 		if( in_type->flags & asOBJ_ENUM )
 		if( in_type->flags & asOBJ_ENUM )
-			foundIdx = mod->enumTypes.IndexOf(CastToEnumType(in_type));
+			foundIdx = mod->m_enumTypes.IndexOf(CastToEnumType(in_type));
 		else if (in_type->flags & asOBJ_TYPEDEF)
 		else if (in_type->flags & asOBJ_TYPEDEF)
-			foundIdx = mod->typeDefs.IndexOf(CastToTypedefType(in_type));
+			foundIdx = mod->m_typeDefs.IndexOf(CastToTypedefType(in_type));
 		else if (in_type->flags & asOBJ_FUNCDEF)
 		else if (in_type->flags & asOBJ_FUNCDEF)
-			foundIdx = mod->funcDefs.IndexOf(CastToFuncdefType(in_type));
+			foundIdx = mod->m_funcDefs.IndexOf(CastToFuncdefType(in_type));
 		else if (in_type->flags & asOBJ_TEMPLATE)
 		else if (in_type->flags & asOBJ_TEMPLATE)
-			foundIdx = mod->templateInstances.IndexOf(CastToObjectType(in_type));
+			foundIdx = mod->m_templateInstances.IndexOf(CastToObjectType(in_type));
 		else
 		else
-			foundIdx = mod->classTypes.IndexOf(CastToObjectType(in_type));
+			foundIdx = mod->m_classTypes.IndexOf(CastToObjectType(in_type));
 
 
 		if( foundIdx >= 0 )
 		if( foundIdx >= 0 )
 		{
 		{
@@ -948,13 +951,30 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedFunc(asCScriptFunction *in_func
 	if( in_func->module != in_mod)
 	if( in_func->module != in_mod)
 		return in_func->module;
 		return in_func->module;
 
 
+	if (in_func->objectType && in_func->objectType->module && 
+		in_func->objectType->module != in_func->module)
+	{
+		// The object type for the method has already been transferred to 
+		// another module, so transfer the method to the same module
+		in_func->module = in_func->objectType->module;
+
+		// Make sure the function is listed in the module
+		// The compiler may not have done this earlier, since the object
+		// type is shared and originally compiled from another module
+		if (in_func->module->m_scriptFunctions.IndexOf(in_func) < 0)
+		{
+			in_func->module->m_scriptFunctions.PushLast(in_func);
+			in_func->AddRefInternal();
+		}
+	}
+
 	for( asUINT n = 0; n < scriptModules.GetLength(); n++ )
 	for( asUINT n = 0; n < scriptModules.GetLength(); n++ )
 	{
 	{
 		// TODO: optimize: If the modules already stored the shared types separately, this would be quicker
 		// TODO: optimize: If the modules already stored the shared types separately, this would be quicker
 		int foundIdx = -1;
 		int foundIdx = -1;
 		asCModule *mod = scriptModules[n];
 		asCModule *mod = scriptModules[n];
 		if( mod == in_func->module ) continue;
 		if( mod == in_func->module ) continue;
-		foundIdx = mod->scriptFunctions.IndexOf(in_func);
+		foundIdx = mod->m_scriptFunctions.IndexOf(in_func);
 
 
 		if( foundIdx >= 0 )
 		if( foundIdx >= 0 )
 		{
 		{
@@ -1495,7 +1515,9 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 	prop->isCompositeIndirect = isCompositeIndirect;
 	prop->isCompositeIndirect = isCompositeIndirect;
 	prop->accessMask          = defaultAccessMask;
 	prop->accessMask          = defaultAccessMask;
 
 
-	CastToObjectType(dt.GetTypeInfo())->properties.PushLast(prop);
+	asCObjectType *ot = CastToObjectType(dt.GetTypeInfo());
+	asUINT idx = ot->properties.GetLength();
+	ot->properties.PushLast(prop);
 
 
 	// Add references to types so they are not released too early
 	// Add references to types so they are not released too early
 	if( type.GetTypeInfo() )
 	if( type.GetTypeInfo() )
@@ -1509,7 +1531,8 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 
 
 	currentGroup->AddReferencesForType(this, type.GetTypeInfo());
 	currentGroup->AddReferencesForType(this, type.GetTypeInfo());
 
 
-	return asSUCCESS;
+	// Return the index of the property to signal success
+	return idx;
 }
 }
 
 
 // interface
 // interface
@@ -1541,7 +1564,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
 	if( token != ttIdentifier || strlen(name) != tokenLen )
 	if( token != ttIdentifier || strlen(name) != tokenLen )
 		return ConfigError(asINVALID_NAME, "RegisterInterface", name, 0);
 		return ConfigError(asINVALID_NAME, "RegisterInterface", name, 0);
 
 
-	r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true);
+	r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
 	if( r < 0 )
 	if( r < 0 )
 		return ConfigError(asNAME_TAKEN, "RegisterInterface", name, 0);
 		return ConfigError(asNAME_TAKEN, "RegisterInterface", name, 0);
 
 
@@ -1603,7 +1626,7 @@ int asCScriptEngine::RegisterInterfaceMethod(const char *intf, const char *decla
 	}
 	}
 
 
 	// Check name conflicts
 	// Check name conflicts
-	r = bld.CheckNameConflictMember(dt.GetTypeInfo(), func->name.AddressOf(), 0, 0, false);
+	r = bld.CheckNameConflictMember(dt.GetTypeInfo(), func->name.AddressOf(), 0, 0, false, false);
 	if( r < 0 )
 	if( r < 0 )
 	{
 	{
 		func->funcType = asFUNC_DUMMY;
 		func->funcType = asFUNC_DUMMY;
@@ -1824,7 +1847,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 			if( token != ttIdentifier || typeName.GetLength() != tokenLen )
 			if( token != ttIdentifier || typeName.GetLength() != tokenLen )
 				return ConfigError(asINVALID_NAME, "RegisterObjectType", name, 0);
 				return ConfigError(asINVALID_NAME, "RegisterObjectType", name, 0);
 
 
-			r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true);
+			r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
 			if( r < 0 )
 			if( r < 0 )
 				return ConfigError(asNAME_TAKEN, "RegisterObjectType", name, 0);
 				return ConfigError(asNAME_TAKEN, "RegisterObjectType", name, 0);
 
 
@@ -2111,6 +2134,8 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 	}
 	}
 	else if( behaviour == asBEHAVE_LIST_CONSTRUCT )
 	else if( behaviour == asBEHAVE_LIST_CONSTRUCT )
 	{
 	{
+		func.name = "$list";
+		
 		// Verify that the return type is void
 		// Verify that the return type is void
 		if( func.returnType != asCDataType::CreatePrimitive(ttVoid, false) )
 		if( func.returnType != asCDataType::CreatePrimitive(ttVoid, false) )
 		{
 		{
@@ -2166,6 +2191,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 	}
 	}
 	else if( behaviour == asBEHAVE_FACTORY || behaviour == asBEHAVE_LIST_FACTORY )
 	else if( behaviour == asBEHAVE_FACTORY || behaviour == asBEHAVE_LIST_FACTORY )
 	{
 	{
+		if( behaviour == asBEHAVE_LIST_FACTORY )
+			func.name = "$list";
+		
 		// Must be a ref type and must not have asOBJ_NOHANDLE
 		// Must be a ref type and must not have asOBJ_NOHANDLE
 		if( !(objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_NOHANDLE) )
 		if( !(objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_NOHANDLE) )
 		{
 		{
@@ -2565,13 +2593,14 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
 	prop->SetRegisteredAddress(pointer);
 	prop->SetRegisteredAddress(pointer);
 	varAddressMap.Insert(prop->GetAddressOfValue(), prop);
 	varAddressMap.Insert(prop->GetAddressOfValue(), prop);
 
 
-	registeredGlobalProps.Put(prop);
+	asUINT idx = registeredGlobalProps.Put(prop);
 	prop->AddRef();
 	prop->AddRef();
 	currentGroup->globalProps.PushLast(prop);
 	currentGroup->globalProps.PushLast(prop);
 
 
 	currentGroup->AddReferencesForType(this, type.GetTypeInfo());
 	currentGroup->AddReferencesForType(this, type.GetTypeInfo());
 
 
-	return asSUCCESS;
+	// Return the index of the property to signal success
+	return int(idx);
 }
 }
 
 
 // internal
 // internal
@@ -2650,10 +2679,13 @@ int asCScriptEngine::GetGlobalPropertyByIndex(asUINT index, const char **name, c
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetGlobalPropertyIndexByName(const char *name) const
+int asCScriptEngine::GetGlobalPropertyIndexByName(const char *in_name) const
 {
 {
-	asSNameSpace *ns = defaultNamespace;
-
+	asCString name;
+	asSNameSpace *ns = 0;
+	if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
+		return asINVALID_ARG;
+			
 	// Find the global var id
 	// Find the global var id
 	while( ns )
 	while( ns )
 	{
 	{
@@ -2793,7 +2825,7 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 	}
 	}
 
 
 	// Check name conflicts
 	// Check name conflicts
-	r = bld.CheckNameConflictMember(objectType, func->name.AddressOf(), 0, 0, false);
+	r = bld.CheckNameConflictMember(objectType, func->name.AddressOf(), 0, 0, false, false);
 	if( r < 0 )
 	if( r < 0 )
 	{
 	{
 		func->funcType = asFUNC_DUMMY;
 		func->funcType = asFUNC_DUMMY;
@@ -2801,6 +2833,18 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 		return ConfigError(asNAME_TAKEN, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
 		return ConfigError(asNAME_TAKEN, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
 	}
 	}
 
 
+	// Validate property signature
+	if( func->IsProperty() && (r = bld.ValidateVirtualProperty(func)) < 0 )
+	{
+		// Set as dummy function before deleting
+		func->funcType = asFUNC_DUMMY;
+		asDELETE(func,asCScriptFunction);
+		if( r == -5 )
+			return ConfigError(asNAME_TAKEN, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
+		else
+			return ConfigError(asINVALID_DECLARATION, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
+	}
+	
 	// Check against duplicate methods
 	// Check against duplicate methods
 	if( func->name == "opConv" || func->name == "opImplConv" || func->name == "opCast" || func->name == "opImplCast" )
 	if( func->name == "opConv" || func->name == "opImplConv" || func->name == "opCast" || func->name == "opImplCast" )
 	{
 	{
@@ -2907,7 +2951,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 	func->nameSpace = defaultNamespace;
 	func->nameSpace = defaultNamespace;
 
 
 	// Check name conflicts
 	// Check name conflicts
-	r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, false);
+	r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, false, false);
 	if( r < 0 )
 	if( r < 0 )
 	{
 	{
 		// Set as dummy function before deleting
 		// Set as dummy function before deleting
@@ -2915,6 +2959,18 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 		asDELETE(func,asCScriptFunction);
 		asDELETE(func,asCScriptFunction);
 		return ConfigError(asNAME_TAKEN, "RegisterGlobalFunction", declaration, 0);
 		return ConfigError(asNAME_TAKEN, "RegisterGlobalFunction", declaration, 0);
 	}
 	}
+	
+	// Validate property signature
+	if( func->IsProperty() && (r = bld.ValidateVirtualProperty(func)) < 0 )
+	{
+		// Set as dummy function before deleting
+		func->funcType = asFUNC_DUMMY;
+		asDELETE(func,asCScriptFunction);
+		if( r == -5 )
+			return ConfigError(asNAME_TAKEN, "RegisterGlobalFunction", declaration, 0);
+		else
+			return ConfigError(asINVALID_DECLARATION, "RegisterGlobalFunction", declaration, 0);
+	}
 
 
 	// Make sure the function is not identical to a previously registered function
 	// Make sure the function is not identical to a previously registered function
 	asUINT n;
 	asUINT n;
@@ -3230,13 +3286,13 @@ asCModule *asCScriptEngine::GetModule(const char *name, bool create)
 	asCModule *retModule = 0;
 	asCModule *retModule = 0;
 
 
 	ACQUIRESHARED(engineRWLock);
 	ACQUIRESHARED(engineRWLock);
-	if( lastModule && lastModule->name == name )
+	if( lastModule && lastModule->m_name == name )
 		retModule = lastModule;
 		retModule = lastModule;
 	else
 	else
 	{
 	{
 		// TODO: optimize: Improve linear search
 		// TODO: optimize: Improve linear search
 		for( asUINT n = 0; n < scriptModules.GetLength(); ++n )
 		for( asUINT n = 0; n < scriptModules.GetLength(); ++n )
-			if( scriptModules[n] && scriptModules[n]->name == name )
+			if( scriptModules[n] && scriptModules[n]->m_name == name )
 			{
 			{
 				retModule = scriptModules[n];
 				retModule = scriptModules[n];
 				break;
 				break;
@@ -3352,9 +3408,9 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 					// It may be without ownership if it was previously created from application with for example GetTypeInfoByDecl
 					// It may be without ownership if it was previously created from application with for example GetTypeInfoByDecl
 					type->module = requestingModule;
 					type->module = requestingModule;
 				}
 				}
-				if( !requestingModule->templateInstances.Exists(type) )
+				if( !requestingModule->m_templateInstances.Exists(type) )
 				{
 				{
-					requestingModule->templateInstances.PushLast(type);
+					requestingModule->m_templateInstances.PushLast(type);
 					type->AddRefInternal();
 					type->AddRefInternal();
 				}
 				}
 			}
 			}
@@ -3394,7 +3450,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	{
 	{
 		// Set the ownership of this template type
 		// Set the ownership of this template type
 		ot->module = requestingModule;
 		ot->module = requestingModule;
-		requestingModule->templateInstances.PushLast(ot);
+		requestingModule->m_templateInstances.PushLast(ot);
 		ot->AddRefInternal();
 		ot->AddRefInternal();
 	}
 	}
 	else
 	else
@@ -3410,7 +3466,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 				ot->module = subTypes[n].GetTypeInfo()->module;
 				ot->module = subTypes[n].GetTypeInfo()->module;
 				if( ot->module )
 				if( ot->module )
 				{
 				{
-					ot->module->templateInstances.PushLast(ot);
+					ot->module->m_templateInstances.PushLast(ot);
 					ot->AddRefInternal();
 					ot->AddRefInternal();
 					break;
 					break;
 				}
 				}
@@ -3434,7 +3490,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 				ot->templateSubTypes.SetLength(0);
 				ot->templateSubTypes.SetLength(0);
 				if( ot->module )
 				if( ot->module )
 				{
 				{
-					ot->module->templateInstances.RemoveValue(ot);
+					ot->module->m_templateInstances.RemoveValue(ot);
 					ot->ReleaseInternal();
 					ot->ReleaseInternal();
 				}
 				}
 				ot->ReleaseInternal();
 				ot->ReleaseInternal();
@@ -5659,7 +5715,7 @@ int asCScriptEngine::RegisterFuncdef(const char *decl)
 	}
 	}
 
 
 	// Check name conflicts
 	// Check name conflicts
-	r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, true);
+	r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, true, false);
 	if( r < 0 )
 	if( r < 0 )
 	{
 	{
 		asDELETE(func,asCScriptFunction);
 		asDELETE(func,asCScriptFunction);
@@ -5754,7 +5810,7 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
 			// Add the new funcdef to the module so it will
 			// Add the new funcdef to the module so it will
 			// be available when saving the bytecode
 			// be available when saving the bytecode
 			funcDef->module = module;
 			funcDef->module = module;
-			module->funcDefs.PushLast(funcDef); // the refCount was already accounted for in the constructor
+			module->AddFuncDef(funcDef); // the refCount was already accounted for in the constructor
 		}
 		}
 
 
 		// Observe, if the funcdef is created without informing a module a reference will be stored in the
 		// Observe, if the funcdef is created without informing a module a reference will be stored in the
@@ -5766,9 +5822,9 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
 	{
 	{
 		// Unless this is a registered funcDef the returned funcDef must
 		// Unless this is a registered funcDef the returned funcDef must
 		// be stored as part of the module for saving/loading bytecode
 		// be stored as part of the module for saving/loading bytecode
-		if (!module->funcDefs.Exists(funcDef))
+		if (!module->m_funcDefs.Exists(funcDef))
 		{
 		{
-			module->funcDefs.PushLast(funcDef);
+			module->AddFuncDef(funcDef);
 			funcDef->AddRefInternal();
 			funcDef->AddRefInternal();
 		}
 		}
 		else
 		else
@@ -5830,7 +5886,7 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 		return ConfigError(asINVALID_NAME, "RegisterTypedef", type, decl);
 		return ConfigError(asINVALID_NAME, "RegisterTypedef", type, decl);
 
 
 	asCBuilder bld(this, 0);
 	asCBuilder bld(this, 0);
-	int r = bld.CheckNameConflict(type, 0, 0, defaultNamespace, true);
+	int r = bld.CheckNameConflict(type, 0, 0, defaultNamespace, true, false);
 	if( r < 0 )
 	if( r < 0 )
 		return ConfigError(asNAME_TAKEN, "RegisterTypedef", type, decl);
 		return ConfigError(asNAME_TAKEN, "RegisterTypedef", type, decl);
 
 
@@ -5902,7 +5958,7 @@ int asCScriptEngine::RegisterEnum(const char *name)
 	if( token != ttIdentifier || strlen(name) != tokenLen )
 	if( token != ttIdentifier || strlen(name) != tokenLen )
 		return ConfigError(asINVALID_NAME, "RegisterEnum", name, 0);
 		return ConfigError(asINVALID_NAME, "RegisterEnum", name, 0);
 
 
-	r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true);
+	r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
 	if( r < 0 )
 	if( r < 0 )
 		return ConfigError(asNAME_TAKEN, "RegisterEnum", name, 0);
 		return ConfigError(asNAME_TAKEN, "RegisterEnum", name, 0);
 
 
@@ -6002,9 +6058,13 @@ asITypeInfo *asCScriptEngine::GetObjectTypeByIndex(asUINT index) const
 }
 }
 
 
 // interface
 // interface
-asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
+asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *in_name) const
 {
 {
-	asSNameSpace *ns = defaultNamespace;
+	asCString name;
+	asSNameSpace *ns = 0;
+	if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
+		return 0;
+			
 	while (ns)
 	while (ns)
 	{
 	{
 		// Check the object types
 		// Check the object types
@@ -6047,6 +6107,49 @@ asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
 	return 0;
 	return 0;
 }
 }
 
 
+// internal
+int asCScriptEngine::DetermineNameAndNamespace(const char *in_name, asSNameSpace *implicitNs, asCString &out_name, asSNameSpace *&out_ns) const
+{
+	if( in_name == 0 )
+		return asINVALID_ARG;
+	
+	asCString name = in_name;
+	asCString scope;
+	asSNameSpace *ns = implicitNs;
+	
+	// Check if the given name contains a scope
+	int pos = name.FindLast("::");
+	if( pos >= 0 )
+	{
+		scope = name.SubString(0, pos);
+		name = name.SubString(pos+2);
+		if( pos == 0 )
+		{
+			// The scope is '::' so the search must start in the global namespace
+			ns = nameSpaces[0];
+		}
+		else if( scope.SubString(0, 2) == "::" )
+		{
+			// The scope starts with '::' so the given scope is fully qualified
+			ns = FindNameSpace(scope.SubString(2).AddressOf());
+		}
+		else
+		{
+			// The scope doesn't start with '::' so it is relative to the current namespace
+			if( implicitNs->name == "" )
+				ns = FindNameSpace(scope.AddressOf());
+			else
+				ns = FindNameSpace((implicitNs->name + "::" + scope).AddressOf());
+		}
+	}
+	
+	out_name = name;
+	out_ns = ns;
+	
+	return 0;
+}
+
+
 // interface
 // interface
 asITypeInfo *asCScriptEngine::GetTypeInfoById(int typeId) const
 asITypeInfo *asCScriptEngine::GetTypeInfoById(int typeId) const
 {
 {

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -305,6 +305,8 @@ public:
 
 
 	asCFuncdefType    *FindMatchingFuncdef(asCScriptFunction *func, asCModule *mod);
 	asCFuncdefType    *FindMatchingFuncdef(asCScriptFunction *func, asCModule *mod);
 
 
+	int                DetermineNameAndNamespace(const char *in_name, asSNameSpace *implicitNs, asCString &out_name, asSNameSpace *&out_ns) const;
+	
 	// Global property management
 	// Global property management
 	asCGlobalProperty *AllocateGlobalProperty();
 	asCGlobalProperty *AllocateGlobalProperty();
 	void RemoveGlobalProperty(asCGlobalProperty *prop);
 	void RemoveGlobalProperty(asCGlobalProperty *prop);

+ 8 - 4
Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -584,9 +584,7 @@ bool asCScriptFunction::IsCompatibleWithTypeId(int typeId) const
 const char *asCScriptFunction::GetModuleName() const
 const char *asCScriptFunction::GetModuleName() const
 {
 {
 	if( module )
 	if( module )
-	{
-		return module->name.AddressOf();
-	}
+		return module->GetName();
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1718,5 +1716,11 @@ bool asCScriptFunction::IsExplicit() const
 	return traits.GetTrait(asTRAIT_EXPLICIT);
 	return traits.GetTrait(asTRAIT_EXPLICIT);
 }
 }
 
 
+// interface
+bool asCScriptFunction::IsProperty() const
+{
+	return traits.GetTrait(asTRAIT_PROPERTY);
+}
+
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

+ 5 - 2
Source/ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -109,7 +109,8 @@ enum asEFuncTrait
 	asTRAIT_OVERRIDE    = 64,
 	asTRAIT_OVERRIDE    = 64,
 	asTRAIT_SHARED      = 128,
 	asTRAIT_SHARED      = 128,
 	asTRAIT_EXTERNAL    = 256,
 	asTRAIT_EXTERNAL    = 256,
-	asTRAIT_EXPLICIT    = 512
+	asTRAIT_EXPLICIT    = 512,
+	asTRAIT_PROPERTY    = 1024
 };
 };
 
 
 struct asSFunctionTraits
 struct asSFunctionTraits
@@ -175,6 +176,7 @@ public:
 	bool                 IsOverride() const;
 	bool                 IsOverride() const;
 	bool                 IsShared() const;
 	bool                 IsShared() const;
 	bool                 IsExplicit() const;
 	bool                 IsExplicit() const;
+	bool                 IsProperty() const;
 	asUINT               GetParamCount() const;
 	asUINT               GetParamCount() const;
 	int                  GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const;
 	int                  GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const;
 	int                  GetReturnTypeId(asDWORD *flags = 0) const;
 	int                  GetReturnTypeId(asDWORD *flags = 0) const;
@@ -212,6 +214,7 @@ public:
 	void SetExplicit(bool set) { traits.SetTrait(asTRAIT_EXPLICIT, set); }
 	void SetExplicit(bool set) { traits.SetTrait(asTRAIT_EXPLICIT, set); }
 	void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
 	void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
 	void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
 	void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
+	void SetProperty(bool set) { traits.SetTrait(asTRAIT_PROPERTY, set); }
 
 
 	asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
 	asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
 	~asCScriptFunction();
 	~asCScriptFunction();

+ 36 - 27
Source/ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -888,30 +888,43 @@ asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject
 
 
 asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 {
 {
-	if( &other != this )
+	CopyFromAs(&other, objType);
+	return *this;
+}
+
+// internal
+int asCScriptObject::CopyFromAs(const asCScriptObject *other, asCObjectType *in_objType)
+{
+	if( other != this )
 	{
 	{
-		if( !other.objType->DerivesFrom(objType) )
+		if( !other->objType->DerivesFrom(in_objType) )
 		{
 		{
 			// We cannot allow a value assignment from a type that isn't the same or 
 			// 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
 			// derives from this type as the member properties may not have the same layout
 			asIScriptContext *ctx = asGetActiveContext();
 			asIScriptContext *ctx = asGetActiveContext();
 			ctx->SetException(TXT_MISMATCH_IN_VALUE_ASSIGN);
 			ctx->SetException(TXT_MISMATCH_IN_VALUE_ASSIGN);
-			return *this;
+			return asERROR;
 		}
 		}
 
 
 		// If the script class implements the opAssign method, it should be called
 		// If the script class implements the opAssign method, it should be called
-		asCScriptEngine *engine = objType->engine;
-		asCScriptFunction *func = engine->scriptFunctions[objType->beh.copy];
+		asCScriptEngine *engine = in_objType->engine;
+		asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
 		if( func->funcType == asFUNC_SYSTEM )
 		if( func->funcType == asFUNC_SYSTEM )
 		{
 		{
-			// Copy all properties
-			for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
+			// If derived, use the base class' assignment operator to copy the inherited
+			// properties. Then only copy new properties for the derived class
+			if( in_objType->derivedFrom )
+				CopyFromAs(other, in_objType->derivedFrom);
+			
+			for( asUINT n = in_objType->derivedFrom ? in_objType->derivedFrom->properties.GetLength() : 0; 
+			     n < in_objType->properties.GetLength(); 
+				 n++ )
 			{
 			{
-				asCObjectProperty *prop = objType->properties[n];
+				asCObjectProperty *prop = in_objType->properties[n];
 				if( prop->type.IsObject() )
 				if( prop->type.IsObject() )
 				{
 				{
 					void **dst = (void**)(((char*)this) + prop->byteOffset);
 					void **dst = (void**)(((char*)this) + prop->byteOffset);
-					void **src = (void**)(((char*)&other) + prop->byteOffset);
+					void **src = (void**)(((char*)other) + prop->byteOffset);
 					if( !prop->type.IsObjectHandle() )
 					if( !prop->type.IsObjectHandle() )
 					{
 					{
 						if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
 						if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
@@ -925,7 +938,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 				else if (prop->type.IsFuncdef())
 				else if (prop->type.IsFuncdef())
 				{
 				{
 					asCScriptFunction **dst = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
 					asCScriptFunction **dst = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
-					asCScriptFunction **src = (asCScriptFunction**)(((char*)&other) + prop->byteOffset);
+					asCScriptFunction **src = (asCScriptFunction**)(((char*)other) + prop->byteOffset);
 					if (*dst)
 					if (*dst)
 						(*dst)->Release();
 						(*dst)->Release();
 					*dst = *src;
 					*dst = *src;
@@ -935,7 +948,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 				else
 				else
 				{
 				{
 					void *dst = ((char*)this) + prop->byteOffset;
 					void *dst = ((char*)this) + prop->byteOffset;
-					void *src = ((char*)&other) + prop->byteOffset;
+					void *src = ((char*)other) + prop->byteOffset;
 					memcpy(dst, src, prop->type.GetSizeInMemoryBytes());
 					memcpy(dst, src, prop->type.GetSizeInMemoryBytes());
 				}
 				}
 			}
 			}
@@ -961,24 +974,20 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 				// Request a context from the engine
 				// Request a context from the engine
 				ctx = engine->RequestContext();
 				ctx = engine->RequestContext();
 				if( ctx == 0 )
 				if( ctx == 0 )
-				{
-					// TODO: How to best report this failure?
-					return *this;
-				}
+					return asERROR;
 			}
 			}
 
 
-			r = ctx->Prepare(engine->scriptFunctions[objType->beh.copy]);
+			r = ctx->Prepare(engine->scriptFunctions[in_objType->beh.copy]);
 			if( r < 0 )
 			if( r < 0 )
 			{
 			{
 				if( isNested )
 				if( isNested )
 					ctx->PopState();
 					ctx->PopState();
 				else
 				else
 					engine->ReturnContext(ctx);
 					engine->ReturnContext(ctx);
-				// TODO: How to best report this failure?
-				return *this;
+				return r;
 			}
 			}
 
 
-			r = ctx->SetArgAddress(0, const_cast<asCScriptObject*>(&other));
+			r = ctx->SetArgAddress(0, const_cast<asCScriptObject*>(other));
 			asASSERT( r >= 0 );
 			asASSERT( r >= 0 );
 			r = ctx->SetObject(this);
 			r = ctx->SetObject(this);
 			asASSERT( r >= 0 );
 			asASSERT( r >= 0 );
@@ -1014,7 +1023,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 					// Return the context to the engine
 					// Return the context to the engine
 					engine->ReturnContext(ctx);
 					engine->ReturnContext(ctx);
 				}
 				}
-				return *this;
+				return asERROR;
 			}
 			}
 
 
 			if( isNested )
 			if( isNested )
@@ -1027,10 +1036,10 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 		}
 		}
 	}
 	}
 
 
-	return *this;
+	return asSUCCESS;
 }
 }
 
 
-int asCScriptObject::CopyFrom(asIScriptObject *other)
+int asCScriptObject::CopyFrom(const asIScriptObject *other)
 {
 {
 	if( other == 0 ) return asINVALID_ARG;
 	if( other == 0 ) return asINVALID_ARG;
 
 
@@ -1039,7 +1048,7 @@ int asCScriptObject::CopyFrom(asIScriptObject *other)
 
 
 	*this = *(asCScriptObject*)other;
 	*this = *(asCScriptObject*)other;
 
 
-	return 0;
+	return asSUCCESS;
 }
 }
 
 
 void *asCScriptObject::AllocateUninitializedObject(asCObjectType *in_objType, asCScriptEngine *engine)
 void *asCScriptObject::AllocateUninitializedObject(asCObjectType *in_objType, asCScriptEngine *engine)
@@ -1089,19 +1098,19 @@ void asCScriptObject::FreeObject(void *ptr, asCObjectType *in_objType, asCScript
 	}
 	}
 }
 }
 
 
-void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *in_objType, asCScriptEngine *engine)
+void asCScriptObject::CopyObject(const void *src, void *dst, asCObjectType *in_objType, asCScriptEngine *engine)
 {
 {
 	int funcIndex = in_objType->beh.copy;
 	int funcIndex = in_objType->beh.copy;
 	if( funcIndex )
 	if( funcIndex )
 	{
 	{
 		asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
 		asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
 		if( func->funcType == asFUNC_SYSTEM )
 		if( func->funcType == asFUNC_SYSTEM )
-			engine->CallObjectMethod(dst, src, funcIndex);
+			engine->CallObjectMethod(dst, const_cast<void*>(src), funcIndex);
 		else
 		else
 		{
 		{
 			// Call the script class' opAssign method
 			// Call the script class' opAssign method
 			asASSERT(in_objType->flags & asOBJ_SCRIPT_OBJECT );
 			asASSERT(in_objType->flags & asOBJ_SCRIPT_OBJECT );
-			reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<asCScriptObject*>(src));
+			reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<const asCScriptObject*>(src));
 		}
 		}
 	}
 	}
 	else if( in_objType->size && (in_objType->flags & asOBJ_POD) )
 	else if( in_objType->size && (in_objType->flags & asOBJ_POD) )

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -94,7 +94,7 @@ public:
 
 
 	// Miscellaneous
 	// Miscellaneous
 	asIScriptEngine *GetEngine() const;
 	asIScriptEngine *GetEngine() const;
-	int              CopyFrom(asIScriptObject *other);
+	int              CopyFrom(const asIScriptObject *other);
 
 
 	// User data
 	// User data
 	void *SetUserData(void *data, asPWORD type = 0);
 	void *SetUserData(void *data, asPWORD type = 0);
@@ -119,8 +119,9 @@ public:
 	// Used for properties
 	// Used for properties
 	void *AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine);
 	void *AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
-	void CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
+	void CopyObject(const void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine);
+	int  CopyFromAs(const asCScriptObject *other, asCObjectType *objType);
 
 
 	void CallDestructor();
 	void CallDestructor();
 
 

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -154,6 +154,7 @@
 #define TXT_INVALID_OP_ON_METHOD                   "Invalid operation on method"
 #define TXT_INVALID_OP_ON_METHOD                   "Invalid operation on method"
 #define TXT_INVALID_REF_PROP_ACCESS                "Invalid reference. Property accessors cannot be used in combined read/write operations"
 #define TXT_INVALID_REF_PROP_ACCESS                "Invalid reference. Property accessors cannot be used in combined read/write operations"
 #define TXT_INVALID_SCOPE                          "Invalid scope resolution"
 #define TXT_INVALID_SCOPE                          "Invalid scope resolution"
+#define TXT_INVALID_SIG_FOR_VIRTPROP               "Invalid signature for virtual property"
 #define TXT_INVALID_TYPE                           "Invalid type"
 #define TXT_INVALID_TYPE                           "Invalid type"
 #define TXT_INVALID_UNICODE_FORMAT_EXPECTED_d      "Invalid unicode escape sequence, expected %d hex digits"
 #define TXT_INVALID_UNICODE_FORMAT_EXPECTED_d      "Invalid unicode escape sequence, expected %d hex digits"
 #define TXT_INVALID_UNICODE_VALUE                  "Invalid unicode code point"
 #define TXT_INVALID_UNICODE_VALUE                  "Invalid unicode code point"
@@ -186,6 +187,7 @@
 #define TXT_NAME_CONFLICT_s_IS_FUNCDEF             "Name conflict. '%s' is a funcdef."
 #define TXT_NAME_CONFLICT_s_IS_FUNCDEF             "Name conflict. '%s' is a funcdef."
 #define TXT_NAME_CONFLICT_s_IS_FUNCTION            "Name conflict. '%s' is a global function."
 #define TXT_NAME_CONFLICT_s_IS_FUNCTION            "Name conflict. '%s' is a global function."
 #define TXT_NAME_CONFLICT_s_IS_MIXIN               "Name conflict. '%s' is a mixin class."
 #define TXT_NAME_CONFLICT_s_IS_MIXIN               "Name conflict. '%s' is a mixin class."
+#define TXT_NAME_CONFLICT_s_IS_VIRTPROP            "Name conflict. '%s' is a virtual property."
 #define TXT_NAME_CONFLICT_s_STRUCT                 "Name conflict. '%s' is a class."
 #define TXT_NAME_CONFLICT_s_STRUCT                 "Name conflict. '%s' is a class."
 #define TXT_NAME_CONFLICT_s_OBJ_PROPERTY           "Name conflict. '%s' is an object property."
 #define TXT_NAME_CONFLICT_s_OBJ_PROPERTY           "Name conflict. '%s' is an object property."
 #define TXT_NAME_CONFLICT_s_METHOD                 "Name conflict. '%s' is a class method."
 #define TXT_NAME_CONFLICT_s_METHOD                 "Name conflict. '%s' is a class method."

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2018 Andreas Jonsson
+   Copyright (c) 2003-2019 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -319,6 +319,7 @@ const char * const FUNCTION_TOKEN  = "function";
 const char * const IF_HANDLE_TOKEN = "if_handle_then_const";
 const char * const IF_HANDLE_TOKEN = "if_handle_then_const";
 const char * const EXTERNAL_TOKEN  = "external";
 const char * const EXTERNAL_TOKEN  = "external";
 const char * const EXPLICIT_TOKEN  = "explicit";
 const char * const EXPLICIT_TOKEN  = "explicit";
+const char * const PROPERTY_TOKEN  = "property";
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

+ 3 - 2
Source/ThirdParty/AngelScript/source/as_typeinfo.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2017 Andreas Jonsson
+   Copyright (c) 2003-2020 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -416,7 +416,8 @@ asCFuncdefType::asCFuncdefType(asCScriptEngine *en, asCScriptFunction *func) : a
 	asASSERT(func->funcdefType == 0);
 	asASSERT(func->funcdefType == 0);
 
 
 	// A function pointer is special kind of reference type
 	// A function pointer is special kind of reference type
-	flags       = asOBJ_REF | asOBJ_FUNCDEF | (func->IsShared() ? asOBJ_SHARED : 0);
+	// It must be possible to garbage collect, as funcdefs can form circular references if used as delegates
+	flags       = asOBJ_REF | asOBJ_GC | asOBJ_FUNCDEF | (func->IsShared() ? asOBJ_SHARED : 0);
 	name        = func->name;
 	name        = func->name;
 	nameSpace   = func->nameSpace;
 	nameSpace   = func->nameSpace;
 	module      = func->module;
 	module      = func->module;

+ 1 - 0
Source/Urho3D/AngelScript/Script.cpp

@@ -127,6 +127,7 @@ Script::Script(Context* context) :
     scriptEngine_->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, (asPWORD)true);
     scriptEngine_->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, (asPWORD)true);
     scriptEngine_->SetEngineProperty(asEP_ALLOW_IMPLICIT_HANDLE_TYPES, (asPWORD)true);
     scriptEngine_->SetEngineProperty(asEP_ALLOW_IMPLICIT_HANDLE_TYPES, (asPWORD)true);
     scriptEngine_->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, (asPWORD)true);
     scriptEngine_->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, (asPWORD)true);
+    scriptEngine_->SetEngineProperty(asEP_PROPERTY_ACCESSOR_MODE, 1);
 // Use the copy of the original asMETHOD macro in a web build (for some reason it still works, presumably because the signature of the function is known)
 // Use the copy of the original asMETHOD macro in a web build (for some reason it still works, presumably because the signature of the function is known)
 #ifdef AS_MAX_PORTABILITY
 #ifdef AS_MAX_PORTABILITY
     scriptEngine_->SetMessageCallback(_asMETHOD(Script, MessageCallback), this, asCALL_THISCALL);
     scriptEngine_->SetMessageCallback(_asMETHOD(Script, MessageCallback), this, asCALL_THISCALL);

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác