Browse Source

Updated to AngelScript 2.24.0a.
Do not sort batches front-to-back on mobile devices.
Disable shadow map reuse in NinjaSnowWar on mobile devices.

Lasse Öörni 13 years ago
parent
commit
96bdad35a0
54 changed files with 3058 additions and 1262 deletions
  1. 4 0
      Bin/Data/Scripts/NinjaSnowWar.as
  2. 1 1
      Docs/Urho3D.dox
  3. 5 1
      Engine/Graphics/Batch.cpp
  4. 414 176
      Engine/Script/Addons.cpp
  5. 47 35
      Engine/Script/Addons.h
  6. 1 1
      Readme.txt
  7. 59 17
      ThirdParty/AngelScript/include/angelscript.h
  8. 48 0
      ThirdParty/AngelScript/source/as_array.h
  9. 1 3
      ThirdParty/AngelScript/source/as_atomic.cpp
  10. 159 25
      ThirdParty/AngelScript/source/as_builder.cpp
  11. 1 0
      ThirdParty/AngelScript/source/as_builder.h
  12. 16 2
      ThirdParty/AngelScript/source/as_bytecode.cpp
  13. 33 27
      ThirdParty/AngelScript/source/as_callfunc.cpp
  14. 9 1
      ThirdParty/AngelScript/source/as_callfunc_arm.cpp
  15. 3 3
      ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  16. 1 1
      ThirdParty/AngelScript/source/as_callfunc_mips.cpp
  17. 1 1
      ThirdParty/AngelScript/source/as_callfunc_ppc.cpp
  18. 1 1
      ThirdParty/AngelScript/source/as_callfunc_ppc_64.cpp
  19. 1 1
      ThirdParty/AngelScript/source/as_callfunc_sh4.cpp
  20. 1 1
      ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  21. 1 1
      ThirdParty/AngelScript/source/as_callfunc_x64_mingw.cpp
  22. 1 1
      ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp
  23. 1 1
      ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  24. 198 255
      ThirdParty/AngelScript/source/as_callfunc_xenon.cpp
  25. 192 33
      ThirdParty/AngelScript/source/as_compiler.cpp
  26. 8 8
      ThirdParty/AngelScript/source/as_config.h
  27. 292 228
      ThirdParty/AngelScript/source/as_context.cpp
  28. 64 47
      ThirdParty/AngelScript/source/as_context.h
  29. 68 2
      ThirdParty/AngelScript/source/as_criticalsection.h
  30. 6 0
      ThirdParty/AngelScript/source/as_gc.cpp
  31. 6 0
      ThirdParty/AngelScript/source/as_generic.cpp
  32. 4 1
      ThirdParty/AngelScript/source/as_generic.h
  33. 7 1
      ThirdParty/AngelScript/source/as_map.h
  34. 122 28
      ThirdParty/AngelScript/source/as_module.cpp
  35. 7 3
      ThirdParty/AngelScript/source/as_module.h
  36. 143 29
      ThirdParty/AngelScript/source/as_objecttype.cpp
  37. 15 9
      ThirdParty/AngelScript/source/as_objecttype.h
  38. 3 0
      ThirdParty/AngelScript/source/as_outputbuffer.cpp
  39. 179 71
      ThirdParty/AngelScript/source/as_parser.cpp
  40. 2 0
      ThirdParty/AngelScript/source/as_parser.h
  41. 182 77
      ThirdParty/AngelScript/source/as_restore.cpp
  42. 2 0
      ThirdParty/AngelScript/source/as_restore.h
  43. 3 1
      ThirdParty/AngelScript/source/as_scriptcode.cpp
  44. 398 57
      ThirdParty/AngelScript/source/as_scriptengine.cpp
  45. 50 29
      ThirdParty/AngelScript/source/as_scriptengine.h
  46. 5 0
      ThirdParty/AngelScript/source/as_scriptfunction.cpp
  47. 4 1
      ThirdParty/AngelScript/source/as_scriptnode.cpp
  48. 99 24
      ThirdParty/AngelScript/source/as_scriptobject.cpp
  49. 5 3
      ThirdParty/AngelScript/source/as_scriptobject.h
  50. 5 0
      ThirdParty/AngelScript/source/as_string.cpp
  51. 1 0
      ThirdParty/AngelScript/source/as_texts.h
  52. 167 53
      ThirdParty/AngelScript/source/as_thread.cpp
  53. 7 2
      ThirdParty/AngelScript/source/as_thread.h
  54. 5 0
      ThirdParty/AngelScript/source/as_variablescope.cpp

+ 4 - 0
Bin/Data/Scripts/NinjaSnowWar.as

@@ -144,6 +144,10 @@ void InitScene()
         return;
         return;
 
 
     gameScene.LoadXML(cache.GetFile("Scenes/NinjaSnowWar.xml"));
     gameScene.LoadXML(cache.GetFile("Scenes/NinjaSnowWar.xml"));
+    
+    // On mobile devices render the shadowmap first
+    if (GetPlatform() == "Android" || GetPlatform() == "iOS")
+        renderer.reuseShadowMaps = false;
 }
 }
 
 
 void InitNetworking()
 void InitNetworking()

+ 1 - 1
Docs/Urho3D.dox

@@ -61,7 +61,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
 
 
-- AngelScript 2.23.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.24.0a (http://www.angelcode.com/angelscript/)
 - Bullet 2.80 (http://www.bulletphysics.org/)
 - Bullet 2.80 (http://www.bulletphysics.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - GLee 5.4 (http://elf-stone.com/)
 - GLee 5.4 (http://elf-stone.com/)

+ 5 - 1
Engine/Graphics/Batch.cpp

@@ -66,7 +66,10 @@ static void SortFrontToBack2Pass(PODVector<Batch*>& batches)
     // First sort with state having priority
     // First sort with state having priority
     Sort(batches.Begin(), batches.End(), CompareBatchesFrontToBack);
     Sort(batches.Begin(), batches.End(), CompareBatchesFrontToBack);
     
     
-    // Then rewrite distances so that different states will be ordered front to back, and sort again
+    // Then rewrite distances so that different states will be ordered front to back, and sort again.
+    // Do not do this on mobile devices as they likely use a tiled deferred approach, with which 
+    // front-to-back sorting is irrelevant
+    #ifndef GL_ES_VERSION_2_0
     float lastDistance;
     float lastDistance;
     unsigned long long lastSortKey;
     unsigned long long lastSortKey;
     for (PODVector<Batch*>::Iterator i = batches.Begin(); i != batches.End(); ++i)
     for (PODVector<Batch*>::Iterator i = batches.Begin(); i != batches.End(); ++i)
@@ -89,6 +92,7 @@ static void SortFrontToBack2Pass(PODVector<Batch*>& batches)
     }
     }
     
     
     Sort(batches.Begin(), batches.End(), CompareBatchesFrontToBack);
     Sort(batches.Begin(), batches.End(), CompareBatchesFrontToBack);
+    #endif
 }
 }
 
 
 void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split, Renderer* renderer, const Vector3& translation)
 void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split, Renderer* renderer, const Vector3& translation)

File diff suppressed because it is too large
+ 414 - 176
Engine/Script/Addons.cpp


+ 47 - 35
Engine/Script/Addons.h

@@ -28,31 +28,39 @@
 // Adapted from Angelscript's scriptarray & scriptstdstring add-ons, but with garbage collection disabled
 // Adapted from Angelscript's scriptarray & scriptstdstring add-ons, but with garbage collection disabled
 
 
 struct SArrayBuffer;
 struct SArrayBuffer;
+struct SArrayCache;
 
 
-/// %Script array type.
+/// %Script array class.
 class CScriptArray
 class CScriptArray
 {
 {
 public:
 public:
     CScriptArray(asUINT length, asIObjectType *ot);
     CScriptArray(asUINT length, asIObjectType *ot);
     CScriptArray(asUINT length, void *defVal, asIObjectType *ot);
     CScriptArray(asUINT length, void *defVal, asIObjectType *ot);
     virtual ~CScriptArray();
     virtual ~CScriptArray();
-    
+
     void AddRef() const;
     void AddRef() const;
     void Release() const;
     void Release() const;
-    
+
     // Type information
     // Type information
     asIObjectType *GetArrayObjectType() const;
     asIObjectType *GetArrayObjectType() const;
-    int GetArrayTypeId() const;
-    int GetElementTypeId() const;
-    
-    void Resize(asUINT numElements);
+    int            GetArrayTypeId() const;
+    int            GetElementTypeId() const;
+
+    void   Reserve(asUINT maxElements);
+    void   Resize(asUINT numElements);
     asUINT GetSize() const;
     asUINT GetSize() const;
-    
+    bool   IsEmpty() const;
+
     // Get a pointer to an element. Returns 0 if out of bounds
     // Get a pointer to an element. Returns 0 if out of bounds
-    void  *At(asUINT index);
-    
+    void       *At(asUINT index);
+    const void *At(asUINT index) const;
+
+    // Set value of an element
+    void  SetValue(asUINT index, void *value);
+
     CScriptArray &operator=(const CScriptArray&);
     CScriptArray &operator=(const CScriptArray&);
-    
+    bool operator==(const CScriptArray &) const;
+
     void InsertAt(asUINT index, void *value);
     void InsertAt(asUINT index, void *value);
     void RemoveAt(asUINT index);
     void RemoveAt(asUINT index);
     void InsertLast(void *value);
     void InsertLast(void *value);
@@ -63,33 +71,37 @@ public:
     void SortDesc(asUINT index, asUINT count);
     void SortDesc(asUINT index, asUINT count);
     void Sort(asUINT index, asUINT count, bool asc);
     void Sort(asUINT index, asUINT count, bool asc);
     void Reverse();
     void Reverse();
-    int Find(void *value);
-    int Find(asUINT index, void *value);
-    
+    int  Find(void *value) const;
+    int  Find(asUINT index, void *value) const;
+
+    // GC methods
+    int  GetRefCount();
+    void SetFlag();
+    bool GetFlag();
+    void EnumReferences(asIScriptEngine *engine);
+    void ReleaseAllHandles(asIScriptEngine *engine);
+
 protected:
 protected:
-    mutable int refCount;
-    mutable bool gcFlag;
-    asIObjectType *objType;
-    SArrayBuffer *buffer;
-    int elementSize;
-    asIScriptFunction* cmpFunc;
-    asIScriptFunction* eqFunc;
-    int subTypeId;
-    
-    bool Less(const void *a, const void *b, bool asc, asIScriptContext *ctx);
+    mutable int       refCount;
+    mutable bool      gcFlag;
+    asIObjectType    *objType;
+    SArrayBuffer     *buffer;
+    int               elementSize;
+    int               subTypeId;
+
+    bool  Less(const void *a, const void *b, bool asc, asIScriptContext *ctx);
     void *GetArrayItemPointer(int index);
     void *GetArrayItemPointer(int index);
     void *GetDataPointer(void *buffer);
     void *GetDataPointer(void *buffer);
-    void Copy(void *dst, void *src);
-    void Precache();
-    bool CheckMaxSize(asUINT numElements);
-    void Resize(int delta, asUINT at);
-    void SetValue(asUINT index, void *value);
-    void CreateBuffer(SArrayBuffer **buf, asUINT numElements);
-    void DeleteBuffer(SArrayBuffer *buf);
-    void CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src);
-    void Construct(SArrayBuffer *buf, asUINT start, asUINT end);
-    void Destruct(SArrayBuffer *buf, asUINT start, asUINT end);
-    bool Equals(const void *a, const void *b, asIScriptContext *ctx);
+    void  Copy(void *dst, void *src);
+    void  Precache();
+    bool  CheckMaxSize(asUINT numElements);
+    void  Resize(int delta, asUINT at);
+    void  CreateBuffer(SArrayBuffer **buf, asUINT numElements);
+    void  DeleteBuffer(SArrayBuffer *buf);
+    void  CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src);
+    void  Construct(SArrayBuffer *buf, asUINT start, asUINT end);
+    void  Destruct(SArrayBuffer *buf, asUINT start, asUINT end);
+    bool  Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const;
 };
 };
 
 
 /// Register the array type to script.
 /// Register the array type to script.

+ 1 - 1
Readme.txt

@@ -36,7 +36,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org) and Horde3D
   http://timothylottes.blogspot.com/2011/04/nvidia-fxaa-ii-for-console.html
   http://timothylottes.blogspot.com/2011/04/nvidia-fxaa-ii-for-console.html
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
-- AngelScript 2.23.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.24.0a (http://www.angelcode.com/angelscript/)
 - Bullet 2.80 (http://www.bulletphysics.org/)
 - Bullet 2.80 (http://www.bulletphysics.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - GLee 5.4 (http://elf-stone.com/)
 - GLee 5.4 (http://elf-stone.com/)

+ 59 - 17
ThirdParty/AngelScript/include/angelscript.h

@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 
 // AngelScript version
 // AngelScript version
 
 
-#define ANGELSCRIPT_VERSION        22301
-#define ANGELSCRIPT_VERSION_STRING "2.23.1"
+#define ANGELSCRIPT_VERSION        22400
+#define ANGELSCRIPT_VERSION_STRING "2.24.0"
 
 
 // Data types
 // Data types
 
 
@@ -213,7 +213,8 @@ enum asERetCodes
 	asILLEGAL_BEHAVIOUR_FOR_TYPE           = -23,
 	asILLEGAL_BEHAVIOUR_FOR_TYPE           = -23,
 	asWRONG_CALLING_CONV                   = -24,
 	asWRONG_CALLING_CONV                   = -24,
 	asBUILD_IN_PROGRESS                    = -25,
 	asBUILD_IN_PROGRESS                    = -25,
-	asINIT_GLOBAL_VARS_FAILED              = -26
+	asINIT_GLOBAL_VARS_FAILED              = -26,
+	asOUT_OF_MEMORY                        = -27
 };
 };
 
 
 // Context states
 // Context states
@@ -257,8 +258,11 @@ enum asETokenClass
 	asTC_WHITESPACE = 5
 	asTC_WHITESPACE = 5
 };
 };
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // Prepare flags
 // Prepare flags
 const int asPREPARE_PREVIOUS = -1;
 const int asPREPARE_PREVIOUS = -1;
+#endif
 
 
 // Type id flags
 // Type id flags
 enum asETypeIdFlags
 enum asETypeIdFlags
@@ -481,7 +485,13 @@ extern "C"
 	AS_API asIScriptContext * asGetActiveContext();
 	AS_API asIScriptContext * asGetActiveContext();
 
 
 	// Thread support
 	// Thread support
-	AS_API int asThreadCleanup();
+	AS_API void asPrepareMultithread();
+	AS_API void asUnprepareMultithread();
+	AS_API void asAcquireExclusiveLock();
+	AS_API void asReleaseExclusiveLock();
+	AS_API void asAcquireSharedLock();
+	AS_API void asReleaseSharedLock();
+	AS_API int  asThreadCleanup();
 
 
 	// Memory management
 	// Memory management
 	AS_API int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
 	AS_API int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
@@ -514,7 +524,10 @@ public:
 	// Global functions
 	// Global functions
 	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
 	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
 	virtual asUINT             GetGlobalFunctionCount() const = 0;
 	virtual asUINT             GetGlobalFunctionCount() const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const = 0;
+#endif
 	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const = 0;
 	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const = 0;
 
 
@@ -586,7 +599,12 @@ public:
 	virtual asIScriptContext *CreateContext() = 0;
 	virtual asIScriptContext *CreateContext() = 0;
 	virtual void             *CreateScriptObject(int typeId) = 0;
 	virtual void             *CreateScriptObject(int typeId) = 0;
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId) = 0;
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId) = 0;
+	virtual void             *CreateUninitializedScriptObject(int typeId) = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-06-07
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
+#endif
+	virtual void              AssignScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
 	virtual void              ReleaseScriptObject(void *obj, int typeId) = 0;
 	virtual void              ReleaseScriptObject(void *obj, int typeId) = 0;
 	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type) = 0;
 	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type) = 0;
 	virtual void              AddRefScriptObject(void *obj, int typeId) = 0;
 	virtual void              AddRefScriptObject(void *obj, int typeId) = 0;
@@ -603,13 +621,13 @@ public:
 	virtual void GCEnumCallback(void *reference) = 0;
 	virtual void GCEnumCallback(void *reference) = 0;
 
 
 	// User data
 	// User data
-	virtual void *SetUserData(void *data) = 0;
-	virtual void *GetUserData() const = 0;
-	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback) = 0;
+	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  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback) = 0;
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
-	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback) = 0;
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type = 0) = 0;
 
 
 protected:
 protected:
 	virtual ~asIScriptEngine() {}
 	virtual ~asIScriptEngine() {}
@@ -632,13 +650,19 @@ public:
 
 
 	// Functions
 	// Functions
 	virtual asUINT             GetFunctionCount() const = 0;
 	virtual asUINT             GetFunctionCount() const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
+#endif
 	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const = 0;
 	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const = 0;
 	virtual asIScriptFunction *GetFunctionByName(const char *name) const = 0;
 	virtual asIScriptFunction *GetFunctionByName(const char *name) const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                RemoveFunction(int funcId) = 0;
 	virtual int                RemoveFunction(int funcId) = 0;
+#endif
 	virtual int                RemoveFunction(asIScriptFunction *func) = 0;
 	virtual int                RemoveFunction(asIScriptFunction *func) = 0;
 
 
 	// Global variables
 	// Global variables
@@ -654,6 +678,7 @@ public:
 	// Type identification
 	// Type identification
 	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
+	virtual asIObjectType *GetObjectTypeByName(const char *name) const = 0;
 	virtual int            GetTypeIdByDecl(const char *decl) const = 0;
 	virtual int            GetTypeIdByDecl(const char *decl) const = 0;
 
 
 	// Enums
 	// Enums
@@ -671,7 +696,7 @@ public:
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const = 0;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const = 0;
 	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const = 0;
 	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const = 0;
 	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const = 0;
 	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const = 0;
-	virtual int         BindImportedFunction(asUINT importIndex, int funcId) = 0;
+	virtual int         BindImportedFunction(asUINT importIndex, asIScriptFunction *func) = 0;
 	virtual int         UnbindImportedFunction(asUINT importIndex) = 0;
 	virtual int         UnbindImportedFunction(asUINT importIndex) = 0;
 	virtual int         BindAllImportedFunctions() = 0;
 	virtual int         BindAllImportedFunctions() = 0;
 	virtual int         UnbindAllImportedFunctions() = 0;
 	virtual int         UnbindAllImportedFunctions() = 0;
@@ -700,13 +725,21 @@ public:
 
 
 	// Execution
 	// Execution
 	virtual int             Prepare(asIScriptFunction *func) = 0;
 	virtual int             Prepare(asIScriptFunction *func) = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	virtual int             Prepare(int funcId) = 0;
 	virtual int             Prepare(int funcId) = 0;
+#endif
 	virtual int             Unprepare() = 0;
 	virtual int             Unprepare() = 0;
-	virtual int             SetObject(void *obj) = 0;
 	virtual int             Execute() = 0;
 	virtual int             Execute() = 0;
 	virtual int             Abort() = 0;
 	virtual int             Abort() = 0;
 	virtual int             Suspend() = 0;
 	virtual int             Suspend() = 0;
 	virtual asEContextState GetState() const = 0;
 	virtual asEContextState GetState() const = 0;
+	virtual int             PushState() = 0;
+	virtual int             PopState() = 0;
+	virtual bool            IsNested(asUINT *nestCount = 0) const = 0;
+
+	// Object pointer for calling class methods
+	virtual int   SetObject(void *obj) = 0;
 
 
 	// Arguments
 	// Arguments
 	virtual int   SetArgByte(asUINT arg, asBYTE value) = 0;
 	virtual int   SetArgByte(asUINT arg, asBYTE value) = 0;
@@ -741,7 +774,7 @@ public:
 	// Debugging
 	// Debugging
 	virtual int                SetLineCallback(asSFuncPtr callback, void *obj, int callConv) = 0;
 	virtual int                SetLineCallback(asSFuncPtr callback, void *obj, int callConv) = 0;
 	virtual void               ClearLineCallback() = 0;
 	virtual void               ClearLineCallback() = 0;
-	virtual asUINT             GetCallstackSize() = 0;
+	virtual asUINT             GetCallstackSize() const = 0;
 	virtual asIScriptFunction *GetFunction(asUINT stackLevel = 0) = 0;
 	virtual asIScriptFunction *GetFunction(asUINT stackLevel = 0) = 0;
 	virtual int                GetLineNumber(asUINT stackLevel = 0, int *column = 0, const char **sectionName = 0) = 0;
 	virtual int                GetLineNumber(asUINT stackLevel = 0, int *column = 0, const char **sectionName = 0) = 0;
 	virtual int                GetVarCount(asUINT stackLevel = 0) = 0;
 	virtual int                GetVarCount(asUINT stackLevel = 0) = 0;
@@ -767,9 +800,12 @@ class asIScriptGeneric
 public:
 public:
 	// Miscellaneous
 	// Miscellaneous
 	virtual asIScriptEngine   *GetEngine() const = 0;
 	virtual asIScriptEngine   *GetEngine() const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	virtual int                GetFunctionId() const = 0;
 	virtual int                GetFunctionId() const = 0;
-	virtual asIScriptFunction *GetFunction() const = 0;
 	virtual void              *GetFunctionUserData() const = 0;
 	virtual void              *GetFunctionUserData() const = 0;
+#endif
+	virtual asIScriptFunction *GetFunction() const = 0;
 
 
 	// Object
 	// Object
 	virtual void   *GetObject() = 0;
 	virtual void   *GetObject() = 0;
@@ -861,16 +897,22 @@ public:
 
 
 	// Factories
 	// Factories
 	virtual asUINT             GetFactoryCount() const = 0;
 	virtual asUINT             GetFactoryCount() const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	virtual int                GetFactoryIdByIndex(asUINT index) const = 0;
 	virtual int                GetFactoryIdByIndex(asUINT index) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
+#endif
 	virtual asIScriptFunction *GetFactoryByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFactoryByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFactoryByDecl(const char *decl) const = 0;
 	virtual asIScriptFunction *GetFactoryByDecl(const char *decl) const = 0;
 
 
 	// Methods
 	// Methods
 	virtual asUINT             GetMethodCount() const = 0;
 	virtual asUINT             GetMethodCount() const = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
+#endif
 	virtual asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodByName(const char *name, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodByName(const char *name, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual = true) const = 0;
@@ -881,12 +923,12 @@ public:
 	virtual const char *GetPropertyDeclaration(asUINT index) const = 0;
 	virtual const char *GetPropertyDeclaration(asUINT index) const = 0;
 
 
 	// Behaviours
 	// Behaviours
-	virtual asUINT GetBehaviourCount() const = 0;
-	virtual int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
+	virtual asUINT             GetBehaviourCount() const = 0;
+	virtual asIScriptFunction *GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
 
 
 	// User data
 	// 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:
 protected:
 	virtual ~asIObjectType() {}
 	virtual ~asIObjectType() {}
@@ -1429,7 +1471,7 @@ struct asSBCInfo
 #endif
 #endif
 
 
 #define asBCINFO(b,t,s) {asBC_##b, asBCTYPE_##t, s, #b}
 #define asBCINFO(b,t,s) {asBC_##b, asBCTYPE_##t, s, #b}
-#define asBCINFO_DUMMY(b) {asEBCInstr(b), asBCTYPE_INFO, 0, "BC_" #b}
+#define asBCINFO_DUMMY(b) {asBC_MAXBYTECODE, asBCTYPE_INFO, 0, "BC_" #b}
 
 
 const asSBCInfo asBCInfo[256] =
 const asSBCInfo asBCInfo[256] =
 {
 {

+ 48 - 0
ThirdParty/AngelScript/source/as_array.h

@@ -67,6 +67,7 @@ public:
 	const T &operator [](size_t index) const;
 	const T &operator [](size_t index) const;
 	T &operator [](size_t index);
 	T &operator [](size_t index);
 	T *AddressOf();
 	T *AddressOf();
+	const T *AddressOf() const;
 
 
 	void Concatenate(const asCArray<T> &);
 	void Concatenate(const asCArray<T> &);
 	void Concatenate(T*, unsigned int count);
 	void Concatenate(T*, unsigned int count);
@@ -94,6 +95,12 @@ T *asCArray<T>::AddressOf()
 	return array;
 	return array;
 }
 }
 
 
+template <class T>
+const T *asCArray<T>::AddressOf() const
+{
+	return array;
+}
+
 template <class T>
 template <class T>
 asCArray<T>::asCArray(void)
 asCArray<T>::asCArray(void)
 {
 {
@@ -160,6 +167,12 @@ void asCArray<T>::PushLast(const T &element)
 			Allocate(1, false);
 			Allocate(1, false);
 		else
 		else
 			Allocate(2*maxLength, true);
 			Allocate(2*maxLength, true);
+
+		if( length == maxLength )
+		{
+			// Out of memory. Return without doing anything
+			return;
+		}
 	}
 	}
 
 
 	array[length++] = element;
 	array[length++] = element;
@@ -189,8 +202,15 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 			// Use the internal buffer
 			// Use the internal buffer
 			tmp = (T*)buf;
 			tmp = (T*)buf;
 		else
 		else
+		{
 			// Allocate the array and construct each of the elements
 			// Allocate the array and construct each of the elements
 			tmp = asNEWARRAY(T,numElements);
 			tmp = asNEWARRAY(T,numElements);
+			if( tmp == 0 )
+			{
+				// Out of memory. Return without doing anything
+				return;
+			}
+		}
 
 
 		if( array == tmp )
 		if( array == tmp )
 		{
 		{
@@ -266,8 +286,15 @@ void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
 			// Use the internal buffer
 			// Use the internal buffer
 			tmp = (T*)buf;
 			tmp = (T*)buf;
 		else
 		else
+		{
 			// Allocate the array and construct each of the elements
 			// Allocate the array and construct each of the elements
 			tmp = asNEWARRAY(T,numElements);
 			tmp = asNEWARRAY(T,numElements);
+			if( tmp == 0 )
+			{
+				// Out of memory. Return without doing anything
+				return;
+			}
+		}
 	}
 	}
 
 
 	if( array )
 	if( array )
@@ -313,7 +340,14 @@ template <class T>
 void asCArray<T>::SetLength(size_t numElements)
 void asCArray<T>::SetLength(size_t numElements)
 {
 {
 	if( numElements > maxLength )
 	if( numElements > maxLength )
+	{
 		Allocate(numElements, true);
 		Allocate(numElements, true);
+		if( numElements > maxLength )
+		{
+			// Out of memory. Return without doing anything
+			return;
+		}
+	}
 
 
 	length = numElements;
 	length = numElements;
 }
 }
@@ -322,7 +356,14 @@ template <class T>
 void asCArray<T>::SetLengthNoConstruct(size_t numElements)
 void asCArray<T>::SetLengthNoConstruct(size_t numElements)
 {
 {
 	if( numElements > maxLength )
 	if( numElements > maxLength )
+	{
 		AllocateNoConstruct(numElements, true);
 		AllocateNoConstruct(numElements, true);
+		if( numElements > maxLength )
+		{
+			// Out of memory. Return without doing anything
+			return;
+		}
+	}
 
 
 	length = numElements;
 	length = numElements;
 }
 }
@@ -331,7 +372,14 @@ template <class T>
 void asCArray<T>::Copy(const T *data, size_t count)
 void asCArray<T>::Copy(const T *data, size_t count)
 {
 {
 	if( maxLength < count )
 	if( maxLength < count )
+	{
 		Allocate(count, false);
 		Allocate(count, false);
+		if( maxLength < count )
+		{
+			// Out of memory. Return without doing anything
+			return;
+		}
+	}
 
 
 	for( size_t n = 0; n < count; n++ )
 	for( size_t n = 0; n < count; n++ )
 		array[n] = data[n];
 		array[n] = data[n];

+ 1 - 3
ThirdParty/AngelScript/source/as_atomic.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2011 Andreas Jonsson
+   Copyright (c) 2003-2012 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -27,8 +27,6 @@
    Andreas Jonsson
    Andreas Jonsson
    [email protected]
    [email protected]
 */
 */
-
-// Modified by Lasse Öörni for Urho3D
  
  
 //
 //
 // as_gc.cpp
 // as_gc.cpp

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

@@ -176,6 +176,9 @@ void asCBuilder::Reset()
 int asCBuilder::AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy)
 int asCBuilder::AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy)
 {
 {
 	asCScriptCode *script = asNEW(asCScriptCode);
 	asCScriptCode *script = asNEW(asCScriptCode);
+	if( script == 0 )
+		return asOUT_OF_MEMORY;
+
 	int r = script->SetCode(name, code, codeLength, makeCopy);
 	int r = script->SetCode(name, code, codeLength, makeCopy);
 	script->lineOffset = lineOffset;
 	script->lineOffset = lineOffset;
 	script->idx = sectionIdx;
 	script->idx = sectionIdx;
@@ -211,6 +214,9 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
 
 
 	// Add the string to the script code
 	// Add the string to the script code
 	asCScriptCode *script = asNEW(asCScriptCode);
 	asCScriptCode *script = asNEW(asCScriptCode);
+	if( script == 0 )
+		return asOUT_OF_MEMORY;
+
 	script->SetCode(sectionName, code, true);
 	script->SetCode(sectionName, code, true);
 	script->lineOffset = lineOffset;
 	script->lineOffset = lineOffset;
 	scripts.PushLast(script);
 	scripts.PushLast(script);
@@ -287,6 +293,9 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 
 
 	// Add the string to the script code
 	// Add the string to the script code
 	asCScriptCode *script = asNEW(asCScriptCode);
 	asCScriptCode *script = asNEW(asCScriptCode);
+	if( script == 0 )
+		return asOUT_OF_MEMORY;
+
 	script->SetCode(sectionName, code, true);
 	script->SetCode(sectionName, code, true);
 	script->lineOffset = lineOffset; 
 	script->lineOffset = lineOffset; 
 	scripts.PushLast(script);
 	scripts.PushLast(script);
@@ -317,6 +326,9 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	// Create the function
 	// Create the function
 	bool isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared;
 	bool isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared;
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_SCRIPT);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_SCRIPT);
+	if( func == 0 )
+		return asOUT_OF_MEMORY;
+
 	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterTypes, func->inOutFlags, func->defaultArgs, func->isReadOnly, isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared);
 	GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterTypes, func->inOutFlags, func->defaultArgs, func->isReadOnly, isConstructor, isDestructor, isPrivate, isFinal, isOverride, isShared);
 	func->id               = engine->GetNextScriptFunctionId();
 	func->id               = engine->GetNextScriptFunctionId();
 	func->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
 	func->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
@@ -349,6 +361,12 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
 	// Fill in the function info for the builder too
 	// Fill in the function info for the builder too
 	node->DisconnectParent();
 	node->DisconnectParent();
 	sFunctionDescription *funcDesc = asNEW(sFunctionDescription);
 	sFunctionDescription *funcDesc = asNEW(sFunctionDescription);
+	if( funcDesc == 0 )
+	{
+		func->Release();
+		return asOUT_OF_MEMORY;
+	}
+
 	functions.PushLast(funcDesc);
 	functions.PushLast(funcDesc);
 	funcDesc->script            = scripts[0];
 	funcDesc->script            = scripts[0];
 	funcDesc->node              = node;
 	funcDesc->node              = node;
@@ -390,10 +408,13 @@ void asCBuilder::ParseScripts()
 	for( n = 0; n < scripts.GetLength(); n++ )
 	for( n = 0; n < scripts.GetLength(); n++ )
 	{
 	{
 		asCParser *parser = asNEW(asCParser)(this);
 		asCParser *parser = asNEW(asCParser)(this);
-		parsers.PushLast(parser);
+		if( parser != 0 )
+		{
+			parsers.PushLast(parser);
 
 
-		// Parse the script file
-		parser->ParseScript(scripts[n]);
+			// Parse the script file
+			parser->ParseScript(scripts[n]);
+		}
 	}
 	}
 
 
 	if( numErrors == 0 )
 	if( numErrors == 0 )
@@ -976,8 +997,11 @@ int asCBuilder::ParseFunctionDeclaration(asCObjectType *objType, const char *dec
 		{
 		{
 			// Strip out white space and comments to better share the string
 			// Strip out white space and comments to better share the string
 			asCString *defaultArgStr = asNEW(asCString);
 			asCString *defaultArgStr = asNEW(asCString);
-			*defaultArgStr = GetCleanExpressionString(n, &source);
-			func->defaultArgs.PushLast(defaultArgStr);
+			if( defaultArgStr )
+			{
+				*defaultArgStr = GetCleanExpressionString(n, &source);
+				func->defaultArgs.PushLast(defaultArgStr);
+			}
 
 
 			n = n->next;
 			n = n->next;
 		}
 		}
@@ -1094,8 +1118,7 @@ int asCBuilder::CheckNameConflictMember(asCObjectType *t, const char *name, asCS
 int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, const asCString &ns)
 int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, const asCString &ns)
 {
 {
 	// Check against registered object types
 	// Check against registered object types
-	// TODO: namespace: Check in correct namespace
-	if( engine->GetObjectType(name) != 0 )
+	if( engine->GetObjectType(name, ns) != 0 )
 	{
 	{
 		if( code )
 		if( code )
 		{
 		{
@@ -1216,6 +1239,12 @@ int asCBuilder::RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, const
 	// necessary after all type declarations have been identified.
 	// necessary after all type declarations have been identified.
 
 
 	sFuncDef *fd = asNEW(sFuncDef);
 	sFuncDef *fd = asNEW(sFuncDef);
+	if( fd == 0 )
+	{
+		node->Destroy(engine);
+		return asOUT_OF_MEMORY;
+	}
+
 	fd->name   = name;
 	fd->name   = name;
 	fd->node   = node;
 	fd->node   = node;
 	fd->script = file;
 	fd->script = file;
@@ -1292,6 +1321,12 @@ int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, cons
 
 
 		// Register the global variable
 		// Register the global variable
 		sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
 		sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
+		if( gvar == 0 )
+		{
+			node->Destroy(engine);
+			return asOUT_OF_MEMORY;
+		}
+			
 		globVariables.PushLast(gvar);
 		globVariables.PushLast(gvar);
 
 
 		gvar->script      = file;
 		gvar->script      = file;
@@ -1358,6 +1393,9 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, const as
 	CheckNameConflict(name.AddressOf(), n, file, ns);
 	CheckNameConflict(name.AddressOf(), n, file, ns);
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
+	if( decl == 0 )
+		return asOUT_OF_MEMORY;
+
 	classDeclarations.PushLast(decl);
 	classDeclarations.PushLast(decl);
 	decl->name             = name;
 	decl->name             = name;
 	decl->script           = file;
 	decl->script           = file;
@@ -1389,6 +1427,9 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, const as
 
 
 	// Create a new object type for this class
 	// Create a new object type for this class
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	asCObjectType *st = asNEW(asCObjectType)(engine);
+	if( st == 0 )
+		return asOUT_OF_MEMORY;
+	
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 
 
 	if( isShared )
 	if( isShared )
@@ -1452,6 +1493,9 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, cons
 	CheckNameConflict(name.AddressOf(), n, file, ns);
 	CheckNameConflict(name.AddressOf(), n, file, ns);
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
+	if( decl == 0 )
+		return asOUT_OF_MEMORY;
+
 	interfaceDeclarations.PushLast(decl);
 	interfaceDeclarations.PushLast(decl);
 	decl->name             = name;
 	decl->name             = name;
 	decl->script           = file;
 	decl->script           = file;
@@ -1483,6 +1527,9 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, cons
 
 
 	// Register the object type for the interface
 	// Register the object type for the interface
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	asCObjectType *st = asNEW(asCObjectType)(engine);
+	if( st == 0 )
+		return asOUT_OF_MEMORY;
+
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 
 
 	if( isShared )
 	if( isShared )
@@ -1512,7 +1559,7 @@ void asCBuilder::CompileGlobalVariables()
 	bool compileSucceeded = true;
 	bool compileSucceeded = true;
 
 
 	// Store state of compilation (errors, warning, output)
 	// Store state of compilation (errors, warning, output)
-	int currNumErrors = numErrors;
+	int currNumErrors   = numErrors;
 	int currNumWarnings = numWarnings;
 	int currNumWarnings = numWarnings;
 
 
 	// Backup the original message stream
 	// Backup the original message stream
@@ -1634,6 +1681,12 @@ void asCBuilder::CompileGlobalVariables()
 			{
 			{
 				// Compile the global variable
 				// Compile the global variable
 				initFunc = asNEW(asCScriptFunction)(engine, module, asFUNC_DUMMY);
 				initFunc = asNEW(asCScriptFunction)(engine, module, asFUNC_DUMMY);
+				if( initFunc == 0 )
+				{
+					// Out of memory
+					return;
+				}
+
 				asCCompiler comp(engine);
 				asCCompiler comp(engine);
 				int r = comp.CompileGlobalVariable(this, gvar->script, gvar->nextNode, gvar, initFunc);
 				int r = comp.CompileGlobalVariable(this, gvar->script, gvar->nextNode, gvar, initFunc);
 				if( r >= 0 )
 				if( r >= 0 )
@@ -1698,6 +1751,13 @@ void asCBuilder::CompileGlobalVariables()
 					asASSERT(NULL != objectType);
 					asASSERT(NULL != objectType);
 
 
 					asSEnumValue *e = asNEW(asSEnumValue);
 					asSEnumValue *e = asNEW(asSEnumValue);
+					if( e == 0 )
+					{
+						// Out of memory
+						numErrors++;
+						return;
+					}
+
 					e->name = gvar->name;
 					e->name = gvar->name;
 					e->value = *(int*)&gvar->constantValue;
 					e->value = *(int*)&gvar->constantValue;
 
 
@@ -2323,7 +2383,9 @@ void asCBuilder::CompileClasses()
 
 
 int asCBuilder::CreateVirtualFunction(asCScriptFunction *func, int idx)
 int asCBuilder::CreateVirtualFunction(asCScriptFunction *func, int idx)
 {
 {
-	asCScriptFunction *vf =  asNEW(asCScriptFunction)(engine, module, asFUNC_VIRTUAL);
+	asCScriptFunction *vf = asNEW(asCScriptFunction)(engine, module, asFUNC_VIRTUAL);
+	if( vf == 0 )
+		return asOUT_OF_MEMORY;
 
 
 	vf->funcType         = asFUNC_VIRTUAL;
 	vf->funcType         = asFUNC_VIRTUAL;
 	vf->name             = func->name;
 	vf->name             = func->name;
@@ -2417,6 +2479,12 @@ void asCBuilder::AddDefaultConstructor(asCObjectType *objType, asCScriptCode *fi
 	// The bytecode for the default constructor will be generated
 	// The bytecode for the default constructor will be generated
 	// only after the potential inheritance has been established
 	// only after the potential inheritance has been established
 	sFunctionDescription *func = asNEW(sFunctionDescription);
 	sFunctionDescription *func = asNEW(sFunctionDescription);
+	if( func == 0 )
+	{
+		// Out of memory
+		return;
+	}
+
 	functions.PushLast(func);
 	functions.PushLast(func);
 
 
 	func->script            = file;
 	func->script            = file;
@@ -2491,6 +2559,8 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, const asC
 		else
 		else
 		{
 		{
 			st = asNEW(asCObjectType)(engine);
 			st = asNEW(asCObjectType)(engine);
+			if( st == 0 )
+				return asOUT_OF_MEMORY;
 
 
 			st->flags     = asOBJ_ENUM;
 			st->flags     = asOBJ_ENUM;
 			if( isShared )
 			if( isShared )
@@ -2509,6 +2579,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, const asC
 
 
 		// Store the location of this declaration for reference in name collisions
 		// Store the location of this declaration for reference in name collisions
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
+		if( decl == 0 )
+			return asOUT_OF_MEMORY;
+
 		decl->name             = name;
 		decl->name             = name;
 		decl->script           = file;
 		decl->script           = file;
 		decl->objType          = st;
 		decl->objType          = st;
@@ -2591,6 +2664,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, const asC
 
 
 				// Create the global variable description so the enum value can be evaluated
 				// Create the global variable description so the enum value can be evaluated
 				sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
 				sGlobalVariableDescription *gvar = asNEW(sGlobalVariableDescription);
+				if( gvar == 0 )
+					return asOUT_OF_MEMORY;
+
 				globVariables.PushLast(gvar);
 				globVariables.PushLast(gvar);
 
 
 				gvar->script		  = file;
 				gvar->script		  = file;
@@ -2608,6 +2684,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, const asC
 				// Allocate dummy property so we can compile the value. 
 				// Allocate dummy property so we can compile the value. 
 				// This will be removed later on so we don't add it to the engine.
 				// This will be removed later on so we don't add it to the engine.
 				gvar->property            = asNEW(asCGlobalProperty);
 				gvar->property            = asNEW(asCGlobalProperty);
+				if( gvar->property == 0 )
+					return asOUT_OF_MEMORY;
+
 				gvar->property->name      = name;
 				gvar->property->name      = name;
 				gvar->property->nameSpace = ns;
 				gvar->property->nameSpace = ns;
 				gvar->property->type      = gvar->datatype;
 				gvar->property->type      = gvar->datatype;
@@ -2640,11 +2719,18 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file, const
 
 
 	// If the name is not already in use add it
 	// If the name is not already in use add it
  	int r = CheckNameConflict(name.AddressOf(), tmp, file, ns);
  	int r = CheckNameConflict(name.AddressOf(), tmp, file, ns);
+
+	asCObjectType *st = 0;
 	if( asSUCCESS == r )
 	if( asSUCCESS == r )
 	{
 	{
 		// Create the new type
 		// Create the new type
-		asCObjectType *st = asNEW(asCObjectType)(engine);
+		st = asNEW(asCObjectType)(engine);
+		if( st == 0 )
+			r = asOUT_OF_MEMORY;
+	}
 
 
+	if( asSUCCESS == r )
+	{
 		st->flags           = asOBJ_TYPEDEF;
 		st->flags           = asOBJ_TYPEDEF;
 		st->size            = dataType.GetSizeInMemoryBytes();
 		st->size            = dataType.GetSizeInMemoryBytes();
 		st->name            = name;
 		st->name            = name;
@@ -2658,10 +2744,15 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file, const
 
 
 		// Store the location of this declaration for reference in name collisions
 		// Store the location of this declaration for reference in name collisions
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
-		decl->name             = name;
-		decl->script           = file;
-		decl->objType          = st;
-		namedTypeDeclarations.PushLast(decl);
+		if( decl == 0 )
+			r = asOUT_OF_MEMORY;
+		else
+		{
+			decl->name             = name;
+			decl->script           = file;
+			decl->objType          = st;
+			namedTypeDeclarations.PushLast(decl);
+		}
 	}
 	}
 
 
 	node->Destroy(engine);
 	node->Destroy(engine);
@@ -2785,7 +2876,8 @@ void asCBuilder::GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *fi
 		{
 		{
 			// Strip out white space and comments to better share the string
 			// Strip out white space and comments to better share the string
 			asCString *defaultArgStr = asNEW(asCString);
 			asCString *defaultArgStr = asNEW(asCString);
-			*defaultArgStr = GetCleanExpressionString(n, file);
+			if( defaultArgStr )
+				*defaultArgStr = GetCleanExpressionString(n, file);
 			defaultArgs.PushLast(defaultArgStr);
 			defaultArgs.PushLast(defaultArgStr);
 
 
 			n = n->next;
 			n = n->next;
@@ -2910,6 +3002,9 @@ int asCBuilder::RegisterScriptFunction(int funcId, asCScriptNode *node, asCScrip
 	if( !isInterface )
 	if( !isInterface )
 	{
 	{
 		sFunctionDescription *func = asNEW(sFunctionDescription);
 		sFunctionDescription *func = asNEW(sFunctionDescription);
+		if( func == 0 )
+			return asOUT_OF_MEMORY;
+
 		functions.PushLast(func);
 		functions.PushLast(func);
 
 
 		func->script            = file;
 		func->script            = file;
@@ -3105,6 +3200,9 @@ int asCBuilder::RegisterScriptFunctionWithSignature(int funcId, asCScriptNode *n
 	else
 	else
 	{
 	{
 		sFunctionDescription *func = asNEW(sFunctionDescription);
 		sFunctionDescription *func = asNEW(sFunctionDescription);
+		if( func == 0 )
+			return asOUT_OF_MEMORY;
+
 		functions.PushLast(func);
 		functions.PushLast(func);
 
 
 		func->script            = file;
 		func->script            = file;
@@ -3343,6 +3441,8 @@ int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file
 			}
 			}
 
 
 			signature = asNEW(sExplicitSignature);
 			signature = asNEW(sExplicitSignature);
+			if( signature == 0 )
+				return asOUT_OF_MEMORY;
 			
 			
 			signature->returnType = emulatedType;
 			signature->returnType = emulatedType;
 
 
@@ -3381,6 +3481,8 @@ int asCBuilder::RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file
 			}
 			}
 
 
 			signature = asNEW(sExplicitSignature)(1);
 			signature = asNEW(sExplicitSignature)(1);
+			if( signature == 0 )
+				return asOUT_OF_MEMORY;
 
 
 			signature->returnType = asCDataType::CreatePrimitive(ttVoid, false);
 			signature->returnType = asCDataType::CreatePrimitive(ttVoid, false);
 
 
@@ -3947,14 +4049,54 @@ asCDataType asCBuilder::ModifyDataTypeFromNode(const asCDataType &type, asCScrip
 
 
 asCObjectType *asCBuilder::GetObjectType(const char *type, const asCString &ns)
 asCObjectType *asCBuilder::GetObjectType(const char *type, const asCString &ns)
 {
 {
-	// TODO: namespace: Registered types should also allow namespaces
-	asCObjectType *ot = engine->GetObjectType(type);
+	asCObjectType *ot = engine->GetObjectType(type, ns);
 	if( !ot && module )
 	if( !ot && module )
 		ot = module->GetObjectType(type, ns);
 		ot = module->GetObjectType(type, ns);
 
 
 	return ot;
 	return ot;
 }
 }
 
 
+// This function will return true if there are any types in the engine or module 
+// with the given name. The namespace is ignored in this verification.
+bool asCBuilder::DoesTypeExist(const char *type)
+{
+	asUINT n;
+
+	// TODO: optimize: Improve linear searches
+
+	// Check if it is a registered type
+	for( n = 0; n < engine->objectTypes.GetLength(); n++ )
+		if( engine->objectTypes[n] &&
+			engine->objectTypes[n]->name == type ) // TODO: template: Should we check the subtype in case of template instances?
+			return true;
+
+	for( n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
+		if( engine->registeredFuncDefs[n]->name == type )
+			return true;
+
+	// Check if it is a script type
+	if( module )
+	{
+		for( n = 0; n < module->classTypes.GetLength(); n++ )
+			if( module->classTypes[n]->name == type )
+				return true;
+
+		for( n = 0; n < module->enumTypes.GetLength(); n++ )
+			if( module->enumTypes[n]->name == type )
+				return true;
+
+		for( n = 0; n < module->typeDefs.GetLength(); n++ )
+			if( module->typeDefs[n]->name == type )
+				return true;
+
+		for( asUINT n = 0; n < module->funcDefs.GetLength(); n++ )
+			if( module->funcDefs[n]->name == type )
+				return true;
+	}
+
+	return false;
+}
+
 asCObjectType *asCBuilder::GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType)
 asCObjectType *asCBuilder::GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType)
 {
 {
 	if( currentType->name == type )
 	if( currentType->name == type )
@@ -3986,23 +4128,15 @@ asCObjectType *asCBuilder::GetObjectTypeFromTypesKnownByObject(const char *type,
 asCScriptFunction *asCBuilder::GetFuncDef(const char *type)
 asCScriptFunction *asCBuilder::GetFuncDef(const char *type)
 {
 {
 	for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 	for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
-	{
 		// TODO: access: Only return the definitions that the module has access to
 		// TODO: access: Only return the definitions that the module has access to
 		if( engine->registeredFuncDefs[n]->name == type )
 		if( engine->registeredFuncDefs[n]->name == type )
-		{
 			return engine->registeredFuncDefs[n];
 			return engine->registeredFuncDefs[n];
-		}
-	}
 
 
 	if( module )
 	if( module )
 	{
 	{
 		for( asUINT n = 0; n < module->funcDefs.GetLength(); n++ )
 		for( asUINT n = 0; n < module->funcDefs.GetLength(); n++ )
-		{
 			if( module->funcDefs[n]->name == type )
 			if( module->funcDefs[n]->name == type )
-			{
 				return module->funcDefs[n];
 				return module->funcDefs[n];
-			}
-		}
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 1 - 0
ThirdParty/AngelScript/source/as_builder.h

@@ -157,6 +157,7 @@ protected:
 
 
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 
 
+	bool               DoesTypeExist(const char *type);
 	asCObjectType     *GetObjectType(const char *type, const asCString &ns);
 	asCObjectType     *GetObjectType(const char *type, const asCString &ns);
 	asCScriptFunction *GetFuncDef(const char *type);
 	asCScriptFunction *GetFuncDef(const char *type);
 	asCObjectType     *GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);
 	asCObjectType     *GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);

+ 16 - 2
ThirdParty/AngelScript/source/as_bytecode.cpp

@@ -1298,7 +1298,14 @@ void asCByteCode::AddCode(asCByteCode *bc)
 
 
 int asCByteCode::AddInstruction()
 int asCByteCode::AddInstruction()
 {
 {
-	cByteInstruction *instr = new(engine->memoryMgr.AllocByteInstruction()) cByteInstruction();
+	void *ptr = engine->memoryMgr.AllocByteInstruction();
+	if( ptr == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
+	cByteInstruction *instr = new(ptr) cByteInstruction();
 	if( first == 0 )
 	if( first == 0 )
 	{
 	{
 		first = last = instr;
 		first = last = instr;
@@ -1314,7 +1321,14 @@ int asCByteCode::AddInstruction()
 
 
 int asCByteCode::AddInstructionFirst()
 int asCByteCode::AddInstructionFirst()
 {
 {
-	cByteInstruction *instr = new(engine->memoryMgr.AllocByteInstruction()) cByteInstruction();
+	void *ptr = engine->memoryMgr.AllocByteInstruction();
+	if( ptr == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
+	cByteInstruction *instr = new(ptr) cByteInstruction();
 	if( first == 0 )
 	if( first == 0 )
 	{
 	{
 		first = last = instr;
 		first = last = instr;

+ 33 - 27
ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -354,7 +354,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 
 
 int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 	int callConv = sysFunc->callConv;
 	if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
 	if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
@@ -392,7 +392,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 
 int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 {
 {
-	asCScriptEngine            *engine  = context->engine;
+	asCScriptEngine            *engine  = context->m_engine;
 	asCScriptFunction          *descr   = engine->scriptFunctions[id];
 	asCScriptFunction          *descr   = engine->scriptFunctions[id];
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 
 
@@ -402,7 +402,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 
 
 	asQWORD  retQW             = 0;
 	asQWORD  retQW             = 0;
 	asQWORD  retQW2            = 0;
 	asQWORD  retQW2            = 0;
-	asDWORD *args              = context->regs.stackPointer;
+	asDWORD *args              = context->m_regs.stackPointer;
 	void    *retPointer        = 0;
 	void    *retPointer        = 0;
 	void    *obj               = 0;
 	void    *obj               = 0;
 	int      popSize           = sysFunc->paramSize;
 	int      popSize           = sysFunc->paramSize;
@@ -442,32 +442,38 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			args += AS_PTR_SIZE;
 			args += AS_PTR_SIZE;
 		}
 		}
 	}
 	}
-
-	context->regs.objectType = descr->returnType.GetObjectType();
-	if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
+	
+	if( descr->DoesReturnOnStack() )
 	{
 	{
 		// Get the address of the location for the return value from the stack
 		// Get the address of the location for the return value from the stack
 		retPointer = (void*)*(asPWORD*)(args);
 		retPointer = (void*)*(asPWORD*)(args);
 		popSize += AS_PTR_SIZE;
 		popSize += AS_PTR_SIZE;
 		args += AS_PTR_SIZE;
 		args += AS_PTR_SIZE;
 
 
-		// When returning the value on the location allocated by the called we shouldn't set the object type in the register
-		context->regs.objectType = 0;
+		// When returning the value on the location allocated by the called 
+		// we shouldn't set the object type in the register
+		context->m_regs.objectType = 0;
+	}
+	else
+	{
+		// Set the object type of the reference held in the register
+		context->m_regs.objectType = descr->returnType.GetObjectType();
 	}
 	}
 
 
-
-	context->callingSystemFunction = descr;
+	context->m_callingSystemFunction = descr;
 	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
 	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
-	context->callingSystemFunction = 0;
+	context->m_callingSystemFunction = 0;
 
 
 #if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
 #if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
 	if( sysFunc->takesObjByVal )
 	if( sysFunc->takesObjByVal )
 	{
 	{
 		// Need to free the complex objects passed by value, but that the 
 		// Need to free the complex objects passed by value, but that the 
-		// calling convention implicitly passes by reference behind the scene
-		args = context->regs.stackPointer;
-		if( callConv >= ICC_THISCALL && !objectPointer )
-			args += AS_PTR_SIZE;
+		// calling convention implicitly passes by reference behind the scene as the 
+		// calling function is the owner of that memory.
+
+		// args is pointing to the first real argument as used in CallSystemFunctionNative,
+		// i.e. hidden arguments such as the object pointer and return address have already 
+		// been skipped.
 
 
 		int spos = 0;
 		int spos = 0;
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
@@ -514,12 +520,12 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			retQW >>= 32;
 			retQW >>= 32;
 #endif
 #endif
 
 
-			context->regs.objectRegister = (void*)(asPWORD)retQW;
+			context->m_regs.objectRegister = (void*)(asPWORD)retQW;
 
 
-			if( sysFunc->returnAutoHandle && context->regs.objectRegister )
+			if( sysFunc->returnAutoHandle && context->m_regs.objectRegister )
 			{
 			{
 				asASSERT( !(descr->returnType.GetObjectType()->flags & asOBJ_NOCOUNT) );
 				asASSERT( !(descr->returnType.GetObjectType()->flags & asOBJ_NOCOUNT) );
-				engine->CallObjectMethod(context->regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
+				engine->CallObjectMethod(context->m_regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
 			}
 			}
 		}
 		}
 		else
 		else
@@ -552,14 +558,14 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			}
 			}
 
 
 			// Store the object in the register
 			// Store the object in the register
-			context->regs.objectRegister = retPointer;
+			context->m_regs.objectRegister = retPointer;
 
 
 			// If the value is returned on the stack we shouldn't update the object register
 			// If the value is returned on the stack we shouldn't update the object register
 			if( descr->DoesReturnOnStack() )
 			if( descr->DoesReturnOnStack() )
 			{
 			{
-				context->regs.objectRegister = 0;
+				context->m_regs.objectRegister = 0;
 
 
-				if( context->status == asEXECUTION_EXCEPTION )
+				if( context->m_status == asEXECUTION_EXCEPTION )
 				{
 				{
 					// If the function raised a script exception it really shouldn't have 
 					// If the function raised a script exception it really shouldn't have 
 					// initialized the object. However, as it is a soft exception there is 
 					// initialized the object. However, as it is a soft exception there is 
@@ -590,7 +596,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			case 1:
 			case 1:
 				{
 				{
 					// 8 bits
 					// 8 bits
-					asBYTE *val = (asBYTE*)&context->regs.valueRegister;
+					asBYTE *val = (asBYTE*)&context->m_regs.valueRegister;
 					val[0] = (asBYTE)retQW;
 					val[0] = (asBYTE)retQW;
 					val[1] = 0;
 					val[1] = 0;
 					val[2] = 0;
 					val[2] = 0;
@@ -604,7 +610,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			case 2:
 			case 2:
 				{
 				{
 					// 16 bits
 					// 16 bits
-					asWORD *val = (asWORD*)&context->regs.valueRegister;
+					asWORD *val = (asWORD*)&context->m_regs.valueRegister;
 					val[0] = (asWORD)retQW;
 					val[0] = (asWORD)retQW;
 					val[1] = 0;
 					val[1] = 0;
 					val[2] = 0;
 					val[2] = 0;
@@ -614,24 +620,24 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			default:
 			default:
 				{
 				{
 					// 32 bits
 					// 32 bits
-					asDWORD *val = (asDWORD*)&context->regs.valueRegister;
+					asDWORD *val = (asDWORD*)&context->m_regs.valueRegister;
 					val[0] = (asDWORD)retQW;
 					val[0] = (asDWORD)retQW;
 					val[1] = 0;
 					val[1] = 0;
 				}
 				}
 				break;
 				break;
 			}
 			}
 #else
 #else
-			*(asDWORD*)&context->regs.valueRegister = (asDWORD)retQW;
+			*(asDWORD*)&context->m_regs.valueRegister = (asDWORD)retQW;
 #endif
 #endif
 		}
 		}
 		else
 		else
-			context->regs.valueRegister = retQW;
+			context->m_regs.valueRegister = retQW;
 	}
 	}
 
 
 	// Release autohandles in the arguments
 	// Release autohandles in the arguments
 	if( sysFunc->hasAutoHandles )
 	if( sysFunc->hasAutoHandles )
 	{
 	{
-		args = context->regs.stackPointer;
+		args = context->m_regs.stackPointer;
 		if( callConv >= ICC_THISCALL && !objectPointer )
 		if( callConv >= ICC_THISCALL && !objectPointer )
 			args += AS_PTR_SIZE;
 			args += AS_PTR_SIZE;
 
 

+ 9 - 1
ThirdParty/AngelScript/source/as_callfunc_arm.cpp

@@ -37,6 +37,14 @@
 // Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
 // Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
 
 
 
 
+// This code has conform to both AAPCS and the modified ABI for iOS
+//
+// Reference:
+//
+// AAPCS: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
+// iOS: http://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/iPhoneOSABIReference.pdf
+
+
 #include "as_config.h"
 #include "as_config.h"
 
 
 #ifndef AS_MAX_PORTABILITY
 #ifndef AS_MAX_PORTABILITY
@@ -57,7 +65,7 @@ extern "C" asQWORD armFuncR0ObjLast(const asDWORD *, int, asFUNCTION_t, asDWORD
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 	int callConv = sysFunc->callConv;
 
 

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

@@ -1,6 +1,6 @@
 /*
 /*
   AngelCode Scripting Library
   AngelCode Scripting Library
-  Copyright (c) 2003-2009 Andreas Jonsson
+  Copyright (c) 2003-2012 Andreas Jonsson
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any
   warranty. In no event will the authors be held liable for any
@@ -28,13 +28,13 @@
   [email protected]
   [email protected]
 */
 */
 
 
-// Modified by Lasse Öörni for Urho3D
-
 // Assembly routines for the ARM call convention
 // Assembly routines for the ARM call convention
 // Written by Fredrik Ehnbom in June 2009
 // Written by Fredrik Ehnbom in June 2009
 
 
 // Adapted to GNUC by darktemplar216 in September 2009
 // Adapted to GNUC by darktemplar216 in September 2009
 
 
+// Modified by Lasse Öörni for 8-byte stack alignment in May 2012
+
 #if defined(__arm__) || defined(__ARM__)
 #if defined(__arm__) || defined(__ARM__)
 
 
 .global armFunc
 .global armFunc

+ 1 - 1
ThirdParty/AngelScript/source/as_callfunc_mips.cpp

@@ -221,7 +221,7 @@ asQWORD GetReturnedDouble()
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 	int callConv = sysFunc->callConv;
 
 

+ 1 - 1
ThirdParty/AngelScript/source/as_callfunc_ppc.cpp

@@ -487,7 +487,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asBYTE argsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	asBYTE argsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	memset( argsType, 0, sizeof(argsType));
 	memset( argsType, 0, sizeof(argsType));
 
 
-	asCScriptEngine            *engine  = context->engine;
+	asCScriptEngine            *engine  = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 
 
 	asQWORD  retQW           = 0;
 	asQWORD  retQW           = 0;

+ 1 - 1
ThirdParty/AngelScript/source/as_callfunc_ppc_64.cpp

@@ -552,7 +552,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asBYTE argsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	asBYTE argsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	memset( argsType, 0, sizeof(argsType));
 	memset( argsType, 0, sizeof(argsType));
 
 
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 
 
 	int callConv = sysFunc->callConv;
 	int callConv = sysFunc->callConv;

+ 1 - 1
ThirdParty/AngelScript/source/as_callfunc_sh4.cpp

@@ -271,7 +271,7 @@ asQWORD GetReturnedDouble()
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 	int callConv = sysFunc->callConv;
 
 

+ 1 - 1
ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -152,7 +152,7 @@ static inline bool IsVariableArgument( asCDataType type )
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
 {
 {
-	asCScriptEngine            *engine             = context->engine;
+	asCScriptEngine            *engine             = context->m_engine;
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	int                         callConv           = sysFunc->callConv;
 	int                         callConv           = sysFunc->callConv;
 	asQWORD                     retQW              = 0;
 	asQWORD                     retQW              = 0;

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

@@ -171,7 +171,7 @@ static asQWORD GetReturnedDouble()
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 
 
 	asQWORD  retQW             = 0;
 	asQWORD  retQW             = 0;

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

@@ -49,7 +49,7 @@ extern "C" asQWORD GetReturnedDouble();
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine *engine = context->engine;
+	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 
 
 	asQWORD  retQW             = 0;
 	asQWORD  retQW             = 0;

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

@@ -88,7 +88,7 @@ asQWORD GetReturnedDouble();
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	asCScriptEngine            *engine    = context->engine;
+	asCScriptEngine            *engine    = context->m_engine;
 	asSSystemFunctionInterface *sysFunc   = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc   = descr->sysFuncIntf;
 
 
 	asQWORD retQW = 0;
 	asQWORD retQW = 0;

+ 198 - 255
ThirdParty/AngelScript/source/as_callfunc_xenon.cpp

@@ -35,7 +35,7 @@
 // These functions handle the actual calling of system functions
 // These functions handle the actual calling of system functions
 //
 //
 // This version is Xenon specific
 // This version is Xenon specific
-// Modified from as_callfunc_ppc.cpp by Laszlo Perneky Februar 2007
+// Modified from as_callfunc_ppc.cpp by Laszlo Perneky February 2007
 //
 //
 // Modified by Cyril Tissier March 2010:
 // Modified by Cyril Tissier March 2010:
 // various fixes in 'float' args passing / function return
 // various fixes in 'float' args passing / function return
@@ -43,6 +43,55 @@
 // various fixes in asm ppcFunc
 // various fixes in asm ppcFunc
 // fix for variable arguments
 // fix for variable arguments
 //
 //
+
+
+
+// XBox 360 calling convention
+// ===========================
+// I've yet to find an official document with the ABI for XBox 360, 
+// but I'll describe what I've gathered from the code and tests
+// performed by the AngelScript community.
+//
+// Arguments are passed in the following registers:
+// r3  - r10   : integer/pointer arguments (each register is 64bit)
+// fr1 - fr13  : float/double arguments    (each register is 64bit)
+// 
+// Arguments that don't fit in the registers will be pushed on the stack.
+// 
+// When a float or double is passed as argument, its value will be placed
+// in the next available float register, but it will also reserve general
+// purpose register. 
+// 
+// Example: void foo(float a, int b). a will be passed in fr1 and b in r4.
+//
+// For each argument passed to a function an 8byte slot is reserved on the 
+// stack, so that the function can offload the value there if needed. The
+// first slot is at r1+20, the next at r1+28, etc.
+//
+// If the function is a class method, the this pointer is passed as hidden 
+// first argument. If the function returns an object in memory, the address
+// for that memory is passed as hidden first argument.
+//
+// Return value are placed in the following registers:
+// r3  : integer/pointer values
+// fr1 : float/double values
+//
+// Rules for registers
+// r1          : stack pointer
+// r14-r31     : nonvolatile, i.e. their values must be preserved
+// fr14-fr31   : nonvolatile, i.e. their values must be preserved
+// r0, r2, r13 : dedicated. I'm not sure what it means, but it is probably best not to use them
+//
+// The stack pointer must always be aligned at 8 bytes.
+//
+// References:
+// https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF77852569970071B0D6/$file/eabi_app.pdf
+//
+// TODO: The code doesn't handle int64 and uint64 parameters
+// TODO: The code doesn't handle objects passed by value (unless they are max 4 bytes in size)
+
+
+
 #include "as_config.h"
 #include "as_config.h"
 
 
 #ifndef AS_MAX_PORTABILITY
 #ifndef AS_MAX_PORTABILITY
@@ -60,83 +109,70 @@
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
 #define AS_PPC_MAX_ARGS         32
 #define AS_PPC_MAX_ARGS         32
-#define AS_MAX_REG_FLOATS       13
-#define AS_MAX_REG_INTS         8
 #define AS_PPC_THISCALL_REG     1
 #define AS_PPC_THISCALL_REG     1
 #define AS_PPC_RETURNINMEM_REG  1
 #define AS_PPC_RETURNINMEM_REG  1
 #define AS_PPC_ENDOFARGS        1
 #define AS_PPC_ENDOFARGS        1
 
 
 // The array used to send values to the correct places.
 // The array used to send values to the correct places.
 // Contains a byte of argTypes to indicate the register type to load, or zero if end of arguments
 // Contains a byte of argTypes to indicate the register type to load, or zero if end of arguments
-
-extern "C" {
-	enum argTypes
-	{
-		ppcENDARG = 0,
-		ppcINTARG,
-		ppcFLOATARG,
-		ppcDOUBLEARG
-	};
-	static asBYTE ppcArgsType[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG + AS_PPC_ENDOFARGS];
-	static asDWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
-}
-
-#define PPC_LINKAGE_SIZE  (0x14)                                 // how big the PPC linkage area is in a stack frame
+enum argTypes
+{
+	ppcENDARG    = 0,
+	ppcINTARG    = 1,
+	ppcFLOATARG  = 2,
+	ppcDOUBLEARG = 3
+};
 
 
 // Loads all data into the correct places and calls the function.
 // Loads all data into the correct places and calls the function.
-// ppcArgsType is an array containing a byte type (enum argTypes) for each argument.
-// iStackArgSize is the size in bytes for how much data to put on the stack frame
-//--------------------------------------------------------------------
-asQWORD __declspec( naked ) ppcFunc(const asDWORD* pArgs, int iStackArgSize, asDWORD dwFunc)
+// pArgs     is the array of the argument values
+// pArgTypes is an array containing a byte indicating the type (enum argTypes) for each argument.
+// dwFunc    is the address of the function that will be called
+asQWORD __declspec( naked ) ppcFunc(const asDWORD* pArgs, asDWORD dwFunc, const asBYTE* pArgTypes)
 {
 {
 	__asm
 	__asm
 	{
 	{
-//////////////////////////////////////////////////////////////////////////
-// Prepare args
-//////////////////////////////////////////////////////////////////////////
 _ppcFunc:
 _ppcFunc:
-		// setup stack
-		// Read link register
+		// Prologue
+		// Read and stack the link register (return address)
 		mflr    r12
 		mflr    r12
-		// Stack the link register
 		stw     r12,-8(r1)
 		stw     r12,-8(r1)
-		// backup all registers we use in this fct
-		std     r31,-10h(r1)
-		std     r30,-18h(r1)
-		std     r29,-20h(r1)
-		std     r28,-28h(r1)
-		std     r27,-30h(r1)
-		std     r26,-38h(r1)
-		std     r25,-40h(r1)
-		std     r24,-48h(r1)
-		std     r23,-50h(r1)
-		std     r22,-58h(r1)
-		std     r21,-60h(r1)
-		// Move stack pointer
-		stwu    r1,-0A0h(r1)
-
-		mr r29, r3			//pArgs
-		mr r30, r4			//iStackArgSize
-		mr r27, r5			//dwFunc
-
-		addi r31, r1, 14h	// stack args for next function call
-
-		// Clear some registers
-		sub r0, r0, r0
-		// Counting of used/assigned GPR's
-		mr  r23, r0
-		// Counting of used/assigned Float Registers
-		mr  r22, r0
-		// Counting extra stack size
-		mr  r21, r0
 
 
-		// Fetch argument types array address
-		lau r25, ppcArgsType
-		lal r25, r25, ppcArgsType
+		// Backup all non-volatile registers we use in this function
+		std     r31,-10h(r1) // stack pointer for pushing arguments
+		std     r27,-18h(r1) // dwFunc
+		std     r26,-20h(r1) // pArgs
+		std     r25,-28h(r1) // pArgTypes
+		std     r24,-30h(r1) // current arg type
+		std     r23,-38h(r1) // counter for used GPRs
+		std     r22,-40h(r1) // counter for used float registers
+
+		// Setup the stack frame to make room for the backup of registers
+		// and the arguments that will be passed to the application function.
+		// 512 bytes is enough for about 50 arguments plus backup of 8
+		// TODO: Should perhaps make this dynamic based on number of arguments
+		stwu	r1,-200h(r1)
+
+//////////////////////////////////////////////////////////////////////////
+// Initialize local variables
+//////////////////////////////////////////////////////////////////////////
+
+		// r31 is our pointer into the stack where the arguments will be place
+		// The MSVC optimizer seems to rely on nobody copying the r1 register directly
+		// so we can't just do a simple 'addi r31, r1, 14h' as the optimizer may
+		// end up moving this instruction to before the update of r1 above. 
+		// Instead we'll read the previous stack pointer from the stack, and then 
+		// subtract to get the correct offset.
+		lwz		r31, 0(r1)
+		subi	r31, r31, 1ECh	// prev r1 - 512 + 20 = curr r1 + 20
 
 
-		// Fetch arguments array address
-		lau r26, ppcArgs
-		lal r26, r26, ppcArgs
+		mr r26, r3			// pArgs
+		mr r27, r4			// dwFunc
+		mr r25, r5			// pArgTypes
+
+		// Counting of used/assigned GPR's
+		sub  r23, r23, r23
+		// Counting of used/assigned Float Registers
+		sub  r22, r22, r22
 
 
 		// Begin loading and stacking registers
 		// Begin loading and stacking registers
 		subi r25, r25, 1
 		subi r25, r25, 1
@@ -214,12 +250,11 @@ ppcArgIsInteger:
 		b ppcLoadIntRegUpd
 		b ppcLoadIntRegUpd
 
 
 		ppcLoadIntRegUpd:
 		ppcLoadIntRegUpd:
-		stw	    r12, 0(r31)			// push on the statck
+		stw	    r12, 0(r31)			// push on the stack
 		addi	r31, r31, 8			// inc stack by 1 reg
 		addi	r31, r31, 8			// inc stack by 1 reg
 
 
 		addi r23, r23, 1			// Increment used int register count
 		addi r23, r23, 1			// Increment used int register count
-		addi r29, r29, 4			// Increment rArgsPtr
-		addi r26, r26, 4			// Increment rStackPtr
+		addi r26, r26, 4			// Increment pArgs
 		b ppcNextArg				// Call next arg
 		b ppcNextArg				// Call next arg
 
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -301,13 +336,12 @@ ppcArgIsFloat:
 		b ppcLoadFloatRegUpd
 		b ppcLoadFloatRegUpd
 
 
 		ppcLoadFloatRegUpd:
 		ppcLoadFloatRegUpd:
-		stfs	fr0, 0(r31)			// push on the statck
+		stfs	fr0, 0(r31)			// push on the stack
 		addi	r31, r31, 8			// inc stack by 1 reg
 		addi	r31, r31, 8			// inc stack by 1 reg
 		
 		
 		addi r22, r22, 1			// Increment used float register count
 		addi r22, r22, 1			// Increment used float register count
 		addi r23, r23, 1			// Increment used int register count - a float reg eats up a GPR		
 		addi r23, r23, 1			// Increment used int register count - a float reg eats up a GPR		
-		addi r29, r29, 4			// Increment rArgsPtr		
-		addi r26, r26, 4			// Increment rStackPtr
+		addi r26, r26, 4			// Increment pArgs
 		b ppcNextArg				// Call next arg
 		b ppcNextArg				// Call next arg
 
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -389,13 +423,12 @@ ppcArgIsDouble:
 		b ppcLoadDoubleRegUpd
 		b ppcLoadDoubleRegUpd
 
 
 		ppcLoadDoubleRegUpd:
 		ppcLoadDoubleRegUpd:
-		stfd	fr0, 0(r31)			// push on the statck
+		stfd	fr0, 0(r31)			// push on the stack
 		addi	r31, r31, 8			// inc stack by 1 reg
 		addi	r31, r31, 8			// inc stack by 1 reg
 		
 		
 		addi r22, r22, 1			// Increment used float register count		
 		addi r22, r22, 1			// Increment used float register count		
 		addi r23, r23, 1			// Increment used int register count
 		addi r23, r23, 1			// Increment used int register count
-		addi r29, r29, 8			// Increment rArgsPtr
-		addi r26, r26, 8			// Increment rStackPtr
+		addi r26, r26, 8			// Increment pArgs
 		b ppcNextArg
 		b ppcNextArg
 
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -406,129 +439,33 @@ ppcArgsEnd:
 		mtctr r27
 		mtctr r27
 		bctrl
 		bctrl
 
 
-		// Function returned
+		// Epilogue
 		// Restore callers stack
 		// Restore callers stack
-		addi	r1, r1, 0A0h
+		addi	r1, r1, 200h
+
+		// restore all registers we used in this fct
+		ld     r22,-40h(r1)
+		ld     r23,-38h(r1)
+		ld     r24,-30h(r1)
+		ld     r25,-28h(r1)
+		ld     r26,-20h(r1)
+		ld     r27,-18h(r1)
+		ld     r31,-10h(r1)
+
 		// Fetch return link to caller
 		// Fetch return link to caller
 		lwz     r12,-8(r1)
 		lwz     r12,-8(r1)
 		mtlr	r12
 		mtlr	r12
-		// restore all registers we used in this fct
-		ld     r31,-10h(r1)
-		ld     r30,-18h(r1)
-		ld     r29,-20h(r1)
-		ld     r28,-28h(r1)
-		ld     r27,-30h(r1)
-		ld     r26,-38h(r1)
-		ld     r25,-40h(r1)
-		ld     r24,-48h(r1)
-		ld     r23,-50h(r1)
-		ld     r22,-58h(r1)
-		ld     r21,-60h(r1) 
 		blr
 		blr
 	}
 	}
 }
 }
 
 
-
-
-
-// Puts the arguments in the correct place in the stack array.
-//-------------------------------------------------------------------
-void stackArgs(const asDWORD *pArgs, int& iNumIntArgs, int& iNumFloatArgs, int& iNumDoubleArgs)
-{
-	asBYTE * pSrcArgs	= (asBYTE *) pArgs;		// pSrcArgs += (4*iArgWordPos);
-	asBYTE * pDstArgs	= (asBYTE *) ppcArgs;	// pDstArgs += (4*iArgWordPos);
-
-	for(int iArg = 0; iArg < AS_PPC_MAX_ARGS; iArg++)
-	{
-		if ( ppcArgsType[iArg] == ppcENDARG )
-			break;
-
-		if ( ppcArgsType[iArg] == ppcFLOATARG )
-		{
-			// stow float			
-			*((float*) pDstArgs) = *((float*) pSrcArgs);
-			pSrcArgs += 4;
-			pDstArgs += 4;
-			iNumFloatArgs++;
-		}
-		else if ( ppcArgsType[iArg] == ppcDOUBLEARG )
-		{
-			// stow double
-			*((double*) pDstArgs) = *((double*) pSrcArgs);
-			pSrcArgs += 8;
-			pDstArgs += 8;
-			iNumDoubleArgs++;
-		}
-		else if ( ppcArgsType[iArg] == ppcINTARG )
-		{
-			// stow register
-			*((int*) pDstArgs) = *((int*) pSrcArgs);
-			pSrcArgs += 4;
-			pDstArgs += 4;
-			iNumIntArgs++;
-		}
-	}
-}
-
-// Prepare the arg list for a CDecl funtion and then call it
-//--------------------------------------------------------------------
-asQWORD CallCDeclFunction(const asDWORD* pArgs, int iArgSize, asDWORD dwFunc)
-{
-	int iIntArgs = 0;
-	int iFloatArgs = 0;
-	int iDoubleArgs = 0;
-
-	// Put the arguments in the correct places in the ppcArgs array
-	if ( iArgSize > 0 )
-		stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
-	
-	return ppcFunc( ppcArgs, iArgSize, dwFunc);
-}
-
-// This function is identical to CallCDeclFunction, with the only difference that
-// the value in the first parameter is the object
-//--------------------------------------------------------------------
-asQWORD CallThisCallFunction(const void* pObj, const asDWORD* pArgs, int iArgSize, asDWORD dwFunc )
-{
-	int iIntArgs = 0;
-	int iFloatArgs = 0;
-	int iDoubleArgs = 0;
-
-	// Put the arguments in the correct places in the ppcArgs array /the this ptr is already in pArgs/
-	if ( iArgSize > 0 )
-		stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
-
-	return ppcFunc( ppcArgs, iArgSize, dwFunc);
-}
-
-// This function is identical to CallCDeclFunction, with the only difference that
-// the value in the last parameter is the object
-//--------------------------------------------------------------------
-asQWORD CallThisCallFunction_objLast(const void* pObj, const asDWORD* pArgs, int iArgSize, asDWORD dwFunc)
-{
-	int iIntArgs = 0;
-	int iFloatArgs = 0;
-	int iDoubleArgs = 0;
-
-	// Put the arguments in the correct places in the ppcArgs array /the this ptr is already in pArgs/
-	if ( iArgSize > 0 )
-		stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
-
-	int iNumArgs	= iIntArgs + iFloatArgs + iDoubleArgs;
-	int iDWordCount = (iIntArgs + iFloatArgs + 2*iDoubleArgs);
-	if ( iDWordCount < AS_PPC_MAX_ARGS )
-	{
-		ppcArgs[iDWordCount]  = (asDWORD)pObj;
-		ppcArgsType[iNumArgs] = ppcINTARG;
-	}
-
-	return ppcFunc( ppcArgs, iArgSize + sizeof(pObj), dwFunc );
-}
-
-//--------------------------------------------------------------------
 asDWORD GetReturnedFloat()
 asDWORD GetReturnedFloat()
 {
 {
-	asDWORD f;
+	// This variable must be declared volatile so that the 
+	// compiler optimizations do not remove its initialization
+	// with the fr1 register due to believing the fr1 register
+	// isn't initialized.
+	volatile asDWORD f;
 
 
 	__asm
 	__asm
 	{
 	{
@@ -538,11 +475,13 @@ asDWORD GetReturnedFloat()
 	return f;
 	return f;
 }
 }
 
 
-
 asQWORD GetReturnedDouble()
 asQWORD GetReturnedDouble()
-//--------------------------------------------------------------------
 {
 {
-	asQWORD f;
+	// This variable must be declared volatile so that the 
+	// compiler optimizations do not remove its initialization
+	// with the fr1 register due to believing the fr1 register
+	// isn't initialized.
+	volatile asQWORD f;
 
 
 	__asm
 	__asm
 	{
 	{
@@ -560,61 +499,53 @@ inline bool IsVariableArgument( asCDataType type )
 
 
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
 {
 {
-	// TODO: optimize: This memset shouldn't be necessary
-	memset( ppcArgsType, 0, sizeof(ppcArgsType));
-
-	asCScriptEngine            *engine  = context->engine;
-	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;	
-
-	int callConv = sysFunc->callConv;
-
-	asQWORD retQW = 0;
-
-	void*    func       = (void*)sysFunc->func;
-	int      paramSize  = sysFunc->paramSize;
-	asDWORD* vftable;
-
-	// We generate the parameter list to this, so it fits to teh callingconvention
-	asDWORD fixedArgs[ AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG ];
-	memset(fixedArgs, 0, sizeof(fixedArgs));
-	int argsPtr = 0;
+	asCScriptEngine            *engine    = context->m_engine;
+	asSSystemFunctionInterface *sysFunc   = descr->sysFuncIntf;	
+	int                         callConv  = sysFunc->callConv;
+	asQWORD                     retQW     = 0;
+	void                       *func      = (void*)sysFunc->func;
+	asDWORD                    *vftable;
+
+	// Pack the arguments into an array that ppcFunc() can use to load each CPU register properly
+	asBYTE  ppcArgsType[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG + AS_PPC_ENDOFARGS];
+	asDWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
+	int     argsCnt = 0;
 
 
 	// If the function returns an object in memory, we allocate the memory and put the ptr to the front (will go to r3)
 	// If the function returns an object in memory, we allocate the memory and put the ptr to the front (will go to r3)
-	if ( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
+	if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
 	{
 	{
-		fixedArgs  [ argsPtr ] = (asDWORD)retPointer;
-		ppcArgsType[ argsPtr ] = ppcINTARG;
-		argsPtr++;
+		ppcArgs[argsCnt] = (asDWORD)retPointer;
+		ppcArgsType[argsCnt] = ppcINTARG;
+		argsCnt++;
 	}
 	}
 
 
-
-
-	// If we have an object and it's not objectlast, then we put it az the first arg
-	if ( obj
-		&& callConv != ICC_CDECL_OBJLAST
-		&& callConv != ICC_CDECL_OBJLAST_RETURNINMEM )
+	// If we have an object and it's not objectlast, then we put it as the first arg
+	if ( obj &&
+		 callConv != ICC_CDECL_OBJLAST &&
+		 callConv != ICC_CDECL_OBJLAST_RETURNINMEM )
 	{
 	{
-		fixedArgs  [ argsPtr ] = (asDWORD)obj;
-		ppcArgsType[ argsPtr ] = ppcINTARG;
-		argsPtr++;
+		ppcArgs[argsCnt] = (asDWORD)obj;
+		ppcArgsType[argsCnt] = ppcINTARG;
+		argsCnt++;
 	}
 	}
 
 
-	asASSERT(descr->parameterTypes.GetLength() <= AS_PPC_MAX_ARGS);
-
-	// Parameter calculation magic
-	asDWORD paramBuffer[64];
-	if ( sysFunc->takesObjByVal )
+	// If the function takes any objects by value, they must be copied 
+	// to the stack, shifting the other arguments as necessary. paramBuffer
+	// will then replace the args pointer that was received from the VM.
+	// TODO: Is this really how XBox 360 passes objects by value?
+	asDWORD paramBuffer[AS_PPC_MAX_ARGS];
+	if( sysFunc->takesObjByVal )
 	{
 	{
-		paramSize = 0;
+		int paramSize = 0;
 		int spos = 0;
 		int spos = 0;
 		int dpos = 1;
 		int dpos = 1;
 
 
-		for ( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
+		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 		{
 			// Parameter object by value
 			// Parameter object by value
-			if (  descr->parameterTypes[n].IsObject()
-				&& !descr->parameterTypes[n].IsObjectHandle()
-				&& !descr->parameterTypes[n].IsReference() )
+			if( descr->parameterTypes[n].IsObject() && 
+				!descr->parameterTypes[n].IsObjectHandle() &&
+				!descr->parameterTypes[n].IsReference() )
 			{
 			{
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
@@ -627,8 +558,9 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 				{
 				{
 					// Copy the object's memory to the buffer
 					// Copy the object's memory to the buffer
 					memcpy( &paramBuffer[dpos], *(void**)(args + spos), descr->parameterTypes[n].GetSizeInMemoryBytes() );
 					memcpy( &paramBuffer[dpos], *(void**)(args + spos), descr->parameterTypes[n].GetSizeInMemoryBytes() );
+
 					// Delete the original memory
 					// Delete the original memory
-					engine->CallFree(*(char**)(args + spos) );
+					engine->CallFree(*(char**)(args + spos));
 
 
 					spos++;
 					spos++;
 					dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
 					dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
@@ -644,10 +576,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 				paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
 				paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
 			}
 			}
 
 
-			// if this was a variable argument parameter, then account for the implicit typeID
+			// If this was a variable argument parameter, then account for the implicit typeId
 			if( IsVariableArgument( descr->parameterTypes[n] ) )
 			if( IsVariableArgument( descr->parameterTypes[n] ) )
 			{
 			{
-				// the TypeID is just a DWORD
+				// the TypeId is just a DWORD
 				paramBuffer[dpos++] = args[spos++];
 				paramBuffer[dpos++] = args[spos++];
 				++paramSize;
 				++paramSize;
 			}
 			}
@@ -655,18 +587,20 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 
 		// Keep a free location at the beginning
 		// Keep a free location at the beginning
 		args = &paramBuffer[1];
 		args = &paramBuffer[1];
+
+		asASSERT( paramSize <= AS_PPC_MAX_ARGS );
 	}
 	}
 
 
 
 
 	const asUINT paramCount = (asUINT)descr->parameterTypes.GetLength();
 	const asUINT paramCount = (asUINT)descr->parameterTypes.GetLength();
 
 
-	asBYTE * pCurArgType		= (asBYTE*)&ppcArgsType[argsPtr];
-	asBYTE * pCurFixedArgValue	= (asBYTE*)&fixedArgs[argsPtr];
+	asBYTE * pCurArgType		= (asBYTE*)&ppcArgsType[argsCnt];
+	asBYTE * pCurFixedArgValue	= (asBYTE*)&ppcArgs[argsCnt];
 	asBYTE * pCurStackArgValue	= (asBYTE*)args;
 	asBYTE * pCurStackArgValue	= (asBYTE*)args;
 
 
-	for( asUINT n = 0; n < paramCount ; n++ )
+	for( asUINT n = 0; n < paramCount; n++ )
 	{		
 	{		
-		argsPtr++;
+		argsCnt++;
 
 
 		if (descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference())
 		if (descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference())
 		{
 		{
@@ -718,49 +652,58 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 
 			pCurFixedArgValue += 4;
 			pCurFixedArgValue += 4;
 			pCurStackArgValue += 4;
 			pCurStackArgValue += 4;
-		}
 
 
-		// if it is a variable argument, account for the typeID
-		// implicitly add another parameter (AFTER the parameter above), for the TypeID
-		if( IsVariableArgument(descr->parameterTypes[n]) )
-		{			
-			argsPtr++;
+			// if it is a variable argument, account for the typeId
+			// implicitly add another parameter (AFTER the parameter above) for the typeId
+			if( IsVariableArgument(descr->parameterTypes[n]) )
+			{			
+				argsCnt++;
 
 
-			*pCurArgType++ = ppcINTARG;
+				*pCurArgType++ = ppcINTARG;
 
 
-			*((int*) pCurFixedArgValue) = *((int*) pCurStackArgValue);
+				*((int*) pCurFixedArgValue) = *((int*) pCurStackArgValue);
 
 
-			pCurFixedArgValue += 4;
-			pCurStackArgValue += 4;
+				pCurFixedArgValue += 4;
+				pCurStackArgValue += 4;
+			}
 		}
 		}
 	}
 	}
 
 
+	// Add the arg list end indicator
+	ppcArgsType[argsCnt] = ppcENDARG;
+
 	switch( callConv )
 	switch( callConv )
 	{
 	{
 	case ICC_CDECL:
 	case ICC_CDECL:
 	case ICC_CDECL_RETURNINMEM:
 	case ICC_CDECL_RETURNINMEM:
 	case ICC_STDCALL:
 	case ICC_STDCALL:
 	case ICC_STDCALL_RETURNINMEM:
 	case ICC_STDCALL_RETURNINMEM:
-		retQW = CallCDeclFunction( fixedArgs, argsPtr, (asDWORD)func );
-		break;
 	case ICC_THISCALL:
 	case ICC_THISCALL:
 	case ICC_THISCALL_RETURNINMEM:
 	case ICC_THISCALL_RETURNINMEM:
-		retQW = CallThisCallFunction( obj, fixedArgs, argsPtr, (asDWORD)func );
+	case ICC_CDECL_OBJFIRST:
+	case ICC_CDECL_OBJFIRST_RETURNINMEM:
+	{
+		retQW = ppcFunc( ppcArgs, (asDWORD)func, ppcArgsType );
 		break;
 		break;
+	}
 	case ICC_VIRTUAL_THISCALL:
 	case ICC_VIRTUAL_THISCALL:
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+	{
 		// Get virtual function table from the object pointer
 		// Get virtual function table from the object pointer
 		vftable = *(asDWORD**)obj;
 		vftable = *(asDWORD**)obj;
-		retQW = CallThisCallFunction( obj, fixedArgs, argsPtr, vftable[asDWORD(func)>>2] );
+		retQW = ppcFunc( ppcArgs, vftable[asDWORD(func)>>2], ppcArgsType );
 		break;
 		break;
+	}
 	case ICC_CDECL_OBJLAST:
 	case ICC_CDECL_OBJLAST:
 	case ICC_CDECL_OBJLAST_RETURNINMEM:
 	case ICC_CDECL_OBJLAST_RETURNINMEM:
-		retQW = CallThisCallFunction_objLast( obj, fixedArgs, argsPtr, (asDWORD)func );
-		break;
-	case ICC_CDECL_OBJFIRST:
-	case ICC_CDECL_OBJFIRST_RETURNINMEM:
-		retQW = CallThisCallFunction( obj, fixedArgs, argsPtr, (asDWORD)func );
+	{
+		// Add the object pointer as the last argument
+		ppcArgsType[argsCnt++] = ppcINTARG;
+		ppcArgsType[argsCnt] = ppcENDARG;
+		*((asPWORD*)pCurFixedArgValue) = (asPWORD)obj;
+		retQW = ppcFunc( ppcArgs, (asDWORD)func, ppcArgsType );
 		break;
 		break;
+	}
 	default:
 	default:
 		context->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
 		context->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
 	}
 	}
@@ -787,5 +730,5 @@ END_AS_NAMESPACE
 #endif // AS_XENON
 #endif // AS_XENON
 #endif // AS_MAX_PORTABILITY
 #endif // AS_MAX_PORTABILITY
 
 
-//------------------------------------------------------------------
+
 
 

+ 192 - 33
ThirdParty/AngelScript/source/as_compiler.cpp

@@ -411,7 +411,10 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, sEx
 				asCString name(&script->code[node->tokenPos], node->tokenLength);
 				asCString name(&script->code[node->tokenPos], node->tokenLength);
 
 
 				if( vs.DeclareVariable(name.AddressOf(), type, stackPos, true) < 0 )
 				if( vs.DeclareVariable(name.AddressOf(), type, stackPos, true) < 0 )
+				{
+					// TODO: It might be an out-of-memory too
 					Error(TXT_PARAMETER_ALREADY_DECLARED, node);
 					Error(TXT_PARAMETER_ALREADY_DECLARED, node);
+				}
 
 
 				// Add marker for variable declaration
 				// Add marker for variable declaration
 				byteCode.VarDecl((int)outFunc->variables.GetLength());
 				byteCode.VarDecl((int)outFunc->variables.GetLength());
@@ -1229,18 +1232,6 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 	// Need to protect arguments by reference
 	// Need to protect arguments by reference
 	if( isFunction && dt.IsReference() )
 	if( isFunction && dt.IsReference() )
 	{
 	{
-		if( paramType->GetTokenType() == ttQuestion )
-		{
-			asCByteCode tmpBC(engine);
-
-			// Place the type id on the stack as a hidden parameter
-			tmpBC.InstrDWORD(asBC_TYPEID, engine->GetTypeIdFromDataType(param));
-
-			// Insert the code before the expression code
-			tmpBC.AddCode(&ctx->bc);
-			ctx->bc.AddCode(&tmpBC);
-		}
-
 		// Allocate a temporary variable of the same type as the argument
 		// Allocate a temporary variable of the same type as the argument
 		dt.MakeReference(false);
 		dt.MakeReference(false);
 		dt.MakeReadOnly(false);
 		dt.MakeReadOnly(false);
@@ -1250,6 +1241,19 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		{
 		{
 			ProcessPropertyGetAccessor(ctx, node);
 			ProcessPropertyGetAccessor(ctx, node);
 
 
+			// Add the type id as hidden arg if the parameter is a ? type
+			if( paramType->GetTokenType() == ttQuestion )
+			{
+				asCByteCode tmpBC(engine);
+
+				// Place the type id on the stack as a hidden parameter
+				tmpBC.InstrDWORD(asBC_TYPEID, engine->GetTypeIdFromDataType(param));
+
+				// Insert the code before the expression code
+				tmpBC.AddCode(&ctx->bc);
+				ctx->bc.AddCode(&tmpBC);
+			}
+
 			// If the reference is const, then it is not necessary to make a copy if the value already is a variable
 			// If the reference is const, then it is not necessary to make a copy if the value already is a variable
 			// Even if the same variable is passed in another argument as non-const then there is no problem
 			// Even if the same variable is passed in another argument as non-const then there is no problem
 			if( dt.IsPrimitive() || dt.IsNullHandle() )
 			if( dt.IsPrimitive() || dt.IsNullHandle() )
@@ -1345,6 +1349,19 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		}
 		}
 		else if( refType == 2 ) // &out
 		else if( refType == 2 ) // &out
 		{
 		{
+			// Add the type id as hidden arg if the parameter is a ? type
+			if( paramType->GetTokenType() == ttQuestion )
+			{
+				asCByteCode tmpBC(engine);
+
+				// Place the type id on the stack as a hidden parameter
+				tmpBC.InstrDWORD(asBC_TYPEID, engine->GetTypeIdFromDataType(param));
+
+				// Insert the code before the expression code
+				tmpBC.AddCode(&ctx->bc);
+				ctx->bc.AddCode(&tmpBC);
+			}
+
 			// Make sure the variable is not used in the expression
 			// Make sure the variable is not used in the expression
 			offset = AllocateVariableNotIn(dt, true, false, ctx);
 			offset = AllocateVariableNotIn(dt, true, false, ctx);
 
 
@@ -1383,6 +1400,19 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		{
 		{
 			ProcessPropertyGetAccessor(ctx, node);
 			ProcessPropertyGetAccessor(ctx, node);
 
 
+			// Add the type id as hidden arg if the parameter is a ? type
+			if( paramType->GetTokenType() == ttQuestion )
+			{
+				asCByteCode tmpBC(engine);
+
+				// Place the type id on the stack as a hidden parameter
+				tmpBC.InstrDWORD(asBC_TYPEID, engine->GetTypeIdFromDataType(param));
+
+				// Insert the code before the expression code
+				tmpBC.AddCode(&ctx->bc);
+				ctx->bc.AddCode(&tmpBC);
+			}
+
 			// Literal constants cannot be passed to inout ref arguments
 			// Literal constants cannot be passed to inout ref arguments
 			if( !ctx->type.isVariable && ctx->type.isConstant )
 			if( !ctx->type.isVariable && ctx->type.isConstant )
 			{
 			{
@@ -1438,6 +1468,12 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 				ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
 				ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
 			else if( ctx->type.dataType.IsPrimitive() )
 			else if( ctx->type.dataType.IsPrimitive() )
 				ctx->bc.Instr(asBC_PshRPtr);
 				ctx->bc.Instr(asBC_PshRPtr);
+			else if( ctx->type.dataType.IsObjectHandle() && !ctx->type.dataType.IsReference() )
+			{
+				asCDataType dt = ctx->type.dataType;
+				dt.MakeReference(true);
+				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, false);
+			}
 		}
 		}
 	}
 	}
 	else
 	else
@@ -1676,6 +1712,11 @@ int asCCompiler::CompileArgumentList(asCScriptNode *node, asCArray<asSExprContex
 		if( r < 0 ) anyErrors = true;
 		if( r < 0 ) anyErrors = true;
 
 
 		args[n] = asNEW(asSExprContext)(engine);
 		args[n] = asNEW(asSExprContext)(engine);
+		if( args[n] == 0 )
+		{
+			// Out of memory
+			return -1;
+		}
 		MergeExprBytecodeAndType(args[n], &expr);
 		MergeExprBytecodeAndType(args[n], &expr);
 
 
 		n--;
 		n--;
@@ -1734,6 +1775,12 @@ int asCCompiler::CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext
 		}
 		}
 
 
 		args[n] = asNEW(asSExprContext)(engine);
 		args[n] = asNEW(asSExprContext)(engine);
+		if( args[n] == 0 )
+		{
+			// Out of memory
+			return -1;
+		}
+
 		MergeExprBytecodeAndType(args[n], &expr);
 		MergeExprBytecodeAndType(args[n], &expr);
 
 
 		// Make sure the default arg expression doesn't end up
 		// Make sure the default arg expression doesn't end up
@@ -1931,7 +1978,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 
 
 		// Verify that the name isn't used by a dynamic data type
 		// Verify that the name isn't used by a dynamic data type
-		if( engine->GetObjectType(name.AddressOf()) != 0 )
+		if( engine->GetObjectType(name.AddressOf(), outFunc->nameSpace) != 0 )
 		{
 		{
 			asCString str;
 			asCString str;
 			str.Format(TXT_ILLEGAL_VARIABLE_NAME_s, name.AddressOf());
 			str.Format(TXT_ILLEGAL_VARIABLE_NAME_s, name.AddressOf());
@@ -1941,6 +1988,8 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 		int offset = AllocateVariable(type, false);
 		int offset = AllocateVariable(type, false);
 		if( variables->DeclareVariable(name.AddressOf(), type, offset, IsVariableOnHeap(offset)) < 0 )
 		if( variables->DeclareVariable(name.AddressOf(), type, offset, IsVariableOnHeap(offset)) < 0 )
 		{
 		{
+			// TODO: It might be an out-of-memory too
+
 			asCString str;
 			asCString str;
 			str.Format(TXT_s_ALREADY_DECLARED, name.AddressOf());
 			str.Format(TXT_s_ALREADY_DECLARED, name.AddressOf());
 			Error(str.AddressOf(), node);
 			Error(str.AddressOf(), node);
@@ -3499,6 +3548,11 @@ void asCCompiler::DestroyVariables(asCByteCode *bc)
 void asCCompiler::AddVariableScope(bool isBreakScope, bool isContinueScope)
 void asCCompiler::AddVariableScope(bool isBreakScope, bool isContinueScope)
 {
 {
 	variables = asNEW(asCVariableScope)(variables);
 	variables = asNEW(asCVariableScope)(variables);
+	if( variables == 0 )
+	{
+		// Out of memory
+		return;
+	}
 	variables->isBreakScope    = isBreakScope;
 	variables->isBreakScope    = isBreakScope;
 	variables->isContinueScope = isContinueScope;
 	variables->isContinueScope = isContinueScope;
 }
 }
@@ -4186,9 +4240,14 @@ bool asCCompiler::CompileRefCast(asSExprContext *ctx, const asCDataType &to, boo
 					arg.type.isExplicitHandle = true;
 					arg.type.isExplicitHandle = true;
 					args.PushLast(&arg);
 					args.PushLast(&arg);
 
 
+					asCTypeInfo prev = ctx->type;
+
 					// Call the behaviour method
 					// Call the behaviour method
 					MakeFunctionCall(ctx, ops[0], ctx->type.dataType.GetObjectType(), args, node);
 					MakeFunctionCall(ctx, ops[0], ctx->type.dataType.GetObjectType(), args, node);
 
 
+					// Release previous temporary variable
+					ReleaseTemporaryVariable(prev, &ctx->bc);
+
 					// Use the reference to the variable as the result of the expression
 					// Use the reference to the variable as the result of the expression
 					// Now we can mark the variable as temporary
 					// Now we can mark the variable as temporary
 					ctx->type.SetVariable(toRef, stackOffset, true);
 					ctx->type.SetVariable(toRef, stackOffset, true);
@@ -4974,10 +5033,41 @@ asUINT asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDat
 
 
 		if( !ctx->type.dataType.IsObjectHandle() )
 		if( !ctx->type.dataType.IsObjectHandle() )
 		{
 		{
-			// An object type can be directly converted to a handle of the same type
+			// An object type can be directly converted to a handle of the 
+			// same type by doing a ref copy to a new variable
 			if( ctx->type.dataType.SupportHandles() )
 			if( ctx->type.dataType.SupportHandles() )
 			{
 			{
-				ctx->type.dataType.MakeHandle(true);
+				asCDataType dt = ctx->type.dataType;
+				dt.MakeHandle(true);
+				dt.MakeReference(false);
+
+				if( generateCode )
+				{
+					// TODO: runtime optimize: This copy is not always necessary. 
+					//                         How to determine when not to do it?
+					int offset = AllocateVariable(dt, true);
+
+					if( ctx->type.dataType.IsReference() )
+						ctx->bc.Instr(asBC_RDSPtr);
+					ctx->bc.InstrSHORT(asBC_PSF, (short)offset);
+					ctx->bc.InstrPTR(asBC_REFCPY, dt.GetObjectType());
+					ctx->bc.Instr(asBC_PopPtr);
+					ctx->bc.InstrSHORT(asBC_PSF, (short)offset);
+
+					ReleaseTemporaryVariable(ctx->type, &ctx->bc);
+
+					if( to.IsReference() )
+						dt.MakeReference(true);
+					else
+						ctx->bc.Instr(asBC_RDSPtr);
+
+					ctx->type.SetVariable(dt, offset, true);
+				}
+				else
+					ctx->type.dataType = dt;
+
+				// When this conversion is done the expression is no longer an lvalue
+				ctx->type.isLValue = false;
 			}
 			}
 
 
 			if( ctx->type.dataType.IsObjectHandle() )
 			if( ctx->type.dataType.IsObjectHandle() )
@@ -5764,10 +5854,10 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 		lctx->type.isExplicitHandle = true;
 		lctx->type.isExplicitHandle = true;
 	}
 	}
 
 
-    // Urho3D: if there is a handle type, and it does not have an overloaded assignment operator, convert to an explicit handle
-    // for scripting convenience. (For the Urho3D handle types, value assignment is not supported)
-    if (lctx->type.dataType.IsObjectHandle() && !lctx->type.isExplicitHandle && !lctx->type.dataType.GetBehaviour()->copy)
-        lctx->type.isExplicitHandle = true;
+	// Urho3D: if there is a handle type, and it does not have an overloaded assignment operator, convert to an explicit handle
+	// for scripting convenience. (For the Urho3D handle types, value assignment is not supported)
+	if (lctx->type.dataType.IsObjectHandle() && !lctx->type.isExplicitHandle && !lctx->type.dataType.GetBehaviour()->copy)
+		lctx->type.isExplicitHandle = true;
 
 
 	// If the left hand expression is a property accessor, then that should be used
 	// If the left hand expression is a property accessor, then that should be used
 	// to do the assignment instead of the ordinary operator. The exception is when
 	// to do the assignment instead of the ordinary operator. The exception is when
@@ -6562,7 +6652,7 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 			bool isPureConstant = false;
 			bool isPureConstant = false;
 			bool isAppProp = false;
 			bool isAppProp = false;
 			asQWORD constantValue;
 			asQWORD constantValue;
-			asCString ns = scope == "::" ? "" : scope;
+			asCString ns = scope;
 
 
 			if( ns == "" )
 			if( ns == "" )
 			{
 			{
@@ -6571,6 +6661,8 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 					ns = outFunc->objectType->nameSpace;
 					ns = outFunc->objectType->nameSpace;
 			}
 			}
+			else if( ns == "::" )
+				ns = "";
 
 
 			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), ns, &isCompiled, &isPureConstant, &constantValue, &isAppProp);
 			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), ns, &isCompiled, &isPureConstant, &constantValue, &isAppProp);
 			if( prop )
 			if( prop )
@@ -6648,7 +6740,7 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 	if( !noFunction && !found && !objType )
 	if( !noFunction && !found && !objType )
 	{
 	{
 		asCArray<int> funcs;
 		asCArray<int> funcs;
-		asCString ns = scope == "::" ? "" : scope;
+		asCString ns = scope;
 
 
 		if( ns == "" )
 		if( ns == "" )
 		{
 		{
@@ -6657,6 +6749,8 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 			else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 			else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 				ns = outFunc->objectType->nameSpace;
 				ns = outFunc->objectType->nameSpace;
 		}
 		}
+		else if( ns == "::" )
+			ns = "";
 
 
 		builder->GetFunctionDescriptions(name.AddressOf(), funcs, ns);
 		builder->GetFunctionDescriptions(name.AddressOf(), funcs, ns);
 
 
@@ -6724,7 +6818,7 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 		else if( !engine->ep.requireEnumScope )
 		else if( !engine->ep.requireEnumScope )
 		{
 		{
 			// Look for the enum value without explicitly informing the enum type
 			// Look for the enum value without explicitly informing the enum type
-			asCString ns = scope == "::" ? "" : scope;
+			asCString ns = scope;
 
 
 			if( ns == "" )
 			if( ns == "" )
 			{
 			{
@@ -6735,6 +6829,8 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 					ns = outFunc->objectType->nameSpace;
 					ns = outFunc->objectType->nameSpace;
 			}
 			}
+			else if( ns == "::" )
+				ns = "";
 
 
 			int e = builder->GetEnumValue(name.AddressOf(), dt, value, ns);
 			int e = builder->GetEnumValue(name.AddressOf(), dt, value, ns);
 			if( e )
 			if( e )
@@ -7821,7 +7917,7 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, a
 		else
 		else
 		{
 		{
 			// The scope is used to define the namespace
 			// The scope is used to define the namespace
-			asCString ns = scope == "::" ? "" : scope;
+			asCString ns = scope;
 
 
 			if( ns == "" )
 			if( ns == "" )
 			{
 			{
@@ -7830,6 +7926,8 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, a
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 				else if( outFunc->objectType && outFunc->objectType->nameSpace != "" )
 					ns = outFunc->objectType->nameSpace;
 					ns = outFunc->objectType->nameSpace;
 			}
 			}
+			else if( ns == "::" )
+				ns = "";
 
 
 			builder->GetFunctionDescriptions(name.AddressOf(), funcs, ns);
 			builder->GetFunctionDescriptions(name.AddressOf(), funcs, ns);
 
 
@@ -7962,18 +8060,30 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx
 			return -1;
 			return -1;
 		}
 		}
 
 
-		// If this is really an object then the handle created is a const handle
-		bool makeConst = !ctx->type.dataType.IsObjectHandle() && !(ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE);
+		// Convert the expression to a handle
+		if( !ctx->type.dataType.IsObjectHandle() && !(ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE) )
+		{
+			asCDataType to = ctx->type.dataType;
+			to.MakeHandle(true);
+			to.MakeReference(true);
+			to.MakeHandleToConst(ctx->type.dataType.IsReadOnly());
+			ImplicitConversion(ctx, to, node, asIC_IMPLICIT_CONV, true, false);
 
 
-		// Mark the type as an object handle
-		ctx->type.dataType.MakeHandle(true);
+			asASSERT( ctx->type.dataType.IsObjectHandle() );
+		}
+		else if( ctx->type.dataType.GetObjectType()->flags & asOBJ_ASHANDLE )
+		{
+			// For the ASHANDLE type we'll simply set the expression as a handle
+			ctx->type.dataType.MakeHandle(true);
+		}
+
+		// Mark the expression as an explicit handle to avoid implicit conversions to non-handle expressions
 		ctx->type.isExplicitHandle = true;
 		ctx->type.isExplicitHandle = true;
-		if( makeConst )
-			ctx->type.dataType.MakeReadOnly(true);
 	}
 	}
-	else if( (op == ttMinus || op == ttBitNot || op == ttInc || op == ttDec) && ctx->type.dataType.IsObject() )
+	else if( (op == ttMinus || op == ttPlus || op == ttBitNot || op == ttInc || op == ttDec) && ctx->type.dataType.IsObject() )
 	{
 	{
 		// Look for the appropriate method
 		// Look for the appropriate method
+		// There is no overloadable operator for unary plus
 		const char *opName = 0;
 		const char *opName = 0;
 		switch( op )
 		switch( op )
 		{
 		{
@@ -8040,6 +8150,12 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx
 				return -1;
 				return -1;
 			}
 			}
 		}
 		}
+		else if( op == ttPlus )
+		{
+			Error(TXT_ILLEGAL_OPERATION, node);
+			ctx->type.SetDummy();
+			return -1;
+		}
 	}
 	}
 	else if( op == ttPlus || op == ttMinus )
 	else if( op == ttPlus || op == ttMinus )
 	{
 	{
@@ -8561,6 +8677,12 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		if( arg )
 		if( arg )
 		{
 		{
 			ctx->property_arg = asNEW(asSExprContext)(engine);
 			ctx->property_arg = asNEW(asSExprContext)(engine);
+			if( ctx->property_arg == 0 )
+			{
+				// Out of memory
+				return -1;
+			}
+
 			MergeExprBytecodeAndType(ctx->property_arg, arg);
 			MergeExprBytecodeAndType(ctx->property_arg, arg);
 		}
 		}
 
 
@@ -9028,10 +9150,14 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 	}
 	}
 	else if( op == ttOpenBracket )
 	else if( op == ttOpenBracket )
 	{
 	{
-		// If the property access takes an index arg, then we should use that instead of processing it now
+		// If the property access takes an index arg and the argument hasn't been evaluated yet, 
+		// then we should use that instead of processing it now. If the argument has already been
+		// evaluated, then we should process the property accessor as a get access now as the new
+		// index operator is on the result of that accessor.
 		asCString propertyName;
 		asCString propertyName;
-		if( (ctx->property_get && builder->GetFunctionDescription(ctx->property_get)->GetParamCount() == 1) ||
-			(ctx->property_set && builder->GetFunctionDescription(ctx->property_set)->GetParamCount() == 2) )
+		if( ((ctx->property_get && builder->GetFunctionDescription(ctx->property_get)->GetParamCount() == 1) ||
+			 (ctx->property_set && builder->GetFunctionDescription(ctx->property_set)->GetParamCount() == 2)) &&
+			(ctx->property_arg && ctx->property_arg->type.dataType.GetTokenType() == ttUnrecognizedToken) )
 		{
 		{
 			// Determine the name of the property accessor
 			// Determine the name of the property accessor
 			asCScriptFunction *func = 0;
 			asCScriptFunction *func = 0;
@@ -9193,13 +9319,41 @@ asUINT asCCompiler::MatchArgument(asCArray<int> &funcs, asCArray<int> &matches,
 			desc->inOutFlags[paramNum] == asTM_INOUTREF &&
 			desc->inOutFlags[paramNum] == asTM_INOUTREF &&
 			desc->parameterTypes[paramNum].GetTokenType() != ttQuestion )
 			desc->parameterTypes[paramNum].GetTokenType() != ttQuestion )
 		{
 		{
+			// Observe, that the below checks are only necessary for when unsafe references have been
+			// enabled by the application. Without this the &inout reference form wouldn't be allowed
+			// for these value types.
+
+			// Don't allow a primitive to be converted to a reference of another primitive type
 			if( desc->parameterTypes[paramNum].IsPrimitive() &&
 			if( desc->parameterTypes[paramNum].IsPrimitive() &&
 				desc->parameterTypes[paramNum].GetTokenType() != argType->dataType.GetTokenType() )
 				desc->parameterTypes[paramNum].GetTokenType() != argType->dataType.GetTokenType() )
+			{
+				asASSERT( engine->ep.allowUnsafeReferences );
 				continue;
 				continue;
+			}
 
 
+			// Don't allow an enum to be converted to a reference of another enum type
 			if( desc->parameterTypes[paramNum].IsEnumType() &&
 			if( desc->parameterTypes[paramNum].IsEnumType() &&
 				desc->parameterTypes[paramNum].GetObjectType() != argType->dataType.GetObjectType() )
 				desc->parameterTypes[paramNum].GetObjectType() != argType->dataType.GetObjectType() )
+			{
+				asASSERT( engine->ep.allowUnsafeReferences );
 				continue;
 				continue;
+			}
+
+			// Don't allow a non-handle expression to be converted to a reference to a handle
+			if( desc->parameterTypes[paramNum].IsObjectHandle() &&
+				!argType->dataType.IsObjectHandle() )
+			{
+				asASSERT( engine->ep.allowUnsafeReferences );
+				continue;
+			}
+
+			// Don't allow a value type to be converted
+			if( (desc->parameterTypes[paramNum].GetObjectType() && (desc->parameterTypes[paramNum].GetObjectType()->GetFlags() & asOBJ_VALUE)) &&
+				(desc->parameterTypes[paramNum].GetObjectType() != argType->dataType.GetObjectType()) )
+			{
+				asASSERT( engine->ep.allowUnsafeReferences );
+				continue;
+			}
 		}
 		}
 
 
 		// How well does the argument match the function parameter?
 		// How well does the argument match the function parameter?
@@ -9226,6 +9380,11 @@ void asCCompiler::PrepareArgument2(asSExprContext *ctx, asSExprContext *arg, asC
 	{
 	{
 		// Store the original bytecode so that it can be reused when processing the deferred output parameter
 		// Store the original bytecode so that it can be reused when processing the deferred output parameter
 		asSExprContext *orig = asNEW(asSExprContext)(engine);
 		asSExprContext *orig = asNEW(asSExprContext)(engine);
+		if( orig == 0 )
+		{
+			// Out of memory
+			return;
+		}
 		MergeExprBytecodeAndType(orig, arg);
 		MergeExprBytecodeAndType(orig, arg);
 		arg->origExpr = orig;
 		arg->origExpr = orig;
 	}
 	}

+ 8 - 8
ThirdParty/AngelScript/source/as_config.h

@@ -549,6 +549,7 @@
 
 
 	// MacOSX and IPhone
 	// MacOSX and IPhone
 	#ifdef __APPLE__
 	#ifdef __APPLE__
+
 		#include <TargetConditionals.h>
 		#include <TargetConditionals.h>
 
 
 		// Is this a Mac or an IPhone?
 		// Is this a Mac or an IPhone?
@@ -802,23 +803,22 @@
 		#define CDECL_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
 		#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 
 
-		// Urho3D: added for Android
-		#undef GNU_STYLE_VIRTUAL_METHOD
-
 		#if (defined(_ARM_) || defined(__arm__))
 		#if (defined(_ARM_) || defined(__arm__))
 			// The stdcall calling convention is not used on the arm cpu
 			// The stdcall calling convention is not used on the arm cpu
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
 
 
-			#define AS_ARM
-			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
-			#define AS_ALIGN
-			
-			// Urho3D: correct complex mask
+			#undef GNU_STYLE_VIRTUAL_METHOD
+
 			#undef COMPLEX_MASK
 			#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)
+			// Urho3D: added complex return mask to be sure
 			#undef COMPLEX_RETURN_MASK
 			#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)
+
+			#define AS_ARM
+			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
+			#define AS_ALIGN
 		#endif
 		#endif
 
 
 	// Haiku OS
 	// Haiku OS

File diff suppressed because it is too large
+ 292 - 228
ThirdParty/AngelScript/source/as_context.cpp


+ 64 - 47
ThirdParty/AngelScript/source/as_context.h

@@ -54,19 +54,32 @@ class asCScriptEngine;
 class asCContext : public asIScriptContext
 class asCContext : public asIScriptContext
 {
 {
 public:
 public:
-	// From asIScriptContext
+	// Memory management
 	int  AddRef() const;
 	int  AddRef() const;
 	int  Release() const;
 	int  Release() const;
 
 
+	// Miscellaneous
 	asIScriptEngine *GetEngine() const;
 	asIScriptEngine *GetEngine() const;
 
 
+	// Execution
+	int             Prepare(asIScriptFunction *func);
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
+	int             Prepare(int functionId);
+#endif
+	int             Unprepare();
+	int             Execute();
+	int             Abort();
+	int             Suspend();
 	asEContextState GetState() const;
 	asEContextState GetState() const;
+	int             PushState();
+	int             PopState();
+	bool            IsNested(asUINT *nestCount = 0) const;
 
 
-	int  Prepare(asIScriptFunction *func);
-	// TODO: interface: deprecate this
-	int  Prepare(int functionId);
-	int  Unprepare();
+	// Object pointer for calling class methods
+	int SetObject(void *obj);
 
 
+	// Arguments
 	int SetArgByte(asUINT arg, asBYTE value);
 	int SetArgByte(asUINT arg, asBYTE value);
 	int SetArgWord(asUINT arg, asWORD value);
 	int SetArgWord(asUINT arg, asWORD value);
 	int SetArgDWord(asUINT arg, asDWORD value);
 	int SetArgDWord(asUINT arg, asDWORD value);
@@ -77,8 +90,7 @@ public:
 	int SetArgObject(asUINT arg, void *obj);
 	int SetArgObject(asUINT arg, void *obj);
 	void *GetAddressOfArg(asUINT arg);
 	void *GetAddressOfArg(asUINT arg);
 
 
-	int SetObject(void *obj);
-
+	// Return value
 	asBYTE  GetReturnByte();
 	asBYTE  GetReturnByte();
 	asWORD  GetReturnWord();
 	asWORD  GetReturnWord();
 	asDWORD GetReturnDWord();
 	asDWORD GetReturnDWord();
@@ -89,21 +101,18 @@ public:
 	void   *GetReturnObject();
 	void   *GetReturnObject();
 	void   *GetAddressOfReturnValue();
 	void   *GetAddressOfReturnValue();
 
 
-	int  Execute();
-	int  Abort();
-	int  Suspend();
-
+	// Exception handling
 	int                SetException(const char *descr);
 	int                SetException(const char *descr);
 	int                GetExceptionLineNumber(int *column, const char **sectionName);
 	int                GetExceptionLineNumber(int *column, const char **sectionName);
 	asIScriptFunction *GetExceptionFunction();
 	asIScriptFunction *GetExceptionFunction();
 	const char *       GetExceptionString();
 	const char *       GetExceptionString();
+	int                SetExceptionCallback(asSFuncPtr callback, void *obj, int callConv);
+	void               ClearExceptionCallback();
 
 
-	int  SetLineCallback(asSFuncPtr callback, void *obj, int callConv);
-	void ClearLineCallback();
-	int  SetExceptionCallback(asSFuncPtr callback, void *obj, int callConv);
-	void ClearExceptionCallback();
-
-	asUINT             GetCallstackSize();
+	// Debugging
+	int                SetLineCallback(asSFuncPtr callback, void *obj, int callConv);
+	void               ClearLineCallback();
+	asUINT             GetCallstackSize() const;
 	asIScriptFunction *GetFunction(asUINT stackLevel);
 	asIScriptFunction *GetFunction(asUINT stackLevel);
 	int                GetLineNumber(asUINT stackLevel, int *column, const char **sectionName);
 	int                GetLineNumber(asUINT stackLevel, int *column, const char **sectionName);
 	int                GetVarCount(asUINT stackLevel);
 	int                GetVarCount(asUINT stackLevel);
@@ -116,6 +125,7 @@ public:
     void              *GetThisPointer(asUINT stackLevel);
     void              *GetThisPointer(asUINT stackLevel);
 	asIScriptFunction *GetSystemFunction();
 	asIScriptFunction *GetSystemFunction();
 
 
+	// User data
 	void *SetUserData(void *data);
 	void *SetUserData(void *data);
 	void *GetUserData() const;
 	void *GetUserData() const;
 
 
@@ -146,52 +156,59 @@ public:
 	void CallInterfaceMethod(asCScriptFunction *func);
 	void CallInterfaceMethod(asCScriptFunction *func);
 	void PrepareScriptFunction();
 	void PrepareScriptFunction();
 
 
+	bool ReserveStackSpace(asUINT size);
+
 	void SetInternalException(const char *descr);
 	void SetInternalException(const char *descr);
 
 
 	// Must be protected for multiple accesses
 	// Must be protected for multiple accesses
-	mutable asCAtomic refCount;
+	mutable asCAtomic m_refCount;
 
 
-	bool holdEngineRef;
-	asCScriptEngine *engine;
+	bool             m_holdEngineRef;
+	asCScriptEngine *m_engine;
 
 
-	asEContextState status;
-	bool doSuspend;
-	bool doAbort;
-	bool externalSuspendRequest;
+	asEContextState m_status;
+	bool            m_doSuspend;
+	bool            m_doAbort;
+	bool            m_externalSuspendRequest;
 
 
-	asCScriptFunction *currentFunction;
-	asCScriptFunction *callingSystemFunction;
-	bool isStackMemoryNotAllocated;
+	asCScriptFunction *m_currentFunction;
+	asCScriptFunction *m_callingSystemFunction;
 
 
-	asCArray<size_t> callStack;
-	asCArray<asDWORD *> stackBlocks;
-	int stackBlockSize;
-	int stackIndex;
+	// The call stack holds program pointer, stack pointer, etc for caller functions
+	asCArray<size_t>    m_callStack;
 
 
-	bool inExceptionHandler;
-	asCString exceptionString;
-	int exceptionFunction;
-	int exceptionLine;
-	int exceptionColumn;
+	// Dynamically growing local stack
+	asCArray<asDWORD *> m_stackBlocks;
+	asUINT              m_stackBlockSize;
+	asUINT              m_stackIndex;
+	asDWORD            *m_originalStackPointer;
 
 
-	int returnValueSize;
-	int argumentsSize;
+	// Exception handling
+	bool      m_isStackMemoryNotAllocated;
+	bool      m_inExceptionHandler;
+	asCString m_exceptionString;
+	int       m_exceptionFunction;
+	int       m_exceptionLine;
+	int       m_exceptionColumn;
 
 
-	asCScriptFunction *initialFunction;
+	// The last prepared function, and some cached values related to it
+	asCScriptFunction *m_initialFunction;
+	int                m_returnValueSize;
+	int                m_argumentsSize;
 
 
 	// callbacks
 	// callbacks
-	bool lineCallback;
-	asSSystemFunctionInterface lineCallbackFunc;
-	void *lineCallbackObj;
+	bool                       m_lineCallback;
+	asSSystemFunctionInterface m_lineCallbackFunc;
+	void *                     m_lineCallbackObj;
 
 
-	bool exceptionCallback;
-	asSSystemFunctionInterface exceptionCallbackFunc;
-	void *exceptionCallbackObj;
+	bool                       m_exceptionCallback;
+	asSSystemFunctionInterface m_exceptionCallbackFunc;
+	void *                     m_exceptionCallbackObj;
 
 
-	void *userData;
+	void *m_userData;
 
 
 	// Registers available to JIT compiler functions
 	// Registers available to JIT compiler functions
-	asSVMRegisters regs;
+	asSVMRegisters m_regs;
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

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

@@ -52,6 +52,12 @@ BEGIN_AS_NAMESPACE
 inline bool tryEnter() { return true; }
 inline bool tryEnter() { return true; }
 #define TRYENTERCRITICALSECTION(x) tryEnter()
 #define TRYENTERCRITICALSECTION(x) tryEnter()
 
 
+#define DECLAREREADWRITELOCK(x)    
+#define ACQUIREEXCLUSIVE(x)        
+#define RELEASEEXCLUSIVE(x)        
+#define ACQUIRESHARED(x)           
+#define RELEASESHARED(x)           
+
 #else
 #else
 
 
 #define DECLARECRITICALSECTION(x)  asCThreadCriticalSection x;
 #define DECLARECRITICALSECTION(x)  asCThreadCriticalSection x;
@@ -59,6 +65,12 @@ inline bool tryEnter() { return true; }
 #define LEAVECRITICALSECTION(x)    x.Leave()
 #define LEAVECRITICALSECTION(x)    x.Leave()
 #define TRYENTERCRITICALSECTION(x) x.TryEnter()
 #define TRYENTERCRITICALSECTION(x) x.TryEnter()
 
 
+#define DECLAREREADWRITELOCK(x)    asCThreadReadWriteLock x;
+#define ACQUIREEXCLUSIVE(x)        x.AcquireExclusive()
+#define RELEASEEXCLUSIVE(x)        x.ReleaseExclusive()
+#define ACQUIRESHARED(x)           x.AcquireShared()
+#define RELEASESHARED(x)           x.ReleaseShared()
+
 #ifdef AS_POSIX_THREADS
 #ifdef AS_POSIX_THREADS
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE
@@ -76,7 +88,25 @@ public:
 	bool TryEnter();
 	bool TryEnter();
 
 
 protected:
 protected:
-	pthread_mutex_t criticalSection;
+	pthread_mutex_t cs;
+};
+
+class asCThreadReadWriteLock
+{
+public:
+	asCThreadReadWriteLock();
+	~asCThreadReadWriteLock();
+
+	void AcquireExclusive();
+	void ReleaseExclusive();
+	bool TryAcquireExclusive();
+
+	void AcquireShared();
+	void ReleaseShared();
+	bool TryAcquireShared();
+
+protected:
+	pthread_rwlock_t lock;
 };
 };
 
 
 #elif defined(AS_WINDOWS_THREADS)
 #elif defined(AS_WINDOWS_THREADS)
@@ -108,9 +138,45 @@ public:
 	bool TryEnter();
 	bool TryEnter();
 
 
 protected:
 protected:
-	CRITICAL_SECTION criticalSection;
+	CRITICAL_SECTION cs;
 };
 };
 
 
+class asCThreadReadWriteLock
+{
+public:
+	asCThreadReadWriteLock();
+	~asCThreadReadWriteLock();
+
+	void AcquireExclusive();
+	void ReleaseExclusive();
+
+	void AcquireShared();
+	void ReleaseShared();
+
+protected:
+	// The Slim Read Write Lock object, SRWLOCK, is more efficient 
+	// but it is only available from Windows Vista so we cannot use it and
+	// maintain compatibility with olders versions of Windows.
+
+	// Critical sections and semaphores are available on Windows XP and onwards. 
+	// Windows XP is oldest version we support with multithreading.
+	
+	// The implementation is based on the following article, that shows
+	// how to implement a fair read/write lock that doesn't risk starving
+	// the writers:
+
+	// http://doc.qt.nokia.com/qq/qq11-mutex.html
+
+	// TODO: Allow use of SRWLOCK through configuration in as_config.h
+
+	CRITICAL_SECTION    writeLock;
+	HANDLE              readLocks;
+};
+
+// This constant really should be a member of asCThreadReadWriteLock,
+// but it gives a compiler error on MSVC6 so I'm leaving it outside
+static const asUINT maxReaders = 10;
+
 #endif
 #endif
 
 
 #endif
 #endif

+ 6 - 0
ThirdParty/AngelScript/source/as_gc.cpp

@@ -58,6 +58,12 @@ asCGarbageCollector::asCGarbageCollector()
 
 
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 {
 {
+	if( obj == 0 || objType == 0 )
+	{
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GC_RECEIVED_NULL_PTR);
+		return;
+	}
+
 	engine->CallObjectMethod(obj, objType->beh.addref);
 	engine->CallObjectMethod(obj, objType->beh.addref);
 	asSObjTypePair ot = {obj, objType, 0};
 	asSObjTypePair ot = {obj, objType, 0};
 
 

+ 6 - 0
ThirdParty/AngelScript/source/as_generic.cpp

@@ -68,11 +68,14 @@ asIScriptEngine *asCGeneric::GetEngine() const
 	return (asIScriptEngine*)engine;
 	return (asIScriptEngine*)engine;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCGeneric::GetFunctionId() const
 int asCGeneric::GetFunctionId() const
 {
 {
 	return sysFunction->id;
 	return sysFunction->id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCGeneric::GetFunction() const
 asIScriptFunction *asCGeneric::GetFunction() const
@@ -80,11 +83,14 @@ asIScriptFunction *asCGeneric::GetFunction() const
 	return sysFunction;
 	return sysFunction;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 void *asCGeneric::GetFunctionUserData() const
 void *asCGeneric::GetFunctionUserData() const
 {
 {
 	return sysFunction->userData;
 	return sysFunction->userData;
 }
 }
+#endif
 
 
 // interface
 // interface
 void *asCGeneric::GetObject()
 void *asCGeneric::GetObject()

+ 4 - 1
ThirdParty/AngelScript/source/as_generic.h

@@ -54,9 +54,12 @@ public:
 //------------------------------
 //------------------------------
 	// Miscellaneous
 	// Miscellaneous
 	asIScriptEngine   *GetEngine() const;
 	asIScriptEngine   *GetEngine() const;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	int                GetFunctionId() const;
 	int                GetFunctionId() const;
-	asIScriptFunction *GetFunction() const;
 	void              *GetFunctionUserData() const;
 	void              *GetFunctionUserData() const;
+#endif
+	asIScriptFunction *GetFunction() const;
 
 
 	// Object
 	// Object
 	void   *GetObject();
 	void   *GetObject();

+ 7 - 1
ThirdParty/AngelScript/source/as_map.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2011 Andreas Jonsson
+   Copyright (c) 2003-2012 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -156,6 +156,12 @@ int asCMap<KEY, VAL>::Insert(const KEY &key, const VAL &value)
 {
 {
 	typedef asSMapNode<KEY,VAL> node_t;
 	typedef asSMapNode<KEY,VAL> node_t;
 	asSMapNode<KEY,VAL> *nnode = asNEW(node_t);
 	asSMapNode<KEY,VAL> *nnode = asNEW(node_t);
+	if( nnode == 0 )
+	{
+		// Out of memory
+		return -1;
+	}
+
 	nnode->key   = key;
 	nnode->key   = key;
 	nnode->value = value;
 	nnode->value = value;
 
 

+ 122 - 28
ThirdParty/AngelScript/source/as_module.cpp

@@ -158,7 +158,11 @@ int asCModule::AddScriptSection(const char *name, const char *code, size_t codeL
 	return asNOT_SUPPORTED;
 	return asNOT_SUPPORTED;
 #else
 #else
 	if( !builder )
 	if( !builder )
+	{
 		builder = asNEW(asCBuilder)(engine, this);
 		builder = asNEW(asCBuilder)(engine, this);
+		if( builder == 0 )
+			return asOUT_OF_MEMORY;
+	}
 
 
 	return builder->AddCode(name, code, (int)codeLength, lineOffset, (int)engine->GetScriptSectionNameIndex(name ? name : ""), engine->ep.copyScriptSections);
 	return builder->AddCode(name, code, (int)codeLength, lineOffset, (int)engine->GetScriptSectionNameIndex(name ? name : ""), engine->ep.copyScriptSections);
 #endif
 #endif
@@ -237,6 +241,8 @@ int asCModule::ResetGlobalVars(asIScriptContext *ctx)
 	return CallInit(ctx);
 	return CallInit(ctx);
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-20
 // interface
 // interface
 int asCModule::GetFunctionIdByIndex(asUINT index) const
 int asCModule::GetFunctionIdByIndex(asUINT index) const
 {
 {
@@ -245,6 +251,7 @@ int asCModule::GetFunctionIdByIndex(asUINT index) const
 
 
 	return globalFunctions[index]->id;
 	return globalFunctions[index]->id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
 asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
@@ -285,7 +292,7 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 					break;
 					break;
 			}
 			}
 
 
-			r = ctx->Prepare(scriptGlobals[n]->GetInitFunc()->id);
+			r = ctx->Prepare(scriptGlobals[n]->GetInitFunc());
 			if( r >= 0 )
 			if( r >= 0 )
 			{
 			{
 				r = ctx->Execute();
 				r = ctx->Execute();
@@ -410,12 +417,15 @@ void asCModule::InternalReset()
 	// Free bind information
 	// Free bind information
 	for( n = 0; n < bindInformations.GetLength(); n++ )
 	for( n = 0; n < bindInformations.GetLength(); n++ )
 	{
 	{
-		asUINT id = bindInformations[n]->importedFunctionSignature->id & 0xFFFF;
-		engine->importedFunctions[id] = 0;
-		engine->freeImportedFunctionIdxs.PushLast(id);
+		if( bindInformations[n] )
+		{
+			asUINT id = bindInformations[n]->importedFunctionSignature->id & 0xFFFF;
+			engine->importedFunctions[id] = 0;
+			engine->freeImportedFunctionIdxs.PushLast(id);
 
 
-		asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
-		asDELETE(bindInformations[n], sBindInfo);
+			asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
+			asDELETE(bindInformations[n], sBindInfo);
+		}
 	}
 	}
 	bindInformations.SetLength(0);
 	bindInformations.SetLength(0);
 
 
@@ -440,6 +450,8 @@ void asCModule::InternalReset()
 	funcDefs.SetLength(0);
 	funcDefs.SetLength(0);
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-20
 // interface
 // interface
 int asCModule::GetFunctionIdByName(const char *name) const
 int asCModule::GetFunctionIdByName(const char *name) const
 {
 {
@@ -462,15 +474,28 @@ int asCModule::GetFunctionIdByName(const char *name) const
 
 
 	return id;
 	return id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
 asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
 {
 {
-	int id = GetFunctionIdByName(name);
-	if( id < 0 )
-		return 0;
+	asIScriptFunction *func = 0;
+	for( size_t n = 0; n < globalFunctions.GetLength(); n++ )
+	{
+		if( globalFunctions[n]->name == name &&
+			globalFunctions[n]->nameSpace == defaultNamespace )
+		{
+			if( func == 0 )
+				func = globalFunctions[n];
+			else
+			{
+				// Multiple functions with the same name
+				return 0;
+			}
+		}
+	}
 
 
-	return engine->GetFunctionById(id);
+	return func;
 }
 }
 
 
 // interface
 // interface
@@ -527,6 +552,8 @@ asUINT asCModule::GetFunctionCount() const
 	return (asUINT)globalFunctions.GetLength();
 	return (asUINT)globalFunctions.GetLength();
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-20
 // interface
 // interface
 int asCModule::GetFunctionIdByDecl(const char *decl) const
 int asCModule::GetFunctionIdByDecl(const char *decl) const
 {
 {
@@ -575,12 +602,58 @@ int asCModule::GetFunctionIdByDecl(const char *decl) const
 
 
 	return id;
 	return id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
 asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
 {
 {
-	int id = GetFunctionIdByDecl(decl);
-	return engine->GetFunctionById(id);
+	asCBuilder bld(engine, const_cast<asCModule*>(this));
+
+	asCScriptFunction func(engine, const_cast<asCModule*>(this), asFUNC_DUMMY);
+	int r = bld.ParseFunctionDeclaration(0, decl, &func, false);
+	if( r < 0 )
+	{
+		// Invalid declaration
+		// TODO: Write error to message stream
+		return 0;
+	}
+
+	// Use the defaultNamespace implicitly unless an explicit namespace has been provided
+	asCString ns = func.nameSpace == "" ? defaultNamespace : func.nameSpace;
+
+	// TODO: optimize: Improve linear search
+	// Search script functions for matching interface
+	asIScriptFunction *f = 0;
+	for( size_t n = 0; n < globalFunctions.GetLength(); ++n )
+	{
+		if( globalFunctions[n]->objectType  == 0 && 
+			func.name                       == globalFunctions[n]->name && 
+			func.returnType                 == globalFunctions[n]->returnType &&
+			func.parameterTypes.GetLength() == globalFunctions[n]->parameterTypes.GetLength() &&
+			ns                              == globalFunctions[n]->nameSpace )
+		{
+			bool match = true;
+			for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
+			{
+				if( func.parameterTypes[p] != globalFunctions[n]->parameterTypes[p] )
+				{
+					match = false;
+					break;
+				}
+			}
+
+			if( match )
+			{
+				if( f == 0 )
+					f = globalFunctions[n];
+				else
+					// Multiple functions
+					return 0;
+			}
+		}
+	}
+
+	return f;
 }
 }
 
 
 // interface
 // interface
@@ -830,6 +903,9 @@ int asCModule::AddScriptFunction(int sectionIdx, int id, const char *name, const
 
 
 	// Store the function information
 	// Store the function information
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, isInterface ? asFUNC_INTERFACE : asFUNC_SCRIPT);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, isInterface ? asFUNC_INTERFACE : asFUNC_SCRIPT);
+	if( func == 0 )
+		return asOUT_OF_MEMORY;
+
 	func->name             = name;
 	func->name             = name;
 	func->nameSpace        = ns;
 	func->nameSpace        = ns;
 	func->id               = id;
 	func->id               = id;
@@ -890,6 +966,9 @@ int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &
 
 
 	// Store the function information
 	// Store the function information
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, asFUNC_IMPORTED);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, asFUNC_IMPORTED);
+	if( func == 0 )
+		return asOUT_OF_MEMORY;
+
 	func->name       = name;
 	func->name       = name;
 	func->id         = id;
 	func->id         = id;
 	func->returnType = returnType;
 	func->returnType = returnType;
@@ -901,6 +980,9 @@ int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &
 	func->objectType = 0;
 	func->objectType = 0;
 
 
 	sBindInfo *info = asNEW(sBindInfo);
 	sBindInfo *info = asNEW(sBindInfo);
+	if( info == 0 )
+		return asOUT_OF_MEMORY;
+
 	info->importedFunctionSignature = func;
 	info->importedFunctionSignature = func;
 	info->boundFunctionId = -1;
 	info->boundFunctionId = -1;
 	info->importFromModule = moduleName;
 	info->importFromModule = moduleName;
@@ -922,7 +1004,7 @@ asCScriptFunction *asCModule::GetImportedFunction(int index) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::BindImportedFunction(asUINT index, int sourceId)
+int asCModule::BindImportedFunction(asUINT index, asIScriptFunction *func)
 {
 {
 	// First unbind the old function
 	// First unbind the old function
 	int r = UnbindImportedFunction(index);
 	int r = UnbindImportedFunction(index);
@@ -932,7 +1014,10 @@ int asCModule::BindImportedFunction(asUINT index, int sourceId)
 	asCScriptFunction *dst = GetImportedFunction(index);
 	asCScriptFunction *dst = GetImportedFunction(index);
 	if( dst == 0 ) return asNO_FUNCTION;
 	if( dst == 0 ) return asNO_FUNCTION;
 
 
-	asCScriptFunction *src = engine->GetScriptFunction(sourceId);
+	if( func == 0 )
+		return asINVALID_ARG;
+
+	asCScriptFunction *src = engine->GetScriptFunction(func->GetId());
 	if( src == 0 ) 
 	if( src == 0 ) 
 		return asNO_FUNCTION;
 		return asNO_FUNCTION;
 
 
@@ -949,8 +1034,8 @@ int asCModule::BindImportedFunction(asUINT index, int sourceId)
 			return asINVALID_INTERFACE;
 			return asINVALID_INTERFACE;
 	}
 	}
 
 
-	bindInformations[index]->boundFunctionId = sourceId;
-	engine->scriptFunctions[sourceId]->AddRef();
+	bindInformations[index]->boundFunctionId = src->GetId();
+	src->AddRef();
 
 
 	return asSUCCESS;
 	return asSUCCESS;
 }
 }
@@ -962,11 +1047,14 @@ int asCModule::UnbindImportedFunction(asUINT index)
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 
 
 	// Remove reference to old module
 	// Remove reference to old module
-	int oldFuncID = bindInformations[index]->boundFunctionId;
-	if( oldFuncID != -1 )
+	if( bindInformations[index] )
 	{
 	{
-		bindInformations[index]->boundFunctionId = -1;
-		engine->scriptFunctions[oldFuncID]->Release();
+		int oldFuncID = bindInformations[index]->boundFunctionId;
+		if( oldFuncID != -1 )
+		{
+			bindInformations[index]->boundFunctionId = -1;
+			engine->scriptFunctions[oldFuncID]->Release();
+		}
 	}
 	}
 
 
 	return asSUCCESS;
 	return asSUCCESS;
@@ -1002,25 +1090,25 @@ int asCModule::BindAllImportedFunctions()
 	int c = GetImportedFunctionCount();
 	int c = GetImportedFunctionCount();
 	for( int n = 0; n < c; ++n )
 	for( int n = 0; n < c; ++n )
 	{
 	{
-		asCScriptFunction *func = GetImportedFunction(n);
-		if( func == 0 ) return asERROR;
+		asCScriptFunction *importFunc = GetImportedFunction(n);
+		if( importFunc == 0 ) return asERROR;
 
 
-		asCString str = func->GetDeclarationStr();
+		asCString str = importFunc->GetDeclarationStr();
 
 
 		// Get module name from where the function should be imported
 		// Get module name from where the function should be imported
 		const char *moduleName = GetImportedFunctionSourceModule(n);
 		const char *moduleName = GetImportedFunctionSourceModule(n);
 		if( moduleName == 0 ) return asERROR;
 		if( moduleName == 0 ) return asERROR;
 
 
 		asCModule *srcMod = engine->GetModule(moduleName, false);
 		asCModule *srcMod = engine->GetModule(moduleName, false);
-		int funcId = -1;
+		asIScriptFunction *func = 0;
 		if( srcMod )
 		if( srcMod )
-			funcId = srcMod->GetFunctionIdByDecl(str.AddressOf());
+			func = srcMod->GetFunctionByDecl(str.AddressOf());
 
 
-		if( funcId < 0 )
+		if( func == 0 )
 			notAllFunctionsWereBound = true;
 			notAllFunctionsWereBound = true;
 		else
 		else
 		{
 		{
-			if( BindImportedFunction(n, funcId) < 0 )
+			if( BindImportedFunction(n, func) < 0 )
 				notAllFunctionsWereBound = true;
 				notAllFunctionsWereBound = true;
 		}
 		}
 	}
 	}
@@ -1528,7 +1616,7 @@ int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int l
 			if( r < 0 )
 			if( r < 0 )
 				return r;
 				return r;
 
 
-			r = ctx->Prepare(prop->GetInitFunc()->id);
+			r = ctx->Prepare(prop->GetInitFunc());
 			if( r >= 0 )
 			if( r >= 0 )
 				r = ctx->Execute();
 				r = ctx->Execute();
 
 
@@ -1597,6 +1685,8 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
 #endif
 #endif
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-20
 // interface
 // interface
 int asCModule::RemoveFunction(int funcId)
 int asCModule::RemoveFunction(int funcId)
 {
 {
@@ -1605,6 +1695,7 @@ int asCModule::RemoveFunction(int funcId)
 
 
 	return asNO_FUNCTION;
 	return asNO_FUNCTION;
 }
 }
+#endif
 
 
 // interface
 // interface
 int asCModule::RemoveFunction(asIScriptFunction *func)
 int asCModule::RemoveFunction(asIScriptFunction *func)
@@ -1628,6 +1719,9 @@ int asCModule::RemoveFunction(asIScriptFunction *func)
 int asCModule::AddFuncDef(const char *name, const asCString &ns)
 int asCModule::AddFuncDef(const char *name, const asCString &ns)
 {
 {
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
+	if( func == 0 )
+		return asOUT_OF_MEMORY;
+
 	func->name      = name;
 	func->name      = name;
 	func->nameSpace = ns;
 	func->nameSpace = ns;
 
 

+ 7 - 3
ThirdParty/AngelScript/source/as_module.h

@@ -107,15 +107,19 @@ public:
 
 
 	// Script functions
 	// Script functions
 	virtual asUINT             GetFunctionCount() const;
 	virtual asUINT             GetFunctionCount() const;
-	// TODO: interface: Deprecate the functions that return the function id
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
+#endif
 	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const;
 	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const;
 	virtual asIScriptFunction *GetFunctionByName(const char *name) const;
 	virtual asIScriptFunction *GetFunctionByName(const char *name) const;
-	// TODO: interface: Deprecate RemoveFunction(int)
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                RemoveFunction(int funcId);
 	virtual int                RemoveFunction(int funcId);
+#endif
 	virtual int                RemoveFunction(asIScriptFunction *func);
 	virtual int                RemoveFunction(asIScriptFunction *func);
 
 
 	// Script global variables
 	// Script global variables
@@ -150,7 +154,7 @@ public:
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const;
 	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const;
 	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const;
 	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const;
 	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const;
-	virtual int         BindImportedFunction(asUINT index, int sourceID);
+	virtual int         BindImportedFunction(asUINT index, asIScriptFunction *func);
 	virtual int         UnbindImportedFunction(asUINT importIndex);
 	virtual int         UnbindImportedFunction(asUINT importIndex);
 	virtual int         BindAllImportedFunctions();
 	virtual int         BindAllImportedFunctions();
 	virtual int         UnbindAllImportedFunctions();
 	virtual int         UnbindAllImportedFunctions();

+ 143 - 29
ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -131,8 +131,6 @@ asCObjectType::asCObjectType()
 	acceptRefSubType   = true;
 	acceptRefSubType   = true;
 
 
 	accessMask = 0xFFFFFFFF;
 	accessMask = 0xFFFFFFFF;
-
-	userData = 0;
 }
 }
 
 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
@@ -145,8 +143,6 @@ asCObjectType::asCObjectType(asCScriptEngine *engine)
 	acceptRefSubType = true;
 	acceptRefSubType = true;
 
 
 	accessMask = 0xFFFFFFFF;
 	accessMask = 0xFFFFFFFF;
-
-	userData = 0;
 }
 }
 
 
 int asCObjectType::AddRef() const
 int asCObjectType::AddRef() const
@@ -161,16 +157,54 @@ int asCObjectType::Release() const
 	return refCount.atomicDec();
 	return refCount.atomicDec();
 }
 }
 
 
-void *asCObjectType::SetUserData(void *data)
+void *asCObjectType::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;
 }
 }
 
 
-void *asCObjectType::GetUserData() const
+void *asCObjectType::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;
 }
 }
 
 
 int asCObjectType::GetRefCount()
 int asCObjectType::GetRefCount()
@@ -224,8 +258,15 @@ asCObjectType::~asCObjectType()
 	enumValues.SetLength(0);
 	enumValues.SetLength(0);
 
 
 	// Clean the user data
 	// Clean the user data
-	if( userData && engine->cleanObjectTypeFunc )
-		engine->cleanObjectTypeFunc(this);
+	for( n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n+1] )
+		{
+			for( asUINT c = 0; c < engine->cleanObjectTypeFuncs.GetLength(); c++ )
+				if( engine->cleanObjectTypeFuncs[c].type == userData[n] )
+					engine->cleanObjectTypeFuncs[c].cleanFunc(this);
+		}
+	}
 }
 }
 
 
 // interface
 // interface
@@ -358,6 +399,8 @@ asUINT asCObjectType::GetFactoryCount() const
 	return (asUINT)beh.factories.GetLength();
 	return (asUINT)beh.factories.GetLength();
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 {
 {
@@ -366,6 +409,7 @@ int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 
 
 	return beh.factories[index];
 	return beh.factories[index];
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetFactoryByIndex(asUINT index) const
 asIScriptFunction *asCObjectType::GetFactoryByIndex(asUINT index) const
@@ -376,6 +420,8 @@ asIScriptFunction *asCObjectType::GetFactoryByIndex(asUINT index) const
 	return engine->GetFunctionById(beh.factories[index]);
 	return engine->GetFunctionById(beh.factories[index]);
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 {
 {
@@ -385,6 +431,7 @@ int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 	// Let the engine parse the string and find the appropriate factory function
 	// Let the engine parse the string and find the appropriate factory function
 	return engine->GetFactoryIdByDecl(this, decl);
 	return engine->GetFactoryIdByDecl(this, decl);
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetFactoryByDecl(const char *decl) const
 asIScriptFunction *asCObjectType::GetFactoryByDecl(const char *decl) const
@@ -402,6 +449,8 @@ asUINT asCObjectType::GetMethodCount() const
 	return (asUINT)methods.GetLength();
 	return (asUINT)methods.GetLength();
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 {
 {
@@ -417,13 +466,26 @@ int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 
 
 	return methods[index];
 	return methods[index];
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual) const
 asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual) const
 {
 {
-	return engine->GetFunctionById(GetMethodIdByIndex(index, getVirtual));
+	if( index >= methods.GetLength() )
+		return 0;
+
+	asCScriptFunction *func = engine->scriptFunctions[methods[index]];
+	if( !getVirtual )
+	{
+		if( func && func->funcType == asFUNC_VIRTUAL )
+			return virtualFunctionTable[func->vfTableIdx];
+	}
+
+	return func;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 {
 {
@@ -450,13 +512,37 @@ int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 
 
 	return id;
 	return id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
 asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
 {
 {
-	return engine->GetFunctionById(GetMethodIdByName(name, getVirtual));
+	int id = -1;
+	for( size_t n = 0; n < methods.GetLength(); n++ )
+	{
+		if( engine->scriptFunctions[methods[n]]->name == name )
+		{
+			if( id == -1 )
+				id = methods[n];
+			else
+				return 0;
+		}
+	}
+
+	if( id == -1 ) return 0;
+
+	asCScriptFunction *func = engine->scriptFunctions[id];
+	if( !getVirtual )
+	{
+		if( func && func->funcType == asFUNC_VIRTUAL )
+			return virtualFunctionTable[func->vfTableIdx];
+	}
+
+	return func;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-25
 // interface
 // interface
 int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 {
 {
@@ -480,11 +566,33 @@ int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 
 
 	return id;
 	return id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetMethodByDecl(const char *decl, bool getVirtual) const
 asIScriptFunction *asCObjectType::GetMethodByDecl(const char *decl, bool getVirtual) const
 {
 {
-	return engine->GetFunctionById(GetMethodIdByDecl(decl, getVirtual));
+	if( methods.GetLength() == 0 )
+		return 0;
+
+	// Get the module from one of the methods, but it will only be
+	// used to allow the parsing of types not already known by the object.
+	// It is possible for object types to be orphaned, e.g. by discarding 
+	// the module that created it. In this case it is still possible to 
+	// find the methods, but any type not known by the object will result in
+	// an invalid declaration.
+	asCModule *mod = engine->scriptFunctions[methods[0]]->module;
+	int id = engine->GetMethodIdByDecl(this, decl, mod);
+	if( id <= 0 )
+		return 0;
+
+	if( !getVirtual )
+	{
+		asCScriptFunction *func = engine->scriptFunctions[id];
+		if( func && func->funcType == asFUNC_VIRTUAL )
+			return virtualFunctionTable[func->vfTableIdx];
+	}
+
+	return engine->scriptFunctions[id];
 }
 }
 
 
 // interface
 // interface
@@ -562,7 +670,7 @@ asUINT asCObjectType::GetBehaviourCount() const
 	return count;
 	return count;
 }
 }
 
 
-int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const
+asIScriptFunction *asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const
 {
 {
 	// Find the correct behaviour
 	// Find the correct behaviour
 	asUINT count = 0;
 	asUINT count = 0;
@@ -570,61 +678,61 @@ int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour
 	if( beh.destruct && count++ == index ) // only increase count if the behaviour is registered
 	if( beh.destruct && count++ == index ) // only increase count if the behaviour is registered
 	{ 
 	{ 
 		if( outBehaviour ) *outBehaviour = asBEHAVE_DESTRUCT;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_DESTRUCT;
-		return beh.destruct;
+		return engine->scriptFunctions[beh.destruct];
 	}
 	}
 
 
 	if( beh.addref && count++ == index )
 	if( beh.addref && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ADDREF;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ADDREF;
-		return beh.addref;
+		return engine->scriptFunctions[beh.addref];
 	}
 	}
 
 
 	if( beh.release && count++ == index )
 	if( beh.release && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASE;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASE;
-		return beh.release;
+		return engine->scriptFunctions[beh.release];
 	}
 	}
 
 
 	if( beh.gcGetRefCount && count++ == index )
 	if( beh.gcGetRefCount && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETREFCOUNT;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETREFCOUNT;
-		return beh.gcGetRefCount;
+		return engine->scriptFunctions[beh.gcGetRefCount];
 	}
 	}
 
 
 	if( beh.gcSetFlag && count++ == index )
 	if( beh.gcSetFlag && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_SETGCFLAG;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_SETGCFLAG;
-		return beh.gcSetFlag;
+		return engine->scriptFunctions[beh.gcSetFlag];
 	}
 	}
 
 
 	if( beh.gcGetFlag && count++ == index )
 	if( beh.gcGetFlag && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETGCFLAG;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETGCFLAG;
-		return beh.gcGetFlag;
+		return engine->scriptFunctions[beh.gcGetFlag];
 	}
 	}
 
 
 	if( beh.gcEnumReferences && count++ == index )
 	if( beh.gcEnumReferences && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ENUMREFS;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ENUMREFS;
-		return beh.gcEnumReferences;
+		return engine->scriptFunctions[beh.gcEnumReferences];
 	}
 	}
 
 
 	if( beh.gcReleaseAllReferences && count++ == index )
 	if( beh.gcReleaseAllReferences && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASEREFS;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASEREFS;
-		return beh.gcReleaseAllReferences;
+		return engine->scriptFunctions[beh.gcReleaseAllReferences];
 	}
 	}
 
 
 	if( beh.templateCallback && count++ == index )
 	if( beh.templateCallback && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_TEMPLATE_CALLBACK;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_TEMPLATE_CALLBACK;
-		return beh.templateCallback;
+		return engine->scriptFunctions[beh.templateCallback];
 	}
 	}
 
 
 	if( beh.listFactory && count++ == index )
 	if( beh.listFactory && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_LIST_FACTORY;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_LIST_FACTORY;
-		return beh.listFactory;
+		return engine->scriptFunctions[beh.listFactory];
 	}
 	}
 
 
 	// For reference types, the factories are also stored in the constructor
 	// For reference types, the factories are also stored in the constructor
@@ -632,7 +740,7 @@ int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour
 	if( index - count < beh.constructors.GetLength() )
 	if( index - count < beh.constructors.GetLength() )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_CONSTRUCT;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_CONSTRUCT;
-		return beh.constructors[index - count];
+		return engine->scriptFunctions[beh.constructors[index - count]];
 	}
 	}
 	else 
 	else 
 		count += (asUINT)beh.constructors.GetLength();
 		count += (asUINT)beh.constructors.GetLength();
@@ -642,10 +750,10 @@ int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour
 		index = 2*(index - count);
 		index = 2*(index - count);
 
 
 		if( outBehaviour ) *outBehaviour = static_cast<asEBehaviours>(beh.operators[index]);
 		if( outBehaviour ) *outBehaviour = static_cast<asEBehaviours>(beh.operators[index]);
-		return beh.operators[index + 1];
+		return engine->scriptFunctions[beh.operators[index + 1]];
 	}
 	}
 
 
-	return asINVALID_ARG;
+	return 0;
 }
 }
 
 
 // interface
 // interface
@@ -672,6 +780,12 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
 
 
 	// Store the properties in the object type descriptor
 	// Store the properties in the object type descriptor
 	asCObjectProperty *prop = asNEW(asCObjectProperty);
 	asCObjectProperty *prop = asNEW(asCObjectProperty);
+	if( prop == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
 	prop->name      = name;
 	prop->name      = name;
 	prop->type      = dt;
 	prop->type      = dt;
 	prop->isPrivate = isPrivate;
 	prop->isPrivate = isPrivate;

+ 15 - 9
ThirdParty/AngelScript/source/as_objecttype.h

@@ -64,9 +64,9 @@ const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
 // asOBJ_GC is used to indicate that the type can potentially 
 // asOBJ_GC is used to indicate that the type can potentially 
 // form circular references, thus is garbage collected.
 // form circular references, thus is garbage collected.
 
 
-// The fact that an object is garbage collected doesn't imply that an object that 
-// can references it also must be garbage collected, only if the garbage collected 
-// object can reference it as well.
+// 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 
 // 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 
 // behaviours are registered. For script types that contain any such type we 
@@ -159,16 +159,22 @@ public:
 
 
 	// Factories
 	// Factories
 	asUINT             GetFactoryCount() const;
 	asUINT             GetFactoryCount() const;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
+#endif
 	asIScriptFunction *GetFactoryByIndex(asUINT index) const;
 	asIScriptFunction *GetFactoryByIndex(asUINT index) const;
 	asIScriptFunction *GetFactoryByDecl(const char *decl) const;
 	asIScriptFunction *GetFactoryByDecl(const char *decl) const;
 
 
 	// Methods
 	// Methods
 	asUINT             GetMethodCount() const;
 	asUINT             GetMethodCount() const;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-25
 	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
+#endif
 	asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual) const;
 	asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual) const;
 	asIScriptFunction *GetMethodByName(const char *name, bool getVirtual) const;
 	asIScriptFunction *GetMethodByName(const char *name, bool getVirtual) const;
 	asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual) const;
 	asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual) const;
@@ -179,12 +185,12 @@ public:
 	const char *GetPropertyDeclaration(asUINT index) const;
 	const char *GetPropertyDeclaration(asUINT index) const;
 
 
 	// Behaviours
 	// Behaviours
-	asUINT GetBehaviourCount() const;
-	int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
+	asUINT             GetBehaviourCount() const;
+	asIScriptFunction *GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
 
 
 	// User data
 	// User data
-	void *SetUserData(void *data);
-	void *GetUserData() const;
+	void *SetUserData(void *data, asPWORD type);
+	void *GetUserData(asPWORD type) const;
 
 
 //===========================================
 //===========================================
 // Internal
 // Internal
@@ -227,8 +233,8 @@ public:
 	bool           acceptValueSubType;
 	bool           acceptValueSubType;
 	bool           acceptRefSubType;
 	bool           acceptRefSubType;
 
 
-	asCScriptEngine *engine;
-	void            *userData;
+	asCScriptEngine  *engine;
+	asCArray<asPWORD> userData;
 
 
 protected:
 protected:
 	mutable asCAtomic refCount;
 	mutable asCAtomic refCount;

+ 3 - 0
ThirdParty/AngelScript/source/as_outputbuffer.cpp

@@ -65,6 +65,9 @@ void asCOutputBuffer::Clear()
 void asCOutputBuffer::Callback(asSMessageInfo *msg)
 void asCOutputBuffer::Callback(asSMessageInfo *msg)
 {
 {
 	message_t *msgInfo = asNEW(message_t);
 	message_t *msgInfo = asNEW(message_t);
+	if( msgInfo == 0 )
+		return;
+
 	msgInfo->section = msg->section;
 	msgInfo->section = msg->section;
 	msgInfo->row = msg->row;
 	msgInfo->row = msg->row;
 	msgInfo->col = msg->col;
 	msgInfo->col = msg->col;

+ 179 - 71
ThirdParty/AngelScript/source/as_parser.cpp

@@ -117,13 +117,27 @@ int asCParser::ParseFunctionDefinition(asCScriptCode *script)
 	return 0;
 	return 0;
 }
 }
 
 
+asCScriptNode *asCParser::CreateNode(eScriptNode type)
+{
+	void *ptr = engine->memoryMgr.AllocScriptNode();
+	if( ptr == 0 )
+	{
+		// Out of memory
+		errorWhileParsing = true;
+		return 0;
+	}
+
+	return new(ptr) asCScriptNode(type);
+}
+
 int asCParser::ParseDataType(asCScriptCode *script, bool isReturnType)
 int asCParser::ParseDataType(asCScriptCode *script, bool isReturnType)
 {
 {
 	Reset();
 	Reset();
 
 
 	this->script = script;
 	this->script = script;
 
 
-	scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	scriptNode = CreateNode(snDataType);
+	if( scriptNode == 0 ) return -1;
 		
 		
 	scriptNode->AddChildLast(ParseType(true));
 	scriptNode->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return -1;
 	if( isSyntaxError ) return -1;
@@ -156,7 +170,8 @@ int asCParser::ParseTemplateDecl(asCScriptCode *script)
 	Reset();
 	Reset();
 
 
 	this->script = script;
 	this->script = script;
-	scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
+	scriptNode = CreateNode(snUndefined);
+	if( scriptNode == 0 ) return -1;
 
 
 	scriptNode->AddChildLast(ParseIdentifier());
 	scriptNode->AddChildLast(ParseIdentifier());
 	if( isSyntaxError ) return -1;
 	if( isSyntaxError ) return -1;
@@ -203,7 +218,8 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
 
 
 	this->script = script;
 	this->script = script;
 
 
-	scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
+	scriptNode = CreateNode(snDeclaration);
+	if( scriptNode == 0 ) return -1;
 
 
 	scriptNode->AddChildLast(ParseType(true));
 	scriptNode->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return -1;
 	if( isSyntaxError ) return -1;
@@ -250,7 +266,8 @@ void asCParser::ParseOptionalScope(asCScriptNode *node)
 
 
 asCScriptNode *asCParser::ParseFunctionDefinition()
 asCScriptNode *asCParser::ParseFunctionDefinition()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
+	asCScriptNode *node = CreateNode(snFunction);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseType(true));
 	node->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -278,7 +295,8 @@ asCScriptNode *asCParser::ParseFunctionDefinition()
 
 
 asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	asCScriptNode *node = CreateNode(snDataType);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 
 
@@ -317,7 +335,8 @@ asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 
 
 asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType)
 asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	asCScriptNode *node = CreateNode(snDataType);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 
 
@@ -403,7 +422,8 @@ asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType)
 
 
 asCScriptNode *asCParser::ParseToken(int token)
 asCScriptNode *asCParser::ParseToken(int token)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
+	asCScriptNode *node = CreateNode(snUndefined);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -422,7 +442,8 @@ asCScriptNode *asCParser::ParseToken(int token)
 
 
 asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
 asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
+	asCScriptNode *node = CreateNode(snUndefined);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -448,7 +469,8 @@ asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
 
 
 asCScriptNode *asCParser::ParseDataType(bool allowVariableType)
 asCScriptNode *asCParser::ParseDataType(bool allowVariableType)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	asCScriptNode *node = CreateNode(snDataType);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -475,7 +497,8 @@ asCScriptNode *asCParser::ParseDataType(bool allowVariableType)
 
 
 asCScriptNode *asCParser::ParseRealType()
 asCScriptNode *asCParser::ParseRealType()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	asCScriptNode *node = CreateNode(snDataType);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -494,7 +517,8 @@ asCScriptNode *asCParser::ParseRealType()
 
 
 asCScriptNode *asCParser::ParseIdentifier()
 asCScriptNode *asCParser::ParseIdentifier()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
+	asCScriptNode *node = CreateNode(snIdentifier);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -513,7 +537,8 @@ asCScriptNode *asCParser::ParseIdentifier()
 
 
 asCScriptNode *asCParser::ParseParameterList()
 asCScriptNode *asCParser::ParseParameterList()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snParameterList);
+	asCScriptNode *node = CreateNode(snParameterList);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -602,7 +627,8 @@ asCScriptNode *asCParser::ParseParameterList()
 
 
 asCScriptNode *asCParser::SuperficiallyParseExpression()
 asCScriptNode *asCParser::SuperficiallyParseExpression()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpression);
+	asCScriptNode *node = CreateNode(snExpression);
+	if( node == 0 ) return 0;
 
 
 	// Simply parse everything until the first , or ), whichever comes first. 
 	// Simply parse everything until the first , or ), whichever comes first. 
 	// Keeping in mind that () and {} can group expressions.
 	// Keeping in mind that () and {} can group expressions.
@@ -759,11 +785,10 @@ bool asCParser::IsDataType(const sToken &token)
 	{
 	{
 		if( checkValidTypes )
 		if( checkValidTypes )
 		{
 		{
-			// Check if this is a registered type
+			// Check if this is an existing type, regardless of namespace
 			asCString str;
 			asCString str;
 			str.Assign(&script->code[token.pos], token.length);
 			str.Assign(&script->code[token.pos], token.length);
-			// TODO: namespace: Should parser really keep track of namespace?
-			if( !builder->GetObjectType(str.AddressOf(), "") && !builder->GetFuncDef(str.AddressOf()) )
+			if( !builder->DoesTypeExist(str.AddressOf()) )
 				return false;
 				return false;
 		}
 		}
 		return true;
 		return true;
@@ -844,8 +869,26 @@ bool asCParser::CheckTemplateType(sToken &t)
 		if( t.type != ttLessThan )
 		if( t.type != ttLessThan )
 			return false;
 			return false;
 
 
-		// Now there must be a data type
+		// There might optionally be a 'const'
 		GetToken(&t);
 		GetToken(&t);
+		if( t.type == ttConst )
+			GetToken(&t);
+
+		// The type may be initiated with the scope operator
+		if( t.type == ttScope )
+			GetToken(&t);
+
+		// There may be multiple levels of scope operators
+		sToken t2;
+		GetToken(&t2);
+		while( t.type == ttIdentifier && t2.type == ttScope )
+		{
+			GetToken(&t);
+			GetToken(&t2);
+		}
+		RewindTo(&t2);
+
+		// Now there must be a data type
 		if( !IsDataType(t) )
 		if( !IsDataType(t) )
 			return false;
 			return false;
 
 
@@ -885,7 +928,8 @@ bool asCParser::CheckTemplateType(sToken &t)
 
 
 asCScriptNode *asCParser::ParseCast()
 asCScriptNode *asCParser::ParseCast()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCast);
+	asCScriptNode *node = CreateNode(snCast);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -942,7 +986,8 @@ asCScriptNode *asCParser::ParseCast()
 
 
 asCScriptNode *asCParser::ParseExprValue()
 asCScriptNode *asCParser::ParseExprValue()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprValue);
+	asCScriptNode *node = CreateNode(snExprValue);
+	if( node == 0 ) return 0;
 
 
 	sToken t1, t2;
 	sToken t1, t2;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -987,7 +1032,8 @@ asCScriptNode *asCParser::ParseExprValue()
 
 
 asCScriptNode *asCParser::ParseConstant()
 asCScriptNode *asCParser::ParseConstant()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
+	asCScriptNode *node = CreateNode(snConstant);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1017,7 +1063,8 @@ asCScriptNode *asCParser::ParseConstant()
 
 
 asCScriptNode *asCParser::ParseStringConstant()
 asCScriptNode *asCParser::ParseStringConstant()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
+	asCScriptNode *node = CreateNode(snConstant);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1035,7 +1082,8 @@ asCScriptNode *asCParser::ParseStringConstant()
 
 
 asCScriptNode *asCParser::ParseFunctionCall()
 asCScriptNode *asCParser::ParseFunctionCall()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunctionCall);
+	asCScriptNode *node = CreateNode(snFunctionCall);
+	if( node == 0 ) return 0;
 
 
 	// Parse scope prefix
 	// Parse scope prefix
 	ParseOptionalScope(node);
 	ParseOptionalScope(node);
@@ -1051,7 +1099,8 @@ asCScriptNode *asCParser::ParseFunctionCall()
 
 
 asCScriptNode *asCParser::ParseVariableAccess()
 asCScriptNode *asCParser::ParseVariableAccess()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVariableAccess);
+	asCScriptNode *node = CreateNode(snVariableAccess);
+	if( node == 0 ) return 0;
 
 
 	// Parse scope prefix
 	// Parse scope prefix
 	ParseOptionalScope(node);
 	ParseOptionalScope(node);
@@ -1064,7 +1113,8 @@ asCScriptNode *asCParser::ParseVariableAccess()
 
 
 asCScriptNode *asCParser::ParseConstructCall()
 asCScriptNode *asCParser::ParseConstructCall()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstructCall);
+	asCScriptNode *node = CreateNode(snConstructCall);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseType(false));
 	node->AddChildLast(ParseType(false));
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -1076,7 +1126,8 @@ asCScriptNode *asCParser::ParseConstructCall()
 
 
 asCScriptNode *asCParser::ParseArgList()
 asCScriptNode *asCParser::ParseArgList()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snArgList);
+	asCScriptNode *node = CreateNode(snArgList);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -1162,7 +1213,8 @@ bool asCParser::IsFunctionCall()
 
 
 asCScriptNode *asCParser::ParseAssignment()
 asCScriptNode *asCParser::ParseAssignment()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snAssignment);
+	asCScriptNode *node = CreateNode(snAssignment);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseCondition());
 	node->AddChildLast(ParseCondition());
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -1185,7 +1237,8 @@ asCScriptNode *asCParser::ParseAssignment()
 
 
 asCScriptNode *asCParser::ParseCondition()
 asCScriptNode *asCParser::ParseCondition()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCondition);
+	asCScriptNode *node = CreateNode(snCondition);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseExpression());
 	node->AddChildLast(ParseExpression());
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -1215,7 +1268,8 @@ asCScriptNode *asCParser::ParseCondition()
 
 
 asCScriptNode *asCParser::ParseExpression()
 asCScriptNode *asCParser::ParseExpression()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpression);
+	asCScriptNode *node = CreateNode(snExpression);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseExprTerm());
 	node->AddChildLast(ParseExprTerm());
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -1240,7 +1294,8 @@ asCScriptNode *asCParser::ParseExpression()
 
 
 asCScriptNode *asCParser::ParseExprTerm()
 asCScriptNode *asCParser::ParseExprTerm()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprTerm);
+	asCScriptNode *node = CreateNode(snExprTerm);
+	if( node == 0 ) return 0;
 
 
 	for(;;)
 	for(;;)
 	{
 	{
@@ -1274,7 +1329,8 @@ asCScriptNode *asCParser::ParseExprTerm()
 
 
 asCScriptNode *asCParser::ParseExprPreOp()
 asCScriptNode *asCParser::ParseExprPreOp()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprPreOp);
+	asCScriptNode *node = CreateNode(snExprPreOp);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1292,7 +1348,8 @@ asCScriptNode *asCParser::ParseExprPreOp()
 
 
 asCScriptNode *asCParser::ParseExprPostOp()
 asCScriptNode *asCParser::ParseExprPostOp()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprPostOp);
+	asCScriptNode *node = CreateNode(snExprPostOp);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1335,7 +1392,8 @@ asCScriptNode *asCParser::ParseExprPostOp()
 
 
 asCScriptNode *asCParser::ParseExprOperator()
 asCScriptNode *asCParser::ParseExprOperator()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprOperator);
+	asCScriptNode *node = CreateNode(snExprOperator);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1353,7 +1411,8 @@ asCScriptNode *asCParser::ParseExprOperator()
 
 
 asCScriptNode *asCParser::ParseAssignOperator()
 asCScriptNode *asCParser::ParseAssignOperator()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprOperator);
+	asCScriptNode *node = CreateNode(snExprOperator);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1486,7 +1545,8 @@ int asCParser::ParseExpression(asCScriptCode *script)
 
 
 asCScriptNode *asCParser::ParseImport()
 asCScriptNode *asCParser::ParseImport()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snImport);
+	asCScriptNode *node = CreateNode(snImport);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -1526,7 +1586,9 @@ asCScriptNode *asCParser::ParseImport()
 		return node;
 		return node;
 	}
 	}
 
 
-	asCScriptNode *mod = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
+	asCScriptNode *mod = CreateNode(snConstant);
+	if( mod == 0 ) return 0;
+
 	node->AddChildLast(mod);
 	node->AddChildLast(mod);
 
 
 	mod->SetToken(&t);
 	mod->SetToken(&t);
@@ -1546,7 +1608,8 @@ asCScriptNode *asCParser::ParseImport()
 
 
 asCScriptNode *asCParser::ParseScript(bool inBlock)
 asCScriptNode *asCParser::ParseScript(bool inBlock)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snScript);
+	asCScriptNode *node = CreateNode(snScript);
+	if( node == 0 ) return 0;
 
 
 	// Determine type of node
 	// Determine type of node
 	sToken t1, t2;
 	sToken t1, t2;
@@ -1639,7 +1702,8 @@ asCScriptNode *asCParser::ParseScript(bool inBlock)
 
 
 asCScriptNode *asCParser::ParseNamespace()
 asCScriptNode *asCParser::ParseNamespace()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snNamespace);
+	asCScriptNode *node = CreateNode(snNamespace);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -1696,7 +1760,8 @@ asCScriptNode *asCParser::ParseEnumeration()
 	asCScriptNode *ident;
 	asCScriptNode *ident;
 	asCScriptNode *dataType;
 	asCScriptNode *dataType;
 
 
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snEnum);
+	asCScriptNode *node = CreateNode(snEnum);
+	if( node == 0 ) return 0;
 
 
 	sToken	token;
 	sToken	token;
 
 
@@ -1729,10 +1794,14 @@ asCScriptNode *asCParser::ParseEnumeration()
 		return node;
 		return node;
 	}
 	}
 
 
-	dataType = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
+	dataType = CreateNode(snDataType);
+	if( dataType == 0 ) return 0;
+
 	node->AddChildLast(dataType);
 	node->AddChildLast(dataType);
 
 
-	ident = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
+	ident = CreateNode(snIdentifier);
+	if( ident == 0 ) return 0;
+
 	ident->SetToken(&token);
 	ident->SetToken(&token);
 	ident->UpdateSourcePos(token.pos, token.length);
 	ident->UpdateSourcePos(token.pos, token.length);
 	dataType->AddChildLast(ident);
 	dataType->AddChildLast(ident);
@@ -1763,7 +1832,9 @@ asCScriptNode *asCParser::ParseEnumeration()
 		}
 		}
 
 
 		//	Add the enum element
 		//	Add the enum element
-		ident = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
+		ident = CreateNode(snIdentifier);
+		if( ident == 0 ) return 0;
+
 		ident->SetToken(&token);
 		ident->SetToken(&token);
 		ident->UpdateSourcePos(token.pos, token.length);
 		ident->UpdateSourcePos(token.pos, token.length);
 		node->AddChildLast(ident);
 		node->AddChildLast(ident);
@@ -2102,7 +2173,8 @@ bool asCParser::IsFuncDecl(bool isMethod)
 
 
 asCScriptNode *asCParser::ParseFuncDef()
 asCScriptNode *asCParser::ParseFuncDef()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFuncDef);
+	asCScriptNode *node = CreateNode(snFuncDef);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -2140,7 +2212,8 @@ asCScriptNode *asCParser::ParseFuncDef()
 
 
 asCScriptNode *asCParser::ParseFunction(bool isMethod)
 asCScriptNode *asCParser::ParseFunction(bool isMethod)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
+	asCScriptNode *node = CreateNode(snFunction);
+	if( node == 0 ) return 0;
 
 
 	sToken t1,t2;
 	sToken t1,t2;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -2206,7 +2279,8 @@ asCScriptNode *asCParser::ParseFunction(bool isMethod)
 
 
 asCScriptNode *asCParser::ParseInterfaceMethod()
 asCScriptNode *asCParser::ParseInterfaceMethod()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
+	asCScriptNode *node = CreateNode(snFunction);
+	if( node == 0 ) return 0;
 
 
 	node->AddChildLast(ParseType(true));
 	node->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return node;
 	if( isSyntaxError ) return node;
@@ -2241,7 +2315,8 @@ asCScriptNode *asCParser::ParseInterfaceMethod()
 
 
 asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
 asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVirtualProperty);
+	asCScriptNode *node = CreateNode(snVirtualProperty);
+	if( node == 0 ) return 0;
 
 
 	sToken t1,t2;
 	sToken t1,t2;
 	GetToken(&t1);
 	GetToken(&t1);
@@ -2278,7 +2353,9 @@ asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterfa
 
 
 		if( IdentifierIs(t1, GET_TOKEN) || IdentifierIs(t1, SET_TOKEN) )
 		if( IdentifierIs(t1, GET_TOKEN) || IdentifierIs(t1, SET_TOKEN) )
 		{
 		{
-			accessorNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVirtualProperty);
+			accessorNode = CreateNode(snVirtualProperty);
+			if( accessorNode == 0 ) return 0;
+
 			node->AddChildLast(accessorNode);
 			node->AddChildLast(accessorNode);
 
 
 			RewindTo(&t1);
 			RewindTo(&t1);
@@ -2340,7 +2417,8 @@ asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterfa
 
 
 asCScriptNode *asCParser::ParseInterface()
 asCScriptNode *asCParser::ParseInterface()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snInterface);
+	asCScriptNode *node = CreateNode(snInterface);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -2413,7 +2491,8 @@ asCScriptNode *asCParser::ParseInterface()
 
 
 asCScriptNode *asCParser::ParseClass()
 asCScriptNode *asCParser::ParseClass()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snClass);
+	asCScriptNode *node = CreateNode(snClass);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -2492,7 +2571,9 @@ asCScriptNode *asCParser::ParseClass()
 		else if( IsVarDecl() )
 		else if( IsVarDecl() )
 		{
 		{
 			// Parse a property declaration
 			// Parse a property declaration
-			asCScriptNode *prop = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
+			asCScriptNode *prop = CreateNode(snDeclaration);
+			if( prop == 0 ) return 0;
+
 			node->AddChildLast(prop);
 			node->AddChildLast(prop);
 
 
 			// A variable declaration can be preceded by 'private'
 			// A variable declaration can be preceded by 'private'
@@ -2536,7 +2617,8 @@ asCScriptNode *asCParser::ParseClass()
 
 
 asCScriptNode *asCParser::ParseGlobalVar()
 asCScriptNode *asCParser::ParseGlobalVar()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snGlobalVar);
+	asCScriptNode *node = CreateNode(snGlobalVar);
+	if( node == 0 ) return 0;
 
 
 	// Parse data type
 	// Parse data type
 	node->AddChildLast(ParseType(true));
 	node->AddChildLast(ParseType(true));
@@ -2611,6 +2693,15 @@ int asCParser::ParseGlobalVarInit(asCScriptCode *script, asCScriptNode *init)
 		Error(ExpectedOneOf(tokens, 2).AddressOf(), &t);
 		Error(ExpectedOneOf(tokens, 2).AddressOf(), &t);
 	}
 	}
 
 
+	// Don't allow any more tokens after the expression
+	GetToken(&t);
+	if( t.type != ttEnd && t.type != ttEndStatement && t.type != ttListSeparator && t.type != ttEndStatementBlock )
+	{
+		asCString msg;
+		msg.Format(TXT_UNEXPECTED_TOKEN_s, asCTokenizer::GetDefinition(t.type));
+		Error(msg.AddressOf(), &t);
+	}
+
 	if( isSyntaxError || errorWhileParsing )
 	if( isSyntaxError || errorWhileParsing )
 		return -1;
 		return -1;
 
 
@@ -2619,7 +2710,8 @@ int asCParser::ParseGlobalVarInit(asCScriptCode *script, asCScriptNode *init)
 
 
 asCScriptNode *asCParser::SuperficiallyParseGlobalVarInit()
 asCScriptNode *asCParser::SuperficiallyParseGlobalVarInit()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snAssignment);
+	asCScriptNode *node = CreateNode(snAssignment);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -2697,7 +2789,8 @@ asCScriptNode *asCParser::SuperficiallyParseGlobalVarInit()
 
 
 asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
 asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snStatementBlock);
+	asCScriptNode *node = CreateNode(snStatementBlock);
+	if( node == 0 ) return 0;
 
 
 	// This function will only superficially parse the statement block in order to find the end of it
 	// This function will only superficially parse the statement block in order to find the end of it
 	sToken t1;
 	sToken t1;
@@ -2730,7 +2823,8 @@ asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
 
 
 asCScriptNode *asCParser::ParseStatementBlock()
 asCScriptNode *asCParser::ParseStatementBlock()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snStatementBlock);
+	asCScriptNode *node = CreateNode(snStatementBlock);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -2807,7 +2901,8 @@ asCScriptNode *asCParser::ParseStatementBlock()
 
 
 asCScriptNode *asCParser::ParseInitList()
 asCScriptNode *asCParser::ParseInitList()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snInitList);
+	asCScriptNode *node = CreateNode(snInitList);
+	if( node == 0 ) return 0;
 
 
 	sToken t1;
 	sToken t1;
 
 
@@ -2837,13 +2932,13 @@ asCScriptNode *asCParser::ParseInitList()
 			if( t1.type == ttListSeparator )
 			if( t1.type == ttListSeparator )
 			{
 			{
 				// No expression 
 				// No expression 
-				node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
-
+				node->AddChildLast(CreateNode(snUndefined));
+				
 				GetToken(&t1);
 				GetToken(&t1);
 				if( t1.type == ttEndStatementBlock )
 				if( t1.type == ttEndStatementBlock )
 				{
 				{
 					// No expression
 					// No expression
-					node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
+					node->AddChildLast(CreateNode(snUndefined));
 					node->UpdateSourcePos(t1.pos, t1.length);
 					node->UpdateSourcePos(t1.pos, t1.length);
 					return node;
 					return node;
 				}
 				}
@@ -2852,7 +2947,7 @@ asCScriptNode *asCParser::ParseInitList()
 			else if( t1.type == ttEndStatementBlock )
 			else if( t1.type == ttEndStatementBlock )
 			{
 			{
 				// No expression 
 				// No expression 
-				node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
+				node->AddChildLast(CreateNode(snUndefined));
 
 
 				node->UpdateSourcePos(t1.pos, t1.length);
 				node->UpdateSourcePos(t1.pos, t1.length);
 
 
@@ -2911,7 +3006,8 @@ asCScriptNode *asCParser::ParseInitList()
 
 
 asCScriptNode *asCParser::ParseDeclaration()
 asCScriptNode *asCParser::ParseDeclaration()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
+	asCScriptNode *node = CreateNode(snDeclaration);
+	if( node == 0 ) return 0;
 
 
 	// Parse data type
 	// Parse data type
 	node->AddChildLast(ParseType(true));
 	node->AddChildLast(ParseType(true));
@@ -3001,7 +3097,8 @@ asCScriptNode *asCParser::ParseStatement()
 
 
 asCScriptNode *asCParser::ParseExpressionStatement()
 asCScriptNode *asCParser::ParseExpressionStatement()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpressionStatement);
+	asCScriptNode *node = CreateNode(snExpressionStatement);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3031,7 +3128,8 @@ asCScriptNode *asCParser::ParseExpressionStatement()
 
 
 asCScriptNode *asCParser::ParseSwitch()
 asCScriptNode *asCParser::ParseSwitch()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snSwitch);
+	asCScriptNode *node = CreateNode(snSwitch);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3107,7 +3205,8 @@ asCScriptNode *asCParser::ParseSwitch()
 
 
 asCScriptNode *asCParser::ParseCase()
 asCScriptNode *asCParser::ParseCase()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCase);
+	asCScriptNode *node = CreateNode(snCase);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3159,7 +3258,8 @@ asCScriptNode *asCParser::ParseCase()
 
 
 asCScriptNode *asCParser::ParseIf()
 asCScriptNode *asCParser::ParseIf()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIf);
+	asCScriptNode *node = CreateNode(snIf);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3206,7 +3306,8 @@ asCScriptNode *asCParser::ParseIf()
 
 
 asCScriptNode *asCParser::ParseFor()
 asCScriptNode *asCParser::ParseFor()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFor);
+	asCScriptNode *node = CreateNode(snFor);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3239,7 +3340,8 @@ asCScriptNode *asCParser::ParseFor()
 	{
 	{
 		RewindTo(&t);
 		RewindTo(&t);
 
 
-		asCScriptNode *n = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpressionStatement);
+		asCScriptNode *n = CreateNode(snExpressionStatement);
+		if( n == 0 ) return 0;
 		node->AddChildLast(n);
 		node->AddChildLast(n);
 		n->AddChildLast(ParseAssignment());
 		n->AddChildLast(ParseAssignment());
 		if( isSyntaxError ) return node;
 		if( isSyntaxError ) return node;
@@ -3259,7 +3361,8 @@ asCScriptNode *asCParser::ParseFor()
 
 
 asCScriptNode *asCParser::ParseWhile()
 asCScriptNode *asCParser::ParseWhile()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snWhile);
+	asCScriptNode *node = CreateNode(snWhile);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3295,7 +3398,8 @@ asCScriptNode *asCParser::ParseWhile()
 
 
 asCScriptNode *asCParser::ParseDoWhile()
 asCScriptNode *asCParser::ParseDoWhile()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDoWhile);
+	asCScriptNode *node = CreateNode(snDoWhile);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3347,7 +3451,8 @@ asCScriptNode *asCParser::ParseDoWhile()
 
 
 asCScriptNode *asCParser::ParseReturn()
 asCScriptNode *asCParser::ParseReturn()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snReturn);
+	asCScriptNode *node = CreateNode(snReturn);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3385,7 +3490,8 @@ asCScriptNode *asCParser::ParseReturn()
 
 
 asCScriptNode *asCParser::ParseBreak()
 asCScriptNode *asCParser::ParseBreak()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snBreak);
+	asCScriptNode *node = CreateNode(snBreak);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3408,7 +3514,8 @@ asCScriptNode *asCParser::ParseBreak()
 
 
 asCScriptNode *asCParser::ParseContinue()
 asCScriptNode *asCParser::ParseContinue()
 {
 {
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snContinue);
+	asCScriptNode *node = CreateNode(snContinue);
+	if( node == 0 ) return 0;
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
@@ -3433,7 +3540,8 @@ asCScriptNode *asCParser::ParseContinue()
 asCScriptNode *asCParser::ParseTypedef()
 asCScriptNode *asCParser::ParseTypedef()
 {
 {
 	// Create the typedef node
 	// Create the typedef node
-	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snTypedef);
+	asCScriptNode *node = CreateNode(snTypedef);
+	if( node == 0 ) return 0;
 
 
 	sToken	token;
 	sToken	token;
 
 

+ 2 - 0
ThirdParty/AngelScript/source/as_parser.h

@@ -76,6 +76,8 @@ protected:
 	void RewindTo(const sToken *token);
 	void RewindTo(const sToken *token);
 	void Error(const char *text, sToken *token);
 	void Error(const char *text, sToken *token);
 
 
+	asCScriptNode *CreateNode(eScriptNode type);
+
 	asCScriptNode *ParseFunctionDefinition();
 	asCScriptNode *ParseFunctionDefinition();
 	asCScriptNode *ParseParameterList();
 	asCScriptNode *ParseParameterList();
 	asCScriptNode *SuperficiallyParseExpression();
 	asCScriptNode *SuperficiallyParseExpression();

+ 182 - 77
ThirdParty/AngelScript/source/as_restore.cpp

@@ -61,14 +61,52 @@ void asCReader::ReadData(void *data, asUINT size)
 #endif
 #endif
 }
 }
 
 
-int asCReader::Read() 
+int asCReader::Read()
 {
 {
-	engine->deferValidationOfTemplateTypes = true;
-
 	// Before starting the load, make sure that 
 	// Before starting the load, make sure that 
 	// any existing resources have been freed
 	// any existing resources have been freed
 	module->InternalReset();
 	module->InternalReset();
 
 
+	// Call the inner method to do the actual loading
+	int r = ReadInner();
+	if( r < 0 )
+	{
+		// Something went wrong while loading the bytecode, so we need
+		// to clean-up whatever has been created during the process.
+
+		// Make sure none of the loaded functions attempt to release
+		// references that have not yet been increased
+		asUINT i;
+		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
+			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
+				module->scriptFunctions[i]->byteCode.SetLength(0);
+		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
+			if( module->scriptGlobals[i]->GetInitFunc() )
+				module->scriptGlobals[i]->GetInitFunc()->byteCode.SetLength(0);
+
+		module->InternalReset();
+	}
+	else
+	{
+		// Init system functions properly
+		engine->PrepareEngine();
+
+		// Initialize the global variables (unless requested not to)
+		if( engine->ep.initGlobalVarsAfterBuild )
+			r = module->ResetGlobalVars(0);
+	}
+
+	return r;
+}
+
+int asCReader::ReadInner() 
+{
+	// This function will load each entity one by one from the stream.
+	// If any error occurs, it will return to the caller who is 
+	// responsible for cleaning up the partially loaded entities.
+
+	engine->deferValidationOfTemplateTypes = true;
+
 	unsigned long i, count;
 	unsigned long i, count;
 
 
 	asCScriptFunction* func;
 	asCScriptFunction* func;
@@ -76,9 +114,12 @@ int asCReader::Read()
 	// Read enums
 	// Read enums
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	module->enumTypes.Allocate(count, 0);
 	module->enumTypes.Allocate(count, 0);
-	for( i = 0; i < count; i++ )
+	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
+		if( ot == 0 )
+			return asOUT_OF_MEMORY;
+
 		ReadObjectTypeDeclaration(ot, 1);
 		ReadObjectTypeDeclaration(ot, 1);
 		engine->classTypes.PushLast(ot);
 		engine->classTypes.PushLast(ot);
 		module->enumTypes.PushLast(ot);
 		module->enumTypes.PushLast(ot);
@@ -86,13 +127,18 @@ int asCReader::Read()
 		ReadObjectTypeDeclaration(ot, 2);
 		ReadObjectTypeDeclaration(ot, 2);
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// classTypes[]
 	// classTypes[]
 	// First restore the structure names, then the properties
 	// First restore the structure names, then the properties
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	module->classTypes.Allocate(count, 0);
 	module->classTypes.Allocate(count, 0);
-	for( i = 0; i < count; ++i )
+	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
+		if( ot == 0 )
+			return asOUT_OF_MEMORY;
+
 		ReadObjectTypeDeclaration(ot, 1);
 		ReadObjectTypeDeclaration(ot, 1);
 
 
 		// If the type is shared, then we should use the original if it exists
 		// If the type is shared, then we should use the original if it exists
@@ -129,17 +175,22 @@ int asCReader::Read()
 		ot->AddRef();
 		ot->AddRef();
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// Read func defs
 	// Read func defs
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	module->funcDefs.Allocate(count, 0);
 	module->funcDefs.Allocate(count, 0);
-	for( i = 0; i < count; i++ )
+	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		asCScriptFunction *func = ReadFunction(false, true);
 		asCScriptFunction *func = ReadFunction(false, true);
-		module->funcDefs.PushLast(func);
+		if( func )
+			module->funcDefs.PushLast(func);
+		else
+			error = true;
 	}
 	}
 
 
 	// Read interface methods
 	// Read interface methods
-	for( i = 0; i < module->classTypes.GetLength(); i++ )
+	for( i = 0; i < module->classTypes.GetLength() && !error; i++ )
 	{
 	{
 		if( module->classTypes[i]->IsInterface() )
 		if( module->classTypes[i]->IsInterface() )
 			ReadObjectTypeDeclaration(module->classTypes[i], 2);
 			ReadObjectTypeDeclaration(module->classTypes[i], 2);
@@ -154,15 +205,15 @@ int asCReader::Read()
 	// so we must updated this in the savedDataTypes if it is there.
 	// so we must updated this in the savedDataTypes if it is there.
 	// All the interface methods were also substituted so the 
 	// All the interface methods were also substituted so the 
 	// savedFunctions must also be updated
 	// savedFunctions must also be updated
-	for( i = 0; i < substitutions.GetLength(); i += 2 )
+	for( i = 0; i < substitutions.GetLength() && !error; i += 2 )
 	{
 	{
-		for( asUINT d = 0; d < savedDataTypes.GetLength(); d++ )
+		for( asUINT d = 0; d < savedDataTypes.GetLength() && !error; d++ )
 		{
 		{
 			if( savedDataTypes[d].GetObjectType() == substitutions[i] )
 			if( savedDataTypes[d].GetObjectType() == substitutions[i] )
 				savedDataTypes[d].SetObjectType(reinterpret_cast<asCObjectType*>(substitutions[i+1]));
 				savedDataTypes[d].SetObjectType(reinterpret_cast<asCObjectType*>(substitutions[i+1]));
 		}
 		}
 
 
-		for( asUINT f = 0; f < savedFunctions.GetLength(); f++ )
+		for( asUINT f = 0; f < savedFunctions.GetLength() && !error; f++ )
 		{
 		{
 			if( savedFunctions[f] == substitutions[i] )
 			if( savedFunctions[f] == substitutions[i] )
 				savedFunctions[f] = reinterpret_cast<asCScriptFunction*>(substitutions[i+1]);
 				savedFunctions[f] = reinterpret_cast<asCScriptFunction*>(substitutions[i+1]);
@@ -171,25 +222,30 @@ int asCReader::Read()
 #endif
 #endif
 
 
 	// Read class methods and behaviours
 	// Read class methods and behaviours
-	for( i = 0; i < module->classTypes.GetLength(); ++i )
+	for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
 	{
 	{
 		if( !module->classTypes[i]->IsInterface() )
 		if( !module->classTypes[i]->IsInterface() )
 			ReadObjectTypeDeclaration(module->classTypes[i], 2);
 			ReadObjectTypeDeclaration(module->classTypes[i], 2);
 	}
 	}
 
 
 	// Read class properties
 	// Read class properties
-	for( i = 0; i < module->classTypes.GetLength(); ++i )
+	for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
 	{
 	{
 		if( !module->classTypes[i]->IsInterface() )
 		if( !module->classTypes[i]->IsInterface() )
 			ReadObjectTypeDeclaration(module->classTypes[i], 3);
 			ReadObjectTypeDeclaration(module->classTypes[i], 3);
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// Read typedefs
 	// Read typedefs
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	module->typeDefs.Allocate(count, 0);
 	module->typeDefs.Allocate(count, 0);
-	for( i = 0; i < count; i++ )
+	for( i = 0; i < count && !error; i++ )
 	{
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
+		if( ot == 0 )
+			return asOUT_OF_MEMORY;
+
 		ReadObjectTypeDeclaration(ot, 1);
 		ReadObjectTypeDeclaration(ot, 1);
 		engine->classTypes.PushLast(ot);
 		engine->classTypes.PushLast(ot);
 		module->typeDefs.PushLast(ot);
 		module->typeDefs.PushLast(ot);
@@ -197,6 +253,8 @@ int asCReader::Read()
 		ReadObjectTypeDeclaration(ot, 2);
 		ReadObjectTypeDeclaration(ot, 2);
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// scriptGlobals[]
 	// scriptGlobals[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	if( engine->ep.disallowGlobalVars )
 	if( engine->ep.disallowGlobalVars )
@@ -205,24 +263,29 @@ int asCReader::Read()
 		error = true;
 		error = true;
 	}
 	}
 	module->scriptGlobals.Allocate(count, 0);
 	module->scriptGlobals.Allocate(count, 0);
-	for( i = 0; i < count; ++i ) 
+	for( i = 0; i < count && !error; ++i ) 
 	{
 	{
 		ReadGlobalProperty();
 		ReadGlobalProperty();
 	}
 	}
 
 
 	// scriptFunctions[]
 	// scriptFunctions[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	for( i = 0; i < count; ++i ) 
+	for( i = 0; i < count && !error; ++i ) 
 	{
 	{
 		size_t len = module->scriptFunctions.GetLength();
 		size_t len = module->scriptFunctions.GetLength();
 		func = ReadFunction();
 		func = ReadFunction();
+		if( func == 0 )
+		{
+			error = true;
+			break;
+		}
 		
 		
 		// Is the function shared and was it created now?
 		// Is the function shared and was it created now?
 		if( func->isShared && len != module->scriptFunctions.GetLength() )
 		if( func->isShared && len != module->scriptFunctions.GetLength() )
 		{
 		{
 			// If the function already existed in another module, then
 			// If the function already existed in another module, then
 			// we need to replace it with previously existing one
 			// we need to replace it with previously existing one
-			for( asUINT n = 0; n < engine->scriptFunctions.GetLength(); n++ )
+			for( asUINT n = 0; n < engine->scriptFunctions.GetLength() && !error; n++ )
 			{
 			{
 				asCScriptFunction *realFunc = engine->scriptFunctions[n];
 				asCScriptFunction *realFunc = engine->scriptFunctions[n];
 				if( realFunc &&
 				if( realFunc &&
@@ -250,20 +313,36 @@ int asCReader::Read()
 
 
 	// globalFunctions[]
 	// globalFunctions[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	for( i = 0; i < count; ++i )
+	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		func = ReadFunction(false, false);
 		func = ReadFunction(false, false);
-		module->globalFunctions.PushLast(func);
-		func->AddRef();
+		if( func )
+		{
+			module->globalFunctions.PushLast(func);
+			func->AddRef();
+		}
+		else
+			error = true;
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// bindInformations[]
 	// bindInformations[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	module->bindInformations.SetLength(count);
-	for( i = 0; i < count; ++i )
+	module->bindInformations.Allocate(count, 0);
+	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		sBindInfo *info = asNEW(sBindInfo);
 		sBindInfo *info = asNEW(sBindInfo);
+		if( info == 0 )
+			return asOUT_OF_MEMORY;
+
 		info->importedFunctionSignature = ReadFunction(false, false);
 		info->importedFunctionSignature = ReadFunction(false, false);
+		if( info->importedFunctionSignature == 0 )
+		{
+			error = true;
+			break;
+		}
+
 		if( engine->freeImportedFunctionIdxs.GetLength() )
 		if( engine->freeImportedFunctionIdxs.GetLength() )
 		{
 		{
 			int id = engine->freeImportedFunctionIdxs.PopLast();
 			int id = engine->freeImportedFunctionIdxs.PopLast();
@@ -277,35 +356,42 @@ int asCReader::Read()
 		}
 		}
 		ReadString(&info->importFromModule);
 		ReadString(&info->importFromModule);
 		info->boundFunctionId = -1;
 		info->boundFunctionId = -1;
-		module->bindInformations[i] = info;
+		module->bindInformations.PushLast(info);
 	}
 	}
 
 
+	if( error ) return asERROR;
+
 	// usedTypes[]
 	// usedTypes[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	usedTypes.Allocate(count, 0);
 	usedTypes.Allocate(count, 0);
-	for( i = 0; i < count; ++i )
+	for( i = 0; i < count && !error; ++i )
 	{
 	{
 		asCObjectType *ot = ReadObjectType();
 		asCObjectType *ot = ReadObjectType();
 		usedTypes.PushLast(ot);
 		usedTypes.PushLast(ot);
 	}
 	}
 
 
 	// usedTypeIds[]
 	// usedTypeIds[]
-	ReadUsedTypeIds();
+	if( !error )
+		ReadUsedTypeIds();
 
 
 	// usedFunctions[]
 	// usedFunctions[]
-	ReadUsedFunctions();
+	if( !error )
+		ReadUsedFunctions();
 
 
 	// usedGlobalProperties[]
 	// usedGlobalProperties[]
-	ReadUsedGlobalProps();
+	if( !error )
+		ReadUsedGlobalProps();
 
 
 	// usedStringConstants[]
 	// usedStringConstants[]
-	ReadUsedStringConstants();
+	if( !error ) 
+		ReadUsedStringConstants();
 
 
 	// usedObjectProperties
 	// usedObjectProperties
-	ReadUsedObjectProps();
+	if( !error )
+		ReadUsedObjectProps();
 
 
 	// Validate the template types
 	// Validate the template types
-	for( i = 0; i < usedTypes.GetLength(); i++ )
+	for( i = 0; i < usedTypes.GetLength() && !error; i++ )
 	{
 	{
 		if( (usedTypes[i]->flags & asOBJ_TEMPLATE) && 
 		if( (usedTypes[i]->flags & asOBJ_TEMPLATE) && 
 			usedTypes[i]->templateSubType.IsValid() &&
 			usedTypes[i]->templateSubType.IsValid() &&
@@ -323,42 +409,26 @@ int asCReader::Read()
 	}
 	}
 	engine->deferValidationOfTemplateTypes = false;
 	engine->deferValidationOfTemplateTypes = false;
 
 
-	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
+	if( error ) return asERROR;
+
+	// Update the loaded bytecode to point to the correct types, property offsets,
+	// function ids, etc. This is basically a linking stage.
+	for( i = 0; i < module->scriptFunctions.GetLength() && !error; i++ )
 		if( module->scriptFunctions[i]->funcType == asFUNC_SCRIPT )
 		if( module->scriptFunctions[i]->funcType == asFUNC_SCRIPT )
 			TranslateFunction(module->scriptFunctions[i]);
 			TranslateFunction(module->scriptFunctions[i]);
-	for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
+	for( i = 0; i < module->scriptGlobals.GetLength() && !error; i++ )
 		if( module->scriptGlobals[i]->GetInitFunc() )
 		if( module->scriptGlobals[i]->GetInitFunc() )
 			TranslateFunction(module->scriptGlobals[i]->GetInitFunc());
 			TranslateFunction(module->scriptGlobals[i]->GetInitFunc());
 
 
-	// Init system functions properly
-	engine->PrepareEngine();
+	if( error ) return asERROR;
 
 
 	// Add references for all functions (except for the pre-existing shared code)
 	// Add references for all functions (except for the pre-existing shared code)
-	if( !error )
-	{
-		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
-				module->scriptFunctions[i]->AddReferences();
-		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
-			if( module->scriptGlobals[i]->GetInitFunc() )
-				module->scriptGlobals[i]->GetInitFunc()->AddReferences();
-
-		if( engine->ep.initGlobalVarsAfterBuild )
-		{
-			int r = module->ResetGlobalVars(0);
-			if( r < 0 ) error = true;
-		}
-	}
-	else
-	{
-		// Make sure none of the loaded functions attempt to release references that have not yet been increased
-		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
-				module->scriptFunctions[i]->byteCode.SetLength(0);
-		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
-			if( module->scriptGlobals[i]->GetInitFunc() )
-				module->scriptGlobals[i]->GetInitFunc()->byteCode.SetLength(0);
-	}
+	for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
+		if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
+			module->scriptFunctions[i]->AddReferences();
+	for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
+		if( module->scriptGlobals[i]->GetInitFunc() )
+			module->scriptGlobals[i]->GetInitFunc()->AddReferences();
 
 
 	return error ? asERROR : asSUCCESS;
 	return error ? asERROR : asSUCCESS;
 }
 }
@@ -369,11 +439,11 @@ void asCReader::ReadUsedStringConstants()
 
 
 	asUINT count;
 	asUINT count;
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	usedStringConstants.SetLength(count);
+	usedStringConstants.Allocate(count, 0);
 	for( asUINT i = 0; i < count; ++i ) 
 	for( asUINT i = 0; i < count; ++i ) 
 	{
 	{
 		ReadString(&str);
 		ReadString(&str);
-		usedStringConstants[i] = engine->AddConstantString(str.AddressOf(), str.GetLength());
+		usedStringConstants.PushLast(engine->AddConstantString(str.AddressOf(), str.GetLength()));
 	}
 	}
 }
 }
 
 
@@ -474,9 +544,16 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	if( count )
 	if( count )
 	{
 	{
 		func->defaultArgs.SetLength(func->parameterTypes.GetLength());
 		func->defaultArgs.SetLength(func->parameterTypes.GetLength());
+		memset(func->defaultArgs.AddressOf(), 0, sizeof(asCString*)*func->parameterTypes.GetLength());
 		for( i = 0; i < count; i++ )
 		for( i = 0; i < count; i++ )
 		{
 		{
 			asCString *str = asNEW(asCString);
 			asCString *str = asNEW(asCString);
+			if( str == 0 )
+			{
+				// Out of memory
+				error = true;
+				return;
+			}
 			func->defaultArgs[func->defaultArgs.GetLength()-1-i] = str;
 			func->defaultArgs[func->defaultArgs.GetLength()-1-i] = str;
 			ReadString(str);
 			ReadString(str);
 		}
 		}
@@ -494,6 +571,8 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 
 
 asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, bool addToGC) 
 asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, bool addToGC) 
 {
 {
+	if( error ) return 0;
+
 	char c;
 	char c;
 	ReadData(&c, 1);
 	ReadData(&c, 1);
 
 
@@ -511,7 +590,6 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 			return savedFunctions[index];
 			return savedFunctions[index];
 		else
 		else
 		{
 		{
-			// TODO: Write to message callback
 			error = true;
 			error = true;
 			return 0;
 			return 0;
 		}
 		}
@@ -519,6 +597,12 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 
 
 	// Load the new function
 	// Load the new function
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
+	if( func == 0 )
+	{
+		// Out of memory
+		error = true;
+		return 0;
+	}
 	savedFunctions.PushLast(func);
 	savedFunctions.PushLast(func);
 
 
 	int i, count;
 	int i, count;
@@ -573,11 +657,17 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 
 
 		// Read the variable information
 		// Read the variable information
 		length = ReadEncodedUInt();
 		length = ReadEncodedUInt();
-		func->variables.SetLength(length);
+		func->variables.Allocate(length, 0);
 		for( i = 0; i < length; i++ )
 		for( i = 0; i < length; i++ )
 		{
 		{
 			asSScriptVariable *var = asNEW(asSScriptVariable);
 			asSScriptVariable *var = asNEW(asSScriptVariable);
-			func->variables[i] = var;
+			if( var == 0 )
+			{
+				// Out of memory
+				error = true;
+				return 0;
+			}
+			func->variables.PushLast(var);
 
 
 			var->declaredAtProgramPos = ReadEncodedUInt();
 			var->declaredAtProgramPos = ReadEncodedUInt();
 			var->stackOffset = ReadEncodedUInt();
 			var->stackOffset = ReadEncodedUInt();
@@ -648,6 +738,12 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			for( int n = 0; n < count; n++ )
 			for( int n = 0; n < count; n++ )
 			{
 			{
 				asSEnumValue *e = asNEW(asSEnumValue);
 				asSEnumValue *e = asNEW(asSEnumValue);
+				if( e == 0 )
+				{
+					// Out of memory
+					error = true;
+					return;
+				}
 				ReadString(&e->name);
 				ReadString(&e->name);
 				ReadData(&e->value, 4);
 				ReadData(&e->value, 4);
 				ot->enumValues.PushLast(e);
 				ot->enumValues.PushLast(e);
@@ -1079,7 +1175,10 @@ void asCReader::ReadString(asCString* str)
 	else
 	else
 	{
 	{
 		asUINT n = ReadEncodedUInt();
 		asUINT n = ReadEncodedUInt();
-		*str = savedStrings[n];
+		if( n < savedStrings.GetLength() )
+			*str = savedStrings[n];
+		else
+			error = true;
 	}
 	}
 }
 }
 
 
@@ -1101,9 +1200,13 @@ void asCReader::ReadGlobalProperty()
 	if( f )
 	if( f )
 	{
 	{
 		asCScriptFunction *func = ReadFunction(false, true);
 		asCScriptFunction *func = ReadFunction(false, true);
-
-		prop->SetInitFunc(func);
-		func->Release();
+		if( func )
+		{
+			prop->SetInitFunc(func);
+			func->Release();
+		}
+		else
+			error = true;
 	}
 	}
 }
 }
 
 
@@ -1210,7 +1313,7 @@ asCObjectType* asCReader::ReadObjectType()
 		// Read the name of the template type
 		// Read the name of the template type
 		asCString typeName;
 		asCString typeName;
 		ReadString(&typeName);
 		ReadString(&typeName);
-		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf());
+		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf(), "");
 		if( tmpl == 0 )
 		if( tmpl == 0 )
 		{
 		{
 			asCString str;
 			asCString str;
@@ -1308,7 +1411,7 @@ asCObjectType* asCReader::ReadObjectType()
 			// Find the object type
 			// Find the object type
 			ot = module->GetObjectType(typeName.AddressOf(), nameSpace);
 			ot = module->GetObjectType(typeName.AddressOf(), nameSpace);
 			if( !ot )
 			if( !ot )
-				ot = engine->GetObjectType(typeName.AddressOf());
+				ot = engine->GetObjectType(typeName.AddressOf(), nameSpace);
 			
 			
 			if( ot == 0 )
 			if( ot == 0 )
 			{
 			{
@@ -1552,12 +1655,12 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
 void asCReader::ReadUsedTypeIds()
 void asCReader::ReadUsedTypeIds()
 {
 {
 	asUINT count = ReadEncodedUInt();
 	asUINT count = ReadEncodedUInt();
-	usedTypeIds.SetLength(count);
+	usedTypeIds.Allocate(count, 0);
 	for( asUINT n = 0; n < count; n++ )
 	for( asUINT n = 0; n < count; n++ )
 	{
 	{
 		asCDataType dt;
 		asCDataType dt;
 		ReadDataType(&dt);
 		ReadDataType(&dt);
-		usedTypeIds[n] = engine->GetTypeIdFromDataType(dt);
+		usedTypeIds.PushLast(engine->GetTypeIdFromDataType(dt));
 	}
 	}
 }
 }
 
 
@@ -1565,7 +1668,7 @@ void asCReader::ReadUsedGlobalProps()
 {
 {
 	int c = ReadEncodedUInt();
 	int c = ReadEncodedUInt();
 
 
-	usedGlobalProperties.SetLength(c);
+	usedGlobalProperties.Allocate(c, 0);
 
 
 	for( int n = 0; n < c; n++ )
 	for( int n = 0; n < c; n++ )
 	{
 	{
@@ -1608,7 +1711,7 @@ void asCReader::ReadUsedGlobalProps()
 			}
 			}
 		}
 		}
 
 
-		usedGlobalProperties[n] = prop;
+		usedGlobalProperties.PushLast(prop);
 
 
 		if( prop == 0 )
 		if( prop == 0 )
 		{
 		{
@@ -2318,7 +2421,8 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 			calledFunc = GetCalledFunction(func, n);
 			calledFunc = GetCalledFunction(func, n);
 			break;
 			break;
 		}
 		}
-		else if( bc == asBC_REFCPY )
+		else if( bc == asBC_REFCPY ||
+				 bc == asBC_COPY )
 		{
 		{
 			// In this case we know there is only 1 pointer on the stack above
 			// In this case we know there is only 1 pointer on the stack above
 			asASSERT( offset == 1 );
 			asASSERT( offset == 1 );
@@ -3189,7 +3293,7 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 
 
 	// Find out which function that will be called
 	// Find out which function that will be called
 	asCScriptFunction *calledFunc = 0;
 	asCScriptFunction *calledFunc = 0;
-	for( asUINT n = programPos; func->byteCode.GetLength(); )
+	for( asUINT n = programPos; n < func->byteCode.GetLength(); )
 	{
 	{
 		asBYTE bc = *(asBYTE*)&func->byteCode[n];
 		asBYTE bc = *(asBYTE*)&func->byteCode[n];
 		if( bc == asBC_CALL ||
 		if( bc == asBC_CALL ||
@@ -3227,7 +3331,8 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 				}
 				}
 			break;
 			break;
 		}
 		}
-		else if( bc == asBC_REFCPY )
+		else if( bc == asBC_REFCPY ||
+				 bc == asBC_COPY )
 		{
 		{
 			// In this case we know there is only 1 pointer on the stack above
 			// In this case we know there is only 1 pointer on the stack above
 			asASSERT( offset == AS_PTR_SIZE );
 			asASSERT( offset == AS_PTR_SIZE );

+ 2 - 0
ThirdParty/AngelScript/source/as_restore.h

@@ -58,6 +58,8 @@ protected:
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
 	bool             error;
 	bool             error;
 
 
+	int                ReadInner();
+
 	void               ReadData(void *data, asUINT size);
 	void               ReadData(void *data, asUINT size);
 	void               ReadString(asCString *str);
 	void               ReadString(asCString *str);
 	asCScriptFunction *ReadFunction(bool addToModule = true, bool addToEngine = true, bool addToGC = true);
 	asCScriptFunction *ReadFunction(bool addToModule = true, bool addToEngine = true, bool addToGC = true);

+ 3 - 1
ThirdParty/AngelScript/source/as_scriptcode.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2011 Andreas Jonsson
+   Copyright (c) 2003-2012 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -76,6 +76,8 @@ int asCScriptCode::SetCode(const char *name, const char *code, size_t length, bo
 	if( makeCopy )
 	if( makeCopy )
 	{
 	{
 		this->code = asNEWARRAY(char,length);
 		this->code = asNEWARRAY(char,length);
+		if( this->code == 0 )
+			return asOUT_OF_MEMORY;
 		memcpy((char*)this->code, code, length);
 		memcpy((char*)this->code, code, length);
 		codeLength = length;
 		codeLength = length;
 		sharedCode = false;
 		sharedCode = false;

+ 398 - 57
ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -236,10 +236,23 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
 		break;
 		break;
 
 
 	case asEP_MAX_STACK_SIZE:
 	case asEP_MAX_STACK_SIZE:
-		// The size is given in bytes, but we only store dwords
-		ep.maximumContextStackSize = (int)value/4;
-		if( initialContextStackSize > ep.maximumContextStackSize )
-			initialContextStackSize = ep.maximumContextStackSize;
+		if( value == 0 )
+		{
+			// Restore default: no limit and initially size 4KB
+			ep.maximumContextStackSize = 0;
+			initialContextStackSize    = 1024;
+		}
+		else
+		{
+			// The size is given in bytes, but we only store dwords
+			ep.maximumContextStackSize = (asUINT)value/4;
+			if( initialContextStackSize > ep.maximumContextStackSize )
+			{
+				initialContextStackSize = ep.maximumContextStackSize;
+				if( initialContextStackSize == 0 )
+					initialContextStackSize = 1;
+			}
+		}
 		break;
 		break;
 
 
 	case asEP_USE_CHARACTER_LITERALS:
 	case asEP_USE_CHARACTER_LITERALS:
@@ -384,7 +397,7 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 
 
 asCScriptEngine::asCScriptEngine() 
 asCScriptEngine::asCScriptEngine() 
 {
 {
-	asCThreadManager::AddRef();
+	asCThreadManager::Prepare();
 
 
 	// Engine properties
 	// Engine properties
 	{
 	{
@@ -424,12 +437,9 @@ asCScriptEngine::asCScriptEngine()
 	lastModule = 0;
 	lastModule = 0;
 
 
 	// User data
 	// User data
-	userData            = 0;
-	cleanEngineFunc     = 0;
 	cleanModuleFunc     = 0;
 	cleanModuleFunc     = 0;
 	cleanContextFunc    = 0;
 	cleanContextFunc    = 0;
 	cleanFunctionFunc   = 0;
 	cleanFunctionFunc   = 0;
-	cleanObjectTypeFunc = 0;
 
 
 
 
 	initialContextStackSize = 1024;      // 4 KB (1024 * sizeof(asDWORD)
 	initialContextStackSize = 1024;      // 4 KB (1024 * sizeof(asDWORD)
@@ -663,10 +673,17 @@ asCScriptEngine::~asCScriptEngine()
 	scriptSectionNames.SetLength(0);
 	scriptSectionNames.SetLength(0);
 
 
 	// Clean the user data
 	// Clean the user data
-	if( userData && cleanEngineFunc )
-		cleanEngineFunc(this);
+	for( n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n+1] )
+		{
+			for( asUINT c = 0; c < cleanEngineFuncs.GetLength(); c++ )
+				if( cleanEngineFuncs[c].type == userData[n] )
+					cleanEngineFuncs[c].cleanFunc(this);
+		}
+	}
 
 
-	asCThreadManager::Release();
+	asCThreadManager::Unprepare();
 }
 }
 
 
 // interface
 // interface
@@ -722,17 +739,55 @@ int asCScriptEngine::SetDefaultNamespace(const char *nameSpace)
 }
 }
 
 
 // interface
 // interface
-void *asCScriptEngine::SetUserData(void *data)
+void *asCScriptEngine::SetUserData(void *data, asPWORD type)
 {
 {
-	void *old = userData;
-	userData = data;
-	return old;
+	// 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(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(engineRWLock);
+
+			return oldData;
+		}
+	}
+
+	userData.PushLast(type);
+	userData.PushLast(reinterpret_cast<asPWORD>(data));
+
+	RELEASEEXCLUSIVE(engineRWLock);
+
+	return 0;
 }
 }
 
 
 // interface
 // interface
-void *asCScriptEngine::GetUserData() const
+void *asCScriptEngine::GetUserData(asPWORD type) const
 {
 {
-	return userData;
+	// There may be multiple threads reading, but when  
+	// setting the user data nobody must be reading.
+	ACQUIRESHARED(engineRWLock);
+
+	for( asUINT n = 0; n < userData.GetLength(); n += 2 )
+	{
+		if( userData[n] == type )
+		{
+			RELEASESHARED(engineRWLock);
+			return reinterpret_cast<void*>(userData[n+1]);
+		}
+	}
+
+	RELEASESHARED(engineRWLock);
+
+	return 0;
 }
 }
 
 
 // interface
 // interface
@@ -1102,6 +1157,8 @@ asIScriptContext *asCScriptEngine::CreateContext()
 int asCScriptEngine::CreateContext(asIScriptContext **context, bool isInternal)
 int asCScriptEngine::CreateContext(asIScriptContext **context, bool isInternal)
 {
 {
 	*context = asNEW(asCContext)(this, !isInternal);
 	*context = asNEW(asCContext)(this, !isInternal);
+	if( *context == 0 )
+		return asOUT_OF_MEMORY;
 
 
 	// We need to make sure the engine has been 
 	// We need to make sure the engine has been 
 	// prepared before any context is executed
 	// prepared before any context is executed
@@ -1135,6 +1192,9 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 		return ConfigError(asINVALID_OBJECT, "RegisterObjectProperty", obj, declaration);
 		return ConfigError(asINVALID_OBJECT, "RegisterObjectProperty", obj, declaration);
 
 
 	asCObjectProperty *prop = asNEW(asCObjectProperty);
 	asCObjectProperty *prop = asNEW(asCObjectProperty);
+	if( prop == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterObjectProperty", obj, declaration);
+
 	prop->name       = name;
 	prop->name       = name;
 	prop->type       = type;
 	prop->type       = type;
 	prop->byteOffset = byteOffset;
 	prop->byteOffset = byteOffset;
@@ -1185,6 +1245,9 @@ int asCScriptEngine::RegisterInterface(const char *name)
 
 
 	// Register the object type for the interface
 	// Register the object type for the interface
 	asCObjectType *st = asNEW(asCObjectType)(this);
 	asCObjectType *st = asNEW(asCObjectType)(this);
+	if( st == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterInterface", name, 0);
+
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT | asOBJ_SHARED;
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT | asOBJ_SHARED;
 	st->size = 0; // Cannot be instanciated
 	st->size = 0; // Cannot be instanciated
 	st->name = name;
 	st->name = name;
@@ -1220,6 +1283,9 @@ int asCScriptEngine::RegisterInterfaceMethod(const char *intf, const char *decla
 		return ConfigError(r, "RegisterInterfaceMethod", intf, declaration);
 		return ConfigError(r, "RegisterInterfaceMethod", intf, declaration);
 
 
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_INTERFACE);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_INTERFACE);
+	if( func == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterInterfaceMethod", intf, declaration);
+
 	func->objectType = dt.GetObjectType();
 	func->objectType = dt.GetObjectType();
 
 
 	r = bld.ParseFunctionDeclaration(func->objectType, declaration, func, false);
 	r = bld.ParseFunctionDeclaration(func->objectType, declaration, func, false);
@@ -1380,6 +1446,9 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		}
 		}
 
 
 		asCObjectType *type = asNEW(asCObjectType)(this);
 		asCObjectType *type = asNEW(asCObjectType)(this);
+		if( type == 0 )
+			return ConfigError(asOUT_OF_MEMORY, "RegisterObjectType", name, 0);
+
 		type->name       = typeName;
 		type->name       = typeName;
 		type->nameSpace  = defaultNamespace;
 		type->nameSpace  = defaultNamespace;
 		type->size       = byteSize;
 		type->size       = byteSize;
@@ -1403,6 +1472,9 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		{
 		{
 			// Create the new subtype if not already existing
 			// Create the new subtype if not already existing
 			subtype = asNEW(asCObjectType)(this);
 			subtype = asNEW(asCObjectType)(this);
+			if( subtype == 0 )
+				return ConfigError(asOUT_OF_MEMORY, "RegisterObjectType", name, 0);
+
 			subtype->name      = subtypeName;
 			subtype->name      = subtypeName;
 			subtype->size      = 0;
 			subtype->size      = 0;
 			subtype->flags     = asOBJ_TEMPLATE_SUBTYPE;
 			subtype->flags     = asOBJ_TEMPLATE_SUBTYPE;
@@ -1424,14 +1496,18 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		asUINT n;
 		asUINT n;
 		for( n = 0; n < objectTypes.GetLength(); n++ )
 		for( n = 0; n < objectTypes.GetLength(); n++ )
 		{
 		{
-			if( objectTypes[n] && objectTypes[n]->name == typeName )
+			if( objectTypes[n] && 
+				objectTypes[n]->name == typeName &&
+				objectTypes[n]->nameSpace == defaultNamespace )
 				// This is not an irrepairable error, as it may just be that the same type is registered twice
 				// This is not an irrepairable error, as it may just be that the same type is registered twice
 				return asALREADY_REGISTERED;
 				return asALREADY_REGISTERED;
 		}
 		}
 
 
 		for( n = 0; n < templateTypes.GetLength(); n++ )
 		for( n = 0; n < templateTypes.GetLength(); n++ )
 		{
 		{
-			if( templateTypes[n] && templateTypes[n]->name == typeName )
+			if( templateTypes[n] && 
+				templateTypes[n]->name == typeName &&
+				templateTypes[n]->nameSpace == defaultNamespace )
 				// This is not an irrepairable error, as it may just be that the same type is registered twice
 				// This is not an irrepairable error, as it may just be that the same type is registered twice
 				return asALREADY_REGISTERED;
 				return asALREADY_REGISTERED;
 		}
 		}
@@ -1467,6 +1543,9 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 
 			// Put the data type in the list
 			// Put the data type in the list
 			asCObjectType *type = asNEW(asCObjectType)(this);
 			asCObjectType *type = asNEW(asCObjectType)(this);
+			if( type == 0 )
+				return ConfigError(asOUT_OF_MEMORY, "RegisterObjectType", name, 0);
+
 			type->name       = typeName;
 			type->name       = typeName;
 			type->nameSpace  = defaultNamespace;
 			type->nameSpace  = defaultNamespace;
 			type->size       = byteSize;
 			type->size       = byteSize;
@@ -1506,6 +1585,9 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 
 			// Put the data type in the list
 			// Put the data type in the list
 			asCObjectType *type = asNEW(asCObjectType)(this);
 			asCObjectType *type = asNEW(asCObjectType)(this);
+			if( type == 0 )
+				return ConfigError(asOUT_OF_MEMORY, "RegisterObjectType", name, 0);
+
 			type->name       = dt.GetObjectType()->name;
 			type->name       = dt.GetObjectType()->name;
 			// The namespace will be the same as the original template type
 			// The namespace will be the same as the original template type
 			type->nameSpace  = dt.GetObjectType()->nameSpace;
 			type->nameSpace  = dt.GetObjectType()->nameSpace;
@@ -1904,11 +1986,42 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 
 
 		if( !(func.parameterTypes.GetLength() == 0 && func.returnType.IsObjectHandle()) &&
 		if( !(func.parameterTypes.GetLength() == 0 && func.returnType.IsObjectHandle()) &&
 			!(func.parameterTypes.GetLength() == 1 && func.parameterTypes[0].GetTokenType() == ttQuestion && func.inOutFlags[0] == asTM_OUTREF && func.returnType.GetTokenType() == ttVoid) )
 			!(func.parameterTypes.GetLength() == 1 && func.parameterTypes[0].GetTokenType() == ttQuestion && func.inOutFlags[0] == asTM_OUTREF && func.returnType.GetTokenType() == ttVoid) )
-		{
 			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
-		}
 
 
-		// TODO: verify that the same cast is not registered already (const or non-const is treated the same for the return type)
+		// Currently it is not supported to register const overloads for the ref cast behaviour
+		if( func.IsReadOnly() )
+			return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+
+		// Verify that the same cast is not registered already 
+		// (const or non-const is treated the same for the return type)
+		if( func.parameterTypes.GetLength() == 1 )
+		{
+			// Check for existing behaviour with ?&out
+			for( asUINT n = 0; n < beh->operators.GetLength(); n+= 2 )
+			{
+				if( beh->operators[n] == asBEHAVE_REF_CAST ||
+					beh->operators[n] == asBEHAVE_IMPLICIT_REF_CAST )
+				{
+					asCScriptFunction *f = scriptFunctions[beh->operators[n+1]];
+					if( f->parameterTypes.GetLength() == 1 )
+						return ConfigError(asALREADY_REGISTERED, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+				}
+			}
+		}
+		else
+		{
+			// Check for existing behaviour with same return type
+			for( asUINT n = 0; n < beh->operators.GetLength(); n+= 2 )
+			{
+				if( beh->operators[n] == asBEHAVE_REF_CAST ||
+					beh->operators[n] == asBEHAVE_IMPLICIT_REF_CAST )
+				{
+					asCScriptFunction *f = scriptFunctions[beh->operators[n+1]];
+					if( f->returnType.GetObjectType() == func.returnType.GetObjectType() )
+						return ConfigError(asALREADY_REGISTERED, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+				}
+			}
+		}
 
 
 		beh->operators.PushLast(behaviour);
 		beh->operators.PushLast(behaviour);
 		func.id = AddBehaviourFunction(func, internal);
 		func.id = AddBehaviourFunction(func, internal);
@@ -1921,6 +2034,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 		return ConfigError(asINVALID_ARG, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 		return ConfigError(asINVALID_ARG, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 	}
 	}
 
 
+	if( func.id < 0 )
+		return ConfigError(func.id, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+
 	// Return function id as success
 	// Return function id as success
 	return func.id;
 	return func.id;
 }
 }
@@ -1946,6 +2062,9 @@ int asCScriptEngine::AddBehaviourFunction(asCScriptFunction &func, asSSystemFunc
 	int id = GetNextScriptFunctionId();
 	int id = GetNextScriptFunctionId();
 
 
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface);
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface);
+	if( newInterface == 0 )
+		return asOUT_OF_MEMORY;
+
 	newInterface->func               = internal.func;
 	newInterface->func               = internal.func;
 	newInterface->baseOffset         = internal.baseOffset;
 	newInterface->baseOffset         = internal.baseOffset;
 	newInterface->callConv           = internal.callConv;
 	newInterface->callConv           = internal.callConv;
@@ -1960,6 +2079,12 @@ int asCScriptEngine::AddBehaviourFunction(asCScriptFunction &func, asSSystemFunc
 	newInterface->hasAutoHandles     = internal.hasAutoHandles;
 	newInterface->hasAutoHandles     = internal.hasAutoHandles;
 
 
 	asCScriptFunction *f = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asCScriptFunction *f = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
+	if( f == 0 )
+	{
+		asDELETE(newInterface, asSSystemFunctionInterface);
+		return asOUT_OF_MEMORY;
+	}
+
 	asASSERT(func.name != "" && func.name != "f");
 	asASSERT(func.name != "" && func.name != "f");
 	f->name           = func.name;
 	f->name           = func.name;
 	f->sysFuncIntf    = newInterface;
 	f->sysFuncIntf    = newInterface;
@@ -2041,6 +2166,11 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
 asCGlobalProperty *asCScriptEngine::AllocateGlobalProperty()
 asCGlobalProperty *asCScriptEngine::AllocateGlobalProperty()
 {
 {
 	asCGlobalProperty *prop = asNEW(asCGlobalProperty);
 	asCGlobalProperty *prop = asNEW(asCGlobalProperty);
+	if( prop == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
 
 
 	// First check the availability of a free slot
 	// First check the availability of a free slot
 	if( freeGlobalPropertyIds.GetLength() )
 	if( freeGlobalPropertyIds.GetLength() )
@@ -2203,8 +2333,16 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 
 
 	// Put the system function in the list of system functions
 	// Put the system function in the list of system functions
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
+	if( newInterface == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
 
 
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
+	if( func == 0 )
+	{
+		asDELETE(newInterface, asSSystemFunctionInterface);
+		return ConfigError(asOUT_OF_MEMORY, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
+	}
+
 	func->sysFuncIntf = newInterface;
 	func->sysFuncIntf = newInterface;
 	func->objectType  = objectType;
 	func->objectType  = objectType;
 
 
@@ -2306,8 +2444,16 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 
 
 	// Put the system function in the list of system functions
 	// Put the system function in the list of system functions
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
+	if( newInterface == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterGlobalFunction", declaration, 0);
 
 
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
+	if( func == 0 )
+	{
+		asDELETE(newInterface, asSSystemFunctionInterface);
+		return ConfigError(asOUT_OF_MEMORY, "RegisterGlobalFunction", declaration, 0);
+	}
+
 	func->sysFuncIntf = newInterface;
 	func->sysFuncIntf = newInterface;
 
 
 	asCBuilder bld(this, 0);
 	asCBuilder bld(this, 0);
@@ -2363,6 +2509,8 @@ asUINT asCScriptEngine::GetGlobalFunctionCount() const
 	return asUINT(registeredGlobalFuncs.GetLength());
 	return asUINT(registeredGlobalFuncs.GetLength());
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-05-20
 // interface
 // interface
 int asCScriptEngine::GetGlobalFunctionIdByIndex(asUINT index) const
 int asCScriptEngine::GetGlobalFunctionIdByIndex(asUINT index) const
 {
 {
@@ -2371,6 +2519,7 @@ int asCScriptEngine::GetGlobalFunctionIdByIndex(asUINT index) const
 
 
 	return registeredGlobalFuncs[index]->id;
 	return registeredGlobalFuncs[index]->id;
 }
 }
+#endif
 
 
 // interface
 // interface
 asIScriptFunction *asCScriptEngine::GetGlobalFunctionByIndex(asUINT index) const
 asIScriptFunction *asCScriptEngine::GetGlobalFunctionByIndex(asUINT index) const
@@ -2427,12 +2576,13 @@ asIScriptFunction *asCScriptEngine::GetGlobalFunctionByDecl(const char *decl) co
 }
 }
 
 
 
 
-asCObjectType *asCScriptEngine::GetObjectType(const char *type)
+asCObjectType *asCScriptEngine::GetObjectType(const char *type, const asCString &ns)
 {
 {
 	// TODO: optimize: Improve linear search
 	// TODO: optimize: Improve linear search
 	for( asUINT n = 0; n < objectTypes.GetLength(); n++ )
 	for( asUINT n = 0; n < objectTypes.GetLength(); n++ )
 		if( objectTypes[n] &&
 		if( objectTypes[n] &&
-			objectTypes[n]->name == type ) // TODO: template: Should we check the subtype in case of template instances?
+			objectTypes[n]->name == type &&
+			objectTypes[n]->nameSpace == ns ) // TODO: template: Should we check the subtype in case of template instances?
 			return objectTypes[n];
 			return objectTypes[n];
 
 
 	return 0;
 	return 0;
@@ -2598,8 +2748,16 @@ int asCScriptEngine::RegisterStringFactory(const char *datatype, const asSFuncPt
 
 
 	// Put the system function in the list of system functions
 	// Put the system function in the list of system functions
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
 	asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
+	if( newInterface == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterStringFactory", datatype, 0);
 
 
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
+	if( func == 0 )
+	{
+		asDELETE(newInterface, asSSystemFunctionInterface);
+		return ConfigError(asOUT_OF_MEMORY, "RegisterStringFactory", datatype, 0);
+	}
+
 	func->name        = "_string_factory_";
 	func->name        = "_string_factory_";
 	func->sysFuncIntf = newInterface;
 	func->sysFuncIntf = newInterface;
 
 
@@ -2666,6 +2824,11 @@ asCModule *asCScriptEngine::GetModule(const char *_name, bool create)
 	if( create )
 	if( create )
 	{
 	{
 		asCModule *module = asNEW(asCModule)(name, this);
 		asCModule *module = asNEW(asCModule)(name, this);
+		if( module == 0 )
+		{
+			// Out of memory
+			return 0;
+		}
 
 
 		scriptModules.PushLast(module);
 		scriptModules.PushLast(module);
 
 
@@ -2689,14 +2852,14 @@ asCModule *asCScriptEngine::GetModuleFromFuncId(int id)
 // internal
 // internal
 int asCScriptEngine::RequestBuild()
 int asCScriptEngine::RequestBuild()
 {
 {
-	ENTERCRITICALSECTION(engineCritical);
+	ACQUIREEXCLUSIVE(engineRWLock);
 	if( isBuilding )
 	if( isBuilding )
 	{
 	{
-		LEAVECRITICALSECTION(engineCritical);
+		RELEASEEXCLUSIVE(engineRWLock);
 		return asBUILD_IN_PROGRESS;
 		return asBUILD_IN_PROGRESS;
 	}
 	}
 	isBuilding = true;
 	isBuilding = true;
-	LEAVECRITICALSECTION(engineCritical);
+	RELEASEEXCLUSIVE(engineRWLock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -2797,6 +2960,12 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 
 
 	// Create a new template instance type based on the templateType
 	// Create a new template instance type based on the templateType
 	asCObjectType *ot = asNEW(asCObjectType)(this);
 	asCObjectType *ot = asNEW(asCObjectType)(this);
+	if( ot == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
 	ot->templateSubType = subType;
 	ot->templateSubType = subType;
 	ot->flags     = templateType->flags;
 	ot->flags     = templateType->flags;
 	ot->size      = templateType->size;
 	ot->size      = templateType->size;
@@ -2927,6 +3096,12 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
 	asCScriptFunction *factory = scriptFunctions[factoryId];
 	asCScriptFunction *factory = scriptFunctions[factoryId];
 
 
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SCRIPT);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SCRIPT);
+	if( func == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
 	func->name             = "factstub";
 	func->name             = "factstub";
 	func->id               = GetNextScriptFunctionId();
 	func->id               = GetNextScriptFunctionId();
 	func->returnType       = asCDataType::CreateObjectHandle(ot, false);
 	func->returnType       = asCDataType::CreateObjectHandle(ot, false);
@@ -3010,16 +3185,31 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
 	if( needNewFunc )
 	if( needNewFunc )
 	{
 	{
 		asCScriptFunction *func2 = asNEW(asCScriptFunction)(this, 0, func->funcType);
 		asCScriptFunction *func2 = asNEW(asCScriptFunction)(this, 0, func->funcType);
+		if( func2 == 0 )
+		{
+			// Out of memory
+			return false;
+		}
+
 		func2->name     = func->name;
 		func2->name     = func->name;
 		func2->id       = GetNextScriptFunctionId();
 		func2->id       = GetNextScriptFunctionId();
 
 
 		if( func->returnType.GetObjectType() == templateType->templateSubType.GetObjectType() )
 		if( func->returnType.GetObjectType() == templateType->templateSubType.GetObjectType() )
 		{
 		{
 			func2->returnType = subType;
 			func2->returnType = subType;
-			if( func->returnType.IsObjectHandle() )
+			if( func->returnType.IsObjectHandle() && !subType.IsObjectHandle() )
+			{
+				// The return type is a handle to the subtype
 				func2->returnType.MakeHandle(true, true);
 				func2->returnType.MakeHandle(true, true);
-			func2->returnType.MakeReference(func->returnType.IsReference());
-			func2->returnType.MakeReadOnly(func->returnType.IsReadOnly());
+				func2->returnType.MakeReference(func->returnType.IsReference());
+				func2->returnType.MakeReadOnly(func->returnType.IsReadOnly());
+			}
+			else
+			{
+				// The return type is the subtype directly
+				func2->returnType.MakeReference(func->returnType.IsReference());
+				func2->returnType.MakeReadOnly(subType.IsReadOnly() || func->returnType.IsReadOnly());
+			}
 		}
 		}
 		else if( func->returnType.GetObjectType() == templateType )
 		else if( func->returnType.GetObjectType() == templateType )
 		{
 		{
@@ -3041,9 +3231,18 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
 			{
 			{
 				func2->parameterTypes[p] = subType;
 				func2->parameterTypes[p] = subType;
 				if( func->parameterTypes[p].IsObjectHandle() )
 				if( func->parameterTypes[p].IsObjectHandle() )
+				{
+					// The parameter is a handle to the subtype
 					func2->parameterTypes[p].MakeHandle(true);
 					func2->parameterTypes[p].MakeHandle(true);
-				func2->parameterTypes[p].MakeReference(func->parameterTypes[p].IsReference());
-				func2->parameterTypes[p].MakeReadOnly(func->parameterTypes[p].IsReference());
+					func2->parameterTypes[p].MakeReference(func->parameterTypes[p].IsReference());
+					func2->parameterTypes[p].MakeReadOnly(func->parameterTypes[p].IsReadOnly());
+				}
+				else
+				{
+					// The parameter is the subtype directly
+					func2->parameterTypes[p].MakeReference(func->parameterTypes[p].IsReference());
+					func2->parameterTypes[p].MakeReadOnly(subType.IsReadOnly() || func->parameterTypes[p].IsReference());
+				}
 			}
 			}
 			else if( func->parameterTypes[p].GetObjectType() == templateType )
 			else if( func->parameterTypes[p].GetObjectType() == templateType )
 			{
 			{
@@ -3362,6 +3561,24 @@ void asCScriptEngine::CallObjectMethod(void *obj, void *param, asSSystemFunction
 		void (*f)(asIScriptGeneric *) = (void (*)(asIScriptGeneric *))(i->func);
 		void (*f)(asIScriptGeneric *) = (void (*)(asIScriptGeneric *))(i->func);
 		f(&gen);
 		f(&gen);
 	}
 	}
+	else if( i->callConv == ICC_VIRTUAL_THISCALL )
+	{
+		// For virtual thiscalls we must call the method as a true class method
+		// so that the compiler will lookup the function address in the vftable
+		union
+		{
+			asSIMPLEMETHOD_t mthd;
+			struct
+			{
+				asFUNCTION_t func;
+				asPWORD baseOffset;  // Same size as the pointer
+			} f;
+		} p;
+		p.f.func = (void (*)())(i->func);
+		p.f.baseOffset = asPWORD(i->baseOffset);
+		void (asCSimpleDummy::*f)(void*) = (void (asCSimpleDummy::*)(void*))(p.mthd);
+		(((asCSimpleDummy*)obj)->*f)(param);
+	}
 	else /*if( i->callConv == ICC_CDECL_OBJFIRST || i->callConv == ICC_THISCALL )*/
 	else /*if( i->callConv == ICC_CDECL_OBJFIRST || i->callConv == ICC_THISCALL )*/
 	{
 	{
 		void (*f)(void *, void *) = (void (*)(void *, void *))(i->func);
 		void (*f)(void *, void *) = (void (*)(void *, void *))(i->func);
@@ -3542,6 +3759,12 @@ int asCScriptEngine::GetTypeIdFromDataType(const asCDataType &dtIn) const
 
 
 	// Insert the basic object type
 	// Insert the basic object type
 	asCDataType *newDt = asNEW(asCDataType)(dt);
 	asCDataType *newDt = asNEW(asCDataType)(dt);
+	if( newDt == 0 )
+	{
+		// Out of memory
+		return 0;
+	}
+
 	newDt->MakeReference(false);
 	newDt->MakeReference(false);
 	newDt->MakeReadOnly(false);
 	newDt->MakeReadOnly(false);
 	newDt->MakeHandle(false);
 	newDt->MakeHandle(false);
@@ -3638,20 +3861,30 @@ void *asCScriptEngine::CreateScriptObject(int typeId)
 	// Is the type id valid?
 	// Is the type id valid?
 	if( !dt.IsValid() ) return 0;
 	if( !dt.IsValid() ) return 0;
 
 
-	// Allocate the memory
 	asCObjectType *objType = dt.GetObjectType();
 	asCObjectType *objType = dt.GetObjectType();
 	void *ptr = 0;
 	void *ptr = 0;
 
 
 	// Construct the object
 	// Construct the object
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
+	{
+		// Call the script class' default factory with a context
 		ptr = ScriptObjectFactory(objType, this);
 		ptr = ScriptObjectFactory(objType, this);
+	}
 	else if( objType->flags & asOBJ_TEMPLATE )
 	else if( objType->flags & asOBJ_TEMPLATE )
-		// The registered factory is moved to the construct behaviour when the type is instanciated
+	{
+		// The registered factory that takes the object type is moved 
+		// to the construct behaviour when the type is instanciated
 		ptr = CallGlobalFunctionRetPtr(objType->beh.construct, objType);
 		ptr = CallGlobalFunctionRetPtr(objType->beh.construct, objType);
+	}
 	else if( objType->flags & asOBJ_REF )
 	else if( objType->flags & asOBJ_REF )
+	{
+		// Call the default factory directly
 		ptr = CallGlobalFunctionRetPtr(objType->beh.factory);
 		ptr = CallGlobalFunctionRetPtr(objType->beh.factory);
+	}
 	else
 	else
 	{
 	{
+		// Manually allocate the memory, then
+		// call the default constructor
 		ptr = CallAlloc(objType);
 		ptr = CallAlloc(objType);
 		int funcIndex = objType->beh.construct;
 		int funcIndex = objType->beh.construct;
 		if( funcIndex )
 		if( funcIndex )
@@ -3661,13 +3894,41 @@ void *asCScriptEngine::CreateScriptObject(int typeId)
 	return ptr;
 	return ptr;
 }
 }
 
 
+// interface
+void *asCScriptEngine::CreateUninitializedScriptObject(int typeId)
+{
+	// Make sure the type id is for an object type, and not a primitive or a handle.
+	// This function only works for script classes. Registered types cannot be created this way.
+	if( (typeId & (asTYPEID_MASK_OBJECT | asTYPEID_MASK_SEQNBR)) != typeId ) return 0;
+	if( (typeId & asTYPEID_MASK_OBJECT) == 0 ) return 0;
+	if( (typeId & asTYPEID_SCRIPTOBJECT) == 0 ) return 0;
+
+	asCDataType dt = GetDataTypeFromTypeId(typeId);
+
+	// Is the type id valid?
+	if( !dt.IsValid() ) return 0;
+
+	asCObjectType *objType = dt.GetObjectType();
+
+	asASSERT( objType->flags & asOBJ_SCRIPT_OBJECT );
+
+	// Construct the object, but do not call the actual constructor that initializes the members
+	// The initialization will be done by the application afterwards, e.g. through serialization.
+	asCScriptObject *obj = reinterpret_cast<asCScriptObject*>(CallAlloc(objType));
+
+	// Pre-initialize the memory so there are no invalid pointers
+	ScriptObject_ConstructUnitialized(objType, obj);
+
+	return obj;
+}
+
 // TODO: interface: Should deprecate this. The application should be calling the factory directly
 // TODO: interface: Should deprecate this. The application should be calling the factory directly
 void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 {
 {
 	void *newObj = CreateScriptObject(typeId);
 	void *newObj = CreateScriptObject(typeId);
 	if( newObj == 0 ) return 0;
 	if( newObj == 0 ) return 0;
 
 
-	CopyScriptObject(newObj, origObj, typeId);
+	AssignScriptObject(newObj, origObj, typeId);
 
 
 	return newObj;
 	return newObj;
 }
 }
@@ -3683,11 +3944,19 @@ void asCScriptEngine::ConstructScriptObjectCopy(void *mem, void *obj, asCObjectT
 	if( funcIndex )
 	if( funcIndex )
 		CallObjectMethod(mem, funcIndex);
 		CallObjectMethod(mem, funcIndex);
 
 
-	CopyScriptObject(mem, obj, type->GetTypeId());
+	AssignScriptObject(mem, obj, type->GetTypeId());
 }
 }
 
 
-// TODO: interface: Should deprecate this. The application should be calling the opAssign method directly
+#ifdef AS_DEPRECATED
+// Deprecated since 2.24.0 - 2012-06-07
 void asCScriptEngine::CopyScriptObject(void *dstObj, void *srcObj, int typeId)
 void asCScriptEngine::CopyScriptObject(void *dstObj, void *srcObj, int typeId)
+{
+	AssignScriptObject(dstObj, srcObj, typeId);
+}
+#endif
+
+// interface
+void asCScriptEngine::AssignScriptObject(void *dstObj, void *srcObj, int typeId)
 {
 {
 	// Make sure the type id is for an object type, and not a primitive or a handle
 	// Make sure the type id is for an object type, and not a primitive or a handle
 	if( (typeId & (asTYPEID_MASK_OBJECT | asTYPEID_MASK_SEQNBR)) != typeId ) return;
 	if( (typeId & (asTYPEID_MASK_OBJECT | asTYPEID_MASK_SEQNBR)) != typeId ) return;
@@ -3797,6 +4066,7 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, const asIObjectType *type)
 	}
 	}
 }
 }
 
 
+// interface
 bool asCScriptEngine::IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const
 bool asCScriptEngine::IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const
 {
 {
 	// if equal, then it is obvious they are compatible
 	// if equal, then it is obvious they are compatible
@@ -3818,16 +4088,20 @@ bool asCScriptEngine::IsHandleCompatibleWithObject(void *obj, int objTypeId, int
 	}
 	}
 	else if( objDt.IsScriptObject() && obj )
 	else if( objDt.IsScriptObject() && obj )
 	{
 	{
-		// There's still a chance the object implements the requested interface
+		// Get the true type from the object instance
 		asCObjectType *objType = ((asCScriptObject*)obj)->objType;
 		asCObjectType *objType = ((asCScriptObject*)obj)->objType;
-		if( objType->Implements(hdlDt.GetObjectType()) )
+
+		// Check if the object implements the interface, or derives from the base class
+		// This will also return true, if the requested handle type is an exact match for the object type
+		if( objType->Implements(hdlDt.GetObjectType()) ||
+		    objType->DerivesFrom(hdlDt.GetObjectType()) )
 			return true;
 			return true;
 	}
 	}
 
 
 	return false;
 	return false;
 }
 }
 
 
-
+// interface
 int asCScriptEngine::BeginConfigGroup(const char *groupName)
 int asCScriptEngine::BeginConfigGroup(const char *groupName)
 {
 {
 	// Make sure the group name doesn't already exist
 	// Make sure the group name doesn't already exist
@@ -3841,6 +4115,9 @@ int asCScriptEngine::BeginConfigGroup(const char *groupName)
 		return asNOT_SUPPORTED;
 		return asNOT_SUPPORTED;
 
 
 	asCConfigGroup *group = asNEW(asCConfigGroup)();
 	asCConfigGroup *group = asNEW(asCConfigGroup)();
+	if( group == 0 )
+		return asOUT_OF_MEMORY;
+
 	group->groupName = groupName;
 	group->groupName = groupName;
 
 
 	configGroups.PushLast(group);
 	configGroups.PushLast(group);
@@ -3849,6 +4126,7 @@ int asCScriptEngine::BeginConfigGroup(const char *groupName)
 	return 0;
 	return 0;
 }
 }
 
 
+// interface
 int asCScriptEngine::EndConfigGroup()
 int asCScriptEngine::EndConfigGroup()
 {
 {
 	// Raise error if trying to end the default config
 	// Raise error if trying to end the default config
@@ -3860,6 +4138,7 @@ int asCScriptEngine::EndConfigGroup()
 	return 0;
 	return 0;
 }
 }
 
 
+// interface
 int asCScriptEngine::RemoveConfigGroup(const char *groupName)
 int asCScriptEngine::RemoveConfigGroup(const char *groupName)
 {
 {
 	// It is not allowed to remove a group that is still in use. 
 	// It is not allowed to remove a group that is still in use. 
@@ -4034,6 +4313,8 @@ int asCScriptEngine::RegisterFuncdef(const char *decl)
 
 
 	// Parse the function declaration
 	// Parse the function declaration
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_FUNCDEF);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_FUNCDEF);
+	if( func == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterFuncdef", decl, 0);
 
 
 	asCBuilder bld(this, 0);
 	asCBuilder bld(this, 0);
 	int r = bld.ParseFunctionDeclaration(0, decl, func, false, 0, 0);
 	int r = bld.ParseFunctionDeclaration(0, decl, func, false, 0, 0);
@@ -4156,10 +4437,14 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 	// types as they are allowed to use the names
 	// types as they are allowed to use the names
 
 
 	// Put the data type in the list
 	// Put the data type in the list
-	asCObjectType *object= asNEW(asCObjectType)(this);
-	object->flags = asOBJ_TYPEDEF;
-	object->size = dataType.GetSizeInMemoryBytes();
-	object->name = type;
+	asCObjectType *object = asNEW(asCObjectType)(this);
+	if( object == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterTypedef", type, decl);
+
+	object->flags           = asOBJ_TYPEDEF;
+	object->size            = dataType.GetSizeInMemoryBytes();
+	object->name            = type;
+	object->nameSpace       = defaultNamespace;
 	object->templateSubType = dataType;
 	object->templateSubType = dataType;
 
 
 	objectTypes.PushLast(object);
 	objectTypes.PushLast(object);
@@ -4237,6 +4522,8 @@ int asCScriptEngine::RegisterEnum(const char *name)
 		return ConfigError(asNAME_TAKEN, "RegisterEnum", name, 0);
 		return ConfigError(asNAME_TAKEN, "RegisterEnum", name, 0);
 
 
 	asCObjectType *st = asNEW(asCObjectType)(this);
 	asCObjectType *st = asNEW(asCObjectType)(this);
+	if( st == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterEnum", name, 0);
 
 
 	asCDataType dataType;
 	asCDataType dataType;
 	dataType.CreatePrimitive(ttInt, false);
 	dataType.CreatePrimitive(ttInt, false);
@@ -4288,6 +4575,9 @@ int asCScriptEngine::RegisterEnumValue(const char *typeName, const char *valueNa
 	}
 	}
 
 
 	asSEnumValue *e = asNEW(asSEnumValue);
 	asSEnumValue *e = asNEW(asSEnumValue);
+	if( e == 0 )
+		return ConfigError(asOUT_OF_MEMORY, "RegisterEnumValue", typeName, valueName);
+
 	e->name = valueName;
 	e->name = valueName;
 	e->value = value;
 	e->value = value;
 
 
@@ -4425,6 +4715,10 @@ bool asCScriptEngine::IsTemplateType(const char *name) const
 // internal
 // internal
 int asCScriptEngine::AddConstantString(const char *str, size_t len)
 int asCScriptEngine::AddConstantString(const char *str, size_t len)
 {
 {
+	// This is only called when build a script module, so it is 
+	// known that only one thread can enter the function at a time.
+	asASSERT( isBuilding );
+
 	// The str may contain null chars, so we cannot use strlen, or strcmp, or strcpy
 	// The str may contain null chars, so we cannot use strlen, or strcmp, or strcpy
 
 
 	// Has the string been registered before?
 	// Has the string been registered before?
@@ -4434,14 +4728,19 @@ int asCScriptEngine::AddConstantString(const char *str, size_t len)
 
 
 	// No match was found, add the string
 	// No match was found, add the string
 	asCString *cstr = asNEW(asCString)(str, len);
 	asCString *cstr = asNEW(asCString)(str, len);
-	stringConstants.PushLast(cstr);
-	int index = (int)stringConstants.GetLength() - 1;
-	stringToIdMap.Insert(asCStringPointer(cstr), index);
+	if( cstr )
+	{
+		stringConstants.PushLast(cstr);
+		int index = (int)stringConstants.GetLength() - 1;
+		stringToIdMap.Insert(asCStringPointer(cstr), index);
 
 
-	// The VM currently doesn't handle string ids larger than 65535
-	asASSERT(stringConstants.GetLength() <= 65536);
+		// The VM currently doesn't handle string ids larger than 65535
+		asASSERT(stringConstants.GetLength() <= 65536);
 
 
-	return index;
+		return index;
+	}
+
+	return 0;
 }
 }
 
 
 // internal
 // internal
@@ -4453,6 +4752,8 @@ const asCString &asCScriptEngine::GetConstantString(int id)
 // internal
 // internal
 int asCScriptEngine::GetScriptSectionNameIndex(const char *name)
 int asCScriptEngine::GetScriptSectionNameIndex(const char *name)
 {
 {
+	ACQUIREEXCLUSIVE(engineRWLock);
+
 	// TODO: These names are only released when the engine is freed. The assumption is that
 	// TODO: These names are only released when the engine is freed. The assumption is that
 	//       the same script section names will be reused instead of there always being new
 	//       the same script section names will be reused instead of there always being new
 	//       names. Is this assumption valid? Do we need to add reference counting?
 	//       names. Is this assumption valid? Do we need to add reference counting?
@@ -4461,17 +4762,42 @@ int asCScriptEngine::GetScriptSectionNameIndex(const char *name)
 	for( asUINT n = 0; n < scriptSectionNames.GetLength(); n++ )
 	for( asUINT n = 0; n < scriptSectionNames.GetLength(); n++ )
 	{
 	{
 		if( scriptSectionNames[n]->Compare(name) == 0 )
 		if( scriptSectionNames[n]->Compare(name) == 0 )
+		{
+			RELEASEEXCLUSIVE(engineRWLock);
 			return n;
 			return n;
+		}
 	}
 	}
 
 
-	scriptSectionNames.PushLast(asNEW(asCString)(name));
-	return int(scriptSectionNames.GetLength()-1);
+	asCString *str = asNEW(asCString)(name);
+	if( str )
+		scriptSectionNames.PushLast(str);
+	int r = int(scriptSectionNames.GetLength()-1);
+
+	RELEASEEXCLUSIVE(engineRWLock);
+
+	return r;
 }
 }
 
 
 // interface 
 // interface 
-void asCScriptEngine::SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback)
+void asCScriptEngine::SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback, asPWORD type)
 {
 {
-	cleanEngineFunc = callback;
+	ACQUIREEXCLUSIVE(engineRWLock);
+
+	for( asUINT n = 0; n < cleanEngineFuncs.GetLength(); n++ )
+	{
+		if( cleanEngineFuncs[n].type == type )
+		{
+			cleanEngineFuncs[n].cleanFunc = callback;
+
+			RELEASEEXCLUSIVE(engineRWLock);
+
+			return;
+		}
+	}
+	SEngineClean otc = {type, callback};
+	cleanEngineFuncs.PushLast(otc);
+
+	RELEASEEXCLUSIVE(engineRWLock);
 }
 }
 
 
 // interface 
 // interface 
@@ -4493,9 +4819,25 @@ void asCScriptEngine::SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t c
 }
 }
 
 
 // interface
 // interface
-void asCScriptEngine::SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback)
+void asCScriptEngine::SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type)
 {
 {
-	cleanObjectTypeFunc = callback;
+	ACQUIREEXCLUSIVE(engineRWLock);
+
+	for( asUINT n = 0; n < cleanObjectTypeFuncs.GetLength(); n++ )
+	{
+		if( cleanObjectTypeFuncs[n].type == type )
+		{
+			cleanObjectTypeFuncs[n].cleanFunc = callback;
+
+			RELEASEEXCLUSIVE(engineRWLock);
+
+			return;
+		}
+	}
+	SObjTypeClean otc = {type, callback};
+	cleanObjectTypeFuncs.PushLast(otc);
+
+	RELEASEEXCLUSIVE(engineRWLock);
 }
 }
 
 
 // Urho3D: modified for smaller executable size
 // Urho3D: modified for smaller executable size
@@ -4509,6 +4851,5 @@ asSFuncPtr::asSFuncPtr(asBYTE f)
 	asMemClear(this, sizeof(asSFuncPtr));
 	asMemClear(this, sizeof(asSFuncPtr));
 	flag = f;
 	flag = f;
 }
 }
-
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

+ 50 - 29
ThirdParty/AngelScript/source/as_scriptengine.h

@@ -95,7 +95,10 @@ public:
 	// Global functions
 	// Global functions
 	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
 	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
 	virtual asUINT             GetGlobalFunctionCount() const;
 	virtual asUINT             GetGlobalFunctionCount() const;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-05-20
 	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const;
 	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const;
+#endif
 	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const;
 	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const;
 
 
@@ -165,13 +168,28 @@ public:
 
 
 	// Script execution
 	// Script execution
 	virtual asIScriptContext *CreateContext();
 	virtual asIScriptContext *CreateContext();
+	// TODO: interface: Deprecate this, add a method that takes the asIObjectType instead
 	virtual void             *CreateScriptObject(int typeId);
 	virtual void             *CreateScriptObject(int typeId);
+	// TODO: interface: Deprecate this, add a method that takes the asIObjectType instead
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId);
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId);
+	// TODO: interface: Deprecate this, add a method that takes the asIObjectType instead
+	virtual void             *CreateUninitializedScriptObject(int typeId);
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.24.0 - 2012-06-07
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId);
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId);
+#endif
+	// TODO: interface: Deprecate this, add a method that takes the asIObjectType instead
+	virtual void              AssignScriptObject(void *dstObj, void *srcObj, int typeId);
+	// TODO: interface: Deprecate this
 	virtual void              ReleaseScriptObject(void *obj, int typeId);
 	virtual void              ReleaseScriptObject(void *obj, int typeId);
 	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type);
 	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type);
+	// TODO: interface: Deprecate this
 	virtual void              AddRefScriptObject(void *obj, int typeId);
 	virtual void              AddRefScriptObject(void *obj, int typeId);
 	virtual void              AddRefScriptObject(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;
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
 
 
 	// String interpretation
 	// String interpretation
@@ -184,13 +202,13 @@ public:
 	virtual void GCEnumCallback(void *reference);
 	virtual void GCEnumCallback(void *reference);
 
 
 	// User data
 	// User data
-	virtual void *SetUserData(void *data);
-	virtual void *GetUserData() const;
-	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback);
+	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  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback);
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
-	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback);
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type);
 
 
 //===========================================================
 //===========================================================
 // internal methods
 // internal methods
@@ -249,7 +267,7 @@ public:
 
 
 	int CreateContext(asIScriptContext **context, bool isInternal);
 	int CreateContext(asIScriptContext **context, bool isInternal);
 
 
-	asCObjectType *GetObjectType(const char *type);
+	asCObjectType *GetObjectType(const char *type, const asCString &ns);
 
 
 	int AddBehaviourFunction(asCScriptFunction &func, asSSystemFunctionInterface &internal);
 	int AddBehaviourFunction(asCScriptFunction &func, asSSystemFunctionInterface &internal);
 
 
@@ -295,7 +313,7 @@ public:
 //===========================================================
 //===========================================================
 	asCMemoryMgr memoryMgr;
 	asCMemoryMgr memoryMgr;
 
 
-	int initialContextStackSize;
+	asUINT initialContextStackSize;
 
 
 	asCObjectType   *defaultArrayObjectType;
 	asCObjectType   *defaultArrayObjectType;
 	asCObjectType    scriptTypeBehaviours;
 	asCObjectType    scriptTypeBehaviours;
@@ -380,37 +398,40 @@ public:
 	asCMap<asCStringPointer, int> stringToIdMap;
 	asCMap<asCStringPointer, int> stringToIdMap;
 
 
 	// User data
 	// User data
-	void                   *userData;
-	asCLEANENGINEFUNC_t     cleanEngineFunc;
+	asCArray<asPWORD>       userData;
+
+	struct SEngineClean { asPWORD type; asCLEANENGINEFUNC_t cleanFunc; };
+	asCArray<SEngineClean> cleanEngineFuncs;
 	asCLEANMODULEFUNC_t     cleanModuleFunc;
 	asCLEANMODULEFUNC_t     cleanModuleFunc;
 	asCLEANCONTEXTFUNC_t    cleanContextFunc;
 	asCLEANCONTEXTFUNC_t    cleanContextFunc;
 	asCLEANFUNCTIONFUNC_t   cleanFunctionFunc;
 	asCLEANFUNCTIONFUNC_t   cleanFunctionFunc;
-	asCLEANOBJECTTYPEFUNC_t cleanObjectTypeFunc;
+	struct SObjTypeClean { asPWORD type; asCLEANOBJECTTYPEFUNC_t cleanFunc; };
+	asCArray<SObjTypeClean> cleanObjectTypeFuncs;
 
 
-	// Critical sections for threads
-	DECLARECRITICALSECTION(engineCritical)
+	// Synchronization for threads
+	DECLAREREADWRITELOCK(mutable engineRWLock)
 
 
 	// Engine properties
 	// Engine properties
 	struct
 	struct
 	{
 	{
-		bool allowUnsafeReferences;
-		bool optimizeByteCode;
-		bool copyScriptSections;
-		int  maximumContextStackSize;
-		bool useCharacterLiterals;
-		bool allowMultilineStrings;
-		bool allowImplicitHandleTypes;
-		bool buildWithoutLineCues;
-		bool initGlobalVarsAfterBuild;
-		bool requireEnumScope;
-		int  scanner;
-		bool includeJitInstructions;
-		int  stringEncoding;
-		int  propertyAccessorMode;
-		bool expandDefaultArrayToTemplate;
-		bool autoGarbageCollect;
-		bool disallowGlobalVars;
-		bool alwaysImplDefaultConstruct;
+		bool   allowUnsafeReferences;
+		bool   optimizeByteCode;
+		bool   copyScriptSections;
+		asUINT maximumContextStackSize;
+		bool   useCharacterLiterals;
+		bool   allowMultilineStrings;
+		bool   allowImplicitHandleTypes;
+		bool   buildWithoutLineCues;
+		bool   initGlobalVarsAfterBuild;
+		bool   requireEnumScope;
+		int    scanner;
+		bool   includeJitInstructions;
+		int    stringEncoding;
+		int    propertyAccessorMode;
+		bool   expandDefaultArrayToTemplate;
+		bool   autoGarbageCollect;
+		bool   disallowGlobalVars;
+		bool   alwaysImplDefaultConstruct;
 	} ep;
 	} ep;
 };
 };
 
 

+ 5 - 0
ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -500,6 +500,11 @@ const char *asCScriptFunction::GetVarDecl(asUINT index) const
 void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
 void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
 {
 {
 	asSScriptVariable *var = asNEW(asSScriptVariable);
 	asSScriptVariable *var = asNEW(asSScriptVariable);
+	if( var == 0 )
+	{
+		// Out of memory
+		return;
+	}
 	var->name                 = name;
 	var->name                 = name;
 	var->type                 = type;
 	var->type                 = type;
 	var->stackOffset          = stackOffset;
 	var->stackOffset          = stackOffset;

+ 4 - 1
ThirdParty/AngelScript/source/as_scriptnode.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2007 Andreas Jonsson
+   Copyright (c) 2003-2012 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -104,6 +104,9 @@ void asCScriptNode::UpdateSourcePos(size_t pos, size_t length)
 
 
 void asCScriptNode::AddChildLast(asCScriptNode *node)
 void asCScriptNode::AddChildLast(asCScriptNode *node)
 {
 {
+	// We might get a null pointer if the parser encounter an out-of-memory situation
+	if( node == 0 ) return;
+
 	if( lastChild )
 	if( lastChild )
 	{
 	{
 		lastChild->next = node;
 		lastChild->next = node;

+ 99 - 24
ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -40,37 +40,74 @@ BEGIN_AS_NAMESPACE
 // This helper function will call the default factory, that is a script function
 // This helper function will call the default factory, that is a script function
 asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine)
 asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine)
 {
 {
-	asIScriptContext *ctx;
+	asIScriptContext *ctx = 0;
+	int r = 0;
+	bool isNested = false;
 
 
 	// TODO: optimize: There should be a pool for the context so it doesn't 
 	// TODO: optimize: There should be a pool for the context so it doesn't 
 	//                 have to be allocated just for creating the script object
 	//                 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
 	// TODO: It must be possible for the application to debug the creation of the object too
 
 
-	int r = engine->CreateContext(&ctx, true);
-	if( r < 0 )
-		return 0;
+	// Use nested call in the context if there is an active context
+	ctx = asGetActiveContext();
+	if( ctx )
+	{
+		r = ctx->PushState();
+
+		// It may not always be possible to reuse the current context, 
+		// in which case we'll have to create a new one any way.
+		if( r == asSUCCESS )
+			isNested = true;
+		else
+			ctx = 0;
+	}
+	
+	if( ctx == 0 )
+	{
+		r = engine->CreateContext(&ctx, true);
+		if( r < 0 )
+			return 0;
+	}
 
 
-	r = ctx->Prepare(objType->beh.factory);
+	r = ctx->Prepare(engine->scriptFunctions[objType->beh.factory]);
 	if( r < 0 )
 	if( r < 0 )
 	{
 	{
-		ctx->Release();
+		if( isNested )
+			ctx->PopState();
+		else
+			ctx->Release();
 		return 0;
 		return 0;
 	}
 	}
 
 
-	r = ctx->Execute();
+	for(;;)
+	{
+		r = ctx->Execute();
+
+		// We can't allow this execution to be suspended 
+		// so resume the execution immediately
+		if( r != asEXECUTION_SUSPENDED )
+			break;
+	}
+
 	if( r != asEXECUTION_FINISHED )
 	if( r != asEXECUTION_FINISHED )
 	{
 	{
-		ctx->Release();
+		if( isNested )
+			ctx->PopState();
+		else
+			ctx->Release();
 		return 0;
 		return 0;
 	}
 	}
 
 
 	asIScriptObject *ptr = (asIScriptObject*)ctx->GetReturnAddress();
 	asIScriptObject *ptr = (asIScriptObject*)ctx->GetReturnAddress();
 
 
-	// Increase the reference, because the context will release it's pointer
+	// Increase the reference, because the context will release its pointer
 	ptr->AddRef();
 	ptr->AddRef();
 
 
-	ctx->Release();
+	if( isNested )
+		ctx->PopState();
+	else
+		ctx->Release();
 
 
 	return ptr;
 	return ptr;
 }
 }
@@ -171,10 +208,15 @@ void ScriptObject_Construct(asCObjectType *objType, asCScriptObject *self)
 	new(self) asCScriptObject(objType);
 	new(self) asCScriptObject(objType);
 }
 }
 
 
-asCScriptObject::asCScriptObject(asCObjectType *ot)
+void ScriptObject_ConstructUnitialized(asCObjectType *objType, asCScriptObject *self)
+{
+	new(self) asCScriptObject(objType, false);
+}
+
+asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 {
 {
 	refCount.set(1);
 	refCount.set(1);
-	objType          = ot;
+	objType = ot;
 	objType->AddRef();
 	objType->AddRef();
 	isDestructCalled = false;
 	isDestructCalled = false;
 
 
@@ -196,7 +238,7 @@ asCScriptObject::asCScriptObject(asCObjectType *ot)
 			else
 			else
 			{
 			{
 				// Allocate the object and call it's constructor
 				// Allocate the object and call it's constructor
-				*ptr = (asPWORD)AllocateObject(prop->type.GetObjectType(), engine);
+				*ptr = (asPWORD)AllocateObject(prop->type.GetObjectType(), engine, doInitialize);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -276,12 +318,13 @@ int asCScriptObject::Release() const
 
 
 void asCScriptObject::CallDestructor()
 void asCScriptObject::CallDestructor()
 {
 {
+	asIScriptContext *ctx = 0;
+	bool isNested = false;
+
 	// Make sure the destructor is called once only, even if the  
 	// Make sure the destructor is called once only, even if the  
 	// reference count is increased and then decreased again
 	// reference count is increased and then decreased again
 	isDestructCalled = true;
 	isDestructCalled = true;
 
 
-	asIScriptContext *ctx = 0;
-
 	// Call the destructor for this class and all the super classes
 	// Call the destructor for this class and all the super classes
 	asCObjectType *ot = objType;
 	asCObjectType *ot = objType;
 	while( ot )
 	while( ot )
@@ -291,17 +334,40 @@ void asCScriptObject::CallDestructor()
 		{
 		{
 			if( ctx == 0 )
 			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;
+				// Check for active context first as it is quicker
+				// to reuse than to set up a new one.
+				ctx = asGetActiveContext();
+				if( ctx )
+				{
+					int r = ctx->PushState();
+					if( r == asSUCCESS )
+						isNested = true;
+					else
+						ctx = 0;
+				}
+
+				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;
+				}
 			}
 			}
 
 
-			int r = ctx->Prepare(funcIndex);
+			int r = ctx->Prepare(objType->engine->scriptFunctions[funcIndex]);
 			if( r >= 0 )
 			if( r >= 0 )
 			{
 			{
 				ctx->SetObject(this);
 				ctx->SetObject(this);
-				ctx->Execute();
+
+				for(;;)
+				{
+					r = ctx->Execute();
+
+					// If the script tries to suspend itself just restart it
+					if( r != asEXECUTION_SUSPENDED )
+						break;
+				}
 
 
 				// There's not much to do if the execution doesn't 
 				// There's not much to do if the execution doesn't 
 				// finish, so we just ignore the result
 				// finish, so we just ignore the result
@@ -313,7 +379,10 @@ void asCScriptObject::CallDestructor()
 
 
 	if( ctx )
 	if( ctx )
 	{
 	{
-		ctx->Release();
+		if( isNested )
+			ctx->PopState();
+		else
+			ctx->Release();
 	}
 	}
 }
 }
 
 
@@ -486,13 +555,19 @@ int asCScriptObject::CopyFrom(asIScriptObject *other)
 	return 0;
 	return 0;
 }
 }
 
 
-void *asCScriptObject::AllocateObject(asCObjectType *objType, asCScriptEngine *engine)
+void *asCScriptObject::AllocateObject(asCObjectType *objType, asCScriptEngine *engine, bool doInitialize)
 {
 {
 	void *ptr = 0;
 	void *ptr = 0;
 
 
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
 	{
 	{
-		ptr = ScriptObjectFactory(objType, engine);
+		if( doInitialize )
+			ptr = ScriptObjectFactory(objType, engine);
+		else
+		{
+			ptr = engine->CallAlloc(objType);
+			ScriptObject_ConstructUnitialized(objType, reinterpret_cast<asCScriptObject*>(ptr));
+		}
 	}
 	}
 	else if( objType->flags & asOBJ_TEMPLATE )
 	else if( objType->flags & asOBJ_TEMPLATE )
 	{
 	{

+ 5 - 3
ThirdParty/AngelScript/source/as_scriptobject.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2011 Andreas Jonsson
+   Copyright (c) 2003-2012 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -82,7 +82,7 @@ public:
 //====================================
 //====================================
 // Internal
 // Internal
 //====================================
 //====================================
-	asCScriptObject(asCObjectType *objType);
+	asCScriptObject(asCObjectType *objType, bool doInitialize = true);
 	virtual ~asCScriptObject();
 	virtual ~asCScriptObject();
 
 
 	asCScriptObject &operator=(const asCScriptObject &other);
 	asCScriptObject &operator=(const asCScriptObject &other);
@@ -96,7 +96,7 @@ public:
 	void ReleaseAllHandles(asIScriptEngine *engine);
 	void ReleaseAllHandles(asIScriptEngine *engine);
 
 
 	// Used for properties
 	// Used for properties
-	void *AllocateObject(asCObjectType *objType, asCScriptEngine *engine);
+	void *AllocateObject(asCObjectType *objType, asCScriptEngine *engine, bool doInitialize);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine);
@@ -117,6 +117,8 @@ protected:
 void ScriptObject_Construct(asCObjectType *objType, asCScriptObject *self);
 void ScriptObject_Construct(asCObjectType *objType, asCScriptObject *self);
 asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject *self);
 asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject *self);
 
 
+void ScriptObject_ConstructUnitialized(asCObjectType *objType, asCScriptObject *self);
+
 void ScriptObject_Construct_Generic(asIScriptGeneric *gen);
 void ScriptObject_Construct_Generic(asIScriptGeneric *gen);
 void ScriptObject_Assignment_Generic(asIScriptGeneric *gen);
 void ScriptObject_Assignment_Generic(asIScriptGeneric *gen);
 
 

+ 5 - 0
ThirdParty/AngelScript/source/as_string.cpp

@@ -123,6 +123,11 @@ void asCString::Allocate(size_t len, bool keepData)
 	{
 	{
 		// Allocate a new dynamic buffer if the new one is larger than the old
 		// Allocate a new dynamic buffer if the new one is larger than the old
 		char *buf = asNEWARRAY(char,len+1);
 		char *buf = asNEWARRAY(char,len+1);
+		if( buf == 0 )
+		{
+			// Out of memory. Return without modifying anything
+			return;
+		}
 
 
 		if( keepData )
 		if( keepData )
 		{
 		{

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

@@ -241,6 +241,7 @@
 #define TXT_FAILED_IN_FUNC_s                       "Failed in call to function '%s'"
 #define TXT_FAILED_IN_FUNC_s                       "Failed in call to function '%s'"
 #define TXT_FAILED_IN_FUNC_s_WITH_s                "Failed in call to function '%s' with '%s'"
 #define TXT_FAILED_IN_FUNC_s_WITH_s                "Failed in call to function '%s' with '%s'"
 #define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s          "Failed in call to function '%s' with '%s' and '%s'"
 #define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s          "Failed in call to function '%s' with '%s' and '%s'"
+#define TXT_GC_RECEIVED_NULL_PTR                   "AddScriptObjectToGC called with null pointer"
 
 
 // Internal names
 // Internal names
 
 

+ 167 - 53
ThirdParty/AngelScript/source/as_thread.cpp

@@ -42,27 +42,57 @@
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
+//=======================================================================
+
+// Singleton
+static asCThreadManager *threadManager = 0;
+
 //======================================================================
 //======================================================================
 
 
+// Global API functions
 extern "C"
 extern "C"
 {
 {
 
 
-// Global API function
 AS_API int asThreadCleanup()
 AS_API int asThreadCleanup()
 {
 {
 	return asCThreadManager::CleanupLocalData();
 	return asCThreadManager::CleanupLocalData();
 }
 }
 
 
+AS_API void asPrepareMultithread()
+{
+	asCThreadManager::Prepare();
 }
 }
 
 
-//=======================================================================
+AS_API void asUnprepareMultithread()
+{
+	asCThreadManager::Unprepare();
+}
 
 
-// Singleton
-static asCThreadManager *threadManager = 0;
+AS_API void asAcquireExclusiveLock()
+{
+	if( threadManager )
+		ACQUIREEXCLUSIVE(threadManager->appRWLock);
+}
 
 
-#ifndef AS_NO_THREADS
-static DECLARECRITICALSECTION(criticalSection)
-#endif
+AS_API void asReleaseExclusiveLock()
+{
+	if( threadManager )
+		RELEASEEXCLUSIVE(threadManager->appRWLock);
+}
+
+AS_API void asAcquireSharedLock()
+{
+	if( threadManager )
+		ACQUIRESHARED(threadManager->appRWLock);
+}
+
+AS_API void asReleaseSharedLock()
+{
+	if( threadManager )
+		RELEASESHARED(threadManager->appRWLock);
+}
+
+}
 
 
 //======================================================================
 //======================================================================
 
 
@@ -76,35 +106,54 @@ asCThreadManager::asCThreadManager()
 	refCount = 1;
 	refCount = 1;
 }
 }
 
 
-void asCThreadManager::AddRef()
+void asCThreadManager::Prepare()
 {
 {
-	// It's necessary to protect this section to 
-	// avoid two threads attempting to create thread
-	// managers at the same time.
-	ENTERCRITICALSECTION(criticalSection);
+	// The critical section cannot be declared globally, as there is no
+	// guarantee for the order in which global variables are initialized
+	// or uninitialized.
+
+	// For this reason it's not possible to prevent two threads from calling 
+	// AddRef at the same time, so there is a chance for a race condition here.
 
 
+	// To avoid the race condition when the thread manager is first created, 
+	// the application must make sure to call the global asPrepareForMultiThread()
+	// in the main thread before any other thread creates a script engine. 
 	if( threadManager == 0 )
 	if( threadManager == 0 )
 		threadManager = asNEW(asCThreadManager);
 		threadManager = asNEW(asCThreadManager);
 	else
 	else
+	{
+		ENTERCRITICALSECTION(threadManager->criticalSection);
 		threadManager->refCount++;
 		threadManager->refCount++;
-
-	LEAVECRITICALSECTION(criticalSection);
+		LEAVECRITICALSECTION(threadManager->criticalSection);
+	}
 }
 }
 
 
-void asCThreadManager::Release()
+void asCThreadManager::Unprepare()
 {
 {
+	asASSERT(threadManager);
+
+	if( threadManager == 0 )
+		return;
+
 	// It's necessary to protect this section so no
 	// It's necessary to protect this section so no
 	// other thread attempts to call AddRef or Release
 	// other thread attempts to call AddRef or Release
 	// while clean up is in progress.
 	// while clean up is in progress.
-	ENTERCRITICALSECTION(criticalSection);
+	ENTERCRITICALSECTION(threadManager->criticalSection);
 	if( --threadManager->refCount == 0 )
 	if( --threadManager->refCount == 0 )
 	{
 	{
-		// The last engine has been destroyed, so we 
-		// need to delete the thread manager as well
-		asDELETE(threadManager,asCThreadManager);
+		// As the critical section will be destroyed together 
+		// with the thread manager we must first clear the global
+		// variable in case a new thread manager needs to be created;
+		asCThreadManager *mgr = threadManager;
 		threadManager = 0;
 		threadManager = 0;
+
+		// Leave the critical section before it is destroyed
+		LEAVECRITICALSECTION(mgr->criticalSection);
+
+		asDELETE(mgr,asCThreadManager);
 	}
 	}
-	LEAVECRITICALSECTION(criticalSection);
+	else
+		LEAVECRITICALSECTION(threadManager->criticalSection);
 }
 }
 
 
 asCThreadManager::~asCThreadManager()
 asCThreadManager::~asCThreadManager()
@@ -133,6 +182,9 @@ asCThreadManager::~asCThreadManager()
 
 
 int asCThreadManager::CleanupLocalData()
 int asCThreadManager::CleanupLocalData()
 {
 {
+	if( threadManager == 0 )
+		return 0;
+
 #ifndef AS_NO_THREADS
 #ifndef AS_NO_THREADS
 	int r = 0;
 	int r = 0;
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
@@ -141,13 +193,7 @@ int asCThreadManager::CleanupLocalData()
 	asPWORD id = (asPWORD)GetCurrentThreadId();
 	asPWORD id = (asPWORD)GetCurrentThreadId();
 #endif
 #endif
 
 
-	ENTERCRITICALSECTION(criticalSection);
-
-	if( threadManager == 0 )
-	{
-		LEAVECRITICALSECTION(criticalSection);
-		return 0;
-	}
+	ENTERCRITICALSECTION(threadManager->criticalSection);
 
 
 	asSMapNode<asPWORD,asCThreadLocalData*> *cursor = 0;
 	asSMapNode<asPWORD,asCThreadLocalData*> *cursor = 0;
 	if( threadManager->tldMap.MoveTo(&cursor, id) )
 	if( threadManager->tldMap.MoveTo(&cursor, id) )
@@ -165,11 +211,11 @@ int asCThreadManager::CleanupLocalData()
 			r = asCONTEXT_ACTIVE;
 			r = asCONTEXT_ACTIVE;
 	}
 	}
 
 
-	LEAVECRITICALSECTION(criticalSection);
+	LEAVECRITICALSECTION(threadManager->criticalSection);
 
 
 	return r;
 	return r;
 #else
 #else
-	if( threadManager && threadManager->tld )
+	if( threadManager->tld )
 	{
 	{
 		if( threadManager->tld->activeContexts.GetLength() == 0 )
 		if( threadManager->tld->activeContexts.GetLength() == 0 )
 		{
 		{
@@ -207,6 +253,9 @@ void asCThreadManager::SetLocalData(asPWORD threadId, asCThreadLocalData *tld)
 
 
 asCThreadLocalData *asCThreadManager::GetLocalData()
 asCThreadLocalData *asCThreadManager::GetLocalData()
 {
 {
+	if( threadManager == 0 )
+		return 0;
+
 #ifndef AS_NO_THREADS
 #ifndef AS_NO_THREADS
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
 	asPWORD id = (asPWORD)pthread_self();
 	asPWORD id = (asPWORD)pthread_self();
@@ -214,31 +263,21 @@ asCThreadLocalData *asCThreadManager::GetLocalData()
 	asPWORD id = (asPWORD)GetCurrentThreadId();
 	asPWORD id = (asPWORD)GetCurrentThreadId();
 #endif
 #endif
 
 
-	ENTERCRITICALSECTION(criticalSection);
-
-	asASSERT(threadManager);
-
-	if( threadManager == 0 )
-	{
-		LEAVECRITICALSECTION(criticalSection);
-		return 0;
-	}
+	ENTERCRITICALSECTION(threadManager->criticalSection);
 
 
 	asCThreadLocalData *tld = threadManager->GetLocalData(id);
 	asCThreadLocalData *tld = threadManager->GetLocalData(id);
 	if( tld == 0 )
 	if( tld == 0 )
 	{
 	{
 		// Create a new tld
 		// Create a new tld
 		tld = asNEW(asCThreadLocalData)();
 		tld = asNEW(asCThreadLocalData)();
-		threadManager->SetLocalData(id, tld);
+		if( tld )
+			threadManager->SetLocalData(id, tld);
 	}
 	}
 
 
-	LEAVECRITICALSECTION(criticalSection);
+	LEAVECRITICALSECTION(threadManager->criticalSection);
 
 
 	return tld;
 	return tld;
 #else
 #else
-	if( threadManager == 0 )
-		return 0;
-
 	if( threadManager->tld == 0 )
 	if( threadManager->tld == 0 )
 		threadManager->tld = asNEW(asCThreadLocalData)();
 		threadManager->tld = asNEW(asCThreadLocalData)();
 
 
@@ -262,49 +301,124 @@ asCThreadLocalData::~asCThreadLocalData()
 asCThreadCriticalSection::asCThreadCriticalSection()
 asCThreadCriticalSection::asCThreadCriticalSection()
 {
 {
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
-	pthread_mutex_init(&criticalSection, 0);
+	pthread_mutex_init(&cs, 0);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
-	InitializeCriticalSection(&criticalSection);
+	InitializeCriticalSection(&cs);
 #endif
 #endif
 }
 }
 
 
 asCThreadCriticalSection::~asCThreadCriticalSection()
 asCThreadCriticalSection::~asCThreadCriticalSection()
 {
 {
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
-	pthread_mutex_destroy(&criticalSection);
+	pthread_mutex_destroy(&cs);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
-	DeleteCriticalSection(&criticalSection);
+	DeleteCriticalSection(&cs);
 #endif
 #endif
 }
 }
 
 
 void asCThreadCriticalSection::Enter()
 void asCThreadCriticalSection::Enter()
 {
 {
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
-	pthread_mutex_lock(&criticalSection);
+	pthread_mutex_lock(&cs);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
-	EnterCriticalSection(&criticalSection);
+	EnterCriticalSection(&cs);
 #endif
 #endif
 }
 }
 
 
 void asCThreadCriticalSection::Leave()
 void asCThreadCriticalSection::Leave()
 {
 {
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
-	pthread_mutex_unlock(&criticalSection);
+	pthread_mutex_unlock(&cs);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
-	LeaveCriticalSection(&criticalSection);
+	LeaveCriticalSection(&cs);
 #endif
 #endif
 }
 }
 
 
 bool asCThreadCriticalSection::TryEnter()
 bool asCThreadCriticalSection::TryEnter()
 {
 {
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
-	return !pthread_mutex_trylock(&criticalSection);
+	return !pthread_mutex_trylock(&cs);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
-	return TryEnterCriticalSection(&criticalSection) ? true : false;
+	return TryEnterCriticalSection(&cs) ? true : false;
 #else
 #else
 	return true;
 	return true;
 #endif
 #endif
 }
 }
+
+asCThreadReadWriteLock::asCThreadReadWriteLock()
+{
+#if defined AS_POSIX_THREADS
+	int r = pthread_rwlock_init(&lock, 0);
+	asASSERT( r == 0 );
+#elif defined AS_WINDOWS_THREADS
+	// Create a semaphore to allow up to maxReaders simultaneous readers
+	readLocks = CreateSemaphore(NULL, maxReaders, maxReaders, 0);
+	// Create a critical section to synchronize writers
+	InitializeCriticalSection(&writeLock);
+#endif
+}
+
+asCThreadReadWriteLock::~asCThreadReadWriteLock()
+{
+#if defined AS_POSIX_THREADS
+	pthread_rwlock_destroy(&lock);
+#elif defined AS_WINDOWS_THREADS
+	DeleteCriticalSection(&writeLock);
+	CloseHandle(readLocks);
+#endif
+}
+
+void asCThreadReadWriteLock::AcquireExclusive()
+{
+#if defined AS_POSIX_THREADS
+	pthread_rwlock_wrlock(&lock);
+#elif defined AS_WINDOWS_THREADS
+	// Synchronize writers, so only one tries to lock out the readers
+	EnterCriticalSection(&writeLock);
+
+	// Lock all reader out from the semaphore. Do this one by one,
+	// so the lock doesn't have to wait until there are no readers at all.
+	// If we try to lock all at once it is quite possible the writer will
+	// never succeed.
+	for( asUINT n = 0; n < maxReaders; n++ )
+		WaitForSingleObject(readLocks, INFINITE);
+
+	// Allow another writer to lock. It will only be able to
+	// lock the readers when this writer releases them anyway.
+	LeaveCriticalSection(&writeLock);
+#endif
+}
+
+void asCThreadReadWriteLock::ReleaseExclusive()
+{
+#if defined AS_POSIX_THREADS
+	pthread_rwlock_unlock(&lock);
+#elif defined AS_WINDOWS_THREADS
+	// Release all readers at once
+	ReleaseSemaphore(readLocks, maxReaders, 0);
+#endif
+}
+
+void asCThreadReadWriteLock::AcquireShared()
+{
+#if defined AS_POSIX_THREADS
+	pthread_rwlock_rdlock(&lock);
+#elif defined AS_WINDOWS_THREADS
+	// Lock a reader slot
+	WaitForSingleObject(readLocks, INFINITE);
+#endif
+}
+
+void asCThreadReadWriteLock::ReleaseShared()
+{
+#if defined AS_POSIX_THREADS
+	pthread_rwlock_unlock(&lock);
+#elif defined AS_WINDOWS_THREADS
+	// Release the reader slot
+	ReleaseSemaphore(readLocks, 1, 0);
+#endif
+}
+
 #endif
 #endif
 
 
 //========================================================================
 //========================================================================

+ 7 - 2
ThirdParty/AngelScript/source/as_thread.h

@@ -55,8 +55,11 @@ public:
 	static asCThreadLocalData *GetLocalData();
 	static asCThreadLocalData *GetLocalData();
 	static int CleanupLocalData();
 	static int CleanupLocalData();
 
 
-	static void AddRef();
-	static void Release();
+	static void Prepare();
+	static void Unprepare();
+
+	// This read/write lock can be used by the application to provide simple synchronization
+	DECLAREREADWRITELOCK(appRWLock)
 
 
 protected:
 protected:
 	asCThreadManager();
 	asCThreadManager();
@@ -67,6 +70,8 @@ protected:
 	int refCount;
 	int refCount;
 
 
 #ifndef AS_NO_THREADS
 #ifndef AS_NO_THREADS
+	DECLARECRITICALSECTION(criticalSection);
+
 	asCThreadLocalData *GetLocalData(asPWORD threadId);
 	asCThreadLocalData *GetLocalData(asPWORD threadId);
 	void SetLocalData(asPWORD threadId, asCThreadLocalData *tld);
 	void SetLocalData(asPWORD threadId, asCThreadLocalData *tld);
 
 

+ 5 - 0
ThirdParty/AngelScript/source/as_variablescope.cpp

@@ -82,6 +82,11 @@ int asCVariableScope::DeclareVariable(const char *name, const asCDataType &type,
 	}
 	}
 
 
 	sVariable *var = asNEW(sVariable);
 	sVariable *var = asNEW(sVariable);
+	if( var == 0 )
+	{
+		// Out of memory. Return without allocating the var
+		return -2;
+	}
 	var->name           = name;
 	var->name           = name;
 	var->type           = type;
 	var->type           = type;
 	var->stackOffset    = stackOffset;
 	var->stackOffset    = stackOffset;

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