Browse Source

Migrated to AngelScript 2.26.1 WIP.
Octree code cleanup.
Added nullchecks to RigidBody in case Bullet callbacks are fired when the body's scene node has been destroyed.

Lasse Öörni 13 years ago
parent
commit
4e836e574f
58 changed files with 4052 additions and 2647 deletions
  1. 1 1
      Docs/Urho3D.dox
  2. 32 36
      Engine/Graphics/Octree.cpp
  3. 2 2
      Engine/Graphics/Octree.h
  4. 32 22
      Engine/Physics/RigidBody.cpp
  5. 1 1
      Readme.txt
  6. 108 83
      ThirdParty/AngelScript/include/angelscript.h
  7. 12 2
      ThirdParty/AngelScript/source/as_array.h
  8. 21 31
      ThirdParty/AngelScript/source/as_atomic.cpp
  9. 1 6
      ThirdParty/AngelScript/source/as_atomic.h
  10. 397 161
      ThirdParty/AngelScript/source/as_builder.cpp
  11. 54 46
      ThirdParty/AngelScript/source/as_builder.h
  12. 545 372
      ThirdParty/AngelScript/source/as_bytecode.cpp
  13. 11 8
      ThirdParty/AngelScript/source/as_bytecode.h
  14. 29 24
      ThirdParty/AngelScript/source/as_callfunc.cpp
  15. 3 1
      ThirdParty/AngelScript/source/as_callfunc.h
  16. 10 4
      ThirdParty/AngelScript/source/as_callfunc_arm.cpp
  17. 253 251
      ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  18. 242 242
      ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm
  19. 2 1
      ThirdParty/AngelScript/source/as_callfunc_mips.cpp
  20. 2 2
      ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  21. 53 34
      ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  22. 1 1
      ThirdParty/AngelScript/source/as_callfunc_xenon.cpp
  23. 327 416
      ThirdParty/AngelScript/source/as_compiler.cpp
  24. 39 13
      ThirdParty/AngelScript/source/as_compiler.h
  25. 121 67
      ThirdParty/AngelScript/source/as_config.h
  26. 28 11
      ThirdParty/AngelScript/source/as_context.cpp
  27. 1 0
      ThirdParty/AngelScript/source/as_context.h
  28. 14 53
      ThirdParty/AngelScript/source/as_datatype.cpp
  29. 5 15
      ThirdParty/AngelScript/source/as_datatype.h
  30. 209 3
      ThirdParty/AngelScript/source/as_debug.h
  31. 57 8
      ThirdParty/AngelScript/source/as_gc.cpp
  32. 9 1
      ThirdParty/AngelScript/source/as_gc.h
  33. 18 5
      ThirdParty/AngelScript/source/as_globalproperty.cpp
  34. 22 4
      ThirdParty/AngelScript/source/as_map.h
  35. 4 0
      ThirdParty/AngelScript/source/as_memory.cpp
  36. 76 45
      ThirdParty/AngelScript/source/as_module.cpp
  37. 16 16
      ThirdParty/AngelScript/source/as_module.h
  38. 90 25
      ThirdParty/AngelScript/source/as_objecttype.cpp
  39. 10 6
      ThirdParty/AngelScript/source/as_objecttype.h
  40. 248 200
      ThirdParty/AngelScript/source/as_parser.cpp
  41. 5 6
      ThirdParty/AngelScript/source/as_parser.h
  42. 2 0
      ThirdParty/AngelScript/source/as_property.h
  43. 313 121
      ThirdParty/AngelScript/source/as_restore.cpp
  44. 1 1
      ThirdParty/AngelScript/source/as_restore.h
  45. 4 5
      ThirdParty/AngelScript/source/as_scriptcode.cpp
  46. 321 181
      ThirdParty/AngelScript/source/as_scriptengine.cpp
  47. 13 10
      ThirdParty/AngelScript/source/as_scriptengine.h
  48. 36 13
      ThirdParty/AngelScript/source/as_scriptfunction.cpp
  49. 4 6
      ThirdParty/AngelScript/source/as_scriptfunction.h
  50. 0 1
      ThirdParty/AngelScript/source/as_scriptnode.h
  51. 165 45
      ThirdParty/AngelScript/source/as_scriptobject.cpp
  52. 1 1
      ThirdParty/AngelScript/source/as_scriptobject.h
  53. 7 1
      ThirdParty/AngelScript/source/as_string.cpp
  54. 3 1
      ThirdParty/AngelScript/source/as_string.h
  55. 22 22
      ThirdParty/AngelScript/source/as_symboltable.h
  56. 12 6
      ThirdParty/AngelScript/source/as_texts.h
  57. 34 5
      ThirdParty/AngelScript/source/as_thread.cpp
  58. 3 3
      ThirdParty/AngelScript/source/as_thread.h

+ 1 - 1
Docs/Urho3D.dox

@@ -72,7 +72,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.25.0 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.26.1 WIP (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/)

+ 32 - 36
Engine/Graphics/Octree.cpp

@@ -85,16 +85,13 @@ inline bool CompareRayQueryResults(const RayQueryResult& lhs, const RayQueryResu
 }
 }
 
 
 Octant::Octant(const BoundingBox& box, unsigned level, Octant* parent, Octree* root, unsigned index) :
 Octant::Octant(const BoundingBox& box, unsigned level, Octant* parent, Octree* root, unsigned index) :
-    worldBoundingBox_(box),
     level_(level),
     level_(level),
     numDrawables_(0),
     numDrawables_(0),
     parent_(parent),
     parent_(parent),
     root_(root),
     root_(root),
     index_(index)
     index_(index)
 {
 {
-    center_ = worldBoundingBox_.Center();
-    halfSize_ = 0.5f * worldBoundingBox_.Size();
-    cullingBox_ = BoundingBox(worldBoundingBox_.min_ - halfSize_, worldBoundingBox_.max_ + halfSize_);
+    Initialize(box);
     
     
     for (unsigned i = 0; i < NUM_OCTANTS; ++i)
     for (unsigned i = 0; i < NUM_OCTANTS; ++i)
         children_[i] = 0;
         children_[i] = 0;
@@ -102,7 +99,21 @@ Octant::Octant(const BoundingBox& box, unsigned level, Octant* parent, Octree* r
 
 
 Octant::~Octant()
 Octant::~Octant()
 {
 {
-    Release();
+    if (root_)
+    {
+        // Remove the drawables (if any) from this octant to the root octant
+        for (PODVector<Drawable*>::Iterator i = drawables_.Begin(); i != drawables_.End(); ++i)
+        {
+            (*i)->SetOctant(root_);
+            root_->drawables_.Push(*i);
+            root_->QueueReinsertion(*i);
+        }
+        drawables_.Clear();
+        numDrawables_ = 0;
+    }
+    
+    for (unsigned i = 0; i < NUM_OCTANTS; ++i)
+        DeleteChild(i);
 }
 }
 
 
 Octant* Octant::GetOrCreateChild(unsigned index)
 Octant* Octant::GetOrCreateChild(unsigned index)
@@ -176,13 +187,13 @@ void Octant::InsertDrawable(Drawable* drawable)
 
 
 bool Octant::CheckDrawableFit(const BoundingBox& box) const
 bool Octant::CheckDrawableFit(const BoundingBox& box) const
 {
 {
-    // If max split level, size always OK, otherwise check that box is at least half size of octant
     Vector3 boxSize = box.Size();
     Vector3 boxSize = box.Size();
     
     
+    // If max split level, size always OK, otherwise check that box is at least half size of octant
     if (level_ >= root_->GetNumLevels() || boxSize.x_ >= halfSize_.x_ || boxSize.y_ >= halfSize_.y_ ||
     if (level_ >= root_->GetNumLevels() || boxSize.x_ >= halfSize_.x_ || boxSize.y_ >= halfSize_.y_ ||
         boxSize.z_ >= halfSize_.z_)
         boxSize.z_ >= halfSize_.z_)
         return true;
         return true;
-    // Also check if the box can not fit a possible child octant's culling box
+    // Also check if the box can not fit a child octant's culling box, in that case size OK (must insert here)
     else
     else
     {
     {
         if (box.min_.x_ <= worldBoundingBox_.min_.x_ - 0.5f * halfSize_.x_ ||
         if (box.min_.x_ <= worldBoundingBox_.min_.x_ - 0.5f * halfSize_.x_ ||
@@ -194,7 +205,7 @@ bool Octant::CheckDrawableFit(const BoundingBox& box) const
             return true;
             return true;
     }
     }
     
     
-    // Should create a child octant
+    // Bounding box too small, should create a child octant
     return false;
     return false;
 }
 }
 
 
@@ -227,6 +238,14 @@ void Octant::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
     }
     }
 }
 }
 
 
+void Octant::Initialize(const BoundingBox& box)
+{
+    worldBoundingBox_ = box;
+    center_ = box.Center();
+    halfSize_ = 0.5f * box.Size();
+    cullingBox_ = BoundingBox(worldBoundingBox_.min_ - halfSize_, worldBoundingBox_.max_ + halfSize_);
+}
+
 void Octant::GetDrawablesInternal(OctreeQuery& query, bool inside) const
 void Octant::GetDrawablesInternal(OctreeQuery& query, bool inside) const
 {
 {
     if (this != root_)
     if (this != root_)
@@ -311,25 +330,6 @@ void Octant::GetDrawablesOnlyInternal(RayOctreeQuery& query, PODVector<Drawable*
     }
     }
 }
 }
 
 
-void Octant::Release()
-{
-    if (root_)
-    {
-        // Remove the drawables (if any) from this octant to the root octant
-        for (PODVector<Drawable*>::Iterator i = drawables_.Begin(); i != drawables_.End(); ++i)
-        {
-            (*i)->SetOctant(root_);
-            root_->drawables_.Push(*i);
-            root_->QueueReinsertion(*i);
-        }
-        drawables_.Clear();
-        numDrawables_ = 0;
-    }
-    
-    for (unsigned i = 0; i < NUM_OCTANTS; ++i)
-        DeleteChild(i);
-}
-
 OBJECTTYPESTATIC(Octree);
 OBJECTTYPESTATIC(Octree);
 
 
 Octree::Octree(Context* context) :
 Octree::Octree(Context* context) :
@@ -380,18 +380,13 @@ void Octree::Resize(const BoundingBox& box, unsigned numLevels)
 {
 {
     PROFILE(ResizeOctree);
     PROFILE(ResizeOctree);
     
     
-    numLevels = Max((int)numLevels, 1);
-    
     // If drawables exist, they are temporarily moved to the root
     // If drawables exist, they are temporarily moved to the root
     for (unsigned i = 0; i < NUM_OCTANTS; ++i)
     for (unsigned i = 0; i < NUM_OCTANTS; ++i)
         DeleteChild(i);
         DeleteChild(i);
     
     
-    worldBoundingBox_ = box;
-    center_ = box.Center();
-    halfSize_ = 0.5f * box.Size();
-    cullingBox_ = BoundingBox(worldBoundingBox_.min_ - halfSize_, worldBoundingBox_.max_ + halfSize_);
+    Initialize(box);
     numDrawables_ = drawables_.Size();
     numDrawables_ = drawables_.Size();
-    numLevels_ = numLevels;
+    numLevels_ = Max((int)numLevels, 1);
 }
 }
 
 
 void Octree::Update(const FrameInfo& frame)
 void Octree::Update(const FrameInfo& frame)
@@ -562,7 +557,7 @@ void Octree::DrawDebugGeometry(bool depthTest)
 
 
 void Octree::UpdateDrawables(const FrameInfo& frame)
 void Octree::UpdateDrawables(const FrameInfo& frame)
 {
 {
-    // Let drawables update themselves before reinsertion
+    // Let drawables update themselves before reinsertion. This can be used for animation
     if (drawableUpdates_.Empty())
     if (drawableUpdates_.Empty())
         return;
         return;
     
     
@@ -597,12 +592,13 @@ void Octree::UpdateDrawables(const FrameInfo& frame)
 
 
 void Octree::ReinsertDrawables(const FrameInfo& frame)
 void Octree::ReinsertDrawables(const FrameInfo& frame)
 {
 {
+    // Reinsert drawables that have been moved or resized, or that have been newly added to the octree and do not sit inside
+    // the proper octant yet
     if (drawableReinsertions_.Empty())
     if (drawableReinsertions_.Empty())
         return;
         return;
     
     
     PROFILE(ReinsertToOctree);
     PROFILE(ReinsertToOctree);
     
     
-    // Reinsert drawables into the octree
     for (Vector<WeakPtr<Drawable> >::Iterator i = drawableReinsertions_.Begin(); i != drawableReinsertions_.End(); ++i)
     for (Vector<WeakPtr<Drawable> >::Iterator i = drawableReinsertions_.Begin(); i != drawableReinsertions_.End(); ++i)
     {
     {
         Drawable* drawable = *i;
         Drawable* drawable = *i;

+ 2 - 2
Engine/Graphics/Octree.h

@@ -93,14 +93,14 @@ public:
     void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     
     
 protected:
 protected:
+    /// Initialize bounding box.
+    void Initialize(const BoundingBox& box);
     /// Return drawable objects by a query, called internally.
     /// Return drawable objects by a query, called internally.
     void GetDrawablesInternal(OctreeQuery& query, bool inside) const;
     void GetDrawablesInternal(OctreeQuery& query, bool inside) const;
     /// Return drawable objects by a ray query, called internally.
     /// Return drawable objects by a ray query, called internally.
     void GetDrawablesInternal(RayOctreeQuery& query) const;
     void GetDrawablesInternal(RayOctreeQuery& query) const;
     /// Return drawable objects only for a threaded ray query, called internally.
     /// Return drawable objects only for a threaded ray query, called internally.
     void GetDrawablesOnlyInternal(RayOctreeQuery& query, PODVector<Drawable*>& drawables) const;
     void GetDrawablesOnlyInternal(RayOctreeQuery& query, PODVector<Drawable*>& drawables) const;
-    /// Free child octants. If drawable objects still exist, move them to root.
-    void Release();
     
     
     /// Increase drawable object count recursively.
     /// Increase drawable object count recursively.
     void IncDrawableCount()
     void IncDrawableCount()

+ 32 - 22
Engine/Physics/RigidBody.cpp

@@ -138,10 +138,15 @@ void RigidBody::ApplyAttributes()
 
 
 void RigidBody::getWorldTransform(btTransform &worldTrans) const
 void RigidBody::getWorldTransform(btTransform &worldTrans) const
 {
 {
-    lastPosition_ = node_->GetWorldPosition();
-    lastRotation_ = node_->GetWorldRotation();
-    worldTrans.setOrigin(ToBtVector3(lastPosition_));
-    worldTrans.setRotation(ToBtQuaternion(lastRotation_));
+    // We may be in a pathological state where a RigidBody exists without a scene node when this callback is fired,
+    // so check to be sure
+    if (node_)
+    {
+        lastPosition_ = node_->GetWorldPosition();
+        lastRotation_ = node_->GetWorldRotation();
+        worldTrans.setOrigin(ToBtVector3(lastPosition_));
+        worldTrans.setRotation(ToBtQuaternion(lastRotation_));
+    }
 }
 }
 
 
 void RigidBody::setWorldTransform(const btTransform &worldTrans)
 void RigidBody::setWorldTransform(const btTransform &worldTrans)
@@ -150,25 +155,30 @@ void RigidBody::setWorldTransform(const btTransform &worldTrans)
     Quaternion newWorldRotation = ToQuaternion(worldTrans.getRotation());
     Quaternion newWorldRotation = ToQuaternion(worldTrans.getRotation());
     RigidBody* parentRigidBody = 0;
     RigidBody* parentRigidBody = 0;
     
     
-    // If the rigid body is parented to another rigid body, can not set the transform immediately.
-    // In that case store it to PhysicsWorld for delayed assignment
-    Node* parent = node_->GetParent();
-    if (parent && parent != GetScene())
-        parentRigidBody = parent->GetComponent<RigidBody>();
-    
-    if (!parentRigidBody)
-        ApplyWorldTransform(newWorldPosition, newWorldRotation);
-    else
-    {
-        DelayedWorldTransform delayed;
-        delayed.rigidBody_ = this;
-        delayed.parentRigidBody_ = parentRigidBody;
-        delayed.worldPosition_ = newWorldPosition;
-        delayed.worldRotation_ = newWorldRotation;
-        physicsWorld_->AddDelayedWorldTransform(delayed);
+    // It is possible that the RigidBody component has been kept alive via a shared pointer,
+    // while its scene node has already been destroyed
+    if (node_)
+    {
+        // If the rigid body is parented to another rigid body, can not set the transform immediately.
+        // In that case store it to PhysicsWorld for delayed assignment
+        Node* parent = node_->GetParent();
+        if (parent && parent != GetScene())
+            parentRigidBody = parent->GetComponent<RigidBody>();
+        
+        if (!parentRigidBody)
+            ApplyWorldTransform(newWorldPosition, newWorldRotation);
+        else
+        {
+            DelayedWorldTransform delayed;
+            delayed.rigidBody_ = this;
+            delayed.parentRigidBody_ = parentRigidBody;
+            delayed.worldPosition_ = newWorldPosition;
+            delayed.worldRotation_ = newWorldRotation;
+            physicsWorld_->AddDelayedWorldTransform(delayed);
+        }
+        
+        MarkNetworkUpdate();
     }
     }
-    
-    MarkNetworkUpdate();
 }
 }
 
 
 void RigidBody::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 void RigidBody::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)

+ 1 - 1
Readme.txt

@@ -45,7 +45,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.25.0 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.26.1 WIP (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/)

+ 108 - 83
ThirdParty/AngelScript/include/angelscript.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 
 // AngelScript version
 // AngelScript version
 
 
-#define ANGELSCRIPT_VERSION        22500
-#define ANGELSCRIPT_VERSION_STRING "2.25.0"
+#define ANGELSCRIPT_VERSION        22601
+#define ANGELSCRIPT_VERSION_STRING "2.26.1 WIP"
 
 
 // Data types
 // Data types
 
 
@@ -73,6 +73,7 @@ class asIObjectType;
 class asIScriptFunction;
 class asIScriptFunction;
 class asIBinaryStream;
 class asIBinaryStream;
 class asIJITCompiler;
 class asIJITCompiler;
+class asIThreadManager;
 
 
 // Enumerations and constants
 // Enumerations and constants
 
 
@@ -102,12 +103,13 @@ enum asEEngineProp
 // Calling conventions
 // Calling conventions
 enum asECallConvTypes
 enum asECallConvTypes
 {
 {
-	asCALL_CDECL            = 0,
-	asCALL_STDCALL          = 1,
-	asCALL_THISCALL         = 2,
-	asCALL_CDECL_OBJLAST    = 3,
-	asCALL_CDECL_OBJFIRST   = 4,
-	asCALL_GENERIC          = 5
+	asCALL_CDECL             = 0,
+	asCALL_STDCALL           = 1,
+	asCALL_THISCALL_ASGLOBAL = 2,
+	asCALL_THISCALL          = 3,
+	asCALL_CDECL_OBJLAST     = 4,
+	asCALL_CDECL_OBJFIRST    = 5,
+	asCALL_GENERIC           = 6
 };
 };
 
 
 // Object type flags
 // Object type flags
@@ -335,7 +337,7 @@ enum asEFuncType
 typedef unsigned char  asBYTE;
 typedef unsigned char  asBYTE;
 typedef unsigned short asWORD;
 typedef unsigned short asWORD;
 typedef unsigned int   asUINT;
 typedef unsigned int   asUINT;
-#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC6 
+#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(__S3E__)
 	// size_t is not really correct, since it only guaranteed to be large enough to hold the segment size.
 	// size_t is not really correct, since it only guaranteed to be large enough to hold the segment size.
 	// For example, on 16bit systems the size_t may be 16bits only even if pointers are 32bit. But nobody
 	// For example, on 16bit systems the size_t may be 16bits only even if pointers are 32bit. But nobody
 	// is likely to use MSVC6 to compile for 16bit systems anymore, so this should be ok.
 	// is likely to use MSVC6 to compile for 16bit systems anymore, so this should be ok.
@@ -397,15 +399,27 @@ typedef void (asCUnknownClass::*asMETHOD_t)();
 
 
 struct asSFuncPtr
 struct asSFuncPtr
 {
 {
-	// Urho3D: modified for smaller executable size
-	asSFuncPtr();
-	asSFuncPtr(asBYTE f);
-	
+	asSFuncPtr(asBYTE f)
+	{
+		for( size_t n = 0; n < sizeof(ptr.dummy); n++ )
+			ptr.dummy[n] = 0;
+		flag = f;
+	}
+
+	void CopyMethodPtr(const void *mthdPtr, size_t size)
+	{
+		for( size_t n = 0; n < size; n++ )
+			ptr.dummy[n] = reinterpret_cast<const char *>(mthdPtr)[n];
+	}
+
 	union
 	union
 	{
 	{
-		// Urho3D: modified for smaller executable size
-		struct {asMETHOD_t   mthd;} m;
-		struct {asFUNCTION_t func;} f;
+		// The largest known method point is 20 bytes (MSVC 64bit),
+		// but with 8byte alignment this becomes 24 bytes. So we need
+		// to be able to store at least that much.
+		char dummy[25]; 
+		struct {asMETHOD_t   mthd; char dummy[25-sizeof(asMETHOD_t)];} m;
+		struct {asFUNCTION_t func; char dummy[25-sizeof(asFUNCTION_t)];} f;
 	} ptr;
 	} ptr;
 	asBYTE flag; // 1 = generic, 2 = global func, 3 = method
 	asBYTE flag; // 1 = generic, 2 = global func, 3 = method
 };
 };
@@ -436,10 +450,17 @@ template <typename T>
 
 
 struct asSFuncPtr
 struct asSFuncPtr
 {
 {
+	asSFuncPtr(asBYTE f)
+	{
+		for( int n = 0; n < sizeof(ptr.dummy); n++ )
+			ptr.dummy[n] = 0;
+		flag = f;
+	}
+
 	union
 	union
 	{
 	{
-		// Urho3D: modified for smaller executable size
-		struct {asFUNCTION_t func;} f;
+		char dummy[25]; // largest known class method pointer
+		struct {asFUNCTION_t func; char dummy[25-sizeof(asFUNCTION_t)];} f;
 	} ptr;
 	} ptr;
 	asBYTE flag; // 1 = generic, 2 = global func
 	asBYTE flag; // 1 = generic, 2 = global func
 };
 };
@@ -486,21 +507,24 @@ struct asSMessageInfo
 extern "C"
 extern "C"
 {
 {
 	// Engine
 	// Engine
-	AS_API asIScriptEngine * asCreateScriptEngine(asDWORD version);
-	AS_API const char * asGetLibraryVersion();
-	AS_API const char * asGetLibraryOptions();
+	AS_API asIScriptEngine *asCreateScriptEngine(asDWORD version);
+	AS_API const char      *asGetLibraryVersion();
+	AS_API const char      *asGetLibraryOptions();
 
 
 	// Context
 	// Context
-	AS_API asIScriptContext * asGetActiveContext();
+	AS_API asIScriptContext *asGetActiveContext();
 
 
 	// Thread support
 	// Thread support
-	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();
+	AS_API int               asPrepareMultithread(asIThreadManager *externalMgr = 0);
+	AS_API void              asUnprepareMultithread();
+	AS_API asIThreadManager *asGetThreadManager();
+	AS_API void              asAcquireExclusiveLock();
+	AS_API void              asReleaseExclusiveLock();
+	AS_API void              asAcquireSharedLock();
+	AS_API void              asReleaseSharedLock();
+	AS_API int               asAtomicInc(int &value);
+	AS_API int               asAtomicDec(int &value);
+	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);
@@ -531,7 +555,7 @@ public:
 	virtual asIJITCompiler *GetJITCompiler() const = 0;
 	virtual asIJITCompiler *GetJITCompiler() const = 0;
 
 
 	// 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, void *objForThiscall = 0) = 0;
 	virtual asUINT             GetGlobalFunctionCount() const = 0;
 	virtual asUINT             GetGlobalFunctionCount() const = 0;
 #ifdef AS_DEPRECATED
 #ifdef AS_DEPRECATED
 	// Deprecated since 2.24.0 - 2012-05-20
 	// Deprecated since 2.24.0 - 2012-05-20
@@ -585,11 +609,12 @@ public:
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace = 0, const char **configGroup = 0, asDWORD *accessMask = 0) const = 0;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace = 0, const char **configGroup = 0, asDWORD *accessMask = 0) const = 0;
 
 
 	// Configuration groups
 	// Configuration groups
-	virtual int     BeginConfigGroup(const char *groupName) = 0;
-	virtual int     EndConfigGroup() = 0;
-	virtual int     RemoveConfigGroup(const char *groupName) = 0;
-	virtual asDWORD SetDefaultAccessMask(asDWORD defaultMask) = 0;
-	virtual int     SetDefaultNamespace(const char *nameSpace) = 0;
+	virtual int         BeginConfigGroup(const char *groupName) = 0;
+	virtual int         EndConfigGroup() = 0;
+	virtual int         RemoveConfigGroup(const char *groupName) = 0;
+	virtual asDWORD     SetDefaultAccessMask(asDWORD defaultMask) = 0;
+	virtual int         SetDefaultNamespace(const char *nameSpace) = 0;
+	virtual const char *GetDefaultNamespace() const = 0;
 
 
 	// Script modules
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag = asGM_ONLY_IF_EXISTS) = 0;
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag = asGM_ONLY_IF_EXISTS) = 0;
@@ -642,6 +667,12 @@ protected:
 	virtual ~asIScriptEngine() {}
 	virtual ~asIScriptEngine() {}
 };
 };
 
 
+class asIThreadManager
+{
+protected:
+	virtual ~asIThreadManager() {}
+};
+
 class asIScriptModule
 class asIScriptModule
 {
 {
 public:
 public:
@@ -650,12 +681,13 @@ public:
 	virtual const char      *GetName() const = 0;
 	virtual const char      *GetName() const = 0;
 
 
 	// Compilation
 	// Compilation
-	virtual int     AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
-	virtual int     Build() = 0;
-	virtual int     CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
-	virtual int     CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
-	virtual asDWORD SetAccessMask(asDWORD accessMask) = 0;
-	virtual int     SetDefaultNamespace(const char *nameSpace) = 0;
+	virtual int         AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
+	virtual int         Build() = 0;
+	virtual int         CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
+	virtual int         CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
+	virtual asDWORD     SetAccessMask(asDWORD accessMask) = 0;
+	virtual int         SetDefaultNamespace(const char *nameSpace) = 0;
+	virtual const char *GetDefaultNamespace() const = 0;
 
 
 	// Functions
 	// Functions
 	virtual asUINT             GetFunctionCount() const = 0;
 	virtual asUINT             GetFunctionCount() const = 0;
@@ -896,8 +928,9 @@ public:
 	virtual asDWORD          GetFlags() const = 0;
 	virtual asDWORD          GetFlags() const = 0;
 	virtual asUINT           GetSize() const = 0;
 	virtual asUINT           GetSize() const = 0;
 	virtual int              GetTypeId() const = 0;
 	virtual int              GetTypeId() const = 0;
-	virtual int              GetSubTypeId() const = 0;
-	virtual asIObjectType   *GetSubType() const = 0;
+	virtual int              GetSubTypeId(asUINT subTypeIndex = 0) const = 0;
+	virtual asIObjectType   *GetSubType(asUINT subTypeIndex = 0) const = 0;
+	virtual asUINT           GetSubTypeCount() const = 0;
 
 
 	// Interfaces
 	// Interfaces
 	virtual asUINT           GetInterfaceCount() const = 0;
 	virtual asUINT           GetInterfaceCount() const = 0;
@@ -1009,32 +1042,24 @@ public:
 //-----------------------------------------------------------------
 //-----------------------------------------------------------------
 // Function pointers
 // Function pointers
 
 
-// Use our own memset() and memcpy() implementations for better portability
-inline void asMemClear(void *_p, size_t size)
-{
-	char *p = reinterpret_cast<char *>(_p);
-	const char *e = p + size;
-	for( ; p < e; p++ )
-		*p = 0;
-}
-
-inline void asMemCopy(void *_d, const void *_s, size_t size)
-{
-	char *d = reinterpret_cast<char *>(_d);
-	const char *s = reinterpret_cast<const char *>(_s);
-	const char *e = s + size;
-	for( ; s < e; d++, s++ )
-		*d = *s;
-}
-
 // Template function to capture all global functions,
 // Template function to capture all global functions,
 // except the ones using the generic calling convention
 // except the ones using the generic calling convention
 template <class T>
 template <class T>
 inline asSFuncPtr asFunctionPtr(T func)
 inline asSFuncPtr asFunctionPtr(T func)
 {
 {
-	// Urho3D: modified for smaller executable size
+	// Mark this as a global function
 	asSFuncPtr p(2);
 	asSFuncPtr p(2);
-	p.ptr.f.func = (asFUNCTION_t)(size_t)func;
+
+#ifdef AS_64BIT_PTR
+	// The size_t cast is to avoid a compiler warning with asFUNCTION(0) 
+	// on 64bit, as 0 is interpreted as a 32bit int value
+	p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(size_t(func));
+#else
+	// MSVC6 doesn't like the size_t cast above so I
+	// solved this with a separate code for 32bit.
+	p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(func);
+#endif
+
 	return p;
 	return p;
 }
 }
 
 
@@ -1042,9 +1067,9 @@ inline asSFuncPtr asFunctionPtr(T func)
 template<>
 template<>
 inline asSFuncPtr asFunctionPtr<asGENFUNC_t>(asGENFUNC_t func)
 inline asSFuncPtr asFunctionPtr<asGENFUNC_t>(asGENFUNC_t func)
 {
 {
-	// Urho3D: modified for smaller executable size
+	// Mark this as a generic function
 	asSFuncPtr p(1);
 	asSFuncPtr p(1);
-	p.ptr.f.func = (asFUNCTION_t)func;
+	p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(func);
 	return p;
 	return p;
 }
 }
 
 
@@ -1069,7 +1094,7 @@ struct asSMethodPtr
 
 
 		int ERROR_UnsupportedMethodPtr[N-100];
 		int ERROR_UnsupportedMethodPtr[N-100];
 
 
-		asSFuncPtr p;
+		asSFuncPtr p(0);
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1081,9 +1106,9 @@ struct asSMethodPtr<SINGLE_PTR_SIZE>
 	template<class M>
 	template<class M>
 	static asSFuncPtr Convert(M Mthd)
 	static asSFuncPtr Convert(M Mthd)
 	{
 	{
-		// Urho3D: modified for smaller executable size
+		// Mark this as a class method
 		asSFuncPtr p(3);
 		asSFuncPtr p(3);
-		asMemCopy(&p, &Mthd, SINGLE_PTR_SIZE);
+		p.CopyMethodPtr(&Mthd, SINGLE_PTR_SIZE);
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1097,9 +1122,9 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+1*sizeof(int)>
 	template <class M>
 	template <class M>
 	static asSFuncPtr Convert(M Mthd)
 	static asSFuncPtr Convert(M Mthd)
 	{
 	{
-		// Urho3D: modified for smaller executable size
+		// Mark this as a class method
 		asSFuncPtr p(3);
 		asSFuncPtr p(3);
-		asMemCopy(&p, &Mthd, SINGLE_PTR_SIZE+sizeof(int));
+		p.CopyMethodPtr(&Mthd, SINGLE_PTR_SIZE+sizeof(int));
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1113,10 +1138,10 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+2*sizeof(int)>
 		// On 32bit platforms with is where a class with virtual inheritance falls.
 		// On 32bit platforms with is where a class with virtual inheritance falls.
 		// On 64bit platforms we can also fall here if 8byte data alignments is used.
 		// On 64bit platforms we can also fall here if 8byte data alignments is used.
 
 
-		// Urho3D: modified for smaller executable size
+		// Mark this as a class method
 		asSFuncPtr p(3);
 		asSFuncPtr p(3);
-		asMemCopy(&p, &Mthd, SINGLE_PTR_SIZE+2*sizeof(int));
-		/*
+		p.CopyMethodPtr(&Mthd, SINGLE_PTR_SIZE+2*sizeof(int));
+
 		// Microsoft has a terrible optimization on class methods with virtual inheritance.
 		// Microsoft has a terrible optimization on class methods with virtual inheritance.
 		// They are hardcoding an important offset, which is not coming in the method pointer.
 		// They are hardcoding an important offset, which is not coming in the method pointer.
 
 
@@ -1138,9 +1163,9 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+2*sizeof(int)>
 
 
 			// Copy the virtual table index to the 4th dword so that AngelScript
 			// Copy the virtual table index to the 4th dword so that AngelScript
 			// can properly detect and deny the use of methods with virtual inheritance.
 			// can properly detect and deny the use of methods with virtual inheritance.
-			*(static_cast<asDWORD*>(&p)+3) = *(static_cast<asDWORD*>(&p)+2);
+			*(reinterpret_cast<asDWORD*>(&p)+3) = *(reinterpret_cast<asDWORD*>(&p)+2);
 #endif
 #endif
-		*/
+
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1151,9 +1176,9 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+3*sizeof(int)>
 	template <class M>
 	template <class M>
 	static asSFuncPtr Convert(M Mthd)
 	static asSFuncPtr Convert(M Mthd)
 	{
 	{
-		// Urho3D: modified for smaller executable size
+		// Mark this as a class method
 		asSFuncPtr p(3);
 		asSFuncPtr p(3);
-		asMemCopy(&p, &Mthd, SINGLE_PTR_SIZE+3*sizeof(int));
+		p.CopyMethodPtr(&Mthd, SINGLE_PTR_SIZE+3*sizeof(int));
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1166,9 +1191,10 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+4*sizeof(int)>
 	{
 	{
 		// On 64bit platforms with 8byte data alignment
 		// On 64bit platforms with 8byte data alignment
 		// the unknown class method pointers will come here.
 		// the unknown class method pointers will come here.
-		// Urho3D: modified for smaller executable size
+
+		// Mark this as a class method
 		asSFuncPtr p(3);
 		asSFuncPtr p(3);
-		asMemCopy(&p, &Mthd, SINGLE_PTR_SIZE+4*sizeof(int));
+		p.CopyMethodPtr(&Mthd, SINGLE_PTR_SIZE+4*sizeof(int));
 		return p;
 		return p;
 	}
 	}
 };
 };
@@ -1399,7 +1425,6 @@ enum asEBCInstr
 	asBC_MAXBYTECODE	= 189,
 	asBC_MAXBYTECODE	= 189,
 
 
 	// Temporary tokens. Can't be output to the final program
 	// Temporary tokens. Can't be output to the final program
-	asBC_DiscardVar		= 250,
 	asBC_VarDecl		= 251,
 	asBC_VarDecl		= 251,
 	asBC_Block			= 252,
 	asBC_Block			= 252,
 	asBC_ObjInfo		= 253,
 	asBC_ObjInfo		= 253,
@@ -1563,7 +1588,7 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO(GETOBJREF,	W_ARG,			0),
 	asBCINFO(GETOBJREF,	W_ARG,			0),
 	asBCINFO(GETREF,	W_ARG,			0),
 	asBCINFO(GETREF,	W_ARG,			0),
 	asBCINFO(PshNull,	NO_ARG,			AS_PTR_SIZE),
 	asBCINFO(PshNull,	NO_ARG,			AS_PTR_SIZE),
-	asBCINFO(ClrVPtr,	rW_ARG,			0),
+	asBCINFO(ClrVPtr,	wW_ARG,			0),
 	asBCINFO(OBJTYPE,	PTR_ARG,		AS_PTR_SIZE),
 	asBCINFO(OBJTYPE,	PTR_ARG,		AS_PTR_SIZE),
 	asBCINFO(TYPEID,	DW_ARG,			1),
 	asBCINFO(TYPEID,	DW_ARG,			1),
 	asBCINFO(SetV4,		wW_DW_ARG,		0),
 	asBCINFO(SetV4,		wW_DW_ARG,		0),
@@ -1740,8 +1765,8 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO_DUMMY(247),
 	asBCINFO_DUMMY(247),
 	asBCINFO_DUMMY(248),
 	asBCINFO_DUMMY(248),
 	asBCINFO_DUMMY(249),
 	asBCINFO_DUMMY(249),
+	asBCINFO_DUMMY(250),
 
 
-	asBCINFO(DiscardVar,	W_ARG,			0),
 	asBCINFO(VarDecl,		W_ARG,			0),
 	asBCINFO(VarDecl,		W_ARG,			0),
 	asBCINFO(Block,			INFO,			0),
 	asBCINFO(Block,			INFO,			0),
 	asBCINFO(ObjInfo,		rW_DW_ARG,		0),
 	asBCINFO(ObjInfo,		rW_DW_ARG,		0),

+ 12 - 2
ThirdParty/AngelScript/source/as_array.h

@@ -75,8 +75,9 @@ public:
 
 
 	bool Exists(T &element) const;
 	bool Exists(T &element) const;
 	int  IndexOf(T &element) const;
 	int  IndexOf(T &element) const;
-	void RemoveIndex(size_t index);     // Removes the entry without reordering the array
-	void RemoveValue(const T &element);
+	void RemoveIndex(size_t index);          // Removes the entry without reordering the array
+	void RemoveValue(const T &element);      // Removes the value without reordering the array
+	void RemoveIndexUnordered(size_t index); // Removes the entry without keeping the order
 
 
 	bool operator==(const asCArray<T> &) const;
 	bool operator==(const asCArray<T> &) const;
 	bool operator!=(const asCArray<T> &) const;
 	bool operator!=(const asCArray<T> &) const;
@@ -501,6 +502,15 @@ void asCArray<T>::RemoveValue(const T &e)
 	}
 	}
 }
 }
 
 
+template <class T>
+void asCArray<T>::RemoveIndexUnordered(size_t index)
+{
+	if( index == length - 1 )
+		PopLast();
+	else if( index < length )
+		array[index] = PopLast();
+}
+
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 
 #endif
 #endif

+ 21 - 31
ThirdParty/AngelScript/source/as_atomic.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -29,9 +29,9 @@
 */
 */
  
  
 //
 //
-// as_gc.cpp
+// as_atomic.cpp
 //
 //
-// The implementation of the garbage collector
+// The implementation of the atomic class for thread safe reference counting
 //
 //
 
 
 #include "as_atomic.h"
 #include "as_atomic.h"
@@ -53,39 +53,29 @@ void asCAtomic::set(asDWORD val)
 	value = val;
 	value = val;
 }
 }
 
 
-//
-// The following code implements the atomicInc and atomicDec on different platforms
-//
-#ifdef AS_NO_THREADS
-
 asDWORD asCAtomic::atomicInc()
 asDWORD asCAtomic::atomicInc()
 {
 {
-	return ++value;
+	return asAtomicInc((int&)value);
 }
 }
 
 
 asDWORD asCAtomic::atomicDec()
 asDWORD asCAtomic::atomicDec()
 {
 {
-	return --value;
+	return asAtomicDec((int&)value);
 }
 }
 
 
-#elif defined(AS_NO_ATOMIC)
+//
+// The following code implements the atomicInc and atomicDec on different platforms
+//
+#if defined(AS_NO_THREADS) || defined(AS_NO_ATOMIC)
 
 
-asDWORD asCAtomic::atomicInc()
+int asAtomicInc(int &value)
 {
 {
-	asDWORD v;
-	ENTERCRITICALSECTION(cs);
-	v = ++value;
-	LEAVECRITICALSECTION(cs);
-	return v;
+	return ++value;
 }
 }
 
 
-asDWORD asCAtomic::atomicDec()
+int asAtomicDec(int &value)
 {
 {
-	asDWORD v;
-	ENTERCRITICALSECTION(cs);
-	v = --value;
-	LEAVECRITICALSECTION(cs);
-	return v;
+	return --value;
 }
 }
 
 
 #elif defined(AS_XENON) /// XBox360
 #elif defined(AS_XENON) /// XBox360
@@ -94,12 +84,12 @@ END_AS_NAMESPACE
 #include <xtl.h>
 #include <xtl.h>
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-asDWORD asCAtomic::atomicInc()
+int asAtomicInc(int &value)
 {
 {
 	return InterlockedIncrement((LONG*)&value);
 	return InterlockedIncrement((LONG*)&value);
 }
 }
 
 
-asDWORD asCAtomic::atomicDec()
+int asAtomicDec(int &value)
 {
 {
 	return InterlockedDecrement((LONG*)&value);
 	return InterlockedDecrement((LONG*)&value);
 }
 }
@@ -111,12 +101,12 @@ END_AS_NAMESPACE
 #include <windows.h>
 #include <windows.h>
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-asDWORD asCAtomic::atomicInc()
+int asAtomicInc(int &value)
 {
 {
 	return InterlockedIncrement((LONG*)&value);
 	return InterlockedIncrement((LONG*)&value);
 }
 }
 
 
-asDWORD asCAtomic::atomicDec()
+int asAtomicDec(int &value)
 {
 {
 	asASSERT(value > 0);
 	asASSERT(value > 0);
 	return InterlockedDecrement((LONG*)&value);
 	return InterlockedDecrement((LONG*)&value);
@@ -135,12 +125,12 @@ asDWORD asCAtomic::atomicDec()
 // use the critical sections, though it is a lot slower.
 // use the critical sections, though it is a lot slower.
 // 
 // 
 
 
-asDWORD asCAtomic::atomicInc()
+int asAtomicInc(int &value)
 {
 {
 	return __sync_add_and_fetch(&value, 1);
 	return __sync_add_and_fetch(&value, 1);
 }
 }
 
 
-asDWORD asCAtomic::atomicDec()
+int asAtomicDec(int &value)
 {
 {
 	return __sync_sub_and_fetch(&value, 1);
 	return __sync_sub_and_fetch(&value, 1);
 }
 }
@@ -151,12 +141,12 @@ END_AS_NAMESPACE
 #include <libkern/OSAtomic.h>
 #include <libkern/OSAtomic.h>
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-asDWORD asCAtomic::atomicInc()
+int asAtomicInc(int &value)
 {
 {
 	return OSAtomicIncrement32((int32_t*)&value);
 	return OSAtomicIncrement32((int32_t*)&value);
 }
 }
 
 
-asDWORD asCAtomic::atomicDec()
+int asAtomicDec(int &value)
 {
 {
 	return OSAtomicDecrement32((int32_t*)&value);
 	return OSAtomicDecrement32((int32_t*)&value);
 }
 }

+ 1 - 6
ThirdParty/AngelScript/source/as_atomic.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -43,7 +43,6 @@
 #define AS_ATOMIC_H
 #define AS_ATOMIC_H
 
 
 #include "as_config.h"
 #include "as_config.h"
-#include "as_criticalsection.h"
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
@@ -63,10 +62,6 @@ public:
 
 
 protected:
 protected:
 	asDWORD value;
 	asDWORD value;
-
-#if !defined(AS_NO_THREADS) && defined(AS_NO_ATOMIC)
-	DECLARECRITICALSECTION(cs)
-#endif
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

File diff suppressed because it is too large
+ 397 - 161
ThirdParty/AngelScript/source/as_builder.cpp


+ 54 - 46
ThirdParty/AngelScript/source/as_builder.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -53,74 +53,77 @@ BEGIN_AS_NAMESPACE
 
 
 #ifndef AS_NO_COMPILER
 #ifndef AS_NO_COMPILER
 
 
-struct sExplicitSignature
-{
-	sExplicitSignature(int argCount = 0) : argTypes(argCount), argModifiers(argCount), argNames(argCount), defaultArgs(argCount) {}
-
-	asCDataType returnType;
-	asCArray<asCDataType> argTypes;
-	asCArray<asETypeModifiers> argModifiers;
-	asCArray<asCString> argNames;
-	asCArray<asCString *> defaultArgs;
-};
-
 struct sFunctionDescription
 struct sFunctionDescription
 {
 {
-	asCScriptCode *script;
-	asCScriptNode *node;
-	asCString name;
-	asCObjectType *objType;
-	sExplicitSignature *explicitSignature;
-	int funcId;
-	bool isExistingShared;
+	asCScriptCode       *script;
+	asCScriptNode       *node;
+	asCString            name;
+	asCObjectType       *objType;
+	asCArray<asCString>  paramNames;
+	int                  funcId;
+	bool                 isExistingShared;
 };
 };
 
 
 struct sGlobalVariableDescription
 struct sGlobalVariableDescription
 {
 {
-	asCScriptCode *script;
-	asCScriptNode *idNode;
-	asCScriptNode *nextNode;
-	asCString name;
+	asCScriptCode     *script;
+	asCScriptNode     *idNode;
+	asCScriptNode     *nextNode;
+	asCString          name;
 	asCGlobalProperty *property;
 	asCGlobalProperty *property;
-	asCDataType datatype;
-	int index;
-	bool isCompiled;
-	bool isPureConstant;
-	bool isEnumValue;
-	asQWORD constantValue;
+	asCDataType        datatype;
+	int                index;
+	bool               isCompiled;
+	bool               isPureConstant;
+	bool               isEnumValue;
+	asQWORD            constantValue;
 };
 };
 
 
 // asCSymbolTable template specializations for sGlobalVariableDescription entries
 // asCSymbolTable template specializations for sGlobalVariableDescription entries
 template<>
 template<>
 void asCSymbolTable<sGlobalVariableDescription>::GetKey(const sGlobalVariableDescription *entry, asCString &key) const;
 void asCSymbolTable<sGlobalVariableDescription>::GetKey(const sGlobalVariableDescription *entry, asCString &key) const;
 
 
+struct sPropertyInitializer
+{
+	sPropertyInitializer() : declNode(0), initNode(0), file(0) {}
+	sPropertyInitializer(const asCString &nm, asCScriptNode *decl, asCScriptNode *init, asCScriptCode *f) : name(nm), declNode(decl), initNode(init), file(f) {}
+	sPropertyInitializer &operator=(const sPropertyInitializer &o) {name = o.name; declNode = o.declNode; initNode = o.initNode; file = o.file; return *this;}
+
+	asCString      name;
+	asCScriptNode *declNode;
+	asCScriptNode *initNode;
+	asCScriptCode *file;
+};
+
 struct sClassDeclaration
 struct sClassDeclaration
 {
 {
 	sClassDeclaration() {script = 0; node = 0; validState = 0; objType = 0; isExistingShared = false; isFinal = false;}
 	sClassDeclaration() {script = 0; node = 0; validState = 0; objType = 0; isExistingShared = false; isFinal = false;}
 
 
 	asCScriptCode *script;
 	asCScriptCode *script;
 	asCScriptNode *node;
 	asCScriptNode *node;
-	asCString name;
-	int validState;
+	asCString      name;
+	int            validState;
 	asCObjectType *objType;
 	asCObjectType *objType;
-	bool isExistingShared;
-	bool isFinal;
+	bool           isExistingShared;
+	bool           isFinal;
+
+	asCArray<sPropertyInitializer> propInits;
 };
 };
 
 
 struct sFuncDef
 struct sFuncDef
 {
 {
 	asCScriptCode *script;
 	asCScriptCode *script;
 	asCScriptNode *node;
 	asCScriptNode *node;
-	asCString name;
-	int idx;
+	asCString      name;
+	int            idx;
 };
 };
 
 
 struct sMixinClass
 struct sMixinClass
 {
 {
 	asCScriptCode *script;
 	asCScriptCode *script;
 	asCScriptNode *node;
 	asCScriptNode *node;
-	asCString name;
-	asSNameSpace *ns;
+	asCString      name;
+	asSNameSpace  *ns;
 };
 };
 
 
 #endif // AS_NO_COMPILER
 #endif // AS_NO_COMPILER
@@ -134,7 +137,7 @@ public:
 	// These methods are used by the application interface
 	// These methods are used by the application interface
 	int VerifyProperty(asCDataType *dt, const char *decl, asCString &outName, asCDataType &outType, asSNameSpace *ns);
 	int VerifyProperty(asCDataType *dt, const char *decl, asCString &outName, asCDataType &outType, asSNameSpace *ns);
 	int ParseDataType(const char *datatype, asCDataType *result, asSNameSpace *implicitNamespace, bool isReturnType = false);
 	int ParseDataType(const char *datatype, asCDataType *result, asSNameSpace *implicitNamespace, bool isReturnType = false);
-	int ParseTemplateDecl(const char *decl, asCString *name, asCString *subtypeName);
+	int ParseTemplateDecl(const char *decl, asCString *name, asCArray<asCString> &subtypeNames);
 	int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0);
 	int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0);
 	int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
 	int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
 	int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns);
 	int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns);
@@ -154,11 +157,11 @@ protected:
 
 
 	void               Reset();
 	void               Reset();
 
 
-	void               WriteInfo(const char *scriptname, const char *msg, int r, int c, bool preMessage);
-	void               WriteInfo(const char *msg, asCScriptCode *file, asCScriptNode *node);
-	void               WriteError(const char *scriptname, const char *msg, int r, int c);
-	void               WriteError(const char *msg, asCScriptCode *file, asCScriptNode *node);
-	void               WriteWarning(const char *scriptname, const char *msg, int r, int c);
+	void               WriteInfo(const asCString &scriptname, const asCString &msg, int r, int c, bool preMessage);
+	void               WriteInfo(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
+	void               WriteError(const asCString &scriptname, const asCString &msg, int r, int c);
+	void               WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
+	void               WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
 
 
 	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
 	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
 	asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
 	asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
@@ -170,6 +173,7 @@ protected:
 	int                ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
 	int                ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
 
 
+	asSNameSpace      *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next);
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
 
 
 	bool               DoesTypeExist(const char *type);
 	bool               DoesTypeExist(const char *type);
@@ -198,13 +202,16 @@ protected:
 protected:
 protected:
 	friend class asCCompiler;
 	friend class asCCompiler;
 
 
+	int                GetNamespaceAndNameFromNode(asCScriptNode *n, asCScriptCode *script, asSNameSpace *implicitNs, asSNameSpace *&outNs, asCString &outName);
 	int                RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	sMixinClass       *GetMixinClass(const char *name, asSNameSpace *ns);
 	sMixinClass       *GetMixinClass(const char *name, asSNameSpace *ns);
 	void               IncludePropertiesFromMixins(sClassDeclaration *decl);
 	void               IncludePropertiesFromMixins(sClassDeclaration *decl);
 	void               IncludeMethodsFromMixins(sClassDeclaration *decl);
 	void               IncludeMethodsFromMixins(sClassDeclaration *decl);
+	void               AddInterfaceToClass(sClassDeclaration *decl, asCScriptNode *errNode, asCObjectType *intf);
+	void               AddInterfaceFromMixinToClass(sClassDeclaration *decl, asCScriptNode *errNode, sMixinClass *mixin);
 
 
-	int                RegisterScriptFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false, bool isMixin = false);
-	int                RegisterScriptFunctionWithSignature(int funcID, asCScriptNode *node, asCScriptCode *file, asCString &name, sExplicitSignature *signature, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, bool isPrivate = false, bool isConst = false, bool isFinal = false, bool isOverride = false, bool treatAsProperty = false, asSNameSpace *ns = 0);
+	int                RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false, bool isMixin = false);
+	int                RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isOverride, bool isFinal, bool isShared);
 	int                RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false);
 	int                RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false);
 	int                RegisterImportedFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterImportedFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
@@ -214,8 +221,9 @@ protected:
 	int                RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	void               CompleteFuncDef(sFuncDef *funcDef);
 	void               CompleteFuncDef(sFuncDef *funcDef);
+	void               CompileInterfaces();
 	void               CompileClasses();
 	void               CompileClasses();
-	void               GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isOverride, bool &isFinal, bool &isShared);
+	void               GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isOverride, bool &isFinal, bool &isShared, asSNameSpace *implicitNamespace);
 	bool               DoesMethodExist(asCObjectType *objType, int methodId, asUINT *methodIndex = 0);
 	bool               DoesMethodExist(asCObjectType *objType, int methodId, asUINT *methodIndex = 0);
 	void               AddDefaultConstructor(asCObjectType *objType, asCScriptCode *file);
 	void               AddDefaultConstructor(asCObjectType *objType, asCScriptCode *file);
 	asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, asCScriptCode *file = 0, asCScriptNode *node = 0);
 	asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, asCScriptCode *file = 0, asCScriptNode *node = 0);

File diff suppressed because it is too large
+ 545 - 372
ThirdParty/AngelScript/source/as_bytecode.cpp


+ 11 - 8
ThirdParty/AngelScript/source/as_bytecode.h

@@ -66,9 +66,10 @@ public:
 
 
 	int GetSize();
 	int GetSize();
 
 
-	void Finalize();
+	void Finalize(const asCArray<int> &tempVariableOffsets);
 
 
-	int  Optimize();
+	void Optimize();
+	void OptimizeLocally(const asCArray<int> &tempVariableOffsets);
 	void ExtractLineNumbers();
 	void ExtractLineNumbers();
 	void ExtractObjectVariableInfo(asCScriptFunction *outFunc);
 	void ExtractObjectVariableInfo(asCScriptFunction *outFunc);
 	int  ResolveJumpAddresses();
 	int  ResolveJumpAddresses();
@@ -96,11 +97,10 @@ public:
 	bool IsSimpleExpression();
 	bool IsSimpleExpression();
 
 
 	void Label(short label);
 	void Label(short label);
-	void Line(int line, int column);
+	void Line(int line, int column, int scriptIdx);
 	void ObjInfo(int offset, int info);
 	void ObjInfo(int offset, int info);
 	void Block(bool start);
 	void Block(bool start);
 	void VarDecl(int varDeclIdx);
 	void VarDecl(int varDeclIdx);
-	void DiscardVar(int varIdx);
 	void Call(asEBCInstr bc, int funcID, int pop);
 	void Call(asEBCInstr bc, int funcID, int pop);
 	void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
 	void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
 	void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
 	void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
@@ -130,11 +130,13 @@ public:
 	int InstrW_W(asEBCInstr bc, int w, int b);
 	int InstrW_W(asEBCInstr bc, int w, int b);
 
 
 	asCArray<int> lineNumbers;
 	asCArray<int> lineNumbers;
+	asCArray<int> sectionIdxs;
 	int largestStackUsed;
 	int largestStackUsed;
 
 
-	void DefineTemporaryVariable(int varOffset);
-
 protected:
 protected:
+	// Assignments are not allowed
+	void operator=(const asCByteCode &) {}
+
 	// Helpers for Optimize
 	// Helpers for Optimize
 	bool CanBeSwapped(asCByteInstruction *curr);
 	bool CanBeSwapped(asCByteInstruction *curr);
 	asCByteInstruction *ChangeFirstDeleteNext(asCByteInstruction *curr, asEBCInstr bc);
 	asCByteInstruction *ChangeFirstDeleteNext(asCByteInstruction *curr, asEBCInstr bc);
@@ -142,9 +144,10 @@ protected:
 	asCByteInstruction *DeleteInstruction(asCByteInstruction *instr);
 	asCByteInstruction *DeleteInstruction(asCByteInstruction *instr);
 	void RemoveInstruction(asCByteInstruction *instr);
 	void RemoveInstruction(asCByteInstruction *instr);
 	asCByteInstruction *GoBack(asCByteInstruction *curr);
 	asCByteInstruction *GoBack(asCByteInstruction *curr);
+	asCByteInstruction *GoForward(asCByteInstruction *curr);
 	void InsertBefore(asCByteInstruction *before, asCByteInstruction *instr);
 	void InsertBefore(asCByteInstruction *before, asCByteInstruction *instr);
 	bool RemoveUnusedValue(asCByteInstruction *curr, asCByteInstruction **next);
 	bool RemoveUnusedValue(asCByteInstruction *curr, asCByteInstruction **next);
-	bool IsTemporary(short offset);
+	bool IsTemporary(int offset);
 	bool IsTempRegUsed(asCByteInstruction *curr);
 	bool IsTempRegUsed(asCByteInstruction *curr);
 	bool IsTempVarRead(asCByteInstruction *curr, int offset);
 	bool IsTempVarRead(asCByteInstruction *curr, int offset);
 	bool PostponeInitOfTemp(asCByteInstruction *curr, asCByteInstruction **next);
 	bool PostponeInitOfTemp(asCByteInstruction *curr, asCByteInstruction **next);
@@ -158,7 +161,7 @@ protected:
 	asCByteInstruction *first;
 	asCByteInstruction *first;
 	asCByteInstruction *last;
 	asCByteInstruction *last;
 
 
-	asCArray<int> temporaryVariables;
+	const asCArray<int> *temporaryVariables;
 
 
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
 };
 };

+ 29 - 24
ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -44,20 +44,21 @@
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, asSSystemFunctionInterface *internal)
+int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal)
 {
 {
 	memset(internal, 0, sizeof(asSSystemFunctionInterface));
 	memset(internal, 0, sizeof(asSSystemFunctionInterface));
 
 
-	internal->func = ptr.ptr.f.func;
+	internal->func           = ptr.ptr.f.func;
+	internal->objForThiscall = 0;
 
 
 	// Was a compatible calling convention specified?
 	// Was a compatible calling convention specified?
 	if( internal->func )
 	if( internal->func )
 	{
 	{
 		if( ptr.flag == 1 && callConv != asCALL_GENERIC )
 		if( ptr.flag == 1 && callConv != asCALL_GENERIC )
 			return asWRONG_CALLING_CONV;
 			return asWRONG_CALLING_CONV;
-		else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL) )
+		else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
 			return asWRONG_CALLING_CONV;
 			return asWRONG_CALLING_CONV;
-		else if( ptr.flag == 3 && callConv != asCALL_THISCALL )
+		else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
 			return asWRONG_CALLING_CONV;
 			return asWRONG_CALLING_CONV;
 	}
 	}
 
 
@@ -68,6 +69,13 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 			internal->callConv = ICC_CDECL;
 			internal->callConv = ICC_CDECL;
 		else if( base == asCALL_STDCALL )
 		else if( base == asCALL_STDCALL )
 			internal->callConv = ICC_STDCALL;
 			internal->callConv = ICC_STDCALL;
+		else if( base == asCALL_THISCALL_ASGLOBAL )
+		{
+			if( objForThiscall == 0 )
+				return asINVALID_ARG;
+			internal->objForThiscall = objForThiscall;
+			internal->callConv       = ICC_THISCALL;
+		}
 		else if( base == asCALL_GENERIC )
 		else if( base == asCALL_GENERIC )
 			internal->callConv = ICC_GENERIC_FUNC;
 			internal->callConv = ICC_GENERIC_FUNC;
 		else
 		else
@@ -409,7 +417,13 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 
 
 	if( callConv >= ICC_THISCALL )
 	if( callConv >= ICC_THISCALL )
 	{
 	{
-		if( objectPointer )
+		if( sysFunc->objForThiscall )
+		{
+			// This class method is being called as if it is a global function
+			obj = sysFunc->objForThiscall;
+			asASSERT( objectPointer == 0 );
+		}
+		else if( objectPointer )
 		{
 		{
 			obj = objectPointer;
 			obj = objectPointer;
 		}
 		}
@@ -423,8 +437,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			if( obj == 0 )
 			if( obj == 0 )
 			{
 			{
 				context->SetInternalException(TXT_NULL_POINTER_ACCESS);
 				context->SetInternalException(TXT_NULL_POINTER_ACCESS);
-				if( retPointer )
-					engine->CallFree(retPointer);
 				return 0;
 				return 0;
 			}
 			}
 
 
@@ -548,6 +560,8 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 		}
 		}
 		else
 		else
 		{
 		{
+			asASSERT( retPointer );
+
 			if( !sysFunc->hostReturnInMemory )
 			if( !sysFunc->hostReturnInMemory )
 			{
 			{
 				// Copy the returned value to the pointer sent by the script engine
 				// Copy the returned value to the pointer sent by the script engine
@@ -575,23 +589,14 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 				}
 				}
 			}
 			}
 
 
-			// Store the object in the register
-			context->m_regs.objectRegister = retPointer;
-
-			// If the value is returned on the stack we shouldn't update the object register
-			if( descr->DoesReturnOnStack() )
+			if( context->m_status == asEXECUTION_EXCEPTION )
 			{
 			{
-				context->m_regs.objectRegister = 0;
-
-				if( context->m_status == asEXECUTION_EXCEPTION )
-				{
-					// If the function raised a script exception it really shouldn't have 
-					// initialized the object. However, as it is a soft exception there is 
-					// no way for the application to not return a value, so instead we simply
-					// destroy it here, to pretend it was never created.
-					if( descr->returnType.GetObjectType()->beh.destruct )
-						engine->CallObjectMethod(retPointer, descr->returnType.GetObjectType()->beh.destruct);
-				}
+				// If the function raised a script exception it really shouldn't have 
+				// initialized the object. However, as it is a soft exception there is 
+				// no way for the application to not return a value, so instead we simply
+				// destroy it here, to pretend it was never created.
+				if( descr->returnType.GetObjectType()->beh.destruct )
+					engine->CallObjectMethod(retPointer, descr->returnType.GetObjectType()->beh.destruct);
 			}
 			}
 		}
 		}
 	}
 	}

+ 3 - 1
ThirdParty/AngelScript/source/as_callfunc.h

@@ -48,7 +48,7 @@ class asCScriptEngine;
 class asCScriptFunction;
 class asCScriptFunction;
 struct asSSystemFunctionInterface;
 struct asSSystemFunctionInterface;
 
 
-int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, asSSystemFunctionInterface *internal);
+int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal);
 
 
 int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
 int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
 
 
@@ -100,6 +100,7 @@ struct asSSystemFunctionInterface
 	asCArray<bool>       paramAutoHandles;
 	asCArray<bool>       paramAutoHandles;
 	bool                 returnAutoHandle;
 	bool                 returnAutoHandle;
 	bool                 hasAutoHandles;
 	bool                 hasAutoHandles;
+	void                *objForThiscall;
 
 
 	asSSystemFunctionInterface() {}
 	asSSystemFunctionInterface() {}
 
 
@@ -122,6 +123,7 @@ struct asSSystemFunctionInterface
 		paramAutoHandles   = in.paramAutoHandles;
 		paramAutoHandles   = in.paramAutoHandles;
 		returnAutoHandle   = in.returnAutoHandle;
 		returnAutoHandle   = in.returnAutoHandle;
 		hasAutoHandles     = in.hasAutoHandles;
 		hasAutoHandles     = in.hasAutoHandles;
+		objForThiscall     = in.objForThiscall;
 		return *this;
 		return *this;
 	}
 	}
 };
 };

+ 10 - 4
ThirdParty/AngelScript/source/as_callfunc_arm.cpp

@@ -37,7 +37,7 @@
 // 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
+// This code has to conform to both AAPCS and the modified ABI for iOS
 //
 //
 // Reference:
 // Reference:
 //
 //
@@ -186,10 +186,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		break;
 		break;
 	case ICC_THISCALL_RETURNINMEM:
 	case ICC_THISCALL_RETURNINMEM:
-#ifndef __GNUC__
+#ifdef __GNUC__
+		// On GNUC the address where the return value will be placed should be put in R0
+		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
+#else
+		// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)obj, (asDWORD)retPointer);
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)obj, (asDWORD)retPointer);
-		break;
 #endif
 #endif
+		break;
 	case ICC_CDECL_OBJFIRST_RETURNINMEM:
 	case ICC_CDECL_OBJFIRST_RETURNINMEM:
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
 		break;
@@ -201,9 +205,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	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 = *(asFUNCTION_t**)obj;
 		vftable = *(asFUNCTION_t**)obj;
-#ifndef __GNUC__
+#ifdef __GNUC__
+		// On GNUC the address where the return value will be placed should be put in R0
 		retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
 		retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
 #else
 #else
+		// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
 		retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj, (asDWORD)retPointer);
 		retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj, (asDWORD)retPointer);
 #endif
 #endif
 		break;
 		break;

+ 253 - 251
ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S

@@ -1,251 +1,253 @@
-/*
-  AngelCode Scripting Library
-  Copyright (c) 2003-2012 Andreas Jonsson
-
-  This software is provided 'as-is', without any express or implied
-  warranty. In no event will the authors be held liable for any
-  damages arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any
-  purpose, including commercial applications, and to alter it and
-  redistribute it freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you
-     must not claim that you wrote the original software. If you use
-     this software in a product, an acknowledgment in the product
-     documentation would be appreciated but is not required.
-
-  2. Altered source versions must be plainly marked as such, and
-     must not be misrepresented as being the original software.
-
-  3. This notice may not be removed or altered from any source
-     distribution.
-
-  The original version of this library can be located at:
-  http://www.angelcode.com/angelscript/
-
-  Andreas Jonsson
-  [email protected]
-*/
-
-// Assembly routines for the ARM call convention
-// Written by Fredrik Ehnbom in June 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__)
-
-.global armFunc
-.global armFuncR0
-.global armFuncR0R1
-.global armFuncObjLast
-.global armFuncR0ObjLast
-    
-armFunc:
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  // arg table
-    movs    r7, r1  // arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  // function address
-    mov     r8, #0
-
-    beq     nomoreargs
-
-    // Load the first 4 arguments into r0-r3
-    cmp     r7, #4
-    ldrge   r0, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #3*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #4*4
-    ldrge   r3, [r6],#4
-    ble     nomoreargs
-
-    // Load the rest of the arguments onto the stack
-    sub     r7, r7, #4*4      // skip the 4 registers already loaded into r0-r3
-    add     r8, r7, #4        // ensure 8-byte stack alignment
-    bic     r8, r8, #4
-    sub     sp, sp, r8
-    mov     r12, sp           // copy size != frame size, so store frame start sp
-stackargsloop:
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     stackargsloop
-    mov     sp, r12
-nomoreargs:
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-
-armFuncObjLast:
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  // arg table
-    movs    r7, r1  // arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  // function address
-    mov     r8, #0
-
-    mov     r0, r3          // objlast. might get overwritten
-    mov     r5, r3          // objlast to temp reg
-
-    beq     nomoreargsarmFuncObjLast
-
-    // Load the first 4 arguments into r0-r3
-    cmp     r7, #4
-    ldrge   r0, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r1, [r6],#4
-    movlt   r1, r5
-    cmp     r7, #3*4
-    ldrge   r2, [r6],#4
-    movlt   r2, r5
-    cmp     r7, #4*4
-    ldrge   r3, [r6],#4
-    movlt   r3, r5
-    blt     nomoreargsarmFuncObjLast
-
-    // Load the rest of the arguments onto the stack
-    sub     r7, r7, #4*4    // skip the 4 registers already loaded into r0-r3
-    add     r8, r7, #8      // account for the objlast pointer, ensure 8-byte stack alignment
-    bic     r8, r8, #4
-    str     r5, [sp,#-4]    // store the objlast on stack, twice in case we adjusted alignment
-    str     r5, [sp,#-8]
-    sub     sp, sp, r8      // adjust frame
-    cmp     r7, #0          // we may also have come here with no extra params
-    beq     nomoreargsarmFuncObjLast
-    mov     r12, sp         // copy size != frame size, so store frame start sp
-stackargslooparmFuncObjLast:
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     stackargslooparmFuncObjLast
-    mov     sp, r12
-nomoreargsarmFuncObjLast:
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-
-armFuncR0ObjLast:
-    stmdb   sp!, {r4-r8, lr}
-    ldr     r5, [sp,#6*4]   // objlast to temp reg
-
-    mov     r6, r0  // arg table
-    movs    r7, r1  // arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  // function address
-    mov     r8, #0
-
-    mov     r0, r3      // r0 explicitly set
-    mov     r1, r5      // objlast.  might get overwritten
-
-    beq     nomoreargsarmFuncR0ObjLast
-
-    // Load the first 3 arguments into r1-r3
-    cmp     r7, #1*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r2, [r6],#4
-    movlt   r2, r5
-    cmp     r7, #3*4
-    ldrge   r3, [r6],#4
-    movlt   r3, r5
-    blt     nomoreargsarmFuncR0ObjLast
-
-    // Load the rest of the arguments onto the stack
-    sub     r7, r7, #3*4    // skip the 3 registers already loaded into r1-r3
-    add     r8, r7, #8      // account for the objlast pointer, ensure 8-byte stack alignment
-    bic     r8, r8, #4
-    str     r5, [sp,#-4]    // store the objlast on stack, twice in case we adjusted alignment
-    str     r5, [sp,#-8]
-    sub     sp, sp, r8      // adjust frame
-    cmp     r7, #0          // we may also have come here with no extra params
-    beq     nomoreargsarmFuncR0ObjLast
-    mov     r12, sp         // copy size != frame size, so store frame start sp
-stackargslooparmFuncR0ObjLast:
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     stackargslooparmFuncR0ObjLast
-    mov     sp, r12
-nomoreargsarmFuncR0ObjLast:
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-
-
-armFuncR0:
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  // arg table
-    movs    r7, r1  // arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  // function address
-    mov     r8, #0
-
-    mov     r0, r3  // r0 explicitly set
-
-    beq     nomoreargsarmFuncR0
-
-    // Load the first 3 arguments into r1-r3
-    cmp     r7, #1*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #3*4
-    ldrge   r3, [r6],#4
-    ble     nomoreargsarmFuncR0
-
-    // Load the rest of the arguments onto the stack
-    sub     r7, r7, #3*4    // skip the 3 registers already loaded into r1-r3
-    add     r8, r7, #4      // ensure 8-byte stack alignment
-    bic     r8, r8, #4
-    sub     sp, sp, r8
-    mov     r12, sp         // copy size != frame size, so store frame start sp
-stackargslooparmFuncR0:
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     stackargslooparmFuncR0
-    mov     sp, r12
-nomoreargsarmFuncR0:
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-
-
-armFuncR0R1:
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  // arg table
-    movs    r7, r1  // arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  // function address
-    mov     r8, #0
-
-    mov     r0, r3          // r0 explicitly set
-    ldr     r1, [sp, #6*4]  // r1 explicitly set too
-
-    beq     nomoreargsarmFuncR0R1
-
-    // Load the first 2 arguments into r2-r3
-    cmp     r7, #1*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r3, [r6],#4
-    ble     nomoreargsarmFuncR0R1
-
-    // Load the rest of the arguments onto the stack
-    sub     r7, r7, #2*4    // skip the 2 registers already loaded into r2-r3
-    add     r8, r7, #4      // ensure 8-byte stack alignment
-    bic     r8, r8, #4
-    sub     sp, sp, r8
-    mov     r12, sp         // copy size != frame size, so store frame start sp
-stackargslooparmFuncR0R1:
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     stackargslooparmFuncR0R1
-    mov     sp, r12
-nomoreargsarmFuncR0R1:
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-
-#endif
+/*
+  AngelCode Scripting Library
+  Copyright (c) 2003-2012 Andreas Jonsson
+
+  This software is provided 'as-is', without any express or implied
+  warranty. In no event will the authors be held liable for any
+  damages arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any
+  purpose, including commercial applications, and to alter it and
+  redistribute it freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you
+     must not claim that you wrote the original software. If you use
+     this software in a product, an acknowledgment in the product
+     documentation would be appreciated but is not required.
+
+  2. Altered source versions must be plainly marked as such, and
+     must not be misrepresented as being the original software.
+
+  3. This notice may not be removed or altered from any source
+     distribution.
+
+  The original version of this library can be located at:
+  http://www.angelcode.com/angelscript/
+
+  Andreas Jonsson
+  [email protected]
+*/
+
+/*
+   Assembly routines for the ARM call convention
+   Written by Fredrik Ehnbom in June 2009
+
+   Adapted to GNUC by darktemplar216 in September 2009
+
+   Modified by Lasse Oorni for 8-byte stack alignment in May 2012
+*/
+
+#if defined(__arm__) || defined(__ARM__)
+
+.global armFunc
+.global armFuncR0
+.global armFuncR0R1
+.global armFuncObjLast
+.global armFuncR0ObjLast
+    
+armFunc:
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r8, #0
+
+    beq     nomoreargs
+
+    /* Load the first 4 arguments into r0-r3 */
+    cmp     r7, #4
+    ldrge   r0, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #3*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #4*4
+    ldrge   r3, [r6],#4
+    ble     nomoreargs
+
+    /* Load the rest of the arguments onto the stack */
+    sub     r7, r7, #4*4      /* skip the 4 registers already loaded into r0-r3 */
+    add     r8, r7, #4        /* ensure 8-byte stack alignment */
+    bic     r8, r8, #4
+    sub     sp, sp, r8
+    mov     r12, sp           /* copy size != frame size, so store frame start sp */
+stackargsloop:
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     stackargsloop
+    mov     sp, r12
+nomoreargs:
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+
+armFuncObjLast:
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r8, #0
+
+    mov     r0, r3          /* objlast. might get overwritten */
+    mov     r5, r3          /* objlast to temp reg */
+
+    beq     nomoreargsarmFuncObjLast
+
+    /* Load the first 4 arguments into r0-r3 */
+    cmp     r7, #4
+    ldrge   r0, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r1, [r6],#4
+    movlt   r1, r5
+    cmp     r7, #3*4
+    ldrge   r2, [r6],#4
+    movlt   r2, r5
+    cmp     r7, #4*4
+    ldrge   r3, [r6],#4
+    movlt   r3, r5
+    blt     nomoreargsarmFuncObjLast
+
+    /* Load the rest of the arguments onto the stack */
+    sub     r7, r7, #4*4    /* skip the 4 registers already loaded into r0-r3 */
+    add     r8, r7, #8      /* account for the objlast pointer, ensure 8-byte stack alignment */
+    bic     r8, r8, #4
+    str     r5, [sp,#-4]    /* store the objlast on stack, twice in case we adjusted alignment */
+    str     r5, [sp,#-8]
+    sub     sp, sp, r8      /* adjust frame */
+    cmp     r7, #0          /* we may also have come here with no extra params */
+    beq     nomoreargsarmFuncObjLast
+    mov     r12, sp         /* copy size != frame size, so store frame start sp */
+stackargslooparmFuncObjLast:
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     stackargslooparmFuncObjLast
+    mov     sp, r12
+nomoreargsarmFuncObjLast:
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+
+armFuncR0ObjLast:
+    stmdb   sp!, {r4-r8, lr}
+    ldr     r5, [sp,#6*4]   /* objlast to temp reg */
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r8, #0
+
+    mov     r0, r3      /* r0 explicitly set */
+    mov     r1, r5      /* objlast.  might get overwritten */
+
+    beq     nomoreargsarmFuncR0ObjLast
+
+    /* Load the first 3 arguments into r1-r3 */
+    cmp     r7, #1*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r2, [r6],#4
+    movlt   r2, r5
+    cmp     r7, #3*4
+    ldrge   r3, [r6],#4
+    movlt   r3, r5
+    blt     nomoreargsarmFuncR0ObjLast
+
+    /* Load the rest of the arguments onto the stack */
+    sub     r7, r7, #3*4    /* skip the 3 registers already loaded into r1-r3 */
+    add     r8, r7, #8      /* account for the objlast pointer, ensure 8-byte stack alignment */
+    bic     r8, r8, #4
+    str     r5, [sp,#-4]    /* store the objlast on stack, twice in case we adjusted alignment */
+    str     r5, [sp,#-8]
+    sub     sp, sp, r8      /* adjust frame */
+    cmp     r7, #0          /* we may also have come here with no extra params */
+    beq     nomoreargsarmFuncR0ObjLast
+    mov     r12, sp         /* copy size != frame size, so store frame start sp */
+stackargslooparmFuncR0ObjLast:
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     stackargslooparmFuncR0ObjLast
+    mov     sp, r12
+nomoreargsarmFuncR0ObjLast:
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+
+
+armFuncR0:
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r8, #0
+
+    mov     r0, r3  /* r0 explicitly set */
+
+    beq     nomoreargsarmFuncR0
+
+    /* Load the first 3 arguments into r1-r3 */
+    cmp     r7, #1*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #3*4
+    ldrge   r3, [r6],#4
+    ble     nomoreargsarmFuncR0
+
+    /* Load the rest of the arguments onto the stack */
+    sub     r7, r7, #3*4    /* skip the 3 registers already loaded into r1-r3 */
+    add     r8, r7, #4      /* ensure 8-byte stack alignment */
+    bic     r8, r8, #4
+    sub     sp, sp, r8
+    mov     r12, sp         /* copy size != frame size, so store frame start sp */
+stackargslooparmFuncR0:
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     stackargslooparmFuncR0
+    mov     sp, r12
+nomoreargsarmFuncR0:
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+
+
+armFuncR0R1:
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r8, #0
+
+    mov     r0, r3          /* r0 explicitly set */
+    ldr     r1, [sp, #6*4]  /* r1 explicitly set too */
+
+    beq     nomoreargsarmFuncR0R1
+
+    /* Load the first 2 arguments into r2-r3 */
+    cmp     r7, #1*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r3, [r6],#4
+    ble     nomoreargsarmFuncR0R1
+
+    /* Load the rest of the arguments onto the stack */
+    sub     r7, r7, #2*4    /* skip the 2 registers already loaded into r2-r3 */
+    add     r8, r7, #4      /* ensure 8-byte stack alignment */
+    bic     r8, r8, #4
+    sub     sp, sp, r8
+    mov     r12, sp         /* copy size != frame size, so store frame start sp */
+stackargslooparmFuncR0R1:
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     stackargslooparmFuncR0R1
+    mov     sp, r12
+nomoreargsarmFuncR0R1:
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+
+#endif

+ 242 - 242
ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm

@@ -1,242 +1,242 @@
-;
-;  AngelCode Scripting Library
-;  Copyright (c) 2003-2009 Andreas Jonsson
-;
-;  This software is provided 'as-is', without any express or implied
-;  warranty. In no event will the authors be held liable for any
-;  damages arising from the use of this software.
-;
-;  Permission is granted to anyone to use this software for any
-;  purpose, including commercial applications, and to alter it and
-;  redistribute it freely, subject to the following restrictions:
-;
-;  1. The origin of this software must not be misrepresented; you
-;     must not claim that you wrote the original software. If you use
-;     this software in a product, an acknowledgment in the product
-;     documentation would be appreciated but is not required.
-;
-;  2. Altered source versions must be plainly marked as such, and
-;     must not be misrepresented as being the original software.
-;
-;  3. This notice may not be removed or altered from any source
-;     distribution.
-;
-;  The original version of this library can be located at:
-;  http://www.angelcode.com/angelscript/
-;
-;  Andreas Jonsson
-;  [email protected]
-;
-
-
-; Assembly routines for the ARM call convention
-; Written by Fredrik Ehnbom in June 2009
-
-; MSVC currently doesn't support inline assembly for the ARM platform
-; so this separate file is needed.
-
-
-    AREA	|.rdata|, DATA, READONLY
-    EXPORT |armFunc|
-    EXPORT armFuncR0
-    EXPORT armFuncR0R1
-    EXPORT armFuncObjLast
-    EXPORT armFuncR0ObjLast
-    
-
-    AREA	|.text|, CODE, ARM
-
-|armFunc| PROC
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  ; arg table
-    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  ; function address
-    mov     r8, #0
-
-    beq     |nomoreargs|
-
-    ; Load the first 4 arguments into r0-r3
-    cmp     r7, #4
-    ldrge   r0, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #3*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #4*4
-    ldrge   r3, [r6],#4
-    ble     |nomoreargs|
-
-    ; Load the rest of the arguments onto the stack
-    sub     r7, r7, #4*4    ; skip the 4 registers already loaded into r0-r3
-    sub     sp, sp, r7
-    mov     r8, r7
-|stackargsloop|
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     |stackargsloop|
-|nomoreargs|
-    sub     sp, sp, r8
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-    ENDP
-
-armFuncObjLast PROC
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  ; arg table
-    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  ; function address
-    mov     r8, #0
-
-    mov     r0, r3          ; objlast. might get overwritten
-    str     r3, [sp, #-4]!  ; objlast again.
-
-    beq     |nomoreargs@armFuncObjLast|
-
-    ; Load the first 4 arguments into r0-r3
-    cmp     r7, #4
-    ldrge   r0, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r1, [r6],#4
-    ldrlt   r1, [sp]    
-    cmp     r7, #3*4
-    ldrge   r2, [r6],#4
-    ldrlt   r2, [sp]
-    cmp     r7, #4*4
-    ldrge   r3, [r6],#4
-    ldrlt   r3, [sp]
-    ble     |nomoreargs@armFuncObjLast|
-
-    ; Load the rest of the arguments onto the stack
-    sub     r7, r7, #4*4    ; skip the 4 registers already loaded into r0-r3
-    sub     sp, sp, r7
-    mov     r8, r7
-|stackargsloop@armFuncObjLast|
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     |stackargsloop@armFuncObjLast|
-|nomoreargs@armFuncObjLast|
-    sub     sp, sp, r8
-    blx     r4
-    add     sp, sp, r8
-    add     sp, sp, #4
-    ldmia   sp!, {r4-r8, pc}
-    ENDP
-
-armFuncR0ObjLast PROC
-    stmdb   sp!, {r4-r8, lr}
-    ldr     r7, [sp,#6*4]
-    str     r7, [sp,#-4]!
-
-    mov     r6, r0  ; arg table
-    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  ; function address
-    mov     r8, #0
-
-    mov     r0, r3      ; r0 explicitly set
-    ldr     r1, [sp]    ; objlast.  might get overwritten
-
-    beq     |nomoreargs@armFuncR0ObjLast|
-
-    ; Load the first 3 arguments into r1-r3
-    cmp     r7, #1*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r2, [r6],#4
-    ldrlt   r2, [sp]
-    cmp     r7, #3*4
-    ldrge   r3, [r6],#4
-    ldrlt   r3, [sp]
-    ble     |nomoreargs@armFuncR0ObjLast|
-
-    ; Load the rest of the arguments onto the stack
-    sub     r7, r7, #3*4    ; skip the 3 registers already loaded into r1-r3
-    sub     sp, sp, r7
-    mov     r8, r7
-|stackargsloop@armFuncR0ObjLast|
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     |stackargsloop@armFuncR0ObjLast|
-|nomoreargs@armFuncR0ObjLast|
-    sub     sp, sp, r8
-    blx     r4
-    add     sp, sp, r8
-    add     sp, sp, #4
-    ldmia   sp!, {r4-r8, pc}
-    ENDP
-
-armFuncR0 PROC
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  ; arg table
-    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  ; function address
-    mov     r8, #0
-
-    mov     r0, r3  ; r0 explicitly set
-
-    beq     |nomoreargs@armFuncR0|
-
-    ; Load the first 3 arguments into r1-r3
-    cmp     r7, #1*4
-    ldrge   r1, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #3*4
-    ldrge   r3, [r6],#4
-    ble     |nomoreargs@armFuncR0|
-
-    ; Load the rest of the arguments onto the stack
-    sub     r7, r7, #3*4    ; skip the 3 registers already loaded into r1-r3
-    sub     sp, sp, r7
-    mov     r8, r7
-|stackargsloop@armFuncR0|
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     |stackargsloop@armFuncR0|
-|nomoreargs@armFuncR0|
-    sub     sp, sp, r8
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-    ENDP
-
-armFuncR0R1 PROC
-    stmdb   sp!, {r4-r8, lr}
-    mov     r6, r0  ; arg table
-    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
-    mov     r4, r2  ; function address
-    mov     r8, #0
-
-    mov     r0, r3          ; r0 explicitly set
-    ldr     r1, [sp, #6*4]  ; r1 explicitly set too
-
-    beq     |nomoreargs@armFuncR0R1|
-
-    ; Load the first 2 arguments into r2-r3
-    cmp     r7, #1*4
-    ldrge   r2, [r6],#4
-    cmp     r7, #2*4
-    ldrge   r3, [r6],#4
-    ble     |nomoreargs@armFuncR0R1|
-
-    ; Load the rest of the arguments onto the stack
-    sub     r7, r7, #2*4    ; skip the 2 registers already loaded into r2-r3
-    sub     sp, sp, r7
-    mov     r8, r7
-|stackargsloop@armFuncR0R1|
-    ldr     r5, [r6], #4
-    str     r5, [sp], #4
-    subs    r7, r7, #4
-    bne     |stackargsloop@armFuncR0R1|
-|nomoreargs@armFuncR0R1|
-    sub     sp, sp, r8
-    blx     r4
-    add     sp, sp, r8
-    ldmia   sp!, {r4-r8, pc}
-    ENDP
-
-    END
+;
+;  AngelCode Scripting Library
+;  Copyright (c) 2003-2009 Andreas Jonsson
+;
+;  This software is provided 'as-is', without any express or implied
+;  warranty. In no event will the authors be held liable for any
+;  damages arising from the use of this software.
+;
+;  Permission is granted to anyone to use this software for any
+;  purpose, including commercial applications, and to alter it and
+;  redistribute it freely, subject to the following restrictions:
+;
+;  1. The origin of this software must not be misrepresented; you
+;     must not claim that you wrote the original software. If you use
+;     this software in a product, an acknowledgment in the product
+;     documentation would be appreciated but is not required.
+;
+;  2. Altered source versions must be plainly marked as such, and
+;     must not be misrepresented as being the original software.
+;
+;  3. This notice may not be removed or altered from any source
+;     distribution.
+;
+;  The original version of this library can be located at:
+;  http://www.angelcode.com/angelscript/
+;
+;  Andreas Jonsson
+;  [email protected]
+;
+
+
+; Assembly routines for the ARM call convention
+; Written by Fredrik Ehnbom in June 2009
+
+; MSVC currently doesn't support inline assembly for the ARM platform
+; so this separate file is needed.
+
+
+    AREA	|.rdata|, DATA, READONLY
+    EXPORT |armFunc|
+    EXPORT armFuncR0
+    EXPORT armFuncR0R1
+    EXPORT armFuncObjLast
+    EXPORT armFuncR0ObjLast
+    
+
+    AREA	|.text|, CODE, ARM
+
+|armFunc| PROC
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  ; arg table
+    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
+    mov     r4, r2  ; function address
+    mov     r8, #0
+
+    beq     |nomoreargs|
+
+    ; Load the first 4 arguments into r0-r3
+    cmp     r7, #4
+    ldrge   r0, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #3*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #4*4
+    ldrge   r3, [r6],#4
+    ble     |nomoreargs|
+
+    ; Load the rest of the arguments onto the stack
+    sub     r7, r7, #4*4    ; skip the 4 registers already loaded into r0-r3
+    sub     sp, sp, r7
+    mov     r8, r7
+|stackargsloop|
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     |stackargsloop|
+|nomoreargs|
+    sub     sp, sp, r8
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+    ENDP
+
+armFuncObjLast PROC
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  ; arg table
+    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
+    mov     r4, r2  ; function address
+    mov     r8, #0
+
+    mov     r0, r3          ; objlast. might get overwritten
+    str     r3, [sp, #-4]!  ; objlast again.
+
+    beq     |nomoreargs@armFuncObjLast|
+
+    ; Load the first 4 arguments into r0-r3
+    cmp     r7, #4
+    ldrge   r0, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r1, [r6],#4
+    ldrlt   r1, [sp]    
+    cmp     r7, #3*4
+    ldrge   r2, [r6],#4
+    ldrlt   r2, [sp]
+    cmp     r7, #4*4
+    ldrge   r3, [r6],#4
+    ldrlt   r3, [sp]
+    ble     |nomoreargs@armFuncObjLast|
+
+    ; Load the rest of the arguments onto the stack
+    sub     r7, r7, #4*4    ; skip the 4 registers already loaded into r0-r3
+    sub     sp, sp, r7
+    mov     r8, r7
+|stackargsloop@armFuncObjLast|
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     |stackargsloop@armFuncObjLast|
+|nomoreargs@armFuncObjLast|
+    sub     sp, sp, r8
+    blx     r4
+    add     sp, sp, r8
+    add     sp, sp, #4
+    ldmia   sp!, {r4-r8, pc}
+    ENDP
+
+armFuncR0ObjLast PROC
+    stmdb   sp!, {r4-r8, lr}
+    ldr     r7, [sp,#6*4]
+    str     r7, [sp,#-4]!
+
+    mov     r6, r0  ; arg table
+    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
+    mov     r4, r2  ; function address
+    mov     r8, #0
+
+    mov     r0, r3      ; r0 explicitly set
+    ldr     r1, [sp]    ; objlast.  might get overwritten
+
+    beq     |nomoreargs@armFuncR0ObjLast|
+
+    ; Load the first 3 arguments into r1-r3
+    cmp     r7, #1*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r2, [r6],#4
+    ldrlt   r2, [sp]
+    cmp     r7, #3*4
+    ldrge   r3, [r6],#4
+    ldrlt   r3, [sp]
+    ble     |nomoreargs@armFuncR0ObjLast|
+
+    ; Load the rest of the arguments onto the stack
+    sub     r7, r7, #3*4    ; skip the 3 registers already loaded into r1-r3
+    sub     sp, sp, r7
+    mov     r8, r7
+|stackargsloop@armFuncR0ObjLast|
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     |stackargsloop@armFuncR0ObjLast|
+|nomoreargs@armFuncR0ObjLast|
+    sub     sp, sp, r8
+    blx     r4
+    add     sp, sp, r8
+    add     sp, sp, #4
+    ldmia   sp!, {r4-r8, pc}
+    ENDP
+
+armFuncR0 PROC
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  ; arg table
+    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
+    mov     r4, r2  ; function address
+    mov     r8, #0
+
+    mov     r0, r3  ; r0 explicitly set
+
+    beq     |nomoreargs@armFuncR0|
+
+    ; Load the first 3 arguments into r1-r3
+    cmp     r7, #1*4
+    ldrge   r1, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #3*4
+    ldrge   r3, [r6],#4
+    ble     |nomoreargs@armFuncR0|
+
+    ; Load the rest of the arguments onto the stack
+    sub     r7, r7, #3*4    ; skip the 3 registers already loaded into r1-r3
+    sub     sp, sp, r7
+    mov     r8, r7
+|stackargsloop@armFuncR0|
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     |stackargsloop@armFuncR0|
+|nomoreargs@armFuncR0|
+    sub     sp, sp, r8
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+    ENDP
+
+armFuncR0R1 PROC
+    stmdb   sp!, {r4-r8, lr}
+    mov     r6, r0  ; arg table
+    movs    r7, r1  ; arg size (also set the condition code flags so that we detect if there are no arguments)
+    mov     r4, r2  ; function address
+    mov     r8, #0
+
+    mov     r0, r3          ; r0 explicitly set
+    ldr     r1, [sp, #6*4]  ; r1 explicitly set too
+
+    beq     |nomoreargs@armFuncR0R1|
+
+    ; Load the first 2 arguments into r2-r3
+    cmp     r7, #1*4
+    ldrge   r2, [r6],#4
+    cmp     r7, #2*4
+    ldrge   r3, [r6],#4
+    ble     |nomoreargs@armFuncR0R1|
+
+    ; Load the rest of the arguments onto the stack
+    sub     r7, r7, #2*4    ; skip the 2 registers already loaded into r2-r3
+    sub     sp, sp, r7
+    mov     r8, r7
+|stackargsloop@armFuncR0R1|
+    ldr     r5, [r6], #4
+    str     r5, [sp], #4
+    subs    r7, r7, #4
+    bne     |stackargsloop@armFuncR0R1|
+|nomoreargs@armFuncR0R1|
+    sub     sp, sp, r8
+    blx     r4
+    add     sp, sp, r8
+    ldmia   sp!, {r4-r8, pc}
+    ENDP
+
+    END

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

@@ -66,7 +66,8 @@ BEGIN_AS_NAMESPACE
 // the +1 is for when CallThis (object methods) is used
 // the +1 is for when CallThis (object methods) is used
 // extra +1 when returning in memory
 // extra +1 when returning in memory
 extern "C" {
 extern "C" {
-static asDWORD mipsArgs[AS_MIPS_MAX_ARGS + 1 + 1];
+// TODO: This array shouldn't be global. It should be a local array in CallSystemFunctionNative
+asDWORD mipsArgs[AS_MIPS_MAX_ARGS + 1 + 1];
 }
 }
 
 
 // Loads all data into the correct places and calls the function.
 // Loads all data into the correct places and calls the function.

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -59,7 +59,7 @@ typedef asQWORD ( *funcptr_t )( void );
 
 
 static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat) 
 static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat) 
 {
 {
-	asQWORD   retQW1;
+	asQWORD   retQW1 = 0;
 
 
 	// Reference: http://www.x86-64.org/documentation/abi.pdf
 	// Reference: http://www.x86-64.org/documentation/abi.pdf
 
 

+ 53 - 34
ThirdParty/AngelScript/source/as_callfunc_x86.cpp

@@ -51,8 +51,8 @@ BEGIN_AS_NAMESPACE
 
 
 //
 //
 // With some compile level optimizations the functions don't clear the FPU
 // With some compile level optimizations the functions don't clear the FPU
-// stack themselves. So we have to do it as part of calling the native functions, 
-// as the compiler will not be able to predict when it is supposed to do it by 
+// stack themselves. So we have to do it as part of calling the native functions,
+// as the compiler will not be able to predict when it is supposed to do it by
 // itself due to the dynamic nature of scripts
 // itself due to the dynamic nature of scripts
 //
 //
 // - fninit clears the FPU stack and the FPU control word
 // - fninit clears the FPU stack and the FPU control word
@@ -283,13 +283,13 @@ endcopy:
 #elif defined ASM_AT_N_T
 #elif defined ASM_AT_N_T
 
 
 	// It is not possible to rely on ESP or BSP to refer to variables or arguments on the stack
 	// It is not possible to rely on ESP or BSP to refer to variables or arguments on the stack
-	// depending on compiler settings BSP may not even be used, and the ESP is not always on the 
+	// depending on compiler settings BSP may not even be used, and the ESP is not always on the
 	// same offset from the local variables. Because the code adjusts the ESP register it is not
 	// same offset from the local variables. Because the code adjusts the ESP register it is not
 	// possible to inform the arguments through symbolic names below.
 	// possible to inform the arguments through symbolic names below.
 
 
 	// It's not also not possible to rely on the memory layout of the function arguments, because
 	// It's not also not possible to rely on the memory layout of the function arguments, because
-	// on some compiler versions and settings the arguments may be copied to local variables with a 
-	// different ordering before they are accessed by the rest of the code. 
+	// on some compiler versions and settings the arguments may be copied to local variables with a
+	// different ordering before they are accessed by the rest of the code.
 
 
 	// I'm copying the arguments into this array where I know the exact memory layout. The address
 	// I'm copying the arguments into this array where I know the exact memory layout. The address
 	// of this array will then be passed to the inline asm in the EDX register.
 	// of this array will then be passed to the inline asm in the EDX register.
@@ -298,7 +298,7 @@ endcopy:
 	asm __volatile__(
 	asm __volatile__(
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -329,9 +329,9 @@ endcopy:
 
 
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -402,7 +402,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -434,9 +434,9 @@ endcopy:
 
 
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -507,7 +507,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -539,9 +539,9 @@ endcopy:
 
 
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -621,7 +621,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -657,9 +657,9 @@ endcopy:
 #endif
 #endif
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -735,7 +735,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -768,9 +768,9 @@ endcopy:
 #endif
 #endif
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -848,7 +848,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -884,9 +884,9 @@ endcopy:
 #endif
 #endif
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -952,7 +952,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -981,9 +981,9 @@ endcopy:
 
 
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -1065,7 +1065,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)    "\n"
 		_S(CLEAR_FPU_STACK)    "\n"
 		"pushl %%ebx            \n"
 		"pushl %%ebx            \n"
-		"movl  %%edx, %%ebx     \n"	
+		"movl  %%edx, %%ebx     \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -1091,16 +1091,21 @@ endcopy:
 		"jne   copyloop1        \n"
 		"jne   copyloop1        \n"
 		"endcopy1:              \n"
 		"endcopy1:              \n"
 		"movl  0(%%ebx), %%ecx  \n" // move obj into ECX
 		"movl  0(%%ebx), %%ecx  \n" // move obj into ECX
+#ifdef THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 		"pushl %%ecx            \n" // push obj on the stack
 		"pushl %%ecx            \n" // push obj on the stack
+#endif
 		"call  *12(%%ebx)       \n"
 		"call  *12(%%ebx)       \n"
+#ifndef THISCALL_CALLEE_POPS_ARGUMENTS
 		"addl  8(%%ebx), %%esp  \n" // pop arguments
 		"addl  8(%%ebx), %%esp  \n" // pop arguments
+#ifdef THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 		"addl  $4, %%esp        \n" // pop obj
 		"addl  $4, %%esp        \n" // pop obj
-
+#endif
+#endif
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp            \n"
 		"popl  %%esp            \n"
-		"popl  %%ebx            \n" 
+		"popl  %%ebx            \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"
@@ -1189,7 +1194,7 @@ endcopy:
 	asm __volatile__ (
 	asm __volatile__ (
 		_S(CLEAR_FPU_STACK)   "\n"
 		_S(CLEAR_FPU_STACK)   "\n"
 		"pushl %%ebx           \n"
 		"pushl %%ebx           \n"
-		"movl  %%edx, %%ebx    \n"	
+		"movl  %%edx, %%ebx    \n"
 
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -1214,21 +1219,35 @@ endcopy:
 		"subl  $4, %%ecx       \n"
 		"subl  $4, %%ecx       \n"
 		"jne   copyloop3       \n"
 		"jne   copyloop3       \n"
 		"endcopy3:             \n"
 		"endcopy3:             \n"
+#if defined(__MINGW32__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4)
+        // MinGW made some strange choices with 4.7, and the thiscall calling convention
+        // when returning an object in memory is completely different from when not returning
+        // in memory
+        "pushl 0(%%ebx)        \n" // push obj on the stack
+        "movl 16(%%ebx), %%ecx \n" // move the return pointer into ECX
+        "call  *12(%%ebx)      \n" // call the function
+#else
 		"movl  0(%%ebx), %%ecx \n" // move obj into ECX
 		"movl  0(%%ebx), %%ecx \n" // move obj into ECX
+#ifdef THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 		"pushl %%ecx           \n" // push obj on the stack
 		"pushl %%ecx           \n" // push obj on the stack
+#endif
 		"pushl 16(%%ebx)       \n" // push retPtr on the stack
 		"pushl 16(%%ebx)       \n" // push retPtr on the stack
 		"call  *12(%%ebx)      \n"
 		"call  *12(%%ebx)      \n"
 #ifndef THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
 #ifndef THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
 		"addl  $4, %%esp       \n" // pop return pointer
 		"addl  $4, %%esp       \n" // pop return pointer
 #endif
 #endif
+#ifndef THISCALL_CALLEE_POPS_ARGUMENTS
 		"addl  8(%%ebx), %%esp \n" // pop arguments
 		"addl  8(%%ebx), %%esp \n" // pop arguments
+#ifdef THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 		"addl  $4, %%esp       \n" // pop the object pointer
 		"addl  $4, %%esp       \n" // pop the object pointer
-		                           // the return pointer was popped by the callee
+#endif
+#endif
+#endif // MINGW
 		// Pop the alignment bytes
 		// Pop the alignment bytes
 		"popl  %%esp           \n"
 		"popl  %%esp           \n"
-		"popl  %%ebx           \n" 
+		"popl  %%ebx           \n"
 
 
-		// Copy EAX:EDX to retQW. As the stack pointer has been 
+		// Copy EAX:EDX to retQW. As the stack pointer has been
 		// restored it is now safe to access the local variable
 		// restored it is now safe to access the local variable
 		"leal  %1, %%ecx        \n"
 		"leal  %1, %%ecx        \n"
 		"movl  %%eax, 0(%%ecx)  \n"
 		"movl  %%eax, 0(%%ecx)  \n"

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

@@ -512,7 +512,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	int     argsCnt = 0;
 	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( sysFunc->hostReturnInMemory )
 	{
 	{
 		ppcArgs[argsCnt] = (asDWORD)retPointer;
 		ppcArgs[argsCnt] = (asDWORD)retPointer;
 		ppcArgsType[argsCnt] = ppcINTARG;
 		ppcArgsType[argsCnt] = ppcINTARG;

File diff suppressed because it is too large
+ 327 - 416
ThirdParty/AngelScript/source/as_compiler.cpp


+ 39 - 13
ThirdParty/AngelScript/source/as_compiler.h

@@ -117,6 +117,14 @@ struct asSExprContext
 	asSExprContext *origExpr;
 	asSExprContext *origExpr;
 };
 };
 
 
+struct asSOverloadCandidate
+{
+	asSOverloadCandidate() : funcId(0), cost(0) {}
+	asSOverloadCandidate(int _id, asUINT _cost ) : funcId(_id), cost(_cost) {}
+	int funcId;
+	asUINT cost;
+};
+
 enum EImplicitConv
 enum EImplicitConv
 {
 {
 	asIC_IMPLICIT_CONV,
 	asIC_IMPLICIT_CONV,
@@ -143,8 +151,8 @@ public:
 	asCCompiler(asCScriptEngine *engine);
 	asCCompiler(asCScriptEngine *engine);
 	~asCCompiler();
 	~asCCompiler();
 
 
-	int CompileFunction(asCBuilder *builder, asCScriptCode *script, sExplicitSignature *signature, asCScriptNode *func, asCScriptFunction *outFunc);
-	int CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, asCScriptFunction *outFunc);
+	int CompileFunction(asCBuilder *builder, asCScriptCode *script, asCArray<asCString> &parameterNames, asCScriptNode *func, asCScriptFunction *outFunc, sClassDeclaration *classDecl);
+	int CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, asCScriptFunction *outFunc, sClassDeclaration *classDecl);
 	int CompileFactory(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
 	int CompileFactory(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
 	int CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *expr, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc);
 	int CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *expr, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc);
 
 
@@ -189,21 +197,23 @@ protected:
 	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
 	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
 	int  CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
 	int  CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
 
 
-	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc);
+	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
 
 
-	int  CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar = false, bool deferDest = false);
+	int  CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, int isVarGlobOrMem = 0, bool deferDest = false);
 	int  CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = false);
 	int  CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = false);
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
 	asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
 	asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
 	int  CompileVariableAccess(const asCString &name, const asCString &scope, asSExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, bool noFunction = false, bool noGlobal = false, asCObjectType *objType = 0);
 	int  CompileVariableAccess(const asCString &name, const asCString &scope, asSExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, bool noFunction = false, bool noGlobal = false, asCObjectType *objType = 0);
+	void CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults);
+	bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem);
 
 
 	// Helper functions
 	// Helper functions
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
-	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, bool isThisAccess = false);
-	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, bool isThisAccess = false);
+	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
+	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, bool forceOnHeap = false);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, bool forceOnHeap = false);
 	void PrepareOperand(asSExprContext *ctx, asCScriptNode *node);
 	void PrepareOperand(asSExprContext *ctx, asCScriptNode *node);
 	void PrepareForAssignment(asCDataType *lvalue, asSExprContext *rvalue, asCScriptNode *node, bool toTemporary, asSExprContext *lvalueExpr = 0);
 	void PrepareForAssignment(asCDataType *lvalue, asSExprContext *rvalue, asCScriptNode *node, bool toTemporary, asSExprContext *lvalueExpr = 0);
@@ -211,7 +221,7 @@ protected:
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	void Dereference(asSExprContext *ctx, bool generateCode);
 	void Dereference(asSExprContext *ctx, bool generateCode);
 	bool CompileRefCast(asSExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
 	bool CompileRefCast(asSExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
-	asUINT MatchArgument(asCArray<int> &funcs, asCArray<int> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct = true);
+	asUINT MatchArgument(asCArray<int> &funcs, asCArray<asSOverloadCandidate> &matches, const asCTypeInfo *argType, int paramNum, bool allowObjectConstruct = true);
 	void PerformFunctionCall(int funcId, asSExprContext *out, bool isConstructor = false, asCArray<asSExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void PerformFunctionCall(int funcId, asSExprContext *out, bool isConstructor = false, asCArray<asSExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset);
 	void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset);
 	void MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asSExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
 	void MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asSExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
@@ -233,6 +243,7 @@ protected:
 	void PushVariableOnStack(asSExprContext *ctx, bool asReference);
 	void PushVariableOnStack(asSExprContext *ctx, bool asReference);
 	void DestroyVariables(asCByteCode *bc);
 	void DestroyVariables(asCByteCode *bc);
 	asSNameSpace *DetermineNameSpace(const asCString &scope);
 	asSNameSpace *DetermineNameSpace(const asCString &scope);
+	int  SetupParametersAndReturnVariable(asCArray<asCString> &parameterNames, asCScriptNode *func);
 
 
 	// Returns the cost of the conversion (the sum of the EConvCost performed)
 	// Returns the cost of the conversion (the sum of the EConvCost performed)
 	asUINT ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
 	asUINT ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
@@ -249,9 +260,9 @@ protected:
 	asUINT ProcessStringConstant(asCString &str, asCScriptNode *node, bool processEscapeSequences = true);
 	asUINT ProcessStringConstant(asCString &str, asCScriptNode *node, bool processEscapeSequences = true);
 	void ProcessHeredocStringConstant(asCString &str, asCScriptNode *node);
 	void ProcessHeredocStringConstant(asCString &str, asCScriptNode *node);
 	int  GetPrecedence(asCScriptNode *op);
 	int  GetPrecedence(asCScriptNode *op);
-	void Error(const char *msg, asCScriptNode *node);
-	void Warning(const char *msg, asCScriptNode *node);
-	void Information(const char *msg, asCScriptNode *node);
+	void Error(const asCString &msg, asCScriptNode *node);
+	void Warning(const asCString &msg, asCScriptNode *node);
+	void Information(const asCString &msg, asCScriptNode *node);
 	void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node);
 	void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node);
 	void AddVariableScope(bool isBreakScope = false, bool isContinueScope = false);
 	void AddVariableScope(bool isBreakScope = false, bool isContinueScope = false);
 	void RemoveVariableScope();
 	void RemoveVariableScope();
@@ -269,8 +280,9 @@ protected:
 	asCScriptCode *script;
 	asCScriptCode *script;
 	asCScriptFunction *outFunc;
 	asCScriptFunction *outFunc;
 
 
-	bool m_isConstructor;
-	bool m_isConstructorCalled;
+	bool               m_isConstructor;
+	bool               m_isConstructorCalled;
+	sClassDeclaration *m_classDecl;
 
 
 	asCArray<int> breakLabels;
 	asCArray<int> breakLabels;
 	asCArray<int> continueLabels;
 	asCArray<int> continueLabels;
@@ -284,11 +296,25 @@ protected:
 	void ReleaseTemporaryVariable(int offset, asCByteCode *bc);
 	void ReleaseTemporaryVariable(int offset, asCByteCode *bc);
 	bool IsVariableOnHeap(int offset);
 	bool IsVariableOnHeap(int offset);
 
 
+	// This ordered array indicates the type of each variable
 	asCArray<asCDataType> variableAllocations;
 	asCArray<asCDataType> variableAllocations;
+
+	// This ordered array indicates which variables are temporaries or not
 	asCArray<bool>        variableIsTemporary;
 	asCArray<bool>        variableIsTemporary;
+
+	// This unordered array gives the offsets of all temporary variables, whether currently allocated or not
+	asCArray<int>         tempVariableOffsets;
+
+	// This ordered array indicated if the variable is on the heap or not
 	asCArray<bool>        variableIsOnHeap;
 	asCArray<bool>        variableIsOnHeap;
+
+	// This unordered array gives the indexes of the currently unused variables
 	asCArray<int>         freeVariables;
 	asCArray<int>         freeVariables;
-	asCArray<int>         tempVariables;
+
+	// This array holds the offsets of the currently allocated temporary variables
+	asCArray<int>         tempVariables; 
+
+	// This array holds the indices of variables that must not be used in an allocation
 	asCArray<int>         reservedVariables;
 	asCArray<int>         reservedVariables;
 
 
 	bool isCompilingDefaultArg;
 	bool isCompilingDefaultArg;

+ 121 - 67
ThirdParty/AngelScript/source/as_config.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -28,7 +28,6 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
 
 
 //
 //
 // as_config.h
 // as_config.h
@@ -61,7 +60,7 @@
 
 
 // AS_DEBUG
 // AS_DEBUG
 // This flag can be defined to make the library write some extra output when
 // This flag can be defined to make the library write some extra output when
-// compiling and executing scripts. 
+// compiling and executing scripts.
 
 
 // AS_DEPRECATED
 // AS_DEPRECATED
 // If this flag is defined then some backwards compatibility is maintained.
 // If this flag is defined then some backwards compatibility is maintained.
@@ -79,9 +78,9 @@
 // AS_DOUBLEBYTE_CHARSET
 // AS_DOUBLEBYTE_CHARSET
 // When this flag is defined, the parser will treat all characters in strings
 // When this flag is defined, the parser will treat all characters in strings
 // that are greater than 127 as lead characters and automatically include the
 // that are greater than 127 as lead characters and automatically include the
-// next character in the script without checking its value. This should be 
-// compatible with common encoding schemes, e.g. Big5. Shift-JIS is not compatible 
-// though as it encodes some single byte characters above 127. 
+// next character in the script without checking its value. This should be
+// compatible with common encoding schemes, e.g. Big5. Shift-JIS is not compatible
+// though as it encodes some single byte characters above 127.
 //
 //
 // If support for international text is desired, it is recommended that UTF-8
 // If support for international text is desired, it is recommended that UTF-8
 // is used as this is supported natively by the compiler without the use for this
 // is used as this is supported natively by the compiler without the use for this
@@ -95,6 +94,12 @@
 // AS_NO_EXCEPTIONS
 // AS_NO_EXCEPTIONS
 // Define this if exception handling is turned off or not available on the target platform.
 // Define this if exception handling is turned off or not available on the target platform.
 
 
+// AS_NO_MEMBER_INIT
+// Disable the support for initialization of class members directly in the declaration.
+// This was as a form to maintain backwards compatibility with versions before 2.26.0
+// if the new order of the member initialization caused null pointer exceptions in older
+// scripts (e.g. if a base class accessed members of a derived class through a virtual method).
+
 
 
 //
 //
 // Library usage
 // Library usage
@@ -119,7 +124,7 @@
 //-----------------------------------------
 //-----------------------------------------
 
 
 // asVSNPRINTF(a,b,c,d)
 // asVSNPRINTF(a,b,c,d)
-// Some compilers use different names for this function. You must 
+// Some compilers use different names for this function. You must
 // define this macro to map to the proper function.
 // define this macro to map to the proper function.
 
 
 // ASM_AT_N_T or ASM_INTEL
 // ASM_AT_N_T or ASM_INTEL
@@ -166,15 +171,6 @@
 // CPU differences
 // CPU differences
 //---------------------------------------
 //---------------------------------------
 
 
-// AS_ALIGN
-// Some CPUs require that data words are aligned in some way. This macro
-// should be defined if the words should be aligned to boundaries of the same
-// size as the word, i.e.
-//  1 byte  on 1 byte boundaries
-//  2 bytes on 2 byte boundaries
-//  4 bytes on 4 byte boundaries
-//  8 bytes on 4 byte boundaries (no it's not a typo)
-
 // AS_USE_DOUBLE_AS_FLOAT
 // AS_USE_DOUBLE_AS_FLOAT
 // If there is no 64 bit floating point type, then this constant can be defined
 // If there is no 64 bit floating point type, then this constant can be defined
 // to treat double like normal floats.
 // to treat double like normal floats.
@@ -207,7 +203,7 @@
 // Use MSVC assembler code for the X64 AMD/Intel CPU family
 // Use MSVC assembler code for the X64 AMD/Intel CPU family
 
 
 // AS_64BIT_PTR
 // AS_64BIT_PTR
-// Define this to make the engine store all pointers in 64bit words. 
+// Define this to make the engine store all pointers in 64bit words.
 
 
 // AS_BIG_ENDIAN
 // AS_BIG_ENDIAN
 // Define this for CPUs that use big endian memory layout, e.g. PPC
 // Define this for CPUs that use big endian memory layout, e.g. PPC
@@ -234,6 +230,7 @@
 // AS_DC        - Sega Dreamcast
 // AS_DC        - Sega Dreamcast
 // AS_GC        - Nintendo GameCube
 // AS_GC        - Nintendo GameCube
 // AS_WII       - Nintendo Wii
 // AS_WII       - Nintendo Wii
+// AS_WIIU      - Nintendo Wii U
 // AS_IPHONE    - Apple IPhone
 // AS_IPHONE    - Apple IPhone
 // AS_ANDROID   - Android
 // AS_ANDROID   - Android
 // AS_HAIKU     - Haiku
 // AS_HAIKU     - Haiku
@@ -272,7 +269,7 @@
 // or in the registers as normal structures
 // or in the registers as normal structures
 
 
 // COMPLEX_MASK
 // COMPLEX_MASK
-// This constant shows what attributes determine if an object is implicitly passed 
+// This constant shows what attributes determine if an object is implicitly passed
 // by reference or not, even if the argument is declared by value
 // by reference or not, even if the argument is declared by value
 
 
 // THISCALL_RETURN_SIMPLE_IN_MEMORY
 // THISCALL_RETURN_SIMPLE_IN_MEMORY
@@ -320,7 +317,7 @@
 
 
 // SPLIT_OBJS_BY_MEMBER_TYPES
 // SPLIT_OBJS_BY_MEMBER_TYPES
 // On some platforms objects with primitive members are split over different
 // On some platforms objects with primitive members are split over different
-// register types when passed by value to functions. 
+// register types when passed by value to functions.
 
 
 
 
 
 
@@ -398,10 +395,8 @@
 	#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 	#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 	#define THISCALL_PASS_OBJECT_POINTER_IN_ECX
 	#define THISCALL_PASS_OBJECT_POINTER_IN_ECX
 
 
-	// There doesn't seem to be a standard define to identify Marmalade, so we'll 
-	// look for one of these defines that have to be given by the project settings
 	// http://www.madewithmarmalade.com/
 	// http://www.madewithmarmalade.com/
-	#if defined(AS_MARMALADE) || defined (MARMALADE)
+	#if defined(__S3E__)
 		#ifndef AS_MARMALADE
 		#ifndef AS_MARMALADE
 			// From now on we'll use the below define
 			// From now on we'll use the below define
 			#define AS_MARMALADE
 			#define AS_MARMALADE
@@ -409,8 +404,20 @@
 
 
 		// Marmalade doesn't use the Windows libraries
 		// Marmalade doesn't use the Windows libraries
 		#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 		#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
-		#define AS_POSIX_THREADS
+		
+		// Marmalade doesn't seem to have proper support for 
+		// atomic instructions or read/write locks, so we turn off 
+		// multithread support
+		//#define AS_POSIX_THREADS
+		#define AS_NO_THREADS
 		#define AS_NO_ATOMIC
 		#define AS_NO_ATOMIC
+
+		// Marmalade has it's own way of identifying the CPU target
+		// Note, when building for ARM, the gnuc compiler will always  
+		// be used so we don't need to check for it here
+		#if defined(I3D_ARCH_X86)
+			#define AS_X86
+		#endif
 	#else
 	#else
 		#if _MSC_VER < 1500  // MSVC++ 9 (aka MSVC++ .NET 2008)
 		#if _MSC_VER < 1500  // MSVC++ 9 (aka MSVC++ .NET 2008)
 			#define asVSNPRINTF(a, b, c, d) _vsnprintf(a, b, c, d)
 			#define asVSNPRINTF(a, b, c, d) _vsnprintf(a, b, c, d)
@@ -451,7 +458,6 @@
 	#endif
 	#endif
 
 
 	#ifdef _ARM_
 	#ifdef _ARM_
-		#define AS_ALIGN
 		#define AS_ARM
 		#define AS_ARM
 		#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 		#define CDECL_RETURN_SIMPLE_IN_MEMORY
 		#define CDECL_RETURN_SIMPLE_IN_MEMORY
@@ -496,7 +502,7 @@
 	#define UNREACHABLE_RETURN
 	#define UNREACHABLE_RETURN
 #endif
 #endif
 
 
-// SN Systems ProDG 
+// SN Systems ProDG
 #if defined(__SNC__) || defined(SNSYS)
 #if defined(__SNC__) || defined(SNSYS)
 	#define GNU_STYLE_VIRTUAL_METHOD
 	#define GNU_STYLE_VIRTUAL_METHOD
 	#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
 	#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
@@ -539,6 +545,7 @@
 #endif
 #endif
 
 
 // GNU C (and MinGW or Cygwin on Windows)
 // GNU C (and MinGW or Cygwin on Windows)
+// Use the following command to determine predefined macros: echo . | mingw32-g++ -dM -E -
 #if (defined(__GNUC__) && !defined(__SNC__)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
 #if (defined(__GNUC__) && !defined(__SNC__)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
 	#define GNU_STYLE_VIRTUAL_METHOD
 	#define GNU_STYLE_VIRTUAL_METHOD
 #if !defined( __amd64__ )
 #if !defined( __amd64__ )
@@ -556,13 +563,66 @@
 	#define STDCALL __attribute__((stdcall))
 	#define STDCALL __attribute__((stdcall))
 	#define ASM_AT_N_T
 	#define ASM_AT_N_T
 
 
+	// WII U
+	#if defined(__ghs__)
+		#define AS_WIIU
+	
+		// Native calling conventions are not yet supported
+		#define AS_MAX_PORTABILITY
+
+	// Marmalade is a cross platform SDK. It uses g++ to compile for iOS and Android
+	#elif defined(__S3E__)
+		#ifndef AS_MARMALADE
+			// From now on we'll use the below define
+			#define AS_MARMALADE
+		#endif
+
+		// STDCALL is not available on Marmalade when compiled for iOS or Android
+		#undef STDCALL
+		#define STDCALL
+
+		// Marmalade doesn't seem to have proper support for 
+		// atomic instructions or read/write locks
+		#define AS_NO_THREADS
+		#define AS_NO_ATOMIC
+
+		// Identify for which CPU the library is being built
+		#if defined(I3D_ARCH_X86)
+			#define AS_X86
+		#elif defined(I3D_ARCH_ARM)
+			#define AS_ARM
+		
+			// Marmalade appear to use the same ABI as Android when built for ARM
+			#define CDECL_RETURN_SIMPLE_IN_MEMORY
+			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+
+			#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+			#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+
+			#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+			#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+
+			#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
+			#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+
+			#undef GNU_STYLE_VIRTUAL_METHOD
+
+			#undef COMPLEX_MASK
+			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+
+			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
+		#endif
+
 	// MacOSX and IPhone
 	// MacOSX and IPhone
-	#ifdef __APPLE__
+	#elif defined(__APPLE__)
 
 
 		#include <TargetConditionals.h>
 		#include <TargetConditionals.h>
 
 
-		// Is this a Mac or an IPhone?
-		#ifdef TARGET_OS_IPHONE
+		// Is this a Mac or an IPhone (or other iOS device)?
+		#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1
 			#define AS_IPHONE
 			#define AS_IPHONE
 		#else
 		#else
 			#define AS_MAC
 			#define AS_MAC
@@ -582,6 +642,7 @@
 		#if defined(i386) && !defined(__LP64__)
 		#if defined(i386) && !defined(__LP64__)
 			// Support native calling conventions on Mac OS X + Intel 32bit CPU
 			// Support native calling conventions on Mac OS X + Intel 32bit CPU
 			#define AS_X86
 			#define AS_X86
+			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#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)
 			#undef COMPLEX_RETURN_MASK
 			#undef COMPLEX_RETURN_MASK
@@ -615,8 +676,6 @@
 		#elif (defined(_ARM_) || defined(__arm__))
 		#elif (defined(_ARM_) || defined(__arm__))
 			// The IPhone use an ARM processor
 			// The IPhone use an ARM processor
 			#define AS_ARM
 			#define AS_ARM
-			#define AS_IPHONE
-			#define AS_ALIGN
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -636,7 +695,7 @@
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#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)
-			
+
 			// STDCALL is not available on ARM
 			// STDCALL is not available on ARM
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
@@ -644,14 +703,8 @@
 			// Unknown CPU type
 			// Unknown CPU type
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
 		#endif
 		#endif
-		
-		// Urho3D: compile AngelScript without threading on iOS, as there will only be a single execution context
-		#ifndef AS_IPHONE
-			#define AS_POSIX_THREADS
-		#else
-			#define AS_NO_ATOMIC
-		#endif
-		
+		#define AS_POSIX_THREADS
+
 	// Windows
 	// Windows
 	#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
 	#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
 		// On Windows the simple classes are returned in the EAX:EDX registers
 		// On Windows the simple classes are returned in the EAX:EDX registers
@@ -667,6 +720,17 @@
 		#if defined(i386) && !defined(__LP64__)
 		#if defined(i386) && !defined(__LP64__)
 			// Support native calling conventions on Intel 32bit CPU
 			// Support native calling conventions on Intel 32bit CPU
 			#define AS_X86
 			#define AS_X86
+
+			// As of version 4.7 MinGW changed the ABI, presumably
+			// to be better aligned with how MSVC works
+			#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4
+				#undef  CALLEE_POPS_HIDDEN_RETURN_POINTER
+				#define THISCALL_CALLEE_POPS_ARGUMENTS
+			#else
+				// Earlier versions than 4.7
+				#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
+			#endif
+
 		#elif defined(__x86_64__)
 		#elif defined(__x86_64__)
 			#define AS_X64_MINGW
 			#define AS_X64_MINGW
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
@@ -692,6 +756,7 @@
 			#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)
 
 
 			// Support native calling conventions on Intel 32bit CPU
 			// Support native calling conventions on Intel 32bit CPU
+			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
 		#elif defined(__LP64__)
 		#elif defined(__LP64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
@@ -708,9 +773,7 @@
 			#define STDCALL
 			#define STDCALL
 		#elif defined(__ARMEL__) || defined(__arm__)
 		#elif defined(__ARMEL__) || defined(__arm__)
 			#define AS_ARM
 			#define AS_ARM
-			#define AS_ALIGN
 			#define AS_NO_ATOMIC
 			#define AS_NO_ATOMIC
-			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 
 
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -723,6 +786,13 @@
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
 			#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
+		#elif defined(__mips__)
+			#define AS_MIPS
+			#define AS_BIG_ENDIAN
+			#define AS_USE_DOUBLE_AS_FLOAT
+
+			// Native calling conventions for Linux/Mips do not work yet.
+			#define AS_MAX_PORTABILITY
 		#else
 		#else
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
 		#endif
 		#endif
@@ -742,6 +812,7 @@
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#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 THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
 		#elif defined(__LP64__)
 		#elif defined(__LP64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
@@ -832,7 +903,6 @@
 
 
 			#define AS_ARM
 			#define AS_ARM
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
-			#define AS_ALIGN
 		#endif
 		#endif
 
 
 	// Haiku OS
 	// Haiku OS
@@ -843,6 +913,7 @@
 		// for future compatibility
 		// for future compatibility
 		#if defined(i386) && !defined(__LP64__)
 		#if defined(i386) && !defined(__LP64__)
 			#define AS_X86
 			#define AS_X86
+			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define CDECL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -864,6 +935,7 @@
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 
 
 			// Support native calling conventions on Intel 32bit CPU
 			// Support native calling conventions on Intel 32bit CPU
+			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
 		#elif defined(__LP64__)
 		#elif defined(__LP64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
@@ -899,7 +971,6 @@
 
 
 // MIPS architecture (generally PS2 and PSP consoles, potentially supports N64 as well)
 // MIPS architecture (generally PS2 and PSP consoles, potentially supports N64 as well)
 #if defined(_MIPS_ARCH) || defined(_mips) || defined(__MIPSEL__) || defined(__PSP__) || defined(__psp__) || defined(_EE_) || defined(_PSP) || defined(_PS2)
 #if defined(_MIPS_ARCH) || defined(_mips) || defined(__MIPSEL__) || defined(__PSP__) || defined(__psp__) || defined(_EE_) || defined(_PSP) || defined(_PS2)
-	#define AS_ALIGN				// align datastructures
 	#define AS_USE_DOUBLE_AS_FLOAT	// use 32bit floats instead of doubles
 	#define AS_USE_DOUBLE_AS_FLOAT	// use 32bit floats instead of doubles
 #endif
 #endif
 
 
@@ -909,26 +980,12 @@
 
 
 	// Gamecube
 	// Gamecube
 	#if defined(_GC)
 	#if defined(_GC)
-		#define AS_ALIGN
 		#define AS_USE_DOUBLE_AS_FLOAT
 		#define AS_USE_DOUBLE_AS_FLOAT
 	#endif
 	#endif
-	// XBox 360
-	#if (_XBOX_VER >= 200)
-		#define AS_ALIGN
-	#endif
-	// PS3
-	#if defined(__PPU__)
-		#define AS_ALIGN
-	#endif
-	// Wii
-	#if defined(EPPC)
-		#define AS_ALIGN
-	#endif
 #endif
 #endif
 
 
 // Dreamcast console
 // Dreamcast console
 #ifdef __SH4_SINGLE_ONLY__
 #ifdef __SH4_SINGLE_ONLY__
-	#define AS_ALIGN				// align datastructures
 	#define AS_USE_DOUBLE_AS_FLOAT	// use 32bit floats instead of doubles
 	#define AS_USE_DOUBLE_AS_FLOAT	// use 32bit floats instead of doubles
 #endif
 #endif
 
 
@@ -940,6 +997,12 @@
 	#endif
 	#endif
 #endif
 #endif
 
 
+// If the platform doesn't support atomic instructions we can't allow 
+// multithreading as the reference counters won't be threadsafe
+#if defined(AS_NO_ATOMIC) && !defined(AS_NO_THREADS)
+	#define AS_NO_THREADS
+#endif
+
 // If the form of threads to use hasn't been chosen
 // If the form of threads to use hasn't been chosen
 // then the library will be compiled without support
 // then the library will be compiled without support
 // for multithreading
 // for multithreading
@@ -947,9 +1010,6 @@
 	#define AS_NO_THREADS
 	#define AS_NO_THREADS
 #endif
 #endif
 
 
-// Urho3D: always use float type, use EMMS to clear FPU stack
-#define AS_USE_DOUBLE_AS_FLOAT
-#define CLEAR_FPU_STACK emms
 
 
 // The assert macro
 // The assert macro
 #if defined(ANDROID)
 #if defined(ANDROID)
@@ -977,12 +1037,6 @@
 // Internal defines (do not change these)
 // Internal defines (do not change these)
 //----------------------------------------------------------------
 //----------------------------------------------------------------
 
 
-#ifdef AS_ALIGN
-	#define	ALIGN(b) (((b)+3)&(~3))
-#else
-	#define	ALIGN(b) (b)
-#endif
-
 #define ARG_W(b)     ((asWORD*)&b)
 #define ARG_W(b)     ((asWORD*)&b)
 #define ARG_DW(b)    ((asDWORD*)&b)
 #define ARG_DW(b)    ((asDWORD*)&b)
 #define ARG_QW(b)    ((asQWORD*)&b)
 #define ARG_QW(b)    ((asQWORD*)&b)
@@ -994,7 +1048,7 @@
 
 
 // This macro is used to avoid warnings about unused variables.
 // This macro is used to avoid warnings about unused variables.
 // Usually where the variables are only used in debug mode.
 // Usually where the variables are only used in debug mode.
-#define UNUSED_VAR(x) (x)=(x)
+#define UNUSED_VAR(x) (void)(x)
 
 
 #include "../include/angelscript.h"
 #include "../include/angelscript.h"
 #include "as_memory.h"
 #include "as_memory.h"

+ 28 - 11
ThirdParty/AngelScript/source/as_context.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -80,7 +80,7 @@ public:
 		// It's useful for determining what needs to be optimized.
 		// It's useful for determining what needs to be optimized.
 
 
 		_mkdir("AS_DEBUG");
 		_mkdir("AS_DEBUG");
-		#if _MSC_VER >= 1500 
+		#if _MSC_VER >= 1500 && !defined(AS_MARMALADE)
 			FILE *f;
 			FILE *f;
 			fopen_s(&f, "AS_DEBUG/stats.txt", "wt");
 			fopen_s(&f, "AS_DEBUG/stats.txt", "wt");
 		#else
 		#else
@@ -202,7 +202,9 @@ bool asCContext::IsNested(asUINT *nestCount) const
 		return false;
 		return false;
 
 
 	// Search for a marker on the call stack
 	// Search for a marker on the call stack
-	for( asUINT n = 1; n <= c; n++ )
+	// This loop starts at 2 because the 0th entry is not stored in m_callStack, 
+	// and then we need to subtract one more to get the base of each frame
+	for( asUINT n = 2; n <= c; n++ )
 	{
 	{
 		const asPWORD *s = m_callStack.AddressOf() + (c - n)*CALLSTACK_FRAME_SIZE;
 		const asPWORD *s = m_callStack.AddressOf() + (c - n)*CALLSTACK_FRAME_SIZE;
 		if( s && s[0] == 0 )
 		if( s && s[0] == 0 )
@@ -1152,6 +1154,13 @@ int asCContext::Execute()
 	while( m_status == asEXECUTION_ACTIVE )
 	while( m_status == asEXECUTION_ACTIVE )
 		ExecuteNext();
 		ExecuteNext();
 
 
+	if( m_lineCallback )
+	{
+		// Call the line callback one last time before leaving 
+		// so anyone listening can catch the state change
+		CallLineCallback();
+	}
+
 	if( m_engine->ep.autoGarbageCollect )
 	if( m_engine->ep.autoGarbageCollect )
 	{
 	{
 		asUINT gcPosObjects = 0;
 		asUINT gcPosObjects = 0;
@@ -1377,11 +1386,19 @@ int asCContext::GetLineNumber(asUINT stackLevel, int *column, const char **secti
 		bytePos -= 1;
 		bytePos -= 1;
 	}
 	}
 
 
-	asDWORD line = func->GetLineNumber(int(bytePos - func->byteCode.AddressOf()));
-	if( column ) *column = (line >> 20);
-
-	if( sectionName ) *sectionName = func->GetScriptSectionName();
+	// For nested calls it is possible that func is null
+	if( func == 0 )
+	{
+		if( column ) *column = 0;
+		if( sectionName ) *sectionName = 0;
+		return 0;
+	}
 
 
+	int sectionIdx;
+	asDWORD line = func->GetLineNumber(int(bytePos - func->byteCode.AddressOf()), &sectionIdx);
+	if( column ) *column = (line >> 20);
+	if( sectionName ) 
+		*sectionName = sectionIdx >= 0 ? m_engine->scriptSectionNames[sectionIdx]->AddressOf() : 0;
 	return (line & 0xFFFFF);
 	return (line & 0xFFFFF);
 }
 }
 
 
@@ -3863,7 +3880,7 @@ void asCContext::SetInternalException(const char *descr)
 
 
 	m_exceptionString       = descr;
 	m_exceptionString       = descr;
 	m_exceptionFunction     = m_currentFunction->id;
 	m_exceptionFunction     = m_currentFunction->id;
-	m_exceptionLine         = m_currentFunction->GetLineNumber(int(m_regs.programPointer - m_currentFunction->byteCode.AddressOf()));
+	m_exceptionLine         = m_currentFunction->GetLineNumber(int(m_regs.programPointer - m_currentFunction->byteCode.AddressOf()), &m_exceptionSectionIdx);
 	m_exceptionColumn       = m_exceptionLine >> 20;
 	m_exceptionColumn       = m_exceptionLine >> 20;
 	m_exceptionLine        &= 0xFFFFF;
 	m_exceptionLine        &= 0xFFFFF;
 
 
@@ -4224,7 +4241,7 @@ int asCContext::GetExceptionLineNumber(int *column, const char **sectionName)
 
 
 	if( column ) *column = m_exceptionColumn;
 	if( column ) *column = m_exceptionColumn;
 
 
-	if( sectionName ) *sectionName = m_engine->scriptFunctions[m_exceptionFunction]->GetScriptSectionName();
+	if( sectionName ) *sectionName = m_engine->scriptSectionNames[m_exceptionSectionIdx]->AddressOf();
 
 
 	return m_exceptionLine;
 	return m_exceptionLine;
 }
 }
@@ -4275,7 +4292,7 @@ int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
 		}
 		}
 	}
 	}
 
 
-	int r = DetectCallingConvention(isObj, callback, callConv, &m_lineCallbackFunc);
+	int r = DetectCallingConvention(isObj, callback, callConv, 0, &m_lineCallbackFunc);
 	if( r < 0 ) m_lineCallback = false;
 	if( r < 0 ) m_lineCallback = false;
 
 
 	m_regs.doProcessSuspend = m_doSuspend || m_lineCallback;
 	m_regs.doProcessSuspend = m_doSuspend || m_lineCallback;
@@ -4308,7 +4325,7 @@ int asCContext::SetExceptionCallback(asSFuncPtr callback, void *obj, int callCon
 			return asINVALID_ARG;
 			return asINVALID_ARG;
 		}
 		}
 	}
 	}
-	int r = DetectCallingConvention(isObj, callback, callConv, &m_exceptionCallbackFunc);
+	int r = DetectCallingConvention(isObj, callback, callConv, 0, &m_exceptionCallbackFunc);
 	if( r < 0 ) m_exceptionCallback = false;
 	if( r < 0 ) m_exceptionCallback = false;
 	return r;
 	return r;
 }
 }

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

@@ -188,6 +188,7 @@ public:
 	bool      m_inExceptionHandler;
 	bool      m_inExceptionHandler;
 	asCString m_exceptionString;
 	asCString m_exceptionString;
 	int       m_exceptionFunction;
 	int       m_exceptionFunction;
+	int       m_exceptionSectionIdx;
 	int       m_exceptionLine;
 	int       m_exceptionLine;
 	int       m_exceptionColumn;
 	int       m_exceptionColumn;
 
 

+ 14 - 53
ThirdParty/AngelScript/source/as_datatype.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -28,7 +28,6 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
 
 
 //
 //
 // as_datatype.cpp
 // as_datatype.cpp
@@ -54,8 +53,6 @@ asCDataType::asCDataType()
 	isObjectHandle = false;
 	isObjectHandle = false;
 	isConstHandle  = false;
 	isConstHandle  = false;
 	funcDef        = 0;
 	funcDef        = 0;
-	// Urho3D: reset cached type id
-	cachedTypeId   = 0;
 }
 }
 
 
 asCDataType::asCDataType(const asCDataType &dt)
 asCDataType::asCDataType(const asCDataType &dt)
@@ -67,8 +64,6 @@ asCDataType::asCDataType(const asCDataType &dt)
 	isObjectHandle = dt.isObjectHandle;
 	isObjectHandle = dt.isObjectHandle;
 	isConstHandle  = dt.isConstHandle;
 	isConstHandle  = dt.isConstHandle;
 	funcDef        = dt.funcDef;
 	funcDef        = dt.funcDef;
-	// Urho3D: copy cached type id
-	cachedTypeId   = dt.cachedTypeId;
 }
 }
 
 
 asCDataType::~asCDataType()
 asCDataType::~asCDataType()
@@ -173,7 +168,8 @@ asCString asCDataType::Format(bool includeNamespace) const
 	}
 	}
 	else if( IsArrayType() && objectType && !objectType->engine->ep.expandDefaultArrayToTemplate )
 	else if( IsArrayType() && objectType && !objectType->engine->ep.expandDefaultArrayToTemplate )
 	{
 	{
-		str += objectType->templateSubType.Format(includeNamespace);
+		asASSERT( objectType->templateSubTypes.GetLength() == 1 );
+		str += objectType->templateSubTypes[0].Format(includeNamespace);
 		str += "[]";
 		str += "[]";
 	}
 	}
 	else if( funcDef )
 	else if( funcDef )
@@ -186,7 +182,12 @@ asCString asCDataType::Format(bool includeNamespace) const
 		if( objectType->flags & asOBJ_TEMPLATE )
 		if( objectType->flags & asOBJ_TEMPLATE )
 		{
 		{
 			str += "<";
 			str += "<";
-			str += objectType->templateSubType.Format(includeNamespace);
+			for( asUINT subtypeIndex = 0; subtypeIndex < objectType->templateSubTypes.GetLength(); subtypeIndex++ )
+			{
+				str += objectType->templateSubTypes[subtypeIndex].Format(includeNamespace);
+				if( subtypeIndex != objectType->templateSubTypes.GetLength()-1 )
+					str += ",";
+			}
 			str += ">";
 			str += ">";
 		}
 		}
 	}
 	}
@@ -217,17 +218,12 @@ asCDataType &asCDataType::operator =(const asCDataType &dt)
 	isObjectHandle   = dt.isObjectHandle;
 	isObjectHandle   = dt.isObjectHandle;
 	isConstHandle    = dt.isConstHandle;
 	isConstHandle    = dt.isConstHandle;
 	funcDef          = dt.funcDef;
 	funcDef          = dt.funcDef;
-	// Urho3D: copy cached type id
-	cachedTypeId     = dt.cachedTypeId;
 
 
 	return (asCDataType &)*this;
 	return (asCDataType &)*this;
 }
 }
 
 
 int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 {
 {
-	// Urho3D: reset cached type id
-	cachedTypeId = 0;
-
 	if( !b )
 	if( !b )
 	{
 	{
 		isObjectHandle = b;
 		isObjectHandle = b;
@@ -260,15 +256,14 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 
 
 int asCDataType::MakeArray(asCScriptEngine *engine)
 int asCDataType::MakeArray(asCScriptEngine *engine)
 {
 {
-	// Urho3D: reset cached type id
-	cachedTypeId = 0;
-
 	if( engine->defaultArrayObjectType == 0 )
 	if( engine->defaultArrayObjectType == 0 )
 		return asINVALID_TYPE;
 		return asINVALID_TYPE;
 
 
 	bool tmpIsReadOnly = isReadOnly;
 	bool tmpIsReadOnly = isReadOnly;
 	isReadOnly = false;
 	isReadOnly = false;
-	asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, *this);
+	asCArray<asCDataType> subTypes;
+	subTypes.PushLast(*this);
+	asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes);
 	isReadOnly = tmpIsReadOnly;
 	isReadOnly = tmpIsReadOnly;
 
 
 	isObjectHandle = false;
 	isObjectHandle = false;
@@ -282,9 +277,6 @@ int asCDataType::MakeArray(asCScriptEngine *engine)
 
 
 int asCDataType::MakeReference(bool b)
 int asCDataType::MakeReference(bool b)
 {
 {
-	// Urho3D: reset cached type id
-	cachedTypeId = 0;
-
 	isReference = b;
 	isReference = b;
 
 
 	return 0;
 	return 0;
@@ -292,9 +284,6 @@ int asCDataType::MakeReference(bool b)
 
 
 int asCDataType::MakeReadOnly(bool b)
 int asCDataType::MakeReadOnly(bool b)
 {
 {
-	// Urho3D: reset cached type id
-	cachedTypeId = 0;
-
 	if( isObjectHandle )
 	if( isObjectHandle )
 	{
 	{
 		isConstHandle = b;
 		isConstHandle = b;
@@ -307,9 +296,6 @@ int asCDataType::MakeReadOnly(bool b)
 
 
 int asCDataType::MakeHandleToConst(bool b)
 int asCDataType::MakeHandleToConst(bool b)
 {
 {
-	// Urho3D: reset cached type id
-	cachedTypeId = 0;
-
 	if( !isObjectHandle ) return -1;
 	if( !isObjectHandle ) return -1;
 
 
 	isReadOnly = b;
 	isReadOnly = b;
@@ -401,10 +387,10 @@ bool asCDataType::IsScriptObject() const
 	return false;
 	return false;
 }
 }
 
 
-asCDataType asCDataType::GetSubType() const
+asCDataType asCDataType::GetSubType(asUINT subtypeIndex) const
 {
 {
 	asASSERT(objectType);
 	asASSERT(objectType);
-	return objectType->templateSubType;
+	return objectType->templateSubTypes[subtypeIndex];
 }
 }
 
 
 
 
@@ -453,31 +439,6 @@ bool asCDataType::IsEqualExceptConst(const asCDataType &dt) const
 	return true;
 	return true;
 }
 }
 
 
-bool asCDataType::IsEqualExceptInterfaceType(const asCDataType &dt) const
-{
-	if( tokenType != dt.tokenType )           return false;
-	if( isReference != dt.isReference )       return false;
-	if( isObjectHandle != dt.isObjectHandle ) return false;
-	if( isReadOnly != dt.isReadOnly )         return false;
-	if( isConstHandle != dt.isConstHandle )   return false;
-
-	if( objectType != dt.objectType )
-	{
-		if( !objectType || !dt.objectType ) return false;
-
-		// If the types are not interfaces or templates with interfaces then the they are not equal
-		if( !objectType->IsInterface() && !((objectType->flags & asOBJ_TEMPLATE) && objectType->templateSubType.GetObjectType() && objectType->templateSubType.GetObjectType()->IsInterface()) ) return false;
-		if( !dt.objectType->IsInterface() && !((dt.objectType->flags & asOBJ_TEMPLATE) && dt.objectType->templateSubType.GetObjectType() && dt.objectType->templateSubType.GetObjectType()->IsInterface()) ) return false;
-
-		// If one is interface and the other is not, then it is not equal
-		if( objectType->IsInterface() != dt.objectType->IsInterface() ) return false;
-	}
-
-	if( funcDef != dt.funcDef ) return false;
-
-	return true;
-}
-
 bool asCDataType::IsPrimitive() const
 bool asCDataType::IsPrimitive() const
 {
 {
 	//	Enumerations are primitives
 	//	Enumerations are primitives

+ 5 - 15
ThirdParty/AngelScript/source/as_datatype.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -28,7 +28,6 @@
    [email protected]
    [email protected]
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
 
 
 //
 //
 // as_datatype.h
 // as_datatype.h
@@ -98,7 +97,6 @@ public:
 	bool IsEqualExceptRef(const asCDataType &)             const;
 	bool IsEqualExceptRef(const asCDataType &)             const;
 	bool IsEqualExceptRefAndConst(const asCDataType &)     const;
 	bool IsEqualExceptRefAndConst(const asCDataType &)     const;
 	bool IsEqualExceptConst(const asCDataType &)           const;
 	bool IsEqualExceptConst(const asCDataType &)           const;
-	bool IsEqualExceptInterfaceType(const asCDataType &dt) const;
 	bool IsNullHandle()                                    const;
 	bool IsNullHandle()                                    const;
 
 
 	bool SupportHandles() const;
 	bool SupportHandles() const;
@@ -108,7 +106,7 @@ public:
 	bool operator ==(const asCDataType &) const;
 	bool operator ==(const asCDataType &) const;
 	bool operator !=(const asCDataType &) const;
 	bool operator !=(const asCDataType &) const;
 
 
-	asCDataType        GetSubType()    const;
+	asCDataType        GetSubType(asUINT subtypeIndex = 0)    const;
 	eTokenType         GetTokenType()  const {return tokenType;}
 	eTokenType         GetTokenType()  const {return tokenType;}
 	asCObjectType     *GetObjectType() const {return objectType;}
 	asCObjectType     *GetObjectType() const {return objectType;}
 	asCScriptFunction *GetFuncDef()    const {return funcDef;}
 	asCScriptFunction *GetFuncDef()    const {return funcDef;}
@@ -117,19 +115,14 @@ public:
 	int  GetSizeInMemoryBytes()  const;
 	int  GetSizeInMemoryBytes()  const;
 	int  GetSizeInMemoryDWords() const;
 	int  GetSizeInMemoryDWords() const;
 
 
-	// Urho3D: reset cached type id whenever something changes
-	void SetTokenType(eTokenType tt)         { tokenType = tt; cachedTypeId = 0; }
-	void SetObjectType(asCObjectType *obj)   { objectType = obj; cachedTypeId = 0; }
-	void SetFuncDef(asCScriptFunction *func) { asASSERT(funcDef); funcDef = func; cachedTypeId = 0; }
+	void SetTokenType(eTokenType tt)         {tokenType = tt;}
+	void SetObjectType(asCObjectType *obj)   {objectType = obj;}
+	void SetFuncDef(asCScriptFunction *func) { asASSERT(funcDef); funcDef = func; }
 
 
 	asCDataType &operator =(const asCDataType &);
 	asCDataType &operator =(const asCDataType &);
 
 
 	asSTypeBehaviour *GetBehaviour() const;
 	asSTypeBehaviour *GetBehaviour() const;
 
 
-	// Urho3D: cache the type id for repeated queries
-	void SetCachedTypeId(int id)       const {cachedTypeId = id;}
-	int GetCachedTypeId()              const {return cachedTypeId;}
-
 protected:
 protected:
 	// Base object type
 	// Base object type
 	eTokenType tokenType;
 	eTokenType tokenType;
@@ -138,9 +131,6 @@ protected:
 	asCObjectType *objectType;
 	asCObjectType *objectType;
 	asCScriptFunction *funcDef;
 	asCScriptFunction *funcDef;
 
 
-	// Urho3D: cached type id
-	mutable int cachedTypeId;
-
 	// Top level
 	// Top level
 	bool isReference:1;
 	bool isReference:1;
 	bool isReadOnly:1;
 	bool isReadOnly:1;

+ 209 - 3
ThirdParty/AngelScript/source/as_debug.h

@@ -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 
@@ -36,6 +36,8 @@
 #ifndef AS_DEBUG_H
 #ifndef AS_DEBUG_H
 #define AS_DEBUG_H
 #define AS_DEBUG_H
 
 
+#include "as_config.h"
+
 #ifndef AS_WII
 #ifndef AS_WII
 // The Wii SDK doesn't have these, we'll survive without AS_DEBUG
 // The Wii SDK doesn't have these, we'll survive without AS_DEBUG
 
 
@@ -44,15 +46,219 @@
 
 
 
 
 #if defined(__GNUC__) || defined( AS_MARMALADE )
 #if defined(__GNUC__) || defined( AS_MARMALADE )
+
+#ifdef __ghs__ 
+// WIIU defines __GNUC__ but types are not defined here in 'conventional' way 
+#include <types.h>
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+typedef float float32_t;
+typedef double float64_t;
+#else
 // Define mkdir for GNUC
 // Define mkdir for GNUC
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #define _mkdir(dirname) mkdir(dirname, S_IRWXU)
 #define _mkdir(dirname) mkdir(dirname, S_IRWXU)
+#endif
 #else
 #else
 #include <direct.h>
 #include <direct.h>
 #endif
 #endif
-#endif
-#endif
+
+
+#if defined(_MSC_VER) && defined(AS_PROFILE)
+// Currently only do profiling with MSVC++
+
+#include <mmsystem.h>
+#include "as_string.h"
+#include "as_map.h"
+#include "as_string_util.h"
+
+BEGIN_AS_NAMESPACE
+
+struct TimeCount
+{
+	double time;
+	int    count;
+	double max;
+	double min;
+};
+
+class CProfiler
+{
+public:
+	CProfiler()
+	{
+		// We need to know how often the clock is updated
+		__int64 tps;
+		if( !QueryPerformanceFrequency((LARGE_INTEGER *)&tps) )
+			usePerformance = false;
+		else
+		{
+			usePerformance = true;
+			ticksPerSecond = double(tps);
+		}
+
+		timeOffset = GetTime();
+	}
+
+	~CProfiler()
+	{
+		WriteSummary();
+	}
+
+	double GetTime()
+	{
+		if( usePerformance )
+		{
+			__int64 ticks;
+			QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
+
+			return double(ticks)/ticksPerSecond - timeOffset;
+		}
+		
+		return double(timeGetTime())/1000.0 - timeOffset;
+	}
+
+	double Begin(const char *name)
+	{
+		double time = GetTime();
+
+		// Add the scope to the key
+		if( key.GetLength() )
+			key += "|";
+		key += name;
+
+		// Compensate for the time spent writing to the file
+		timeOffset += GetTime() - time;
+
+		return time;
+	}
+
+	void End(const char *name, double beginTime)
+	{
+		double time = GetTime();
+
+		double elapsed = time - beginTime;
+
+		// Update the profile info for this scope
+		asSMapNode<asCString, TimeCount> *cursor;
+		if( map.MoveTo(&cursor, key) )
+		{
+			cursor->value.time += elapsed;
+			cursor->value.count++;
+			if( cursor->value.max < elapsed ) 
+				cursor->value.max = elapsed;
+			if( cursor->value.min > elapsed ) 
+				cursor->value.min = elapsed;
+		}
+		else
+		{
+			TimeCount tc = {elapsed, 1, elapsed, elapsed};
+			map.Insert(key, tc);
+		}
+
+		// Remove the inner most scope from the key
+		int n = key.FindLast("|");
+		if( n > 0 )
+			key.SetLength(n);
+		else
+			key.SetLength(0);
+
+		// Compensate for the time spent writing to the file
+		timeOffset += GetTime() - time;
+	}
+	
+protected:
+	void WriteSummary()
+	{
+		// Write the analyzed info into a file for inspection
+		_mkdir("AS_DEBUG");
+		FILE *fp;
+		#if _MSC_VER >= 1500 && !defined(AS_MARMALADE)
+			fopen_s(&fp, "AS_DEBUG/profiling_summary.txt", "wt");
+		#else
+			fp = fopen("AS_DEBUG/profiling_summary.txt", "wt");
+		#endif
+		if( fp == 0 )
+			return;
+
+		fprintf(fp, "%-60s %10s %15s %15s %15s %15s\n\n", "Scope", "Count", "Tot time", "Avg time", "Max time", "Min time");
+
+		asSMapNode<asCString, TimeCount> *cursor;
+		map.MoveLast(&cursor);
+		while( cursor )
+		{
+			asCString key = cursor->key;
+			int count;
+			int n = key.FindLast("|", &count);
+			if( count )
+			{
+				key = asCString("                                               ", count) + key.SubString(n+1);
+			}
+
+			fprintf(fp, "%-60s %10d %15.6f %15.6f %15.6f %15.6f\n", key.AddressOf(), cursor->value.count, cursor->value.time, cursor->value.time / cursor->value.count, cursor->value.max, cursor->value.min);
+
+			map.MovePrev(&cursor, cursor);
+		}
+
+		fclose(fp);
+	}
+
+	double  timeOffset;
+	double  ticksPerSecond;
+	bool    usePerformance;
+
+	asCString                    key;
+	asCMap<asCString, TimeCount> map;
+};
+
+extern CProfiler g_profiler;
+
+class CProfilerScope
+{
+public:
+	CProfilerScope(const char *name)
+	{
+		this->name = name;
+		beginTime = g_profiler.Begin(name);
+	}
+
+	~CProfilerScope()
+	{
+		g_profiler.End(name, beginTime);
+	}
+
+protected:
+	const char *name;
+	double      beginTime;
+};
+
+#define TimeIt(x) CProfilerScope profilescope(x)
+
+END_AS_NAMESPACE
+
+#else // _MSC_VER && AS_PROFILE
+
+// Define it so nothing is done
+#define TimeIt(x) 
+
+#endif // !(_MSC_VER && AS_PROFILE)
+
+
+
+
+
+
+
+
+#endif // _WIN32_WCE
+#endif // AS_WII
 
 
 #endif
 #endif
 
 

+ 57 - 8
ThirdParty/AngelScript/source/as_gc.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    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
@@ -57,6 +57,29 @@ asCGarbageCollector::asCGarbageCollector()
 	isProcessing    = false;
 	isProcessing    = false;
 }
 }
 
 
+asCGarbageCollector::~asCGarbageCollector()
+{
+	// This local typedef is done to workaround a compiler error on
+	// MSVC6 when using the typedef declared in the class definition
+	typedef asSMapNode_t node_t;
+	for( asUINT n = 0; n < freeNodes.GetLength(); n++ )
+		asDELETE(freeNodes[n], node_t);
+	freeNodes.SetLength(0);
+}
+
+bool asCGarbageCollector::IsObjectInGC(void *obj)
+{
+	asUINT n;
+	for( n = 0; n < gcNewObjects.GetLength(); n++ )
+		if( gcNewObjects[n].obj == obj )
+			return true;
+	for( n = 0; n < gcOldObjects.GetLength(); n++ )
+		if( gcOldObjects[n].obj == obj )
+			return true;
+
+	return false;
+}
+
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 {
 {
 	if( obj == 0 || objType == 0 )
 	if( obj == 0 || objType == 0 )
@@ -163,12 +186,19 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
 				if( count != (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength()) )
 				if( count != (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength()) )
 					count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
 					count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
 				else
 				else
-					break;
+				{
+					// Let the engine destroy the types that reached refCount 0
+					// If none were destroyed, then leave the GC
+					// TODO: The asCObjectType should destroy its content when refCount reaches 0
+					//       since no-one is using them. The registered types should have their
+					//       refcount increased by the config groups. Doing it like that will allow 
+					//       me to remove this call to ClearUnusedTypes() that the GC really 
+					//       shouldn't be calling.
+					if( engine->ClearUnusedTypes() == 0 )
+						break;
+				}
 			}
 			}
 
 
-			// Take the opportunity to clear unused types as well
-			engine->ClearUnusedTypes();
-
 			isProcessing = false;
 			isProcessing = false;
 			LEAVECRITICALSECTION(gcCollecting);
 			LEAVECRITICALSECTION(gcCollecting);
 			return 0;
 			return 0;
@@ -541,7 +571,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 
 
 				engine->CallObjectMethod(obj, it.type->beh.release);
 				engine->CallObjectMethod(obj, it.type->beh.release);
 
 
-				gcMap.Erase(cursor);
+				ReturnNode(gcMap.Remove(cursor));
 
 
 				return 1;
 				return 1;
 			}
 			}
@@ -580,7 +610,8 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				if( refCount > 1 )
 				if( refCount > 1 )
 				{
 				{
 					asSIntTypePair it = {refCount-1, gcObj.type};
 					asSIntTypePair it = {refCount-1, gcObj.type};
-					gcMap.Insert(gcObj.obj, it);
+
+					gcMap.Insert(GetNode(gcObj.obj, it));
 
 
 					// Increment the object's reference counter when putting it in the map
 					// Increment the object's reference counter when putting it in the map
 					engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
 					engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
@@ -695,7 +726,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				if( gcMap.MoveTo(&cursor, gcObj) )
 				if( gcMap.MoveTo(&cursor, gcObj) )
 				{
 				{
 					type = gcMap.GetValue(cursor).type;
 					type = gcMap.GetValue(cursor).type;
-					gcMap.Erase(cursor);
+					ReturnNode(gcMap.Remove(cursor));
 
 
 					// We need to decrease the reference count again as we remove the object from the map
 					// We need to decrease the reference count again as we remove the object from the map
 					engine->CallObjectMethod(gcObj, type->beh.release);
 					engine->CallObjectMethod(gcObj, type->beh.release);
@@ -800,6 +831,24 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 	UNREACHABLE_RETURN;
 	UNREACHABLE_RETURN;
 }
 }
 
 
+asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIntTypePair it)
+{
+	asSMapNode_t *node;
+	if( freeNodes.GetLength() )
+		node = freeNodes.PopLast();
+	else
+		node = asNEW(asSMapNode_t);
+
+	node->Init(obj, it);
+	return node;
+}
+
+void asCGarbageCollector::ReturnNode(asSMapNode_t *node)
+{
+	if( node )
+		freeNodes.PushLast(node);
+}
+
 void asCGarbageCollector::GCEnumCallback(void *reference)
 void asCGarbageCollector::GCEnumCallback(void *reference)
 {
 {
 	if( detectState == countReferences_loop )
 	if( detectState == countReferences_loop )

+ 9 - 1
ThirdParty/AngelScript/source/as_gc.h

@@ -54,11 +54,13 @@ class asCGarbageCollector
 {
 {
 public:
 public:
 	asCGarbageCollector();
 	asCGarbageCollector();
+	~asCGarbageCollector();
 
 
 	int  GarbageCollect(asDWORD flags);
 	int  GarbageCollect(asDWORD flags);
 	void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	void GCEnumCallback(void *reference);
 	void GCEnumCallback(void *reference);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
+	bool IsObjectInGC(void *obj);
 
 
 	int ReportAndReleaseUndestroyedObjects();
 	int ReportAndReleaseUndestroyedObjects();
 
 
@@ -67,6 +69,7 @@ public:
 protected:
 protected:
 	struct asSObjTypePair {void *obj; asCObjectType *type; int count;};
 	struct asSObjTypePair {void *obj; asCObjectType *type; int count;};
 	struct asSIntTypePair {int i; asCObjectType *type;};
 	struct asSIntTypePair {int i; asCObjectType *type;};
+	typedef asSMapNode<void*, asSIntTypePair> asSMapNode_t;
 
 
 	enum egcDestroyState
 	enum egcDestroyState
 	{
 	{
@@ -124,9 +127,14 @@ protected:
 	egcDetectState                     detectState;
 	egcDetectState                     detectState;
 	asUINT                             detectIdx;
 	asUINT                             detectIdx;
 	asUINT                             numDetected;
 	asUINT                             numDetected;
-	asSMapNode<void*, asSIntTypePair> *gcMapCursor;
+	asSMapNode_t                      *gcMapCursor;
 	bool                               isProcessing;
 	bool                               isProcessing;
 
 
+	// We'll keep a pool of nodes to avoid allocating memory all the time
+	asSMapNode_t            *GetNode(void *obj, asSIntTypePair it);
+	void                     ReturnNode(asSMapNode_t *node);
+	asCArray<asSMapNode_t*>  freeNodes;
+
 	// Critical section for multithreaded access
 	// Critical section for multithreaded access
 	DECLARECRITICALSECTION(gcCritical)   // Used for adding/removing objects
 	DECLARECRITICALSECTION(gcCritical)   // Used for adding/removing objects
 	DECLARECRITICALSECTION(gcCollecting) // Used for processing
 	DECLARECRITICALSECTION(gcCollecting) // Used for processing

+ 18 - 5
ThirdParty/AngelScript/source/as_globalproperty.cpp

@@ -143,6 +143,24 @@ void asCGlobalProperty::ReleaseAllHandles(asIScriptEngine *)
 	}
 	}
 }
 }
 
 
+void asCGlobalProperty::Orphan(asCModule *module)
+{
+	if( initFunc && initFunc->module == module )
+	{
+		// The owning module is releasing the property, so we need to notify 
+		// the GC in order to resolve any circular references that may exists
+
+		// This will add the property
+		initFunc->engine->gc.AddScriptObjectToGC(this, &initFunc->engine->globalPropertyBehaviours);
+
+		// This will add the function
+		initFunc->AddRef();
+		initFunc->Orphan(module);
+	}
+
+	Release();
+}
+
 void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
 void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
 {
 {
 	// This should only be done once
 	// This should only be done once
@@ -150,11 +168,6 @@ void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
 
 
 	this->initFunc = initFunc;
 	this->initFunc = initFunc;
 	this->initFunc->AddRef();
 	this->initFunc->AddRef();
-
-	// When there is an initialization function there is a chance that
-	// a circular reference is created, so it is necessary to notify the
-	// GC of this property.
-	initFunc->engine->gc.AddScriptObjectToGC(this, &initFunc->engine->globalPropertyBehaviours);
 }
 }
 
 
 asCScriptFunction *asCGlobalProperty::GetInitFunc()
 asCScriptFunction *asCGlobalProperty::GetInitFunc()

+ 22 - 4
ThirdParty/AngelScript/source/as_map.h

@@ -48,6 +48,7 @@ public:
 	~asCMap();
 	~asCMap();
 
 
 	int   Insert(const KEY &key, const VAL &value);
 	int   Insert(const KEY &key, const VAL &value);
+	int   Insert(asSMapNode<KEY,VAL> *node);
 	int   GetCount() const;
 	int   GetCount() const;
 	
 	
 	const KEY &GetKey(const asSMapNode<KEY,VAL> *cursor) const;
 	const KEY &GetKey(const asSMapNode<KEY,VAL> *cursor) const;
@@ -55,6 +56,7 @@ public:
 	VAL       &GetValue(asSMapNode<KEY,VAL> *cursor);
 	VAL       &GetValue(asSMapNode<KEY,VAL> *cursor);
 
 
 	void Erase(asSMapNode<KEY,VAL> *cursor);
 	void Erase(asSMapNode<KEY,VAL> *cursor);
+	asSMapNode<KEY,VAL> *Remove(asSMapNode<KEY,VAL> *cursor);
 	void EraseAll();
 	void EraseAll();
 
 
 	void SwapWith(asCMap<KEY,VAL> &other);
 	void SwapWith(asCMap<KEY,VAL> &other);
@@ -104,6 +106,7 @@ protected:
 template <class KEY, class VAL> struct asSMapNode
 template <class KEY, class VAL> struct asSMapNode
 {
 {
 	asSMapNode() {parent = 0; left = 0; right = 0; isRed = true;}
 	asSMapNode() {parent = 0; left = 0; right = 0; isRed = true;}
+	void Init(KEY k, VAL v) {key = k; value = v; parent = 0; left = 0; right = 0; isRed = true;}
 
 
 	asSMapNode *parent;
 	asSMapNode *parent;
 	asSMapNode *left;
 	asSMapNode *left;
@@ -183,6 +186,12 @@ int asCMap<KEY, VAL>::Insert(const KEY &key, const VAL &value)
 	nnode->key   = key;
 	nnode->key   = key;
 	nnode->value = value;
 	nnode->value = value;
 
 
+	return Insert(nnode);
+}
+
+template <class KEY, class VAL>
+int asCMap<KEY, VAL>::Insert(asSMapNode<KEY,VAL> *nnode)
+{
 	// Insert the node
 	// Insert the node
 	if( root == 0 )
 	if( root == 0 )
 		root = nnode;
 		root = nnode;
@@ -362,7 +371,17 @@ bool asCMap<KEY, VAL>::MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key) const
 template <class KEY, class VAL>
 template <class KEY, class VAL>
 void asCMap<KEY, VAL>::Erase(asSMapNode<KEY,VAL> *cursor)
 void asCMap<KEY, VAL>::Erase(asSMapNode<KEY,VAL> *cursor)
 {
 {
-	if( cursor == 0 ) return;
+	asSMapNode<KEY,VAL> *node = Remove(cursor);
+	asASSERT( node == cursor );
+
+	typedef asSMapNode<KEY,VAL> node_t;
+	asDELETE(node,node_t);
+}
+
+template <class KEY, class VAL>
+asSMapNode<KEY,VAL> *asCMap<KEY, VAL>::Remove(asSMapNode<KEY,VAL> *cursor)
+{
+	if( cursor == 0 ) return 0;
 
 
 	asSMapNode<KEY,VAL> *node = cursor;
 	asSMapNode<KEY,VAL> *node = cursor;
 
 
@@ -423,10 +442,9 @@ void asCMap<KEY, VAL>::Erase(asSMapNode<KEY,VAL> *cursor)
 		if( remove->right ) remove->right->parent = remove;	
 		if( remove->right ) remove->right->parent = remove;	
 	}
 	}
 
 
-	typedef asSMapNode<KEY,VAL> node_t;
-	asDELETE(node,node_t);
-
 	count--;
 	count--;
+
+	return node;
 }
 }
 
 
 // Call method only if removed node was black
 // Call method only if removed node was black

+ 4 - 0
ThirdParty/AngelScript/source/as_memory.cpp

@@ -38,6 +38,10 @@
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 
 
+#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ )
+#include <malloc.h>
+#endif
+
 #include "as_config.h"
 #include "as_config.h"
 #include "as_memory.h"
 #include "as_memory.h"
 #include "as_scriptnode.h"
 #include "as_scriptnode.h"

+ 76 - 45
ThirdParty/AngelScript/source/as_module.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -41,6 +41,7 @@
 #include "as_builder.h"
 #include "as_builder.h"
 #include "as_context.h"
 #include "as_context.h"
 #include "as_texts.h"
 #include "as_texts.h"
+#include "as_debug.h"
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
@@ -116,6 +117,12 @@ const char *asCModule::GetName() const
 	return name.AddressOf();
 	return name.AddressOf();
 }
 }
 
 
+// interface
+const char *asCModule::GetDefaultNamespace() const
+{
+	return defaultNamespace->name.AddressOf();
+}
+
 // interface
 // interface
 int asCModule::SetDefaultNamespace(const char *nameSpace)
 int asCModule::SetDefaultNamespace(const char *nameSpace)
 {
 {
@@ -187,6 +194,8 @@ int asCModule::Build()
 #ifdef AS_NO_COMPILER
 #ifdef AS_NO_COMPILER
 	return asNOT_SUPPORTED;
 	return asNOT_SUPPORTED;
 #else
 #else
+	TimeIt("asCModule::Build");
+
 	// Only one thread may build at one time
 	// Only one thread may build at one time
 	// TODO: It should be possible to have multiple threads perform compilations
 	// TODO: It should be possible to have multiple threads perform compilations
 	int r = engine->RequestBuild();
 	int r = engine->RequestBuild();
@@ -226,6 +235,17 @@ int asCModule::Build()
     JITCompile();
     JITCompile();
 
 
  	engine->PrepareEngine();
  	engine->PrepareEngine();
+
+#ifdef AS_DEBUG
+	// Verify that there are no unwanted gaps in the scriptFunctions array.
+	for( asUINT n = 1; n < engine->scriptFunctions.GetLength(); n++ )
+	{
+		int id = n;
+		if( engine->scriptFunctions[n] == 0 && !engine->freeScriptFunctionIds.Exists(id) )
+			asASSERT( false );
+	}
+#endif
+
 	engine->BuildCompleted();
 	engine->BuildCompleted();
 
 
 	// Initialize global variables
 	// Initialize global variables
@@ -306,8 +326,8 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 					asCScriptFunction *func = desc->GetInitFunc();
 					asCScriptFunction *func = desc->GetInitFunc();
 
 
 					engine->WriteMessage(func->scriptSectionIdx >= 0 ? engine->scriptSectionNames[func->scriptSectionIdx]->AddressOf() : "",
 					engine->WriteMessage(func->scriptSectionIdx >= 0 ? engine->scriptSectionNames[func->scriptSectionIdx]->AddressOf() : "",
-										 func->GetLineNumber(0) & 0xFFFFF, 
-										 func->GetLineNumber(0) >> 20,
+										 func->GetLineNumber(0, 0) & 0xFFFFF, 
+										 func->GetLineNumber(0, 0) >> 20,
 										 asMSGTYPE_ERROR,
 										 asMSGTYPE_ERROR,
 										 msg.AddressOf());
 										 msg.AddressOf());
 										 
 										 
@@ -400,21 +420,15 @@ void asCModule::InternalReset()
 
 
 	// First release all compiled functions
 	// First release all compiled functions
 	for( n = 0; n < scriptFunctions.GetLength(); n++ )
 	for( n = 0; n < scriptFunctions.GetLength(); n++ )
-	{
 		if( scriptFunctions[n] )
 		if( scriptFunctions[n] )
-		{
-			// Remove the module reference in the functions
-			scriptFunctions[n]->module = 0;
-			scriptFunctions[n]->Release();
-		}
-	}
+			scriptFunctions[n]->Orphan(this);
 	scriptFunctions.SetLength(0);
 	scriptFunctions.SetLength(0);
 
 
 	// Release the global properties declared in the module
 	// Release the global properties declared in the module
 	asCSymbolTableIterator<asCGlobalProperty> globIt = scriptGlobals.List();
 	asCSymbolTableIterator<asCGlobalProperty> globIt = scriptGlobals.List();
 	while( globIt )
 	while( globIt )
 	{
 	{
-		(*globIt)->Release();
+		(*globIt)->Orphan(this);
 		globIt++;
 		globIt++;
 	}
 	}
 	scriptGlobals.Clear();
 	scriptGlobals.Clear();
@@ -437,8 +451,9 @@ void asCModule::InternalReset()
 	bindInformations.SetLength(0);
 	bindInformations.SetLength(0);
 
 
 	// Free declared types, including classes, typedefs, and enums
 	// Free declared types, including classes, typedefs, and enums
+	// TODO: optimize: Check if it is possible to destroy the object directly without notifying the GC
 	for( n = 0; n < classTypes.GetLength(); n++ )
 	for( n = 0; n < classTypes.GetLength(); n++ )
-		classTypes[n]->Release();
+		classTypes[n]->Orphan(this);
 	classTypes.SetLength(0);
 	classTypes.SetLength(0);
 	for( n = 0; n < enumTypes.GetLength(); n++ )
 	for( n = 0; n < enumTypes.GetLength(); n++ )
 		enumTypes[n]->Release();
 		enumTypes[n]->Release();
@@ -675,7 +690,7 @@ int asCModule::RemoveGlobalVar(asUINT index)
 	asCGlobalProperty *prop = scriptGlobals.Get(index);
 	asCGlobalProperty *prop = scriptGlobals.Get(index);
 	if( !prop )
 	if( !prop )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
-	prop->Release();
+	prop->Orphan(this);
 	scriptGlobals.Erase(index);
 	scriptGlobals.Erase(index);
 
 
 	return 0;
 	return 0;
@@ -689,7 +704,9 @@ int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
 	asCString name;
 	asCString name;
 	asSNameSpace *nameSpace;
 	asSNameSpace *nameSpace;
 	asCDataType dt;
 	asCDataType dt;
-	bld.ParseVariableDeclaration(decl, defaultNamespace, name, nameSpace, dt);
+	int r = bld.ParseVariableDeclaration(decl, defaultNamespace, name, nameSpace, dt);
+	if( r < 0 )
+		return r;
 
 
 	// Search global variables for a match
 	// Search global variables for a match
 	int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
 	int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
@@ -851,7 +868,7 @@ const char *asCModule::GetTypedefByIndex(asUINT index, int *typeId, const char *
 		return 0;
 		return 0;
 
 
 	if( typeId )
 	if( typeId )
-		*typeId = engine->GetTypeIdFromDataType(typeDefs[index]->templateSubType); 
+		*typeId = engine->GetTypeIdFromDataType(typeDefs[index]->templateSubTypes[0]); 
 
 
 	if( nameSpace )
 	if( nameSpace )
 		*nameSpace = typeDefs[index]->nameSpace->name.AddressOf();
 		*nameSpace = typeDefs[index]->nameSpace->name.AddressOf();
@@ -870,8 +887,9 @@ int asCModule::GetNextImportedFunctionId()
 	return FUNC_IMPORTED | (asUINT)engine->importedFunctions.GetLength();
 	return FUNC_IMPORTED | (asUINT)engine->importedFunctions.GetLength();
 }
 }
 
 
+#ifndef AS_NO_COMPILER
 // internal
 // internal
-int asCModule::AddScriptFunction(int sectionIdx, int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, asCString **defaultArgs, int paramCount, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
+int asCModule::AddScriptFunction(int sectionIdx, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
 {
 {
 	asASSERT(id >= 0);
 	asASSERT(id >= 0);
 
 
@@ -883,26 +901,26 @@ int asCModule::AddScriptFunction(int sectionIdx, int id, const char *name, const
 	if( ns == 0 )
 	if( ns == 0 )
 		ns = engine->nameSpaces[0];
 		ns = engine->nameSpaces[0];
 
 
+	// All methods of shared objects are also shared
+	if( objType && objType->IsShared() )
+		isShared = true;
+
 	func->name             = name;
 	func->name             = name;
 	func->nameSpace        = ns;
 	func->nameSpace        = ns;
 	func->id               = id;
 	func->id               = id;
 	func->returnType       = returnType;
 	func->returnType       = returnType;
 	func->scriptSectionIdx = sectionIdx;
 	func->scriptSectionIdx = sectionIdx;
-	for( int n = 0; n < paramCount; n++ )
-	{
-		func->parameterTypes.PushLast(params[n]);
-		func->inOutFlags.PushLast(inOutFlags[n]);
-		func->defaultArgs.PushLast(defaultArgs[n]);
-	}
-	func->objectType = objType;
-	func->isReadOnly = isConstMethod;
-	func->isPrivate  = isPrivate;
-	func->isFinal    = isFinal;
-	func->isOverride = isOverride;
-	// All methods of shared objects are also shared
-	if( objType && objType->IsShared() )
-		isShared = true;
-	func->isShared   = isShared;
+	func->parameterTypes   = params;
+	func->inOutFlags       = inOutFlags;
+	func->defaultArgs      = defaultArgs;
+	func->objectType       = objType;
+	func->isReadOnly       = isConstMethod;
+	func->isPrivate        = isPrivate;
+	func->isFinal          = isFinal;
+	func->isOverride       = isOverride;
+	func->isShared         = isShared;
+
+	asASSERT( params.GetLength() == inOutFlags.GetLength() && params.GetLength() == defaultArgs.GetLength() );
 
 
 	// Verify that we are not assigning either the final or override specifier(s) if we are registering a non-member function
 	// Verify that we are not assigning either the final or override specifier(s) if we are registering a non-member function
 	asASSERT( !(!objType && isFinal) );
 	asASSERT( !(!objType && isFinal) );
@@ -937,7 +955,7 @@ int asCModule::AddScriptFunction(asCScriptFunction *func)
 }
 }
 
 
 // internal
 // internal
-int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, int paramCount, const asCString &moduleName)
+int asCModule::AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName)
 {
 {
 	asASSERT(id >= 0);
 	asASSERT(id >= 0);
 
 
@@ -946,23 +964,22 @@ int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &
 	if( func == 0 )
 	if( func == 0 )
 		return asOUT_OF_MEMORY;
 		return asOUT_OF_MEMORY;
 
 
-	func->name       = name;
-	func->id         = id;
-	func->returnType = returnType;
-	for( int n = 0; n < paramCount; n++ )
-	{
-		func->parameterTypes.PushLast(params[n]);
-		func->inOutFlags.PushLast(inOutFlags[n]);
-	}
-	func->objectType = 0;
+	func->name           = name;
+	func->id             = id;
+	func->returnType     = returnType;
+	func->nameSpace      = ns;
+	func->parameterTypes = params;
+	func->inOutFlags     = inOutFlags;
+	func->defaultArgs    = defaultArgs;
+	func->objectType     = 0;
 
 
 	sBindInfo *info = asNEW(sBindInfo);
 	sBindInfo *info = asNEW(sBindInfo);
 	if( info == 0 )
 	if( info == 0 )
 		return asOUT_OF_MEMORY;
 		return asOUT_OF_MEMORY;
 
 
 	info->importedFunctionSignature = func;
 	info->importedFunctionSignature = func;
-	info->boundFunctionId = -1;
-	info->importFromModule = moduleName;
+	info->boundFunctionId           = -1;
+	info->importFromModule          = moduleName;
 	bindInformations.PushLast(info);
 	bindInformations.PushLast(info);
 
 
 	// Add the info to the array in the engine
 	// Add the info to the array in the engine
@@ -973,6 +990,7 @@ int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &
 
 
 	return 0;
 	return 0;
 }
 }
+#endif
 
 
 // internal
 // internal
 asCScriptFunction *asCModule::GetImportedFunction(int index) const
 asCScriptFunction *asCModule::GetImportedFunction(int index) const
@@ -1155,6 +1173,7 @@ int asCModule::SaveByteCode(asIBinaryStream *out, bool stripDebugInfo) const
 {
 {
 #ifdef AS_NO_COMPILER
 #ifdef AS_NO_COMPILER
 	UNUSED_VAR(out);
 	UNUSED_VAR(out);
+	UNUSED_VAR(stripDebugInfo);
 	return asNOT_SUPPORTED;
 	return asNOT_SUPPORTED;
 #else
 #else
 	if( out == 0 ) return asINVALID_ARG;
 	if( out == 0 ) return asINVALID_ARG;
@@ -1180,6 +1199,16 @@ int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
 
 
     JITCompile();
     JITCompile();
 
 
+#ifdef AS_DEBUG
+	// Verify that there are no unwanted gaps in the scriptFunctions array.
+	for( asUINT n = 1; n < engine->scriptFunctions.GetLength(); n++ )
+	{
+		int id = n;
+		if( engine->scriptFunctions[n] == 0 && !engine->freeScriptFunctionIds.Exists(id) )
+			asASSERT( false );
+	}
+#endif
+
 	engine->BuildCompleted();
 	engine->BuildCompleted();
 
 
 	return r;
 	return r;
@@ -1331,15 +1360,16 @@ int asCModule::RemoveFunction(asIScriptFunction *func)
 		globalFunctions.Erase(idx);
 		globalFunctions.Erase(idx);
 		f->Release();
 		f->Release();
 		scriptFunctions.RemoveValue(f);
 		scriptFunctions.RemoveValue(f);
-		f->Release();
+		f->Orphan(this);
 		return 0;
 		return 0;
 	}
 	}
 
 
 	return asNO_FUNCTION;
 	return asNO_FUNCTION;
 }
 }
 
 
+#ifndef AS_NO_COMPILER
 // internal
 // internal
-int asCModule::AddFuncDef(const char *name, asSNameSpace *ns)
+int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
 {
 {
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
 	if( func == 0 )
 	if( func == 0 )
@@ -1356,6 +1386,7 @@ int asCModule::AddFuncDef(const char *name, asSNameSpace *ns)
 
 
 	return (int)funcDefs.GetLength()-1;
 	return (int)funcDefs.GetLength()-1;
 }
 }
+#endif
 
 
 // interface
 // interface
 asDWORD asCModule::SetAccessMask(asDWORD mask)
 asDWORD asCModule::SetAccessMask(asDWORD mask)

+ 16 - 16
ThirdParty/AngelScript/source/as_module.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -99,14 +99,16 @@ public:
 	virtual asIScriptEngine *GetEngine() const;
 	virtual asIScriptEngine *GetEngine() const;
 	virtual void             SetName(const char *name);
 	virtual void             SetName(const char *name);
 	virtual const char      *GetName() const;
 	virtual const char      *GetName() const;
+	// TODO: interface: Should have a method Discard(); which will replace the engine's DiscardModule() method
 
 
 	// Compilation
 	// Compilation
-	virtual int     AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset);
-	virtual int     Build();
-	virtual int     CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD reserved, asIScriptFunction **outFunc);
-	virtual int     CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
-	virtual asDWORD SetAccessMask(asDWORD accessMask);
-	virtual int     SetDefaultNamespace(const char *nameSpace);
+	virtual int         AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset);
+	virtual int         Build();
+	virtual int         CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD reserved, asIScriptFunction **outFunc);
+	virtual int         CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
+	virtual asDWORD     SetAccessMask(asDWORD accessMask);
+	virtual int         SetDefaultNamespace(const char *nameSpace);
+	virtual const char *GetDefaultNamespace() const;
 
 
 	// Script functions
 	// Script functions
 	virtual asUINT             GetFunctionCount() const;
 	virtual asUINT             GetFunctionCount() const;
@@ -190,20 +192,18 @@ public:
 
 
 	void JITCompile();
 	void JITCompile();
 
 
-	int  AddScriptFunction(int sectionIdx, int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, asCString **defaultArgs, int paramCount, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
+#ifndef AS_NO_COMPILER
+	int  AddScriptFunction(int sectionIdx, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
 	int  AddScriptFunction(asCScriptFunction *func);
 	int  AddScriptFunction(asCScriptFunction *func);
-	int  AddImportedFunction(int id, const char *name, const asCDataType &returnType, asCDataType *params, asETypeModifiers *inOutFlags, int paramCount, const asCString &moduleName);
-	int  AddFuncDef(const char *name, asSNameSpace *ns);
-
-	int  GetNextImportedFunctionId();
+	int  AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName);
+	int  AddFuncDef(const asCString &name, asSNameSpace *ns);
+#endif
 
 
+	int                GetNextImportedFunctionId();
 	asCScriptFunction *GetImportedFunction(int funcId) const;
 	asCScriptFunction *GetImportedFunction(int funcId) const;
-
-	asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
-
+	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns);
 	asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
 	asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
 
 
-
 	asCString name;
 	asCString name;
 
 
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;

+ 90 - 25
ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -124,6 +124,7 @@ void RegisterObjectTypeGCBehaviours(asCScriptEngine *engine)
 asCObjectType::asCObjectType() 
 asCObjectType::asCObjectType() 
 {
 {
 	engine = 0; 
 	engine = 0; 
+	module = 0;
 	refCount.set(0); 
 	refCount.set(0); 
 	derivedFrom = 0;
 	derivedFrom = 0;
 
 
@@ -137,6 +138,7 @@ asCObjectType::asCObjectType()
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
 {
 {
 	this->engine = engine; 
 	this->engine = engine; 
+	module = 0;
 	refCount.set(0); 
 	refCount.set(0); 
 	derivedFrom  = 0;
 	derivedFrom  = 0;
 
 
@@ -159,6 +161,26 @@ int asCObjectType::Release() const
 	return refCount.atomicDec();
 	return refCount.atomicDec();
 }
 }
 
 
+void asCObjectType::Orphan(asCModule *mod)
+{
+	if( mod && mod == module )
+	{
+		module = 0;
+		if( flags & asOBJ_SCRIPT_OBJECT )
+		{
+			// Tell the GC that this type exists so it can resolve potential circular references
+			engine->gc.AddScriptObjectToGC(this, &engine->objectTypeBehaviours);
+
+			// It's necessary to orphan the template instance types that refer to this object type,
+			// otherwise the garbage collector cannot identify the circular references that involve 
+			// the type and the template type
+			engine->OrphanTemplateInstances(this);
+		}
+	}
+
+	Release();
+}
+
 void *asCObjectType::SetUserData(void *data, asPWORD type)
 void *asCObjectType::SetUserData(void *data, asPWORD type)
 {
 {
 	// As a thread might add a new new user data at the same time as another
 	// As a thread might add a new new user data at the same time as another
@@ -226,28 +248,19 @@ void asCObjectType::SetGCFlag()
 
 
 asCObjectType::~asCObjectType()
 asCObjectType::~asCObjectType()
 {
 {
-	// Release the object type held by the templateSubType
-	if( templateSubType.GetObjectType() )
-		templateSubType.GetObjectType()->Release();
+	// Release the object types held by the templateSubTypes
+	for( asUINT subtypeIndex = 0; subtypeIndex < templateSubTypes.GetLength(); subtypeIndex++ )
+	{
+		if( templateSubTypes[subtypeIndex].GetObjectType() )
+			templateSubTypes[subtypeIndex].GetObjectType()->Release();
+	}
 
 
 	if( derivedFrom )
 	if( derivedFrom )
 		derivedFrom->Release();
 		derivedFrom->Release();
 
 
 	asUINT n;
 	asUINT n;
-	for( n = 0; n < properties.GetLength(); n++ )
-		if( properties[n] ) 
-		{
-			if( flags & asOBJ_SCRIPT_OBJECT )
-			{
-				// Release the config group for script classes that are being destroyed
-				asCConfigGroup *group = engine->FindConfigGroupForObjectType(properties[n]->type.GetObjectType());
-				if( group != 0 ) group->Release();
-			}
 
 
-			asDELETE(properties[n],asCObjectProperty);
-		}
-
-	properties.SetLength(0);
+	ReleaseAllProperties();
 
 
 	ReleaseAllFunctions();
 	ReleaseAllFunctions();
 
 
@@ -346,13 +359,14 @@ int asCObjectType::GetTypeId() const
 }
 }
 
 
 // interface
 // interface
-int asCObjectType::GetSubTypeId() const
+int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
 {
 {
-	// TODO: template: This method should allow indexing multiple template subtypes
-
 	if( flags & asOBJ_TEMPLATE )
 	if( flags & asOBJ_TEMPLATE )
 	{
 	{
-		return engine->GetTypeIdFromDataType(templateSubType);
+		if( subtypeIndex >= templateSubTypes.GetLength() )
+			return asINVALID_ARG;
+
+		return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
 	}
 	}
 
 
 	// Only template types have sub types
 	// Only template types have sub types
@@ -360,20 +374,27 @@ int asCObjectType::GetSubTypeId() const
 }
 }
 
 
 // interface
 // interface
-asIObjectType *asCObjectType::GetSubType() const
+asIObjectType *asCObjectType::GetSubType(asUINT subtypeIndex) const
 {
 {
-	// TODO: template: This method should allow indexing multiple template subtypes
 	if( flags & asOBJ_TEMPLATE )
 	if( flags & asOBJ_TEMPLATE )
 	{
 	{
-		return templateSubType.GetObjectType();
+		if( subtypeIndex >= templateSubTypes.GetLength() )
+			return 0;
+
+		return templateSubTypes[subtypeIndex].GetObjectType();
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+asUINT asCObjectType::GetSubTypeCount() const
+{
+	return asUINT(templateSubTypes.GetLength());
+}
+
 asUINT asCObjectType::GetInterfaceCount() const
 asUINT asCObjectType::GetInterfaceCount() const
 {
 {
-	return (asUINT)interfaces.GetLength();
+	return asUINT(interfaces.GetLength());
 }
 }
 
 
 asIObjectType *asCObjectType::GetInterface(asUINT index) const
 asIObjectType *asCObjectType::GetInterface(asUINT index) const
@@ -777,6 +798,7 @@ asDWORD asCObjectType::GetAccessMask() const
 // internal
 // internal
 asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
 asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
 {
 {
+	asASSERT( flags & asOBJ_SCRIPT_OBJECT );
 	asASSERT( dt.CanBeInstanciated() );
 	asASSERT( dt.CanBeInstanciated() );
 	asASSERT( !IsInterface() );
 	asASSERT( !IsInterface() );
 
 
@@ -815,13 +837,45 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
 	asCConfigGroup *group = engine->FindConfigGroupForObjectType(prop->type.GetObjectType());
 	asCConfigGroup *group = engine->FindConfigGroupForObjectType(prop->type.GetObjectType());
 	if( group != 0 ) group->AddRef();
 	if( group != 0 ) group->AddRef();
 
 
+	// Add reference to object types
+	asCObjectType *type = prop->type.GetObjectType();
+	if( type )
+		type->AddRef();
+
 	return prop;
 	return prop;
 }
 }
 
 
+// internal
+void asCObjectType::ReleaseAllProperties()
+{
+	for( asUINT n = 0; n < properties.GetLength(); n++ )
+	{
+		if( properties[n] ) 
+		{
+			if( flags & asOBJ_SCRIPT_OBJECT )
+			{
+				// Release the config group for script classes that are being destroyed
+				asCConfigGroup *group = engine->FindConfigGroupForObjectType(properties[n]->type.GetObjectType());
+				if( group != 0 ) group->Release();
+
+				// Release references to objects types
+				asCObjectType *type = properties[n]->type.GetObjectType();
+				if( type )
+					type->Release();
+			}
+
+			asDELETE(properties[n],asCObjectProperty);
+		}
+	}
+
+	properties.SetLength(0);
+}
+
 // internal
 // internal
 void asCObjectType::ReleaseAllHandles(asIScriptEngine *)
 void asCObjectType::ReleaseAllHandles(asIScriptEngine *)
 {
 {
 	ReleaseAllFunctions();
 	ReleaseAllFunctions();
+	ReleaseAllProperties();
 }
 }
 
 
 // internal
 // internal
@@ -967,6 +1021,17 @@ void asCObjectType::EnumReferences(asIScriptEngine *)
 	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
 	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
 		if( virtualFunctionTable[d] )
 		if( virtualFunctionTable[d] )
 			engine->GCEnumCallback(virtualFunctionTable[d]);
 			engine->GCEnumCallback(virtualFunctionTable[d]);
+
+	for( asUINT p = 0; p < properties.GetLength(); p++ )
+	{
+		asCObjectType *type = properties[p]->type.GetObjectType();
+		if( type )
+			engine->GCEnumCallback(type);
+	}
+
+	for( asUINT t = 0; t < templateSubTypes.GetLength(); t++ )
+		if( templateSubTypes[t].GetObjectType() )
+			engine->GCEnumCallback(templateSubTypes[t].GetObjectType());
 }
 }
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 10 - 6
ThirdParty/AngelScript/source/as_objecttype.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -150,8 +150,9 @@ public:
 	asDWORD          GetFlags() const;
 	asDWORD          GetFlags() const;
 	asUINT           GetSize() const;
 	asUINT           GetSize() const;
 	int              GetTypeId() const;
 	int              GetTypeId() const;
-	int              GetSubTypeId() const;
-	asIObjectType   *GetSubType() const;
+	int              GetSubTypeId(asUINT subtypeIndex = 0) const;
+	asIObjectType   *GetSubType(asUINT subtypeIndex = 0) const;
+	asUINT			 GetSubTypeCount() const;
 
 
 	// Interfaces
 	// Interfaces
 	asUINT           GetInterfaceCount() const;
 	asUINT           GetInterfaceCount() const;
@@ -200,6 +201,7 @@ public:
 	asCObjectType(asCScriptEngine *engine);
 	asCObjectType(asCScriptEngine *engine);
 	~asCObjectType();
 	~asCObjectType();
 
 
+	void Orphan(asCModule *module);
 	int  GetRefCount();
 	int  GetRefCount();
 	void SetGCFlag();
 	void SetGCFlag();
 	bool GetGCFlag();
 	bool GetGCFlag();
@@ -212,6 +214,7 @@ public:
 	bool IsShared() const;
 	bool IsShared() const;
 
 
 	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
 	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
+	void ReleaseAllProperties();
 
 
 	asCString                    name;
 	asCString                    name;
 	asSNameSpace                *nameSpace;
 	asSNameSpace                *nameSpace;
@@ -229,11 +232,12 @@ public:
 	asSTypeBehaviour beh;
 	asSTypeBehaviour beh;
 
 
 	// Used for template types
 	// Used for template types
-	asCDataType    templateSubType;
-	bool           acceptValueSubType;
-	bool           acceptRefSubType;
+	asCArray<asCDataType> templateSubTypes;
+	bool                  acceptValueSubType;
+	bool                  acceptRefSubType;
 
 
 	asCScriptEngine  *engine;
 	asCScriptEngine  *engine;
+	asCModule        *module;
 	asCArray<asPWORD> userData;
 	asCArray<asPWORD> userData;
 
 
 protected:
 protected:

File diff suppressed because it is too large
+ 248 - 200
ThirdParty/AngelScript/source/as_parser.cpp


+ 5 - 6
ThirdParty/AngelScript/source/as_parser.h

@@ -63,7 +63,7 @@ public:
 
 
 	// Called from compiler
 	// Called from compiler
 	int ParseStatementBlock(asCScriptCode *script, asCScriptNode *block);
 	int ParseStatementBlock(asCScriptCode *script, asCScriptNode *block);
-	int ParseGlobalVarInit(asCScriptCode *script, asCScriptNode *init);
+	int ParseVarInit(asCScriptCode *script, asCScriptNode *init);
 	int ParseExpression(asCScriptCode *script);
 	int ParseExpression(asCScriptCode *script);
 #endif
 #endif
 	
 	
@@ -75,8 +75,8 @@ protected:
 	void GetToken(sToken *token);
 	void GetToken(sToken *token);
 	void RewindTo(const sToken *token);
 	void RewindTo(const sToken *token);
 	void SetPos(size_t pos);
 	void SetPos(size_t pos);
-	void Error(const char *text, sToken *token);
-	void Info(const char *text, sToken *token);
+	void Error(const asCString &text, sToken *token);
+	void Info(const asCString &text, sToken *token);
 
 
 	asCScriptNode *CreateNode(eScriptNode type);
 	asCScriptNode *CreateNode(eScriptNode type);
 
 
@@ -96,7 +96,7 @@ protected:
 #ifndef AS_NO_COMPILER
 #ifndef AS_NO_COMPILER
 	// Statements
 	// Statements
 	asCScriptNode *SuperficiallyParseStatementBlock();
 	asCScriptNode *SuperficiallyParseStatementBlock();
-	asCScriptNode *SuperficiallyParseGlobalVarInit();
+	asCScriptNode *SuperficiallyParseVarInit();
 	asCScriptNode *ParseStatementBlock();
 	asCScriptNode *ParseStatementBlock();
 	asCScriptNode *ParseStatement();
 	asCScriptNode *ParseStatement();
 	asCScriptNode *ParseExpressionStatement();
 	asCScriptNode *ParseExpressionStatement();
@@ -111,13 +111,12 @@ protected:
 	asCScriptNode *ParseContinue();
 	asCScriptNode *ParseContinue();
 
 
 	// Declarations
 	// Declarations
-	asCScriptNode *ParseDeclaration();
+	asCScriptNode *ParseDeclaration(bool isClassProp = false, bool isGlobalVar = false);
 	asCScriptNode *ParseImport();
 	asCScriptNode *ParseImport();
 	asCScriptNode *ParseScript(bool inBlock);
 	asCScriptNode *ParseScript(bool inBlock);
 	asCScriptNode *ParseNamespace();
 	asCScriptNode *ParseNamespace();
 	asCScriptNode *ParseFunction(bool isMethod = false);
 	asCScriptNode *ParseFunction(bool isMethod = false);
 	asCScriptNode *ParseFuncDef();
 	asCScriptNode *ParseFuncDef();
-	asCScriptNode *ParseGlobalVar();
 	asCScriptNode *ParseClass();
 	asCScriptNode *ParseClass();
 	asCScriptNode *ParseMixin();
 	asCScriptNode *ParseMixin();
 	asCScriptNode *ParseInitList();
 	asCScriptNode *ParseInitList();

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

@@ -92,6 +92,8 @@ public:
 	void EnumReferences(asIScriptEngine *);
 	void EnumReferences(asIScriptEngine *);
 	void ReleaseAllHandles(asIScriptEngine *);
 	void ReleaseAllHandles(asIScriptEngine *);
 
 
+	void Orphan(asCModule *module);
+
 	// This is only stored for registered properties, and keeps the pointer given by the application
 	// This is only stored for registered properties, and keeps the pointer given by the application
 	void       *realAddress;
 	void       *realAddress;
 
 

+ 313 - 121
ThirdParty/AngelScript/source/as_restore.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -127,7 +127,32 @@ int asCReader::ReadInner()
 			return asOUT_OF_MEMORY;
 			return asOUT_OF_MEMORY;
 
 
 		ReadObjectTypeDeclaration(ot, 1);
 		ReadObjectTypeDeclaration(ot, 1);
-		engine->classTypes.PushLast(ot);
+
+		// If the type is shared then we should use the original if it exists
+		bool sharedExists = false;
+		if( ot->IsShared() )
+		{
+			for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+			{
+				asCObjectType *t = engine->classTypes[n];
+				if( t && 
+					t->IsShared() &&
+					t->name == ot->name &&
+					t->nameSpace == ot->nameSpace &&
+					(t->flags & asOBJ_ENUM) )
+				{
+					asDELETE(ot, asCObjectType);
+					ot = t;
+					sharedExists = true;
+					break;
+				}
+			}
+		}
+
+		if( sharedExists )
+			existingShared.Insert(ot, true);
+		else
+			engine->classTypes.PushLast(ot);
 		module->enumTypes.PushLast(ot);
 		module->enumTypes.PushLast(ot);
 		ot->AddRef();
 		ot->AddRef();
 		ReadObjectTypeDeclaration(ot, 2);
 		ReadObjectTypeDeclaration(ot, 2);
@@ -157,6 +182,7 @@ int asCReader::ReadInner()
 				if( t &&
 				if( t &&
 					t->IsShared() &&
 					t->IsShared() &&
 					t->name == ot->name &&
 					t->name == ot->name &&
+					t->nameSpace == ot->nameSpace &&
 					t->IsInterface() == ot->IsInterface() )
 					t->IsInterface() == ot->IsInterface() )
 				{
 				{
 					asDELETE(ot, asCObjectType);
 					asDELETE(ot, asCObjectType);
@@ -173,9 +199,8 @@ int asCReader::ReadInner()
 		{
 		{
 			engine->classTypes.PushLast(ot);
 			engine->classTypes.PushLast(ot);
 
 
-			// Add script classes to the GC
-			if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && !ot->IsInterface() )
-				engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
+			// Set this module as the owner
+			ot->module = module;
 		}
 		}
 		module->classTypes.PushLast(ot);
 		module->classTypes.PushLast(ot);
 		ot->AddRef();
 		ot->AddRef();
@@ -188,7 +213,8 @@ int asCReader::ReadInner()
 	module->funcDefs.Allocate(count, 0);
 	module->funcDefs.Allocate(count, 0);
 	for( i = 0; i < count && !error; i++ )
 	for( i = 0; i < count && !error; i++ )
 	{
 	{
-		asCScriptFunction *func = ReadFunction(false, true);
+		bool isNew;
+		asCScriptFunction *func = ReadFunction(isNew, false, true);
 		if( func )
 		if( func )
 			module->funcDefs.PushLast(func);
 			module->funcDefs.PushLast(func);
 		else
 		else
@@ -238,7 +264,7 @@ int asCReader::ReadInner()
 
 
 	// scriptGlobals[]
 	// scriptGlobals[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
-	if( engine->ep.disallowGlobalVars )
+	if( count && engine->ep.disallowGlobalVars )
 	{
 	{
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
 		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
 		error = true;
 		error = true;
@@ -254,7 +280,8 @@ int asCReader::ReadInner()
 	for( i = 0; i < count && !error; ++i ) 
 	for( i = 0; i < count && !error; ++i ) 
 	{
 	{
 		size_t len = module->scriptFunctions.GetLength();
 		size_t len = module->scriptFunctions.GetLength();
-		func = ReadFunction();
+		bool isNew;
+		func = ReadFunction(isNew);
 		if( func == 0 )
 		if( func == 0 )
 		{
 		{
 			error = true;
 			error = true;
@@ -287,6 +314,7 @@ int asCReader::ReadInner()
 					func->id = 0;
 					func->id = 0;
 					func->byteCode.SetLength(0);
 					func->byteCode.SetLength(0);
 					func->Release();
 					func->Release();
+					break;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -296,7 +324,8 @@ int asCReader::ReadInner()
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
 	for( i = 0; i < count && !error; ++i )
 	for( i = 0; i < count && !error; ++i )
 	{
 	{
-		func = ReadFunction(false, false);
+		bool isNew;
+		func = ReadFunction(isNew, false, false);
 		if( func )
 		if( func )
 		{
 		{
 			module->globalFunctions.Put(func);
 			module->globalFunctions.Put(func);
@@ -317,7 +346,8 @@ int asCReader::ReadInner()
 		if( info == 0 )
 		if( info == 0 )
 			return asOUT_OF_MEMORY;
 			return asOUT_OF_MEMORY;
 
 
-		info->importedFunctionSignature = ReadFunction(false, false);
+		bool isNew;
+		info->importedFunctionSignature = ReadFunction(isNew, false, false);
 		if( info->importedFunctionSignature == 0 )
 		if( info->importedFunctionSignature == 0 )
 		{
 		{
 			error = true;
 			error = true;
@@ -372,18 +402,26 @@ int asCReader::ReadInner()
 		ReadUsedObjectProps();
 		ReadUsedObjectProps();
 
 
 	// Validate the template types
 	// Validate the template types
-	for( i = 0; i < usedTypes.GetLength() && !error; i++ )
+	if( !error )
 	{
 	{
-		if( (usedTypes[i]->flags & asOBJ_TEMPLATE) && 
-			usedTypes[i]->templateSubType.IsValid() &&
-			usedTypes[i]->beh.templateCallback )
+		for( i = 0; i < usedTypes.GetLength() && !error; i++ )
 		{
 		{
+			if( !(usedTypes[i]->flags & asOBJ_TEMPLATE) || 
+				!usedTypes[i]->beh.templateCallback )
+				continue;
+			
 			bool dontGarbageCollect = false;
 			bool dontGarbageCollect = false;
 			asCScriptFunction *callback = engine->scriptFunctions[usedTypes[i]->beh.templateCallback];
 			asCScriptFunction *callback = engine->scriptFunctions[usedTypes[i]->beh.templateCallback];
 			if( !engine->CallGlobalFunctionRetBool(usedTypes[i], &dontGarbageCollect, callback->sysFuncIntf, callback) )
 			if( !engine->CallGlobalFunctionRetBool(usedTypes[i], &dontGarbageCollect, callback->sysFuncIntf, callback) )
 			{
 			{
+				asCString sub = usedTypes[i]->templateSubTypes[0].Format();
+				for( asUINT n = 1; n < usedTypes[i]->templateSubTypes.GetLength(); n++ )
+				{
+					sub += ",";
+					sub += usedTypes[i]->templateSubTypes[n].Format();
+				}
 				asCString str;
 				asCString str;
-				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), usedTypes[i]->templateSubType.Format().AddressOf());
+				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), sub.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				error = true;
 				error = true;
 			}
 			}
@@ -568,8 +606,9 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	}
 	}
 }
 }
 
 
-asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, bool addToGC) 
+asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool addToEngine, bool addToGC) 
 {
 {
+	isNew = false;
 	if( error ) return 0;
 	if( error ) return 0;
 
 
 	char c;
 	char c;
@@ -595,6 +634,7 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 	}
 	}
 
 
 	// Load the new function
 	// Load the new function
+	isNew = true;
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
 	asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
 	if( func == 0 )
 	if( func == 0 )
 	{
 	{
@@ -610,11 +650,9 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 
 
 	ReadFunctionSignature(func);
 	ReadFunctionSignature(func);
 
 
-	func->id = engine->GetNextScriptFunctionId();
-
 	if( func->funcType == asFUNC_SCRIPT )
 	if( func->funcType == asFUNC_SCRIPT )
 	{
 	{
-		if( addToGC )
+		if( addToGC && !addToModule )
 			engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
 			engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
 		
 		
 		ReadByteCode(func);
 		ReadByteCode(func);
@@ -653,6 +691,12 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 			func->lineNumbers.SetLength(length);
 			func->lineNumbers.SetLength(length);
 			for( i = 0; i < length; ++i )
 			for( i = 0; i < length; ++i )
 				func->lineNumbers[i] = ReadEncodedUInt();
 				func->lineNumbers[i] = ReadEncodedUInt();
+
+			// Read the array of script sections 
+			length = ReadEncodedUInt();
+			func->sectionIdxs.SetLength(length);
+			for( i = 0; i < length; ++i )
+				func->sectionIdxs[i] = ReadEncodedUInt();
 		}
 		}
 
 
 		ReadData(&func->isShared, 1);
 		ReadData(&func->isShared, 1);
@@ -679,6 +723,8 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 				ReadDataType(&var->type);
 				ReadDataType(&var->type);
 			}
 			}
 		}
 		}
+
+		ReadData(&func->dontCleanUpOnException, 1);
 	}
 	}
 	else if( func->funcType == asFUNC_VIRTUAL )
 	else if( func->funcType == asFUNC_VIRTUAL )
 	{
 	{
@@ -699,7 +745,10 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
 		module->scriptFunctions.PushLast(func);
 		module->scriptFunctions.PushLast(func);
 	}
 	}
 	if( addToEngine )
 	if( addToEngine )
+	{
+		func->id = engine->GetNextScriptFunctionId();
 		engine->SetScriptFunction(func);
 		engine->SetScriptFunction(func);
+	}
 	if( func->objectType )
 	if( func->objectType )
 		func->ComputeSignatureId();
 		func->ComputeSignatureId();
 
 
@@ -744,25 +793,57 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 		if( ot->flags & asOBJ_ENUM )
 		if( ot->flags & asOBJ_ENUM )
 		{
 		{
 			int count = ReadEncodedUInt();
 			int count = ReadEncodedUInt();
-			ot->enumValues.Allocate(count, 0);
-			for( int n = 0; n < count; n++ )
+			bool sharedExists = existingShared.MoveTo(0, ot);
+			if( !sharedExists )
 			{
 			{
-				asSEnumValue *e = asNEW(asSEnumValue);
-				if( e == 0 )
+				ot->enumValues.Allocate(count, 0);
+				for( int n = 0; n < count; n++ )
 				{
 				{
-					// Out of memory
-					error = true;
-					return;
+					asSEnumValue *e = asNEW(asSEnumValue);
+					if( e == 0 )
+					{
+						// Out of memory
+						error = true;
+						return;
+					}
+					ReadString(&e->name);
+					ReadData(&e->value, 4); // TODO: Should be encoded
+					ot->enumValues.PushLast(e);
+				}
+			}
+			else
+			{
+				// Verify that the enum values exists in the original
+				asCString name;
+				int value;
+				for( int n = 0; n < count; n++ )
+				{
+					ReadString(&name);
+					ReadData(&value, 4); // TODO: Should be encoded
+					bool found = false;
+					for( asUINT e = 0; e < ot->enumValues.GetLength(); e++ )
+					{
+						if( ot->enumValues[e]->name == name &&
+							ot->enumValues[e]->value == value )
+						{
+							found = true;
+							break;
+						}
+					}
+					if( !found )
+					{
+						asCString str;
+						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+						error = true;
+					}
 				}
 				}
-				ReadString(&e->name);
-				ReadData(&e->value, 4);
-				ot->enumValues.PushLast(e);
 			}
 			}
 		}
 		}
 		else if( ot->flags & asOBJ_TYPEDEF )
 		else if( ot->flags & asOBJ_TYPEDEF )
 		{
 		{
 			eTokenType t = (eTokenType)ReadEncodedUInt();
 			eTokenType t = (eTokenType)ReadEncodedUInt();
-			ot->templateSubType = asCDataType::CreatePrimitive(t, false);
+			ot->templateSubTypes.PushLast(asCDataType::CreatePrimitive(t, false));
 		}
 		}
 		else
 		else
 		{
 		{
@@ -774,7 +855,9 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 				asCObjectType *dt = ReadObjectType();
 				asCObjectType *dt = ReadObjectType();
 				if( ot->derivedFrom != dt )
 				if( ot->derivedFrom != dt )
 				{
 				{
-					// TODO: Write message
+					asCString str;
+					str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+					engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 					error = true;
 					error = true;
 				}
 				}
 			}
 			}
@@ -794,7 +877,9 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					asCObjectType *intf = ReadObjectType();
 					asCObjectType *intf = ReadObjectType();
 					if( !ot->Implements(intf) )
 					if( !ot->Implements(intf) )
 					{
 					{
-						// TODO: Write message
+						asCString str;
+						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 						error = true;
 						error = true;
 					}
 					}
 				}
 				}
@@ -812,7 +897,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			// behaviours
 			// behaviours
 			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
 			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
 			{
 			{
-				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
+				bool isNew;
+				asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
 				if( sharedExists )
 				if( sharedExists )
 				{
 				{
 					// Find the real function in the object, and update the savedFunctions array
 					// Find the real function in the object, and update the savedFunctions array
@@ -825,15 +911,20 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					}
 					}
 					else
 					else
 					{
 					{
-						// TODO: Write message
+						asCString str;
+						str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+						engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 						error = true;
 						error = true;
 					}
 					}
-					// Destroy the function without releasing any references
 					if( func )
 					if( func )
 					{
 					{
-						func->id = 0;
-						func->byteCode.SetLength(0);
-						func->Release();
+						if( isNew )
+						{
+							// Destroy the function without releasing any references
+							func->id = 0;
+							func->byteCode.SetLength(0);
+							func->Release();
+						}
 						module->scriptFunctions.PushLast(realFunc);
 						module->scriptFunctions.PushLast(realFunc);
 						realFunc->AddRef();
 						realFunc->AddRef();
 						dontTranslate.Insert(realFunc, true);
 						dontTranslate.Insert(realFunc, true);
@@ -853,7 +944,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 				size = ReadEncodedUInt();
 				size = ReadEncodedUInt();
 				for( int n = 0; n < size; n++ )
 				for( int n = 0; n < size; n++ )
 				{
 				{
-					asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
+					bool isNew;
+					asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
 					if( func )
 					if( func )
 					{
 					{
 						if( sharedExists )
 						if( sharedExists )
@@ -877,13 +969,18 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							}
 							}
 							if( !found )
 							if( !found )
 							{
 							{
-								// TODO: Write message
+								asCString str;
+								str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+								engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 								error = true;
 								error = true;
 							}
 							}
-							// Destroy the function without releasing any references
-							func->id = 0;
-							func->byteCode.SetLength(0);
-							func->Release();
+							if( isNew )
+							{
+								// Destroy the function without releasing any references
+								func->id = 0;
+								func->byteCode.SetLength(0);
+								func->Release();
+							}
 						}
 						}
 						else
 						else
 						{
 						{
@@ -900,7 +997,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 						error = true;
 						error = true;
 					}
 					}
 
 
-					func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
+					func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
 					if( func )
 					if( func )
 					{
 					{
 						if( sharedExists )
 						if( sharedExists )
@@ -924,13 +1021,18 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							}
 							}
 							if( !found )
 							if( !found )
 							{
 							{
-								// TODO: Write message
+								asCString str;
+								str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+								engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 								error = true;
 								error = true;
 							}
 							}
-							// Destroy the function without releasing any references
-							func->id = 0;
-							func->byteCode.SetLength(0);
-							func->Release();
+							if( isNew )
+							{
+								// Destroy the function without releasing any references
+								func->id = 0;
+								func->byteCode.SetLength(0);
+								func->Release();
+							}
 						}
 						}
 						else
 						else
 						{
 						{
@@ -954,7 +1056,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			int n;
 			int n;
 			for( n = 0; n < size; n++ ) 
 			for( n = 0; n < size; n++ ) 
 			{
 			{
-				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
+				bool isNew;
+				asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
 					if( sharedExists )
 					if( sharedExists )
@@ -978,12 +1081,12 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 						}
 						}
 						if( !found )
 						if( !found )
 						{
 						{
-							// TODO: Write message
+							asCString str;
+							str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+							engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 							error = true;
 							error = true;
 						}
 						}
-						// If the function received wasn't an already existing 
-						// function we must now destroy it
-						if( !savedFunctions.Exists(func) )
+						if( isNew )
 						{
 						{
 							// Destroy the function without releasing any references
 							// Destroy the function without releasing any references
 							func->id = 0;
 							func->id = 0;
@@ -993,6 +1096,16 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					}
 					}
 					else
 					else
 					{
 					{
+						// If the method is the assignment operator we need to replace the default implementation
+						if( func->name == "opAssign" && func->parameterTypes.GetLength() == 1 &&
+							func->parameterTypes[0].GetObjectType() == func->objectType &&
+							(func->inOutFlags[0] & asTM_INREF) )
+						{
+							engine->scriptFunctions[ot->beh.copy]->Release();
+							ot->beh.copy = func->id;
+							func->AddRef();
+						}
+						
 						ot->methods.PushLast(func->id);
 						ot->methods.PushLast(func->id);
 						func->AddRef();
 						func->AddRef();
 					}
 					}
@@ -1008,7 +1121,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			size = ReadEncodedUInt();
 			size = ReadEncodedUInt();
 			for( n = 0; n < size; n++ )
 			for( n = 0; n < size; n++ )
 			{
 			{
-				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
+				bool isNew;
+				asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
 					if( sharedExists )
 					if( sharedExists )
@@ -1032,12 +1146,12 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 						}
 						}
 						if( !found )
 						if( !found )
 						{
 						{
-							// TODO: Write message
+							asCString str;
+							str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
+							engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 							error = true;
 							error = true;
 						}
 						}
-						// If the function received wasn't an already existing 
-						// function we must now destroy it
-						if( !savedFunctions.Exists(func) )
+						if( isNew )
 						{
 						{
 							// Destroy the function without releasing any references
 							// Destroy the function without releasing any references
 							func->id = 0;
 							func->id = 0;
@@ -1212,7 +1326,10 @@ void asCReader::ReadGlobalProperty()
 	ReadData(&f, 1);
 	ReadData(&f, 1);
 	if( f )
 	if( f )
 	{
 	{
-		asCScriptFunction *func = ReadFunction(false, true);
+		bool isNew;
+		// Do not add the function to the GC at this time. It will 
+		// only be added to the GC when the module releases the property
+		asCScriptFunction *func = ReadFunction(isNew, false, true, false);
 		if( func )
 		if( func )
 		{
 		{
 			prop->SetInitFunc(func);
 			prop->SetInitFunc(func);
@@ -1313,7 +1430,10 @@ void asCReader::ReadDataType(asCDataType *dt)
 	if( isObjectHandle )
 	if( isObjectHandle )
 	{
 	{
 		dt->MakeReadOnly(isHandleToConst);
 		dt->MakeReadOnly(isHandleToConst);
-		dt->MakeHandle(true);
+		
+		// Here we must allow a scoped type to be a handle 
+		// e.g. if the datatype is for a system function
+		dt->MakeHandle(true, true);
 	}
 	}
 	dt->MakeReadOnly(isReadOnly);
 	dt->MakeReadOnly(isReadOnly);
 	dt->MakeReference(isReference);
 	dt->MakeReference(isReference);
@@ -1342,41 +1462,48 @@ asCObjectType* asCReader::ReadObjectType()
 			return 0;
 			return 0;
 		}
 		}
 
 
-		ReadData(&ch, 1);
-		if( ch == 's' )
+		asUINT numSubTypes = ReadEncodedUInt();
+		asCArray<asCDataType> subTypes;
+		for( asUINT n = 0; n < numSubTypes; n++ )
 		{
 		{
-			asCDataType dt;
-			ReadDataType(&dt);
-
-			if( tmpl->templateSubType.GetObjectType() == dt.GetObjectType() )
-				ot = tmpl;
+			ReadData(&ch, 1);
+			if( ch == 's' )
+			{
+				asCDataType dt;
+				ReadDataType(&dt);
+				subTypes.PushLast(dt);
+			}
 			else
 			else
-				ot = engine->GetTemplateInstanceType(tmpl, dt);
-			
-			if( ot == 0 )
 			{
 			{
-				asCString str;
-				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
-				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				error = true;
-				return 0;
+				eTokenType tokenType = (eTokenType)ReadEncodedUInt();
+				asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
+				subTypes.PushLast(dt);
 			}
 			}
 		}
 		}
+
+		// Return the actual template if the subtypes are the template's dummy types
+		if( tmpl->templateSubTypes == subTypes )
+			ot = tmpl;
 		else
 		else
 		{
 		{
-			eTokenType tokenType = (eTokenType)ReadEncodedUInt();
-			asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
+			// Get the template instance type based on the loaded subtypes
+			ot = engine->GetTemplateInstanceType(tmpl, subTypes);
+		}
 
 
-			ot = engine->GetTemplateInstanceType(tmpl, dt);
-			
-			if( ot == 0 )
+		if( ot == 0 )
+		{
+			// Show all subtypes in error message
+			asCString sub = subTypes[0].Format();
+			for( asUINT n = 1; n < subTypes.GetLength(); n++ )
 			{
 			{
-				asCString str;
-				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
-				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
-				error = true;
-				return 0;
+				sub += ",";
+				sub += subTypes[n].Format();
 			}
 			}
+			asCString str;
+			str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), sub.AddressOf());
+			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+			error = true;
+			return 0;
 		}
 		}
 	}
 	}
 	else if( ch == 's' )
 	else if( ch == 's' )
@@ -1468,7 +1595,7 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
 
 
 		// Allocate the space for the instruction
 		// Allocate the space for the instruction
 		asUINT len = asBCTypeSize[asBCInfo[b].type];
 		asUINT len = asBCTypeSize[asBCInfo[b].type];
-		asUINT newSize = func->byteCode.GetLength() + len;
+		asUINT newSize = asUINT(func->byteCode.GetLength()) + len;
 		if( func->byteCode.GetCapacity() < newSize )
 		if( func->byteCode.GetCapacity() < newSize )
 		{
 		{
 			// Determine the average size of the loaded instructions and re-estimate the final size
 			// Determine the average size of the loaded instructions and re-estimate the final size
@@ -1864,16 +1991,25 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 			int *tid = (int*)&bc[n+1];
 			int *tid = (int*)&bc[n+1];
 			*tid = FindTypeId(*tid);
 			*tid = FindTypeId(*tid);
 
 
-			// COPY is used to copy POD types that don't have the opAssign method
+			// COPY is used to copy POD types that don't have the opAssign method. It is 
+			// also used to copy references to scoped types during variable initializations.
 			// Update the number of dwords to copy as it may be different on the target platform
 			// Update the number of dwords to copy as it may be different on the target platform
-			asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
-			if( !dt.IsValid() )
+			if( (*tid) & asTYPEID_OBJHANDLE )
 			{
 			{
-				// TODO: Write error to message
-				error = true;
+				// It is the actual reference that is being copied, not the object itself
+				asBC_SWORDARG0(&bc[n]) = AS_PTR_SIZE;
 			}
 			}
 			else
 			else
-				asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
+			{
+				asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
+				if( !dt.IsValid() )
+				{
+					// TODO: Write error to message
+					error = true;
+				}
+				else
+					asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
+			}
 		}
 		}
 		else if( c == asBC_RET )
 		else if( c == asBC_RET )
 		{
 		{
@@ -1911,12 +2047,12 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 			asPWORD *arg = (asPWORD*)&bc[n+1];
 			asPWORD *arg = (asPWORD*)&bc[n+1];
 			*(asCObjectType**)arg = FindObjectType(*(int*)arg);
 			*(asCObjectType**)arg = FindObjectType(*(int*)arg);
 
 
-			// If the object type is a script class then the constructor id must be translated
-			asCObjectType *ot = *(asCObjectType**)arg;
-			if( ot && (ot->flags & asOBJ_SCRIPT_OBJECT) )
+			// The constructor function id must be translated, unless it is zero
+			int *fid = (int*)&bc[n+1+AS_PTR_SIZE];
+			if( *fid != 0 )
 			{
 			{
-				int *fid = (int*)&bc[n+1+AS_PTR_SIZE];
-				asCScriptFunction *f = FindFunction(*fid);
+				// Subtract 1 from the id, as it was incremented during the writing
+				asCScriptFunction *f = FindFunction(*fid-1);
 				if( f )
 				if( f )
 					*fid = f->id;
 					*fid = f->id;
 				else
 				else
@@ -2112,9 +2248,9 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 	// The program position (every even number) needs to be adjusted
 	// The program position (every even number) needs to be adjusted
 	// for the line numbers to be in number of dwords instead of number of instructions 
 	// for the line numbers to be in number of dwords instead of number of instructions 
 	for( n = 0; n < func->lineNumbers.GetLength(); n += 2 )
 	for( n = 0; n < func->lineNumbers.GetLength(); n += 2 )
-	{
 		func->lineNumbers[n] = instructionNbrToPos[func->lineNumbers[n]];
 		func->lineNumbers[n] = instructionNbrToPos[func->lineNumbers[n]];
-	}
+	for( n = 0; n < func->sectionIdxs.GetLength(); n += 2 )
+		func->sectionIdxs[n] = instructionNbrToPos[func->sectionIdxs[n]];
 
 
 	CalculateStackNeeded(func);
 	CalculateStackNeeded(func);
 }
 }
@@ -2400,11 +2536,26 @@ asCScriptFunction *asCReader::GetCalledFunction(asCScriptFunction *func, asDWORD
 	}
 	}
 	else if( bc == asBC_CallPtr )
 	else if( bc == asBC_CallPtr )
 	{
 	{
-		// Find the funcdef from the local variable
+		asUINT v;
 		int var = asBC_SWORDARG0(&func->byteCode[programPos]);
 		int var = asBC_SWORDARG0(&func->byteCode[programPos]);
-		for( asUINT v = 0; v < func->objVariablePos.GetLength(); v++ )
+
+		// Find the funcdef from the local variable
+		for( v = 0; v < func->objVariablePos.GetLength(); v++ )
 			if( func->objVariablePos[v] == var )
 			if( func->objVariablePos[v] == var )
 				return func->funcVariableTypes[v];
 				return func->funcVariableTypes[v];
+
+		// Look in parameters
+		int paramPos = 0;
+		if( func->objectType )
+			paramPos -= AS_PTR_SIZE;
+		if( func->DoesReturnOnStack() )
+			paramPos -= AS_PTR_SIZE;
+		for( v = 0; v < func->parameterTypes.GetLength(); v++ )
+		{
+			if( var == paramPos )
+				return func->parameterTypes[v].GetFuncDef();
+			paramPos -= func->parameterTypes[v].GetSizeOnStackDWords();
+		}
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -2828,6 +2979,17 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 				else
 				else
 					WriteEncodedInt64(func->lineNumbers[i]);
 					WriteEncodedInt64(func->lineNumbers[i]);
 			}
 			}
+
+			// Write the array of script sections
+			length = (asUINT)func->sectionIdxs.GetLength();
+			WriteEncodedInt64(length);
+			for( i = 0; i < length; ++i )
+			{
+				if( (i & 1) == 0 )
+					WriteEncodedInt64(bytecodeNbrByPos[func->sectionIdxs[i]]);
+				else
+					WriteEncodedInt64(func->sectionIdxs[i]);
+			}
 		}
 		}
 
 
 		WriteData(&func->isShared, 1);
 		WriteData(&func->isShared, 1);
@@ -2846,6 +3008,8 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
 				WriteDataType(&func->variables[i]->type);
 				WriteDataType(&func->variables[i]->type);
 			}
 			}
 		}
 		}
+
+		WriteData(&func->dontCleanUpOnException, 1);
 	}
 	}
 	else if( func->funcType == asFUNC_VIRTUAL )
 	else if( func->funcType == asFUNC_VIRTUAL )
 	{
 	{
@@ -2907,7 +3071,7 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
 		}
 		}
 		else if( ot->flags & asOBJ_TYPEDEF )
 		else if( ot->flags & asOBJ_TYPEDEF )
 		{
 		{
-			eTokenType t = ot->templateSubType.GetTokenType();
+			eTokenType t = ot->templateSubTypes[0].GetTokenType();
 			WriteEncodedInt64(t);
 			WriteEncodedInt64(t);
 		}
 		}
 		else
 		else
@@ -3147,24 +3311,28 @@ void asCWriter::WriteObjectType(asCObjectType* ot)
 	if( ot )
 	if( ot )
 	{
 	{
 		// Check for template instances/specializations
 		// Check for template instances/specializations
-		if( ot->templateSubType.GetTokenType() != ttUnrecognizedToken )
+		if( ot->templateSubTypes.GetLength() )
 		{
 		{
 			ch = 'a';
 			ch = 'a';
 			WriteData(&ch, 1);
 			WriteData(&ch, 1);
 			WriteString(&ot->name);
 			WriteString(&ot->name);
 
 
-			if( ot->templateSubType.IsObject() || ot->templateSubType.IsEnumType() )
-			{
-				ch = 's';
-				WriteData(&ch, 1);
-				WriteDataType(&ot->templateSubType);
-			}
-			else
+			WriteEncodedInt64(ot->templateSubTypes.GetLength());
+			for( asUINT n = 0; n < ot->templateSubTypes.GetLength(); n++ )
 			{
 			{
-				ch = 't';
-				WriteData(&ch, 1);
-				eTokenType t = ot->templateSubType.GetTokenType();
-				WriteEncodedInt64(t);
+				if( ot->templateSubTypes[0].IsObject() || ot->templateSubTypes[0].IsEnumType() )
+				{
+					ch = 's';
+					WriteData(&ch, 1);
+					WriteDataType(&ot->templateSubTypes[0]);
+				}
+				else
+				{
+					ch = 't';
+					WriteData(&ch, 1);
+					eTokenType t = ot->templateSubTypes[0].GetTokenType();
+					WriteEncodedInt64(t);
+				}
 			}
 			}
 		}
 		}
 		else if( ot->flags & asOBJ_TEMPLATE_SUBTYPE )
 		else if( ot->flags & asOBJ_TEMPLATE_SUBTYPE )
@@ -3349,14 +3517,35 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 		}
 		}
 		else if( bc == asBC_CallPtr )
 		else if( bc == asBC_CallPtr )
 		{
 		{
-			// Find the funcdef from the local variable
 			int var = asBC_SWORDARG0(&func->byteCode[n]);
 			int var = asBC_SWORDARG0(&func->byteCode[n]);
-			for( asUINT v = 0; v < func->objVariablePos.GetLength(); v++ )
+			asUINT v;
+			// Find the funcdef from the local variable
+			for( v = 0; v < func->objVariablePos.GetLength(); v++ )
+			{
 				if( func->objVariablePos[v] == var )
 				if( func->objVariablePos[v] == var )
 				{
 				{
 					calledFunc = func->funcVariableTypes[v];
 					calledFunc = func->funcVariableTypes[v];
 					break;
 					break;
 				}
 				}
+			}
+			if( !calledFunc )
+			{
+				// Look in parameters
+				int paramPos = 0;
+				if( func->objectType )
+					paramPos -= AS_PTR_SIZE;
+				if( func->DoesReturnOnStack() )
+					paramPos -= AS_PTR_SIZE;
+				for( v = 0; v < func->parameterTypes.GetLength(); v++ )
+				{
+					if( var == paramPos )
+					{
+						calledFunc = func->parameterTypes[v].GetFuncDef();
+						break;
+					}
+					paramPos -= func->parameterTypes[v].GetSizeOnStackDWords();
+				}
+			}
 			break;
 			break;
 		}
 		}
 		else if( bc == asBC_REFCPY ||
 		else if( bc == asBC_REFCPY ||
@@ -3440,9 +3629,12 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
 			asCObjectType *ot = *(asCObjectType**)(tmp+1);
 			asCObjectType *ot = *(asCObjectType**)(tmp+1);
 			*(asPWORD*)(tmp+1) = FindObjectTypeIdx(ot);
 			*(asPWORD*)(tmp+1) = FindObjectTypeIdx(ot);
 
 
-			// Translate the constructor func id, if it is a script class
-			if( ot->flags & asOBJ_SCRIPT_OBJECT )
-				*(int*)&tmp[1+AS_PTR_SIZE] = FindFunctionIndex(engine->scriptFunctions[*(int*)&tmp[1+AS_PTR_SIZE]]);
+			// Translate the constructor func id, unless it is 0
+			if( *(int*)&tmp[1+AS_PTR_SIZE] != 0 )
+			{
+				// Increment 1 to the translated function id, as 0 will be reserved for no function
+				*(int*)&tmp[1+AS_PTR_SIZE] = 1+FindFunctionIndex(engine->scriptFunctions[*(int*)&tmp[1+AS_PTR_SIZE]]);
+			}
 		}
 		}
 		else if( c == asBC_FREE    || // wW_PTR_ARG
 		else if( c == asBC_FREE    || // wW_PTR_ARG
 			     c == asBC_REFCPY  || // PTR_ARG
 			     c == asBC_REFCPY  || // PTR_ARG

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

@@ -63,7 +63,7 @@ protected:
 
 
 	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 &isNew, bool addToModule = true, bool addToEngine = true, bool addToGC = true);
 	void               ReadFunctionSignature(asCScriptFunction *func);
 	void               ReadFunctionSignature(asCScriptFunction *func);
 	void               ReadGlobalProperty();
 	void               ReadGlobalProperty();
 	void               ReadObjectProperty(asCObjectType *ot);
 	void               ReadObjectProperty(asCObjectType *ot);

+ 4 - 5
ThirdParty/AngelScript/source/as_scriptcode.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -68,19 +68,18 @@ int asCScriptCode::SetCode(const char *name, const char *code, size_t length, bo
 	if( !code ) return asINVALID_ARG;
 	if( !code ) return asINVALID_ARG;
 	this->name = name ? name : "";
 	this->name = name ? name : "";
 	if( !sharedCode && this->code ) 
 	if( !sharedCode && this->code ) 
-	{
 		asDELETEARRAY(this->code);
 		asDELETEARRAY(this->code);
-	}
+
 	if( length == 0 )
 	if( length == 0 )
 		length = strlen(code);
 		length = strlen(code);
 	if( makeCopy )
 	if( makeCopy )
 	{
 	{
+		codeLength = length;
+		sharedCode = false;
 		this->code = asNEWARRAY(char,length);
 		this->code = asNEWARRAY(char,length);
 		if( this->code == 0 )
 		if( this->code == 0 )
 			return asOUT_OF_MEMORY;
 			return asOUT_OF_MEMORY;
 		memcpy((char*)this->code, code, length);
 		memcpy((char*)this->code, code, length);
-		codeLength = length;
-		sharedCode = false;
 	}
 	}
 	else
 	else
 	{
 	{

File diff suppressed because it is too large
+ 321 - 181
ThirdParty/AngelScript/source/as_scriptengine.cpp


+ 13 - 10
ThirdParty/AngelScript/source/as_scriptengine.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -93,7 +93,7 @@ public:
     virtual asIJITCompiler *GetJITCompiler() const;
     virtual asIJITCompiler *GetJITCompiler() const;
 
 
 	// 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, void *objForThiscall = 0);
 	virtual asUINT             GetGlobalFunctionCount() const;
 	virtual asUINT             GetGlobalFunctionCount() const;
 #ifdef AS_DEPRECATED
 #ifdef AS_DEPRECATED
 	// Deprecated since 2.24.0 - 2012-05-20
 	// Deprecated since 2.24.0 - 2012-05-20
@@ -148,11 +148,12 @@ public:
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace, const char **configGroup = 0, asDWORD *accessMask = 0) const;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace, const char **configGroup = 0, asDWORD *accessMask = 0) const;
 
 
 	// Configuration groups
 	// Configuration groups
-	virtual int     BeginConfigGroup(const char *groupName);
-	virtual int     EndConfigGroup();
-	virtual int     RemoveConfigGroup(const char *groupName);
-	virtual asDWORD SetDefaultAccessMask(asDWORD defaultMask);
-	virtual int     SetDefaultNamespace(const char *nameSpace);
+	virtual int         BeginConfigGroup(const char *groupName);
+	virtual int         EndConfigGroup();
+	virtual int         RemoveConfigGroup(const char *groupName);
+	virtual asDWORD     SetDefaultAccessMask(asDWORD defaultMask);
+	virtual int         SetDefaultNamespace(const char *nameSpace);
+	virtual const char *GetDefaultNamespace() const;
 
 
 	// Script modules
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag);
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag);
@@ -251,7 +252,7 @@ public:
 
 
 	void ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type);
 	void ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type);
 
 
-	void ClearUnusedTypes();
+	int  ClearUnusedTypes();
 	void RemoveTemplateInstanceType(asCObjectType *t);
 	void RemoveTemplateInstanceType(asCObjectType *t);
 	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
 	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
 
 
@@ -294,9 +295,11 @@ public:
 	void               RemoveFromTypeIdMap(asCObjectType *type);
 	void               RemoveFromTypeIdMap(asCObjectType *type);
 
 
 	bool               IsTemplateType(const char *name) const;
 	bool               IsTemplateType(const char *name) const;
-	asCObjectType     *GetTemplateInstanceType(asCObjectType *templateType, asCDataType &subType);
+	asCObjectType     *GetTemplateInstanceType(asCObjectType *templateType, asCArray<asCDataType> &subTypes);
 	asCScriptFunction *GenerateTemplateFactoryStub(asCObjectType *templateType, asCObjectType *templateInstanceType, int origFactoryId);
 	asCScriptFunction *GenerateTemplateFactoryStub(asCObjectType *templateType, asCObjectType *templateInstanceType, int origFactoryId);
-	bool               GenerateNewTemplateFunction(asCObjectType *templateType, asCObjectType *templateInstanceType, asCDataType &subType, asCScriptFunction *templateFunc, asCScriptFunction **newFunc);
+	bool               GenerateNewTemplateFunction(asCObjectType *templateType, asCObjectType *templateInstanceType, asCScriptFunction *templateFunc, asCScriptFunction **newFunc);
+	void               OrphanTemplateInstances(asCObjectType *subType);
+	asCDataType        DetermineTypeForTemplate(const asCDataType &orig, asCObjectType *tmpl, asCObjectType *ot);
 
 
 	// String constants
 	// String constants
 	// TODO: Must free unused string constants, thus the ref count for each must be tracked
 	// TODO: Must free unused string constants, thus the ref count for each must be tracked

+ 36 - 13
ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -151,19 +151,8 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
 	variableSpace          = 0;
 	variableSpace          = 0;
 	nameSpace              = engine->nameSpaces[0];
 	nameSpace              = engine->nameSpaces[0];
 
 
-	// TODO: runtime optimize: The engine could notify the GC just before it wants to
-	//                         discard the function. That way the GC won't waste time
-	//                         trying to determine if the functions are garbage before
-	//                         they can actually be considered garbage.
-	//                         Should have a method called Orphan(void *owner). The module
-	//                         should call this method instead of Release() when freeing
-	//                         its reference to the object. The script function would then
-	//                         check if module that is calling Orphan is the owner, and if 
-	//                         so notify the GC. If the module that is calling method isn't
-	//                         the owner, then the script function would simply call Release 
-	//                         as normal.
 	// Notify the GC of script functions
 	// Notify the GC of script functions
-	if( funcType == asFUNC_SCRIPT )
+	if( funcType == asFUNC_SCRIPT && mod == 0 )
 		engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
 		engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
 }
 }
 
 
@@ -246,6 +235,22 @@ int asCScriptFunction::Release() const
 	return r;
 	return r;
 }
 }
 
 
+// internal
+void asCScriptFunction::Orphan(asIScriptModule *mod)
+{
+	if( mod && module == mod )
+	{
+		module = 0;
+		if( funcType == asFUNC_SCRIPT && refCount.get() > 1 )
+		{
+			// This function is being orphaned, so notify the GC so it can check for circular references
+			engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
+		}
+	}
+
+	Release();
+}
+
 // interface
 // interface
 int asCScriptFunction::GetTypeId() const
 int asCScriptFunction::GetTypeId() const
 {
 {
@@ -457,10 +462,22 @@ int asCScriptFunction::FindNextLineWithCode(int line) const
 }
 }
 
 
 // internal
 // internal
-int asCScriptFunction::GetLineNumber(int programPosition)
+int asCScriptFunction::GetLineNumber(int programPosition, int *sectionIdx)
 {
 {
+	if( sectionIdx ) *sectionIdx = scriptSectionIdx;
 	if( lineNumbers.GetLength() == 0 ) return 0;
 	if( lineNumbers.GetLength() == 0 ) return 0;
 
 
+	if( sectionIdx )
+	{
+		// Find the correct section index if the function is compiled from multiple sections
+		// This array will be empty most of the time so we don't need a sofisticated algorithm to search it
+		for( asUINT n = 0; n < sectionIdxs.GetLength(); n += 2 )
+		{
+			if( sectionIdxs[n] <= programPosition )
+				*sectionIdx = sectionIdxs[n+1];
+		}
+	}
+
 	// Do a binary search in the buffer
 	// Do a binary search in the buffer
 	int max = (int)lineNumbers.GetLength()/2 - 1;
 	int max = (int)lineNumbers.GetLength()/2 - 1;
 	int min = 0;
 	int min = 0;
@@ -592,6 +609,12 @@ bool asCScriptFunction::IsSignatureExceptNameEqual(const asCDataType &retType, c
 	return IsSignatureExceptNameAndReturnTypeEqual(paramTypes, paramInOut, objType, readOnly);
 	return IsSignatureExceptNameAndReturnTypeEqual(paramTypes, paramInOut, objType, readOnly);
 }
 }
 
 
+// internal
+bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCScriptFunction *func) const
+{
+	return IsSignatureExceptNameAndReturnTypeEqual(func->parameterTypes, func->inOutFlags, func->objectType, func->isReadOnly);
+}
+
 // internal
 // internal
 bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &paramInOut, const asCObjectType *objType, bool readOnly) const
 bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &paramInOut, const asCObjectType *objType, bool readOnly) const
 {
 {

+ 4 - 6
ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -87,11 +87,6 @@ struct asSSystemFunctionInterface;
 //       also functions/methods that are being called. This could be used to build a 
 //       also functions/methods that are being called. This could be used to build a 
 //       code database with call graphs, etc.
 //       code database with call graphs, etc.
 
 
-// TODO: runtime optimize: The GC should only be notified of the script function when the last module
-//                         removes it from the scope. Must make sure it is only added to the GC once
-//                         in case the function is added to another module after the GC already knows 
-//                         about the function.
-
 void RegisterScriptFunction(asCScriptEngine *engine);
 void RegisterScriptFunction(asCScriptEngine *engine);
 
 
 class asCScriptFunction : public asIScriptFunction
 class asCScriptFunction : public asIScriptFunction
@@ -152,17 +147,19 @@ public:
 	~asCScriptFunction();
 	~asCScriptFunction();
 
 
 	void      DestroyInternal();
 	void      DestroyInternal();
+	void      Orphan(asIScriptModule *mod);
 
 
 	void      AddVariable(asCString &name, asCDataType &type, int stackOffset);
 	void      AddVariable(asCString &name, asCDataType &type, int stackOffset);
 
 
 	int       GetSpaceNeededForArguments();
 	int       GetSpaceNeededForArguments();
 	int       GetSpaceNeededForReturnValue();
 	int       GetSpaceNeededForReturnValue();
 	asCString GetDeclarationStr(bool includeObjectName = true, bool includeNamespace = false) const;
 	asCString GetDeclarationStr(bool includeObjectName = true, bool includeNamespace = false) const;
-	int       GetLineNumber(int programPosition);
+	int       GetLineNumber(int programPosition, int *sectionIdx);
 	void      ComputeSignatureId();
 	void      ComputeSignatureId();
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCDataType &retType, const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const;
 	bool      IsSignatureExceptNameEqual(const asCDataType &retType, const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const;
+	bool      IsSignatureExceptNameAndReturnTypeEqual(const asCScriptFunction *fun) const;
 	bool      IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const;
 	bool      IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const;
 
 
 	bool      DoesReturnOnStack() const;
 	bool      DoesReturnOnStack() const;
@@ -237,6 +234,7 @@ public:
 	int                             stackNeeded;
 	int                             stackNeeded;
 	asCArray<int>                   lineNumbers;      // debug info
 	asCArray<int>                   lineNumbers;      // debug info
 	int                             scriptSectionIdx; // debug info
 	int                             scriptSectionIdx; // debug info
+	asCArray<int>                   sectionIdxs;      // debug info. Store position/index pairs if the bytecode is compiled from multiple script sections
 	bool                            dontCleanUpOnException;   // Stub functions don't own the object and parameters
 	bool                            dontCleanUpOnException;   // Stub functions don't own the object and parameters
 
 
 	// Used by asFUNC_VIRTUAL
 	// Used by asFUNC_VIRTUAL

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

@@ -74,7 +74,6 @@ enum eScriptNode
 	snDoWhile,
 	snDoWhile,
 	snAssignment,
 	snAssignment,
 	snCondition,
 	snCondition,
-	snGlobalVar,
 	snSwitch,
 	snSwitch,
 	snCase,
 	snCase,
 	snImport,
 	snImport,

+ 165 - 45
ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -237,21 +237,57 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 	if( objType->flags & asOBJ_GC )
 	if( objType->flags & asOBJ_GC )
 		objType->engine->gc.AddScriptObjectToGC(this, objType);
 		objType->engine->gc.AddScriptObjectToGC(this, objType);
 
 
-	// Construct all properties
-	asCScriptEngine *engine = objType->engine;
-	for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
+	if( doInitialize )
 	{
 	{
-		asCObjectProperty *prop = objType->properties[n];
-		if( prop->type.IsObject() )
+#ifndef AS_NO_MEMBER_INIT
+		// The actual initialization will be done by the bytecode, so here we should just clear the
+		// memory to guarantee that no pointers with have scratch values in case of an exception
+		// TODO: runtime optimize: Is it quicker to just do a memset on the entire object? 
+		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
 		{
 		{
-			asPWORD *ptr = (asPWORD*)(((char*)this) + prop->byteOffset);
-
-			if( prop->type.IsObjectHandle() )
+			asCObjectProperty *prop = objType->properties[n];
+			if( prop->type.IsObject() )
+			{
+				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
 				*ptr = 0;
 				*ptr = 0;
-			else
+			}
+		}
+#else
+		// When member initialization is disabled the constructor must make sure
+		// to allocate and initialize all members with the default constructor
+		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
+		{
+			asCObjectProperty *prop = objType->properties[n];
+			if( prop->type.IsObject() )
+			{
+				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
+				if( prop->type.IsObjectHandle() )
+					*ptr = 0;
+				else
+				{
+					if( prop->type.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT )
+						*ptr = (asPWORD)ScriptObjectFactory(prop->type.GetObjectType(), ot->engine);
+					else
+						*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), ot->engine);
+				}
+			}
+		}
+#endif
+	}
+	else
+	{
+		// When the object is created without initialization, all non-handle members must be allocated, but not initialized
+		asCScriptEngine *engine = objType->engine;
+		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
+		{
+			asCObjectProperty *prop = objType->properties[n];
+			if( prop->type.IsObject() )
 			{
 			{
-				// Allocate the object and call it's constructor
-				*ptr = (asPWORD)AllocateObject(prop->type.GetObjectType(), engine, doInitialize);
+				asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
+				if( prop->type.IsObjectHandle() )
+					*ptr = 0;
+				else
+					*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), engine);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -271,8 +307,6 @@ void asCScriptObject::Destruct()
 
 
 asCScriptObject::~asCScriptObject()
 asCScriptObject::~asCScriptObject()
 {
 {
-	objType->Release();
-
 	// The engine pointer should be available from the objectType
 	// The engine pointer should be available from the objectType
 	asCScriptEngine *engine = objType->engine;
 	asCScriptEngine *engine = objType->engine;
 
 
@@ -291,6 +325,8 @@ asCScriptObject::~asCScriptObject()
 			}
 			}
 		}
 		}
 	}
 	}
+
+	objType->Release();
 }
 }
 
 
 asIScriptEngine *asCScriptObject::GetEngine() const
 asIScriptEngine *asCScriptObject::GetEngine() const
@@ -440,7 +476,7 @@ int asCScriptObject::GetTypeId() const
 	return objType->engine->GetTypeIdFromDataType(dt);
 	return objType->engine->GetTypeIdFromDataType(dt);
 }
 }
 
 
-// interface
+// Urho3D: added function
 void *asCScriptObject::SetUserData(void *data)
 void *asCScriptObject::SetUserData(void *data)
 {
 {
 	void *oldData = userData;
 	void *oldData = userData;
@@ -448,7 +484,7 @@ void *asCScriptObject::SetUserData(void *data)
 	return oldData;
 	return oldData;
 }
 }
 
 
-// interface
+// Urho3D: added function
 void *asCScriptObject::GetUserData() const
 void *asCScriptObject::GetUserData() const
 {
 {
 	return userData;
 	return userData;
@@ -543,27 +579,106 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
 	{
 	{
 		asASSERT( other.objType->DerivesFrom(objType) );
 		asASSERT( other.objType->DerivesFrom(objType) );
 
 
+		// If the script class implements the opAssign method, it should be called
 		asCScriptEngine *engine = objType->engine;
 		asCScriptEngine *engine = objType->engine;
-
-		// Copy all properties
-		for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
+		asCScriptFunction *func = engine->scriptFunctions[objType->beh.copy];
+		if( func->funcType == asFUNC_SYSTEM )
 		{
 		{
-			asCObjectProperty *prop = objType->properties[n];
-			if( prop->type.IsObject() )
+			// Copy all properties
+			for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
 			{
 			{
-				void **dst = (void**)(((char*)this) + prop->byteOffset);
-				void **src = (void**)(((char*)&other) + prop->byteOffset);
-				if( !prop->type.IsObjectHandle() )
-					CopyObject(*src, *dst, prop->type.GetObjectType(), engine);
+				asCObjectProperty *prop = objType->properties[n];
+				if( prop->type.IsObject() )
+				{
+					void **dst = (void**)(((char*)this) + prop->byteOffset);
+					void **src = (void**)(((char*)&other) + prop->byteOffset);
+					if( !prop->type.IsObjectHandle() )
+						CopyObject(*src, *dst, prop->type.GetObjectType(), engine);
+					else
+						CopyHandle((asPWORD*)src, (asPWORD*)dst, prop->type.GetObjectType(), engine);
+				}
 				else
 				else
-					CopyHandle((asPWORD*)src, (asPWORD*)dst, prop->type.GetObjectType(), engine);
+				{
+					void *dst = ((char*)this) + prop->byteOffset;
+					void *src = ((char*)&other) + prop->byteOffset;
+					memcpy(dst, src, prop->type.GetSizeInMemoryBytes());
+				}
 			}
 			}
-			else
+		}
+		else
+		{
+			// Reuse the active context or create a new one to call the script class' opAssign method
+			asIScriptContext *ctx = 0;
+			int r = 0;
+			bool isNested = false;
+
+			ctx = asGetActiveContext();
+			if( ctx )
+			{
+				r = ctx->PushState();
+				if( r == asSUCCESS )
+					isNested = true;
+				else
+					ctx = 0;
+			}
+
+			if( ctx == 0 )
+			{
+				r = engine->CreateContext(&ctx, true);
+				if( r < 0 )
+					return *this;
+			}
+
+			r = ctx->Prepare(engine->scriptFunctions[objType->beh.copy]);
+			if( r < 0 )
+			{
+				if( isNested )
+					ctx->PopState();
+				else
+					ctx->Release();
+				return *this;
+			}
+
+			r = ctx->SetArgAddress(0, const_cast<asCScriptObject*>(&other));
+			asASSERT( r >= 0 );
+			r = ctx->SetObject(this);
+			asASSERT( r >= 0 );
+
+			for(;;)
 			{
 			{
-				void *dst = ((char*)this) + prop->byteOffset;
-				void *src = ((char*)&other) + prop->byteOffset;
-				memcpy(dst, src, prop->type.GetSizeInMemoryBytes());
+				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( isNested )
+				{
+					ctx->PopState();
+
+					// If the execution was aborted or an exception occurred,
+					// then we should forward that to the outer execution.
+					if( r == asEXECUTION_EXCEPTION )
+					{
+						// TODO: How to improve this exception
+						ctx->SetException(TXT_EXCEPTION_IN_NESTED_CALL);
+					}
+					else if( r == asEXECUTION_ABORTED )
+						ctx->Abort();
+				}
+				else
+					ctx->Release();
+				return *this;
+			}
+
+			if( isNested )
+				ctx->PopState();
+			else
+				ctx->Release();
 		}
 		}
 	}
 	}
 
 
@@ -582,19 +697,14 @@ int asCScriptObject::CopyFrom(asIScriptObject *other)
 	return 0;
 	return 0;
 }
 }
 
 
-void *asCScriptObject::AllocateObject(asCObjectType *objType, asCScriptEngine *engine, bool doInitialize)
+void *asCScriptObject::AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine)
 {
 {
 	void *ptr = 0;
 	void *ptr = 0;
 
 
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
 	if( objType->flags & asOBJ_SCRIPT_OBJECT )
 	{
 	{
-		if( doInitialize )
-			ptr = ScriptObjectFactory(objType, engine);
-		else
-		{
-			ptr = engine->CallAlloc(objType);
-			ScriptObject_ConstructUnitialized(objType, reinterpret_cast<asCScriptObject*>(ptr));
-		}
+		ptr = engine->CallAlloc(objType);
+		ScriptObject_ConstructUnitialized(objType, reinterpret_cast<asCScriptObject*>(ptr));
 	}
 	}
 	else if( objType->flags & asOBJ_TEMPLATE )
 	else if( objType->flags & asOBJ_TEMPLATE )
 	{
 	{
@@ -636,22 +746,32 @@ void asCScriptObject::FreeObject(void *ptr, asCObjectType *objType, asCScriptEng
 
 
 void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine)
 void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine)
 {
 {
-	// TODO: If the object doesn't have the copy behaviour, and it is not a 
-	//       POD object then the copy must not be performed
 	int funcIndex = objType->beh.copy;
 	int funcIndex = objType->beh.copy;
-
 	if( funcIndex )
 	if( funcIndex )
-		engine->CallObjectMethod(dst, src, funcIndex);
-	else
+	{
+		asCScriptFunction *func = engine->scriptFunctions[objType->beh.copy];
+		if( func->funcType == asFUNC_SYSTEM )
+			engine->CallObjectMethod(dst, src, funcIndex);
+		else
+		{
+			// Call the script class' opAssign method
+			asASSERT( objType->flags & asOBJ_SCRIPT_OBJECT );
+			reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<asCScriptObject*>(src));
+		}
+	}
+	else if( objType->size && (objType->flags & asOBJ_POD) )
 		memcpy(dst, src, objType->size);
 		memcpy(dst, src, objType->size);
 }
 }
 
 
 void asCScriptObject::CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine)
 void asCScriptObject::CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine)
 {
 {
-	if( *dst )
+	// asOBJ_NOCOUNT doesn't have addref or release behaviours
+	asASSERT( (objType->flags & asOBJ_NOCOUNT) || (objType->beh.release && objType->beh.addref) );
+
+	if( *dst && objType->beh.release )
 		engine->CallObjectMethod(*(void**)dst, objType->beh.release);
 		engine->CallObjectMethod(*(void**)dst, objType->beh.release);
 	*dst = *src;
 	*dst = *src;
-	if( *dst )
+	if( *dst && objType->beh.addref )
 		engine->CallObjectMethod(*(void**)dst, objType->beh.addref);
 		engine->CallObjectMethod(*(void**)dst, objType->beh.addref);
 }
 }
 
 

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

@@ -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, bool doInitialize);
+	void *AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
 	void CopyObject(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);

+ 7 - 1
ThirdParty/AngelScript/source/as_string.cpp

@@ -308,17 +308,23 @@ size_t asCString::RecalculateLength()
 	return length;
 	return length;
 }
 }
 
 
-int asCString::FindLast(const char *str) const
+int asCString::FindLast(const char *str, int *count) const
 {
 {
 	// There is no strstr that starts from the end, so 
 	// There is no strstr that starts from the end, so 
 	// we'll iterate until we find the last occurrance.
 	// we'll iterate until we find the last occurrance.
 	// This shouldn't cause a performance problem because
 	// This shouldn't cause a performance problem because
 	// it is not expected that this will be done very often,
 	// it is not expected that this will be done very often,
 	// and then only on quite short strings anyway.
 	// and then only on quite short strings anyway.
+
+	if( count ) *count = 0;
+
 	const char *last = 0;
 	const char *last = 0;
 	const char *curr = AddressOf()-1;
 	const char *curr = AddressOf()-1;
 	while( (curr = strstr(curr+1, str)) != 0 )
 	while( (curr = strstr(curr+1, str)) != 0 )
+	{
+		if( count ) (*count)++;
 		last = curr;
 		last = curr;
+	}
 
 
 	if( last )
 	if( last )
 		return int(last - AddressOf());
 		return int(last - AddressOf());

+ 3 - 1
ThirdParty/AngelScript/source/as_string.h

@@ -38,6 +38,8 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
 
 
+// TODO: optimize: On compilers with C++11 support the string class should take advantage of the move operator &&
+
 class asCString
 class asCString
 {
 {
 public:
 public:
@@ -65,7 +67,7 @@ public:
 
 
 	asCString SubString(size_t start, size_t length = (size_t)(-1)) const;
 	asCString SubString(size_t start, size_t length = (size_t)(-1)) const;
 
 
-	int FindLast(const char *str) const;
+	int FindLast(const char *str, int *count = 0) const;
 
 
 	size_t Format(const char *fmt, ...);
 	size_t Format(const char *fmt, ...);
 
 

+ 22 - 22
ThirdParty/AngelScript/source/as_symboltable.h

@@ -2,23 +2,23 @@
    AngelCode Scripting Library
    AngelCode Scripting Library
    Copyright (c) 2012 Andreas Jonsson
    Copyright (c) 2012 Andreas Jonsson
 
 
-   This software is provided 'as-is', without any express or implied 
-   warranty. In no event will the authors be held liable for any 
+   This software is provided 'as-is', without any express or implied
+   warranty. In no event will the authors be held liable for any
    damages arising from the use of this software.
    damages arising from the use of this software.
 
 
-   Permission is granted to anyone to use this software for any 
-   purpose, including commercial applications, and to alter it and 
+   Permission is granted to anyone to use this software for any
+   purpose, including commercial applications, and to alter it and
    redistribute it freely, subject to the following restrictions:
    redistribute it freely, subject to the following restrictions:
 
 
-   1. The origin of this software must not be misrepresented; you 
+   1. The origin of this software must not be misrepresented; you
       must not claim that you wrote the original software. If you use
       must not claim that you wrote the original software. If you use
-      this software in a product, an acknowledgment in the product 
+      this software in a product, an acknowledgment in the product
       documentation would be appreciated but is not required.
       documentation would be appreciated but is not required.
 
 
-   2. Altered source versions must be plainly marked as such, and 
+   2. Altered source versions must be plainly marked as such, and
       must not be misrepresented as being the original software.
       must not be misrepresented as being the original software.
 
 
-   3. This notice may not be removed or altered from any source 
+   3. This notice may not be removed or altered from any source
       distribution.
       distribution.
 
 
    The original version of this library can be located at:
    The original version of this library can be located at:
@@ -50,13 +50,13 @@
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-// TODO: cleanup: This should be in its own header. It is only here because it is 
+// TODO: cleanup: This should be in its own header. It is only here because it is
 //                needed for the template and cannot be resolved with a forward declaration
 //                needed for the template and cannot be resolved with a forward declaration
 struct asSNameSpace
 struct asSNameSpace
 {
 {
 	asCString name;
 	asCString name;
 
 
-	// TODO: namespace: A namespace should have access masks. The application should be 
+	// TODO: namespace: A namespace should have access masks. The application should be
 	//                  able to restrict specific namespaces from access to specific modules
 	//                  able to restrict specific namespaces from access to specific modules
 };
 };
 
 
@@ -150,7 +150,7 @@ private:
 
 
     friend class asCSymbolTableIterator<T, T>;
     friend class asCSymbolTableIterator<T, T>;
     friend class asCSymbolTableIterator<T, const T>;
     friend class asCSymbolTableIterator<T, const T>;
-	
+
 	void GetKey(const T *entry, asCString &key) const;
 	void GetKey(const T *entry, asCString &key) const;
 	void BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const;
 	void BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const;
 	bool CheckIdx(unsigned idx) const;
 	bool CheckIdx(unsigned idx) const;
@@ -224,7 +224,7 @@ const asCArray<unsigned int> &asCSymbolTable<T>::GetIndexes(const asSNameSpace *
 		return m_map.GetValue(cursor);
 		return m_map.GetValue(cursor);
 
 
 	static asCArray<unsigned int> dummy;
 	static asCArray<unsigned int> dummy;
-	return dummy;	
+	return dummy;
 }
 }
 
 
 
 
@@ -362,7 +362,7 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 
 
     T *entry = m_entries[idx];
     T *entry = m_entries[idx];
     asASSERT(entry);
     asASSERT(entry);
-    if( !entry ) 
+    if( !entry )
 		return false;
 		return false;
 
 
 	if( idx == m_entries.GetLength() - 1 )
 	if( idx == m_entries.GetLength() - 1 )
@@ -398,7 +398,7 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 template<class T>
 template<class T>
 int asCSymbolTable<T>::Put(T *entry)
 int asCSymbolTable<T>::Put(T *entry)
 {
 {
-	unsigned int idx = m_entries.GetLength();
+	unsigned int idx = (unsigned int)(m_entries.GetLength());
 	asCString key;
 	asCString key;
 	GetKey(entry, key);
 	GetKey(entry, key);
 
 
@@ -422,10 +422,10 @@ int asCSymbolTable<T>::Put(T *entry)
 template<class T>
 template<class T>
 void asCSymbolTable<T>::BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const
 void asCSymbolTable<T>::BuildKey(const asSNameSpace *ns, const asCString &name, asCString &key) const
 {
 {
-	// TODO: optimize: The key shouldn't be just an asCString. It should keep the 
+	// TODO: optimize: The key shouldn't be just an asCString. It should keep the
 	//                 namespace as a pointer, so it can be compared as pointer.
 	//                 namespace as a pointer, so it can be compared as pointer.
-	//                 Which should be compared first, the namespace or the name? There is likely 
-	//                 going to be many symbols with the same namespace, so it is probably best to 
+	//                 Which should be compared first, the namespace or the name? There is likely
+	//                 going to be many symbols with the same namespace, so it is probably best to
 	//                 compare the name first
 	//                 compare the name first
     key = ns->name + "::" + name;
     key = ns->name + "::" + name;
 }
 }
@@ -455,7 +455,7 @@ unsigned int asCSymbolTable<T>::GetSize() const
 template<class T>
 template<class T>
 bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 {
 {
-    return (idx >= 0 && idx < m_entries.GetLength());
+    return idx < m_entries.GetLength();
 }
 }
 
 
 
 
@@ -464,7 +464,7 @@ bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 template<class T>
 template<class T>
 int asCSymbolTable<T>::GetLastIndex() const
 int asCSymbolTable<T>::GetLastIndex() const
 {
 {
-    unsigned int idx = m_entries.GetLength() - 1;
+    unsigned int idx = (unsigned int)(m_entries.GetLength()) - 1;
 	asASSERT( idx == asUINT(-1) || m_entries[idx] );
 	asASSERT( idx == asUINT(-1) || m_entries[idx] );
     return int(idx);
     return int(idx);
 }
 }
@@ -495,7 +495,7 @@ typename asCSymbolTable<T>::const_iterator asCSymbolTable<T>::List() const
 template<class T, class T2>
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>::asCSymbolTableIterator(asCSymbolTable<T> *table) : m_table(table), m_idx(0)
 asCSymbolTableIterator<T, T2>::asCSymbolTableIterator(asCSymbolTable<T> *table) : m_table(table), m_idx(0)
 {
 {
-    unsigned int sz = m_table->m_entries.GetLength();
+    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
         m_idx++;
         m_idx++;
 }
 }
@@ -543,7 +543,7 @@ asCSymbolTableIterator<T, T2>::operator bool() const
 template<class T, class T2>
 template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Next()
 void asCSymbolTableIterator<T, T2>::Next()
 {
 {
-    unsigned int sz = m_table->m_entries.GetLength();
+    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
     m_idx++;
     m_idx++;
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
         m_idx++;
         m_idx++;
@@ -555,7 +555,7 @@ template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Previous()
 void asCSymbolTableIterator<T, T2>::Previous()
 {
 {
     // overflow on stepping over first element
     // overflow on stepping over first element
-    unsigned int sz = m_table->m_entries.GetLength();
+    unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
     m_idx--;
     m_idx--;
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
     while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
         m_idx--;
         m_idx--;

+ 12 - 6
ThirdParty/AngelScript/source/as_texts.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -52,12 +52,13 @@
 #define TXT_CANNOT_CALL_CONSTRUCTOR_IN_LOOPS     "Can't call a constructor in loops"
 #define TXT_CANNOT_CALL_CONSTRUCTOR_IN_LOOPS     "Can't call a constructor in loops"
 #define TXT_CANNOT_CALL_CONSTRUCTOR_IN_SWITCH    "Can't call a constructor in switch"
 #define TXT_CANNOT_CALL_CONSTRUCTOR_IN_SWITCH    "Can't call a constructor in switch"
 #define TXT_CANNOT_CALL_CONSTRUCTOR_TWICE        "Can't call a constructor multiple times"
 #define TXT_CANNOT_CALL_CONSTRUCTOR_TWICE        "Can't call a constructor multiple times"
+#define TXT_CANNOT_IMPLEMENT_SELF                "Can't implement itself, or another interface that implements this interface"
 #define TXT_CANNOT_INHERIT_FROM_s_FINAL          "Can't inherit from class '%s' marked as final"
 #define TXT_CANNOT_INHERIT_FROM_s_FINAL          "Can't inherit from class '%s' marked as final"
 #define TXT_CANNOT_INHERIT_FROM_MULTIPLE_CLASSES "Can't inherit from multiple classes"
 #define TXT_CANNOT_INHERIT_FROM_MULTIPLE_CLASSES "Can't inherit from multiple classes"
 #define TXT_CANNOT_INHERIT_FROM_SELF             "Can't inherit from itself, or another class that inherits from this class"
 #define TXT_CANNOT_INHERIT_FROM_SELF             "Can't inherit from itself, or another class that inherits from this class"
 #define TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s "Can't instanciate template '%s' with subtype '%s'"
 #define TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s "Can't instanciate template '%s' with subtype '%s'"
-#define TXT_CANT_IMPLICITLY_CONVERT_s_TO_s       "Can't implicitly convert from '%s' to '%s'."
 #define TXT_CANNOT_RETURN_REF_TO_LOCAL           "Can't return reference to local value."
 #define TXT_CANNOT_RETURN_REF_TO_LOCAL           "Can't return reference to local value."
+#define TXT_CANT_IMPLICITLY_CONVERT_s_TO_s       "Can't implicitly convert from '%s' to '%s'."
 #define TXT_CANT_RETURN_VALUE                    "Can't return value when return type is 'void'"
 #define TXT_CANT_RETURN_VALUE                    "Can't return value when return type is 'void'"
 #define TXT_CHANGE_SIGN                          "Implicit conversion changed sign of value"
 #define TXT_CHANGE_SIGN                          "Implicit conversion changed sign of value"
 #define TXT_COMPILING_s                          "Compiling %s"
 #define TXT_COMPILING_s                          "Compiling %s"
@@ -110,6 +111,7 @@
 #define TXT_ILLEGAL_VARIABLE_NAME_s             "Illegal variable name '%s'."
 #define TXT_ILLEGAL_VARIABLE_NAME_s             "Illegal variable name '%s'."
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s     "Initialization lists cannot be used with '%s'"
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s     "Initialization lists cannot be used with '%s'"
 #define TXT_INTERFACE_s_ALREADY_IMPLEMENTED     "The interface '%s' is already implemented"
 #define TXT_INTERFACE_s_ALREADY_IMPLEMENTED     "The interface '%s' is already implemented"
+#define TXT_INTERFACE_CAN_ONLY_IMPLEMENT_INTERFACE "Interfaces can only implement other interfaces"
 #define TXT_INVALID_BREAK                       "Invalid 'break'"
 #define TXT_INVALID_BREAK                       "Invalid 'break'"
 #define TXT_INVALID_CHAR_LITERAL                "Invalid character literal"
 #define TXT_INVALID_CHAR_LITERAL                "Invalid character literal"
 #define TXT_INVALID_CONTINUE                    "Invalid 'continue'"
 #define TXT_INVALID_CONTINUE                    "Invalid 'continue'"
@@ -127,7 +129,7 @@
 #define TXT_MISSING_IMPLEMENTATION_OF_s             "Missing implementation of '%s'"
 #define TXT_MISSING_IMPLEMENTATION_OF_s             "Missing implementation of '%s'"
 #define TXT_MIXIN_CANNOT_BE_DECLARED_AS_s           "Mixin class cannot be declared as '%s'"
 #define TXT_MIXIN_CANNOT_BE_DECLARED_AS_s           "Mixin class cannot be declared as '%s'"
 #define TXT_MIXIN_CANNOT_HAVE_CONSTRUCTOR           "Mixin classes cannot have constructors or destructors"
 #define TXT_MIXIN_CANNOT_HAVE_CONSTRUCTOR           "Mixin classes cannot have constructors or destructors"
-#define TXT_MIXIN_CLASS_CANNOT_INHERIT              "Mixin class cannot inherit from classes or implement interfaces"
+#define TXT_MIXIN_CLASS_CANNOT_INHERIT              "Mixin class cannot inherit from classes"
 #define TXT_MORE_THAN_ONE_MATCHING_OP               "Found more than one matching operator"
 #define TXT_MORE_THAN_ONE_MATCHING_OP               "Found more than one matching operator"
 #define TXT_MULTIPLE_MATCHING_SIGNATURES_TO_s       "Multiple matching signatures to '%s'"
 #define TXT_MULTIPLE_MATCHING_SIGNATURES_TO_s       "Multiple matching signatures to '%s'"
 #define TXT_MULTIPLE_PROP_GET_ACCESSOR_FOR_s        "Found multiple get accessors for property '%s'"
 #define TXT_MULTIPLE_PROP_GET_ACCESSOR_FOR_s        "Found multiple get accessors for property '%s'"
@@ -159,6 +161,7 @@
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPES_s_AND_s "No matching operator that takes the types '%s' and '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPES_s_AND_s "No matching operator that takes the types '%s' and '%s' found"
 #define TXT_NON_CONST_METHOD_ON_CONST_OBJ          "Non-const method call on read-only object reference"
 #define TXT_NON_CONST_METHOD_ON_CONST_OBJ          "Non-const method call on read-only object reference"
+#define TXT_NONTERMINATED_STRING                   "Non-terminated string literal"
 #define TXT_NOT_A_FUNC_s_IS_VAR                    "Expression doesn't form a function call. '%s' is a variable of a non-function type"
 #define TXT_NOT_A_FUNC_s_IS_VAR                    "Expression doesn't form a function call. '%s' is a variable of a non-function type"
 #define TXT_NOT_ALL_PATHS_RETURN                   "Not all paths return a value"
 #define TXT_NOT_ALL_PATHS_RETURN                   "Not all paths return a value"
 #define TXT_s_NOT_DECLARED                         "'%s' is not declared"
 #define TXT_s_NOT_DECLARED                         "'%s' is not declared"
@@ -187,6 +190,7 @@
 #define TXT_PROPERTY_CANT_BE_CONST                "Class properties cannot be declared as const"
 #define TXT_PROPERTY_CANT_BE_CONST                "Class properties cannot be declared as const"
 #define TXT_PROPERTY_HAS_NO_GET_ACCESSOR          "The property has no get accessor"
 #define TXT_PROPERTY_HAS_NO_GET_ACCESSOR          "The property has no get accessor"
 #define TXT_PROPERTY_HAS_NO_SET_ACCESSOR          "The property has no set accessor"
 #define TXT_PROPERTY_HAS_NO_SET_ACCESSOR          "The property has no set accessor"
+#define TXT_PROPERTY_WITHOUT_ACCESSOR             "Virtual property must have at least one get or set accessor"
 
 
 #define TXT_REF_IS_READ_ONLY                    "Reference is read-only"
 #define TXT_REF_IS_READ_ONLY                    "Reference is read-only"
 #define TXT_REF_IS_TEMP                         "Reference is temporary"
 #define TXT_REF_IS_TEMP                         "Reference is temporary"
@@ -196,17 +200,18 @@
 
 
 #define TXT_SHARED_CANNOT_ACCESS_NON_SHARED_VAR_s      "Shared code cannot access non-shared global variable '%s'"
 #define TXT_SHARED_CANNOT_ACCESS_NON_SHARED_VAR_s      "Shared code cannot access non-shared global variable '%s'"
 #define TXT_SHARED_CANNOT_CALL_NON_SHARED_FUNC_s       "Shared code cannot call non-shared function '%s'"
 #define TXT_SHARED_CANNOT_CALL_NON_SHARED_FUNC_s       "Shared code cannot call non-shared function '%s'"
-#define TXT_SHARED_CANNOT_IMPLEMENT_NON_SHARED_s       "Shared class cannot implement non-shared interface '%s'"
+#define TXT_SHARED_CANNOT_IMPLEMENT_NON_SHARED_s       "Shared type cannot implement non-shared interface '%s'"
 #define TXT_SHARED_CANNOT_INHERIT_FROM_NON_SHARED_s    "Shared class cannot inherit from non-shared class '%s'"
 #define TXT_SHARED_CANNOT_INHERIT_FROM_NON_SHARED_s    "Shared class cannot inherit from non-shared class '%s'"
 #define TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s        "Shared code cannot use non-shared type '%s'"
 #define TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s        "Shared code cannot use non-shared type '%s'"
-#define TXT_SHARED_DOESNT_MATCH_ORIGINAL               "Shared type doesn't match the original declaration in other module"
+#define TXT_SHARED_s_DOESNT_MATCH_ORIGINAL             "Shared type '%s' doesn't match the original declaration in other module"
 #define TXT_SIGNED_UNSIGNED_MISMATCH                   "Signed/Unsigned mismatch"
 #define TXT_SIGNED_UNSIGNED_MISMATCH                   "Signed/Unsigned mismatch"
 #define TXT_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #define TXT_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #define TXT_SWITCH_CASE_MUST_BE_CONSTANT               "Case expressions must be constants"
 #define TXT_SWITCH_CASE_MUST_BE_CONSTANT               "Case expressions must be constants"
 #define TXT_SWITCH_MUST_BE_INTEGRAL                    "Switch expressions must be integral numbers"
 #define TXT_SWITCH_MUST_BE_INTEGRAL                    "Switch expressions must be integral numbers"
 
 
-#define TXT_TYPE_s_NOT_AVAILABLE_FOR_MODULE  "Type '%s' is not available for this module"
+#define TXT_TMPL_s_EXPECTS_d_SUBTYPES        "Template '%s' expects %d sub type(s)"
 #define TXT_TOO_MANY_JUMP_LABELS             "The function has too many jump labels to handle. Split the function into smaller ones."
 #define TXT_TOO_MANY_JUMP_LABELS             "The function has too many jump labels to handle. Split the function into smaller ones."
+#define TXT_TYPE_s_NOT_AVAILABLE_FOR_MODULE  "Type '%s' is not available for this module"
 
 
 #define TXT_UNEXPECTED_END_OF_FILE        "Unexpected end of file"
 #define TXT_UNEXPECTED_END_OF_FILE        "Unexpected end of file"
 #define TXT_UNEXPECTED_TOKEN_s            "Unexpected token '%s'"
 #define TXT_UNEXPECTED_TOKEN_s            "Unexpected token '%s'"
@@ -220,6 +225,7 @@
 #define TXT_WHILE_PARSING_ARG_LIST        "While parsing argument list"
 #define TXT_WHILE_PARSING_ARG_LIST        "While parsing argument list"
 #define TXT_WHILE_PARSING_EXPRESSION      "While parsing expression"
 #define TXT_WHILE_PARSING_EXPRESSION      "While parsing expression"
 #define TXT_WHILE_PARSING_INIT_LIST       "While parsing initialization list"
 #define TXT_WHILE_PARSING_INIT_LIST       "While parsing initialization list"
+#define TXT_WHILE_PARSING_NAMESPACE       "While parsing namespace"
 #define TXT_WHILE_PARSING_STATEMENT_BLOCK "While parsing statement block"
 #define TXT_WHILE_PARSING_STATEMENT_BLOCK "While parsing statement block"
 #define TXT_WHILE_INCLUDING_MIXIN         "Previous error occurred while including mixin"
 #define TXT_WHILE_INCLUDING_MIXIN         "Previous error occurred while including mixin"
 
 

+ 34 - 5
ThirdParty/AngelScript/source/as_thread.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -58,9 +58,14 @@ AS_API int asThreadCleanup()
 	return asCThreadManager::CleanupLocalData();
 	return asCThreadManager::CleanupLocalData();
 }
 }
 
 
-AS_API void asPrepareMultithread()
+AS_API asIThreadManager *asGetThreadManager()
 {
 {
-	asCThreadManager::Prepare();
+	return threadManager;
+}
+
+AS_API int asPrepareMultithread(asIThreadManager *externalThreadMgr)
+{
+	return asCThreadManager::Prepare(externalThreadMgr);
 }
 }
 
 
 AS_API void asUnprepareMultithread()
 AS_API void asUnprepareMultithread()
@@ -71,25 +76,33 @@ AS_API void asUnprepareMultithread()
 AS_API void asAcquireExclusiveLock()
 AS_API void asAcquireExclusiveLock()
 {
 {
 	if( threadManager )
 	if( threadManager )
+	{
 		ACQUIREEXCLUSIVE(threadManager->appRWLock);
 		ACQUIREEXCLUSIVE(threadManager->appRWLock);
+	}
 }
 }
 
 
 AS_API void asReleaseExclusiveLock()
 AS_API void asReleaseExclusiveLock()
 {
 {
 	if( threadManager )
 	if( threadManager )
+	{
 		RELEASEEXCLUSIVE(threadManager->appRWLock);
 		RELEASEEXCLUSIVE(threadManager->appRWLock);
+	}
 }
 }
 
 
 AS_API void asAcquireSharedLock()
 AS_API void asAcquireSharedLock()
 {
 {
 	if( threadManager )
 	if( threadManager )
+	{
 		ACQUIRESHARED(threadManager->appRWLock);
 		ACQUIRESHARED(threadManager->appRWLock);
+	}
 }
 }
 
 
 AS_API void asReleaseSharedLock()
 AS_API void asReleaseSharedLock()
 {
 {
 	if( threadManager )
 	if( threadManager )
+	{
 		RELEASESHARED(threadManager->appRWLock);
 		RELEASESHARED(threadManager->appRWLock);
+	}
 }
 }
 
 
 }
 }
@@ -106,8 +119,13 @@ asCThreadManager::asCThreadManager()
 	refCount = 1;
 	refCount = 1;
 }
 }
 
 
-void asCThreadManager::Prepare()
+int asCThreadManager::Prepare(asIThreadManager *externalThreadMgr)
 {
 {
+	// Don't allow an external thread manager if there 
+	// is already a thread manager defined
+	if( externalThreadMgr && threadManager )
+		return asINVALID_ARG;
+
 	// The critical section cannot be declared globally, as there is no
 	// The critical section cannot be declared globally, as there is no
 	// guarantee for the order in which global variables are initialized
 	// guarantee for the order in which global variables are initialized
 	// or uninitialized.
 	// or uninitialized.
@@ -118,14 +136,24 @@ void asCThreadManager::Prepare()
 	// To avoid the race condition when the thread manager is first created, 
 	// To avoid the race condition when the thread manager is first created, 
 	// the application must make sure to call the global asPrepareForMultiThread()
 	// the application must make sure to call the global asPrepareForMultiThread()
 	// in the main thread before any other thread creates a script engine. 
 	// in the main thread before any other thread creates a script engine. 
-	if( threadManager == 0 )
+	if( threadManager == 0 && externalThreadMgr == 0 )
 		threadManager = asNEW(asCThreadManager);
 		threadManager = asNEW(asCThreadManager);
 	else
 	else
 	{
 	{
+		// If an application uses different dlls each dll will get it's own memory
+		// space for global variables. If multiple dlls then uses AngelScript's 
+		// global thread support functions it is then best to share the thread
+		// manager to make sure all dlls use the same critical section.
+		if( externalThreadMgr )
+			threadManager = reinterpret_cast<asCThreadManager*>(externalThreadMgr);
+
 		ENTERCRITICALSECTION(threadManager->criticalSection);
 		ENTERCRITICALSECTION(threadManager->criticalSection);
 		threadManager->refCount++;
 		threadManager->refCount++;
 		LEAVECRITICALSECTION(threadManager->criticalSection);
 		LEAVECRITICALSECTION(threadManager->criticalSection);
 	}
 	}
+
+	// Success
+	return 0;
 }
 }
 
 
 void asCThreadManager::Unprepare()
 void asCThreadManager::Unprepare()
@@ -350,6 +378,7 @@ asCThreadReadWriteLock::asCThreadReadWriteLock()
 #if defined AS_POSIX_THREADS
 #if defined AS_POSIX_THREADS
 	int r = pthread_rwlock_init(&lock, 0);
 	int r = pthread_rwlock_init(&lock, 0);
 	asASSERT( r == 0 );
 	asASSERT( r == 0 );
+	UNUSED_VAR(r);
 #elif defined AS_WINDOWS_THREADS
 #elif defined AS_WINDOWS_THREADS
 	// Create a semaphore to allow up to maxReaders simultaneous readers
 	// Create a semaphore to allow up to maxReaders simultaneous readers
 	readLocks = CreateSemaphore(NULL, maxReaders, maxReaders, 0);
 	readLocks = CreateSemaphore(NULL, maxReaders, maxReaders, 0);

+ 3 - 3
ThirdParty/AngelScript/source/as_thread.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2013 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    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 
@@ -49,13 +49,13 @@ BEGIN_AS_NAMESPACE
 
 
 class asCThreadLocalData;
 class asCThreadLocalData;
 
 
-class asCThreadManager
+class asCThreadManager : public asIThreadManager
 {
 {
 public:
 public:
 	static asCThreadLocalData *GetLocalData();
 	static asCThreadLocalData *GetLocalData();
 	static int CleanupLocalData();
 	static int CleanupLocalData();
 
 
-	static void Prepare();
+	static int  Prepare(asIThreadManager *externalThreadMgr);
 	static void Unprepare();
 	static void Unprepare();
 
 
 	// This read/write lock can be used by the application to provide simple synchronization
 	// This read/write lock can be used by the application to provide simple synchronization

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