Browse Source

Update to AngelScript 2.29.1. Closes #412.

Lasse Öörni 11 năm trước cách đây
mục cha
commit
562a2e2d77

+ 1 - 1
Bin/Data/Scripts/Editor/EditorView.as

@@ -105,7 +105,7 @@ class ViewportContext
         viewport = Viewport(editorScene, camera, viewRect);
         index = index_;
         viewportId = viewportId_;
-        camera.viewMask = -1; // It's easier to only have 1 gizmo active this viewport is shared with the gizmo
+        camera.viewMask = 0xffffffff; // It's easier to only have 1 gizmo active this viewport is shared with the gizmo
     }
 
     void ResetCamera()

+ 1 - 1
Docs/Urho3D.dox

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

+ 1 - 1
Readme.txt

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

+ 6 - 6
Source/Engine/Script/APITemplates.h

@@ -63,7 +63,7 @@ template <class T> CScriptArray* VectorToArray(const Vector<T>& vector, const ch
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(vector.Size(), type);
+        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
             *(static_cast<T*>(arr->At(i))) = vector[i];
@@ -81,7 +81,7 @@ template <class T> CScriptArray* VectorToArray(const PODVector<T>& vector, const
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(vector.Size(), type);
+        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
             *(static_cast<T*>(arr->At(i))) = vector[i];
@@ -99,7 +99,7 @@ template <class T> CScriptArray* BufferToArray(const T* buffer, unsigned size, c
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(size, type);
+        CScriptArray* arr = CScriptArray::Create(type, size);
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
             *(static_cast<T*>(arr->At(i))) = buffer[i];
@@ -117,7 +117,7 @@ template <class T> CScriptArray* VectorToHandleArray(const Vector<T*>& vector, c
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(vector.Size(), type);
+        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
         {
@@ -141,7 +141,7 @@ template <class T> CScriptArray* VectorToHandleArray(const PODVector<T*>& vector
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(vector.Size(), type);
+        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
         {
@@ -165,7 +165,7 @@ template <class T> CScriptArray* VectorToHandleArray(const Vector<SharedPtr<T> >
     if (context)
     {
         asIObjectType* type = GetScriptContext()->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = new CScriptArray(vector.Size(), type);
+        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
 
         for (unsigned i = 0; i < arr->GetSize(); ++i)
         {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 286 - 231
Source/Engine/Script/Addons.cpp


+ 177 - 64
Source/Engine/Script/Addons.h

@@ -40,105 +40,190 @@ struct SArrayCache;
 class URHO3D_API CScriptArray
 {
 public:
-    CScriptArray(asIObjectType *ot, void *buf);
-    CScriptArray(asUINT length, asIObjectType *ot);
-    CScriptArray(asUINT length, void *defVal, asIObjectType *ot);
-    CScriptArray(const CScriptArray &other);
-    virtual ~CScriptArray();
+    // Set the memory functions that should be used by all CScriptArrays
+    static void SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
 
+    // Factory functions
+    static CScriptArray *Create(asIObjectType *ot);
+    static CScriptArray *Create(asIObjectType *ot, asUINT length);
+    static CScriptArray *Create(asIObjectType *ot, asUINT length, void *defaultValue);
+    static CScriptArray *Create(asIObjectType *ot, void *listBuffer);
+
+    // Memory management
     void AddRef() const;
     void Release() const;
 
     // Type information
     asIObjectType *GetArrayObjectType() const;
-    int GetArrayTypeId() const;
-    int GetElementTypeId() const;
+    int            GetArrayTypeId() const;
+    int            GetElementTypeId() const;
 
-    void Reserve(asUINT maxElements);
-    void Resize(asUINT numElements);
+    // Get the current size
     asUINT GetSize() const;
-    bool IsEmpty() const;
+
+    // Returns true if the array is empty
+    bool   IsEmpty() const;
+
+    // Pre-allocates memory for elements
+    void   Reserve(asUINT maxElements);
+
+    // Resize the array
+    void   Resize(asUINT numElements);
 
     // Get a pointer to an element. Returns 0 if out of bounds
-    void *At(asUINT index);
+    void       *At(asUINT index);
     const void *At(asUINT index) const;
 
-    // Set value of an element
-    void SetValue(asUINT index, void *value);
+    // Set value of an element. 
+    // The value arg should be a pointer to the value that will be copied to the element.
+    // Remember, if the array holds handles the value parameter should be the 
+    // address of the handle. The refCount of the object will also be incremented
+    void  SetValue(asUINT index, void *value);
 
+    // Copy the contents of one array to another (only if the types are the same)
     CScriptArray &operator=(const CScriptArray&);
+
+    // Compare two arrays
     bool operator==(const CScriptArray &) const;
 
+    // Array manipulation
     void InsertAt(asUINT index, void *value);
     void RemoveAt(asUINT index);
     void InsertLast(void *value);
     void RemoveLast();
     void SortAsc();
     void SortDesc();
-    void SortAsc(asUINT index, asUINT count);
-    void SortDesc(asUINT index, asUINT count);
-    void Sort(asUINT index, asUINT count, bool asc);
+    void SortAsc(asUINT startAt, asUINT count);
+    void SortDesc(asUINT startAt, asUINT count);
+    void Sort(asUINT startAt, asUINT count, bool asc);
     void Reverse();
-    int Find(void *value) const;
-    int Find(asUINT index, void *value) const;
+    int  Find(void *value) const;
+    int  Find(asUINT startAt, void *value) const;
+    int  FindByRef(void *ref) const;
+    int  FindByRef(asUINT startAt, void *ref) const;
 
     // GC methods
-    int GetRefCount();
+    int  GetRefCount();
     void SetFlag();
     bool GetFlag();
     void EnumReferences(asIScriptEngine *engine);
     void ReleaseAllHandles(asIScriptEngine *engine);
 
 protected:
-    mutable int refCount;
-    mutable bool gcFlag;
-    asIObjectType *objType;
-    SArrayBuffer *buffer;
-    int elementSize;
-    int subTypeId;
+    mutable int       refCount;
+    mutable bool      gcFlag;
+    asIObjectType    *objType;
+    SArrayBuffer     *buffer;
+    int               elementSize;
+    int               subTypeId;
+
+    // Constructors
+    CScriptArray(asIObjectType *ot, void *initBuf); // Called from script when initialized with list
+    CScriptArray(asUINT length, asIObjectType *ot);
+    CScriptArray(asUINT length, void *defVal, asIObjectType *ot);
+    CScriptArray(const CScriptArray &other);
+    virtual ~CScriptArray();
 
-    bool Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache);
+    bool  Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache);
     void *GetArrayItemPointer(int index);
     void *GetDataPointer(void *buffer);
-    void Copy(void *dst, void *src);
-    void Precache();
-    bool CheckMaxSize(asUINT numElements);
-    void Resize(int delta, asUINT at);
-    void CreateBuffer(SArrayBuffer **buf, asUINT numElements);
-    void DeleteBuffer(SArrayBuffer *buf);
-    void CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src);
-    void Construct(SArrayBuffer *buf, asUINT start, asUINT end);
-    void Destruct(SArrayBuffer *buf, asUINT start, asUINT end);
-    bool Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const;
+    void  Copy(void *dst, void *src);
+    void  Precache();
+    bool  CheckMaxSize(asUINT numElements);
+    void  Resize(int delta, asUINT at);
+    void  CreateBuffer(SArrayBuffer **buf, asUINT numElements);
+    void  DeleteBuffer(SArrayBuffer *buf);
+    void  CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src);
+    void  Construct(SArrayBuffer *buf, asUINT start, asUINT end);
+    void  Destruct(SArrayBuffer *buf, asUINT start, asUINT end);
+    bool  Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const;
 };
 
-/// Script dictionary class
-class CScriptDictionary
+class CScriptDictionary;
+
+/// %Script dictionary value.
+class URHO3D_API CScriptDictValue
 {
 public:
-    // Memory management
-    CScriptDictionary(asIScriptEngine *engine);
-    CScriptDictionary(asBYTE *buffer);
+    // This class must not be declared as local variable in C++, because it needs 
+    // to receive the script engine pointer in all operations. The engine pointer
+    // is not kept as member in order to keep the size down
+    CScriptDictValue();
+    CScriptDictValue(asIScriptEngine *engine, void *value, int typeId);
+
+    // Destructor must not be called without first calling FreeValue, otherwise a memory leak will occur
+    ~CScriptDictValue();
+
+    // Replace the stored value
+    void Set(asIScriptEngine *engine, void *value, int typeId);
+    void Set(asIScriptEngine *engine, const asINT64 &value);
+    void Set(asIScriptEngine *engine, const double &value);
+
+    // Gets the stored value. Returns false if the value isn't compatible with the informed typeId
+    bool Get(asIScriptEngine *engine, void *value, int typeId) const;
+    bool Get(asIScriptEngine *engine, asINT64 &value) const;
+    bool Get(asIScriptEngine *engine, double &value) const;
+
+    // Returns the type id of the stored value
+    int  GetTypeId() const;
+
+    // Free the stored value
+    void FreeValue(asIScriptEngine *engine);
+
+protected:
+    friend class CScriptDictionary;
+
+    union
+    {
+        asINT64 m_valueInt;
+        double  m_valueFlt;
+        void   *m_valueObj;
+    };
+    int m_typeId;
+};
+
+/// %Script dictionary class.
+class URHO3D_API CScriptDictionary
+{
+public:
+    // Factory functions
+    static CScriptDictionary *Create(asIScriptEngine *engine);
+
+    // Called from the script to instantiate a dictionary from an initialization list
+    static CScriptDictionary *Create(asBYTE *buffer);
+
+    // Reference counting
     void AddRef() const;
     void Release() const;
 
+    // Reassign the dictionary
     CScriptDictionary &operator =(const CScriptDictionary &other);
 
-    // Sets/Gets a variable type value for a key
+    // Sets a key/value pair
     void Set(const String &key, void *value, int typeId);
-    bool Get(const String &key, void *value, int typeId) const;
+    void Set(const String &key, const asINT64 &value);
+    void Set(const String &key, const double &value);
 
-    // Sets/Gets an integer number value for a key
-    void Set(const String &key, asINT64 &value);
+    // Gets the stored value. Returns false if the value isn't compatible with the informed typeId
+    bool Get(const String &key, void *value, int typeId) const;
     bool Get(const String &key, asINT64 &value) const;
-
-    // Sets/Gets a real number value for a key
-    void Set(const String &key, double &value);
     bool Get(const String &key, double &value) const;
 
+    // Index accessors. If the dictionary is not const it inserts the value if it doesn't already exist
+    // If the dictionary is const then a script exception is set if it doesn't exist and a null pointer is returned
+    CScriptDictValue *operator[](const String &key);
+    const CScriptDictValue *operator[](const String &key) const;
+
+    // Returns the type id of the stored value, or negative if it doesn't exist
+    int GetTypeId(const String &key) const;
+
     // Returns true if the key is set
     bool Exists(const String &key) const;
+
+    // Returns true if there are no key/value pairs in the dictionary
     bool IsEmpty() const;
+
+    // Returns the number of key/value pairs in the dictionary
     asUINT GetSize() const;
 
     // Deletes the key
@@ -150,6 +235,43 @@ public:
     // Get an array of all keys
     CScriptArray *GetKeys() const;
 
+public:
+    // STL style iterator
+    class CIterator
+    {
+    public:
+        void operator++();    // Pre-increment
+        void operator++(int); // Post-increment
+
+        // This is needed to support C++11 range-for
+        CIterator &operator*();
+
+        bool operator==(const CIterator &other) const;
+        bool operator!=(const CIterator &other) const;
+
+        // Accessors
+        const String &GetKey() const;
+        int                GetTypeId() const;
+        bool               GetValue(asINT64 &value) const;
+        bool               GetValue(double &value) const;
+        bool               GetValue(void *value, int typeId) const;
+
+    protected:
+        friend class CScriptDictionary;
+
+        CIterator();
+        CIterator(const CScriptDictionary &dict,
+                  HashMap<String, CScriptDictValue>::ConstIterator it);
+
+        CIterator &operator=(const CIterator &) {return *this;} // Not used
+
+        HashMap<String, CScriptDictValue>::ConstIterator m_it;
+        const CScriptDictionary &m_dict;
+    };
+
+    CIterator begin() const;
+    CIterator end() const;
+
     // Garbage collections behaviours
     int GetRefCount();
     void SetGCFlag();
@@ -158,33 +280,24 @@ public:
     void ReleaseAllReferences(asIScriptEngine *engine);
 
 protected:
-    // The structure for holding the values
-    struct valueStruct
-    {
-        union
-        {
-            asINT64 valueInt;
-            double  valueFlt;
-            void   *valueObj;
-        };
-        int   typeId;
-    };
+    // Since the dictionary uses the asAllocMem and asFreeMem functions to allocate memory
+    // the constructors are made protected so that the application cannot allocate it 
+    // manually in a different way
+    CScriptDictionary(asIScriptEngine *engine);
+    CScriptDictionary(asBYTE *buffer);
 
     // We don't want anyone to call the destructor directly, it should be called through the Release method
     virtual ~CScriptDictionary();
-
-    // Helper methods
-    void FreeValue(valueStruct &value);
     
     // Our properties
     asIScriptEngine *engine;
     mutable int refCount;
     mutable bool gcFlag;
 
-    HashMap<String, valueStruct> dict;
+    // TODO: memory: The allocator should use the asAllocMem and asFreeMem
+    HashMap<String, CScriptDictValue> dict;
 };
 
-
 /// Register the array type to script.
 void RegisterArray(asIScriptEngine* engine);
 /// Register the dictionary type to script.

+ 58 - 3
Source/ThirdParty/AngelScript/include/angelscript.h

@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 // AngelScript version
 
-#define ANGELSCRIPT_VERSION        22900
-#define ANGELSCRIPT_VERSION_STRING "2.29.0"
+#define ANGELSCRIPT_VERSION        22901
+#define ANGELSCRIPT_VERSION_STRING "2.29.1 WIP"
 
 // Data types
 
@@ -134,6 +134,7 @@ enum asEEngineProp
 	asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT      = 18,
 	asEP_COMPILER_WARNINGS                  = 19,
 	asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE = 20,
+	asEP_ALTER_SYNTAX_NAMED_ARGS            = 21,
 
 	asEP_LAST_PROPERTY
 };
@@ -200,7 +201,8 @@ enum asEObjTypeFlags
 	asOBJ_LIST_PATTERN               = (1<<25),
 	asOBJ_ENUM                       = (1<<26),
 	asOBJ_TEMPLATE_SUBTYPE           = (1<<27),
-	asOBJ_TYPEDEF                    = (1<<28)
+	asOBJ_TYPEDEF                    = (1<<28),
+	asOBJ_ABSTRACT                   = (1<<29)
 };
 
 // Behaviours
@@ -562,6 +564,59 @@ extern "C"
 }
 #endif // ANGELSCRIPT_DLL_MANUAL_IMPORT
 
+// Determine traits of a type for registration of value types
+// Relies on C++11 features so it can not be used with non-compliant compilers
+#ifdef AS_CAN_USE_CPP11
+
+END_AS_NAMESPACE
+#include <type_traits>
+BEGIN_AS_NAMESPACE
+
+template<typename T>
+asUINT asGetTypeTraits()
+{
+	bool hasConstructor =  std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
+#if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) 
+	// http://stackoverflow.com/questions/12702103/writing-code-that-works-when-has-trivial-destructor-is-defined-instead-of-is
+	bool hasDestructor = std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value;
+#else
+	bool hasDestructor = std::is_destructible<T>::value && !std::has_trivial_destructor<T>::value;
+#endif
+	bool hasAssignmentOperator = std::is_copy_assignable<T>::value && !std::has_trivial_copy_assign<T>::value;
+	bool hasCopyConstructor = std::is_copy_constructible<T>::value && !std::has_trivial_copy_constructor<T>::value;
+	bool isFloat = std::is_floating_point<T>::value;
+	bool isPrimitive = std::is_integral<T>::value || std::is_pointer<T>::value || std::is_enum<T>::value;
+	bool isClass = std::is_class<T>::value;
+	bool isArray = std::is_array<T>::value;
+
+	if( isFloat )
+		return asOBJ_APP_FLOAT;
+	if( isPrimitive )
+		return asOBJ_APP_PRIMITIVE;
+	
+	if( isClass )
+	{
+		asDWORD flags = asOBJ_APP_CLASS;
+		if( hasConstructor )
+			flags |= asOBJ_APP_CLASS_CONSTRUCTOR;
+		if( hasDestructor )
+			flags |= asOBJ_APP_CLASS_DESTRUCTOR;
+		if( hasAssignmentOperator )
+			flags |= asOBJ_APP_CLASS_ASSIGNMENT;
+		if( hasCopyConstructor )
+			flags |= asOBJ_APP_CLASS_COPY_CONSTRUCTOR;
+		return flags;
+	}
+
+	if( isArray )
+		return asOBJ_APP_ARRAY;
+
+	// Unknown type traits
+	return 0;
+}
+
+#endif // c++11
+
 // Interface declarations
 
 class asIScriptEngine

+ 111 - 69
Source/ThirdParty/AngelScript/source/as_builder.cpp

@@ -99,9 +99,7 @@ asCBuilder::~asCBuilder()
 		if( functions[n] )
 		{
 			if( functions[n]->node )
-			{
 				functions[n]->node->Destroy(engine);
-			}
 
 			asDELETE(functions[n],sFunctionDescription);
 		}
@@ -126,9 +124,7 @@ asCBuilder::~asCBuilder()
 	for( n = 0; n < scripts.GetLength(); n++ )
 	{
 		if( scripts[n] )
-		{
 			asDELETE(scripts[n],asCScriptCode);
-		}
 
 		scripts[n] = 0;
 	}
@@ -139,9 +135,7 @@ asCBuilder::~asCBuilder()
 		if( classDeclarations[n] )
 		{
 			if( classDeclarations[n]->node )
-			{
 				classDeclarations[n]->node->Destroy(engine);
-			}
 
 			asDELETE(classDeclarations[n],sClassDeclaration);
 			classDeclarations[n] = 0;
@@ -153,9 +147,7 @@ asCBuilder::~asCBuilder()
 		if( interfaceDeclarations[n] )
 		{
 			if( interfaceDeclarations[n]->node )
-			{
 				interfaceDeclarations[n]->node->Destroy(engine);
-			}
 
 			asDELETE(interfaceDeclarations[n],sClassDeclaration);
 			interfaceDeclarations[n] = 0;
@@ -167,9 +159,7 @@ asCBuilder::~asCBuilder()
 		if( namedTypeDeclarations[n] )
 		{
 			if( namedTypeDeclarations[n]->node )
-			{
 				namedTypeDeclarations[n]->node->Destroy(engine);
-			}
 
 			asDELETE(namedTypeDeclarations[n],sClassDeclaration);
 			namedTypeDeclarations[n] = 0;
@@ -495,9 +485,7 @@ void asCBuilder::ParseScripts()
 
 		// Register the complete function definitions
 		for( n = 0; n < funcDefs.GetLength(); n++ )
-		{
 			CompleteFuncDef(funcDefs[n]);
-		}
 
 		// Register script methods found in the interfaces
 		for( n = 0; n < interfaceDeclarations.GetLength(); n++ )
@@ -866,8 +854,8 @@ int asCBuilder::VerifyProperty(asCDataType *dt, const char *decl, asCString &nam
 	name.Assign(&decl[nameNode->tokenPos], nameNode->tokenLength);
 
 	// Validate that the type really can be a registered property
-	// We cannot use CanBeInstanciated, as it is allowed to register
-	// properties of type that cannot otherwise be instanciated
+	// We cannot use CanBeInstantiated, as it is allowed to register
+	// properties of type that cannot otherwise be instantiated
 	if( type.GetFuncDef() && !type.IsObjectHandle() )
 	{
 		// Function definitions must always be handles
@@ -1441,14 +1429,16 @@ int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSN
 	// What data type is it?
 	asCDataType type = CreateDataTypeFromNode(node->firstChild, file, ns);
 
-	if( !type.CanBeInstanciated() )
+	if( !type.CanBeInstantiated() )
 	{
 		asCString str;
-		// TODO: Change to "'type' cannot be declared as variable"
-		str.Format(TXT_DATA_TYPE_CANT_BE_s, type.Format().AddressOf());
-
-		int r, c;
-		file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+		if( type.IsAbstractClass() )
+			str.Format(TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED, type.Format().AddressOf());
+		else if( type.IsInterface() )
+			str.Format(TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED, type.Format().AddressOf());
+		else
+			// TODO: Improve error message to explain why
+			str.Format(TXT_DATA_TYPE_CANT_BE_s, type.Format().AddressOf());
 
 		WriteError(str, file, node);
 	}
@@ -1563,24 +1553,58 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 	asCScriptNode *n = node->firstChild;
 	bool isFinal = false;
 	bool isShared = false;
+	bool isAbstract = false;
 
-	if( n->tokenType == ttIdentifier && file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) )
-	{
-		isFinal = true;
-		n = n->next;
-	}
-
-	if( n->tokenType == ttIdentifier && file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN) )
+	// Check the class modifiers
+	while( n->tokenType == ttIdentifier )
 	{
-		isShared = true;
-		n = n->next;
-
-		// Check for final again
-		if( n->tokenType == ttIdentifier && file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) )
+		if( file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) )
 		{
-			isFinal = true;
-			n = n->next;
+			if( isAbstract )
+				WriteError(TXT_CLASS_CANT_BE_FINAL_AND_ABSTRACT, file, n);
+			else
+			{
+				if( isFinal )
+				{
+					asCString msg;
+					msg.Format(TXT_ATTR_s_INFORMED_MULTIPLE_TIMES, asCString(&file->code[n->tokenPos], n->tokenLength).AddressOf());
+					WriteWarning(msg, file, n);
+				}
+				isFinal = true;
+			}
+		}
+		else if( file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN) )
+		{
+			if( isShared )
+			{
+				asCString msg;
+				msg.Format(TXT_ATTR_s_INFORMED_MULTIPLE_TIMES, asCString(&file->code[n->tokenPos], n->tokenLength).AddressOf());
+				WriteWarning(msg, file, n);
+			}
+			isShared = true;
 		}
+		else if( file->TokenEquals(n->tokenPos, n->tokenLength, ABSTRACT_TOKEN) )
+		{
+			if( isFinal )
+				WriteError(TXT_CLASS_CANT_BE_FINAL_AND_ABSTRACT, file, n);
+			else
+			{
+				if( isAbstract )
+				{
+					asCString msg;
+					msg.Format(TXT_ATTR_s_INFORMED_MULTIPLE_TIMES, asCString(&file->code[n->tokenPos], n->tokenLength).AddressOf());
+					WriteWarning(msg, file, n);
+				}
+				isAbstract = true;
+			}
+		}
+		else
+		{
+			// This is the name of the class
+			break;
+		}
+
+		n = n->next;
 	}
 
 	asCString name(&file->code[n->tokenPos], n->tokenLength);
@@ -1646,6 +1670,9 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
 	if( isFinal )
 		st->flags |= asOBJ_NOINHERIT;
 
+	if( isAbstract )
+		st->flags |= asOBJ_ABSTRACT;
+
 	if( node->tokenType == ttHandle )
 		st->flags |= asOBJ_IMPLICIT_HANDLE;
 
@@ -1745,7 +1772,7 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
 	if( isShared )
 		st->flags |= asOBJ_SHARED;
 
-	st->size = 0; // Cannot be instanciated
+	st->size = 0; // Cannot be instantiated
 	st->name = name;
 	st->nameSpace = ns;
 	module->classTypes.PushLast(st);
@@ -2114,7 +2141,7 @@ void asCBuilder::AddInterfaceFromMixinToClass(sClassDeclaration *decl, asCScript
 			asCObjectType *objType = GetObjectType(name.AddressOf(), ns);
 
 			// Check that the object type is an interface
-			if( objType && objType->size == 0 && (objType->flags & asOBJ_SCRIPT_OBJECT) )
+			if( objType && objType->IsInterface() )
 			{
 				// Only add the interface if the class doesn't already implement it
 				if( !decl->objType->Implements(objType) )
@@ -2224,7 +2251,7 @@ void asCBuilder::CompileInterfaces()
 
 			// Check that the object type is an interface
 			bool ok = true;
-			if( objType && objType->size == 0 && (objType->flags & asOBJ_SCRIPT_OBJECT) )
+			if( objType && objType->IsInterface() )
 			{
 				// Check that the implemented interface is shared if the base interface is shared
 				if( intfType->IsShared() && !objType->IsShared() )
@@ -2367,16 +2394,10 @@ void asCBuilder::CompileClasses()
 		bool multipleInheritance = false;
 		asCScriptNode *node = decl->node->firstChild;
 
-		if( decl->objType->IsShared() )
-		{
-			// Skip the keyword 'shared'
-			asASSERT(node->tokenType == ttIdentifier);
-			node = node->next;
-		}
-		if( decl->objType->flags & asOBJ_NOINHERIT )
+		while( file->TokenEquals(node->tokenPos, node->tokenLength, FINAL_TOKEN) ||
+			   file->TokenEquals(node->tokenPos, node->tokenLength, SHARED_TOKEN) ||
+			   file->TokenEquals(node->tokenPos, node->tokenLength, ABSTRACT_TOKEN) )
 		{
-			// skip the keyword 'final'
-			asASSERT(node->tokenType == ttIdentifier);
 			node = node->next;
 		}
 
@@ -2397,6 +2418,7 @@ void asCBuilder::CompileClasses()
 			// Find the object type for the interface
 			asCObjectType *objType = 0;
 			sMixinClass *mixin = 0;
+			asSNameSpace *origNs = ns;
 			while( ns )
 			{
 				objType = GetObjectType(name.AddressOf(), ns);
@@ -2412,7 +2434,10 @@ void asCBuilder::CompileClasses()
 			if( objType == 0 && mixin == 0 )
 			{
 				asCString str;
-				str.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, name.AddressOf());
+				if( origNs->name == "" )
+					str.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_GLOBAL_NS, name.AddressOf());
+				else
+					str.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_NS_s, name.AddressOf(), origNs->name.AddressOf());
 				WriteError(str, file, node);
 			}
 			else if( mixin )
@@ -2687,10 +2712,6 @@ void asCBuilder::CompileClasses()
 
 		// Enumerate each of the declared properties
 		asCScriptNode *node = decl->node->firstChild->next;
-		if( decl->objType->IsShared() )
-			node = node->next;
-		if( decl->objType->flags & asOBJ_NOINHERIT )
-			node = node->next;
 
 		// Skip list of classes and interfaces
 		while( node && node->nodeType == snIdentifier )
@@ -3024,10 +3045,9 @@ void asCBuilder::IncludeMethodsFromMixins(sClassDeclaration *decl)
 {
 	asCScriptNode *node = decl->node->firstChild;
 
-	// Skip the 'final' and 'shared' keywords
-	if( decl->objType->IsShared() )
-		node = node->next;
-	if( decl->objType->flags & asOBJ_NOINHERIT )
+	// Skip the class attributes
+	while( node->nodeType == snIdentifier &&
+		   !decl->script->TokenEquals(node->tokenPos, node->tokenLength, decl->name.AddressOf()) )
 		node = node->next;
 
 	// Skip the name of the class
@@ -3099,10 +3119,9 @@ void asCBuilder::IncludePropertiesFromMixins(sClassDeclaration *decl)
 {
 	asCScriptNode *node = decl->node->firstChild;
 
-	// Skip the 'final' and 'shared' keywords
-	if( decl->objType->IsShared() )
-		node = node->next;
-	if( decl->objType->flags & asOBJ_NOINHERIT )
+	// Skip the class attributes
+	while( node->nodeType == snIdentifier &&
+		   !decl->script->TokenEquals(node->tokenPos, node->tokenLength, decl->name.AddressOf()) )
 		node = node->next;
 
 	// Skip the name of the class
@@ -3272,12 +3291,18 @@ asCObjectProperty *asCBuilder::AddPropertyToClass(sClassDeclaration *decl, const
 	if( node )
 	{
 		// Check if the property is allowed
-		if( !dt.CanBeInstanciated() )
+		if( !dt.CanBeInstantiated() )
 		{
 			if( file && node )
 			{
 				asCString str;
-				str.Format(TXT_DATA_TYPE_CANT_BE_s, dt.Format().AddressOf());
+				if( dt.IsAbstractClass() )
+					str.Format(TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+				else if( dt.IsInterface() )
+					str.Format(TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+				else
+					// TODO: Improve error message to explain why
+					str.Format(TXT_DATA_TYPE_CANT_BE_s, dt.Format().AddressOf());
 				WriteError(str, file, node);
 			}
 			return 0;
@@ -4494,6 +4519,15 @@ void asCBuilder::WriteWarning(const asCString &scriptname, const asCString &mess
 	}
 }
 
+void asCBuilder::WriteWarning(const asCString &message, asCScriptCode *file, asCScriptNode *node)
+{
+	int r = 0, c = 0;
+	if( node && file )
+		file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+
+	WriteWarning(file ? file->name : asCString(""), message, r, c);
+}
+
 asCString asCBuilder::GetScopeFromNode(asCScriptNode *node, asCScriptCode *script, asCScriptNode **next)
 {
 	asCString scope;
@@ -4590,6 +4624,7 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 		str.Assign(&file->code[n->tokenPos], n->tokenLength);
 
 		// Recursively search parent namespaces for matching type
+		asSNameSpace *origNs = ns;
 		while( ns && !found )
 		{
 			asCObjectType *ot = 0;
@@ -4670,8 +4705,6 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 								return asCDataType::CreatePrimitive(ttInt, false);
 							}
 
-							asASSERT( subTypes.GetLength() == ot->templateSubTypes.GetLength() );
-
 							// Check if any of the given subtypes are different from the template's declared subtypes
 							bool isDifferent = false;
 							for( subtypeIndex = 0; subtypeIndex < subTypes.GetLength(); subtypeIndex++ )
@@ -4693,7 +4726,7 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 								{
 									asCString msg;
 									// TODO: Should name all subtypes
-									msg.Format(TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s, ot->name.AddressOf(), subTypes[0].Format().AddressOf());
+									msg.Format(TXT_CANNOT_INSTANTIATE_TEMPLATE_s_WITH_s, ot->name.AddressOf(), subTypes[0].Format().AddressOf());
 									WriteError(msg, file, n);
 								}
 
@@ -4739,7 +4772,10 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 		if( !found )
 		{
 			asCString msg;
-			msg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, (const char *)str.AddressOf());
+			if( origNs->name == "" )
+				msg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_GLOBAL_NS, str.AddressOf());
+			else
+				msg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_NS_s, str.AddressOf(), origNs->name.AddressOf());
 			WriteError(msg, file, n);
 
 			dt = asCDataType::CreatePrimitive(ttInt, isConst);
@@ -4762,12 +4798,18 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 	{
 		if( n->tokenType == ttOpenBracket )
 		{
-			// Make sure the sub type can be instanciated
-			if( !dt.CanBeInstanciated() )
+			// Make sure the sub type can be instantiated
+			if( !dt.CanBeInstantiated() )
 			{
 				asCString str;
-				// TODO: Change to "Array sub type cannot be 'type'"
-				str.Format(TXT_DATA_TYPE_CANT_BE_s, dt.Format().AddressOf());
+				if( dt.IsAbstractClass() )
+					str.Format(TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+				else if( dt.IsInterface() )
+					str.Format(TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+				else
+					// TODO: Improve error message to explain why
+					str.Format(TXT_DATA_TYPE_CANT_BE_s, dt.Format().AddressOf());
+
 				WriteError(str, file, n);
 			}
 

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

@@ -166,6 +166,7 @@ protected:
 	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);
+	void               WriteWarning(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
 
 	bool               DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp = 0, sGlobalVariableDescription **outDesc = 0, bool *isAppProp = 0);
 	asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);

+ 479 - 479
Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -1,479 +1,479 @@
-/*
-   AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
-
-   This software is provided 'as-is', without any express or implied
-   warranty. In no event will the authors be held liable for any
-   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]
-*/
-
-/*
- * Implements the AMD64 calling convention for gcc-based 64bit Unices
- *
- * Author: Ionut "gargltk" Leonte <[email protected]>
- *
- * Initial author: niteice
- *
- * Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
- */
-
-// Useful references for the System V AMD64 ABI:
-// http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
-// http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf
- 
-#include "as_config.h"
-
-#ifndef AS_MAX_PORTABILITY
-#ifdef AS_X64_GCC
-
-#include "as_scriptengine.h"
-#include "as_texts.h"
-#include "as_context.h"
-
-BEGIN_AS_NAMESPACE
-
-enum argTypes { x64INTARG = 0, x64FLOATARG = 1 };
-typedef asQWORD ( *funcptr_t )( void );
-
-#define X64_MAX_ARGS             32
-#define MAX_CALL_INT_REGISTERS    6
-#define MAX_CALL_SSE_REGISTERS    8
-#define X64_CALLSTACK_SIZE        ( X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 )
-
-// Note to self: Always remember to inform the used registers on the clobber line, 
-// so that the gcc optimizer doesn't try to use them for other things
-
-static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat) 
-{
-	// Need to flag the variable as volatile so the compiler doesn't optimize out the variable
-	volatile asQWORD retQW1 = 0;
-
-	// Reference: http://www.x86-64.org/documentation/abi.pdf
-
-	__asm__ __volatile__ (
-
-		"  movq %0, %%rcx \n" 	// rcx = cnt
-		"  movq %1, %%r10 \n"	// r10 = args
-		"  movq %2, %%r11 \n"	// r11 = func
-
-	// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
-		"  movq %%rsp, %%r15 \n"
-	// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
-		" .cfi_def_cfa_register r15 \n"
-
-	// Skip the first 128 bytes on the stack frame, called "red zone",  
-	// that might be used by the compiler to store temporary values
-		"  sub $128, %%rsp \n"
-
-	// Make sure the stack pointer will be aligned to 16 bytes when the function is called
-		"  movq %%rcx, %%rdx \n"
-		"  salq $3, %%rdx \n"
-		"  movq %%rsp, %%rax \n"
-		"  sub %%rdx, %%rax \n"
-		"  and $15, %%rax \n"
-		"  sub %%rax, %%rsp \n"
-
-	// Push the stack parameters, i.e. the arguments that won't be loaded into registers
-		"  movq %%rcx, %%rsi \n"
-		"  testl %%esi, %%esi \n"
-		"  jle endstack \n"
-		"  subl $1, %%esi \n"
-		"  xorl %%edx, %%edx \n"
-		"  leaq	8(, %%rsi, 8), %%rcx \n"
-		"loopstack: \n"
-		"  movq 112(%%r10, %%rdx), %%rax \n"
-		"  pushq %%rax \n"
-		"  addq $8, %%rdx \n"
-		"  cmpq %%rcx, %%rdx \n"
-		"  jne loopstack \n"
-		"endstack: \n"
-
-	// Populate integer and floating point parameters
-		"  movq %%r10, %%rax \n"
-		"  mov     (%%rax), %%rdi \n"
-		"  mov    8(%%rax), %%rsi \n"
-		"  mov   16(%%rax), %%rdx \n"
-		"  mov   24(%%rax), %%rcx \n"
-		"  mov   32(%%rax), %%r8 \n"
-		"  mov   40(%%rax), %%r9 \n"
-		"  add   $48, %%rax \n"
-		"  movsd   (%%rax), %%xmm0 \n"
-		"  movsd  8(%%rax), %%xmm1 \n"
-		"  movsd 16(%%rax), %%xmm2 \n"
-		"  movsd 24(%%rax), %%xmm3 \n"
-		"  movsd 32(%%rax), %%xmm4 \n"
-		"  movsd 40(%%rax), %%xmm5 \n"
-		"  movsd 48(%%rax), %%xmm6 \n"
-		"  movsd 56(%%rax), %%xmm7 \n"
-
-	// Call the function
-		"  call	*%%r11 \n"
-
-	// Restore stack pointer
-		"  mov %%r15, %%rsp \n"
-	// Inform the stack unwind logic that the stack pointer has been restored
-		" .cfi_def_cfa_register rsp \n"
-
-	// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
-		"  movl %5, %%ecx \n"
-		"  testb %%cl, %%cl \n"
-		"  je intret \n"
-		"  lea %3, %%rax \n"
-		"  movq %%xmm0, (%%rax) \n"
-		"  lea %4, %%rdx \n"
-		"  movq %%xmm1, (%%rdx) \n"
-		"  jmp endcall \n"
-		"intret: \n"
-		"  movq %%rax, %3 \n"
-		"  movq %%rdx, %4 \n"
-		"endcall: \n"
-
-		: : "r" ((asQWORD)cnt), "r" (args), "r" (func), "m" (retQW1), "m" (retQW2), "m" (returnFloat)
-		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 
-		  "%rdi", "%rsi", "%rax", "%rdx", "%rcx", "%r8", "%r9", "%r10", "%r11", "%r15");
-		
-	return retQW1;
-}
-
-// returns true if the given parameter is a 'variable argument'
-static inline bool IsVariableArgument( asCDataType type )
-{
-	return ( type.GetTokenType() == ttQuestion ) ? true : false;
-}
-
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
-{
-	asCScriptEngine            *engine             = context->m_engine;
-	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
-	int                         callConv           = sysFunc->callConv;
-	asQWORD                     retQW              = 0;
-	asDWORD                    *stack_pointer      = args;
-	funcptr_t                  *vftable            = NULL;
-	int                         totalArgumentCount = 0;
-	int                         n                  = 0;
-	int                         param_post         = 0;
-	int                         argIndex           = 0;
-	funcptr_t                   func               = (funcptr_t)sysFunc->func;
-
-	if( sysFunc->hostReturnInMemory ) 
-	{
-		// The return is made in memory
-		callConv++;
-	}
-
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
-	// param_post has value 2 if is an THISCALL_OBJLAST
-#endif
-
-
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-	// Determine the real function pointer in case of virtual method
-	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) 
-#else
-	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL ||
-		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
-		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
-		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
-		callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
-		callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
-#endif
-	{
-		vftable = *((funcptr_t**)obj);
-		func = vftable[FuncPtrToUInt(asFUNCTION_t(func)) >> 3];
-	}
-
-	// Determine the type of the arguments, and prepare the input array for the X64_CallFunction 
-	asQWORD  paramBuffer[X64_CALLSTACK_SIZE] = { 0 };
-	asBYTE	 argsType[X64_CALLSTACK_SIZE] = { 0 };
-
-	switch ( callConv ) 
-	{
-		case ICC_CDECL_RETURNINMEM:
-		case ICC_STDCALL_RETURNINMEM: 
-		{
-			paramBuffer[0] = (asPWORD)retPointer;
-			argsType[0] = x64INTARG;
-
-			argIndex = 1;
-
-			break;
-		}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-		case ICC_THISCALL_OBJLAST:
-		case ICC_VIRTUAL_THISCALL_OBJLAST:
-			param_post = 2;
-#endif
-		case ICC_THISCALL:
-		case ICC_VIRTUAL_THISCALL:
-		case ICC_CDECL_OBJFIRST: 
-		{
-			paramBuffer[0] = (asPWORD)obj;
-			argsType[0] = x64INTARG;
-
-			argIndex = 1;
-
-			break;
-		}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-		case ICC_THISCALL_OBJLAST_RETURNINMEM:
-		case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
-			param_post = 2;
-#endif
-		case ICC_THISCALL_RETURNINMEM:
-		case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-		case ICC_CDECL_OBJFIRST_RETURNINMEM: 
-		{
-			paramBuffer[0] = (asPWORD)retPointer;
-			paramBuffer[1] = (asPWORD)obj;
-			argsType[0] = x64INTARG;
-			argsType[1] = x64INTARG;
-
-			argIndex = 2;
-
-			break;
-		}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-		case ICC_THISCALL_OBJFIRST:
-		case ICC_VIRTUAL_THISCALL_OBJFIRST:
-		{
-			paramBuffer[0] = (asPWORD)obj;
-			paramBuffer[1] = (asPWORD)secondObject;
-			argsType[0] = x64INTARG;
-			argsType[1] = x64INTARG;
-
-			argIndex = 2;
-			break;
-		}
-		case ICC_THISCALL_OBJFIRST_RETURNINMEM:
-		case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
-		{
-			paramBuffer[0] = (asPWORD)retPointer;
-			paramBuffer[1] = (asPWORD)obj;
-			paramBuffer[2] = (asPWORD)secondObject;
-			argsType[0] = x64INTARG;
-			argsType[1] = x64INTARG;
-			argsType[2] = x64INTARG;
-
-			argIndex = 3;
-			break;
-		}
-#endif
-		case ICC_CDECL_OBJLAST:
-			param_post = 1;
-			break;
-		case ICC_CDECL_OBJLAST_RETURNINMEM: 
-		{
-			paramBuffer[0] = (asPWORD)retPointer;
-			argsType[0] = x64INTARG;
-
-			argIndex = 1;
-			param_post = 1;
-
-			break;
-		}
-	}
-
-	int argumentCount = ( int )descr->parameterTypes.GetLength();
-	for( int a = 0; a < argumentCount; ++a ) 
-	{
-		const asCDataType &parmType = descr->parameterTypes[a];
-		if( parmType.IsFloatType() && !parmType.IsReference() ) 
-		{
-			argsType[argIndex] = x64FLOATARG;
-			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(float));
-			argIndex++;
-			stack_pointer++;
-		}
-		else if( parmType.IsDoubleType() && !parmType.IsReference() ) 
-		{
-			argsType[argIndex] = x64FLOATARG;
-			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(double));
-			argIndex++;
-			stack_pointer += 2;
-		}
-		else if( IsVariableArgument( parmType ) ) 
-		{
-			// The variable args are really two, one pointer and one type id
-			argsType[argIndex] = x64INTARG;
-			argsType[argIndex+1] = x64INTARG;
-			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(void*));
-			memcpy(paramBuffer + argIndex + 1, stack_pointer + 2, sizeof(asDWORD));
-			argIndex += 2;
-			stack_pointer += 3;
-		}
-		else if( parmType.IsPrimitive() ||
-		         parmType.IsReference() || 
-		         parmType.IsObjectHandle() )
-		{
-			argsType[argIndex] = x64INTARG;
-			if( parmType.GetSizeOnStackDWords() == 1 )
-			{
-				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asDWORD));
-				stack_pointer++;
-			}
-			else
-			{
-				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
-				stack_pointer += 2;
-			}
-			argIndex++;
-		}
-		else
-		{
-			// An object is being passed by value
-			if( (parmType.GetObjectType()->flags & COMPLEX_MASK) ||
-			    parmType.GetSizeInMemoryDWords() > 4 )
-			{
-				// Copy the address of the object
-				argsType[argIndex] = x64INTARG;
-				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
-				argIndex++;
-			}
-			else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLINTS) ||
-			         (parmType.GetObjectType()->flags & asOBJ_APP_PRIMITIVE) )
-			{
-				// Copy the value of the object
-				if( parmType.GetSizeInMemoryDWords() > 2 )
-				{
-					argsType[argIndex] = x64INTARG;
-					argsType[argIndex+1] = x64INTARG;
-					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
-					argIndex += 2;
-				}
-				else
-				{
-					argsType[argIndex] = x64INTARG;
-					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
-					argIndex++;
-				}
-				// Delete the original memory
-				engine->CallFree(*(void**)stack_pointer);
-			}
-			else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS) ||
-			         (parmType.GetObjectType()->flags & asOBJ_APP_FLOAT) )
-			{
-				// Copy the value of the object
-				if( parmType.GetSizeInMemoryDWords() > 2 )
-				{
-					argsType[argIndex] = x64FLOATARG;
-					argsType[argIndex+1] = x64FLOATARG;
-					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
-					argIndex += 2;
-				}
-				else
-				{
-					argsType[argIndex] = x64FLOATARG;
-					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
-					argIndex++;
-				}
-				// Delete the original memory
-				engine->CallFree(*(void**)stack_pointer);
-			}
-			stack_pointer += 2;
-		}
-	}
-
-	// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
-	if( param_post )
-	{
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-		paramBuffer[argIndex] = (asPWORD)obj;
-#else
-		paramBuffer[argIndex] = (asPWORD)(param_post > 1 ? secondObject : obj);
-#endif
-		argsType[argIndex] = x64INTARG;
-		argIndex++;
-	}
-
-	totalArgumentCount = argIndex;
-
-	/*
-	 * Q: WTF is going on here !?
-	 *
-	 * A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
-	 * it's little magic which must work regardless of how the compiler decides to
-	 * allocate registers. Basically:
-	 * - the first MAX_CALL_INT_REGISTERS entries in tempBuff will
-	 *   contain the values/types of the x64INTARG parameters - that is the ones who
-	 *   go into the registers. If the function has less then MAX_CALL_INT_REGISTERS
-	 *   integer parameters then the last entries will be set to 0
-	 * - the next MAX_CALL_SSE_REGISTERS entries will contain the float/double arguments
-	 *   that go into the floating point registers. If the function has less than
-	 *   MAX_CALL_SSE_REGISTERS floating point parameters then the last entries will
-	 *   be set to 0
-	 * - index MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS marks the start of the
-	 *   parameters which will get passed on the stack. These are added to the array
-	 *   in reverse order so that X64_CallFunction() can simply push them to the stack
-	 *   without the need to perform further tests
-	 */
-	asQWORD tempBuff[X64_CALLSTACK_SIZE] = { 0 };
-	asBYTE  argsSet[X64_CALLSTACK_SIZE]  = { 0 };
-	int     used_int_regs   = 0;
-	int     used_sse_regs   = 0;
-	int     used_stack_args = 0;
-	int     idx             = 0;
-	for ( n = 0; ( n < totalArgumentCount ) && ( used_int_regs < MAX_CALL_INT_REGISTERS ); n++ ) 
-	{
-		if ( argsType[n] == x64INTARG ) 
-		{
-			argsSet[n] = 1;
-			tempBuff[idx++] = paramBuffer[n];
-			used_int_regs++;
-		}
-	}
-	idx = MAX_CALL_INT_REGISTERS;
-	for ( n = 0; ( n < totalArgumentCount ) && ( used_sse_regs < MAX_CALL_SSE_REGISTERS ); n++ ) 
-	{
-		if ( argsType[n] == x64FLOATARG ) 
-		{
-			argsSet[n] = 1;
-			tempBuff[idx++] = paramBuffer[n];
-			used_sse_regs++;
-		}
-	}
-	idx = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS;
-	for ( n = totalArgumentCount - 1; n >= 0; n-- ) 
-	{
-		if ( !argsSet[n] ) 
-		{
-			tempBuff[idx++] = paramBuffer[n];
-			used_stack_args++;
-		}
-	}
-
-	retQW = X64_CallFunction( tempBuff, used_stack_args, func, retQW2, sysFunc->hostReturnFloat );
-
-	return retQW;
-}
-
-END_AS_NAMESPACE
-
-#endif // AS_X64_GCC
-#endif // AS_MAX_PORTABILITY
-
+/*
+   AngelCode Scripting Library
+   Copyright (c) 2003-2014 Andreas Jonsson
+
+   This software is provided 'as-is', without any express or implied
+   warranty. In no event will the authors be held liable for any
+   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]
+*/
+
+/*
+ * Implements the AMD64 calling convention for gcc-based 64bit Unices
+ *
+ * Author: Ionut "gargltk" Leonte <[email protected]>
+ *
+ * Initial author: niteice
+ *
+ * Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
+ */
+
+// Useful references for the System V AMD64 ABI:
+// http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
+// http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf
+ 
+#include "as_config.h"
+
+#ifndef AS_MAX_PORTABILITY
+#ifdef AS_X64_GCC
+
+#include "as_scriptengine.h"
+#include "as_texts.h"
+#include "as_context.h"
+
+BEGIN_AS_NAMESPACE
+
+enum argTypes { x64INTARG = 0, x64FLOATARG = 1 };
+typedef asQWORD ( *funcptr_t )( void );
+
+#define X64_MAX_ARGS             32
+#define MAX_CALL_INT_REGISTERS    6
+#define MAX_CALL_SSE_REGISTERS    8
+#define X64_CALLSTACK_SIZE        ( X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 )
+
+// Note to self: Always remember to inform the used registers on the clobber line, 
+// so that the gcc optimizer doesn't try to use them for other things
+
+static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat) 
+{
+	// Need to flag the variable as volatile so the compiler doesn't optimize out the variable
+	volatile asQWORD retQW1 = 0;
+
+	// Reference: http://www.x86-64.org/documentation/abi.pdf
+
+	__asm__ __volatile__ (
+
+		"  movq %0, %%rcx \n" 	// rcx = cnt
+		"  movq %1, %%r10 \n"	// r10 = args
+		"  movq %2, %%r11 \n"	// r11 = func
+
+	// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
+		"  movq %%rsp, %%r15 \n"
+	// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
+		" .cfi_def_cfa_register r15 \n"
+
+	// Skip the first 128 bytes on the stack frame, called "red zone",  
+	// that might be used by the compiler to store temporary values
+		"  sub $128, %%rsp \n"
+
+	// Make sure the stack pointer will be aligned to 16 bytes when the function is called
+		"  movq %%rcx, %%rdx \n"
+		"  salq $3, %%rdx \n"
+		"  movq %%rsp, %%rax \n"
+		"  sub %%rdx, %%rax \n"
+		"  and $15, %%rax \n"
+		"  sub %%rax, %%rsp \n"
+
+	// Push the stack parameters, i.e. the arguments that won't be loaded into registers
+		"  movq %%rcx, %%rsi \n"
+		"  testl %%esi, %%esi \n"
+		"  jle endstack \n"
+		"  subl $1, %%esi \n"
+		"  xorl %%edx, %%edx \n"
+		"  leaq	8(, %%rsi, 8), %%rcx \n"
+		"loopstack: \n"
+		"  movq 112(%%r10, %%rdx), %%rax \n"
+		"  pushq %%rax \n"
+		"  addq $8, %%rdx \n"
+		"  cmpq %%rcx, %%rdx \n"
+		"  jne loopstack \n"
+		"endstack: \n"
+
+	// Populate integer and floating point parameters
+		"  movq %%r10, %%rax \n"
+		"  mov     (%%rax), %%rdi \n"
+		"  mov    8(%%rax), %%rsi \n"
+		"  mov   16(%%rax), %%rdx \n"
+		"  mov   24(%%rax), %%rcx \n"
+		"  mov   32(%%rax), %%r8 \n"
+		"  mov   40(%%rax), %%r9 \n"
+		"  add   $48, %%rax \n"
+		"  movsd   (%%rax), %%xmm0 \n"
+		"  movsd  8(%%rax), %%xmm1 \n"
+		"  movsd 16(%%rax), %%xmm2 \n"
+		"  movsd 24(%%rax), %%xmm3 \n"
+		"  movsd 32(%%rax), %%xmm4 \n"
+		"  movsd 40(%%rax), %%xmm5 \n"
+		"  movsd 48(%%rax), %%xmm6 \n"
+		"  movsd 56(%%rax), %%xmm7 \n"
+
+	// Call the function
+		"  call	*%%r11 \n"
+
+	// Restore stack pointer
+		"  mov %%r15, %%rsp \n"
+	// Inform the stack unwind logic that the stack pointer has been restored
+		" .cfi_def_cfa_register rsp \n"
+
+	// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
+		"  movl %5, %%ecx \n"
+		"  testb %%cl, %%cl \n"
+		"  je intret \n"
+		"  lea %3, %%rax \n"
+		"  movq %%xmm0, (%%rax) \n"
+		"  lea %4, %%rdx \n"
+		"  movq %%xmm1, (%%rdx) \n"
+		"  jmp endcall \n"
+		"intret: \n"
+		"  movq %%rax, %3 \n"
+		"  movq %%rdx, %4 \n"
+		"endcall: \n"
+
+		: : "r" ((asQWORD)cnt), "r" (args), "r" (func), "m" (retQW1), "m" (retQW2), "m" (returnFloat)
+		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 
+		  "%rdi", "%rsi", "%rax", "%rdx", "%rcx", "%r8", "%r9", "%r10", "%r11", "%r15");
+		
+	return retQW1;
+}
+
+// returns true if the given parameter is a 'variable argument'
+static inline bool IsVariableArgument( asCDataType type )
+{
+	return ( type.GetTokenType() == ttQuestion ) ? true : false;
+}
+
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
+{
+	asCScriptEngine            *engine             = context->m_engine;
+	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
+	int                         callConv           = sysFunc->callConv;
+	asQWORD                     retQW              = 0;
+	asDWORD                    *stack_pointer      = args;
+	funcptr_t                  *vftable            = NULL;
+	int                         totalArgumentCount = 0;
+	int                         n                  = 0;
+	int                         param_post         = 0;
+	int                         argIndex           = 0;
+	funcptr_t                   func               = (funcptr_t)sysFunc->func;
+
+	if( sysFunc->hostReturnInMemory ) 
+	{
+		// The return is made in memory
+		callConv++;
+	}
+
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+	// Unpack the two object pointers
+	void **objectsPtrs  = (void**)obj;
+	void  *secondObject = objectsPtrs[1];
+	obj                 = objectsPtrs[0];
+
+	// param_post has value 2 if is an THISCALL_OBJLAST
+#endif
+
+
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
+	// Determine the real function pointer in case of virtual method
+	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) 
+#else
+	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL ||
+		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
+		callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
+#endif
+	{
+		vftable = *((funcptr_t**)obj);
+		func = vftable[FuncPtrToUInt(asFUNCTION_t(func)) >> 3];
+	}
+
+	// Determine the type of the arguments, and prepare the input array for the X64_CallFunction 
+	asQWORD  paramBuffer[X64_CALLSTACK_SIZE] = { 0 };
+	asBYTE	 argsType[X64_CALLSTACK_SIZE] = { 0 };
+
+	switch ( callConv ) 
+	{
+		case ICC_CDECL_RETURNINMEM:
+		case ICC_STDCALL_RETURNINMEM: 
+		{
+			paramBuffer[0] = (asPWORD)retPointer;
+			argsType[0] = x64INTARG;
+
+			argIndex = 1;
+
+			break;
+		}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJLAST:
+		case ICC_VIRTUAL_THISCALL_OBJLAST:
+			param_post = 2;
+#endif
+		case ICC_THISCALL:
+		case ICC_VIRTUAL_THISCALL:
+		case ICC_CDECL_OBJFIRST: 
+		{
+			paramBuffer[0] = (asPWORD)obj;
+			argsType[0] = x64INTARG;
+
+			argIndex = 1;
+
+			break;
+		}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJLAST_RETURNINMEM:
+		case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
+			param_post = 2;
+#endif
+		case ICC_THISCALL_RETURNINMEM:
+		case ICC_VIRTUAL_THISCALL_RETURNINMEM:
+		case ICC_CDECL_OBJFIRST_RETURNINMEM: 
+		{
+			paramBuffer[0] = (asPWORD)retPointer;
+			paramBuffer[1] = (asPWORD)obj;
+			argsType[0] = x64INTARG;
+			argsType[1] = x64INTARG;
+
+			argIndex = 2;
+
+			break;
+		}
+#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
+		case ICC_THISCALL_OBJFIRST:
+		case ICC_VIRTUAL_THISCALL_OBJFIRST:
+		{
+			paramBuffer[0] = (asPWORD)obj;
+			paramBuffer[1] = (asPWORD)secondObject;
+			argsType[0] = x64INTARG;
+			argsType[1] = x64INTARG;
+
+			argIndex = 2;
+			break;
+		}
+		case ICC_THISCALL_OBJFIRST_RETURNINMEM:
+		case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
+		{
+			paramBuffer[0] = (asPWORD)retPointer;
+			paramBuffer[1] = (asPWORD)obj;
+			paramBuffer[2] = (asPWORD)secondObject;
+			argsType[0] = x64INTARG;
+			argsType[1] = x64INTARG;
+			argsType[2] = x64INTARG;
+
+			argIndex = 3;
+			break;
+		}
+#endif
+		case ICC_CDECL_OBJLAST:
+			param_post = 1;
+			break;
+		case ICC_CDECL_OBJLAST_RETURNINMEM: 
+		{
+			paramBuffer[0] = (asPWORD)retPointer;
+			argsType[0] = x64INTARG;
+
+			argIndex = 1;
+			param_post = 1;
+
+			break;
+		}
+	}
+
+	int argumentCount = ( int )descr->parameterTypes.GetLength();
+	for( int a = 0; a < argumentCount; ++a ) 
+	{
+		const asCDataType &parmType = descr->parameterTypes[a];
+		if( parmType.IsFloatType() && !parmType.IsReference() ) 
+		{
+			argsType[argIndex] = x64FLOATARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(float));
+			argIndex++;
+			stack_pointer++;
+		}
+		else if( parmType.IsDoubleType() && !parmType.IsReference() ) 
+		{
+			argsType[argIndex] = x64FLOATARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(double));
+			argIndex++;
+			stack_pointer += 2;
+		}
+		else if( IsVariableArgument( parmType ) ) 
+		{
+			// The variable args are really two, one pointer and one type id
+			argsType[argIndex] = x64INTARG;
+			argsType[argIndex+1] = x64INTARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(void*));
+			memcpy(paramBuffer + argIndex + 1, stack_pointer + 2, sizeof(asDWORD));
+			argIndex += 2;
+			stack_pointer += 3;
+		}
+		else if( parmType.IsPrimitive() ||
+		         parmType.IsReference() || 
+		         parmType.IsObjectHandle() )
+		{
+			argsType[argIndex] = x64INTARG;
+			if( parmType.GetSizeOnStackDWords() == 1 )
+			{
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asDWORD));
+				stack_pointer++;
+			}
+			else
+			{
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
+				stack_pointer += 2;
+			}
+			argIndex++;
+		}
+		else
+		{
+			// An object is being passed by value
+			if( (parmType.GetObjectType()->flags & COMPLEX_MASK) ||
+			    parmType.GetSizeInMemoryDWords() > 4 )
+			{
+				// Copy the address of the object
+				argsType[argIndex] = x64INTARG;
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
+				argIndex++;
+			}
+			else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLINTS) ||
+			         (parmType.GetObjectType()->flags & asOBJ_APP_PRIMITIVE) )
+			{
+				// Copy the value of the object
+				if( parmType.GetSizeInMemoryDWords() > 2 )
+				{
+					argsType[argIndex] = x64INTARG;
+					argsType[argIndex+1] = x64INTARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
+					argIndex += 2;
+				}
+				else
+				{
+					argsType[argIndex] = x64INTARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
+					argIndex++;
+				}
+				// Delete the original memory
+				engine->CallFree(*(void**)stack_pointer);
+			}
+			else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS) ||
+			         (parmType.GetObjectType()->flags & asOBJ_APP_FLOAT) )
+			{
+				// Copy the value of the object
+				if( parmType.GetSizeInMemoryDWords() > 2 )
+				{
+					argsType[argIndex] = x64FLOATARG;
+					argsType[argIndex+1] = x64FLOATARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
+					argIndex += 2;
+				}
+				else
+				{
+					argsType[argIndex] = x64FLOATARG;
+					memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
+					argIndex++;
+				}
+				// Delete the original memory
+				engine->CallFree(*(void**)stack_pointer);
+			}
+			stack_pointer += 2;
+		}
+	}
+
+	// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
+	if( param_post )
+	{
+#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
+		paramBuffer[argIndex] = (asPWORD)obj;
+#else
+		paramBuffer[argIndex] = (asPWORD)(param_post > 1 ? secondObject : obj);
+#endif
+		argsType[argIndex] = x64INTARG;
+		argIndex++;
+	}
+
+	totalArgumentCount = argIndex;
+
+	/*
+	 * Q: WTF is going on here !?
+	 *
+	 * A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
+	 * it's little magic which must work regardless of how the compiler decides to
+	 * allocate registers. Basically:
+	 * - the first MAX_CALL_INT_REGISTERS entries in tempBuff will
+	 *   contain the values/types of the x64INTARG parameters - that is the ones who
+	 *   go into the registers. If the function has less then MAX_CALL_INT_REGISTERS
+	 *   integer parameters then the last entries will be set to 0
+	 * - the next MAX_CALL_SSE_REGISTERS entries will contain the float/double arguments
+	 *   that go into the floating point registers. If the function has less than
+	 *   MAX_CALL_SSE_REGISTERS floating point parameters then the last entries will
+	 *   be set to 0
+	 * - index MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS marks the start of the
+	 *   parameters which will get passed on the stack. These are added to the array
+	 *   in reverse order so that X64_CallFunction() can simply push them to the stack
+	 *   without the need to perform further tests
+	 */
+	asQWORD tempBuff[X64_CALLSTACK_SIZE] = { 0 };
+	asBYTE  argsSet[X64_CALLSTACK_SIZE]  = { 0 };
+	int     used_int_regs   = 0;
+	int     used_sse_regs   = 0;
+	int     used_stack_args = 0;
+	int     idx             = 0;
+	for ( n = 0; ( n < totalArgumentCount ) && ( used_int_regs < MAX_CALL_INT_REGISTERS ); n++ ) 
+	{
+		if ( argsType[n] == x64INTARG ) 
+		{
+			argsSet[n] = 1;
+			tempBuff[idx++] = paramBuffer[n];
+			used_int_regs++;
+		}
+	}
+	idx = MAX_CALL_INT_REGISTERS;
+	for ( n = 0; ( n < totalArgumentCount ) && ( used_sse_regs < MAX_CALL_SSE_REGISTERS ); n++ ) 
+	{
+		if ( argsType[n] == x64FLOATARG ) 
+		{
+			argsSet[n] = 1;
+			tempBuff[idx++] = paramBuffer[n];
+			used_sse_regs++;
+		}
+	}
+	idx = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS;
+	for ( n = totalArgumentCount - 1; n >= 0; n-- ) 
+	{
+		if ( !argsSet[n] ) 
+		{
+			tempBuff[idx++] = paramBuffer[n];
+			used_stack_args++;
+		}
+	}
+
+	retQW = X64_CallFunction( tempBuff, used_stack_args, func, retQW2, sysFunc->hostReturnFloat );
+
+	return retQW;
+}
+
+END_AS_NAMESPACE
+
+#endif // AS_X64_GCC
+#endif // AS_MAX_PORTABILITY
+

+ 30 - 9
Source/ThirdParty/AngelScript/source/as_compiler.cpp

@@ -195,7 +195,7 @@ int asCCompiler::CompileFactory(asCBuilder *builder, asCScriptCode *script, asCS
 		}
 	}
 
-	// Allocate the class and instanciate it with the constructor
+	// Allocate the class and instantiate it with the constructor
 	int varOffset = AllocateVariable(dt, true);
 
 	outFunc->scriptData->variableSpace = AS_PTR_SIZE;
@@ -341,8 +341,8 @@ int asCCompiler::SetupParametersAndReturnVariable(asCArray<asCString> &parameter
 	}
 
 	// Is the return type allowed?
-	if( (!returnType.CanBeInstanciated() && returnType != asCDataType::CreatePrimitive(ttVoid, false)) ||
-		(returnType.IsReference() && !returnType.CanBeInstanciated()) )
+	if( returnType != asCDataType::CreatePrimitive(ttVoid, false) &&
+		!returnType.CanBeInstantiated() )
 	{
 		// TODO: Hasn't this been validated by the builder already?
 		asCString str;
@@ -368,8 +368,8 @@ int asCCompiler::SetupParametersAndReturnVariable(asCArray<asCString> &parameter
 
 		// Is the data type allowed?
 		// TODO: Hasn't this been validated by the builder already?
-		if( (type.IsReference() && inoutFlag != asTM_INOUTREF && !type.CanBeInstanciated()) ||
-			(!type.IsReference() && !type.CanBeInstanciated()) )
+		if( (type.IsReference() && inoutFlag != asTM_INOUTREF && !type.CanBeInstantiated()) ||
+			(!type.IsReference() && !type.CanBeInstantiated()) )
 		{
 			asCString parm = type.Format();
 			if( inoutFlag == asTM_INREF )
@@ -1804,6 +1804,7 @@ void asCCompiler::PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asSE
 
 	// If the function being called is the opAssign or copy constructor for the same type
 	// as the argument, then we should avoid making temporary copy of the argument
+	asASSERT( descr->parameterTypes.GetLength() == args.GetLength() );
 	bool makingCopy = false;
 	if( descr->parameterTypes.GetLength() == 1 &&
 		descr->parameterTypes[0].IsEqualExceptRefAndConst(args[0]->type.dataType) &&
@@ -2521,11 +2522,16 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 			preCompiled = CompileAutoType(type, compiledCtx, node->next, node);
 
 		// Is the type allowed?
-		if( !type.CanBeInstanciated() )
+		if( !type.CanBeInstantiated() )
 		{
 			asCString str;
-			// TODO: Change to "'type' cannot be declared as variable"
-			str.Format(TXT_DATA_TYPE_CANT_BE_s, type.Format().AddressOf());
+			if( type.IsAbstractClass() )
+				str.Format(TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED, type.Format().AddressOf());
+			else if( type.IsInterface() )
+				str.Format(TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED, type.Format().AddressOf());
+			else
+				// TODO: Improve error message to explain why
+				str.Format(TXT_DATA_TYPE_CANT_BE_s, type.Format().AddressOf());
 			Error(str, node);
 
 			// Use int instead to avoid further problems
@@ -5960,7 +5966,7 @@ asUINT asCCompiler::ImplicitConvObjectRef(asSExprContext *ctx, const asCDataType
 
 	asASSERT(ctx->type.dataType.GetObjectType() || ctx->methodName != "");
 
-	// First attempt to convert the base type without instanciating another instance
+	// First attempt to convert the base type without instantiating another instance
 	if( to.GetObjectType() != ctx->type.dataType.GetObjectType() && ctx->methodName == "" )
 	{
 		// If the to type is an interface and the from type implements it, then we can convert it immediately
@@ -9209,6 +9215,21 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 		return;
 	}
 
+	if( !dt.CanBeInstantiated() )
+	{
+		asCString str;
+		if( dt.IsAbstractClass() )
+			str.Format(TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+		else if( dt.IsInterface() )
+			str.Format(TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED, dt.Format().AddressOf());
+		else
+			// TODO: Improve error message to explain why
+			str.Format(TXT_DATA_TYPE_CANT_BE_s, dt.Format().AddressOf());
+		Error(str, node);
+		ctx->type.SetDummy();
+		return;
+	}
+
 	// Do not allow constructing non-shared types in shared functions
 	if( outFunc->IsShared() &&
 		dt.GetObjectType() && !dt.GetObjectType()->IsShared() )

+ 30 - 10
Source/ThirdParty/AngelScript/source/as_datatype.cpp

@@ -348,19 +348,39 @@ bool asCDataType::SupportHandles() const
 	return false;
 }
 
-bool asCDataType::CanBeInstanciated() const
-{
-	if( GetSizeOnStackDWords() == 0 ||
-		(IsObject() && 
-		 (objectType->flags & asOBJ_REF) &&        // It's a ref type and
-		 ((objectType->flags & asOBJ_NOHANDLE) ||  // the ref type doesn't support handles or
-		  (!IsObjectHandle() &&                    // it's not a handle and
-		   objectType->beh.factories.GetLength() == 0))) ) // the ref type cannot be instanciated
+bool asCDataType::CanBeInstantiated() const
+{
+	if( GetSizeOnStackDWords() == 0 ) // Void
+		return false;
+
+	if( !IsObject() ) // Primitives
+		return true; 
+
+	if( IsObjectHandle() && !(objectType->flags & asOBJ_NOHANDLE) ) // Handles
+		return true;
+
+	if( funcDef ) // Funcdefs can be instantiated as delegates
+		 return true;
+
+	if( (objectType->flags & asOBJ_REF) && objectType->beh.factories.GetLength() == 0 ) // ref types without factories
+		return false;
+
+	if( (objectType->flags & asOBJ_ABSTRACT) && !IsObjectHandle() ) // Can't instantiate abstract classes
 		return false;
 
 	return true;
 }
 
+bool asCDataType::IsAbstractClass() const
+{
+	return objectType && (objectType->flags & asOBJ_ABSTRACT) ? true : false;
+}
+
+bool asCDataType::IsInterface() const
+{
+	return objectType && objectType->IsInterface();
+}
+
 bool asCDataType::CanBeCopied() const
 {
 	// All primitives can be copied
@@ -369,8 +389,8 @@ bool asCDataType::CanBeCopied() const
 	// Plain-old-data structures can always be copied
 	if( objectType->flags & asOBJ_POD ) return true;
 
-	// It must be possible to instanciate the type
-	if( !CanBeInstanciated() ) return false;
+	// It must be possible to instantiate the type
+	if( !CanBeInstantiated() ) return false;
 
 	// It must have a default constructor or factory
 	if( objectType->beh.construct == 0 &&

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

@@ -96,6 +96,8 @@ public:
 	bool IsEnumType()             const;
 	bool IsAnyType()              const {return tokenType == ttQuestion;}
 	bool IsHandleToAsHandleType() const {return isHandleToAsHandleType;}
+	bool IsAbstractClass()        const;
+	bool IsInterface()            const;
 
 	bool IsObjectConst()    const;
 
@@ -105,7 +107,7 @@ public:
 	bool IsNullHandle()                                    const;
 
 	bool SupportHandles() const;
-	bool CanBeInstanciated() const;
+	bool CanBeInstantiated() const;
 	bool CanBeCopied() const;
 
 	bool operator ==(const asCDataType &) const;

+ 3 - 3
Source/ThirdParty/AngelScript/source/as_module.cpp

@@ -351,8 +351,8 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 		{
 			if( ctx == 0 )
 			{
-				r = engine->CreateContext(&ctx, true);
-				if( r < 0 )
+				ctx = engine->RequestContext();
+				if( ctx == 0 )
 					break;
 			}
 
@@ -391,7 +391,7 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 
 	if( ctx && !myCtx )
 	{
-		ctx->Release();
+		engine->ReturnContext(ctx);
 		ctx = 0;
 	}
 

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

@@ -713,7 +713,7 @@ asDWORD asCObjectType::GetAccessMask() const
 asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
 {
 	asASSERT( flags & asOBJ_SCRIPT_OBJECT );
-	asASSERT( dt.CanBeInstanciated() );
+	asASSERT( dt.CanBeInstantiated() );
 	asASSERT( !IsInterface() );
 
 	// Store the properties in the object type descriptor

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

@@ -851,6 +851,15 @@ void asCParser::Error(const asCString &text, sToken *token)
 		builder->WriteError(script->name, text, row, col);
 }
 
+void asCParser::Warning(const asCString &text, sToken *token)
+{
+	int row, col;
+	script->ConvertPosToRowCol(token->pos, &row, &col);
+
+	if( builder )
+		builder->WriteWarning(script->name, text, row, col);
+}
+
 void asCParser::Info(const asCString &text, sToken *token)
 {
 	RewindTo(token);
@@ -1238,14 +1247,25 @@ asCScriptNode *asCParser::ParseExprValue()
 			else 
 				break;
 		}
+
+		bool isDataType = IsDataType(t2);
+		bool isTemplateType = false;
+		if( isDataType )
+		{
+			// Is this a template type?
+			tempString.Assign(&script->code[t2.pos], t2.length);
+			if( engine->IsTemplateType(tempString.AddressOf()) )
+				isTemplateType = true;
+		}
 		
 		// Rewind so the real parsing can be done, after deciding what to parse
 		RewindTo(&t1);
 
 		// Check if this is a construct call
-		if( IsDataType(t2) && (t.type == ttOpenParanthesis || 
-		                       t.type == ttLessThan || 
-		                       t.type == ttOpenBracket) )
+		if( isDataType && (t.type == ttOpenParanthesis ||  // type()
+			               t.type == ttOpenBracket) )      // type[]()
+			node->AddChildLast(ParseConstructCall());
+		else if( isTemplateType && t.type == ttLessThan )  // type<t>()
 			node->AddChildLast(ParseConstructCall());
 		else if( IsFunctionCall() )
 			node->AddChildLast(ParseFunctionCall());
@@ -1425,14 +1445,17 @@ asCScriptNode *asCParser::ParseArgList(bool withParenthesis)
 		for(;;)
 		{
 			// Determine if this is a named argument
-			// Careful not to mistake 'type = {init list}' as named argument
-			sToken tl, t2, t3;
+			sToken tl, t2;
 			GetToken(&tl);
 			GetToken(&t2);
-			GetToken(&t3);
 			RewindTo(&tl);
 
-			if( tl.type == ttIdentifier && t2.type == ttAssignment && t3.type != ttStartStatementBlock )
+			// Named arguments uses the syntax: arg : expr
+			// This avoids confusion when the argument has the same name as a local variable, i.e. var = expr
+			// It also avoids conflict with expressions to that creates anonymous objects initialized with lists, i.e. type = {...}
+			// The alternate syntax: arg = expr, is supported to provide backwards compatibility with 2.29.0
+			// TODO: 3.0.0: Remove the alternate syntax
+			if( tl.type == ttIdentifier && (t2.type == ttColon || (engine->ep.alterSyntaxNamedArgs && t2.type == ttAssignment)) )
 			{
 				asCScriptNode *named = CreateNode(snNamedArgument);
 				if( named == 0 ) return 0;
@@ -1440,7 +1463,9 @@ asCScriptNode *asCParser::ParseArgList(bool withParenthesis)
 
 				named->AddChildLast(ParseIdentifier());
 				GetToken(&t2);
-				asASSERT( t2.type == ttAssignment );
+
+				if( engine->ep.alterSyntaxNamedArgs == 1 && t2.type == ttAssignment )
+					Warning(TXT_NAMED_ARGS_WITH_OLD_SYNTAX, &t2);
 
 				named->AddChildLast(ParseAssignment());
 			}
@@ -1978,8 +2003,8 @@ asCScriptNode *asCParser::ParseScript(bool inBlock)
 			else if( t1.type == ttTypedef )
 				node->AddChildLast(ParseTypedef());		// Handle primitive typedefs
 			else if( t1.type == ttClass || 
-					 ((IdentifierIs(t1, SHARED_TOKEN) || IdentifierIs(t1, FINAL_TOKEN)) && t2.type == ttClass) || 
-					 (IdentifierIs(t1, SHARED_TOKEN) && IdentifierIs(t2, FINAL_TOKEN)) )
+					((IdentifierIs(t1, SHARED_TOKEN) || IdentifierIs(t1, FINAL_TOKEN) || IdentifierIs(t1, ABSTRACT_TOKEN)) && t2.type == ttClass) || 
+					 (IdentifierIs(t1, SHARED_TOKEN) && (IdentifierIs(t2, FINAL_TOKEN) || IdentifierIs(t2, ABSTRACT_TOKEN))) )
 				node->AddChildLast(ParseClass());
 			else if( t1.type == ttMixin )
 				node->AddChildLast(ParseMixin());
@@ -2298,8 +2323,10 @@ bool asCParser::IsVarDecl()
 	}
 
 	// Object handles can be interleaved with the array brackets
+	// Even though declaring variables with & is invalid we'll accept 
+	// it here to give an appropriate error message later
 	GetToken(&t2);
-	while( t2.type == ttHandle || t2.type == ttOpenBracket )
+	while( t2.type == ttHandle || t2.type == ttAmp || t2.type == ttOpenBracket )
 	{
 		if( t2.type == ttOpenBracket )
 		{
@@ -2679,6 +2706,7 @@ asCScriptNode *asCParser::ParseFunction(bool isMethod)
 		if( t1.type == ttConst )
 			node->AddChildLast(ParseToken(ttConst));
 
+		// TODO: Should support abstract methods, in which case no statement block should be provided
 		ParseMethodOverrideBehaviors(node);
 		if( isSyntaxError ) return node;
 	}
@@ -2958,15 +2986,10 @@ asCScriptNode *asCParser::ParseClass()
 	sToken t;
 	GetToken(&t);
 
-	// Allow the keyword 'shared' before 'class'
-	if( IdentifierIs(t, SHARED_TOKEN) )
-	{
-		RewindTo(&t);
-		node->AddChildLast(ParseIdentifier());
-		GetToken(&t);
-	}
-
-	if( IdentifierIs(t, FINAL_TOKEN) )
+	// Allow the keywords 'shared', 'abstract', and 'final' before 'class'
+	while( IdentifierIs(t, SHARED_TOKEN) ||
+		   IdentifierIs(t, ABSTRACT_TOKEN) ||
+		   IdentifierIs(t, FINAL_TOKEN) )
 	{
 		RewindTo(&t);
 		node->AddChildLast(ParseIdentifier());
@@ -3563,7 +3586,14 @@ asCScriptNode *asCParser::ParseStatement()
 	else if( t1.type == ttSwitch )
 		return ParseSwitch();
 	else
+	{
+		if( IsVarDecl() )
+		{
+			Error(TXT_UNEXPECTED_VAR_DECL, &t1);
+			return 0;
+		}
 		return ParseExpressionStatement();
+	}
 }
 
 asCScriptNode *asCParser::ParseExpressionStatement()

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

@@ -76,6 +76,7 @@ protected:
 	void RewindTo(const sToken *token);
 	void SetPos(size_t pos);
 	void Error(const asCString &text, sToken *token);
+	void Warning(const asCString &text, sToken *token);
 	void Info(const asCString &text, sToken *token);
 
 	asCScriptNode *CreateNode(eScriptNode type);

+ 27 - 9
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -784,7 +784,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	ReadFunctionSignature(func);
 	if( error )
 	{
-		asDELETE(func, asCScriptFunction);
+		func->DestroyHalfCreated();
 		return 0;
 	}
 
@@ -795,7 +795,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 		{
 			// Out of memory
 			error = true;
-			asDELETE(func, asCScriptFunction);
+			func->DestroyHalfCreated();
 			return 0;
 		}
 
@@ -817,6 +817,13 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			func->scriptData->funcVariableTypes.PushLast((asCScriptFunction*)(asPWORD)idx);
 			num = ReadEncodedUInt();
 			func->scriptData->objVariablePos.PushLast(num);
+
+			if( error )
+			{
+				// No need to continue (the error has already been reported before)
+				func->DestroyHalfCreated();
+				return 0;
+			}
 		}
 		if( count > 0 )
 			func->scriptData->objVariablesOnHeap = ReadEncodedUInt();
@@ -840,7 +847,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			{
 				// Out of memory
 				error = true;
-				asDELETE(func, asCScriptFunction);
+				func->DestroyHalfCreated();
 				return 0;
 			}
 			for( i = 0; i < length; ++i )
@@ -853,7 +860,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			{
 				// Out of memory
 				error = true;
-				asDELETE(func, asCScriptFunction);
+				func->DestroyHalfCreated();
 				return 0;
 			}
 			for( i = 0; i < length; ++i )
@@ -881,7 +888,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 				{
 					// Out of memory
 					error = true;
-					asDELETE(func, asCScriptFunction);
+					func->DestroyHalfCreated();
 					return 0;
 				}
 				func->scriptData->variables.PushLast(var);
@@ -890,6 +897,13 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 				var->stackOffset = ReadEncodedUInt();
 				ReadString(&var->name);
 				ReadDataType(&var->type);
+
+				if( error )
+				{
+					// No need to continue (the error has already been reported before)
+					func->DestroyHalfCreated();
+					return 0;
+				}
 			}
 		}
 
@@ -914,7 +928,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 			if( count > func->parameterTypes.GetLength() )
 			{
 				error = true;
-				asDELETE(func, asCScriptFunction);
+				func->DestroyHalfCreated();
 				return 0;
 			}
 			func->parameterNames.SetLength(count);
@@ -1640,9 +1654,12 @@ asCObjectType* asCReader::ReadObjectType()
 	if( ch == 'a' )
 	{
 		// Read the name of the template type
-		asCString typeName;
+		asCString typeName, ns;
 		ReadString(&typeName);
-		asCObjectType *tmpl = engine->GetRegisteredObjectType(typeName.AddressOf(), engine->nameSpaces[0]);
+		ReadString(&ns);
+		asSNameSpace *nameSpace = engine->AddNameSpace(ns.AddressOf());
+
+		asCObjectType *tmpl = engine->GetRegisteredObjectType(typeName.AddressOf(), nameSpace);
 		if( tmpl == 0 )
 		{
 			asCString str;
@@ -1770,7 +1787,7 @@ asCObjectType* asCReader::ReadObjectType()
 	else
 	{
 		// No object type
-		asASSERT( ch == '\0' );
+		asASSERT( ch == '\0' || error );
 		ot = 0;
 	}
 
@@ -3823,6 +3840,7 @@ void asCWriter::WriteObjectType(asCObjectType* ot)
 				ch = 'a';
 				WriteData(&ch, 1);
 				WriteString(&ot->name);
+				WriteString(&ot->nameSpace->name);
 
 				WriteEncodedInt64(ot->templateSubTypes.GetLength());
 				for( asUINT n = 0; n < ot->templateSubTypes.GetLength(); n++ )

+ 109 - 30
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -58,7 +58,7 @@ BEGIN_AS_NAMESPACE
 
 
 #ifdef AS_PROFILE
-// Instanciate the profiler once
+// Instantiate the profiler once
 CProfiler g_profiler;
 #endif
 
@@ -370,6 +370,13 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
 		ep.disallowValueAssignForRefType = value ? true : false;
 		break;
 
+	case asEP_ALTER_SYNTAX_NAMED_ARGS:
+		if( value <= 2 )
+			ep.alterSyntaxNamedArgs = (int)value;
+		else
+			return asINVALID_ARG;
+		break;
+
 	default:
 		return asINVALID_ARG;
 	}
@@ -442,6 +449,9 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 	case asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE:
 		return ep.disallowValueAssignForRefType;
 
+	case asEP_ALTER_SYNTAX_NAMED_ARGS:
+		return ep.alterSyntaxNamedArgs;
+
 	default:
 		return 0;
 	}
@@ -499,6 +509,7 @@ asCScriptEngine::asCScriptEngine()
 		ep.compilerWarnings              = 1;         // 0 = no warnings, 1 = warning, 2 = treat as error
 		// TODO: 3.0.0: disallowValueAssignForRefType should be true by default
 		ep.disallowValueAssignForRefType = false;
+		ep.alterSyntaxNamedArgs          = 0;         // 0 = no alternate syntax, 1 = accept alternate syntax but warn, 2 = accept without warning
 	}
 
 	gc.engine = this;
@@ -572,6 +583,12 @@ asCScriptEngine::~asCScriptEngine()
 	asASSERT(refCount.get() == 0);
 	asUINT n;
 
+	// Clear the context callbacks. If new context's are needed for the clean-up the engine will take care of this itself.
+	// Context callbacks are normally used for pooling contexts, and if we allow new contexts to be created without being
+	// immediately destroyed afterwards it means the engine's refcount will increase. This is turn may cause memory access
+	// violations later on when the pool releases its contexts.
+	SetContextCallbacks(0, 0, 0);
+
 	// The modules must be deleted first, as they may use
 	// object types from the config groups
 	for( n = (asUINT)scriptModules.GetLength(); n-- > 0; )
@@ -652,6 +669,11 @@ asCScriptEngine::~asCScriptEngine()
 	GarbageCollect();
 	ClearUnusedTypes();
 
+	// It is allowed to create new references to the engine temporarily while destroying objects
+	// but these references must be release immediately or else something is can go wrong later on
+	if( refCount.get() > 0 )
+		WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_ENGINE_REF_COUNT_ERROR_DURING_SHUTDOWN);
+
 	// If the application hasn't registered GC behaviours for all types
 	// that can form circular references with script types, then there
 	// may still be objects in the GC.
@@ -796,7 +818,8 @@ void asCScriptEngine::CleanupAfterDiscardModule()
 // interface
 int asCScriptEngine::SetContextCallbacks(asREQUESTCONTEXTFUNC_t requestCtx, asRETURNCONTEXTFUNC_t returnCtx, void *param)
 {
-	if( requestCtx == 0 || returnCtx == 0 )
+	// Both callbacks or neither must be set
+	if( (requestCtx == 0 && returnCtx != 0) || (requestCtx != 0 && returnCtx == 0) )
 		return asINVALID_ARG;
 
 	requestCtxFunc   = requestCtx;
@@ -1304,7 +1327,7 @@ int asCScriptEngine::GetFactoryIdByDecl(const asCObjectType *ot, const char *dec
 	asCModule *mod = 0;
 
 	// Is this a script class?
-	if( ot->flags & asOBJ_SCRIPT_OBJECT && ot->size > 0 )
+	if( (ot->flags & asOBJ_SCRIPT_OBJECT) && ot->size > 0 )
 		mod = scriptFunctions[ot->beh.factories[0]]->module;
 
 	asCBuilder bld(this, mod);
@@ -1511,7 +1534,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
 		return ConfigError(asOUT_OF_MEMORY, "RegisterInterface", name, 0);
 
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT | asOBJ_SHARED;
-	st->size = 0; // Cannot be instanciated
+	st->size = 0; // Cannot be instantiated
 	st->name = name;
 	st->nameSpace = defaultNamespace;
 
@@ -1625,12 +1648,11 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 	else if( flags & asOBJ_VALUE )
 	{
 		// Cannot use reference flags
-		// TODO: template: Should be possible to register a value type as template type
-		if( flags & (asOBJ_REF | asOBJ_GC | asOBJ_NOHANDLE | asOBJ_SCOPED | asOBJ_TEMPLATE | asOBJ_NOCOUNT) )
+		if( flags & (asOBJ_REF | asOBJ_GC | asOBJ_NOHANDLE | asOBJ_SCOPED | asOBJ_NOCOUNT) )
 			return ConfigError(asINVALID_ARG, "RegisterObjectType", name, 0);
 
-		// flags are exclusive
-		if( (flags & asOBJ_POD) && (flags & asOBJ_ASHANDLE) )
+		// Flags are exclusive
+		if( (flags & asOBJ_POD) && (flags & (asOBJ_ASHANDLE | asOBJ_TEMPLATE)) )
 			return ConfigError(asINVALID_ARG, "RegisterObjectType", name, 0);
 
 		// If the app type is given, we must validate the flags
@@ -2010,12 +2032,22 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
 				return ConfigError(asILLEGAL_BEHAVIOUR_FOR_TYPE, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
 			}
 
+			// The templates take a hidden parameter with the object type
+			if( (objectType->flags & asOBJ_TEMPLATE) &&
+				(func.parameterTypes.GetLength() == 0 ||
+				 !func.parameterTypes[0].IsReference()) )
+			{
+				WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_FIRST_PARAM_MUST_BE_REF_FOR_TEMPLATE_FACTORY);
+				return ConfigError(asINVALID_DECLARATION, "RegisterObjectBehaviour", objectType->name.AddressOf(), decl);
+			}
+
 			// TODO: Verify that the same constructor hasn't been registered already
 
 			// Store all constructors in a list
 			func.id = AddBehaviourFunction(func, internal);
 			beh->constructors.PushLast(func.id);
-			if( func.parameterTypes.GetLength() == 0 )
+			if( func.parameterTypes.GetLength() == 0 ||
+				(func.parameterTypes.GetLength() == 1 && (objectType->flags & asOBJ_TEMPLATE)) )
 			{
 				beh->construct = func.id;
 			}
@@ -2826,7 +2858,7 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 	// TODO: beh.copy member will be removed, so this is not necessary
 	// Is this the default copy behaviour?
 	if( func->name == "opAssign" && func->parameterTypes.GetLength() == 1 && func->isReadOnly == false &&
-		(objectType->flags & asOBJ_SCRIPT_OBJECT || func->parameterTypes[0].IsEqualExceptRefAndConst(asCDataType::CreateObject(func->objectType, false))) )
+		((objectType->flags & asOBJ_SCRIPT_OBJECT) || func->parameterTypes[0].IsEqualExceptRefAndConst(asCDataType::CreateObject(func->objectType, false))) )
 	{
 		if( func->objectType->beh.copy != 0 )
 			return ConfigError(asALREADY_REGISTERED, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
@@ -3433,6 +3465,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	ot->flags            = templateType->flags;
 	ot->size             = templateType->size;
 	ot->name             = templateType->name;
+	ot->nameSpace        = templateType->nameSpace;
 
 	// The template instance type will inherit the same module as the subType
 	// This will allow the module to orphan the template instance types afterwards
@@ -3461,7 +3494,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 			bool dontGarbageCollect = false;
 			if( !CallGlobalFunctionRetBool(ot, &dontGarbageCollect, callback->sysFuncIntf, callback) )
 			{
-				// The type cannot be instanciated
+				// The type cannot be instantiated
 				ot->templateSubTypes.SetLength(0);
 				asDELETE(ot, asCObjectType);
 				return 0;
@@ -3480,14 +3513,22 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	for( n = 0; n < ot->methods.GetLength(); n++ )
 		scriptFunctions[ot->methods[n]]->AddRef();
 
-	// Store the real factory in the constructor. This is used by the CreateScriptObject function.
-	// Otherwise it wouldn't be necessary to store the real factory ids.
-	ot->beh.construct = templateType->beh.factory;
-	ot->beh.constructors = templateType->beh.factories;
+	if( templateType->flags & asOBJ_REF )
+	{
+		// Store the real factory in the constructor. This is used by the CreateScriptObject function.
+		// Otherwise it wouldn't be necessary to store the real factory ids.
+		ot->beh.construct = templateType->beh.factory;
+		ot->beh.constructors = templateType->beh.factories;
+	}
+	else
+	{
+		ot->beh.construct = templateType->beh.construct;
+		ot->beh.constructors = templateType->beh.constructors;
+	}
 	for( n = 0; n < ot->beh.constructors.GetLength(); n++ )
 		scriptFunctions[ot->beh.constructors[n]]->AddRef();
 
-	// As the new template type is instanciated the engine should
+	// As the new template type is instantiated the engine should
 	// generate new functions to substitute the ones with the template subtype.
 	for( n = 0; n < ot->beh.constructors.GetLength(); n++ )
 	{
@@ -3507,17 +3548,37 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 
 	ot->beh.factory = 0;
 
-	// Generate factory stubs for each of the factories
-	for( n = 0; n < ot->beh.constructors.GetLength(); n++ )
+	if( templateType->flags & asOBJ_REF )
+	{
+		// Generate factory stubs for each of the factories
+		for( n = 0; n < ot->beh.constructors.GetLength(); n++ )
+		{
+			asCScriptFunction *func = GenerateTemplateFactoryStub(templateType, ot, ot->beh.constructors[n]);
+
+			// The function's refCount was already initialized to 1
+			ot->beh.factories.PushLast(func->id);
+
+			// Set the default factory as well
+			if( ot->beh.constructors[n] == ot->beh.construct )
+				ot->beh.factory = func->id;
+		}
+	}
+	else
 	{
-		asCScriptFunction *func = GenerateTemplateFactoryStub(templateType, ot, ot->beh.constructors[n]);
+		// Generate factory stubs for each of the constructors
+		for( n = 0; n < ot->beh.constructors.GetLength(); n++ )
+		{
+			asCScriptFunction *func = GenerateTemplateFactoryStub(templateType, ot, ot->beh.constructors[n]);
 
-		// The function's refCount was already initialized to 1
-		ot->beh.factories.PushLast(func->id);
+			// The function's refCount was already initialized to 1
+			if( ot->beh.constructors[n] == ot->beh.construct )
+				ot->beh.construct = func->id;
+
+			// Release previous constructor
+			scriptFunctions[ot->beh.constructors[n]]->Release();
 
-		// Set the default factory as well
-		if( ot->beh.constructors[n] == ot->beh.construct )
-			ot->beh.factory = func->id;
+			ot->beh.constructors[n] = func->id;
+		}
 	}
 
 	// Generate stub for the list factory as well
@@ -3533,6 +3594,8 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	if( scriptFunctions[ot->beh.addref] ) scriptFunctions[ot->beh.addref]->AddRef();
 	ot->beh.release = templateType->beh.release;
 	if( scriptFunctions[ot->beh.release] ) scriptFunctions[ot->beh.release]->AddRef();
+	ot->beh.destruct = templateType->beh.destruct;
+	if( scriptFunctions[ot->beh.destruct] ) scriptFunctions[ot->beh.destruct]->AddRef();
 	ot->beh.copy = templateType->beh.copy;
 	if( scriptFunctions[ot->beh.copy] ) scriptFunctions[ot->beh.copy]->AddRef();
 	ot->beh.operators = templateType->beh.operators;
@@ -3551,7 +3614,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 	ot->beh.getWeakRefFlag = templateType->beh.getWeakRefFlag;
 	if( scriptFunctions[ot->beh.getWeakRefFlag] ) scriptFunctions[ot->beh.getWeakRefFlag]->AddRef();
 
-	// As the new template type is instanciated the engine should
+	// As the new template type is instantiated the engine should
 	// generate new functions to substitute the ones with the template subtype.
 	for( n = 1; n < ot->beh.operators.GetLength(); n += 2 )
 	{
@@ -3566,7 +3629,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
 		}
 	}
 
-	// As the new template type is instanciated, the engine should
+	// As the new template type is instantiated, the engine should
 	// generate new functions to substitute the ones with the template subtype.
 	for( n = 0; n < ot->methods.GetLength(); n++ )
 	{
@@ -3679,8 +3742,16 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
 	func->AllocateScriptFunctionData();
 	func->name             = "factstub";
 	func->id               = GetNextScriptFunctionId();
-	func->returnType       = asCDataType::CreateObjectHandle(ot, false);
 	func->isShared         = true;
+	if( templateType->flags & asOBJ_REF )
+	{
+		func->returnType   = asCDataType::CreateObjectHandle(ot, false);
+	}
+	else
+	{
+		func->returnType   = factory->returnType; // constructors return nothing
+		func->objectType   = ot;
+	}
 
 	// Skip the first parameter as this is the object type pointer that the stub will add
 	func->parameterTypes.SetLength(factory->parameterTypes.GetLength()-1);
@@ -3701,6 +3772,8 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
 
 	if( ep.includeJitInstructions )
 		bcLength += asBCTypeSize[asBCInfo[asBC_JitEntry].type];
+	if( templateType->flags & asOBJ_VALUE )
+		bcLength += asBCTypeSize[asBCInfo[asBC_SwapPtr].type];
 
 	func->scriptData->byteCode.SetLength(bcLength);
 	asDWORD *bc = func->scriptData->byteCode.AddressOf();
@@ -3715,6 +3788,12 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
 	*(asBYTE*)bc = asBC_OBJTYPE;
 	*(asPWORD*)(bc+1) = (asPWORD)ot;
 	bc += asBCTypeSize[asBCInfo[asBC_OBJTYPE].type];
+	if( templateType->flags & asOBJ_VALUE )
+	{
+		// Swap the object pointer with the object type
+		*(asBYTE*)bc = asBC_SwapPtr;
+		bc += asBCTypeSize[asBCInfo[asBC_SwapPtr].type];
+	}
 	*(asBYTE*)bc = asBC_CALLSYS;
 	*(asDWORD*)(bc+1) = factoryId;
 	bc += asBCTypeSize[asBCInfo[asBC_CALLSYS].type];
@@ -3795,9 +3874,9 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
 	for( asUINT p = 0; p < func->parameterTypes.GetLength(); p++ )
 		func2->parameterTypes[p] = DetermineTypeForTemplate(func->parameterTypes[p], templateType, ot);
 
-	// TODO: template: Must be careful when instanciating templates for garbage collected types
+	// TODO: template: Must be careful when instantiating templates for garbage collected types
 	//                 If the template hasn't been registered with the behaviours, it shouldn't
-	//                 permit instanciation of garbage collected types that in turn may refer to
+	//                 permit instantiation of garbage collected types that in turn may refer to
 	//                 this instance.
 
 	func2->inOutFlags = func->inOutFlags;
@@ -4513,7 +4592,7 @@ void *asCScriptEngine::CreateScriptObject(const asIObjectType *type)
 	else if( objType->flags & asOBJ_TEMPLATE )
 	{
 		// The registered factory that takes the object type is moved
-		// to the construct behaviour when the type is instanciated
+		// to the construct behaviour when the type is instantiated
 #ifdef AS_NO_EXCEPTIONS
 		ptr = CallGlobalFunctionRetPtr(objType->beh.construct, objType);
 #else

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

@@ -343,7 +343,7 @@ public:
 
 	// Store information about template types
 	// This list will contain all instances of templates, both registered specialized 
-	// types and those automacially instanciated from scripts
+	// types and those automacially instantiated from scripts
 	asCArray<asCObjectType *>      templateInstanceTypes;
 
 	// Store information about list patterns
@@ -375,7 +375,7 @@ public:
 	bool                   isBuilding;
 	bool                   deferValidationOfTemplateTypes;
 
-	// Tokenizer is instanciated once to share resources
+	// Tokenizer is instantiated once to share resources
 	asCTokenizer tok;
 
 	// Stores script declared object types
@@ -475,6 +475,7 @@ public:
 		bool   alwaysImplDefaultConstruct;
 		int    compilerWarnings;
 		bool   disallowValueAssignForRefType;
+		int    alterSyntaxNamedArgs;
 	} ep;
 
 	// This flag is to allow a quicker shutdown when releasing the engine

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

@@ -133,7 +133,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCScriptFunction,GetFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCScriptFunction,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCScriptFunction,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	// TODO: 2.29.0: Need some way to allow the arg type to adapt when the funcdefs are instanciated
+	// TODO: 2.29.0: Need some way to allow the arg type to adapt when the funcdefs are instantiated
 //	r = engine->RegisterMethodToObjectType(&engine->functionBehaviours, "bool opEquals(const int &in)", asMETHOD(asCScriptFunction,operator==), asCALL_THISCALL); asASSERT( r >= 0 );
 #else
 	r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptFunction_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
@@ -415,6 +415,23 @@ asCScriptFunction::~asCScriptFunction()
 	engine = 0;
 }
 
+// internal
+void asCScriptFunction::DestroyHalfCreated()
+{
+	asASSERT( refCount.get() == 1 );
+
+	// Set the funcType to dummy so the destructor won't complain
+	funcType = asFUNC_DUMMY;
+
+	// If the bytecode exist remove it before destroying, otherwise it
+	// will fail when the destructor releases the references as the bytecode
+	// is not fully constructed.
+	if( scriptData )
+		scriptData->byteCode.SetLength(0);
+
+	delete this;
+}
+
 // internal
 void asCScriptFunction::DestroyInternal()
 {

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

@@ -178,6 +178,8 @@ public:
 	asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
 	~asCScriptFunction();
 
+	void     DestroyHalfCreated();
+
 	// TODO: 2.29.0: operator==
 	// TODO: 2.29.0: The asIScriptFunction should provide operator== and operator!= that should do a
 	//               a value comparison. Two delegate objects that point to the same object and class method should compare as equal

+ 14 - 5
Source/ThirdParty/AngelScript/source/as_texts.h

@@ -42,7 +42,9 @@
 // Compiler messages
 
 #define TXT_s_ALREADY_DECLARED                    "'%s' is already declared"
+#define TXT_ABSTRACT_CLASS_s_CANNOT_BE_INSTANTIATED "Abstract class '%s' cannot be instantiated"
 #define TXT_ARG_NOT_LVALUE                        "Argument cannot be assigned. Output will be discarded."
+#define TXT_ATTR_s_INFORMED_MULTIPLE_TIMES        "Attribute '%s' informed multiple times"
 
 #define TXT_BOTH_MUST_BE_SAME                     "Both expressions must have the same type"
 #define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
@@ -57,12 +59,13 @@
 #define TXT_CANNOT_INHERIT_FROM_s_FINAL            "Can't inherit from class '%s' marked as final"
 #define TXT_CANNOT_INHERIT_FROM_MULTIPLE_CLASSES   "Can't inherit from multiple classes"
 #define TXT_CANNOT_INHERIT_FROM_SELF               "Can't inherit from itself, or another class that inherits from this class"
-#define TXT_CANNOT_INSTANCIATE_TEMPLATE_s_WITH_s   "Can't instanciate template '%s' with subtype '%s'"
+#define TXT_CANNOT_INSTANTIATE_TEMPLATE_s_WITH_s   "Can't instantiate template '%s' with subtype '%s'"
 #define TXT_CANNOT_PASS_CLASS_METHOD_AS_ARG        "Can't pass class method as arg directly. Use a delegate object instead"
 #define TXT_CANNOT_RETURN_REF_TO_LOCAL             "Can't return reference to local value."
 #define TXT_CANT_IMPLICITLY_CONVERT_s_TO_s         "Can't implicitly convert from '%s' to '%s'."
 #define TXT_CANT_RETURN_VALUE                      "Can't return value when return type is 'void'"
 #define TXT_CHANGE_SIGN                            "Implicit conversion changed sign of value"
+#define TXT_CLASS_CANT_BE_FINAL_AND_ABSTRACT       "A class cannot be both abstract and final"
 #define TXT_COMPILING_s                            "Compiling %s"
 #define TXT_COMPOUND_ASGN_WITH_PROP                "Compound assignments with property accessors are not allowed"
 #define TXT_CONSTRUCTOR_NAME_ERROR                 "The name of constructors and destructors must be the same as the class"
@@ -115,6 +118,8 @@
 #define TXT_HANDLE_OF_HANDLE_IS_NOT_ALLOWED      "Handle to handle is not allowed"
 
 #define TXT_IDENTIFIER_s_NOT_DATA_TYPE             "Identifier '%s' is not a data type"
+#define TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_GLOBAL_NS "Identifier '%s' is not a data type in global namespace"
+#define TXT_IDENTIFIER_s_NOT_DATA_TYPE_IN_NS_s     "Identifier '%s' is not a data type in namespace '%s' or parent"
 #define TXT_IF_WITH_EMPTY_STATEMENT                "If with empty statement"
 #define TXT_ILLEGAL_MEMBER_TYPE                    "Illegal member type"
 // TODO: Should be TXT_ILLEGAL_OPERATION_ON_s
@@ -124,6 +129,7 @@
 #define TXT_ILLEGAL_VARIABLE_NAME_s                "Illegal variable name '%s'."
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s        "Initialization lists cannot be used with '%s'"
 #define TXT_INSTEAD_FOUND_s                        "Instead found '%s'"
+#define TXT_INTERFACE_s_CANNOT_BE_INSTANTIATED     "Interface '%s' cannot be instantiated"
 #define TXT_INTERFACE_CAN_ONLY_IMPLEMENT_INTERFACE "Interfaces can only implement other interfaces"
 #define TXT_INVALID_BREAK                          "Invalid 'break'"
 #define TXT_INVALID_CHAR_LITERAL                   "Invalid character literal"
@@ -163,14 +169,15 @@
 #define TXT_NAME_CONFLICT_s_OBJ_PROPERTY           "Name conflict. '%s' is an object property."
 #define TXT_NAME_CONFLICT_s_METHOD                 "Name conflict. '%s' is a class method."
 #define TXT_NAME_CONFLICT_s_ALREADY_USED           "Name conflict. '%s' is already used."
+#define TXT_NAMED_ARGS_WITH_OLD_SYNTAX             "Detected named argument with old syntax"
 #define TXT_NO_APPROPRIATE_INDEX_OPERATOR          "No appropriate indexing operator found"
-#define TXT_NO_APPROPRIATE_OPHNDLASSIGN_s          "No appropriate opHndlAssign method found in '%s'"
+#define TXT_NO_APPROPRIATE_OPHNDLASSIGN_s          "No appropriate opHndlAssign method found in '%s' for handle assignment"
 #define TXT_NO_APPROPRIATE_OPEQUALS                "No appropriate opEquals method found"
 #define TXT_NO_CONVERSION_s_TO_s                   "No conversion from '%s' to '%s' available."
 #define TXT_NO_CONVERSION_s_TO_MATH_TYPE           "No conversion from '%s' to math type available."
 #define TXT_NO_DEFAULT_ARRAY_TYPE                  "The application doesn't support the default array type."
 #define TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s           "No default constructor for object of type '%s'."
-#define TXT_NO_DEFAULT_COPY_OP_FOR_s               "No appropriate opAssign method found in '%s'"
+#define TXT_NO_DEFAULT_COPY_OP_FOR_s               "No appropriate opAssign method found in '%s' for value assignment"
 #define TXT_NO_COPY_CONSTRUCTOR_FOR_s              "No copy constructor for object of type '%s'."
 #define TXT_NO_MATCHING_SIGNATURES_TO_s            "No matching signatures to '%s'"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
@@ -198,7 +205,7 @@
 #define TXT_OPERANDS_MUST_BE_HANDLES       "Both operands must be handles when comparing identity"
 
 #define TXT_PARAMETER_ALREADY_DECLARED            "Parameter already declared"
-#define TXT_PARAMETER_CANT_BE_s                   "Parameter type can't be '%s', because the type cannot be instanciated."
+#define TXT_PARAMETER_CANT_BE_s                   "Parameter type can't be '%s', because the type cannot be instantiated."
 #define TXT_PRIVATE_METHOD_CALL_s                 "Illegal call to private method '%s'"
 #define TXT_PRIVATE_PROP_ACCESS_s                 "Illegal access to private property '%s'"
 #define TXT_PROPERTY_ACCESSOR_DISABLED            "Property accessors have been disabled by the application"
@@ -236,6 +243,7 @@
 
 #define TXT_UNEXPECTED_END_OF_FILE             "Unexpected end of file"
 #define TXT_UNEXPECTED_TOKEN_s                 "Unexpected token '%s'"
+#define TXT_UNEXPECTED_VAR_DECL                "Unexpected variable declaration"
 #define TXT_UNINITIALIZED_GLOBAL_VAR_s         "Use of uninitialized global variable '%s'."
 #define TXT_UNKNOWN_SCOPE_s                    "Unknown scope '%s'"
 #define TXT_UNREACHABLE_CODE                   "Unreachable code"
@@ -284,7 +292,7 @@
 #define TXT_TEMPLATE_LIST_FACTORY_EXPECTS_2_REF_PARAMS   "Template list factory expects two reference parameters. The last is the pointer to the initialization buffer"
 #define TXT_LIST_FACTORY_EXPECTS_1_REF_PARAM             "List factory expects only one reference parameter. The pointer to the initialization buffer will be passed in this parameter"
 #define TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s            "Failed to read subtype of template type '%s'"
-#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s               "Attempting to instanciate invalid template type '%s<%s>'"
+#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s               "Attempting to instantiate invalid template type '%s<%s>'"
 #define TXT_FAILED_IN_FUNC_s_d                           "Failed in call to function '%s' (Code: %d)"
 #define TXT_FAILED_IN_FUNC_s_WITH_s_d                    "Failed in call to function '%s' with '%s' (Code: %d)"
 #define TXT_FAILED_IN_FUNC_s_WITH_s_AND_s_d              "Failed in call to function '%s' with '%s' and '%s' (Code: %d)"
@@ -296,6 +304,7 @@
 #define TXT_RESURRECTING_SCRIPTOBJECT_s                  "The script object of type '%s' is being resurrected illegally during destruction"
 #define TXT_INVALID_BYTECODE_d                           "LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: %d"
 #define TXT_NO_JIT_IN_FUNC_s                             "Function '%s' appears to have been compiled without JIT entry points"
+#define TXT_ENGINE_REF_COUNT_ERROR_DURING_SHUTDOWN       "Uh oh! The engine's reference count is increasing while it is being destroyed. Make sure references needed for clean-up are immediately released"
 
 // Internal names
 

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

@@ -308,6 +308,7 @@ const char * const FINAL_TOKEN    = "final";
 const char * const OVERRIDE_TOKEN = "override";
 const char * const GET_TOKEN      = "get";
 const char * const SET_TOKEN      = "set";
+const char * const ABSTRACT_TOKEN = "abstract";
 
 END_AS_NAMESPACE
 

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