Browse Source

Merge remote-tracking branch 'upstream/master'

rasteron 11 years ago
parent
commit
60ce72af6e
53 changed files with 3110 additions and 1119 deletions
  1. 1 1
      Docs/Urho3D.dox
  2. 1 1
      Readme.txt
  3. 3 2
      Source/Engine/Script/Addons.cpp
  4. 4 3
      Source/Engine/Script/ScriptFile.cpp
  5. 2 0
      Source/Engine/Urho2D/RigidBody2D.cpp
  6. 78 52
      Source/ThirdParty/AngelScript/include/angelscript.h
  7. 15 3
      Source/ThirdParty/AngelScript/source/as_array.h
  8. 17 1
      Source/ThirdParty/AngelScript/source/as_atomic.cpp
  9. 137 73
      Source/ThirdParty/AngelScript/source/as_builder.cpp
  10. 8 10
      Source/ThirdParty/AngelScript/source/as_builder.h
  11. 20 5
      Source/ThirdParty/AngelScript/source/as_bytecode.cpp
  12. 129 15
      Source/ThirdParty/AngelScript/source/as_callfunc.cpp
  13. 10 2
      Source/ThirdParty/AngelScript/source/as_callfunc.h
  14. 145 25
      Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp
  15. 7 1
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  16. 71 2
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  17. 44 1
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_mingw.cpp
  18. 45 1
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp
  19. 62 3
      Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  20. 507 135
      Source/ThirdParty/AngelScript/source/as_compiler.cpp
  21. 21 10
      Source/ThirdParty/AngelScript/source/as_compiler.h
  22. 119 47
      Source/ThirdParty/AngelScript/source/as_config.h
  23. 1 1
      Source/ThirdParty/AngelScript/source/as_configgroup.cpp
  24. 95 40
      Source/ThirdParty/AngelScript/source/as_context.cpp
  25. 3 3
      Source/ThirdParty/AngelScript/source/as_context.h
  26. 91 47
      Source/ThirdParty/AngelScript/source/as_datatype.cpp
  27. 26 18
      Source/ThirdParty/AngelScript/source/as_datatype.h
  28. 9 3
      Source/ThirdParty/AngelScript/source/as_debug.h
  29. 67 23
      Source/ThirdParty/AngelScript/source/as_gc.cpp
  30. 3 2
      Source/ThirdParty/AngelScript/source/as_gc.h
  31. 15 1
      Source/ThirdParty/AngelScript/source/as_memory.cpp
  32. 73 9
      Source/ThirdParty/AngelScript/source/as_module.cpp
  33. 10 9
      Source/ThirdParty/AngelScript/source/as_module.h
  34. 3 2
      Source/ThirdParty/AngelScript/source/as_namespace.h
  35. 10 17
      Source/ThirdParty/AngelScript/source/as_objecttype.cpp
  36. 1 23
      Source/ThirdParty/AngelScript/source/as_objecttype.h
  37. 236 46
      Source/ThirdParty/AngelScript/source/as_parser.cpp
  38. 5 4
      Source/ThirdParty/AngelScript/source/as_parser.h
  39. 228 107
      Source/ThirdParty/AngelScript/source/as_restore.cpp
  40. 6 3
      Source/ThirdParty/AngelScript/source/as_restore.h
  41. 308 197
      Source/ThirdParty/AngelScript/source/as_scriptengine.cpp
  42. 53 38
      Source/ThirdParty/AngelScript/source/as_scriptengine.h
  43. 202 21
      Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp
  44. 21 7
      Source/ThirdParty/AngelScript/source/as_scriptfunction.h
  45. 3 2
      Source/ThirdParty/AngelScript/source/as_scriptnode.h
  46. 37 21
      Source/ThirdParty/AngelScript/source/as_scriptobject.cpp
  47. 54 3
      Source/ThirdParty/AngelScript/source/as_string.cpp
  48. 6 3
      Source/ThirdParty/AngelScript/source/as_string.h
  49. 25 15
      Source/ThirdParty/AngelScript/source/as_symboltable.h
  50. 65 56
      Source/ThirdParty/AngelScript/source/as_texts.h
  51. 3 1
      Source/ThirdParty/AngelScript/source/as_tokendef.h
  52. 4 3
      Source/ThirdParty/AngelScript/source/as_tokenizer.cpp
  53. 1 1
      Source/ThirdParty/SDL/src/video/uikit/SDL_uikitappdelegate.m

+ 1 - 1
Docs/Urho3D.dox

@@ -114,7 +114,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 
 Urho3D uses the following third-party libraries:
 
-- AngelScript 2.28.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.29.0 (http://www.angelcode.com/angelscript/)
 - Box2D 2.3.0 (http://box2d.org/)
 - Bullet 2.82 (http://www.bulletphysics.org/)
 - Civetweb (http://sourceforge.net/projects/civetweb/)

+ 1 - 1
Readme.txt

@@ -76,7 +76,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org) and Horde3D
   http://warp.povusers.org/SortComparison/
 
 Urho3D uses the following third-party libraries:
-- AngelScript 2.28.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.29.0 (http://www.angelcode.com/angelscript/)
 - Box2D 2.3.0 (http://box2d.org/)
 - Bullet 2.82 (http://www.bulletphysics.org/)
 - Civetweb (http://sourceforge.net/projects/civetweb/)

+ 3 - 2
Source/Engine/Script/Addons.cpp

@@ -1376,8 +1376,9 @@ void CScriptArray::Precache()
                 if( !isCmp && !isEq )
                     continue;
 
-                // The parameter must either be a reference to the subtype or a handle to the subtype            
-                int paramTypeId = func->GetParamTypeId(0, &flags);
+                // The parameter must either be a reference to the subtype or a handle to the subtype
+                int paramTypeId;
+                func->GetParam(0, &paramTypeId, &flags);
 
                 if( (paramTypeId & ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) != (subTypeId &  ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) )
                     continue;

+ 4 - 3
Source/Engine/Script/ScriptFile.cpp

@@ -645,9 +645,10 @@ void ScriptFile::SetParameters(asIScriptContext* context, asIScriptFunction* fun
     unsigned paramCount = function->GetParamCount();
     for (unsigned i = 0; i < parameters.Size() && i < paramCount; ++i)
     {
-        int paramType = function->GetParamTypeId(i);
+        int paramTypeId;
+        function->GetParam(i, &paramTypeId);
         
-        switch (paramType)
+        switch (paramTypeId)
         {
         case asTYPEID_BOOL:
             context->SetArgByte(i, (unsigned char)parameters[i].GetBool());
@@ -673,7 +674,7 @@ void ScriptFile::SetParameters(asIScriptContext* context, asIScriptFunction* fun
             break;
             
         default:
-            if (paramType & asTYPEID_APPOBJECT)
+            if (paramTypeId & asTYPEID_APPOBJECT)
             {
                 switch (parameters[i].GetType())
                 {

+ 2 - 0
Source/Engine/Urho2D/RigidBody2D.cpp

@@ -57,6 +57,8 @@ RigidBody2D::RigidBody2D(Context* context) :
     useFixtureMass_(true),
     body_(0)
 {
+    // Make sure the massData's center is zero-initialized as well
+    massData_.center.SetZero();
 }
 
 RigidBody2D::~RigidBody2D()

+ 78 - 52
Source/ThirdParty/AngelScript/include/angelscript.h

@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 // AngelScript version
 
-#define ANGELSCRIPT_VERSION        22801
-#define ANGELSCRIPT_VERSION_STRING "2.28.1"
+#define ANGELSCRIPT_VERSION        22900
+#define ANGELSCRIPT_VERSION_STRING "2.29.0"
 
 // Data types
 
@@ -147,25 +147,27 @@ enum asECallConvTypes
 	asCALL_THISCALL          = 3,
 	asCALL_CDECL_OBJLAST     = 4,
 	asCALL_CDECL_OBJFIRST    = 5,
-	asCALL_GENERIC           = 6
+	asCALL_GENERIC           = 6,
+	asCALL_THISCALL_OBJLAST  = 7,
+	asCALL_THISCALL_OBJFIRST = 8
 };
 
 // Object type flags
 enum asEObjTypeFlags
 {
-	asOBJ_REF                        = 0x01,
-	asOBJ_VALUE                      = 0x02,
-	asOBJ_GC                         = 0x04,
-	asOBJ_POD                        = 0x08,
-	asOBJ_NOHANDLE                   = 0x10,
-	asOBJ_SCOPED                     = 0x20,
-	asOBJ_TEMPLATE                   = 0x40,
-	asOBJ_ASHANDLE                   = 0x80,
-	asOBJ_APP_CLASS                  = 0x100,
-	asOBJ_APP_CLASS_CONSTRUCTOR      = 0x200,
-	asOBJ_APP_CLASS_DESTRUCTOR       = 0x400,
-	asOBJ_APP_CLASS_ASSIGNMENT       = 0x800,
-	asOBJ_APP_CLASS_COPY_CONSTRUCTOR = 0x1000,
+	asOBJ_REF                        = (1<<0),
+	asOBJ_VALUE                      = (1<<1),
+	asOBJ_GC                         = (1<<2),
+	asOBJ_POD                        = (1<<3),
+	asOBJ_NOHANDLE                   = (1<<4),
+	asOBJ_SCOPED                     = (1<<5),
+	asOBJ_TEMPLATE                   = (1<<6),
+	asOBJ_ASHANDLE                   = (1<<7),
+	asOBJ_APP_CLASS                  = (1<<8),
+	asOBJ_APP_CLASS_CONSTRUCTOR      = (1<<9),
+	asOBJ_APP_CLASS_DESTRUCTOR       = (1<<10),
+	asOBJ_APP_CLASS_ASSIGNMENT       = (1<<11),
+	asOBJ_APP_CLASS_COPY_CONSTRUCTOR = (1<<12),
 	asOBJ_APP_CLASS_C                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_CONSTRUCTOR),
 	asOBJ_APP_CLASS_CD               = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_CONSTRUCTOR + asOBJ_APP_CLASS_DESTRUCTOR),
 	asOBJ_APP_CLASS_CA               = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_CONSTRUCTOR + asOBJ_APP_CLASS_ASSIGNMENT),
@@ -181,17 +183,24 @@ enum asEObjTypeFlags
 	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_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
-	asOBJ_APP_PRIMITIVE              = 0x2000,
-	asOBJ_APP_FLOAT                  = 0x4000,
-	asOBJ_APP_CLASS_ALLINTS          = 0x8000,
-	asOBJ_APP_CLASS_ALLFLOATS        = 0x10000,
-	asOBJ_NOCOUNT                    = 0x20000,
-	asOBJ_APP_CLASS_ALIGN8           = 0x40000,
-	asOBJ_MASK_VALID_FLAGS           = 0x7FFFF,
-	asOBJ_SCRIPT_OBJECT              = 0x80000,
-	asOBJ_SHARED                     = 0x100000,
-	asOBJ_NOINHERIT                  = 0x200000,
-	asOBJ_SCRIPT_FUNCTION            = 0x400000
+	asOBJ_APP_PRIMITIVE              = (1<<13),
+	asOBJ_APP_FLOAT                  = (1<<14),
+	asOBJ_APP_ARRAY                  = (1<<15),
+	asOBJ_APP_CLASS_ALLINTS          = (1<<16),
+	asOBJ_APP_CLASS_ALLFLOATS        = (1<<17),
+	asOBJ_NOCOUNT                    = (1<<18),
+	asOBJ_APP_CLASS_ALIGN8           = (1<<19),
+	asOBJ_MASK_VALID_FLAGS           = 0x0FFFFF,
+	// Internal flags
+	asOBJ_SCRIPT_OBJECT              = (1<<20),
+	asOBJ_SHARED                     = (1<<21),
+	asOBJ_NOINHERIT                  = (1<<22),
+	asOBJ_SCRIPT_FUNCTION            = (1<<23),
+	asOBJ_IMPLICIT_HANDLE            = (1<<24),
+	asOBJ_LIST_PATTERN               = (1<<25),
+	asOBJ_ENUM                       = (1<<26),
+	asOBJ_TEMPLATE_SUBTYPE           = (1<<27),
+	asOBJ_TYPEDEF                    = (1<<28)
 };
 
 // Behaviours
@@ -354,7 +363,7 @@ typedef unsigned int   asUINT;
     typedef long asINT64;
 #else
     typedef unsigned long asDWORD;
-  #if defined(__GNUC__) || defined(__MWERKS__)
+  #if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC)
     typedef uint64_t asQWORD;
     typedef int64_t asINT64;
   #else
@@ -379,6 +388,19 @@ typedef void (*asCLEANMODULEFUNC_t)(asIScriptModule *);
 typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
 typedef void (*asCLEANFUNCTIONFUNC_t)(asIScriptFunction *);
 typedef void (*asCLEANOBJECTTYPEFUNC_t)(asIObjectType *);
+typedef asIScriptContext *(*asREQUESTCONTEXTFUNC_t)(asIScriptEngine *, void *);
+typedef void (*asRETURNCONTEXTFUNC_t)(asIScriptEngine *, asIScriptContext *, void *);
+
+// Check if the compiler can use C++11 features
+#if !defined(_MSC_VER) || _MSC_VER >= 1700   // MSVC 2012
+#if !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)  // gnuc 4.7
+#if !(defined(__GNUC__) && defined(__cplusplus) && __cplusplus < 201103L) // g++ -std=c++11
+#if !defined(__SUNPRO_CC)
+#define AS_CAN_USE_CPP11 1
+#endif
+#endif
+#endif
+#endif
 
 // This macro does basically the same thing as offsetof defined in stddef.h, but
 // GNUC should not complain about the usage as I'm not using 0 as the base pointer.
@@ -530,8 +552,10 @@ extern "C"
 	AS_API int               asThreadCleanup();
 
 	// Memory management
-	AS_API int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
-	AS_API int asResetGlobalMemoryFunctions();
+	AS_API int   asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
+	AS_API int   asResetGlobalMemoryFunctions();
+	AS_API void *asAllocMem(size_t size);
+	AS_API void  asFreeMem(void *mem);
 
 	// Auxiliary
 	AS_API asILockableSharedBool *asCreateLockableSharedBool();
@@ -576,17 +600,18 @@ public:
 	// Object types
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags) = 0;
 	virtual int            RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset) = 0;
-	virtual int            RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
+	virtual int            RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0) = 0;
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0) = 0;
 	virtual int            RegisterInterface(const char *name) = 0;
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration) = 0;
 	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual asIObjectType *GetObjectTypeByName(const char *name) const = 0;
+	virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const = 0;
 
 	// String factory
 	virtual int RegisterStringFactory(const char *datatype, const asSFuncPtr &factoryFunc, asDWORD callConv, void *objForThiscall = 0) = 0;
-	virtual int GetStringFactoryReturnTypeId() const = 0;
+	virtual int GetStringFactoryReturnTypeId(asDWORD *flags = 0) const = 0;
 
 	// Default array type
 	virtual int RegisterDefaultArrayType(const char *type) = 0;
@@ -636,15 +661,6 @@ public:
 
 	// Script execution
 	virtual asIScriptContext      *CreateContext() = 0;
-#ifdef AS_DEPRECATED
-	// Deprecated since 2.27.0, 2013-07-18
-	virtual void                  *CreateScriptObject(int typeId) = 0;
-	virtual void                  *CreateScriptObjectCopy(void *obj, int typeId) = 0;
-	virtual void                  *CreateUninitializedScriptObject(int typeId) = 0;
-	virtual void                   AssignScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
-	virtual void                   ReleaseScriptObject(void *obj, int typeId) = 0;
-	virtual void                   AddRefScriptObject(void *obj, int typeId) = 0;
-#endif
 	virtual void                  *CreateScriptObject(const asIObjectType *type) = 0;
 	virtual void                  *CreateScriptObjectCopy(void *obj, const asIObjectType *type) = 0;
 	virtual void                  *CreateUninitializedScriptObject(const asIObjectType *type) = 0;
@@ -655,11 +671,16 @@ public:
 	virtual bool                   IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const = 0;
 	virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const = 0;
 
+	// Context pooling
+	virtual asIScriptContext      *RequestContext() = 0;
+	virtual void                   ReturnContext(asIScriptContext *ctx) = 0;
+	virtual int                    SetContextCallbacks(asREQUESTCONTEXTFUNC_t requestCtx, asRETURNCONTEXTFUNC_t returnCtx, void *param = 0) = 0;
+
 	// String interpretation
 	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, int *tokenLength = 0) const = 0;
 
 	// Garbage collection
-	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE) = 0;
+	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1) = 0;
 	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed = 0, asUINT *totalDetected = 0, asUINT *newObjects = 0, asUINT *totalNewDestroyed = 0) const = 0;
 	virtual int  NotifyGarbageCollectorOfNewObject(void *obj, asIObjectType *type) = 0;
 	virtual int  GetObjectInGC(asUINT idx, asUINT *seqNbr = 0, void **obj = 0, asIObjectType **type = 0) = 0;
@@ -669,9 +690,9 @@ public:
 	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
 	virtual void *GetUserData(asPWORD type = 0) const = 0;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback, asPWORD type = 0) = 0;
-	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback) = 0;
-	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
-	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback, asPWORD type = 0) = 0;
+	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type = 0) = 0;
+	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type = 0) = 0;
 	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type = 0) = 0;
 
 protected:
@@ -722,6 +743,7 @@ public:
 	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual asIObjectType *GetObjectTypeByName(const char *name) const = 0;
+	virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const = 0;
 	virtual int            GetTypeIdByDecl(const char *decl) const = 0;
 
 	// Enums
@@ -749,8 +771,8 @@ public:
 	virtual int LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped = 0) = 0;
 
 	// User data
-	virtual void *SetUserData(void *data) = 0;
-	virtual void *GetUserData() const = 0;
+	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
+	virtual void *GetUserData(asPWORD type = 0) const = 0;
 
 protected:
 	virtual ~asIScriptModule() {}
@@ -827,8 +849,8 @@ public:
 	virtual asIScriptFunction *GetSystemFunction() = 0;
 
 	// User data
-	virtual void *SetUserData(void *data) = 0;
-	virtual void *GetUserData() const = 0;
+	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
+	virtual void *GetUserData(asPWORD type = 0) const = 0;
 
 protected:
 	virtual ~asIScriptContext() {}
@@ -982,14 +1004,18 @@ public:
 	virtual const char      *GetObjectName() const = 0;
 	virtual const char      *GetName() const = 0;
 	virtual const char      *GetNamespace() const = 0;
-	virtual const char      *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false) const = 0;
+	virtual const char      *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const = 0;
 	virtual bool             IsReadOnly() const = 0;
 	virtual bool             IsPrivate() const = 0;
 	virtual bool             IsFinal() const = 0;
 	virtual bool             IsOverride() const = 0;
 	virtual bool             IsShared() 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;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.29.0, 2014-04-06
 	virtual int              GetParamTypeId(asUINT index, asDWORD *flags = 0) const = 0;
+#endif
 	virtual int              GetReturnTypeId(asDWORD *flags = 0) const = 0;
 
 	// Type id for function pointers 
@@ -1011,8 +1037,8 @@ public:
 	virtual asDWORD         *GetByteCode(asUINT *length = 0) = 0;
 
 	// User data
-	virtual void            *SetUserData(void *userData) = 0;
-	virtual void            *GetUserData() const = 0;
+	virtual void            *SetUserData(void *userData, asPWORD type = 0) = 0;
+	virtual void            *GetUserData(asPWORD type = 0) const = 0;
 
 protected:
 	virtual ~asIScriptFunction() {};

+ 15 - 3
Source/ThirdParty/AngelScript/source/as_array.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -70,7 +70,7 @@ public:
 	T       *AddressOf();
 	const T *AddressOf() const;
 
-	void Concatenate(const asCArray<T> &);
+	bool Concatenate(const asCArray<T> &);
 	void Concatenate(T*, unsigned int count);
 
 	bool Exists(const T &element) const;
@@ -443,16 +443,28 @@ bool asCArray<T>::operator !=(const asCArray<T> &other) const
 	return !(*this == other);
 }
 
+
+// Returns false if the concatenation wasn't successful due to out of memory
 template <class T>
-void asCArray<T>::Concatenate(const asCArray<T> &other)
+bool asCArray<T>::Concatenate(const asCArray<T> &other)
 {
 	if( maxLength < length + other.length )
+	{
 		Allocate(length + other.length, true);
+		if( maxLength < length + other.length )
+		{
+			// Out of memory
+			return false;
+		}
+	}
 
 	for( size_t n = 0; n < other.length; n++ )
 		array[length+n] = other.array[n];
 
 	length += other.length;
+
+	// Success
+	return true;
 }
 
 template <class T>

+ 17 - 1
Source/ThirdParty/AngelScript/source/as_atomic.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -45,21 +45,37 @@ asCAtomic::asCAtomic()
 
 asDWORD asCAtomic::get() const
 {
+	// A very high ref count is highly unlikely. It most likely a problem with
+	// memory that has been overwritten or is being accessed after it was deleted.
+	asASSERT(value < 1000000);
+
 	return value;
 }
 
 void asCAtomic::set(asDWORD val)
 {
+	// A very high ref count is highly unlikely. It most likely a problem with
+	// memory that has been overwritten or is being accessed after it was deleted.
+	asASSERT(value < 1000000);
+
 	value = val;
 }
 
 asDWORD asCAtomic::atomicInc()
 {
+	// A very high ref count is highly unlikely. It most likely a problem with
+	// memory that has been overwritten or is being accessed after it was deleted.
+	asASSERT(value < 1000000);
+
 	return asAtomicInc((int&)value);
 }
 
 asDWORD asCAtomic::atomicDec()
 {
+	// A very high ref count is highly unlikely. It most likely a problem with
+	// memory that has been overwritten or is being accessed after it was deleted.
+	asASSERT(value < 1000000);
+
 	return asAtomicDec((int&)value);
 }
 

+ 137 - 73
Source/ThirdParty/AngelScript/source/as_builder.cpp

@@ -56,8 +56,8 @@ BEGIN_AS_NAMESPACE
 template<>
 void asCSymbolTable<sGlobalVariableDescription>::GetKey(const sGlobalVariableDescription *entry, asSNameSpaceNamePair &key) const
 {
-	asSNameSpace *ns = entry->property->nameSpace;
-	asCString name = entry->property->name;
+	asSNameSpace *ns = entry->ns;
+	asCString name = entry->name;
 	key = asSNameSpaceNamePair(ns, name);
 }
 
@@ -81,10 +81,10 @@ private:
 
 #endif
 
-asCBuilder::asCBuilder(asCScriptEngine *engine, asCModule *module)
+asCBuilder::asCBuilder(asCScriptEngine *_engine, asCModule *_module)
 {
-	this->engine = engine;
-	this->module = module;
+	this->engine = _engine;
+	this->module = _module;
 	silent = false;
 }
 
@@ -207,7 +207,7 @@ void asCBuilder::Reset()
 {
 	numErrors = 0;
 	numWarnings = 0;
-	preMessage.isSet = false;
+	engine->preMessage.isSet = false;
 
 #ifndef AS_NO_COMPILER
 	// Clear the cache of known types
@@ -243,9 +243,11 @@ int asCBuilder::Build()
 
 	ParseScripts();
 
+	// Compile the global variables first, so the auto types can be
+	// resolved before the variables is used else where in the code
+	CompileGlobalVariables();
 	CompileInterfaces();
 	CompileClasses();
-	CompileGlobalVariables();
 	CompileFunctions();
 
 	// TODO: Attempt to reorder the initialization of global variables so that
@@ -384,8 +386,7 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	if( func == 0 )
 		return asOUT_OF_MEMORY;
 
-	asCArray<asCString> parameterNames;
-	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, func->isReadOnly, isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared, module->defaultNamespace);
+	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, func->isReadOnly, isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared, module->defaultNamespace);
 	func->id                           = engine->GetNextScriptFunctionId();
 	func->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
 	int row, col;
@@ -432,11 +433,11 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	funcDesc->node              = node;
 	funcDesc->name              = func->name;
 	funcDesc->funcId            = func->id;
-	funcDesc->paramNames        = parameterNames;
+	funcDesc->paramNames        = func->parameterNames;
 	funcDesc->isExistingShared  = false;
 
 	asCCompiler compiler(engine);
-	compiler.CompileFunction(this, functions[0]->script, parameterNames, functions[0]->node, func, 0);
+	compiler.CompileFunction(this, functions[0]->script, func->parameterNames, functions[0]->node, func, 0);
 
 	if( numWarnings > 0 && engine->ep.compilerWarnings == 2 )
 		WriteError(TXT_WARNINGS_TREATED_AS_ERROR, 0, 0);
@@ -746,7 +747,7 @@ void asCBuilder::CompileFunctions()
 			// When compiling a constructor need to pass the class declaration for member initializations
 			compiler.CompileFunction(this, current->script, current->paramNames, current->node, func, classDecl);
 
-			preMessage.isSet = false;
+			engine->preMessage.isSet = false;
 		}
 		else if( current->objType && current->name == current->objType->name )
 		{
@@ -764,7 +765,7 @@ void asCBuilder::CompileFunctions()
 			// automatically if not implemented by the user.
 			compiler.CompileDefaultConstructor(this, current->script, node, func, classDecl);
 
-			preMessage.isSet = false;
+			engine->preMessage.isSet = false;
 		}
 		else
 		{
@@ -816,7 +817,7 @@ int asCBuilder::ParseTemplateDecl(const char *decl, asCString *name, asCArray<as
 	asCScriptNode *node = parser.GetScriptNode()->firstChild;
 
 	name->Assign(&decl[node->tokenPos], node->tokenLength);
-	while( (node = node->next) )
+	while( (node = node->next) != 0 )
 	{
 		asCString subtypeName;
 		subtypeName.Assign(&decl[node->tokenPos], node->tokenLength);
@@ -913,32 +914,20 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
 }
 #endif
 
-asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp)
+bool asCBuilder::DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp, sGlobalVariableDescription **outDesc, bool *isAppProp)
 {
-	if( isCompiled )     *isCompiled     = true;
-	if( isPureConstant ) *isPureConstant = false;
-	if( isAppProp )      *isAppProp      = false;
+	if( outProp )   *outProp = 0;
+	if( outDesc )   *outDesc = 0;
+	if( isAppProp ) *isAppProp = false;
 
 	// Check application registered properties
 	asCString name(prop);
 	asCGlobalProperty *globProp = engine->registeredGlobalProps.GetFirst(ns, name);
 	if( globProp )
 	{
-		if( module )
-		{
-			// Determine if the module has access to the property
-			if( module->accessMask & globProp->accessMask )
-			{
-				if( isAppProp ) *isAppProp = true;
-				return globProp;
-			}
-		}
-		else
-		{
-			// We're not compiling a module right now, so it must be a registered global property
-			if( isAppProp ) *isAppProp = true;
-			return globProp;
-		}
+		if( isAppProp ) *isAppProp = true;
+		if( outProp )   *outProp   = globProp;
+		return true;
 	}
 
 #ifndef AS_NO_COMPILER
@@ -946,18 +935,55 @@ asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace
 	sGlobalVariableDescription* desc = globVariables.GetFirst(ns, prop);
 	if( desc && !desc->isEnumValue )
 	{
-		if( isCompiled )     *isCompiled     = desc->isCompiled;
-		if( isPureConstant ) *isPureConstant = desc->isPureConstant;
-		if( constantValue  ) *constantValue  = desc->constantValue;
-		return desc->property;
+		if( outProp ) *outProp = desc->property;
+		if( outDesc ) *outDesc = desc;
+		return true;
 	}
-#else
-	UNUSED_VAR(constantValue);
 #endif
 
 	// Check previously compiled global variables
 	if( module )
-		return module->scriptGlobals.GetFirst(ns, prop);
+	{
+		globProp = module->scriptGlobals.GetFirst(ns, prop);
+		if( globProp )
+		{
+			if( outProp ) *outProp = globProp;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp)
+{
+	if( isCompiled )     *isCompiled     = true;
+	if( isPureConstant ) *isPureConstant = false;
+	if( isAppProp )      *isAppProp      = false;
+	if( constantValue )  *constantValue  = 0;
+
+	asCGlobalProperty          *globProp = 0;
+	sGlobalVariableDescription *globDesc = 0;
+	if( DoesGlobalPropertyExist(prop, ns, &globProp, &globDesc, isAppProp) )
+	{
+#ifndef AS_NO_COMPILER
+		if( globDesc )
+		{
+			// The property was declared in this build call, check if it has been compiled successfully already
+			if( isCompiled )     *isCompiled     = globDesc->isCompiled;
+			if( isPureConstant ) *isPureConstant = globDesc->isPureConstant;
+			if( constantValue  ) *constantValue  = globDesc->constantValue;
+		}
+		else 
+#endif
+		if( isAppProp )
+		{
+			// Don't return the property if the module doesn't have access to it
+			if( !(module->accessMask & globProp->accessMask) )
+				globProp = 0;
+		}
+		return globProp;
+	}
 
 	return 0;
 }
@@ -1025,11 +1051,13 @@ int asCBuilder::ParseFunctionDeclaration(asCObjectType *objType, const char *dec
 
 	// Preallocate memory
 	func->parameterTypes.Allocate(paramCount, false);
+	func->parameterNames.SetLength(paramCount);
 	func->inOutFlags.Allocate(paramCount, false);
 	func->defaultArgs.Allocate(paramCount, false);
 	if( paramAutoHandles ) paramAutoHandles->Allocate(paramCount, false);
 
 	n = paramList->firstChild;
+	asUINT index = 0;
 	while( n )
 	{
 		asETypeModifiers inOutFlags;
@@ -1064,8 +1092,11 @@ int asCBuilder::ParseFunctionDeclaration(asCObjectType *objType, const char *dec
 
 		// Move to next parameter
 		n = n->next->next;
-		if( n && n->nodeType == snIdentifier )
+		if( n && n->nodeType == snIdentifier ) {
+			func->parameterNames[index] = asCString(&source.code[n->tokenPos], n->tokenLength);
 			n = n->next;
+		}
+		++index;
 
 		if( n && n->nodeType == snExpression )
 		{
@@ -1215,10 +1246,8 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 		return -1;
 	}
 
-	// TODO: Must verify global properties in all config groups, whether the module has access or not
 	// Check against global properties
-	asCGlobalProperty *prop = GetGlobalProperty(name, ns, 0, 0, 0, 0);
-	if( prop )
+	if( DoesGlobalPropertyExist(name, ns) )
 	{
 		if( code )
 		{
@@ -1356,7 +1385,6 @@ int asCBuilder::RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNam
 
 void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 {
-	asCArray<asCString>        parameterNames;
 	asCArray<asCString *>      defaultArgs;
 	bool                       isConstMethod;
 	bool                       isConstructor;
@@ -1369,7 +1397,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 	asCScriptFunction *func = module->funcDefs[funcDef->idx];
 	asASSERT( func );
 
-	GetParsedFunctionDetails(funcDef->node, funcDef->script, 0, funcDef->name, func->returnType, parameterNames, func->parameterTypes, func->inOutFlags, defaultArgs, isConstMethod, isConstructor, isDestructor, isPrivate, isOverride, isFinal, isShared, func->nameSpace);
+	GetParsedFunctionDetails(funcDef->node, funcDef->script, 0, funcDef->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, defaultArgs, isConstMethod, isConstructor, isDestructor, isPrivate, isOverride, isFinal, isShared, func->nameSpace);
 
 	// There should not be any defaultArgs, but if there are any we need to delete them to avoid leaks
 	for( asUINT n = 0; n < defaultArgs.GetLength(); n++ )
@@ -1446,12 +1474,14 @@ int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSN
 		gvar->isCompiled  = false;
 		gvar->datatype    = type;
 		gvar->isEnumValue = false;
+		gvar->ns          = ns;
 
 		// TODO: Give error message if wrong
 		asASSERT(!gvar->datatype.IsReference());
 
-		gvar->property = module->AllocateGlobalProperty(name.AddressOf(), gvar->datatype, ns);
-		gvar->index    = gvar->property->id;
+		// Allocation is done when the variable is compiled, to allow for autos
+		gvar->property = 0;
+		gvar->index    = 0;
 
 		globVariables.Put(gvar);
 
@@ -1606,7 +1636,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 	// is known, can the flag be cleared for those objects that truly cannot
 	// form circular references. This is important because a template
 	// callback may be called with a script class before the compilation
-	// complete, and until it is known, the callback must assume the class
+	// completes, and until it is known, the callback must assume the class
 	// is garbage collected.
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT | asOBJ_GC;
 
@@ -1876,7 +1906,7 @@ void asCBuilder::CompileGlobalVariables()
 				}
 
 				// Set the namespace that should be used for this function
-				initFunc->nameSpace = gvar->property->nameSpace;
+				initFunc->nameSpace = gvar->ns;
 
 				asCCompiler comp(engine);
 				int r = comp.CompileGlobalVariable(this, gvar->script, gvar->initializationNode, gvar, initFunc);
@@ -1967,7 +1997,7 @@ void asCBuilder::CompileGlobalVariables()
 				accumWarnings += numWarnings;
 			}
 
-			preMessage.isSet = false;
+			engine->preMessage.isSet = false;
 		}
 
 		if( !compileSucceeded )
@@ -2038,7 +2068,8 @@ void asCBuilder::CompileGlobalVariables()
 
 			asDELETE(gvar, sGlobalVariableDescription);
 		}
-		it++;
+		else
+			it++;
 	}
 }
 
@@ -2508,6 +2539,8 @@ void asCBuilder::CompileClasses()
 			// added to the shared class that wasn't there in the previous
 			// compilation. We do not care if something that is there in the previous
 			// declaration is not included in the new declaration though.
+
+			asASSERT( decl->objType->interfaces.GetLength() == decl->objType->interfaceVFTOffsets.GetLength() );
 		}
 
 		// Methods included from mixin classes should take precedence over inherited methods
@@ -2742,6 +2775,8 @@ void asCBuilder::CompileClasses()
 
 		if( !decl->isExistingShared )
 			toValidate.PushLast(decl);
+
+		asASSERT( decl->objType->interfaces.GetLength() == decl->objType->interfaceVFTOffsets.GetLength() );
 	}
 
 	// TODO: Warn if a method overrides a base method without marking it as 'override'.
@@ -3009,7 +3044,20 @@ void asCBuilder::IncludeMethodsFromMixins(sClassDeclaration *decl)
 			continue;
 		}
 
-		sMixinClass *mixin = GetMixinClass(name.AddressOf(), ns);
+		sMixinClass *mixin = 0;
+		while( ns )
+		{
+			// Need to make sure the name is not an object type 
+			asCObjectType *objType = GetObjectType(name.AddressOf(), ns);
+			if( objType == 0 )
+				mixin = GetMixinClass(name.AddressOf(), ns);
+			
+			if( objType || mixin )
+				break;
+
+			ns = GetParentNameSpace(ns);
+		}
+
 		if( mixin )
 		{
 			// Find methods from mixin declaration
@@ -3071,7 +3119,20 @@ void asCBuilder::IncludePropertiesFromMixins(sClassDeclaration *decl)
 			continue;
 		}
 
-		sMixinClass *mixin = GetMixinClass(name.AddressOf(), ns);
+		sMixinClass *mixin = 0;
+		while( ns )
+		{
+			// Need to make sure the name is not an object type 
+			asCObjectType *objType = GetObjectType(name.AddressOf(), ns);
+			if( objType == 0 )
+				mixin = GetMixinClass(name.AddressOf(), ns);
+			
+			if( objType || mixin )
+				break;
+
+			ns = GetParentNameSpace(ns);
+		}
+
 		if( mixin )
 		{
 			// Find properties from mixin declaration
@@ -3270,10 +3331,11 @@ void asCBuilder::AddDefaultConstructor(asCObjectType *objType, asCScriptCode *fi
 	asCArray<asCDataType> parameterTypes;
 	asCArray<asETypeModifiers> inOutFlags;
 	asCArray<asCString *> defaultArgs;
+	asCArray<asCString> parameterNames;
 
 	// Add the script function
 	// TODO: declaredAt should be set to where the class has been declared
-	module->AddScriptFunction(file->idx, 0, funcId, objType->name, returnType, parameterTypes, inOutFlags, defaultArgs, false, objType);
+	module->AddScriptFunction(file->idx, 0, funcId, objType->name, returnType, parameterTypes, parameterNames, inOutFlags, defaultArgs, false, objType);
 
 	// Set it as default constructor
 	if( objType->beh.construct )
@@ -3308,7 +3370,7 @@ void asCBuilder::AddDefaultConstructor(asCObjectType *objType, asCScriptCode *fi
 	objType->beh.factories[0] = funcId;
 	returnType = asCDataType::CreateObjectHandle(objType, false);
 	// TODO: should be the same as the constructor
-	module->AddScriptFunction(file->idx, 0, funcId, objType->name, returnType, parameterTypes, inOutFlags, defaultArgs, false);
+	module->AddScriptFunction(file->idx, 0, funcId, objType->name, returnType, parameterTypes, parameterNames, inOutFlags, defaultArgs, false);
 	functions.PushLast(0);
 	asCCompiler compiler(engine);
 	compiler.CompileFactory(this, file, engine->scriptFunctions[funcId]);
@@ -3464,6 +3526,7 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
 				gvar->initializationNode = asnNode;
 				gvar->name               = name;
 				gvar->datatype           = type;
+				gvar->ns                 = ns;
 				// No need to allocate space on the global memory stack since the values are stored in the asCObjectType
 				// Set the index to a negative to allow compiler to diferentiate from ordinary global var when compiling the initialization
 				gvar->index              = -1; 
@@ -3978,7 +4041,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 		int row = 0, col = 0;
 		if( node )
 			file->ConvertPosToRowCol(node->tokenPos, &row, &col);
-		module->AddScriptFunction(file->idx, (row&0xFFFFF)|((col&0xFFF)<<20), funcId, name, returnType, parameterTypes, inOutFlags, defaultArgs, isInterface, objType, isConstMethod, isGlobalFunction, isPrivate, isFinal, isOverride, isShared, ns);
+		module->AddScriptFunction(file->idx, (row&0xFFFFF)|((col&0xFFF)<<20), funcId, name, returnType, parameterTypes, parameterNames, inOutFlags, defaultArgs, isInterface, objType, isConstMethod, isGlobalFunction, isPrivate, isFinal, isOverride, isShared, ns);
 	}
 
 	// Make sure the default args are declared correctly
@@ -4018,7 +4081,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
 					defaultArgs[n] = asNEW(asCString)(*defaultArgs[n]);
 
 			asCDataType dt = asCDataType::CreateObjectHandle(objType, false);
-			module->AddScriptFunction(file->idx, engine->scriptFunctions[funcId]->scriptData->declaredAt, factoryId, name, dt, parameterTypes, inOutFlags, defaultArgs, false);
+			module->AddScriptFunction(file->idx, engine->scriptFunctions[funcId]->scriptData->declaredAt, factoryId, name, dt, parameterTypes, parameterNames, inOutFlags, defaultArgs, false);
 
 			// If the object is shared, then the factory must also be marked as shared
 			if( objType->flags & asOBJ_SHARED )
@@ -4379,15 +4442,15 @@ void asCBuilder::WriteInfo(const asCString &scriptname, const asCString &message
 	// Need to store the pre message in a structure
 	if( pre )
 	{
-		preMessage.isSet = true;
-		preMessage.c = c;
-		preMessage.r = r;
-		preMessage.message = message;
-		preMessage.scriptname = scriptname;
+		engine->preMessage.isSet      = true;
+		engine->preMessage.c          = c;
+		engine->preMessage.r          = r;
+		engine->preMessage.message    = message;
+		engine->preMessage.scriptname = scriptname;
 	}
 	else
 	{
-		preMessage.isSet = false;
+		engine->preMessage.isSet = false;
 
 		if( !silent )
 			engine->WriteMessage(scriptname.AddressOf(), r, c, asMSGTYPE_INFORMATION, message.AddressOf());
@@ -4416,10 +4479,6 @@ void asCBuilder::WriteError(const asCString &scriptname, const asCString &messag
 {
 	numErrors++;
 
-	// Need to pass the preMessage first
-	if( preMessage.isSet )
-		WriteInfo(preMessage.scriptname, preMessage.message, preMessage.r, preMessage.c, false);
-
 	if( !silent )
 		engine->WriteMessage(scriptname.AddressOf(), r, c, asMSGTYPE_ERROR, message.AddressOf());
 }
@@ -4430,10 +4489,6 @@ void asCBuilder::WriteWarning(const asCString &scriptname, const asCString &mess
 	{
 		numWarnings++;
 
-		// Need to pass the preMessage first
-		if( preMessage.isSet )
-			WriteInfo(preMessage.scriptname, preMessage.message, preMessage.r, preMessage.c, false);
-
 		if( !silent )
 			engine->WriteMessage(scriptname.AddressOf(), r, c, asMSGTYPE_WARNING, message.AddressOf());
 	}
@@ -4691,6 +4746,10 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 			return dt;
 		}
 	}
+	else if( n->tokenType == ttAuto )
+	{
+		dt = asCDataType::CreateAuto(isConst);
+	}
 	else
 	{
 		// Create primitive data type
@@ -4722,7 +4781,12 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 		else
 		{
 			// Make the type a handle
-			if( dt.MakeHandle(true, acceptHandleForScope) < 0 )
+			if( dt.IsObjectHandle() )
+			{
+				WriteError(TXT_HANDLE_OF_HANDLE_IS_NOT_ALLOWED, file, n);
+				break;
+			}
+			else if( dt.MakeHandle(true, acceptHandleForScope) < 0 )
 			{
 				WriteError(TXT_OBJECT_HANDLE_NOT_SUPPORTED, file, n);
 				break;

+ 8 - 10
Source/ThirdParty/AngelScript/source/as_builder.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -51,6 +51,11 @@
 
 BEGIN_AS_NAMESPACE
 
+#ifdef AS_NO_COMPILER
+// Forward declare the structure, as it is part of some function signatures used even without the compiler
+struct sGlobalVariableDescription;
+#endif
+
 #ifndef AS_NO_COMPILER
 
 struct sFunctionDescription
@@ -72,6 +77,7 @@ struct sGlobalVariableDescription
 	asCString          name;
 	asCGlobalProperty *property;
 	asCDataType        datatype;
+	asSNameSpace      *ns;
 	int                index;
 	bool               isCompiled;
 	bool               isPureConstant;
@@ -161,6 +167,7 @@ protected:
 	void               WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
 	void               WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
 
+	bool               DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp = 0, sGlobalVariableDescription **outDesc = 0, bool *isAppProp = 0);
 	asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
 	int                ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
@@ -175,15 +182,6 @@ protected:
 	asCDataType        CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope = false, asCObjectType *currentType = 0);
 	asCDataType        ModifyDataTypeFromNode(const asCDataType &type, asCScriptNode *node, asCScriptCode *file, asETypeModifiers *inOutFlag, bool *autoHandle);
 
-	struct preMessage_t
-	{
-		bool isSet;
-		asCString message;
-		asCString scriptname;
-		int r;
-		int c;
-	} preMessage;
-
 	int numErrors;
 	int numWarnings;
 	bool silent;

+ 20 - 5
Source/ThirdParty/AngelScript/source/as_bytecode.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -864,7 +864,6 @@ void asCByteCode::OptimizeLocally(const asCArray<int> &tempVariableOffsets)
 
 				instr = GoForward(curr);
 			}
-
 		}
 		else if( currOp == asBC_RDSPtr )
 		{
@@ -1553,6 +1552,7 @@ int asCByteCode::GetSize()
 
 void asCByteCode::AddCode(asCByteCode *bc)
 {
+	if( bc == this ) return;
 	if( bc->first )
 	{
 		if( first == 0 )
@@ -2079,7 +2079,9 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 	fprintf(file, "Variables: \n");
 	for( n = 0; n < func->scriptData->variables.GetLength(); n++ )
 	{
-		fprintf(file, " %.3d: %s %s\n", func->scriptData->variables[n]->stackOffset, func->scriptData->variables[n]->type.Format().AddressOf(), func->scriptData->variables[n]->name.AddressOf());
+		int idx = func->scriptData->objVariablePos.IndexOf(func->scriptData->variables[n]->stackOffset);
+		bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
+		fprintf(file, " %.3d: %s%s %s\n", func->scriptData->variables[n]->stackOffset, isOnHeap ? "(heap) " : "", func->scriptData->variables[n]->type.Format().AddressOf(), func->scriptData->variables[n]->name.AddressOf());
 	}
 	asUINT offset = 0;
 	if( func->objectType )
@@ -2099,7 +2101,11 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			}
 		}
 		if( !found )
-			fprintf(file, " %.3d: %s {noname param}\n", offset, func->parameterTypes[n].Format().AddressOf());
+		{
+			int idx = func->scriptData->objVariablePos.IndexOf(offset);
+			bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
+			fprintf(file, " %.3d: %s%s {noname param}\n", offset, isOnHeap ? "(heap) " : "", func->parameterTypes[n].Format().AddressOf());
+		}
 
 		offset -= func->parameterTypes[n].GetSizeOnStackDWords();
 	}
@@ -2115,7 +2121,16 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			}
 		}
 		if( !found )
-			fprintf(file, " %.3d: %s {noname}\n", func->scriptData->objVariablePos[n], func->scriptData->objVariableTypes[n]->name.AddressOf());
+		{
+			if( func->scriptData->objVariableTypes[n] )
+			{
+				int idx = func->scriptData->objVariablePos.IndexOf(func->scriptData->objVariablePos[n]);
+				bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
+				fprintf(file, " %.3d: %s%s {noname}\n", func->scriptData->objVariablePos[n], isOnHeap ? "(heap) " : "", func->scriptData->objVariableTypes[n]->name.AddressOf());
+			}
+			else
+				fprintf(file, " %.3d: null handle {noname}\n", func->scriptData->objVariablePos[n]);
+		}
 	}
 	fprintf(file, "\n\n");
 

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

@@ -57,9 +57,9 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 	{
 		if( ptr.flag == 1 && callConv != asCALL_GENERIC )
 			return asWRONG_CALLING_CONV;
-		else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
+		else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
 			return asWRONG_CALLING_CONV;
-		else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
+		else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
 			return asWRONG_CALLING_CONV;
 	}
 
@@ -90,12 +90,36 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 	if( isMethod )
 	{
 #ifndef AS_NO_CLASS_METHODS
-		if( base == asCALL_THISCALL )
+		if( base == asCALL_THISCALL || base == asCALL_THISCALL_OBJFIRST || base == asCALL_THISCALL_OBJLAST )
 		{
-			internal->callConv = ICC_THISCALL;
+			internalCallConv thisCallConv;
+			if( base == asCALL_THISCALL )
+			{
+				if( callConv != asCALL_THISCALL_ASGLOBAL && objForThiscall )
+					return asINVALID_ARG;
+
+				thisCallConv = ICC_THISCALL;
+			}
+			else
+			{
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
+				return asNOT_SUPPORTED;
+#endif
+
+				if( objForThiscall == 0 )
+					return asINVALID_ARG;
+
+				internal->objForThiscall = objForThiscall;
+				if( base == asCALL_THISCALL_OBJFIRST )
+					thisCallConv = ICC_THISCALL_OBJFIRST;
+				else //if( base == asCALL_THISCALL_OBJLAST )
+					thisCallConv = ICC_THISCALL_OBJLAST;
+			}
+
+			internal->callConv = thisCallConv;
 #ifdef GNU_STYLE_VIRTUAL_METHOD
 			if( (size_t(ptr.ptr.f.func) & 1) )
-				internal->callConv = ICC_VIRTUAL_THISCALL;
+				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
 			internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
 #if defined(AS_ARM) && defined(__GNUC__)
@@ -103,7 +127,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 			// on ARM processors, the LSB in the __delta variable is used instead of
 			// the one in __pfn on ARM processors.
 			if( (size_t(internal->baseOffset) & 1) )
-				internal->callConv = ICC_VIRTUAL_THISCALL;
+				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
 
 #ifdef HAVE_VIRTUAL_BASE_OFFSET
@@ -142,11 +166,14 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
 int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
 {
 #ifdef AS_MAX_PORTABILITY
+	UNUSED_VAR(func);
+	UNUSED_VAR(internal);
+	UNUSED_VAR(engine);
+
 	// This should never happen, as when AS_MAX_PORTABILITY is on, all functions 
 	// are asCALL_GENERIC, which are prepared by PrepareSystemFunctionGeneric
 	asASSERT(false);
-#endif
-
+#else
 	// References are always returned as primitive data
 	if( func->returnType.IsReference() || func->returnType.IsObjectHandle() )
 	{
@@ -162,7 +189,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 		// Only value types can be returned by value
 		asASSERT( objType & asOBJ_VALUE );
 
-		if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT)) )
+		if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
 		{
 			// If the return is by value then we need to know the true type
 			engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
@@ -172,6 +199,13 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 			engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 		}
+		else if( objType & asOBJ_APP_ARRAY )
+		{
+			// Array types are always returned in memory
+			internal->hostReturnInMemory = true;
+			internal->hostReturnSize     = sizeof(void*)/4;
+			internal->hostReturnFloat = false;
+		}
 		else if( objType & asOBJ_APP_CLASS )
 		{
 			internal->hostReturnFloat = false;
@@ -203,7 +237,13 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 
 #ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
 				if((internal->callConv == ICC_THISCALL ||
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 					internal->callConv == ICC_VIRTUAL_THISCALL) &&
+#else
+					internal->callConv == ICC_VIRTUAL_THISCALL ||
+					internal->callConv == ICC_THISCALL_OBJFIRST ||
+					internal->callConv == ICC_THISCALL_OBJLAST) &&
+#endif
 					func->returnType.GetSizeInMemoryDWords() >= THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
 				{
 					internal->hostReturnInMemory = true;
@@ -313,7 +353,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			internal->takesObjByVal = true;
 
 			// Can't pass objects by value unless the application type is informed
-			if( !(func->parameterTypes[n].GetObjectType()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT)) )
+			if( !(func->parameterTypes[n].GetObjectType()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
 			{
 				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
 	
@@ -360,7 +400,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 			break;
 		}
 	}
-
+#endif // !defined(AS_MAX_PORTABILITY)
 	return 0;
 }
 
@@ -401,6 +441,8 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 //
 // The function should return the value that is returned in registers. 
 //
+// When thiscall functors are enabled (!AS_NO_THISCALL_FUNCTOR_METHOD) the 
+// obj argument is a an array of 2 void* holding the two possible this pointers
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2);
 
 
@@ -418,9 +460,11 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	asQWORD  retQW2            = 0;
 	asDWORD *args              = context->m_regs.stackPointer;
 	void    *retPointer        = 0;
-	void    *obj               = 0;
 	int      popSize           = sysFunc->paramSize;
 
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
+	void    *obj               = 0;
+
 	if( callConv >= ICC_THISCALL )
 	{
 		if( sysFunc->objForThiscall )
@@ -460,7 +504,74 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			args += AS_PTR_SIZE;
 		}
 	}
-	
+#else
+	// TODO: clean-up: CallSystemFunctionNative should have two arguments for object pointers
+	//                 objForThiscall is the object pointer that should be used for the thiscall
+	//                 objForArg is the object pointer that should be passed as argument when using OBJFIRST or OBJLAST
+
+	// Used to save two object pointers with THISCALL_OBJLAST or THISCALL_OBJFIRST
+	void* objectsPtrs[2] = { 0, 0 };
+
+	if( callConv >= ICC_THISCALL )
+	{
+		bool continueCheck = true;  // True if need check objectPointer or context stack for object
+		int continueCheckIndex = 0; // Index into objectsPtrs to save the object if continueCheck
+
+		if( callConv >= ICC_THISCALL_OBJLAST )
+		{
+			asASSERT( sysFunc->objForThiscall != 0 );
+			// This class method is being called as object method (sysFunc->objForThiscall must be set).
+			objectsPtrs[0] = sysFunc->objForThiscall;
+			continueCheckIndex = 1;
+		}
+		else if( sysFunc->objForThiscall )
+		{
+			// This class method is being called as if it is a global function
+			objectsPtrs[0] = sysFunc->objForThiscall;
+			continueCheck = false;
+			asASSERT( objectPointer == 0 );
+		}
+
+		if( continueCheck )
+		{
+			void *tempPtr = 0;
+			if( objectPointer )
+			{
+				tempPtr = objectPointer;
+			}
+			else
+			{
+				// The object pointer should be popped from the context stack
+				popSize += AS_PTR_SIZE;
+
+				// Check for null pointer
+				tempPtr = (void*)*(asPWORD*)(args);
+				if( tempPtr == 0 )
+				{
+					context->SetInternalException(TXT_NULL_POINTER_ACCESS);
+					return 0;
+				}
+
+				// Add the base offset for multiple inheritance
+#if defined(__GNUC__) && defined(AS_ARM)
+				// 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
+				tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
+#else
+				tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
+#endif
+
+				// Skip the object pointer
+				args += AS_PTR_SIZE;
+			}
+
+			objectsPtrs[continueCheckIndex] = tempPtr;
+		}
+	}
+	void *obj = &objectsPtrs[0]; // Get the pointer to first element
+#endif // AS_NO_THISCALL_FUNCTOR_METHOD
+
 	if( descr->DoesReturnOnStack() )
 	{
 		// Get the address of the location for the return value from the stack
@@ -479,6 +590,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	}
 
 	context->m_callingSystemFunction = descr;
+	bool cppException = false;
 #ifdef AS_NO_EXCEPTIONS
 	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
 #else
@@ -493,6 +605,8 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	}
 	catch(...)
 	{
+		cppException = true;
+
 		// Convert the exception to a script exception so the VM can 
 		// properly report the error to the application and then clean up
 		context->SetException(TXT_EXCEPTION_CAUGHT);
@@ -516,7 +630,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 		{
 			bool needFree = false;
 			asCDataType &dt = descr->parameterTypes[n];
-#ifdef COMPLEX_OBJS_PASSED_BY_REF				
+#ifdef COMPLEX_OBJS_PASSED_BY_REF
 			if( dt.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
 #endif
 #ifdef AS_LARGE_OBJS_PASSED_BY_REF
@@ -595,7 +709,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 				}
 			}
 
-			if( context->m_status == asEXECUTION_EXCEPTION )
+			if( context->m_status == asEXECUTION_EXCEPTION && !cppException )
 			{
 				// If the function raised a script exception it really shouldn't have 
 				// initialized the object. However, as it is a soft exception there is 

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -83,7 +83,15 @@ enum internalCallConv
 	ICC_CDECL_OBJFIRST,
 	ICC_CDECL_OBJFIRST_RETURNINMEM,
 	ICC_GENERIC_METHOD,
-	ICC_GENERIC_METHOD_RETURNINMEM // never used
+	ICC_GENERIC_METHOD_RETURNINMEM, // never used
+	ICC_THISCALL_OBJLAST,
+	ICC_THISCALL_OBJLAST_RETURNINMEM,
+	ICC_VIRTUAL_THISCALL_OBJLAST,
+	ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM,
+	ICC_THISCALL_OBJFIRST,
+	ICC_THISCALL_OBJFIRST_RETURNINMEM,
+	ICC_VIRTUAL_THISCALL_OBJFIRST,
+	ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM
 };
 
 struct asSSystemFunctionInterface

+ 145 - 25
Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -37,6 +37,8 @@
 // Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
 //
 // The code was complemented to support Linux with ARM by Carlos Luna in December, 2012.
+//
+// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
 
 
 // This code has to conform to both AAPCS and the modified ABI for iOS
@@ -87,33 +89,57 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// The return is made in memory
 		callConv++;
 	}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
+#endif
 
 	asDWORD paramBuffer[64+2];
 	// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
 	// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this 
 	//                         doesn't have to be done for functions that don't have any 64bit types
 #if !defined(AS_ANDROID) && !defined(AS_LINUX)
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( sysFunc->takesObjByVal )
+#else
+	// In cases of thiscall methods, the callstack is configured as a standard thiscall
+	// adding the secondObject as first or last element in callstack
+	if( sysFunc->takesObjByVal || isThisCallMethod )
+#endif
 #endif
 	{
 #if defined(AS_ANDROID) || defined(AS_LINUX)
 		// mask is used as a toggler to skip uneven registers.
 		int mask = 1;
 
-		// Check for object pointer as first argument
-		switch( callConv )
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod )
+		{
+			mask = 0;
+		}
+		else
+#endif
 		{
-			case ICC_THISCALL:
-			case ICC_CDECL_OBJFIRST:
-			case ICC_VIRTUAL_THISCALL:
-			case ICC_THISCALL_RETURNINMEM:
-			case ICC_CDECL_OBJFIRST_RETURNINMEM:
-			case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-				mask = 0;
-				break;
-			default:
-				break;
+			// Check for object pointer as first argument
+			switch( callConv )
+			{
+				case ICC_THISCALL:
+				case ICC_CDECL_OBJFIRST:
+				case ICC_VIRTUAL_THISCALL:
+				case ICC_THISCALL_RETURNINMEM:
+				case ICC_CDECL_OBJFIRST_RETURNINMEM:
+				case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+					mask = 0;
+					break;
+				default:
+					break;
+			}
 		}
+
 		// Check for hidden address in case of return by value
 		if( sysFunc->hostReturnInMemory )
 			mask = !mask;
@@ -122,6 +148,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		int spos = 0;
 		int dpos = 2;
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
+			callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
+		{
+			// Add the object pointer as the first parameter
+			paramBuffer[dpos++] = (asDWORD)secondObject;
+			paramSize++;
+		}
+#endif
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 			// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
@@ -177,6 +212,16 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 				paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
 			}
 		}
+
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
+			callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
+		{
+			// Add the object pointer as the last parameter
+			paramBuffer[dpos++] = (asDWORD)secondObject;
+			paramSize++;
+		}
+#endif
 		// Keep a free location at the beginning
 		args = &paramBuffer[2];
 	}
@@ -193,9 +238,17 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 	case ICC_THISCALL:  // fall through
 	case ICC_CDECL_OBJFIRST:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST:
+	case ICC_THISCALL_OBJLAST:
+#endif
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		break;
 	case ICC_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 #ifdef __GNUC__
 		// On GNUC the address where the return value will be placed should be put in R0
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
@@ -208,11 +261,19 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST:
+	case ICC_VIRTUAL_THISCALL_OBJLAST:
+#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 #ifdef __GNUC__
@@ -307,6 +368,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		callConv++;
 	}
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
+#endif
+
 	// Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
 	// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this 
 	//                         doesn't have to be done for functions that don't have any 64bit types
@@ -314,19 +384,28 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// mask is used as a toggler to skip uneven registers.
 		int mask = 1;
 
-		// Check for object pointer as first argument
-		switch( callConv )
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod )
 		{
-			case ICC_THISCALL:
-			case ICC_CDECL_OBJFIRST:
-			case ICC_VIRTUAL_THISCALL:
-			case ICC_THISCALL_RETURNINMEM:
-			case ICC_CDECL_OBJFIRST_RETURNINMEM:
-			case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-				mask = 0;
-				break;
-			default:
-				break;
+			mask = 0;
+		}
+		else
+#endif
+		{
+			// Check for object pointer as first argument
+			switch( callConv )
+			{
+				case ICC_THISCALL:
+				case ICC_CDECL_OBJFIRST:
+				case ICC_VIRTUAL_THISCALL:
+				case ICC_THISCALL_RETURNINMEM:
+				case ICC_CDECL_OBJFIRST_RETURNINMEM:
+				case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+					mask = 0;
+					break;
+				default:
+					break;
+			}
 		}
 		// Check for hidden address in case of return by value
 		if( sysFunc->hostReturnInMemory )
@@ -336,6 +415,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		int spos = 0;
 		int dpos = 2;
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
+			callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
+		{
+			// Add the object pointer as the first parameter
+			paramBuffer[dpos++] = (asDWORD)secondObject;
+			paramSize++;
+		}
+#endif
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 			// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
@@ -501,6 +589,22 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			}// else...
 		}// Loop
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
+			callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
+		{
+			if (paramSize < 4)
+			{
+				paramBuffer[dpos++] = (asDWORD)secondObject;
+				paramSize++;
+			}
+			else
+			{
+				paramBuffer[stackPos++] = (asDWORD)secondObject;
+				stackSize++;
+			}
+		}
+#endif
 		// Keep a free location at the beginning
 		args = &paramBuffer[2];
 	}
@@ -519,9 +623,17 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 	case ICC_THISCALL:  // fall through
 	case ICC_CDECL_OBJFIRST:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST:
+	case ICC_THISCALL_OBJLAST:
+#endif
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		break;
 	case ICC_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 		// On GNUC the address where the return value will be placed should be put in R0
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
@@ -529,11 +641,19 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST:
+	case ICC_VIRTUAL_THISCALL_OBJLAST:
+#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		// On GNUC the address where the return value will be placed should be put in R0

+ 7 - 1
Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S

@@ -687,6 +687,12 @@ nomoreargsarmFuncR0R1:
 
     pop {r4-r8, r10, r11, pc}
 
-#endif
+#endif /* hard float abi */
 
+#if defined(__linux__) && defined(__ELF__)
+/* ref: http://hardened.gentoo.org/gnu-stack.xml */
+.section .note.GNU-stack,"",%progbits
 #endif
+
+#endif /* arm */
+

+ 71 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -34,8 +34,14 @@
  * Author: Ionut "gargltk" Leonte <[email protected]>
  *
  * Initial author: niteice
+ *
+ * Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
  */
 
+// Useful references for the System V AMD64 ABI:
+// http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
+// http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf
+ 
 #include "as_config.h"
 
 #ifndef AS_MAX_PORTABILITY
@@ -73,6 +79,8 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
 
 	// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
 		"  movq %%rsp, %%r15 \n"
+	// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
+		" .cfi_def_cfa_register r15 \n"
 
 	// Skip the first 128 bytes on the stack frame, called "red zone",  
 	// that might be used by the compiler to store temporary values
@@ -124,6 +132,8 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
 
 	// Restore stack pointer
 		"  mov %%r15, %%rsp \n"
+	// Inform the stack unwind logic that the stack pointer has been restored
+		" .cfi_def_cfa_register rsp \n"
 
 	// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
 		"  movl %5, %%ecx \n"
@@ -172,8 +182,27 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		callConv++;
 	}
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	// param_post has value 2 if is an THISCALL_OBJLAST
+#endif
+
+
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	// Determine the real function pointer in case of virtual method
 	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) 
+#else
+	if ( obj && ( 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) )
+#endif
 	{
 		vftable = *((funcptr_t**)obj);
 		func = vftable[FuncPtrToUInt(asFUNCTION_t(func)) >> 3];
@@ -195,6 +224,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 			break;
 		}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJLAST:
+		case ICC_VIRTUAL_THISCALL_OBJLAST:
+			param_post = 2;
+#endif
 		case ICC_THISCALL:
 		case ICC_VIRTUAL_THISCALL:
 		case ICC_CDECL_OBJFIRST: 
@@ -206,6 +240,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 			break;
 		}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJLAST_RETURNINMEM:
+		case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+			param_post = 2;
+#endif
 		case ICC_THISCALL_RETURNINMEM:
 		case ICC_VIRTUAL_THISCALL_RETURNINMEM:
 		case ICC_CDECL_OBJFIRST_RETURNINMEM: 
@@ -219,7 +258,33 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 			break;
 		}
-		case ICC_CDECL_OBJLAST: 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJFIRST:
+		case ICC_VIRTUAL_THISCALL_OBJFIRST:
+		{
+			paramBuffer[0] = (asPWORD)obj;
+			paramBuffer[1] = (asPWORD)secondObject;
+			argsType[0] = x64INTARG;
+			argsType[1] = x64INTARG;
+
+			argIndex = 2;
+			break;
+		}
+		case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+		case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+		{
+			paramBuffer[0] = (asPWORD)retPointer;
+			paramBuffer[1] = (asPWORD)obj;
+			paramBuffer[2] = (asPWORD)secondObject;
+			argsType[0] = x64INTARG;
+			argsType[1] = x64INTARG;
+			argsType[2] = x64INTARG;
+
+			argIndex = 3;
+			break;
+		}
+#endif
+		case ICC_CDECL_OBJLAST:
 			param_post = 1;
 			break;
 		case ICC_CDECL_OBJLAST_RETURNINMEM: 
@@ -337,7 +402,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
 	if( param_post )
 	{
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 		paramBuffer[argIndex] = (asPWORD)obj;
+#else
+		paramBuffer[argIndex] = (asPWORD)(param_post > 1 ? secondObject : obj);
+#endif
 		argsType[argIndex] = x64INTARG;
 		argIndex++;
 	}

+ 44 - 1
Source/ThirdParty/AngelScript/source/as_callfunc_x64_mingw.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -31,6 +31,8 @@
 //
 // This code was adapted from as_callfunc_x64_msvc by _Vicious_ on August 20th, 2011.
 //
+// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
+//
 
 #include <stdio.h>
 
@@ -189,10 +191,21 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		allArgBuffer[paramSize++] = (asQWORD)retPointer;
 	}
 
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( callConv == ICC_THISCALL ||
 		callConv == ICC_THISCALL_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL ||
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
+#else
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	// 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) )
+#endif
 	{
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
@@ -204,8 +217,28 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	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
+		allArgBuffer[paramSize++] = (asQWORD)secondObject;
+	}
+#endif
+
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( callConv == ICC_VIRTUAL_THISCALL ||
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
+#else
+	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 )
+#endif
 	{
 		// Get the true function pointer from the virtual function table
 		vftable = *(void***)obj;
@@ -287,6 +320,16 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the last parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	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
+		allArgBuffer[paramSize++] = (asQWORD)secondObject;
+	}
+#endif
 
 	retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
 

+ 45 - 1
Source/ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -28,6 +28,9 @@
    [email protected]
 */
 
+//
+// Added support for thiscall methods by Jordi Oliveras Rovira in April, 2014.
+//
 
 #include <stdio.h>
 
@@ -62,10 +65,22 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asQWORD  floatArgBuffer[4];
 
 	int callConv = sysFunc->callConv;
+
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( callConv == ICC_THISCALL ||
 		callConv == ICC_THISCALL_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL || 
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
+#else
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	// 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) )
+#endif
 	{
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
@@ -86,9 +101,28 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	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
+		allArgBuffer[paramSize++] = (asQWORD)secondObject;
+	}
+#endif
 
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( callConv == ICC_VIRTUAL_THISCALL ||
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
+#else
+	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 )
+#endif
 	{
 		// Get the true function pointer from the virtual function table
 		vftable = *(void***)obj;
@@ -170,6 +204,16 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the last parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	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
+		allArgBuffer[paramSize++] = (asQWORD)secondObject;
+	}
+#endif
 
 	retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
 

+ 62 - 3
Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -34,6 +34,8 @@
 //
 // These functions handle the actual calling of system functions
 //
+// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
+//
 
 
 
@@ -95,13 +97,44 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asQWORD retQW = 0;
 
 	// Prepare the parameters
-	int paramSize = sysFunc->paramSize;
 	asDWORD paramBuffer[64];
+	int callConv = sysFunc->callConv;
+
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
+	int paramSize = sysFunc->paramSize;
 	if( sysFunc->takesObjByVal )
 	{
 		paramSize = 0;
 		int spos = 0;
 		int dpos = 1;
+#else
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	// Changed because need check for ICC_THISCALL_OBJFIRST or
+	// ICC_THISCALL_OBJLAST if sysFunc->takesObjByVal (avoid copy code)
+	// Check if is THISCALL_OBJ* calling convention (in this case needs to add secondObject pointer into stack).
+	bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
+	int paramSize = isThisCallMethod || sysFunc->takesObjByVal ? 0 : sysFunc->paramSize;
+
+	int dpos = 1;
+
+	if( isThisCallMethod && 
+		(callConv >= ICC_THISCALL_OBJFIRST &&
+		 callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
+	{
+		// Add the object pointer as the first parameter
+		paramBuffer[dpos++] = (asDWORD)secondObject;
+		paramSize++;
+	}
+
+	if( sysFunc->takesObjByVal || isThisCallMethod )
+	{
+		int spos = 0;
+#endif // AS_NO_THISCALL_FUNCTOR_METHOD
+
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
@@ -146,9 +179,19 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		args = &paramBuffer[1];
 	}
 
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	if( isThisCallMethod && 
+		(callConv >= ICC_THISCALL_OBJLAST &&
+		 callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
+	{
+		// Add the object pointer as the last parameter
+		paramBuffer[dpos++] = (asDWORD)secondObject;
+		paramSize++;
+	}
+#endif // AS_NO_THISCALL_FUNCTOR_METHOD
+
 	// Make the actual call
 	asFUNCTION_t func = sysFunc->func;
-	int callConv = sysFunc->callConv;
 	if( sysFunc->hostReturnInMemory )
 		callConv++;
 
@@ -176,14 +219,26 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 
 	case ICC_THISCALL:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST:
+	case ICC_THISCALL_OBJLAST:
+#endif
 		retQW = CallThisCallFunction(obj, args, paramSize<<2, func);
 		break;
 
 	case ICC_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 		retQW = CallThisCallFunctionRetByRef(obj, args, paramSize<<2, func, retPointer);
 		break;
 
 	case ICC_VIRTUAL_THISCALL:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST:
+	case ICC_VIRTUAL_THISCALL_OBJLAST:
+#endif
 		{
 			// Get virtual function table from the object pointer
 			asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;
@@ -192,6 +247,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+#endif
 		{
 			// Get virtual function table from the object pointer
 			asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;

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


+ 21 - 10
Source/ThirdParty/AngelScript/source/as_compiler.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -143,6 +143,13 @@ struct asSOverloadCandidate
 	asUINT cost;
 };
 
+struct asSNamedArgument
+{
+	asCString name;
+	asSExprContext *ctx;
+	asUINT match;
+};
+
 enum EImplicitConv
 {
 	asIC_IMPLICIT_CONV,
@@ -212,21 +219,23 @@ protected:
 	void CompileBitwiseOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
 	void CompileComparisonOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
 	void CompileBooleanOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
+	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool isHandle = false);
 	int  CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
 
 	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
-	int  CompileInitListElement(asSListPatternNode *&patternNode, asCScriptNode *&valueNode, int bufferTypeId, short bufferVar, asUINT &bufferSize, asCByteCode &byteCode);
+	int  CompileInitListElement(asSListPatternNode *&patternNode, asCScriptNode *&valueNode, int bufferTypeId, short bufferVar, asUINT &bufferSize, asCByteCode &byteCode, int &elementsInSubList);
 
-	int  CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, int isVarGlobOrMem = 0, bool derefDest = false);
+	int  CallDefaultConstructor(const asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, int isVarGlobOrMem = 0, bool derefDest = false);
 	int  CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = false);
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
-	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
-	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
-	asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
+	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args, asCArray<asSNamedArgument> &namedArgs);
+	int  CompileDefaultAndNamedArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, int funcId, asCObjectType *type, asCArray<asSNamedArgument> *namedArgs = 0);
+	asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCArray<asSNamedArgument> *namedArgs = NULL, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
 	int  CompileVariableAccess(const asCString &name, const asCString &scope, asSExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, bool noFunction = false, bool noGlobal = false, asCObjectType *objType = 0);
 	void CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults);
-	bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem);
+	bool CompileAutoType(asCDataType &autoType, asSExprContext &compiledCtx, asCScriptNode *exprNode, asCScriptNode *errNode);
+	bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem, asSExprContext *preCompiled = 0);
+	void CompileInitAsCopy(asCDataType &type, int offset, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool derefDestination);
 
 	// Helper functions
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
@@ -241,13 +250,14 @@ protected:
 	void Dereference(asSExprContext *ctx, bool generateCode);
 	bool CompileRefCast(asSExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
 	asUINT MatchArgument(asCArray<int> &funcs, asCArray<asSOverloadCandidate> &matches, const asSExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
+	int  MatchArgument(asCScriptFunction *desc, const asSExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
 	void PerformFunctionCall(int funcId, asSExprContext *out, bool isConstructor = false, asCArray<asSExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset);
 	void MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asSExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
 	void PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args);
 	void AfterFunctionCall(int funcId, asCArray<asSExprContext*> &args, asSExprContext *ctx, bool deferAll);
 	void ProcessDeferredParams(asSExprContext *ctx);
-	void PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
+	int  PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
 	void PrepareArgument2(asSExprContext *ctx, asSExprContext *arg, asCDataType *paramType, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
 	bool IsLValue(asCTypeInfo &type);
 	int  DoAssignment(asSExprContext *out, asSExprContext *lctx, asSExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, int op, asCScriptNode *opNode);
@@ -275,6 +285,7 @@ protected:
 	asUINT ImplicitConvObjectRef(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
 	asUINT ImplicitConvObjectValue(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
 	void   ImplicitConversionConstant(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType);
+	void   ImplicitConvObjectToBestMathType(asSExprContext *ctx, asCScriptNode *node);
 
 	void LineInstr(asCByteCode *bc, size_t pos);
 
@@ -284,7 +295,7 @@ protected:
 	void Error(const asCString &msg, asCScriptNode *node);
 	void Warning(const asCString &msg, asCScriptNode *node);
 	void Information(const asCString &msg, asCScriptNode *node);
-	void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node);
+	void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node, asCObjectType *inType = 0);
 	void AddVariableScope(bool isBreakScope = false, bool isContinueScope = false);
 	void RemoveVariableScope();
 	void FinalizeFunction();

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

@@ -101,6 +101,10 @@
 // if the new order of the member initialization caused null pointer exceptions in older
 // scripts (e.g. if a base class accessed members of a derived class through a virtual method).
 
+// AS_USE_NAMESPACE
+// Adds the AngelScript namespace on the declarations.
+
+
 
 //
 // Library usage
@@ -140,12 +144,12 @@
 // STDCALL
 // This is used to declare a function to use the stdcall calling convention.
 
-// AS_USE_NAMESPACE
-// Adds the AngelScript namespace on the declarations.
-
 // AS_NO_MEMORY_H
 // Some compilers don't come with the memory.h header file.
 
+// AS_NO_THISCALL_FUNCTOR_METHOD
+// Defined if the support for functor methods hasn't been implemented on the platform.
+
 
 
 //
@@ -166,6 +170,9 @@
 // Embarcadero C++Builder
 //  __BORLANDC__ is defined
 
+// Sun CC compiler
+// __SUNPRO_CC is defined
+
 
 
 //
@@ -213,6 +220,9 @@
 // AS_BIG_ENDIAN
 // Define this for CPUs that use big endian memory layout, e.g. PPC
 
+// AS_SPARC
+// Define this for SPARC CPU family
+
 
 
 //
@@ -241,6 +251,7 @@
 // AS_HAIKU     - Haiku
 // AS_ILLUMOS   - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
 // AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
+// AS_SUN       - Sun UNIX
 
 
 
@@ -339,6 +350,9 @@
 #define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
 #define THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
 
+// Not implemented by default. Undefined with tested platforms.
+#define AS_NO_THISCALL_FUNCTOR_METHOD
+
 
 // Embarcadero C++Builder
 #if defined(__BORLANDC__)
@@ -437,6 +451,7 @@
 	#define THISCALL_CALLEE_POPS_ARGUMENTS
 	#define STDCALL __stdcall
 	#define AS_SIZEOF_BOOL 1
+	#define COMPLEX_OBJS_PASSED_BY_REF
 
 	#define ASM_INTEL  // Intel style for inline assembly on microsoft compilers
 
@@ -452,14 +467,18 @@
 	#else
 		#if defined(_XBOX) || (defined(_M_IX86) && !defined(__LP64__))
 			#define AS_X86
+			#ifndef _XBOX
+				// Not tested with xbox (only enabled if is Windows)
+				#undef AS_NO_THISCALL_FUNCTOR_METHOD
+			#endif 
 		#elif defined(_M_X64)
 			#define AS_X64_MSVC
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJ_MIN_SIZE 3
-			#define COMPLEX_OBJS_PASSED_BY_REF
-			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 		#endif
 	#endif
 
@@ -468,18 +487,17 @@
 		#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#define CDECL_RETURN_SIMPLE_IN_MEMORY
 		#define STDCALL_RETURN_SIMPLE_IN_MEMORY
-		#define COMPLEX_OBJS_PASSED_BY_REF
-		#define COMPLEX_MASK asOBJ_APP_CLASS_ASSIGNMENT
-		#define COMPLEX_RETURN_MASK asOBJ_APP_CLASS_ASSIGNMENT
+		#define COMPLEX_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
 		#define AS_SOFTFP
 	#endif
 
 	#ifndef COMPLEX_MASK
-		#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
+		#define COMPLEX_MASK (asOBJ_APP_ARRAY)
 	#endif
 
 	#ifndef COMPLEX_RETURN_MASK
-		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
 	#endif
 
 	#define UNREACHABLE_RETURN
@@ -563,8 +581,8 @@
 	#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 	#define CALLEE_POPS_HIDDEN_RETURN_POINTER
 	#define COMPLEX_OBJS_PASSED_BY_REF
-	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
-	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_ARRAY)
+	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_ARRAY)
 	#define AS_NO_MEMORY_H
 	#define AS_SIZEOF_BOOL 1
 	#define STDCALL __attribute__((stdcall))
@@ -618,9 +636,9 @@
 			#undef GNU_STYLE_VIRTUAL_METHOD
 
 			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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)
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#endif
@@ -651,6 +669,7 @@
 		#if (defined(_ARM_) || defined(__arm__))
 			// iOS use ARM processor
 			#define AS_ARM
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
@@ -666,9 +685,9 @@
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 			#define COMPLEX_OBJS_PASSED_BY_REF
 			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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)
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 			// iOS uses soft-float ABI
 			#define AS_SOFTFP
@@ -679,8 +698,8 @@
 
 		#elif (defined(__arm64__))
 			// The IPhone 5S+ uses an ARM64 processor
-			
-			// AngelScript currently doesn't support native calling 
+
+			// AngelScript currently doesn't support native calling
 			// for 64bit ARM processors so it's necessary to turn on
 			// portability mode
 			#define AS_MAX_PORTABILITY
@@ -692,21 +711,23 @@
 		#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 			// Support native calling conventions on Mac OS X + Intel 32bit CPU
 			#define AS_X86
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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)
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 		#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__arm64__)
 			// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
 			#define AS_X64_GCC
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#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)
+			#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)
+			#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
 			// STDCALL is not available on 64bit Mac
@@ -720,9 +741,9 @@
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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)
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 		#elif (defined(__ppc__) || defined(__PPC__)) && defined(__LP64__)
 			#define AS_PPC_64
@@ -740,13 +761,14 @@
 		//#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 
 		#undef COMPLEX_MASK
-		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+		#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)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 			// Support native calling conventions on Intel 32bit CPU
 			#define AS_X86
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 
 			// As of version 4.7 MinGW changed the ABI, presumably
 			// to be better aligned with how MSVC works
@@ -760,6 +782,7 @@
 
 		#elif defined(__x86_64__)
 			#define AS_X64_MINGW
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJ_MIN_SIZE 3
 			#define COMPLEX_OBJS_PASSED_BY_REF
@@ -773,9 +796,9 @@
 	#elif defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)
 
 		#undef COMPLEX_MASK
-		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+		#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)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
 
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
@@ -785,8 +808,10 @@
 			// Support native calling conventions on Intel 32bit CPU
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 		#elif defined(__LP64__) && !defined(__arm64__)
 			#define AS_X64_GCC
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define HAS_128_BIT_PRIMITIVES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#define AS_LARGE_OBJS_PASSED_BY_REF
@@ -822,9 +847,12 @@
 			// Verify if soft-float or hard-float ABI is used
 			#if defined(__SOFTFP__) && __SOFTFP__ == 1
 				// -ffloat-abi=softfp or -ffloat-abi=soft
-				#define AS_SOFTFP	
+				#define AS_SOFTFP
 			#endif
 
+			// Tested with both hard float and soft float abi
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
+
 		#elif defined(__mips__)
 			#define AS_MIPS
 			#define AS_BIG_ENDIAN
@@ -848,9 +876,9 @@
 		#define AS_BSD
 		#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
 			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#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)
+			#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 AS_X86
 		#elif defined(__LP64__)
@@ -858,9 +886,9 @@
 			#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)
+			#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)
+			#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
@@ -915,36 +943,47 @@
 	#elif defined(ANDROID) || defined(__ANDROID__)
 		#define AS_ANDROID
 
-		// Android NDK 9+ supports posix threads
+		// Android 2.3+ supports posix threads
 		#define AS_POSIX_THREADS
 
+		// Common configuration with Android arm and x86
 		#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
-
-		#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
-		#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
-		#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+		#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)
 
 		#if (defined(_ARM_) || defined(__arm__))
+			// Android ARM
+
+			#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+			#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+			#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+
+			#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+			#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+			#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+
 			// The stdcall calling convention is not used on the arm cpu
 			#undef STDCALL
 			#define STDCALL
 
 			#undef GNU_STYLE_VIRTUAL_METHOD
 
-			#undef COMPLEX_MASK
-			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
-			#undef COMPLEX_RETURN_MASK
-			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
-
 			#define AS_ARM
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define AS_SOFTFP
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
+		#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
+			// Android Intel x86 (same config as Linux x86). Tested with Intel x86 Atom System Image.
+
+			// Support native calling conventions on Intel 32bit CPU
+			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
+			#define AS_X86
+			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 		#endif
 
 	// Haiku OS
@@ -1001,6 +1040,39 @@
 	#define UNREACHABLE_RETURN
 #endif
 
+// Sun CC
+// Initial information provided by Andrey Bergman
+#if defined(__SUNPRO_CC)
+	#if defined(__sparc)
+		#define AS_SPARC
+	#endif
+
+	#if defined(__sun)
+		#define AS_SUN
+	#endif
+
+	// Native calling conventions is not yet supported for Sun CC
+	#if !defined(AS_MAX_PORTABILITY)
+		#define AS_MAX_PORTABILITY
+	#endif
+
+	// I presume Sun CC uses a similar structure of method pointers as gnuc
+	#define MULTI_BASE_OFFSET(x) (*((asPWORD*)(&x)+1))
+
+	#if !defined(AS_SIZEOF_BOOL)
+		#define AS_SIZEOF_BOOL 1 // sizeof(bool) == 1
+	#endif
+	#if !defined(UNREACHABLE_RETURN)
+		#define UNREACHABLE_RETURN
+	#endif
+	#if !defined(STDCALL)
+		#define STDCALL // There is no stdcall on Solaris/SunPro/SPARC
+	#endif
+	#if !defined(asVSNPRINTF)
+		#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
+	#endif
+#endif
+
 
 //
 // Detect target hardware

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

@@ -150,7 +150,7 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 	// Remove object types (skip this if it is possible other groups are still using the types)
 	if( !notUsed )
 	{
-		for( n = 0; n < objTypes.GetLength(); n++ )
+		for( n = asUINT(objTypes.GetLength()); n-- > 0; )
 		{
 			asCObjectType *t = objTypes[n];
 			asSMapNode<asSNameSpaceNamePair, asCObjectType*> *cursor;

+ 95 - 40
Source/ThirdParty/AngelScript/source/as_context.cpp

@@ -261,8 +261,16 @@ void asCContext::DetachEngine()
 	m_stackBlockSize = 0;
 
 	// Clean the user data
-	if( m_userData && m_engine->cleanContextFunc )
-		m_engine->cleanContextFunc(this);
+	for( asUINT n = 0; n < m_userData.GetLength(); n += 2 )
+	{
+		if( m_userData[n+1] )
+		{
+			for( asUINT c = 0; c < m_engine->cleanContextFuncs.GetLength(); c++ )
+				if( m_engine->cleanContextFuncs[c].type == m_userData[n] )
+					m_engine->cleanContextFuncs[c].cleanFunc(this);
+		}
+	}
+	m_userData.SetLength(0);
 
 	// Clear engine pointer
 	if( m_holdEngineRef )
@@ -277,17 +285,55 @@ asIScriptEngine *asCContext::GetEngine() const
 }
 
 // interface
-void *asCContext::SetUserData(void *data)
+void *asCContext::SetUserData(void *data, asPWORD type)
 {
-	void *oldData = m_userData;
-	m_userData = data;
-	return oldData;
+	// As a thread might add a new new user data at the same time as another
+	// it is necessary to protect both read and write access to the userData member
+	ACQUIREEXCLUSIVE(m_engine->engineRWLock);
+
+	// It is not intended to store a lot of different types of userdata,
+	// so a more complex structure like a associative map would just have
+	// more overhead than a simple array.
+	for( asUINT n = 0; n < m_userData.GetLength(); n += 2 )
+	{
+		if( m_userData[n] == type )
+		{
+			void *oldData = reinterpret_cast<void*>(m_userData[n+1]);
+			m_userData[n+1] = reinterpret_cast<asPWORD>(data);
+
+			RELEASEEXCLUSIVE(m_engine->engineRWLock);
+
+			return oldData;
+		}
+	}
+
+	m_userData.PushLast(type);
+	m_userData.PushLast(reinterpret_cast<asPWORD>(data));
+
+	RELEASEEXCLUSIVE(m_engine->engineRWLock);
+
+	return 0;
 }
 
 // interface
-void *asCContext::GetUserData() const
+void *asCContext::GetUserData(asPWORD type) const
 {
-	return m_userData;
+	// There may be multiple threads reading, but when
+	// setting the user data nobody must be reading.
+	ACQUIRESHARED(m_engine->engineRWLock);
+
+	for( asUINT n = 0; n < m_userData.GetLength(); n += 2 )
+	{
+		if( m_userData[n] == type )
+		{
+			RELEASESHARED(m_engine->engineRWLock);
+			return reinterpret_cast<void*>(m_userData[n+1]);
+		}
+	}
+
+	RELEASESHARED(m_engine->engineRWLock);
+
+	return 0;
 }
 
 // interface
@@ -322,6 +368,16 @@ int asCContext::Prepare(asIScriptFunction *func)
 	// Release the returned object (if any)
 	CleanReturnObject();
 
+	// Release the object if it is a script object
+	if( m_initialFunction && m_initialFunction->objectType && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
+	{
+		asCScriptObject *obj = *(asCScriptObject**)&m_regs.stackFramePointer[0];
+		if( obj )
+			obj->Release();
+
+		*(asPWORD*)&m_regs.stackFramePointer[0] = 0;
+	}
+
 	if( m_initialFunction && m_initialFunction == func )
 	{
 		// If the same function is executed again, we can skip a lot of the setup
@@ -437,6 +493,14 @@ int asCContext::Unprepare()
 	// Release the returned object (if any)
 	CleanReturnObject();
 
+	// Release the object if it is a script object
+	if( m_initialFunction && m_initialFunction->objectType && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
+	{
+		asCScriptObject *obj = *(asCScriptObject**)&m_regs.stackFramePointer[0];
+		if( obj )
+			obj->Release();
+	}
+
 	// Release the initial function
 	if( m_initialFunction )
 	{
@@ -624,8 +688,15 @@ int asCContext::SetObject(void *obj)
 		return asERROR;
 	}
 
+	asASSERT( *(asPWORD*)&m_regs.stackFramePointer[0] == 0 );
+
 	*(asPWORD*)&m_regs.stackFramePointer[0] = (asPWORD)obj;
 
+	// TODO: This should be optional by having a flag where the application can chose whether it should be done or not
+	//       The flag could be named something like takeOwnership and have default value of true
+	if( obj && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
+		reinterpret_cast<asCScriptObject*>(obj)->AddRef();
+
 	return 0;
 }
 
@@ -1174,13 +1245,12 @@ int asCContext::Execute()
 		if( gcPosObjects > gcPreObjects )
 		{
 			// Execute as many steps as there were new objects created
-			while( gcPosObjects-- > gcPreObjects )
-				m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE);
+			m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE, gcPosObjects - gcPreObjects);
 		}
 		else if( gcPosObjects > 0 )
 		{
 			// Execute at least one step, even if no new objects were created
-			m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE);
+			m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE, 1);
 		}
 	}
 
@@ -1512,26 +1582,28 @@ void asCContext::CallScriptFunction(asCScriptFunction *func)
 	m_currentFunction = func;
 	m_regs.programPointer = m_currentFunction->scriptData->byteCode.AddressOf();
 
+	PrepareScriptFunction();
+}
+
+void asCContext::PrepareScriptFunction()
+{
+	asASSERT( m_currentFunction->scriptData );
+
 	// Make sure there is space on the stack to execute the function
 	asDWORD *oldStackPointer = m_regs.stackPointer;
-	if( !ReserveStackSpace(func->scriptData->stackNeeded) )
+	if( !ReserveStackSpace(m_currentFunction->scriptData->stackNeeded) )
 		return;
 
 	// If a new stack block was allocated then we'll need to move
-	// over the function arguments to the new block
+	// over the function arguments to the new block.
 	if( m_regs.stackPointer != oldStackPointer )
 	{
-		int numDwords = func->GetSpaceNeededForArguments() + (func->objectType ? AS_PTR_SIZE : 0) + (func->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
+		int numDwords = m_currentFunction->GetSpaceNeededForArguments() + 
+		                (m_currentFunction->objectType ? AS_PTR_SIZE : 0) + 
+		                (m_currentFunction->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
 		memcpy(m_regs.stackPointer, oldStackPointer, sizeof(asDWORD)*numDwords);
 	}
 
-	PrepareScriptFunction();
-}
-
-void asCContext::PrepareScriptFunction()
-{
-	asASSERT( m_currentFunction->scriptData );
-
 	// Update framepointer
 	m_regs.stackFramePointer = m_regs.stackPointer;
 
@@ -4622,23 +4694,6 @@ void asCContext::CleanStackFrame()
 				}
 			}
 		}
-
-		// If the object is a script declared object, then we must release it
-		// as the compiler adds a reference at the entry of the function. Make sure
-		// the function has actually been entered
-		if( m_currentFunction->objectType && m_regs.programPointer != m_currentFunction->scriptData->byteCode.AddressOf() )
-		{
-			// Methods returning a reference or constructors don't add a reference
-			if( !m_currentFunction->returnType.IsReference() && m_currentFunction->name != m_currentFunction->objectType->name )
-			{
-				asSTypeBehaviour *beh = &m_currentFunction->objectType->beh;
-				if( beh->release && *(asPWORD*)&m_regs.stackFramePointer[0] != 0 )
-				{
-					m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackFramePointer[0], beh->release);
-					*(asPWORD*)&m_regs.stackFramePointer[0] = 0;
-				}
-			}
-		}
 	}
 	else
 		m_isStackMemoryNotAllocated = false;
@@ -4733,7 +4788,7 @@ int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
 	m_regs.doProcessSuspend = true;
 	m_lineCallbackObj = obj;
 	bool isObj = false;
-	if( (unsigned)callConv == asCALL_GENERIC )
+	if( (unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST )
 	{
 		m_lineCallback = false;
 		m_regs.doProcessSuspend = m_doSuspend;
@@ -4772,7 +4827,7 @@ int asCContext::SetExceptionCallback(asSFuncPtr callback, void *obj, int callCon
 	m_exceptionCallback = true;
 	m_exceptionCallbackObj = obj;
 	bool isObj = false;
-	if( (unsigned)callConv == asCALL_GENERIC )
+	if( (unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST )
 		return asNOT_SUPPORTED;
 	if( (unsigned)callConv >= asCALL_THISCALL )
 	{

+ 3 - 3
Source/ThirdParty/AngelScript/source/as_context.h

@@ -122,8 +122,8 @@ public:
 	asIScriptFunction *GetSystemFunction();
 
 	// User data
-	void *SetUserData(void *data);
-	void *GetUserData() const;
+	void *SetUserData(void *data, asPWORD type);
+	void *GetUserData(asPWORD type) const;
 
 public:
 	// Internal public functions
@@ -204,7 +204,7 @@ public:
 	asSSystemFunctionInterface m_exceptionCallbackFunc;
 	void *                     m_exceptionCallbackObj;
 
-	void *m_userData;
+	asCArray<asPWORD> m_userData;
 
 	// Registers available to JIT compiler functions
 	asSVMRegisters m_regs;

+ 91 - 47
Source/ThirdParty/AngelScript/source/as_datatype.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -46,24 +46,28 @@ BEGIN_AS_NAMESPACE
 
 asCDataType::asCDataType()
 {
-	tokenType      = ttUnrecognizedToken;
-	objectType     = 0;
-	isReference    = false;
-	isReadOnly     = false;
-	isObjectHandle = false;
-	isConstHandle  = false;
-	funcDef        = 0;
+	tokenType              = ttUnrecognizedToken;
+	objectType             = 0;
+	isReference            = false;
+	isReadOnly             = false;
+	isAuto                 = false;
+	isObjectHandle         = false;
+	isConstHandle          = false;
+	funcDef                = 0;
+	isHandleToAsHandleType = false;
 }
 
 asCDataType::asCDataType(const asCDataType &dt)
 {
-	tokenType      = dt.tokenType;
-	objectType     = dt.objectType;
-	isReference    = dt.isReference;
-	isReadOnly     = dt.isReadOnly;
-	isObjectHandle = dt.isObjectHandle;
-	isConstHandle  = dt.isConstHandle;
-	funcDef        = dt.funcDef;
+	tokenType              = dt.tokenType;
+	objectType             = dt.objectType;
+	isReference            = dt.isReference;
+	isReadOnly             = dt.isReadOnly;
+	isAuto                 = dt.isAuto;
+	isObjectHandle         = dt.isObjectHandle;
+	isConstHandle          = dt.isConstHandle;
+	funcDef                = dt.funcDef;
+	isHandleToAsHandleType = dt.isHandleToAsHandleType;
 }
 
 asCDataType::~asCDataType()
@@ -90,6 +94,17 @@ asCDataType asCDataType::CreateObject(asCObjectType *ot, bool isConst)
 	return dt;
 }
 
+asCDataType asCDataType::CreateAuto(bool isConst)
+{
+	asCDataType dt;
+
+	dt.tokenType        = ttIdentifier;
+	dt.isReadOnly       = isConst;
+	dt.isAuto           = true;
+
+	return dt;
+}
+
 asCDataType asCDataType::CreateObjectHandle(asCObjectType *ot, bool isConst)
 {
 	asCDataType dt;
@@ -191,6 +206,13 @@ asCString asCDataType::Format(bool includeNamespace) const
 			str += ">";
 		}
 	}
+	else if( isAuto )
+	{
+		if( isObjectHandle )
+			str += "<auto@>";
+		else
+			str += "<auto>";
+	}
 	else
 	{
 		str = "<unknown>";
@@ -211,13 +233,15 @@ asCString asCDataType::Format(bool includeNamespace) const
 
 asCDataType &asCDataType::operator =(const asCDataType &dt)
 {
-	tokenType        = dt.tokenType;
-	isReference      = dt.isReference;
-	objectType       = dt.objectType;
-	isReadOnly       = dt.isReadOnly;
-	isObjectHandle   = dt.isObjectHandle;
-	isConstHandle    = dt.isConstHandle;
-	funcDef          = dt.funcDef;
+	tokenType              = dt.tokenType;
+	isReference            = dt.isReference;
+	objectType             = dt.objectType;
+	isReadOnly             = dt.isReadOnly;
+	isObjectHandle         = dt.isObjectHandle;
+	isConstHandle          = dt.isConstHandle;
+	isAuto                 = dt.isAuto;
+	funcDef                = dt.funcDef;
+	isHandleToAsHandleType = dt.isHandleToAsHandleType;
 
 	return (asCDataType &)*this;
 }
@@ -226,29 +250,40 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 {
 	if( !b )
 	{
-		isObjectHandle = b;
+		isObjectHandle = false;
 		isConstHandle = false;
+		isHandleToAsHandleType = false;
 	}
-	else if( b && !isObjectHandle )
+	else
 	{
-		// Only reference types are allowed to be handles, 
-		// but not nohandle reference types, and not scoped references 
-		// (except when returned from registered function)
-		// funcdefs are special reference types and support handles
-		// value types with asOBJ_ASHANDLE are treated as a handle
-		if( !funcDef && 
-			(!objectType || 
-			!((objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_TEMPLATE_SUBTYPE) || (objectType->flags & asOBJ_ASHANDLE)) || 
-			(objectType->flags & asOBJ_NOHANDLE) || 
-			((objectType->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
-			return -1;
-
-		isObjectHandle = b;
-		isConstHandle = false;
-
-		// ASHANDLE supports being handle, but as it really is a value type it will not be marked as a handle
-		if( (objectType->flags & asOBJ_ASHANDLE) )
-			isObjectHandle = false;
+		if( isAuto )
+		{
+			isObjectHandle = true;
+		}
+		else if( !isObjectHandle )
+		{
+			// Only reference types are allowed to be handles, 
+			// but not nohandle reference types, and not scoped references 
+			// (except when returned from registered function)
+			// funcdefs are special reference types and support handles
+			// value types with asOBJ_ASHANDLE are treated as a handle
+			if( !funcDef && 
+				(!objectType || 
+				!((objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_TEMPLATE_SUBTYPE) || (objectType->flags & asOBJ_ASHANDLE)) || 
+				(objectType->flags & asOBJ_NOHANDLE) || 
+				((objectType->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
+				return -1;
+
+			isObjectHandle = b;
+			isConstHandle = false;
+
+			// ASHANDLE supports being handle, but as it really is a value type it will not be marked as a handle
+			if( (objectType->flags & asOBJ_ASHANDLE) )
+			{
+				isObjectHandle = false;
+				isHandleToAsHandleType = true;
+			}
+		}
 	}
 
 	return 0;
@@ -305,7 +340,7 @@ int asCDataType::MakeHandleToConst(bool b)
 bool asCDataType::SupportHandles() const
 {
 	if( objectType &&
-		(objectType->flags & asOBJ_REF) && 
+		(objectType->flags & (asOBJ_REF | asOBJ_ASHANDLE)) && 
 		!(objectType->flags & asOBJ_NOHANDLE) &&
 		!isObjectHandle )
 		return true;
@@ -361,6 +396,14 @@ bool asCDataType::IsHandleToConst() const
 	return isReadOnly;
 }
 
+bool asCDataType::IsObjectConst() const
+{
+	if( IsObjectHandle() )
+		return IsHandleToConst();
+
+	return IsReadOnly();
+}
+
 // TODO: 3.0.0: This should be removed
 bool asCDataType::IsArrayType() const
 {
@@ -505,13 +548,14 @@ bool asCDataType::IsBooleanType() const
 
 bool asCDataType::IsObject() const
 {
-	//	Enumerations are not objects, even though they are described with an objectType.
-	if( IsEnumType() )
+	if( IsPrimitive() )
 		return false;
 
-	if( objectType ) return true;
+	// Null handle doesn't have an object type but should still be considered an object
+	if( objectType == 0 ) 
+		return IsNullHandle();
 
-	return false;
+	return true;
 }
 
 int asCDataType::GetSizeInMemoryBytes() const

+ 26 - 18
Source/ThirdParty/AngelScript/source/as_datatype.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -66,6 +66,7 @@ public:
 
 	static asCDataType CreatePrimitive(eTokenType tt, bool isConst);
 	static asCDataType CreateObject(asCObjectType *ot, bool isConst);
+	static asCDataType CreateAuto(bool isConst);
 	static asCDataType CreateObjectHandle(asCObjectType *ot, bool isConst);
 	static asCDataType CreateFuncDef(asCScriptFunction *ot);
 	static asCDataType CreateNullHandle();
@@ -76,22 +77,27 @@ public:
 	int MakeReadOnly(bool b);
 	int MakeHandleToConst(bool b);
 
-	bool IsTemplate()       const;
-	bool IsScriptObject()   const;
-	bool IsPrimitive()      const;
-	bool IsObject()         const;
-	bool IsReference()      const {return isReference;}
-	bool IsReadOnly()       const; 
-	bool IsIntegerType()    const;
-	bool IsUnsignedType()   const;
-	bool IsFloatType()      const;
-	bool IsDoubleType()     const;
-	bool IsBooleanType()    const;
-	bool IsObjectHandle()   const {return isObjectHandle;}
-	bool IsHandleToConst()  const;
-	bool IsArrayType()      const;
-	bool IsEnumType()       const;
-	bool IsAnyType()        const {return tokenType == ttQuestion;}
+	bool IsTemplate()             const;
+	bool IsScriptObject()         const;
+	bool IsPrimitive()            const;
+	bool IsObject()               const;
+	bool IsReference()            const {return isReference;}
+	bool IsAuto()                 const {return isAuto;}
+	bool IsReadOnly()             const;
+	bool IsIntegerType()          const;
+	bool IsUnsignedType()         const;
+	bool IsFloatType()            const;
+	bool IsDoubleType()           const;
+	bool IsBooleanType()          const;
+	bool IsObjectHandle()         const {return isObjectHandle;}
+	bool IsHandleToAuto()         const {return isAuto && isObjectHandle;}
+	bool IsHandleToConst()        const;
+	bool IsArrayType()            const;
+	bool IsEnumType()             const;
+	bool IsAnyType()              const {return tokenType == ttQuestion;}
+	bool IsHandleToAsHandleType() const {return isHandleToAsHandleType;}
+
+	bool IsObjectConst()    const;
 
 	bool IsEqualExceptRef(const asCDataType &)             const;
 	bool IsEqualExceptRefAndConst(const asCDataType &)     const;
@@ -135,7 +141,9 @@ protected:
 	bool isReadOnly:1;
 	bool isObjectHandle:1;
 	bool isConstHandle:1;
-	char dummy:4;
+	bool isAuto:1;
+	bool isHandleToAsHandleType:1; // Used by the compiler to know how to initialize the object
+	char dummy:2;
 };
 
 END_AS_NAMESPACE

+ 9 - 3
Source/ThirdParty/AngelScript/source/as_debug.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -38,6 +38,8 @@
 
 #include "as_config.h"
 
+#if defined(AS_DEBUG)
+
 #ifndef AS_WII
 // The Wii SDK doesn't have these, we'll survive without AS_DEBUG
 
@@ -254,11 +256,15 @@ END_AS_NAMESPACE
 
 
 
+#endif // _WIN32_WCE
+#endif // AS_WII
 
+#else // !defined(AS_DEBUG)
 
+// Define it so nothing is done
+#define TimeIt(x) 
 
-#endif // _WIN32_WCE
-#endif // AS_WII
+#endif // !defined(AS_DEBUG)
 
 #endif
 

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -156,7 +156,14 @@ int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, a
 	return asSUCCESS;
 }
 
-int asCGarbageCollector::GarbageCollect(asDWORD flags)
+// TODO: Should have a flag to tell the garbage collector to automatically determine how many iterations are needed
+//       It should then gather statistics such as how many objects has been created since last run, and how many objects
+//       are destroyed per iteration, and how many objects are detected as cyclic garbage per iteration.
+//       It should try to reach a stable number of objects, i.e. so that on average the number of objects added to 
+//       the garbage collector is the same as the number of objects destroyed. And it should try to minimize the number
+//       of iterations of detections that must be executed per cycle while still identifying the cyclic garbage
+//       These variables should also be available for inspection through the gcstatistics.
+int asCGarbageCollector::GarbageCollect(asDWORD flags, asUINT iterations)
 {
 	// If the GC is already processing in another thread, then don't enter here again
 	if( TRYENTERCRITICALSECTION(gcCollecting) )
@@ -178,9 +185,8 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 			// Reset the state
 			if( doDetect )
 			{
-				// Move all objects to the old list, so we guarantee that all is detected
-				for( asUINT n = (asUINT)gcNewObjects.GetLength(); n-- > 0; )
-					MoveObjectToOldList(n);
+				// Move all new objects to the old list, so we guarantee that all is detected
+				MoveAllObjectsToOldList();
 				detectState  = clearCounters_init;
 			}
 			if( doDestroy )
@@ -189,7 +195,10 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 				destroyOldState = destroyGarbage_init;
 			}
 
-			unsigned int count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
+			// The full cycle only works with the objects in the old list so that the
+			// set of objects scanned for garbage is fixed even if new objects are added
+			// by other threads in parallel.
+			unsigned int count = (unsigned int)(gcOldObjects.GetLength());
 			for(;;)
 			{
 				// Detect all garbage with cyclic references
@@ -199,13 +208,14 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 				// Now destroy all known garbage
 				if( doDestroy )
 				{
-					while( DestroyNewGarbage() == 1 ) {}
+					if( !doDetect )
+						while( DestroyNewGarbage() == 1 ) {}
 					while( DestroyOldGarbage() == 1 ) {}
 				}
 
 				// Run another iteration if any garbage was destroyed
-				if( count != (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength()) )
-					count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
+				if( count != (unsigned int)(gcOldObjects.GetLength()) )
+					count = (unsigned int)(gcOldObjects.GetLength());
 				else
 				{
 					// Let the engine destroy the types that reached refCount 0
@@ -226,16 +236,19 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 		}
 		else
 		{
-			// Destroy the garbage that we know of
-			if( doDestroy )
+			while( iterations-- > 0 )
 			{
-				DestroyNewGarbage();
-				DestroyOldGarbage();
-			}
+				// Destroy the garbage that we know of
+				if( doDestroy )
+				{
+					DestroyNewGarbage();
+					DestroyOldGarbage();
+				}
 
-			// Run another incremental step of the identification of cyclic references
-			if( doDetect )
-				IdentifyGarbageWithCyclicRefs();
+				// Run another incremental step of the identification of cyclic references
+				if( doDetect && gcOldObjects.GetLength() > 0 )
+					IdentifyGarbageWithCyclicRefs();
+			}
 		}
 
 		isProcessing = false;
@@ -246,19 +259,33 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 	return 1;
 }
 
+// TODO: Additional statistics to gather
+//
+//       - How many objects are added on average between each destroyed object
+//       - How many objects are added on average between each detected object
+//       - how many iterations are needed for each destroyed object
+//       - how many iterations are needed for each detected object
+//
+//       The average must have a decay so that long running applications will not suffer
+//       from objects being created early on in the application and then never destroyed.
+//
+//       This ought to be possible to accomplish by holding two buckets.
+//       Numbers will be accumulated in one bucket while the other is held fixed.
+//       When returning the average it should use a weighted average between the two buckets using the size as weight.
+//       When a bucket is filled up, the buckets are switched, and then new bucket is emptied to gather new statistics.
 void asCGarbageCollector::GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const
 {
-	// It's not necessary to protect this access, as
-	// it doesn't matter if another thread is currently
-	// appending a new object.
+	// It is not necessary to protect this with critical sections, however
+	// as it is not protected the variables can be filled in slightly different
+	// moments and might not match perfectly when inspected by the application
+	// afterwards.
+
 	if( currentSize )
 		*currentSize = (asUINT)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
 
 	if( totalDestroyed )
 		*totalDestroyed = numDestroyed;
 
-	asASSERT( numAdded == gcNewObjects.GetLength() + gcOldObjects.GetLength() + numDestroyed );
-
 	if( totalDetected )
 		*totalDetected = numDetected;
 
@@ -328,6 +355,16 @@ void asCGarbageCollector::MoveObjectToOldList(int idx)
 	LEAVECRITICALSECTION(gcCritical);
 }
 
+void asCGarbageCollector::MoveAllObjectsToOldList()
+{
+	// We need to protect this update with a critical section as
+	// another thread might be appending an object at the same time
+	ENTERCRITICALSECTION(gcCritical);
+	if( gcOldObjects.Concatenate(gcNewObjects) )
+		gcNewObjects.SetLength(0);
+	LEAVECRITICALSECTION(gcCritical);
+}
+
 int asCGarbageCollector::DestroyNewGarbage()
 {
 	// This function will only be called within the critical section gcCollecting
@@ -900,8 +937,15 @@ asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIn
 	if( freeNodes.GetLength() )
 		node = freeNodes.PopLast();
 	else
+	{
 		node = asNEW(asSMapNode_t);
-
+		if( !node )
+		{
+			// Out of memory
+			return 0;
+		}
+	}
+	
 	node->Init(obj, it);
 	return node;
 }

+ 3 - 2
Source/ThirdParty/AngelScript/source/as_gc.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -56,7 +56,7 @@ public:
 	asCGarbageCollector();
 	~asCGarbageCollector();
 
-	int    GarbageCollect(asDWORD flags);
+	int    GarbageCollect(asDWORD flags, asUINT iterations);
 	void   GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	void   GCEnumCallback(void *reference);
 	int    AddScriptObjectToGC(void *obj, asCObjectType *objType);
@@ -104,6 +104,7 @@ protected:
 	void           RemoveNewObjectAtIdx(int idx);
 	void           RemoveOldObjectAtIdx(int idx);
 	void           MoveObjectToOldList(int idx);
+	void           MoveAllObjectsToOldList();
 
 	// Holds all the objects known by the garbage collector
 	asCArray<asSObjTypePair>           gcNewObjects;

+ 15 - 1
Source/ThirdParty/AngelScript/source/as_memory.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -70,6 +70,7 @@ asFREEFUNC_t  userFree  = free;
 extern "C"
 {
 
+// interface
 int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
 {
 	userAlloc = allocFunc;
@@ -78,6 +79,7 @@ int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
 	return 0;
 }
 
+// interface
 int asResetGlobalMemoryFunctions()
 {
 	asThreadCleanup();
@@ -88,6 +90,18 @@ int asResetGlobalMemoryFunctions()
 	return 0;
 }
 
+// interface
+void *asAllocMem(size_t size)
+{
+	return asNEWARRAY(asBYTE, size);
+}
+
+// interface
+void asFreeMem(void *mem)
+{
+	asDELETEARRAY(mem);
+}
+
 } // extern "C"
 
 asCMemoryMgr::asCMemoryMgr()

+ 73 - 9
Source/ThirdParty/AngelScript/source/as_module.cpp

@@ -75,8 +75,15 @@ asCModule::~asCModule()
 	if( engine )
 	{
 		// Clean the user data
-		if( userData && engine->cleanModuleFunc )
-			engine->cleanModuleFunc(this);
+		for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+		{
+			if( userData[n+1] )
+			{
+				for( asUINT c = 0; c < engine->cleanModuleFuncs.GetLength(); c++ )
+					if( engine->cleanModuleFuncs[c].type == userData[n] )
+						engine->cleanModuleFuncs[c].cleanFunc(this);
+			}
+		}
 
 		// Remove the module from the engine
 		if( engine->lastModule == this )
@@ -92,17 +99,55 @@ void asCModule::Discard()
 }
 
 // interface
-void *asCModule::SetUserData(void *data)
+void *asCModule::SetUserData(void *data, asPWORD type)
 {
-	void *oldData = userData;
-	userData = data;
-	return oldData;
+	// As a thread might add a new new user data at the same time as another
+	// it is necessary to protect both read and write access to the userData member
+	ACQUIREEXCLUSIVE(engine->engineRWLock);
+
+	// It is not intended to store a lot of different types of userdata,
+	// so a more complex structure like a associative map would just have
+	// more overhead than a simple array.
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n] == type )
+		{
+			void *oldData = reinterpret_cast<void*>(userData[n+1]);
+			userData[n+1] = reinterpret_cast<asPWORD>(data);
+
+			RELEASEEXCLUSIVE(engine->engineRWLock);
+
+			return oldData;
+		}
+	}
+
+	userData.PushLast(type);
+	userData.PushLast(reinterpret_cast<asPWORD>(data));
+
+	RELEASEEXCLUSIVE(engine->engineRWLock);
+
+	return 0;
 }
 
 // interface
-void *asCModule::GetUserData() const
+void *asCModule::GetUserData(asPWORD type) const
 {
-	return userData;
+	// There may be multiple threads reading, but when
+	// setting the user data nobody must be reading.
+	ACQUIRESHARED(engine->engineRWLock);
+
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n] == type )
+		{
+			RELEASESHARED(engine->engineRWLock);
+			return reinterpret_cast<void*>(userData[n+1]);
+		}
+	}
+
+	RELEASESHARED(engine->engineRWLock);
+
+	return 0;
 }
 
 // interface
@@ -744,6 +789,24 @@ int asCModule::GetTypeIdByDecl(const char *decl) const
 	return engine->GetTypeIdFromDataType(dt);
 }
 
+// interface
+asIObjectType *asCModule::GetObjectTypeByDecl(const char *decl) const
+{
+	asCDataType dt;
+
+	// This const cast is safe since we know the engine won't be modified
+	asCBuilder bld(engine, const_cast<asCModule*>(this));
+
+	// Don't write parser errors to the message callback
+	bld.silent = true;
+
+	int r = bld.ParseDataType(decl, &dt, defaultNamespace);
+	if( r < 0 )
+		return 0;
+
+	return dt.GetObjectType();
+}
+
 // interface
 asUINT asCModule::GetEnumCount() const
 {
@@ -827,7 +890,7 @@ int asCModule::GetNextImportedFunctionId()
 
 #ifndef AS_NO_COMPILER
 // internal
-int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
+int asCModule::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, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
 {
 	asASSERT(id >= 0);
 
@@ -860,6 +923,7 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
 		func->scriptData->declaredAt = declaredAt;
 	}
 	func->parameterTypes   = params;
+	func->parameterNames   = paramNames;
 	func->inOutFlags       = inOutFlags;
 	func->defaultArgs      = defaultArgs;
 	func->objectType       = objType;

+ 10 - 9
Source/ThirdParty/AngelScript/source/as_module.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -132,6 +132,7 @@ public:
 	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual asIObjectType *GetObjectTypeByName(const char *name) const;
+	virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const;
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 
 	// Enums
@@ -159,8 +160,8 @@ public:
 	virtual int LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped);
 
 	// User data
-	virtual void *SetUserData(void *data);
-	virtual void *GetUserData() const;
+	virtual void *SetUserData(void *data, asPWORD type);
+	virtual void *GetUserData(asPWORD type) const;
 
 //-----------------------------------------------
 // Internal
@@ -184,7 +185,7 @@ public:
 	void JITCompile();
 
 #ifndef AS_NO_COMPILER
-	int  AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isFinal = false, bool isOverride = false, bool isShared = false, 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 isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
 	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  AddFuncDef(const asCString &name, asSNameSpace *ns);
@@ -197,11 +198,11 @@ public:
 
 	asCString name;
 
-	asCScriptEngine *engine;
-	asCBuilder      *builder;
-	void            *userData;
-	asDWORD          accessMask;
-	asSNameSpace    *defaultNamespace;
+	asCScriptEngine  *engine;
+	asCBuilder       *builder;
+	asCArray<asPWORD> userData;
+	asDWORD           accessMask;
+	asSNameSpace     *defaultNamespace;
 
 	// This array holds all functions, class members, factories, etc that were compiled with the module
 	asCArray<asCScriptFunction *>     scriptFunctions;

+ 3 - 2
Source/ThirdParty/AngelScript/source/as_namespace.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2013 Andreas Jonsson
+   Copyright (c) 2013-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -73,4 +73,5 @@ struct asSNameSpaceNamePair
 
 END_AS_NAMESPACE
 
-#endif
+#endif
+

+ 10 - 17
Source/ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -369,30 +369,23 @@ int asCObjectType::GetTypeId() const
 // interface
 int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
 {
-	if( flags & asOBJ_TEMPLATE )
-	{
-		if( subtypeIndex >= templateSubTypes.GetLength() )
-			return asINVALID_ARG;
+	// This method is only supported for templates and template specializations
+	if( templateSubTypes.GetLength() == 0 )
+		return asERROR;
 
-		return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
-	}
+	if( subtypeIndex >= templateSubTypes.GetLength() )
+		return asINVALID_ARG;
 
-	// Only template types have sub types
-	return asERROR;
+	return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
 }
 
 // interface
 asIObjectType *asCObjectType::GetSubType(asUINT subtypeIndex) const
 {
-	if( flags & asOBJ_TEMPLATE )
-	{
-		if( subtypeIndex >= templateSubTypes.GetLength() )
-			return 0;
-
-		return templateSubTypes[subtypeIndex].GetObjectType();
-	}
+	if( subtypeIndex >= templateSubTypes.GetLength() )
+		return 0;
 
-	return 0;
+	return templateSubTypes[subtypeIndex].GetObjectType();
 }
 
 asUINT asCObjectType::GetSubTypeCount() const

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -51,28 +51,6 @@ BEGIN_AS_NAMESPACE
 
 // TODO: memory: Need to minimize used memory here, because not all types use all properties of the class
 
-// TODO: The type id should have flags for differenciating between value types and reference types. It should also have a flag for differenciating interface types.
-
-// Additional flag to the class object type
-const asDWORD asOBJ_IMPLICIT_HANDLE  = 0x00400000;
-const asDWORD asOBJ_LIST_PATTERN     = 0x08000000;
-const asDWORD asOBJ_ENUM             = 0x10000000;
-const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
-const asDWORD asOBJ_TYPEDEF          = 0x40000000;
-
-
-
-// asOBJ_GC is used to indicate that the type can potentially 
-// form circular references, thus is garbage collected.
-
-// The fact that an object is garbage collected doesn't imply that an other object  
-// that can reference it also must be garbage collected, only if the garbage collected 
-// object can reference the other object as well.
-
-// For registered types however, we set the flag asOBJ_GC if the GC 
-// behaviours are registered. For script types that contain any such type we 
-// automatically make garbage collected as well, because we cannot know what type
-// of references that object can contain, and must assume the worst.
 
 struct asSTypeBehaviour
 {

File diff suppressed because it is too large
+ 236 - 46
Source/ThirdParty/AngelScript/source/as_parser.cpp


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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -83,11 +83,11 @@ protected:
 	asCScriptNode *ParseFunctionDefinition();
 	asCScriptNode *ParseParameterList();
 	asCScriptNode *SuperficiallyParseExpression();
-	asCScriptNode *ParseType(bool allowConst, bool allowVariableType = false);
+	asCScriptNode *ParseType(bool allowConst, bool allowVariableType = false, bool allowAuto = false);
 	asCScriptNode *ParseTypeMod(bool isParam);
 	void           ParseOptionalScope(asCScriptNode *node);
 	asCScriptNode *ParseRealType();
-	asCScriptNode *ParseDataType(bool allowVariableType = false);
+	asCScriptNode *ParseDataType(bool allowVariableType = false, bool allowAuto = false);
 	asCScriptNode *ParseIdentifier();
 
 	asCScriptNode *ParseListPattern();
@@ -143,7 +143,7 @@ protected:
 	asCScriptNode *ParseExprPreOp();
 	asCScriptNode *ParseExprPostOp();
 	asCScriptNode *ParseExprValue();
-	asCScriptNode *ParseArgList();
+	asCScriptNode *ParseArgList(bool withParenthesis = true);
 	asCScriptNode *ParseFunctionCall();
 	asCScriptNode *ParseVariableAccess();
 	asCScriptNode *ParseConstructCall();
@@ -168,6 +168,7 @@ protected:
 	asCString ExpectedTokens(const char *token1, const char *token2);
 	asCString ExpectedOneOf(int *tokens, int count);
 	asCString ExpectedOneOf(const char **tokens, int count);
+	asCString InsteadFound(sToken &t);
 
 	bool errorWhileParsing;
 	bool isSyntaxError;

+ 228 - 107
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -386,6 +386,10 @@ int asCReader::ReadInner()
 		func = ReadFunction(isNew, false, false);
 		if( func )
 		{
+			// All the global functions were already loaded while loading the scriptFunctions, here
+			// we're just re-reading the refernces to know which goes into the globalFunctions array
+			asASSERT( !isNew );
+
 			module->globalFunctions.Put(func);
 			func->AddRef();
 		}
@@ -486,6 +490,12 @@ int asCReader::ReadInner()
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				Error(TXT_INVALID_BYTECODE_d);
 			}
+			else
+			{
+				// If the callback said this template instance won't be garbage collected then remove the flag
+				if( dontGarbageCollect )
+					usedTypes[i]->flags &= ~asOBJ_GC;
+			}
 		}
 	}
 	engine->deferValidationOfTemplateTypes = false;
@@ -544,6 +554,12 @@ void asCReader::ReadUsedFunctions()
 	asUINT count;
 	count = ReadEncodedUInt();
 	usedFunctions.SetLength(count);
+	if( usedFunctions.GetLength() != count )
+	{
+		// Out of memory
+		error = true;
+		return;
+	}
 	memset(usedFunctions.AddressOf(), 0, sizeof(asCScriptFunction *)*count);
 
 	for( asUINT n = 0; n < usedFunctions.GetLength(); n++ )
@@ -652,6 +668,12 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	}
 
 	func->inOutFlags.SetLength(func->parameterTypes.GetLength());
+	if( func->inOutFlags.GetLength() != func->parameterTypes.GetLength() )
+	{
+		// Out of memory
+		error = true;
+		return;
+	}
 	memset(func->inOutFlags.AddressOf(), 0, sizeof(asETypeModifiers)*func->inOutFlags.GetLength());
 	count = ReadEncodedUInt();
 	if( count > func->parameterTypes.GetLength() )
@@ -679,6 +701,12 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	if( count )
 	{
 		func->defaultArgs.SetLength(func->parameterTypes.GetLength());
+		if( func->defaultArgs.GetLength() != func->parameterTypes.GetLength() )
+		{
+			// Out of memory
+			error = true;
+			return;
+		}
 		memset(func->defaultArgs.AddressOf(), 0, sizeof(asCString*)*func->defaultArgs.GetLength());
 		for( i = 0; i < count; i++ )
 		{
@@ -740,7 +768,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 
 	// Load the new function
 	isNew = true;
-	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
+	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,0,asFUNC_DUMMY);
 	if( func == 0 )
 	{
 		// Out of memory
@@ -763,6 +791,13 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	if( func->funcType == asFUNC_SCRIPT )
 	{
 		func->AllocateScriptFunctionData();
+		if( func->scriptData == 0 )
+		{
+			// Out of memory
+			error = true;
+			asDELETE(func, asCScriptFunction);
+			return 0;
+		}
 
 		if( addToGC && !addToModule )
 			engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
@@ -801,12 +836,26 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 		{
 			length = ReadEncodedUInt();
 			func->scriptData->lineNumbers.SetLength(length);
+			if( int(func->scriptData->lineNumbers.GetLength()) != length )
+			{
+				// Out of memory
+				error = true;
+				asDELETE(func, asCScriptFunction);
+				return 0;
+			}
 			for( i = 0; i < length; ++i )
 				func->scriptData->lineNumbers[i] = ReadEncodedUInt();
 
 			// Read the array of script sections 
 			length = ReadEncodedUInt();
 			func->scriptData->sectionIdxs.SetLength(length);
+			if( int(func->scriptData->sectionIdxs.GetLength()) != length )
+			{
+				// Out of memory
+				error = true;
+				asDELETE(func, asCScriptFunction);
+				return 0;
+			}
 			for( i = 0; i < length; ++i )
 			{
 				if( (i & 1) == 0 )
@@ -820,8 +869,6 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			}
 		}
 
-		ReadData(&func->isShared, 1);
-
 		// Read the variable information
 		if( !noDebugInfo )
 		{
@@ -846,7 +893,10 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			}
 		}
 
-		ReadData(&func->dontCleanUpOnException, 1);
+		char bits;
+		ReadData(&bits, 1);
+		func->isShared               = bits & 1 ? true : false;
+		func->dontCleanUpOnException = bits & 2 ? true : false;
 
 		// Read script section name
 		if( !noDebugInfo )
@@ -856,6 +906,21 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			func->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(name.AddressOf());
 			func->scriptData->declaredAt = ReadEncodedUInt();
 		}
+
+		// Read parameter names
+		if( !noDebugInfo )
+		{
+			asUINT count = asUINT(ReadEncodedUInt64());
+			if( count > func->parameterTypes.GetLength() )
+			{
+				error = true;
+				asDELETE(func, asCScriptFunction);
+				return 0;
+			}
+			func->parameterNames.SetLength(count);
+			for( asUINT n = 0; n < count; n++ )
+				ReadString(&func->parameterNames[n]);
+		}
 	}
 	else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
 	{
@@ -866,6 +931,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	{
 		// The refCount is already 1
 		module->scriptFunctions.PushLast(func);
+		func->module = module;
 	}
 	if( addToEngine )
 	{
@@ -1449,21 +1515,17 @@ void asCReader::ReadGlobalProperty()
 	asCGlobalProperty *prop = module->AllocateGlobalProperty(name.AddressOf(), type, nameSpace);
 
 	// Read the initialization function
-	bool f;
-	ReadData(&f, 1);
-	if( f )
+	bool isNew;
+	// Do not add the function to the GC at this time. It will 
+	// only be added to the GC when the module releases the property
+	asCScriptFunction *func = ReadFunction(isNew, false, true, false);
+	if( func )
 	{
-		bool isNew;
-		// Do not add the function to the GC at this time. It will 
-		// only be added to the GC when the module releases the property
-		asCScriptFunction *func = ReadFunction(isNew, false, true, false);
-		if( func )
-		{
-			prop->SetInitFunc(func);
-			func->Release();
-		}
-		else
-			Error(TXT_INVALID_BYTECODE_d);
+		// Make sure the function knows it is owned by the module
+		func->module = module;
+
+		prop->SetInitFunc(func);
+		func->Release();
 	}
 }
 
@@ -1484,36 +1546,36 @@ void asCReader::ReadObjectProperty(asCObjectType *ot)
 
 void asCReader::ReadDataType(asCDataType *dt) 
 {
-	eTokenType tokenType;
-
-	tokenType = (eTokenType)ReadEncodedUInt();
-	if( tokenType == 0 )
+	// Check if this is a previously used type
+	asUINT n = ReadEncodedUInt();
+	if( n != 0 )
 	{
 		// Get the datatype from the cache
-		asUINT n = ReadEncodedUInt();
-		*dt = savedDataTypes[n];
+		*dt = savedDataTypes[n-1];
 		return;
 	}
 
+	// Read the type definition
+	eTokenType tokenType = (eTokenType)ReadEncodedUInt();
+
 	// Reserve a spot in the savedDataTypes
 	size_t saveSlot = savedDataTypes.GetLength();
 	savedDataTypes.PushLast(asCDataType());
 
 	// Read the datatype for the first time
 	asCObjectType *objType = 0;
-	bool isObjectHandle  = false;
-	bool isReadOnly      = false;
-	bool isHandleToConst = false;
-	bool isReference     = false;
-
 	if( tokenType == ttIdentifier )
-	{
 		objType = ReadObjectType();
-		ReadData(&isObjectHandle, 1);
-		ReadData(&isHandleToConst, 1);
-	}
-	ReadData(&isReference, 1);
-	ReadData(&isReadOnly, 1);
+
+	struct
+	{
+		char isObjectHandle :1;
+		char isHandleToConst:1;
+		char isReference    :1;
+		char isReadOnly     :1;
+	} bits = {0};
+	asASSERT( sizeof(bits) == 1 );
+	ReadData(&bits, 1);
 
 	asCScriptFunction *funcDef = 0;
 	if( tokenType == ttIdentifier && objType && objType->name == "_builtin_function_" )
@@ -1555,16 +1617,16 @@ void asCReader::ReadDataType(asCDataType *dt)
 		*dt = asCDataType::CreateObject(objType, false);
 	else
 		*dt = asCDataType::CreatePrimitive(tokenType, false);
-	if( isObjectHandle )
+	if( bits.isObjectHandle )
 	{
-		dt->MakeReadOnly(isHandleToConst);
+		dt->MakeReadOnly(bits.isHandleToConst ? true : false);
 		
 		// Here we must allow a scoped type to be a handle 
 		// e.g. if the datatype is for a system function
 		dt->MakeHandle(true, true);
 	}
-	dt->MakeReadOnly(isReadOnly);
-	dt->MakeReference(isReference);
+	dt->MakeReadOnly(bits.isReadOnly ? true : false);
+	dt->MakeReference(bits.isReference ? true : false);
 
 	// Update the previously saved slot
 	savedDataTypes[saveSlot] = *dt;
@@ -2080,9 +2142,10 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 	// Pre-compute the size of each instruction in order to translate jump offsets
 	asUINT n;
 	asDWORD *bc = func->scriptData->byteCode.AddressOf();
-	asCArray<asUINT> bcSizes(func->scriptData->byteCode.GetLength());
-	asCArray<asUINT> instructionNbrToPos(func->scriptData->byteCode.GetLength());
-	for( n = 0; n < func->scriptData->byteCode.GetLength(); )
+	asUINT bcLength = (asUINT)func->scriptData->byteCode.GetLength();
+	asCArray<asUINT> bcSizes(bcLength);
+	asCArray<asUINT> instructionNbrToPos(bcLength);
+	for( n = 0; n < bcLength; )
 	{
 		int c = *(asBYTE*)&bc[n];
 		asUINT size = asBCTypeSize[asBCInfo[c].type];
@@ -2097,7 +2160,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 	}
 
 	asUINT bcNum = 0;
-	for( n = 0; n < func->scriptData->byteCode.GetLength(); bcNum++ )
+	for( n = 0; n < bcLength; bcNum++ )
 	{
 		int c = *(asBYTE*)&bc[n];
 		if( c == asBC_REFCPY || 
@@ -2137,7 +2200,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 			{
 				// List patterns have a different way of adjusting the offsets
 				SListAdjuster *listAdj = listAdjusters[listAdjusters.GetLength()-1];
-				*(((short*)&bc[n])+2) = (short)listAdj->AdjustOffset(*(((short*)&bc[n])+2), ot);
+				*(((short*)&bc[n])+2) = (short)listAdj->AdjustOffset(*(((short*)&bc[n])+2));
 			}
 			else
 			{
@@ -2308,7 +2371,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 
 			// The adjuster also needs to know the list type so it can know the type of the elements
 			asCObjectType *ot = func->GetObjectTypeOfLocalVar(asBC_SWORDARG0(&bc[n]));
-			listAdjusters.PushLast(asNEW(SListAdjuster)(&bc[n], ot));
+			listAdjusters.PushLast(asNEW(SListAdjuster)(this, &bc[n], ot));
 		}
 		else if( c == asBC_FREE )
 		{
@@ -2319,6 +2382,12 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 			asCObjectType *ot = *(asCObjectType**)pot;
 			if( ot && (ot->flags & asOBJ_LIST_PATTERN) )
 			{
+				if( listAdjusters.GetLength() == 0 )
+				{
+					Error(TXT_INVALID_BYTECODE_d);
+					return;
+				}
+
 				// Finalize the adjustment of the list buffer that was initiated with asBC_AllocMem
 				SListAdjuster *list = listAdjusters.PopLast();
 				list->AdjustAllocMem();
@@ -2329,7 +2398,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 		{
 			// Adjust the offset in the list where the size is informed
 			SListAdjuster *listAdj = listAdjusters[listAdjusters.GetLength()-1];
-			bc[n+1] = listAdj->AdjustOffset(bc[n+1], listAdj->patternType);
+			bc[n+1] = listAdj->AdjustOffset(bc[n+1]);
 
 			// Inform the list adjuster how many values will be repeated
 			listAdj->SetRepeatCount(bc[n+2]);
@@ -2338,13 +2407,13 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 		{
 			// Adjust the offset in the list where the size is informed
 			SListAdjuster *listAdj = listAdjusters[listAdjusters.GetLength()-1];
-			bc[n+1] = listAdj->AdjustOffset(bc[n+1], listAdj->patternType);
+			bc[n+1] = listAdj->AdjustOffset(bc[n+1]);
 		}
 		else if( c == asBC_SetListType )
 		{
 			// Adjust the offset in the list where the typeid is informed
 			SListAdjuster *listAdj = listAdjusters[listAdjusters.GetLength()-1];
-			bc[n+1] = listAdj->AdjustOffset(bc[n+1], listAdj->patternType);
+			bc[n+1] = listAdj->AdjustOffset(bc[n+1]);
 
 			// Translate the type id
 			bc[n+2] = FindTypeId(bc[n+2]);
@@ -2361,7 +2430,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 
 	// Adjust all variable positions in the bytecode
 	bc = func->scriptData->byteCode.AddressOf();
-	for( n = 0; n < func->scriptData->byteCode.GetLength(); )
+	for( n = 0; n < bcLength; )
 	{
 		int c = *(asBYTE*)&bc[n];
 		switch( asBCInfo[c].type )
@@ -2430,7 +2499,7 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 	//                 This will also make the AdjustGetOffset() function quicker as it can 
 	//                 receive the called function directly instead of having to search for it.
 	bc = func->scriptData->byteCode.AddressOf();
-	for( n = 0; n < func->scriptData->byteCode.GetLength(); )
+	for( n = 0; n < bcLength; )
 	{
 		int c = *(asBYTE*)&bc[n];
 
@@ -2461,8 +2530,8 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 	CalculateStackNeeded(func);
 }
 
-asCReader::SListAdjuster::SListAdjuster(asDWORD *bc, asCObjectType *listType) : 
-	allocMemBC(bc), maxOffset(0), patternType(listType), repeatCount(0), lastOffset(-1), nextTypeId(-1)
+asCReader::SListAdjuster::SListAdjuster(asCReader *rd, asDWORD *bc, asCObjectType *listType) : 
+	reader(rd), allocMemBC(bc), maxOffset(0), patternType(listType), repeatCount(0), lastOffset(-1), nextOffset(0), nextTypeId(-1)
 {
 	asASSERT( patternType && (patternType->flags & asOBJ_LIST_PATTERN) );
 
@@ -2472,13 +2541,13 @@ asCReader::SListAdjuster::SListAdjuster(asDWORD *bc, asCObjectType *listType) :
 	patternNode = node->next;
 }
 
-int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatternType)
+int asCReader::SListAdjuster::AdjustOffset(int offset)
 {
-	// TODO: cleanup: The listPatternType parameter is not needed
-	asASSERT( listPatternType == patternType );
-	UNUSED_VAR( listPatternType );
-
-	asASSERT( offset >= lastOffset );
+	if( offset < lastOffset )
+	{
+		reader->Error(TXT_INVALID_BYTECODE_d);
+		return 0;
+	}
 
 	// If it is the same offset being accessed again, just return the same adjusted value
 	if( lastOffset == offset )
@@ -2488,7 +2557,7 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 	lastAdjustedOffset = maxOffset;
 
 	// What is being expected at this position?
-	if( patternNode->type == asLPT_REPEAT )
+	if( patternNode->type == asLPT_REPEAT || patternNode->type == asLPT_REPEAT_SAME )
 	{
 		// Align the offset to 4 bytes boundary
 		if( maxOffset & 0x3 )
@@ -2499,6 +2568,7 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 
 		// Don't move the patternNode yet because the caller must make a call to SetRepeatCount too
 		maxOffset += 4;
+		nextOffset = offset+1;
 		return lastAdjustedOffset;
 	}
 	else if( patternNode->type == asLPT_TYPE )
@@ -2513,7 +2583,7 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 
 				asCDataType dt = patternType->engine->GetDataTypeFromTypeId(nextTypeId);
 				asUINT size;
-				if( dt.IsObjectHandle() )
+				if( dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_REF)) )
 					size = AS_PTR_SIZE*4;
 				else
 					size = dt.GetSizeInMemoryBytes();
@@ -2532,6 +2602,7 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 				nextTypeId = -1;
 
 				maxOffset += size;
+				nextOffset = offset+1;
 				return lastAdjustedOffset;
 			}
 			else
@@ -2545,36 +2616,40 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 
 				// The first adjustment is for the typeId
 				maxOffset += 4;
-
+				nextOffset = offset+1;
 				return lastAdjustedOffset;
 			}
 		}
 		else
 		{
-			if( repeatCount > 0 )
-				repeatCount--;
-
 			// Determine the size of the element
 			asUINT size;
 			asCDataType dt = reinterpret_cast<asSListPatternDataTypeNode*>(patternNode)->dataType;
-			if( dt.IsObjectHandle() )
+			if( dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_REF)) )
 				size = AS_PTR_SIZE*4;
 			else
 				size = dt.GetSizeInMemoryBytes();
 
-			// Align the offset to 4 bytes boundary
-			if( size >= 4 && (maxOffset & 0x3) )
+			// If values are skipped, the offset needs to be incremented
+			while( nextOffset <= offset )
 			{
-				maxOffset += 4 - (maxOffset & 0x3);
+				if( repeatCount > 0 )
+					repeatCount--;
+
+				// Align the offset to 4 bytes boundary
+				if( size >= 4 && (maxOffset & 0x3) )
+					maxOffset += 4 - (maxOffset & 0x3);
+
 				lastAdjustedOffset = maxOffset;
+				nextOffset += 1;
+				maxOffset += size;
 			}
 
-			maxOffset += size;
-
 			// Only move the patternNode if we're not expecting any more repeated entries
 			if( repeatCount == 0 )
 				patternNode = patternNode->next;
 
+			nextOffset = offset+1;
 			return lastAdjustedOffset;
 		}
 	}
@@ -2589,10 +2664,16 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 		patternNode = patternNode->next;
 
 		lastOffset--;
-		return AdjustOffset(offset, listPatternType);
+		return AdjustOffset(offset);
 	}
 	else if( patternNode->type == asLPT_END )
 	{
+		if( stack.GetLength() == 0 )
+		{
+			reader->Error(TXT_INVALID_BYTECODE_d);
+			return 0;
+		}
+
 		SInfo info = stack.PopLast();
 		repeatCount = info.repeatCount;
 		if( repeatCount )
@@ -2601,21 +2682,22 @@ int asCReader::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 			patternNode = patternNode->next;
 
 		lastOffset--;
-		return AdjustOffset(offset, listPatternType);
+		return AdjustOffset(offset);
 	}
 	else
 	{
 		// Something is wrong with the pattern list declaration
-		asASSERT( false );
+		reader->Error(TXT_INVALID_BYTECODE_d);
+		return 0;
 	}
 
-	return 0;
+	UNREACHABLE_RETURN;
 }
 
 void asCReader::SListAdjuster::SetRepeatCount(asUINT rc)
 {
 	// Make sure the list is expecting a repeat at this location
-	asASSERT( patternNode->type == asLPT_REPEAT );
+	asASSERT( patternNode->type == asLPT_REPEAT || patternNode->type == asLPT_REPEAT_SAME );
 
 	// Now move to the next patternNode
 	patternNode = patternNode->next;
@@ -3392,8 +3474,6 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 			}
 		}
 
-		WriteData(&func->isShared, 1);
-
 		// Write the variable information
 		if( !stripDebugInfo )
 		{
@@ -3409,7 +3489,10 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 			}
 		}
 
-		WriteData(&func->dontCleanUpOnException, 1);
+		char bits = 0;
+		bits += func->isShared ? 1 : 0;
+		bits += func->dontCleanUpOnException ? 2 : 0;
+		WriteData(&bits,1);
 
 		// Store script section name
 		if( !stripDebugInfo )
@@ -3423,6 +3506,15 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 			}
 			WriteEncodedInt64(func->scriptData->declaredAt);
 		}
+
+		// Store the parameter names
+		if( !stripDebugInfo )
+		{
+			asUINT count = asUINT(func->parameterNames.GetLength());
+			WriteEncodedInt64(count);
+			for( asUINT n = 0; n < count; n++ )
+				WriteString(&func->parameterNames[n]);
+		}
 	}
 	else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
 	{
@@ -3487,6 +3579,7 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 			int size = (asUINT)ot->interfaces.GetLength();
 			WriteEncodedInt64(size);
 			asUINT n;
+			asASSERT( ot->interfaces.GetLength() == ot->interfaceVFTOffsets.GetLength() );
 			for( n = 0; n < ot->interfaces.GetLength(); n++ )
 			{
 				WriteObjectType(ot->interfaces[n]);
@@ -3655,18 +3748,7 @@ void asCWriter::WriteGlobalProperty(asCGlobalProperty* prop)
 	WriteDataType(&prop->type);
 
 	// Store the initialization function
-	if( prop->GetInitFunc() )
-	{
-		bool f = true;
-		WriteData(&f, 1);
-
-		WriteFunction(prop->GetInitFunc());
-	}
-	else
-	{
-		bool f = false;
-		WriteData(&f, 1);
-	}
+	WriteFunction(prop->GetInitFunc());
 }
 
 void asCWriter::WriteObjectProperty(asCObjectProperty* prop) 
@@ -3683,31 +3765,36 @@ void asCWriter::WriteDataType(const asCDataType *dt)
 	{
 		if( *dt == savedDataTypes[n] )
 		{
-			asUINT c = 0;
-			WriteEncodedInt64(c);
-			WriteEncodedInt64(n);
+			WriteEncodedInt64(n+1);
 			return;
 		}
 	}
 
+	// Indicate a new type with a null byte
+	asUINT c = 0;
+	WriteEncodedInt64(c);
+
 	// Save the new datatype
 	savedDataTypes.PushLast(*dt);
 
-	bool b;
 	int t = dt->GetTokenType();
 	WriteEncodedInt64(t);
 	if( t == ttIdentifier )
-	{
 		WriteObjectType(dt->GetObjectType());
-		b = dt->IsObjectHandle();
-		WriteData(&b, 1);
-		b = dt->IsHandleToConst();
-		WriteData(&b, 1);
-	}
-	b = dt->IsReference();
-	WriteData(&b, 1);
-	b = dt->IsReadOnly();
-	WriteData(&b, 1);
+
+	struct
+	{
+		char isObjectHandle :1;
+		char isHandleToConst:1;
+		char isReference    :1;
+		char isReadOnly     :1;
+	} bits = {0};
+
+	bits.isObjectHandle  = dt->IsObjectHandle();
+	bits.isHandleToConst = dt->IsHandleToConst();
+	bits.isReference     = dt->IsReference();
+	bits.isReadOnly      = dt->IsReadOnly();
+	WriteData(&bits, 1);
 
 	if( t == ttIdentifier && dt->GetObjectType()->name == "_builtin_function_" )
 	{
@@ -4476,7 +4563,7 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
 	}
 }
 
-asCWriter::SListAdjuster::SListAdjuster(asCObjectType *ot) : patternType(ot), repeatCount(0), entries(0), lastOffset(-1), nextTypeId(-1)
+asCWriter::SListAdjuster::SListAdjuster(asCObjectType *ot) : patternType(ot), repeatCount(0), entries(0), lastOffset(-1), nextOffset(0), nextTypeId(-1)
 { 
 	asASSERT( ot && (ot->flags & asOBJ_LIST_PATTERN) ); 
 
@@ -4498,12 +4585,16 @@ int asCWriter::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 	if( offset == lastOffset )
 		return entries-1;
 
+	asASSERT( offset >= nextOffset );
+
+	// Update last offset for next call
 	lastOffset = offset;
 
 	// What is being expected at this position?
-	if( patternNode->type == asLPT_REPEAT )
+	if( patternNode->type == asLPT_REPEAT || patternNode->type == asLPT_REPEAT_SAME )
 	{
 		// Don't move the patternNode yet because the caller must make a call to SetRepeatCount too
+		nextOffset = offset + 4;
 		return entries++;
 	}
 	else if( patternNode->type == asLPT_TYPE )
@@ -4516,6 +4607,8 @@ int asCWriter::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 			// we can move to the next node
 			if( nextTypeId != -1 )
 			{
+				nextOffset = offset + 4;
+
 				if( repeatCount > 0 )
 					repeatCount--;
 
@@ -4529,7 +4622,35 @@ int asCWriter::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 		else 
 		{
 			if( repeatCount > 0 )
+			{
+				// Was any value skipped?
+				asUINT size;
+				if( dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_REF)) )
+					size = AS_PTR_SIZE*4;
+				else
+					size = dt.GetSizeInMemoryBytes();
+
+				int count = 0;
+				while( nextOffset <= offset )
+				{
+					count++;
+					nextOffset += size;
+
+					// Align the offset on 4 byte boundaries
+					if( size >= 4 && (nextOffset & 0x3) )
+						nextOffset += 4 - (nextOffset & 0x3);
+				}
+
+				if( --count > 0 )
+				{
+					// Skip these values
+					repeatCount -= count;
+					entries += count;
+				}
+
+				nextOffset = offset + size;
 				repeatCount--;
+			}
 
 			// Only move the patternNode if we're not expecting any more repeated entries
 			if( repeatCount == 0 )
@@ -4575,7 +4696,7 @@ int asCWriter::SListAdjuster::AdjustOffset(int offset, asCObjectType *listPatter
 void asCWriter::SListAdjuster::SetRepeatCount(asUINT rc)
 {
 	// Make sure the list is expecting a repeat at this location
-	asASSERT( patternNode->type == asLPT_REPEAT );
+	asASSERT( patternNode->type == asLPT_REPEAT || patternNode->type == asLPT_REPEAT_SAME );
 
 	// Now move to the next patternNode
 	patternNode = patternNode->next;

+ 6 - 3
Source/ThirdParty/AngelScript/source/as_restore.h

@@ -124,9 +124,9 @@ protected:
 	// Helper class for adjusting offsets within initialization list buffers
 	struct SListAdjuster
 	{
-		SListAdjuster(asDWORD *bc, asCObjectType *ot);
+		SListAdjuster(asCReader *rd, asDWORD *bc, asCObjectType *ot);
 		void AdjustAllocMem();
-		int  AdjustOffset(int offset, asCObjectType *listPatternType);
+		int  AdjustOffset(int offset);
 		void SetRepeatCount(asUINT rc);
 		void SetNextType(int typeId);
 
@@ -137,11 +137,13 @@ protected:
 		};
 		asCArray<SInfo> stack;
 
+		asCReader          *reader;
 		asDWORD            *allocMemBC;
 		asUINT              maxOffset;
 		asCObjectType      *patternType;
 		asUINT              repeatCount;
 		int                 lastOffset;
+		int                 nextOffset;
 		asUINT              lastAdjustedOffset;
 		asSListPatternNode *patternNode;
 		int                 nextTypeId;
@@ -239,7 +241,8 @@ protected:
 		asUINT              repeatCount;
 		asSListPatternNode *patternNode;
 		asUINT              entries;
-		int                 lastOffset;
+		int                 lastOffset;  // Last offset adjusted
+		int                 nextOffset;  // next expected offset to be adjusted
 		int                 nextTypeId;
 	};
 	asCArray<SListAdjuster*> listAdjusters;

File diff suppressed because it is too large
+ 308 - 197
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp


+ 53 - 38
Source/ThirdParty/AngelScript/source/as_scriptengine.h

@@ -100,17 +100,18 @@ public:
 	// Type registration
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags);
 	virtual int            RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset);
-	virtual int            RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
+	virtual int            RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
 	virtual int            RegisterInterface(const char *name);
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration);
 	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual asIObjectType *GetObjectTypeByName(const char *name) const;
+	virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const;
 
 	// String factory
 	virtual int RegisterStringFactory(const char *datatype, const asSFuncPtr &factoryFunc, asDWORD callConv, void *objForThiscall = 0);
-	virtual int GetStringFactoryReturnTypeId() const;
+	virtual int GetStringFactoryReturnTypeId(asDWORD *flags) const;
 
 	// Default array type
 	virtual int RegisterDefaultArrayType(const char *type);
@@ -160,47 +161,43 @@ public:
 	virtual int            GetSizeOfPrimitiveType(int typeId) const;
 
 	// Script execution
-	virtual asIScriptContext  *CreateContext();
-#ifdef AS_DEPRECATED
-// Deprecated since 2.27.0, 2013-07-18
-	virtual void              *CreateScriptObject(int typeId);
-	virtual void              *CreateScriptObjectCopy(void *obj, int typeId);
-	virtual void              *CreateUninitializedScriptObject(int typeId);
-	virtual void               AssignScriptObject(void *dstObj, void *srcObj, int typeId);
-	virtual void               ReleaseScriptObject(void *obj, int typeId);
-	virtual void               AddRefScriptObject(void *obj, int typeId);
-#endif
-	virtual void              *CreateScriptObject(const asIObjectType *type);
-	virtual void              *CreateScriptObjectCopy(void *obj, const asIObjectType *type);
-	virtual void              *CreateUninitializedScriptObject(const asIObjectType *type);
-	virtual asIScriptFunction *CreateDelegate(asIScriptFunction *func, void *obj);
-	virtual void               AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type);
-	virtual void               ReleaseScriptObject(void *obj, const asIObjectType *type);
-	virtual void               AddRefScriptObject(void *obj, const asIObjectType *type);
+	virtual asIScriptContext      *CreateContext();
+	virtual void                  *CreateScriptObject(const asIObjectType *type);
+	virtual void                  *CreateScriptObjectCopy(void *obj, const asIObjectType *type);
+	virtual void                  *CreateUninitializedScriptObject(const asIObjectType *type);
+	virtual asIScriptFunction     *CreateDelegate(asIScriptFunction *func, void *obj);
+	virtual void                   AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type);
+	virtual void                   ReleaseScriptObject(void *obj, const asIObjectType *type);
+	virtual void                   AddRefScriptObject(void *obj, const asIObjectType *type);
 	// TODO: interface: Should have a method void *CastObject(void *obj, asIObjectType *fromType, asIObjectType *toType); 
 	//                  For script objects it should simply check if the object implements or derives from the toType
 	//                  For application objects it should look for ref cast behaviours and call the matching one
 	//                  Once implemented the IsHandleCompatibleWithObject should be removed from the engine
-	virtual bool               IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
-	asILockableSharedBool     *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const;
+	virtual bool                   IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
+	virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const;
+
+	// Context pooling
+	virtual asIScriptContext *RequestContext();
+	virtual void              ReturnContext(asIScriptContext *ctx);
+	virtual int               SetContextCallbacks(asREQUESTCONTEXTFUNC_t requestCtx, asRETURNCONTEXTFUNC_t returnCtx, void *param = 0);
 
 	// String interpretation
 	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, int *tokenLength = 0) const;
 
 	// Garbage collection
-	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE);
+	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1);
 	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	virtual int  NotifyGarbageCollectorOfNewObject(void *obj, asIObjectType *type);
 	virtual int  GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj = 0, asIObjectType **type = 0);
 	virtual void GCEnumCallback(void *reference);
 
 	// User data
-	virtual void *SetUserData(void *data, asPWORD type = 0);
-	virtual void *GetUserData(asPWORD type = 0) const;
-	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback, asPWORD type = 0);
-	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback);
-	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
-	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
+	virtual void *SetUserData(void *data, asPWORD type);
+	virtual void *GetUserData(asPWORD type) const;
+	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback, asPWORD type);
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback, asPWORD type);
+	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type);
+	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type);
 	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type);
 
 //===========================================================
@@ -220,12 +217,12 @@ public:
 	friend class asCByteCode;
 	friend int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
 
-	int RegisterMethodToObjectType(asCObjectType *objectType, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
+	int RegisterMethodToObjectType(asCObjectType *objectType, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
 	int RegisterBehaviourToObjectType(asCObjectType *objectType, asEBehaviours behaviour, const char *decl, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall);
 
 	int VerifyVarTypeNotInFunction(asCScriptFunction *func);
 
-	void *CallAlloc(asCObjectType *objType) const;
+	void *CallAlloc(const asCObjectType *objType) const;
 	void  CallFree(void *obj) const;
 
 	void *CallGlobalFunctionRetPtr(int func) const;
@@ -409,7 +406,17 @@ public:
 	bool                        msgCallback;
 	asSSystemFunctionInterface  msgCallbackFunc;
 	void                       *msgCallbackObj;
-
+	struct preMessage_t
+	{
+		preMessage_t() { isSet = false; }
+		bool      isSet;
+		asCString message;
+		asCString scriptname;
+		int       r;
+		int       c;
+	} preMessage;
+
+	// JIt compilation
 	asIJITCompiler             *jitCompiler;
 
 	// Namespaces
@@ -423,16 +430,24 @@ public:
 	asCArray<asCString*>          stringConstants;
 	asCMap<asCStringPointer, int> stringToIdMap;
 
+	// Callbacks for context pooling
+	asREQUESTCONTEXTFUNC_t  requestCtxFunc;
+	asRETURNCONTEXTFUNC_t   returnCtxFunc;
+	void                   *ctxCallbackParam;
+
 	// User data
 	asCArray<asPWORD>       userData;
 
-	struct SEngineClean { asPWORD type; asCLEANENGINEFUNC_t cleanFunc; };
-	asCArray<SEngineClean>  cleanEngineFuncs;
-	asCLEANMODULEFUNC_t     cleanModuleFunc;
-	asCLEANCONTEXTFUNC_t    cleanContextFunc;
-	asCLEANFUNCTIONFUNC_t   cleanFunctionFunc;
-	struct SObjTypeClean { asPWORD type; asCLEANOBJECTTYPEFUNC_t cleanFunc; };
-	asCArray<SObjTypeClean> cleanObjectTypeFuncs;
+	struct SEngineClean   { asPWORD type; asCLEANENGINEFUNC_t     cleanFunc; };
+	asCArray<SEngineClean>   cleanEngineFuncs;
+	struct SModuleClean   { asPWORD type; asCLEANMODULEFUNC_t     cleanFunc; };
+	asCArray<SModuleClean>   cleanModuleFuncs;
+	struct SContextClean  { asPWORD type; asCLEANCONTEXTFUNC_t    cleanFunc; };
+	asCArray<SContextClean>  cleanContextFuncs;
+	struct SFunctionClean { asPWORD type; asCLEANFUNCTIONFUNC_t   cleanFunc; };
+	asCArray<SFunctionClean> cleanFunctionFuncs;
+	struct SObjTypeClean  { asPWORD type; asCLEANOBJECTTYPEFUNC_t cleanFunc; };
+	asCArray<SObjTypeClean>  cleanObjectTypeFuncs;
 
 	// Synchronization for threads
 	DECLAREREADWRITELOCK(mutable engineRWLock)

+ 202 - 21
Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -105,6 +105,15 @@ static void ScriptFunction_CreateDelegate_Generic(asIScriptGeneric *gen)
 	gen->SetReturnAddress(CreateDelegate(func, obj));
 }
 
+// TODO: 2.29.0: operator==
+/*static void ScriptFunction_opEquals_Generic(asIScriptGeneric *gen)
+{
+	asCScriptFunction *funcSelf = (asCScriptFunction*)gen->GetObject();
+	asCScriptFunction *funcOther = (asCScriptFunction*)gen->GetArgAddress(0);
+	*(bool*)gen->GetAddressOfReturnLocation() = *funcSelf == *funcOther;
+}
+*/
+
 #endif
 
 
@@ -124,6 +133,8 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCScriptFunction,GetFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCScriptFunction,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCScriptFunction,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
+	// TODO: 2.29.0: Need some way to allow the arg type to adapt when the funcdefs are instanciated
+//	r = engine->RegisterMethodToObjectType(&engine->functionBehaviours, "bool opEquals(const int &in)", asMETHOD(asCScriptFunction,operator==), asCALL_THISCALL); asASSERT( r >= 0 );
 #else
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptFunction_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptFunction_Release_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
@@ -132,6 +143,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ScriptFunction_GetFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptFunction_EnumReferences_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptFunction_ReleaseAllHandles_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
+//	r = engine->RegisterMethodToObjectType(&engine->functionBehaviours, "bool opEquals(const int &in)", asFUNCTION(ScriptFunction_opEquals_Generic), asCALL_GENERIC); asASSERT( r >= 0 );
 #endif
 
 	// Register the builtin function for creating delegates
@@ -214,6 +226,24 @@ asIScriptFunction *asCScriptFunction::GetDelegateFunction() const
 	return funcForDelegate;
 }
 
+// TODO: 2.29.0: operator==
+/*
+// internal
+bool asCScriptFunction::operator==(const asCScriptFunction &other) const
+{
+	if( this == &other ) return true;
+
+	if( this->funcType == asFUNC_DELEGATE && other.funcType == asFUNC_DELEGATE )
+	{
+		if( this->objForDelegate == other.objForDelegate &&
+			this->funcForDelegate == other.funcForDelegate )
+			return true;
+	}
+
+	return false;
+}
+*/
+
 // internal
 int asCScriptFunction::RegisterListPattern(const char *decl, asCScriptNode *listNodes)
 {
@@ -243,8 +273,23 @@ int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char
 	{
 		if( listNodes->nodeType == snIdentifier )
 		{
-			node->next = asNEW(asSListPatternNode)(asLPT_REPEAT);
-			node = node->next;
+			asCString token(&decl[listNodes->tokenPos], listNodes->tokenLength);
+			if( token == "repeat" )
+			{
+				node->next = asNEW(asSListPatternNode)(asLPT_REPEAT);
+				node = node->next;
+			}
+			else if( token == "repeat_same" )
+			{
+				// TODO: list: Should make sure this is a sub-list
+				node->next = asNEW(asSListPatternNode)(asLPT_REPEAT_SAME);
+				node = node->next;
+			}
+			else
+			{
+				// Shouldn't happen as the parser already reported the error
+				asASSERT(false);
+			}
 		}
 		else if( listNodes->nodeType == snDataType )
 		{
@@ -374,9 +419,16 @@ asCScriptFunction::~asCScriptFunction()
 void asCScriptFunction::DestroyInternal()
 {
 	// Clean up user data
-	if( userData && engine->cleanFunctionFunc )
-		engine->cleanFunctionFunc(this);
-	userData = 0;
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n+1] )
+		{
+			for( asUINT c = 0; c < engine->cleanFunctionFuncs.GetLength(); c++ )
+				if( engine->cleanFunctionFuncs[c].type == userData[n] )
+					engine->cleanFunctionFuncs[c].cleanFunc(this);
+		}
+	}
+	userData.SetLength(0);
 
 	// Release all references the function holds to other objects
 	ReleaseReferences();
@@ -560,7 +612,7 @@ bool asCScriptFunction::DoesReturnOnStack() const
 }
 
 // internal
-asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool includeNamespace) const
+asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool includeNamespace, bool includeParamNames) const
 {
 	asCString str;
 
@@ -618,6 +670,12 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 				else if( inOutFlags[n] == asTM_INOUTREF ) str += "inout";
 			}
 
+			if( includeParamNames && n < parameterNames.GetLength() && parameterNames[n].GetLength() != 0 )
+			{
+				str += " ";
+				str += parameterNames[n];
+			}
+
 			if( defaultArgs.GetLength() > n && defaultArgs[n] )
 			{
 				asCString tmp;
@@ -637,6 +695,12 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 			else if( inOutFlags[n] == asTM_INOUTREF ) str += "inout";
 		}
 
+		if( includeParamNames && n < parameterNames.GetLength() && parameterNames[n].GetLength() != 0 )
+		{
+			str += " ";
+			str += parameterNames[n];
+		}
+
 		if( defaultArgs.GetLength() > n && defaultArgs[n] )
 		{
 			asCString tmp;
@@ -654,17 +718,32 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 	if( listPattern )
 	{
 		asSListPatternNode *n = listPattern;
+		bool first = true;
 		while( n )
 		{
 			if( n->type == asLPT_START )
+			{
 				str += " {";
+				first = true;
+			}
 			else if( n->type == asLPT_END )
+			{
 				str += " }";
+				first = false;
+			}
 			else if( n->type == asLPT_REPEAT )
 				str += " repeat";
+			else if( n->type == asLPT_REPEAT_SAME )
+				str += " repeat_same";
 			else if( n->type == asLPT_TYPE )
 			{
-				str += " ";
+				if( first )
+				{
+					str += " ";
+					first = false;
+				}
+				else
+					str += ", ";
 				str += reinterpret_cast<asSListPatternDataTypeNode*>(n)->dataType.Format();
 			}
 
@@ -694,7 +773,7 @@ int asCScriptFunction::FindNextLineWithCode(int line) const
 		{
 			static int cmp(const void *a, const void *b) { return *(int*)a - *(int*)b; }
 		};
-		qsort(&lineNbrs[0], lineNbrs.GetLength(), sizeof(int), C::cmp);
+		std::qsort(&lineNbrs[0], lineNbrs.GetLength(), sizeof(int), C::cmp);
 
 		if( line < lineNbrs[0] && line < (scriptData->declaredAt&0xFFFFF)) return -1;
 		if( line > lineNbrs[lineNbrs.GetLength()-1] ) return -1;
@@ -936,7 +1015,8 @@ void asCScriptFunction::AddReferences()
 				parameterTypes[p].GetObjectType()->AddRef();
 
 		for( asUINT v = 0; v < scriptData->objVariableTypes.GetLength(); v++ )
-			scriptData->objVariableTypes[v]->AddRef();
+			if( scriptData->objVariableTypes[v] ) // The null handle is also stored, but it doesn't have an object type
+				scriptData->objVariableTypes[v]->AddRef();
 
 		// Go through the byte code and add references to all resources used by the function
 		asCArray<asDWORD> &bc = scriptData->byteCode;
@@ -1197,6 +1277,42 @@ asUINT asCScriptFunction::GetParamCount() const
 }
 
 // interface
+int asCScriptFunction::GetParam(asUINT index, int *typeId, asDWORD *flags, const char **name, const char **defaultArg) const
+{
+	if( index >= parameterTypes.GetLength() )
+		return asINVALID_ARG;
+
+	if( typeId )
+		*typeId = engine->GetTypeIdFromDataType(parameterTypes[index]);
+
+	if( flags )
+	{
+		*flags = inOutFlags[index];
+		*flags |= parameterTypes[index].IsReadOnly() ? asTM_CONST : 0;
+	}
+
+	if( name )
+	{
+		// The parameter names are not stored if loading from bytecode without debug information
+		if( index < parameterNames.GetLength() )
+			*name = parameterNames[index].AddressOf();
+		else
+			*name = 0;
+	}
+
+	if( defaultArg )
+	{
+		if( index < defaultArgs.GetLength() && defaultArgs[index] )
+			*defaultArg = defaultArgs[index]->AddressOf();
+		else
+			*defaultArg = 0;
+	}
+
+	return asSUCCESS;
+}
+
+#ifdef AS_DEPRECATED
+// Deprecated since 2014-04-06, 2.29.0
 int asCScriptFunction::GetParamTypeId(asUINT index, asDWORD *flags) const
 {
 	if( index >= parameterTypes.GetLength() )
@@ -1210,6 +1326,7 @@ int asCScriptFunction::GetParamTypeId(asUINT index, asDWORD *flags) const
 
 	return engine->GetTypeIdFromDataType(parameterTypes[index]);
 }
+#endif
 
 // interface
 asIScriptEngine *asCScriptFunction::GetEngine() const
@@ -1218,10 +1335,10 @@ asIScriptEngine *asCScriptFunction::GetEngine() const
 }
 
 // interface
-const char *asCScriptFunction::GetDeclaration(bool includeObjectName, bool includeNamespace) const
+const char *asCScriptFunction::GetDeclaration(bool includeObjectName, bool includeNamespace, bool includeParamNames) const
 {
 	asCString *tempString = &asCThreadManager::GetLocalData()->string;
-	*tempString = GetDeclarationStr(includeObjectName, includeNamespace);
+	*tempString = GetDeclarationStr(includeObjectName, includeNamespace, includeParamNames);
 	return tempString->AddressOf();
 }
 
@@ -1267,6 +1384,33 @@ void asCScriptFunction::JITCompile()
 	if( !jit )
 		return;
 
+	// Make sure the function has been compiled with JitEntry instructions
+	// For functions that has JitEntry this will be a quick test
+	asUINT length;
+	asDWORD *byteCode = GetByteCode(&length);
+	asDWORD *end = byteCode + length;
+	bool foundJitEntry = false;
+	while( byteCode < end )
+	{
+		// Determine the instruction
+		asEBCInstr op = asEBCInstr(*(asBYTE*)byteCode);
+		if( op == asBC_JitEntry )
+		{
+			foundJitEntry = true;
+			break;
+		}
+
+		// Move to next instruction
+		byteCode += asBCTypeSize[asBCInfo[op].type];
+	}
+
+	if( !foundJitEntry )
+	{
+		asCString msg;
+		msg.Format(TXT_NO_JIT_IN_FUNC_s, GetDeclaration());
+		engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
+	}
+
 	// Release the previous function, if any
 	if( scriptData->jitFunction )
 	{
@@ -1277,9 +1421,7 @@ void asCScriptFunction::JITCompile()
 	// Compile for native system
 	int r = jit->CompileFunction(this, &scriptData->jitFunction);
 	if( r < 0 )
-	{
 		asASSERT( scriptData->jitFunction == 0 );
-	}
 }
 
 // interface
@@ -1297,17 +1439,55 @@ asDWORD *asCScriptFunction::GetByteCode(asUINT *length)
 }
 
 // interface
-void *asCScriptFunction::SetUserData(void *data)
+void *asCScriptFunction::SetUserData(void *data, asPWORD type)
 {
-	void *oldData = userData;
-	userData = data;
-	return oldData;
+	// As a thread might add a new new user data at the same time as another
+	// it is necessary to protect both read and write access to the userData member
+	ACQUIREEXCLUSIVE(engine->engineRWLock);
+
+	// It is not intended to store a lot of different types of userdata,
+	// so a more complex structure like a associative map would just have
+	// more overhead than a simple array.
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n] == type )
+		{
+			void *oldData = reinterpret_cast<void*>(userData[n+1]);
+			userData[n+1] = reinterpret_cast<asPWORD>(data);
+
+			RELEASEEXCLUSIVE(engine->engineRWLock);
+
+			return oldData;
+		}
+	}
+
+	userData.PushLast(type);
+	userData.PushLast(reinterpret_cast<asPWORD>(data));
+
+	RELEASEEXCLUSIVE(engine->engineRWLock);
+
+	return 0;
 }
 
 // interface
-void *asCScriptFunction::GetUserData() const
+void *asCScriptFunction::GetUserData(asPWORD type) const
 {
-	return userData;
+	// There may be multiple threads reading, but when
+	// setting the user data nobody must be reading.
+	ACQUIRESHARED(engine->engineRWLock);
+
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n] == type )
+		{
+			RELEASESHARED(engine->engineRWLock);
+			return reinterpret_cast<void*>(userData[n+1]);
+		}
+	}
+
+	RELEASESHARED(engine->engineRWLock);
+
+	return 0;
 }
 
 // internal
@@ -1451,7 +1631,8 @@ void asCScriptFunction::ReleaseAllHandles(asIScriptEngine *)
 			}
 
 		for( asUINT n = 0; n < scriptData->objVariableTypes.GetLength(); n++ )
-			scriptData->objVariableTypes[n]->Release();
+			if( scriptData->objVariableTypes[n] ) // Null handle is also stored, but it doesn't have an object type
+				scriptData->objVariableTypes[n]->Release();
 		scriptData->objVariableTypes.SetLength(0);
 
 		// Release all script functions

+ 21 - 7
Source/ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -66,6 +66,7 @@ struct asSScriptVariable
 enum asEListPatternNodeType
 {
 	asLPT_REPEAT,
+	asLPT_REPEAT_SAME,
 	asLPT_START,
 	asLPT_END,
 	asLPT_TYPE
@@ -134,14 +135,18 @@ public:
 	const char          *GetObjectName() const;
 	const char          *GetName() const;
 	const char          *GetNamespace() const;
-	const char          *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false) const;
+	const char          *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const;
 	bool                 IsReadOnly() const;
 	bool                 IsPrivate() const;
 	bool                 IsFinal() const;
 	bool                 IsOverride() const;
 	bool                 IsShared() const;
 	asUINT               GetParamCount() const;
+	int                  GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const;
+#ifdef AS_DEPRECATED
+	// Deprecated, since 2.29.0, 2014-04-06
 	int                  GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
+#endif
 	int                  GetReturnTypeId(asDWORD *flags = 0) const;
 
 	// Type id for function pointers 
@@ -163,8 +168,8 @@ public:
 	asDWORD             *GetByteCode(asUINT *length = 0);
 
 	// User data
-	void                *SetUserData(void *userData);
-	void                *GetUserData() const;
+	void                *SetUserData(void *userData, asPWORD type);
+	void                *GetUserData(asPWORD type) const;
 
 public:
 	//-----------------------------------
@@ -173,6 +178,14 @@ public:
 	asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
 	~asCScriptFunction();
 
+	// TODO: 2.29.0: operator==
+	// TODO: 2.29.0: The asIScriptFunction should provide operator== and operator!= that should do a
+	//               a value comparison. Two delegate objects that point to the same object and class method should compare as equal
+	// TODO: 2.29.0: The operator== should also be provided in script as opEquals to allow the same comparison in script
+	//               To do this we'll need some way to adapt the argtype for opEquals for each funcdef, preferrably without instantiating lots of different methods
+	//               Perhaps reusing 'auto' to mean the same type as the object
+	//bool      operator==(const asCScriptFunction &other) const;
+
 	void      DestroyInternal();
 	void      Orphan(asIScriptModule *mod);
 
@@ -180,7 +193,7 @@ public:
 
 	int       GetSpaceNeededForArguments();
 	int       GetSpaceNeededForReturnValue();
-	asCString GetDeclarationStr(bool includeObjectName = true, bool includeNamespace = false) const;
+	asCString GetDeclarationStr(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const;
 	int       GetLineNumber(int programPosition, int *sectionIdx);
 	void      ComputeSignatureId();
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
@@ -225,12 +238,13 @@ public:
 	asCScriptEngine             *engine;
 	asCModule                   *module;
 
-	void                        *userData;
+	asCArray<asPWORD>            userData;
 
 	// Function signature
 	asCString                    name;
 	asCDataType                  returnType;
 	asCArray<asCDataType>        parameterTypes;
+	asCArray<asCString>          parameterNames;
 	asCArray<asETypeModifiers>   inOutFlags;
 	asCArray<asCString *>        defaultArgs;
 	bool                         isReadOnly;
@@ -264,7 +278,7 @@ public:
 		// The stack space needed for the local variables
 		asDWORD                         variableSpace;
 
-		// These hold information objects and function pointers, including temporary
+		// These hold information on objects and function pointers, including temporary
 		// variables used by exception handler and when saving bytecode
 		asCArray<asCObjectType*>        objVariableTypes;
 		asCArray<asCScriptFunction*>    funcVariableTypes;

+ 3 - 2
Source/ThirdParty/AngelScript/source/as_scriptnode.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -88,7 +88,8 @@ enum eScriptNode
 	snVirtualProperty,
 	snNamespace,
 	snMixin,
-	snListPattern
+	snListPattern,
+	snNamedArgument
 };
 
 struct sToken

+ 37 - 21
Source/ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -45,11 +45,6 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 	int r = 0;
 	bool isNested = false;
 
-	// TODO: runtime optimize: There should be a pool for the context so it doesn't 
-	//                         have to be allocated just for creating the script object
-
-	// TODO: It must be possible for the application to debug the creation of the object too
-
 	// Use nested call in the context if there is an active context
 	ctx = asGetActiveContext();
 	if( ctx )
@@ -64,9 +59,13 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 	
 	if( ctx == 0 )
 	{
-		r = engine->CreateContext(&ctx, true);
-		if( r < 0 )
+		// Request a context from the engine
+		ctx = engine->RequestContext();
+		if( ctx == 0 )
+		{
+			// TODO: How to best report this failure?
 			return 0;
+		}
 	}
 
 	r = ctx->Prepare(engine->scriptFunctions[objType->beh.factory]);
@@ -75,7 +74,7 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 		if( isNested )
 			ctx->PopState();
 		else
-			ctx->Release();
+			engine->ReturnContext(ctx);
 		return 0;
 	}
 
@@ -106,7 +105,7 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 				ctx->Abort();
 		}
 		else
-			ctx->Release();
+			engine->ReturnContext(ctx);
 		return 0;
 	}
 
@@ -118,7 +117,7 @@ asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngi
 	if( isNested )
 		ctx->PopState();
 	else
-		ctx->Release();
+		engine->ReturnContext(ctx);
 
 	return ptr;
 }
@@ -251,7 +250,7 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 
 	// Initialize members to zero. Technically we only need to zero the pointer
 	// members, but just the memset is faster than having to loop and check the datatypes
-	memset(this+1, 0, objType->size - sizeof(asCScriptObject));
+	memset((void*)(this+1), 0, objType->size - sizeof(asCScriptObject));
 
 	if( doInitialize )
 	{
@@ -495,10 +494,13 @@ void asCScriptObject::CallDestructor()
 
 				if( ctx == 0 )
 				{
-					// Setup a context for calling the default constructor
-					asCScriptEngine *engine = objType->engine;
-					int r = engine->CreateContext(&ctx, true);
-					if( r < 0 ) return;
+					// Request a context from the engine
+					ctx = objType->engine->RequestContext();
+					if( ctx == 0 )
+					{
+						// TODO: How to best report this failure?
+						return;
+					}
 				}
 			}
 
@@ -542,7 +544,10 @@ void asCScriptObject::CallDestructor()
 				ctx->Abort();
 		}
 		else
-			ctx->Release();
+		{
+			// Return the context to engine
+			objType->engine->ReturnContext(ctx);
+		}
 	}
 }
 
@@ -744,9 +749,13 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 
 			if( ctx == 0 )
 			{
-				r = engine->CreateContext(&ctx, true);
-				if( r < 0 )
+				// Request a context from the engine
+				ctx = engine->RequestContext();
+				if( ctx == 0 )
+				{
+					// TODO: How to best report this failure?
 					return *this;
+				}
 			}
 
 			r = ctx->Prepare(engine->scriptFunctions[objType->beh.copy]);
@@ -755,7 +764,8 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 				if( isNested )
 					ctx->PopState();
 				else
-					ctx->Release();
+					engine->ReturnContext(ctx);
+				// TODO: How to best report this failure?
 				return *this;
 			}
 
@@ -791,14 +801,20 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 						ctx->Abort();
 				}
 				else
-					ctx->Release();
+				{
+					// Return the context to the engine
+					engine->ReturnContext(ctx);
+				}
 				return *this;
 			}
 
 			if( isNested )
 				ctx->PopState();
 			else
-				ctx->Release();
+			{
+				// Return the context to the engine
+				engine->ReturnContext(ctx);
+			}
 		}
 	}
 

+ 54 - 3
Source/ThirdParty/AngelScript/source/as_string.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -31,8 +31,8 @@
 #include "as_config.h"
 
 #include <stdarg.h>		// va_list, va_start(), etc
-#include <stdlib.h>     // strtod(), strtol()
-#include <string.h> // some compilers declare memcpy() here
+#include <stdlib.h>		// strtod(), strtol()
+#include <string.h>		// some compilers declare memcpy() here
 
 #if !defined(AS_NO_MEMORY_H)
 #include <memory.h>
@@ -56,6 +56,26 @@ asCString::asCString(const asCString &str)
 	Assign(str.AddressOf(), str.length);
 }
 
+#ifdef AS_CAN_USE_CPP11
+asCString::asCString(asCString &&str)
+{
+	if( str.length <= 11 )
+	{
+		length = str.length;
+		memcpy(local, str.local, length);
+		local[length] = 0;
+	}
+	else
+	{
+		dynamic = str.dynamic;
+		length = str.length;
+	}
+
+	str.dynamic = 0;
+	str.length = 0;
+}
+#endif // c++11
+
 asCString::asCString(const char *str, size_t len)
 {
 	length = 0;
@@ -183,6 +203,37 @@ asCString &asCString::operator =(const asCString &str)
 	return *this;
 }
 
+#ifdef AS_CAN_USE_CPP11
+asCString &asCString::operator =(asCString &&str)
+{
+	if( this != &str )
+	{
+		if( length > 11 && dynamic )
+		{
+			asDELETEARRAY(dynamic);
+		}
+
+		if ( str.length <= 11 )
+		{
+			length = str.length;
+
+			memcpy(local, str.local, length);
+			local[length] = 0;
+		}
+		else
+		{
+			dynamic = str.dynamic;
+			length = str.length;
+		}
+
+		str.dynamic = 0;
+		str.length = 0;
+	}
+
+	return *this;
+}
+#endif // c++11
+
 asCString &asCString::operator =(char ch)
 {
 	Assign(&ch, 1);

+ 6 - 3
Source/ThirdParty/AngelScript/source/as_string.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -38,14 +38,17 @@
 #include <stdio.h>
 #include <string.h>
 
-// TODO: optimize: On compilers with C++11 support the string class should take advantage of the move operator &&
-
 class asCString
 {
 public:
 	asCString();
 	~asCString();
 
+#ifdef AS_CAN_USE_CPP11
+	asCString(asCString &&);
+	asCString &operator =(asCString &&);
+#endif // c++11
+
 	asCString(const asCString &);
 	asCString(const char *);
 	asCString(const char *, size_t length);

+ 25 - 15
Source/ThirdParty/AngelScript/source/as_symboltable.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2012-2013 Andreas Jonsson
+   Copyright (c) 2012-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -125,7 +125,7 @@ public:
 
 	const asCArray<unsigned int> &GetIndexes(const asSNameSpace *ns, const asCString &name) const;
 
-	int          Put(T* entry);
+	int      Put(T* entry);
 
 	unsigned int GetSize() const;
 
@@ -355,19 +355,7 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 	if( !entry )
 		return false;
 
-	if( idx == m_entries.GetLength() - 1 )
-	{
-		m_entries.PopLast();
-
-		// TODO: Should remove all trailing empty slots
-	}
-	else
-	{
-		// TODO: Must pack or reuse empty slots
-		m_entries[idx] = 0;
-	}
-	m_size--;
-
+	// Remove the symbol from the lookup map
 	asSNameSpaceNamePair key;
 	GetKey(entry, key);
 
@@ -382,6 +370,28 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 	else
 		asASSERT(false);
 
+	// Remove the symbol from the indexed array
+	if( idx == m_entries.GetLength() - 1 )
+		m_entries.PopLast();
+	else
+	{
+		// Must keep the array packed
+		int prevIdx = int(m_entries.GetLength()-1);
+		m_entries[idx] = m_entries.PopLast();
+		
+		// Update the index in the lookup map
+		entry = m_entries[idx];
+		GetKey(entry, key);
+		if( m_map.MoveTo(&cursor, key) )
+		{
+			asCArray<unsigned int> &arr = m_map.GetValue(cursor);
+			arr[arr.IndexOf(prevIdx)] = idx;
+		}
+		else
+			asASSERT(false);
+	}
+	m_size--;
+
 	return true;
 }
 

+ 65 - 56
Source/ThirdParty/AngelScript/source/as_texts.h

@@ -41,41 +41,46 @@
 
 // Compiler messages
 
-#define TXT_s_ALREADY_DECLARED            "'%s' is already declared"
-#define TXT_ARG_NOT_LVALUE                "Argument cannot be assigned. Output will be discarded."
+#define TXT_s_ALREADY_DECLARED                    "'%s' is already declared"
+#define TXT_ARG_NOT_LVALUE                        "Argument cannot be assigned. Output will be discarded."
 
 #define TXT_BOTH_MUST_BE_SAME                     "Both expressions must have the same type"
 #define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
 #define TEXT_BASE_DOESNT_HAVE_DEF_CONSTR          "Base class doesn't have default constructor. Make explicit call to base constructor"
 
-#define TXT_CANDIDATES_ARE                       "Candidates are:"
-#define TXT_CANNOT_CALL_CONSTRUCTOR_IN_LOOPS     "Can't call a constructor in loops"
-#define TXT_CANNOT_CALL_CONSTRUCTOR_IN_SWITCH    "Can't call a constructor in switch"
-#define TXT_CANNOT_CALL_CONSTRUCTOR_TWICE        "Can't call a constructor multiple times"
+#define TXT_CANDIDATES_ARE                         "Candidates are:"
+#define TXT_CANNOT_CALL_CONSTRUCTOR_IN_LOOPS       "Can't call a constructor in loops"
+#define TXT_CANNOT_CALL_CONSTRUCTOR_IN_SWITCH      "Can't call a constructor in switch"
+#define TXT_CANNOT_CALL_CONSTRUCTOR_TWICE          "Can't call a constructor multiple times"
 #define TXT_CANNOT_CREATE_DELEGATE_FOR_NOREF_TYPES "Can't create delegate for types that do not support handles"
-#define TXT_CANNOT_IMPLEMENT_SELF                "Can't implement itself, or another interface that implements this interface"
-#define TXT_CANNOT_INHERIT_FROM_s_FINAL          "Can't inherit from class '%s' marked as final"
-#define TXT_CANNOT_INHERIT_FROM_MULTIPLE_CLASSES "Can't inherit from multiple classes"
-#define TXT_CANNOT_INHERIT_FROM_SELF             "Can't inherit from itself, or another class that inherits from this class"
-#define TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s "Can't instanciate template '%s' with subtype '%s'"
-#define TXT_CANNOT_RETURN_REF_TO_LOCAL           "Can't return reference to local value."
-#define TXT_CANT_IMPLICITLY_CONVERT_s_TO_s       "Can't implicitly convert from '%s' to '%s'."
-#define TXT_CANT_RETURN_VALUE                    "Can't return value when return type is 'void'"
-#define TXT_CHANGE_SIGN                          "Implicit conversion changed sign of value"
-#define TXT_COMPILING_s                          "Compiling %s"
-#define TXT_COMPOUND_ASGN_WITH_PROP              "Compound assignments with property accessors are not allowed"
-#define TXT_CONSTRUCTOR_NAME_ERROR               "The name of constructors and destructors must be the same as the class"
-
-#define TXT_DATA_TYPE_CANT_BE_s           "Data type can't be '%s'"
-#define TXT_DECL_IN_SWITCH                "Variables cannot be declared in switch cases, except inside statement blocks"
-#define TXT_DEFAULT_MUST_BE_LAST          "The default case must be the last one"
-#define TXT_DEF_ARG_MISSING_IN_FUNC_s     "All subsequent parameters after the first default value must have default values in function '%s'"
-#define TXT_DEF_ARG_TYPE_DOESNT_MATCH     "The type of the default argument expression doesn't match the function parameter type"
+#define TXT_CANNOT_IMPLEMENT_SELF                  "Can't implement itself, or another interface that implements this interface"
+#define TXT_CANNOT_INHERIT_FROM_s_FINAL            "Can't inherit from class '%s' marked as final"
+#define TXT_CANNOT_INHERIT_FROM_MULTIPLE_CLASSES   "Can't inherit from multiple classes"
+#define TXT_CANNOT_INHERIT_FROM_SELF               "Can't inherit from itself, or another class that inherits from this class"
+#define TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s   "Can't instanciate template '%s' with subtype '%s'"
+#define TXT_CANNOT_PASS_CLASS_METHOD_AS_ARG        "Can't pass class method as arg directly. Use a delegate object instead"
+#define TXT_CANNOT_RETURN_REF_TO_LOCAL             "Can't return reference to local value."
+#define TXT_CANT_IMPLICITLY_CONVERT_s_TO_s         "Can't implicitly convert from '%s' to '%s'."
+#define TXT_CANT_RETURN_VALUE                      "Can't return value when return type is 'void'"
+#define TXT_CHANGE_SIGN                            "Implicit conversion changed sign of value"
+#define TXT_COMPILING_s                            "Compiling %s"
+#define TXT_COMPOUND_ASGN_WITH_PROP                "Compound assignments with property accessors are not allowed"
+#define TXT_CONSTRUCTOR_NAME_ERROR                 "The name of constructors and destructors must be the same as the class"
+
+#define TXT_DATA_TYPE_CANT_BE_s                     "Data type can't be '%s'"
+#define TXT_CANNOT_RESOLVE_AUTO                     "Unable to resolve auto type"
+#define TXT_AUTO_NOT_ALLOWED                        "Auto is not allowed here"
+#define TXT_DECL_IN_SWITCH                          "Variables cannot be declared in switch cases, except inside statement blocks"
+#define TXT_DEFAULT_MUST_BE_LAST                    "The default case must be the last one"
+#define TXT_DEF_ARG_MISSING_IN_FUNC_s               "All subsequent parameters after the first default value must have default values in function '%s'"
+#define TXT_DEF_ARG_TYPE_DOESNT_MATCH               "The type of the default argument expression doesn't match the function parameter type"
+#define TXT_POS_ARG_AFTER_NAMED_ARG                 "Positional arguments cannot be passed after named arguments"
+#define TXT_DUPLICATE_NAMED_ARG                     "Duplicate named argument"
 #define TXT_DERIVED_METHOD_MUST_HAVE_SAME_RETTYPE_s "The method in the derived class must have the same return type as in the base class: '%s'"
-#define TXT_DESTRUCTOR_MAY_NOT_HAVE_PARM  "The destructor must not have any parameters"
-#define TXT_DISALLOW_ASSIGN_ON_REF_TYPE   "Value assignment on reference types is not allowed. Did you mean to do a handle assignment?"
-#define TXT_DISALLOW_COMPOUND_ASSIGN_ON_REF_TYPE "Compound assignment on reference types is not allowed"
-#define TXT_DUPLICATE_SWITCH_CASE         "Duplicate switch case"
+#define TXT_DESTRUCTOR_MAY_NOT_HAVE_PARM            "The destructor must not have any parameters"
+#define TXT_DISALLOW_ASSIGN_ON_REF_TYPE             "Value assignment on reference types is not allowed. Did you mean to do a handle assignment?"
+#define TXT_DISALLOW_COMPOUND_ASSIGN_ON_REF_TYPE    "Compound assignment on reference types is not allowed"
+#define TXT_DUPLICATE_SWITCH_CASE                   "Duplicate switch case"
 
 #define TXT_ELSE_WITH_EMPTY_STATEMENT     "Else with empty statement"
 #define TXT_EMPTY_SWITCH                  "Empty switch statement"
@@ -107,28 +112,31 @@
 
 #define TXT_HANDLE_ASSIGN_ON_NON_HANDLE_PROP     "It is not allowed to perform a handle assignment on a non-handle property"
 #define TXT_HANDLE_COMPARISON                    "The operand is implicitly converted to handle in order to compare them"
+#define TXT_HANDLE_OF_HANDLE_IS_NOT_ALLOWED      "Handle to handle is not allowed"
 
-#define TXT_IDENTIFIER_s_NOT_DATA_TYPE          "Identifier '%s' is not a data type"
-#define TXT_IF_WITH_EMPTY_STATEMENT             "If with empty statement"
-#define TXT_ILLEGAL_MEMBER_TYPE                 "Illegal member type"
+#define TXT_IDENTIFIER_s_NOT_DATA_TYPE             "Identifier '%s' is not a data type"
+#define TXT_IF_WITH_EMPTY_STATEMENT                "If with empty statement"
+#define TXT_ILLEGAL_MEMBER_TYPE                    "Illegal member type"
 // TODO: Should be TXT_ILLEGAL_OPERATION_ON_s
-#define TXT_ILLEGAL_OPERATION                   "Illegal operation on this datatype"
-#define TXT_ILLEGAL_OPERATION_ON_s              "Illegal operation on '%s'"
-#define TXT_ILLEGAL_TARGET_TYPE_FOR_REF_CAST    "Illegal target type for reference cast"
-#define TXT_ILLEGAL_VARIABLE_NAME_s             "Illegal variable name '%s'."
-#define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s     "Initialization lists cannot be used with '%s'"
+#define TXT_ILLEGAL_OPERATION                      "Illegal operation on this datatype"
+#define TXT_ILLEGAL_OPERATION_ON_s                 "Illegal operation on '%s'"
+#define TXT_ILLEGAL_TARGET_TYPE_FOR_REF_CAST       "Illegal target type for reference cast"
+#define TXT_ILLEGAL_VARIABLE_NAME_s                "Illegal variable name '%s'."
+#define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s        "Initialization lists cannot be used with '%s'"
+#define TXT_INSTEAD_FOUND_s                        "Instead found '%s'"
 #define TXT_INTERFACE_CAN_ONLY_IMPLEMENT_INTERFACE "Interfaces can only implement other interfaces"
-#define TXT_INVALID_BREAK                       "Invalid 'break'"
-#define TXT_INVALID_CHAR_LITERAL                "Invalid character literal"
-#define TXT_INVALID_CONTINUE                    "Invalid 'continue'"
-#define TXT_INVALID_ESCAPE_SEQUENCE             "Invalid escape sequence"
-#define TXT_INVALID_OP_ON_METHOD                "Invalid operation on method"
-#define TXT_INVALID_REF_PROP_ACCESS             "Invalid reference. Property accessors cannot be used in combined read/write operations"
-#define TXT_INVALID_SCOPE                       "Invalid scope resolution"
-#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_VALUE               "Invalid unicode code point"
-#define TXT_INVALID_UNICODE_SEQUENCE_IN_SRC     "Invalid unicode sequence in source"
+#define TXT_INVALID_BREAK                          "Invalid 'break'"
+#define TXT_INVALID_CHAR_LITERAL                   "Invalid character literal"
+#define TXT_INVALID_CONTINUE                       "Invalid 'continue'"
+#define TXT_INVALID_ESCAPE_SEQUENCE                "Invalid escape sequence"
+#define TXT_INVALID_EXPRESSION_AMBIGUOUS_NAME     "Invalid expression: ambiguous name"
+#define TXT_INVALID_OP_ON_METHOD                   "Invalid operation on method"
+#define TXT_INVALID_REF_PROP_ACCESS                "Invalid reference. Property accessors cannot be used in combined read/write operations"
+#define TXT_INVALID_SCOPE                          "Invalid scope resolution"
+#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_VALUE                  "Invalid unicode code point"
+#define TXT_INVALID_UNICODE_SEQUENCE_IN_SRC        "Invalid unicode sequence in source"
 
 #define TXT_METHOD_CANNOT_OVERRIDE_s                "Method '%s' declared as final and cannot be overridden"
 #define TXT_METHOD_CANT_HAVE_NAME_OF_CLASS          "The method cannot be named with the class name"
@@ -156,13 +164,13 @@
 #define TXT_NAME_CONFLICT_s_METHOD                 "Name conflict. '%s' is a class method."
 #define TXT_NAME_CONFLICT_s_ALREADY_USED           "Name conflict. '%s' is already used."
 #define TXT_NO_APPROPRIATE_INDEX_OPERATOR          "No appropriate indexing operator found"
-#define TXT_NO_APPROPRIATE_OPASSIGN                "No appropriate opAssign method found"
+#define TXT_NO_APPROPRIATE_OPHNDLASSIGN_s          "No appropriate opHndlAssign method found in '%s'"
 #define TXT_NO_APPROPRIATE_OPEQUALS                "No appropriate opEquals method found"
 #define TXT_NO_CONVERSION_s_TO_s                   "No conversion from '%s' to '%s' available."
 #define TXT_NO_CONVERSION_s_TO_MATH_TYPE           "No conversion from '%s' to math type available."
 #define TXT_NO_DEFAULT_ARRAY_TYPE                  "The application doesn't support the default array type."
 #define TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s           "No default constructor for object of type '%s'."
-#define TXT_NO_DEFAULT_COPY_OP_FOR_s               "There is no copy operator for the type '%s' available."
+#define TXT_NO_DEFAULT_COPY_OP_FOR_s               "No appropriate opAssign method found in '%s'"
 #define TXT_NO_COPY_CONSTRUCTOR_FOR_s              "No copy constructor for object of type '%s'."
 #define TXT_NO_MATCHING_SIGNATURES_TO_s            "No matching signatures to '%s'"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
@@ -226,13 +234,13 @@
 #define TXT_TOO_MANY_VALUES_FOR_LIST           "Too many values to match pattern"
 #define TXT_TYPE_s_NOT_AVAILABLE_FOR_MODULE    "Type '%s' is not available for this module"
 
-#define TXT_UNEXPECTED_END_OF_FILE        "Unexpected end of file"
-#define TXT_UNEXPECTED_TOKEN_s            "Unexpected token '%s'"
-#define TXT_UNINITIALIZED_GLOBAL_VAR_s    "Use of uninitialized global variable '%s'."
-#define TXT_UNKNOWN_SCOPE_s               "Unknown scope '%s'"
-#define TXT_UNREACHABLE_CODE              "Unreachable code"
+#define TXT_UNEXPECTED_END_OF_FILE             "Unexpected end of file"
+#define TXT_UNEXPECTED_TOKEN_s                 "Unexpected token '%s'"
+#define TXT_UNINITIALIZED_GLOBAL_VAR_s         "Use of uninitialized global variable '%s'."
+#define TXT_UNKNOWN_SCOPE_s                    "Unknown scope '%s'"
+#define TXT_UNREACHABLE_CODE                   "Unreachable code"
 #define TXT_UNRECOGNIZED_VIRTUAL_PROPERTY_NODE "Virtual property contains unrecognized aspect"
-#define TXT_UNUSED_SCRIPT_NODE            "Unused script node"
+#define TXT_UNUSED_SCRIPT_NODE                 "Unused script node"
 
 #define TXT_VALUE_TOO_LARGE_FOR_TYPE      "Value is too large for data type"
 #define TXT_VOID_CANT_BE_OPERAND          "Void cannot be an operand in expressions"
@@ -247,7 +255,7 @@
 
 // Global variable initialization
 
-#define TXT_FAILED_TO_INITIALIZE_s		"Failed to initialize global variable '%s'"
+#define TXT_FAILED_TO_INITIALIZE_s      "Failed to initialize global variable '%s'"
 #define TXT_EXCEPTION_s_IN_s            "Exception '%s' in '%s'"
 
 // Engine message
@@ -287,6 +295,7 @@
 #define TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d               "The function in previous message is named '%s'. The func type is %d"
 #define TXT_RESURRECTING_SCRIPTOBJECT_s                  "The script object of type '%s' is being resurrected illegally during destruction"
 #define TXT_INVALID_BYTECODE_d                           "LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: %d"
+#define TXT_NO_JIT_IN_FUNC_s                             "Function '%s' appears to have been compiled without JIT entry points"
 
 // Internal names
 

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

@@ -172,7 +172,8 @@ enum eTokenType
 	ttCast,                // cast
 	ttPrivate,             // private
 	ttNamespace,           // namespace
-	ttMixin                // mixin
+	ttMixin,               // mixin
+	ttAuto                 // auto
 };
 
 struct sTokenWord
@@ -239,6 +240,7 @@ sTokenWord const tokenWords[] =
 	asTokenDef("!is"       , ttNotIs),
 	asTokenDef("@"         , ttHandle),
 	asTokenDef("and"       , ttAnd),
+	asTokenDef("auto"      , ttAuto),
 	asTokenDef("bool"      , ttBool),
 	asTokenDef("break"     , ttBreak),
 	asTokenDef("case"      , ttCase), 

+ 4 - 3
Source/ThirdParty/AngelScript/source/as_tokenizer.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -223,7 +223,7 @@ bool asCTokenizer::IsComment(const char *source, size_t sourceLength, size_t &to
 		}
 
 		tokenType   = ttOnelineComment;
-		tokenLength = n+1;
+		tokenLength = n < sourceLength ? n+1 : n;
 
 		return true;
 	}
@@ -443,7 +443,8 @@ bool asCTokenizer::IsKeyWord(const char *source, size_t sourceLength, size_t &to
 			// and the tokens "!" and "isTrue" in the "!isTrue" expression.
 			if( wlen < sourceLength &&
 				((source[wlen-1] >= 'a' && source[wlen-1] <= 'z') ||
-				 (source[wlen-1] >= 'A' && source[wlen-1] <= 'Z')) &&
+				 (source[wlen-1] >= 'A' && source[wlen-1] <= 'Z') ||
+				 (source[wlen-1] >= '0' && source[wlen-1] <= '9')) &&
 				((source[wlen] >= 'a' && source[wlen] <= 'z') ||
 				 (source[wlen] >= 'A' && source[wlen] <= 'Z') ||
 				 (source[wlen] >= '0' && source[wlen] <= '9') ||

+ 1 - 1
Source/ThirdParty/SDL/src/video/uikit/SDL_uikitappdelegate.m

@@ -88,7 +88,7 @@ const char* SDL_IOS_GetResourceDir()
     if (!resource_dir)
     {
         const char *temp = [[[NSBundle mainBundle] resourcePath] UTF8String];
-        resource_dir = malloc(strlen(temp + 1));
+        resource_dir = malloc(strlen(temp) + 1);
         strcpy(resource_dir, temp);
     }
     

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