浏览代码

Update Angelscript to 2.30.1

JSandusky 10 年之前
父节点
当前提交
8239cc2e5e
共有 56 个文件被更改,包括 3880 次插入2368 次删除
  1. 78 42
      Source/ThirdParty/AngelScript/include/angelscript.h
  2. 43 43
      Source/ThirdParty/AngelScript/source/as_array.h
  3. 402 138
      Source/ThirdParty/AngelScript/source/as_builder.cpp
  4. 9 7
      Source/ThirdParty/AngelScript/source/as_builder.h
  5. 50 11
      Source/ThirdParty/AngelScript/source/as_bytecode.cpp
  6. 165 116
      Source/ThirdParty/AngelScript/source/as_callfunc.cpp
  7. 12 4
      Source/ThirdParty/AngelScript/source/as_callfunc.h
  8. 9 49
      Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp
  9. 2 1
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_gcc.S
  10. 2 2
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm
  11. 480 0
      Source/ThirdParty/AngelScript/source/as_callfunc_arm_vita.S
  12. 4 2
      Source/ThirdParty/AngelScript/source/as_callfunc_mips.cpp
  13. 4 2
      Source/ThirdParty/AngelScript/source/as_callfunc_ppc.cpp
  14. 6 3
      Source/ThirdParty/AngelScript/source/as_callfunc_ppc_64.cpp
  15. 4 2
      Source/ThirdParty/AngelScript/source/as_callfunc_sh4.cpp
  16. 1 11
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  17. 1 6
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_mingw.cpp
  18. 11 31
      Source/ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp
  19. 2 28
      Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp
  20. 4 2
      Source/ThirdParty/AngelScript/source/as_callfunc_xenon.cpp
  21. 417 276
      Source/ThirdParty/AngelScript/source/as_compiler.cpp
  22. 10 8
      Source/ThirdParty/AngelScript/source/as_compiler.h
  23. 40 11
      Source/ThirdParty/AngelScript/source/as_config.h
  24. 30 71
      Source/ThirdParty/AngelScript/source/as_configgroup.cpp
  25. 7 4
      Source/ThirdParty/AngelScript/source/as_configgroup.h
  26. 257 66
      Source/ThirdParty/AngelScript/source/as_context.cpp
  27. 10 9
      Source/ThirdParty/AngelScript/source/as_context.h
  28. 39 11
      Source/ThirdParty/AngelScript/source/as_datatype.cpp
  29. 9 3
      Source/ThirdParty/AngelScript/source/as_datatype.h
  30. 5 0
      Source/ThirdParty/AngelScript/source/as_debug.h
  31. 1 11
      Source/ThirdParty/AngelScript/source/as_gc.cpp
  32. 21 139
      Source/ThirdParty/AngelScript/source/as_globalproperty.cpp
  33. 78 1
      Source/ThirdParty/AngelScript/source/as_memory.cpp
  34. 31 1
      Source/ThirdParty/AngelScript/source/as_memory.h
  35. 421 94
      Source/ThirdParty/AngelScript/source/as_module.cpp
  36. 17 12
      Source/ThirdParty/AngelScript/source/as_module.h
  37. 139 247
      Source/ThirdParty/AngelScript/source/as_objecttype.cpp
  38. 19 13
      Source/ThirdParty/AngelScript/source/as_objecttype.h
  39. 110 27
      Source/ThirdParty/AngelScript/source/as_parser.cpp
  40. 6 13
      Source/ThirdParty/AngelScript/source/as_property.h
  41. 123 79
      Source/ThirdParty/AngelScript/source/as_restore.cpp
  42. 314 338
      Source/ThirdParty/AngelScript/source/as_scriptengine.cpp
  43. 74 42
      Source/ThirdParty/AngelScript/source/as_scriptengine.h
  44. 156 243
      Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp
  45. 11 4
      Source/ThirdParty/AngelScript/source/as_scriptfunction.h
  46. 101 29
      Source/ThirdParty/AngelScript/source/as_scriptobject.cpp
  47. 28 22
      Source/ThirdParty/AngelScript/source/as_scriptobject.h
  48. 1 1
      Source/ThirdParty/AngelScript/source/as_string_util.cpp
  49. 43 42
      Source/ThirdParty/AngelScript/source/as_symboltable.h
  50. 51 36
      Source/ThirdParty/AngelScript/source/as_texts.h
  51. 2 0
      Source/ThirdParty/AngelScript/source/as_tokendef.h
  52. 3 1
      Source/ThirdParty/AngelScript/source/as_typeinfo.cpp
  53. 3 2
      Source/ThirdParty/AngelScript/source/as_typeinfo.h
  54. 4 4
      Source/Urho3D/AngelScript/APITemplates.h
  55. 8 6
      Source/Urho3D/AngelScript/Addons.cpp
  56. 2 2
      Source/Urho3D/AngelScript/ScriptFile.cpp

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -59,8 +59,8 @@ BEGIN_AS_NAMESPACE
 
 // AngelScript version
 
-#define ANGELSCRIPT_VERSION        22901
-#define ANGELSCRIPT_VERSION_STRING "2.29.1 WIP"
+#define ANGELSCRIPT_VERSION        23001
+#define ANGELSCRIPT_VERSION_STRING "2.30.1 WIP"
 
 // Data types
 
@@ -108,7 +108,8 @@ enum asERetCodes
 	asWRONG_CALLING_CONV                   = -24,
 	asBUILD_IN_PROGRESS                    = -25,
 	asINIT_GLOBAL_VARS_FAILED              = -26,
-	asOUT_OF_MEMORY                        = -27
+	asOUT_OF_MEMORY                        = -27,
+	asMODULE_IS_IN_USE                     = -28
 };
 
 // Engine properties
@@ -135,6 +136,9 @@ enum asEEngineProp
 	asEP_COMPILER_WARNINGS                  = 19,
 	asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE = 20,
 	asEP_ALTER_SYNTAX_NAMED_ARGS            = 21,
+	asEP_DISABLE_INTEGER_DIVISION           = 22,
+	asEP_DISALLOW_EMPTY_LIST_ELEMENTS       = 23,
+	asEP_PRIVATE_PROP_AS_PROTECTED          = 24,
 
 	asEP_LAST_PROPERTY
 };
@@ -191,18 +195,19 @@ enum asEObjTypeFlags
 	asOBJ_APP_CLASS_ALLFLOATS        = (1<<17),
 	asOBJ_NOCOUNT                    = (1<<18),
 	asOBJ_APP_CLASS_ALIGN8           = (1<<19),
-	asOBJ_MASK_VALID_FLAGS           = 0x0FFFFF,
+	asOBJ_IMPLICIT_HANDLE            = (1<<20),
+	asOBJ_MASK_VALID_FLAGS           = 0x1FFFFF,
 	// Internal flags
-	asOBJ_SCRIPT_OBJECT              = (1<<20),
-	asOBJ_SHARED                     = (1<<21),
-	asOBJ_NOINHERIT                  = (1<<22),
-	asOBJ_SCRIPT_FUNCTION            = (1<<23),
-	asOBJ_IMPLICIT_HANDLE            = (1<<24),
+	asOBJ_SCRIPT_OBJECT              = (1<<21),
+	asOBJ_SHARED                     = (1<<22),
+	asOBJ_NOINHERIT                  = (1<<23),
+	asOBJ_SCRIPT_FUNCTION            = (1<<24),
 	asOBJ_LIST_PATTERN               = (1<<25),
 	asOBJ_ENUM                       = (1<<26),
 	asOBJ_TEMPLATE_SUBTYPE           = (1<<27),
 	asOBJ_TYPEDEF                    = (1<<28),
-	asOBJ_ABSTRACT                   = (1<<29)
+	asOBJ_ABSTRACT                   = (1<<29),
+	asOBJ_APP_ALIGN16                = (1<<30)
 };
 
 // Behaviours
@@ -221,10 +226,14 @@ enum asEBehaviours
 	asBEHAVE_GET_WEAKREF_FLAG,
 
 	// Object operators
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.30.0, 2014-10-24
 	asBEHAVE_VALUE_CAST,
 	asBEHAVE_IMPLICIT_VALUE_CAST,
+	// Deprecated since 2.30.0, 2014-12-30
 	asBEHAVE_REF_CAST,
 	asBEHAVE_IMPLICIT_REF_CAST,
+#endif
 	asBEHAVE_TEMPLATE_CALLBACK,
 
 	// Garbage collection behaviours
@@ -365,7 +374,7 @@ typedef unsigned int   asUINT;
     typedef long asINT64;
 #else
     typedef unsigned long asDWORD;
-  #if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC)
+  #if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) || defined(__psp2__)
     typedef uint64_t asQWORD;
     typedef int64_t asINT64;
   #else
@@ -390,6 +399,7 @@ typedef void (*asCLEANMODULEFUNC_t)(asIScriptModule *);
 typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
 typedef void (*asCLEANFUNCTIONFUNC_t)(asIScriptFunction *);
 typedef void (*asCLEANOBJECTTYPEFUNC_t)(asIObjectType *);
+typedef void (*asCLEANSCRIPTOBJECTFUNC_t)(asIScriptObject *);
 typedef asIScriptContext *(*asREQUESTCONTEXTFUNC_t)(asIScriptEngine *, void *);
 typedef void (*asRETURNCONTEXTFUNC_t)(asIScriptEngine *, asIScriptContext *, void *);
 
@@ -447,7 +457,7 @@ struct asSFuncPtr
 		// The largest known method point is 20 bytes (MSVC 64bit),
 		// but with 8byte alignment this becomes 24 bytes. So we need
 		// to be able to store at least that much.
-		char dummy[25]; 
+		char dummy[25];
 		struct {asMETHOD_t   mthd; char dummy[25-sizeof(asMETHOD_t)];} m;
 		struct {asFUNCTION_t func; char dummy[25-sizeof(asFUNCTION_t)];} f;
 	} ptr;
@@ -523,7 +533,7 @@ struct asSMessageInfo
   #else // statically linked library
     #define AS_API
   #endif
-#elif defined(__GNUC__) 
+#elif defined(__GNUC__)
   #if defined(ANGELSCRIPT_EXPORT)
     #define AS_API __attribute__((visibility ("default")))
   #else
@@ -578,25 +588,40 @@ 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;
+#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS)
+	// MSVC & XCode/Clang
+	// C++11 compliant code
+	bool hasConstructor        = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
+	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
+	bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::is_trivially_copy_assignable<T>::value;
+	bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::is_trivially_copy_constructible<T>::value;
+#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+	// gnuc 4.8+
+	// gnuc is using a mix of C++11 standard and pre-standard templates
+	bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
+	bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
+	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;
 #else
-	bool hasDestructor = std::is_destructible<T>::value && !std::has_trivial_destructor<T>::value;
+	// Not fully C++11 compliant. The has_trivial checks were used while the standard was still
+	// being elaborated, but were then removed in favor of the above is_trivially checks
+	// http://stackoverflow.com/questions/12702103/writing-code-that-works-when-has-trivial-destructor-is-defined-instead-of-is
+	// https://github.com/mozart/mozart2/issues/51
+	bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
+	bool hasDestructor         = std::is_destructible<T>::value          && !std::has_trivial_destructor<T>::value;
+	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;
 #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 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;
+	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;
@@ -628,6 +653,7 @@ public:
 	// Memory management
 	virtual int AddRef() const = 0;
 	virtual int Release() const = 0;
+	virtual int ShutDownAndRelease() = 0;
 
 	// Engine properties
 	virtual int     SetEngineProperty(asEEngineProp property, asPWORD value) = 0;
@@ -723,10 +749,14 @@ public:
 	virtual void                  *CreateScriptObjectCopy(void *obj, const asIObjectType *type) = 0;
 	virtual void                  *CreateUninitializedScriptObject(const asIObjectType *type) = 0;
 	virtual asIScriptFunction     *CreateDelegate(asIScriptFunction *func, void *obj) = 0;
-	virtual void                   AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type) = 0;
+	virtual int                    AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type) = 0;
 	virtual void                   ReleaseScriptObject(void *obj, const asIObjectType *type) = 0;
 	virtual void                   AddRefScriptObject(void *obj, const asIObjectType *type) = 0;
+	virtual int                    RefCastObject(void *obj, asIObjectType *fromType, asIObjectType *toType, void **newPtr, bool useOnlyImplicitCast = false) = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.30.0, 2014-11-04
 	virtual bool                   IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const = 0;
+#endif
 	virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const = 0;
 
 	// Context pooling
@@ -735,7 +765,7 @@ public:
 	virtual int                    SetContextCallbacks(asREQUESTCONTEXTFUNC_t requestCtx, asRETURNCONTEXTFUNC_t returnCtx, void *param = 0) = 0;
 
 	// String interpretation
-	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, int *tokenLength = 0) const = 0;
+	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, asUINT *tokenLength = 0) const = 0;
 
 	// Garbage collection
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1) = 0;
@@ -752,6 +782,7 @@ public:
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type = 0) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type = 0) = 0;
 	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type = 0) = 0;
+	virtual void  SetScriptObjectUserDataCleanupCallback(asCLEANSCRIPTOBJECTFUNC_t callback, asPWORD type = 0) = 0;
 
 protected:
 	virtual ~asIScriptEngine() {}
@@ -824,7 +855,7 @@ public:
 	virtual int         BindAllImportedFunctions() = 0;
 	virtual int         UnbindAllImportedFunctions() = 0;
 
-	// Bytecode saving and loading
+	// Byte code saving and loading
 	virtual int SaveByteCode(asIBinaryStream *out, bool stripDebugInfo = false) const = 0;
 	virtual int LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped = 0) = 0;
 
@@ -869,6 +900,7 @@ public:
 	virtual int   SetArgDouble(asUINT arg, double value) = 0;
 	virtual int   SetArgAddress(asUINT arg, void *addr) = 0;
 	virtual int   SetArgObject(asUINT arg, void *obj) = 0;
+	virtual int   SetArgVarType(asUINT arg, void *ptr, int typeId) = 0;
 	virtual void *GetAddressOfArg(asUINT arg) = 0;
 
 	// Return value
@@ -958,8 +990,9 @@ class asIScriptObject
 {
 public:
 	// Memory management
-	virtual int AddRef() const = 0;
-	virtual int Release() const = 0;
+	virtual int                    AddRef() const = 0;
+	virtual int                    Release() const = 0;
+	virtual asILockableSharedBool *GetWeakRefFlag() const = 0;
 
 	// Type info
 	virtual int            GetTypeId() const = 0;
@@ -971,12 +1004,13 @@ public:
 	virtual const char *GetPropertyName(asUINT prop) const = 0;
 	virtual void       *GetAddressOfProperty(asUINT prop) = 0;
 
+	// Miscellaneous
 	virtual asIScriptEngine *GetEngine() const = 0;
 	virtual int              CopyFrom(asIScriptObject *other) = 0;
 
-	// Urho3D: added userdata
-	virtual void *SetUserData(void *data) = 0;
-	virtual void *GetUserData() const = 0;
+	// User data
+	virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
+	virtual void *GetUserData(asPWORD type = 0) const = 0;
 
 protected:
 	virtual ~asIScriptObject() {}
@@ -985,6 +1019,7 @@ protected:
 class asIObjectType
 {
 public:
+	// Miscellaneous
 	virtual asIScriptEngine *GetEngine() const = 0;
 	virtual const char      *GetConfigGroup() const = 0;
 	virtual asDWORD          GetAccessMask() const = 0;
@@ -1024,7 +1059,7 @@ public:
 
 	// Properties
 	virtual asUINT      GetPropertyCount() const = 0;
-	virtual int         GetProperty(asUINT index, const char **name, int *typeId = 0, bool *isPrivate = 0, int *offset = 0, bool *isReference = 0, asDWORD *accessMask = 0) const = 0;
+	virtual int         GetProperty(asUINT index, const char **name, int *typeId = 0, bool *isPrivate = 0, bool *isProtected = 0, int *offset = 0, bool *isReference = 0, asDWORD *accessMask = 0) const = 0;
 	virtual const char *GetPropertyDeclaration(asUINT index, bool includeNamespace = false) const = 0;
 
 	// Behaviours
@@ -1065,6 +1100,7 @@ public:
 	virtual const char      *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const = 0;
 	virtual bool             IsReadOnly() const = 0;
 	virtual bool             IsPrivate() const = 0;
+	virtual bool             IsProtected() const = 0;
 	virtual bool             IsFinal() const = 0;
 	virtual bool             IsOverride() const = 0;
 	virtual bool             IsShared() const = 0;
@@ -1076,7 +1112,7 @@ public:
 #endif
 	virtual int              GetReturnTypeId(asDWORD *flags = 0) const = 0;
 
-	// Type id for function pointers 
+	// Type id for function pointers
 	virtual int              GetTypeId() const = 0;
 	virtual bool             IsCompatibleWithTypeId(int typeId) const = 0;
 
@@ -1122,7 +1158,7 @@ public:
 	// Value
 	virtual bool Get() const = 0;
 	virtual void Set(bool val) = 0;
-	
+
 	// Thread management
 	virtual void Lock() const = 0;
 	virtual void Unlock() const = 0;
@@ -1143,7 +1179,7 @@ inline asSFuncPtr asFunctionPtr(T func)
 	asSFuncPtr p(2);
 
 #ifdef AS_64BIT_PTR
-	// The size_t cast is to avoid a compiler warning with asFUNCTION(0) 
+	// The size_t cast is to avoid a compiler warning with asFUNCTION(0)
 	// on 64bit, as 0 is interpreted as a 32bit int value
 	p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(size_t(func));
 #else
@@ -1239,9 +1275,9 @@ struct asSMethodPtr<SINGLE_PTR_SIZE+2*sizeof(int)>
 
 #if defined(_MSC_VER) && !defined(AS_64BIT_PTR)
 			// Method pointers for virtual inheritance is not supported,
-			// as it requires the location of the vbase table, which is 
+			// as it requires the location of the vbase table, which is
 			// only available to the C++ compiler, but not in the method
-			// pointer. 
+			// pointer.
 
 			// You can get around this by forward declaring the class and
 			// storing the sizeof its method pointer in a constant. Example:
@@ -1524,8 +1560,8 @@ enum asEBCInstr
 	asBC_POWdi			= 197,
 	asBC_POWi64			= 198,
 	asBC_POWu64			= 199,
-
-	asBC_MAXBYTECODE	= 200,
+	asBC_Thiscall1		= 200,
+	asBC_MAXBYTECODE	= 201,
 
 	// Temporary tokens. Can't be output to the final program
 	asBC_VarDecl		= 251,
@@ -1819,8 +1855,8 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO(POWdi,		wW_rW_rW_ARG,	0),
 	asBCINFO(POWi64,	wW_rW_rW_ARG,	0),
 	asBCINFO(POWu64,	wW_rW_rW_ARG,	0),
+	asBCINFO(Thiscall1, DW_ARG,			-AS_PTR_SIZE-1),
 
-	asBCINFO_DUMMY(200),
 	asBCINFO_DUMMY(201),
 	asBCINFO_DUMMY(202),
 	asBCINFO_DUMMY(203),

+ 43 - 43
Source/ThirdParty/AngelScript/source/as_array.h

@@ -47,26 +47,26 @@ template <class T> class asCArray
 public:
 	asCArray();
 	asCArray(const asCArray<T> &);
-	asCArray(size_t reserve);
+	asCArray(asUINT reserve);
 	~asCArray();
 
-	void   Allocate(size_t numElements, bool keepData);
-	void   AllocateNoConstruct(size_t numElements, bool keepData);
-	size_t GetCapacity() const;
+	void   Allocate(asUINT numElements, bool keepData);
+	void   AllocateNoConstruct(asUINT numElements, bool keepData);
+	asUINT GetCapacity() const;
 
 	void PushLast(const T &element);
 	T    PopLast();
 
-	bool   SetLength(size_t numElements);
-	bool   SetLengthNoConstruct(size_t numElements);
-	size_t GetLength() const;
+	bool   SetLength(asUINT numElements);
+	bool   SetLengthNoConstruct(asUINT numElements);
+	asUINT GetLength() const;
 
-	void         Copy(const T*, size_t count);
+	void         Copy(const T*, asUINT count);
 	asCArray<T> &operator =(const asCArray<T> &);
 	void         SwapWith(asCArray<T> &other);
 
-	const T &operator [](size_t index) const;
-	T       &operator [](size_t index);
+	const T &operator [](asUINT index) const;
+	T       &operator [](asUINT index);
 	T       *AddressOf();
 	const T *AddressOf() const;
 
@@ -75,18 +75,18 @@ public:
 
 	bool Exists(const T &element) const;
 	int  IndexOf(const T &element) const;
-	void RemoveIndex(size_t index);          // Removes the entry without reordering the array
+	void RemoveIndex(asUINT index);          // Removes the entry without reordering the array
 	void RemoveValue(const T &element);      // Removes the value without reordering the array
-	void RemoveIndexUnordered(size_t index); // Removes the entry without keeping the order
+	void RemoveIndexUnordered(asUINT index); // Removes the entry without keeping the order
 
 	bool operator==(const asCArray<T> &) const;
 	bool operator!=(const asCArray<T> &) const;
 
 protected:
 	T      *array;
-	size_t  length;
-	size_t  maxLength;
-	char    buf[8];
+	asUINT  length;                  // 32bits is enough for all uses of this array
+	asUINT  maxLength;
+	char    buf[2*4*AS_PTR_SIZE];    // Avoid dynamically allocated memory for tiny arrays
 };
 
 // Implementation
@@ -122,7 +122,7 @@ asCArray<T>::asCArray(const asCArray<T> &copy)
 }
 
 template <class T>
-asCArray<T>::asCArray(size_t reserve)
+asCArray<T>::asCArray(asUINT reserve)
 {
 	array     = 0;
 	length    = 0;
@@ -139,13 +139,13 @@ asCArray<T>::~asCArray(void)
 }
 
 template <class T>
-size_t asCArray<T>::GetLength() const
+asUINT asCArray<T>::GetLength() const
 {
 	return length;
 }
 
 template <class T>
-const T &asCArray<T>::operator [](size_t index) const
+const T &asCArray<T>::operator [](asUINT index) const
 {
 	asASSERT(index < length);
 
@@ -153,7 +153,7 @@ const T &asCArray<T>::operator [](size_t index) const
 }
 
 template <class T>
-T &asCArray<T>::operator [](size_t index)
+T &asCArray<T>::operator [](asUINT index)
 {
 	asASSERT(index < length);
 
@@ -189,7 +189,7 @@ T asCArray<T>::PopLast()
 }
 
 template <class T>
-void asCArray<T>::Allocate(size_t numElements, bool keepData)
+void asCArray<T>::Allocate(asUINT numElements, bool keepData)
 {
 	// We have 4 situations
 	// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
@@ -200,7 +200,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 	T *tmp = 0;
 	if( numElements )
 	{
-		if( sizeof(T)*numElements <= 8 )
+		if( sizeof(T)*numElements <= sizeof(buf) )
 			// Use the internal buffer
 			tmp = reinterpret_cast<T*>(buf);
 		else
@@ -217,20 +217,20 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 		if( array == tmp )
 		{
 			// Construct only the newly allocated elements
-			for( size_t n = length; n < numElements; n++ )
+			for( asUINT n = length; n < numElements; n++ )
 				new (&tmp[n]) T();
 		}
 		else
 		{
 			// Construct all elements
-			for( size_t n = 0; n < numElements; n++ )
+			for( asUINT n = 0; n < numElements; n++ )
 				new (&tmp[n]) T();
 		}
 	}
 
 	if( array )
 	{	
-		size_t oldLength = length;
+		asUINT oldLength = length;
 
 		if( array == tmp )
 		{
@@ -243,7 +243,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 				length = 0;
 
 			// Call the destructor for elements that are no longer used
-			for( size_t n = length; n < oldLength; n++ )
+			for( asUINT n = length; n < oldLength; n++ )
 				array[n].~T();
 		}
 		else
@@ -253,14 +253,14 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 				if( length > numElements )
 					length = numElements;
 
-				for( size_t n = 0; n < length; n++ )
+				for( asUINT n = 0; n < length; n++ )
 					tmp[n] = array[n];
 			}
 			else
 				length = 0;
 
 			// Call the destructor for all elements
-			for( size_t n = 0; n < oldLength; n++ )
+			for( asUINT n = 0; n < oldLength; n++ )
 				array[n].~T();
 
 			if( array != reinterpret_cast<T*>(buf) )
@@ -273,7 +273,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
 }
 
 template <class T>
-void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
+void asCArray<T>::AllocateNoConstruct(asUINT numElements, bool keepData)
 {
 	// We have 4 situations
 	// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
@@ -284,7 +284,7 @@ void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
 	T *tmp = 0;
 	if( numElements )
 	{
-		if( sizeof(T)*numElements <= 8 )
+		if( sizeof(T)*numElements <= sizeof(buf) )
 			// Use the internal buffer
 			tmp = reinterpret_cast<T*>(buf);
 		else
@@ -333,13 +333,13 @@ void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
 }
 
 template <class T>
-size_t asCArray<T>::GetCapacity() const
+asUINT asCArray<T>::GetCapacity() const
 {
 	return maxLength;
 }
 
 template <class T>
-bool asCArray<T>::SetLength(size_t numElements)
+bool asCArray<T>::SetLength(asUINT numElements)
 {
 	if( numElements > maxLength )
 	{
@@ -356,7 +356,7 @@ bool asCArray<T>::SetLength(size_t numElements)
 }
 
 template <class T>
-bool asCArray<T>::SetLengthNoConstruct(size_t numElements)
+bool asCArray<T>::SetLengthNoConstruct(asUINT numElements)
 {
 	if( numElements > maxLength )
 	{
@@ -373,7 +373,7 @@ bool asCArray<T>::SetLengthNoConstruct(size_t numElements)
 }
 
 template <class T>
-void asCArray<T>::Copy(const T *data, size_t count)
+void asCArray<T>::Copy(const T *data, asUINT count)
 {
 	if( maxLength < count )
 	{
@@ -385,7 +385,7 @@ void asCArray<T>::Copy(const T *data, size_t count)
 		}
 	}
 
-	for( size_t n = 0; n < count; n++ )
+	for( asUINT n = 0; n < count; n++ )
 		array[n] = data[n];
 
 	length = count;
@@ -403,8 +403,8 @@ template <class T>
 void asCArray<T>::SwapWith(asCArray<T> &other)
 {
 	T      *tmpArray = array;
-	size_t  tmpLength = length;
-	size_t  tmpMaxLength = maxLength;
+	asUINT  tmpLength = length;
+	asUINT  tmpMaxLength = maxLength;
 	char    tmpBuf[sizeof(buf)];
 	memcpy(tmpBuf, buf, sizeof(buf));
 
@@ -430,7 +430,7 @@ bool asCArray<T>::operator ==(const asCArray<T> &other) const
 {
 	if( length != other.length ) return false;
 
-	for( size_t n = 0; n < length; n++ )
+	for( asUINT n = 0; n < length; n++ )
 		if( array[n] != other.array[n] )
 			return false;
 
@@ -458,7 +458,7 @@ bool asCArray<T>::Concatenate(const asCArray<T> &other)
 		}
 	}
 
-	for( size_t n = 0; n < other.length; n++ )
+	for( asUINT n = 0; n < other.length; n++ )
 		array[length+n] = other.array[n];
 
 	length += other.length;
@@ -483,18 +483,18 @@ bool asCArray<T>::Exists(const T &e) const
 template <class T>
 int asCArray<T>::IndexOf(const T &e) const
 {
-	for( size_t n = 0; n < length; n++ )
+	for( asUINT n = 0; n < length; n++ )
 		if( array[n] == e ) return static_cast<int>(n);
 
 	return -1;
 }
 
 template <class T>
-void asCArray<T>::RemoveIndex(size_t index)
+void asCArray<T>::RemoveIndex(asUINT index)
 {
 	if( index < length )
 	{
-		for( size_t n = index; n < length-1; n++ )
+		for( asUINT n = index; n < length-1; n++ )
 			array[n] = array[n+1];
 
 		PopLast();
@@ -504,7 +504,7 @@ void asCArray<T>::RemoveIndex(size_t index)
 template <class T>
 void asCArray<T>::RemoveValue(const T &e)
 {
-	for( size_t n = 0; n < length; n++ )
+	for( asUINT n = 0; n < length; n++ )
 	{
 		if( array[n] == e )
 		{
@@ -515,7 +515,7 @@ void asCArray<T>::RemoveValue(const T &e)
 }
 
 template <class T>
-void asCArray<T>::RemoveIndexUnordered(size_t index)
+void asCArray<T>::RemoveIndexUnordered(asUINT index)
 {
 	if( index == length - 1 )
 		PopLast();

文件差异内容过多而无法显示
+ 402 - 138
Source/ThirdParty/AngelScript/source/as_builder.cpp


+ 9 - 7
Source/ThirdParty/AngelScript/source/as_builder.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -174,8 +174,8 @@ protected:
 	asCString          GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
 
 	asSNameSpace      *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next);
+	asSNameSpace      *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script);
 	asCString          GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
-	asSNameSpace      *GetParentNameSpace(asSNameSpace *ns);
 
 	asCObjectType     *GetObjectType(const char *type, asSNameSpace *ns);
 	asCScriptFunction *GetFuncDef(const char *type);
@@ -194,6 +194,7 @@ protected:
 protected:
 	friend class asCCompiler;
 
+	int                CheckForConflictsDueToDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func, asCObjectType *objType);
 	int                GetNamespaceAndNameFromNode(asCScriptNode *n, asCScriptCode *script, asSNameSpace *implicitNs, asSNameSpace *&outNs, asCString &outName);
 	int                RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	sMixinClass       *GetMixinClass(const char *name, asSNameSpace *ns);
@@ -203,7 +204,7 @@ protected:
 	void               AddInterfaceFromMixinToClass(sClassDeclaration *decl, asCScriptNode *errNode, sMixinClass *mixin);
 
 	int                RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false, bool isMixin = false);
-	int                RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isOverride, bool isFinal, bool isShared);
+	int                RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isProtected, bool isOverride, bool isFinal, bool isShared);
 	int                RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false);
 	int                RegisterImportedFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	int                RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
@@ -214,11 +215,11 @@ protected:
 	int                RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
 	void               CompleteFuncDef(sFuncDef *funcDef);
 	void               CompileInterfaces();
-	void               CompileClasses();
-	void               GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isOverride, bool &isFinal, bool &isShared, asSNameSpace *implicitNamespace);
+	void               CompileClasses(asUINT originalNumTempl);
+	void               GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isProtected, bool &isOverride, bool &isFinal, bool &isShared, asSNameSpace *implicitNamespace);
 	bool               DoesMethodExist(asCObjectType *objType, int methodId, asUINT *methodIndex = 0);
 	void               AddDefaultConstructor(asCObjectType *objType, asCScriptCode *file);
-	asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, asCScriptCode *file = 0, asCScriptNode *node = 0);
+	asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, bool isProtected, bool isInherited, asCScriptCode *file = 0, asCScriptNode *node = 0);
 	int                CreateVirtualFunction(asCScriptFunction *func, int idx);
 	void               ParseScripts();
 	void               RegisterTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
@@ -231,7 +232,8 @@ protected:
 	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
 	asCScriptFunction *GetFunctionDescription(int funcId);
 	void               GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
-	void               GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
+	void               GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "", asCScriptNode *errNode = 0, asCScriptCode *script = 0);
+	void               EvaluateTemplateInstances(asUINT startIdx, bool keepSilent);
 
 	asCArray<asCScriptCode *>                  scripts;
 	asCArray<sFunctionDescription *>           functions;

+ 50 - 11
Source/ThirdParty/AngelScript/source/as_bytecode.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -2037,7 +2037,14 @@ void asCByteCode::PostProcess()
 			DeleteInstruction(curr);
 		}
 		else
+		{
+#ifndef AS_DEBUG
+			// If the stackSize is negative, then there is a problem with the bytecode.
+			// If AS_DEBUG is turned on, this same check is done in DebugOutput.
+			asASSERT( instr->stackSize >= 0 || asBCInfo[instr->op].type == asBCTYPE_INFO );
+#endif
 			instr = instr->next;
+		}
 	}
 }
 
@@ -2081,7 +2088,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 	{
 		int idx = func->scriptData->objVariablePos.IndexOf(func->scriptData->variables[n]->stackOffset);
 		bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
-		fprintf(file, " %.3d: %s%s %s\n", func->scriptData->variables[n]->stackOffset, isOnHeap ? "(heap) " : "", func->scriptData->variables[n]->type.Format().AddressOf(), func->scriptData->variables[n]->name.AddressOf());
+		fprintf(file, " %.3d: %s%s %s\n", func->scriptData->variables[n]->stackOffset, isOnHeap ? "(heap) " : "", func->scriptData->variables[n]->type.Format(func->nameSpace).AddressOf(), func->scriptData->variables[n]->name.AddressOf());
 	}
 	asUINT offset = 0;
 	if( func->objectType )
@@ -2104,7 +2111,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 		{
 			int idx = func->scriptData->objVariablePos.IndexOf(offset);
 			bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
-			fprintf(file, " %.3d: %s%s {noname param}\n", offset, isOnHeap ? "(heap) " : "", func->parameterTypes[n].Format().AddressOf());
+			fprintf(file, " %.3d: %s%s {noname param}\n", offset, isOnHeap ? "(heap) " : "", func->parameterTypes[n].Format(func->nameSpace).AddressOf());
 		}
 
 		offset -= func->parameterTypes[n].GetSizeOnStackDWords();
@@ -2134,6 +2141,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 	}
 	fprintf(file, "\n\n");
 
+	bool invalidStackSize = false;
 	int pos = 0;
 	asUINT lineIndex = 0;
 	asCByteInstruction *instr = first;
@@ -2146,10 +2154,19 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			lineIndex += 2;
 		}
 
-		fprintf(file, "%5d ", pos);
-		pos += instr->GetSize();
+		if( instr->GetSize() > 0 )
+		{
+			fprintf(file, "%5d ", pos);
+			pos += instr->GetSize();
 
-		fprintf(file, "%3d %c ", int(instr->stackSize + func->scriptData->variableSpace), instr->marked ? '*' : ' ');
+			fprintf(file, "%3d %c ", int(instr->stackSize + func->scriptData->variableSpace), instr->marked ? '*' : ' ');
+			if( instr->stackSize < 0 )
+				invalidStackSize = true;
+		}
+		else
+		{
+			fprintf(file, "            ");
+		}
 
 		switch( asBCInfo[instr->op].type )
 		{
@@ -2197,7 +2214,10 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			switch( instr->op )
 			{
 			case asBC_OBJTYPE:
-				fprintf(file, "   %-8s 0x%x\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg));
+				{
+					asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
+					fprintf(file, "   %-8s 0x%x           (type:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), ot->GetName());
+				}
 				break;
 
 			case asBC_PshC4:
@@ -2213,6 +2233,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			case asBC_CALLSYS:
 			case asBC_CALLBND:
 			case asBC_CALLINTF:
+			case asBC_Thiscall1:
 				{
 					int funcID = *(int*)ARG_DW(instr->arg);
 					asCString decl = engine->GetFunctionDeclaration(funcID);
@@ -2244,6 +2265,16 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			break;
 
 		case asBCTYPE_QW_ARG:
+			switch( instr->op )
+			{
+			case asBC_OBJTYPE:
+				{
+					asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
+					fprintf(file, "   %-8s 0x%x          (type:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), ot->GetName());
+				}
+				break;
+	
+			default:
 #ifdef __GNUC__
 #ifdef _LP64
 			fprintf(file, "   %-8s 0x%lx           (i:%ld, f:%g)\n", asBCInfo[instr->op].name, *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
@@ -2253,6 +2284,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 #else
 			fprintf(file, "   %-8s 0x%I64x          (i:%I64d, f:%g)\n", asBCInfo[instr->op].name, *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
 #endif
+			}
 			break;
 
 		case asBCTYPE_wW_QW_ARG:
@@ -2272,7 +2304,8 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			if( instr->op == asBC_ALLOC )
 			{
 				asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
-				fprintf(file, "   %-8s 0x%x, %d             (type:%s)\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1), ot->GetName());
+				asCScriptFunction *func = engine->scriptFunctions[instr->wArg[0]];
+				fprintf(file, "   %-8s 0x%x, %d             (type:%s, %s)\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
 			}
 			else
 				fprintf(file, "   %-8s %u, %d\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1));
@@ -2286,14 +2319,15 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 			if( instr->op == asBC_ALLOC )
 			{
 				asCObjectType *ot = *(asCObjectType**)ARG_QW(instr->arg);
+				asCScriptFunction *func = engine->scriptFunctions[instr->wArg[0]];
 #ifdef __GNUC__
 #ifdef AS_64BIT_PTR
-				fprintf(file, "   %-8s 0x%lx, %d             (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
+				fprintf(file, "   %-8s 0x%lx, %d             (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
 #else
-				fprintf(file, "   %-8s 0x%llx, %d             (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
+				fprintf(file, "   %-8s 0x%llx, %d             (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
 #endif
 #else
-				fprintf(file, "   %-8s 0x%I64x, %d             (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
+				fprintf(file, "   %-8s 0x%I64x, %d             (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
 #endif
 			}
 			else
@@ -2348,6 +2382,11 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
 	}
 
 	fclose(file);
+
+	// If the stackSize is negative then there is something wrong with the 
+	// bytecode, i.e. there is a bug in the compiler or in the optimizer. We 
+	// only check this here to have the bytecode available on file for verification
+	asASSERT( !invalidStackSize );
 }
 #endif
 

+ 165 - 116
Source/ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -45,6 +45,14 @@
 
 BEGIN_AS_NAMESPACE
 
+// ref: Member Function Pointers and the Fastest Possible C++ Delegates
+//      describes the structure of class method pointers for most compilers
+//      http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
+
+// ref: The code comments for ItaniumCXXABI::EmitLoadOfMemberFunctionPointer in the LLVM compiler
+//      describes the structure for class method pointers on Itanium and arm64 ABI
+//      http://clang.llvm.org/doxygen/CodeGen_2ItaniumCXXABI_8cpp_source.html#l00937
+
 int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal)
 {
 	memset(internal, 0, sizeof(asSSystemFunctionInterface));
@@ -104,8 +112,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 			{
 #ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 				return asNOT_SUPPORTED;
-#endif
-
+#else
 				if( objForThiscall == 0 )
 					return asINVALID_ARG;
 
@@ -114,6 +121,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 					thisCallConv = ICC_THISCALL_OBJFIRST;
 				else //if( base == asCALL_THISCALL_OBJLAST )
 					thisCallConv = ICC_THISCALL_OBJLAST;
+#endif
 			}
 
 			internal->callConv = thisCallConv;
@@ -122,7 +130,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
 				internal->callConv = (internalCallConv)(thisCallConv + 2);
 #endif
 			internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
-#if defined(AS_ARM) && defined(__GNUC__)
+#if defined(AS_ARM) && (defined(__GNUC__) || defined(AS_PSVITA))
 			// As the least significant bit in func is used to switch to THUMB mode
 			// on ARM processors, the LSB in the __delta variable is used instead of
 			// the one in __pfn on ARM processors.
@@ -159,6 +167,49 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
 	// Calculate the size needed for the parameters
 	internal->paramSize = func->GetSpaceNeededForArguments();
 
+	// Prepare the clean up instructions for the function arguments
+	internal->cleanArgs.SetLength(0);
+	int offset = 0;
+	for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
+	{
+		asCDataType &dt = func->parameterTypes[n];
+
+		if( dt.IsObject() && !dt.IsReference() )
+		{
+			asSTypeBehaviour *beh = &dt.GetObjectType()->beh;
+			if( dt.GetObjectType()->flags & asOBJ_REF )
+			{
+				asASSERT( (dt.GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
+				if( beh->release )
+				{
+					asSSystemFunctionInterface::SClean clean;
+					clean.op  = 0; // call release
+					clean.ot  = dt.GetObjectType();
+					clean.off = short(offset);
+					internal->cleanArgs.PushLast(clean);
+				}
+			}
+			else
+			{
+				asSSystemFunctionInterface::SClean clean;
+				clean.op  = 1; // call free
+				clean.ot  = dt.GetObjectType();
+				clean.off = short(offset);
+
+				// Call the destructor then free the memory
+				if( beh->destruct )
+					clean.op = 2; // call destruct, then free
+
+				internal->cleanArgs.PushLast(clean);
+			}
+		}
+
+		if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
+			offset += AS_PTR_SIZE;
+		else
+			offset += dt.GetSizeOnStackDWords();
+	}
+
 	return 0;
 }
 
@@ -282,7 +333,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
 
 				asCString str;
-				str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format().AddressOf());
+				str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format(func->nameSpace).AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
 			}
@@ -390,15 +441,55 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 		}
 	}
 
-	// Verify if the function has any registered autohandles
-	internal->hasAutoHandles = false;
-	for( n = 0; n < internal->paramAutoHandles.GetLength(); n++ )
+	// Prepare the clean up instructions for the function arguments
+	internal->cleanArgs.SetLength(0);
+	int offset = 0;
+	for( n = 0; n < func->parameterTypes.GetLength(); n++ )
 	{
-		if( internal->paramAutoHandles[n] )
+		asCDataType &dt = func->parameterTypes[n];
+
+#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
+		bool needFree = false;
+#ifdef COMPLEX_OBJS_PASSED_BY_REF
+		if( dt.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
+#endif
+#ifdef AS_LARGE_OBJS_PASSED_BY_REF
+		if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
+#endif
+		if( needFree &&
+			dt.IsObject() &&
+			!dt.IsObjectHandle() && 
+			!dt.IsReference() )
 		{
-			internal->hasAutoHandles = true;
-			break;
+			asSSystemFunctionInterface::SClean clean;
+			clean.op  = 1; // call free
+			clean.ot  = dt.GetObjectType();
+			clean.off = short(offset);
+
+#ifndef AS_CALLEE_DESTROY_OBJ_BY_VAL
+			// If the called function doesn't destroy objects passed by value we must do so here
+			asSTypeBehaviour *beh = &dt.GetObjectType()->beh;
+			if( beh->destruct )
+				clean.op = 2; // call destruct, then free
+#endif
+
+			internal->cleanArgs.PushLast(clean);
 		}
+#endif
+
+		if( n < internal->paramAutoHandles.GetLength() && internal->paramAutoHandles[n] )
+		{
+			asSSystemFunctionInterface::SClean clean;
+			clean.op  = 0; // call release
+			clean.ot  = dt.GetObjectType();
+			clean.off = short(offset);
+			internal->cleanArgs.PushLast(clean);
+		}
+
+		if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
+			offset += AS_PTR_SIZE;
+		else
+			offset += dt.GetSizeOnStackDWords();
 	}
 #endif // !defined(AS_MAX_PORTABILITY)
 	return 0;
@@ -406,13 +497,14 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 
 #ifdef AS_MAX_PORTABILITY
 
-int CallSystemFunction(int id, asCContext *context, void *objectPointer)
+int CallSystemFunction(int id, asCContext *context)
 {
 	asCScriptEngine *engine = context->m_engine;
-	asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
+	asCScriptFunction *func = engine->scriptFunctions[id];
+	asSSystemFunctionInterface *sysFunc = func->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 	if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
-		return context->CallGeneric(id, objectPointer);
+		return context->CallGeneric(func);
 
 	context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
 
@@ -436,17 +528,15 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 // args       - This is the function arguments, which are packed as in AngelScript
 // retPointer - This points to a the memory buffer where the return object is to be placed, if the function returns the value in memory rather than in registers
 // retQW2     - This output parameter should be used if the function returns a value larger than 64bits in registers
+// secondObj  - This is the object pointer that the proxy method should invoke its method on when the call convention is THISCALL_OBJFIRST/LAST
 //
 // Return value:
 //
 // The function should return the value that is returned in registers. 
-//
-// When thiscall functors are enabled (!AS_NO_THISCALL_FUNCTOR_METHOD) the 
-// obj argument is a an array of 2 void* holding the two possible this pointers
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2);
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObj);
 
 
-int CallSystemFunction(int id, asCContext *context, void *objectPointer)
+int CallSystemFunction(int id, asCContext *context)
 {
 	asCScriptEngine            *engine  = context->m_engine;
 	asCScriptFunction          *descr   = engine->scriptFunctions[id];
@@ -454,7 +544,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 
 	int callConv = sysFunc->callConv;
 	if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
-		return context->CallGeneric(id, objectPointer);
+		return context->CallGeneric(descr);
 
 	asQWORD  retQW             = 0;
 	asQWORD  retQW2            = 0;
@@ -464,6 +554,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 
 #ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	void    *obj               = 0;
+	void    *secondObj         = 0;
 
 	if( callConv >= ICC_THISCALL )
 	{
@@ -471,11 +562,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 		{
 			// This class method is being called as if it is a global function
 			obj = sysFunc->objForThiscall;
-			asASSERT( objectPointer == 0 );
-		}
-		else if( objectPointer )
-		{
-			obj = objectPointer;
 		}
 		else
 		{
@@ -491,7 +577,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			}
 
 			// Add the base offset for multiple inheritance
-#if defined(__GNUC__) && defined(AS_ARM)
+#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
 			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
 			// and the whole offset is thus shifted one bit left to keep the original
 			// offset resolution
@@ -510,7 +596,8 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	//                 objForArg is the object pointer that should be passed as argument when using OBJFIRST or OBJLAST
 
 	// Used to save two object pointers with THISCALL_OBJLAST or THISCALL_OBJFIRST
-	void* objectsPtrs[2] = { 0, 0 };
+	void *obj               = 0;
+	void *secondObj         = 0;
 
 	if( callConv >= ICC_THISCALL )
 	{
@@ -521,55 +608,53 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 		{
 			asASSERT( sysFunc->objForThiscall != 0 );
 			// This class method is being called as object method (sysFunc->objForThiscall must be set).
-			objectsPtrs[0] = sysFunc->objForThiscall;
+			obj = sysFunc->objForThiscall;
 			continueCheckIndex = 1;
 		}
 		else if( sysFunc->objForThiscall )
 		{
 			// This class method is being called as if it is a global function
-			objectsPtrs[0] = sysFunc->objForThiscall;
+			obj = sysFunc->objForThiscall;
 			continueCheck = false;
-			asASSERT( objectPointer == 0 );
 		}
 
 		if( continueCheck )
 		{
 			void *tempPtr = 0;
-			if( objectPointer )
+
+			// The object pointer should be popped from the context stack
+			popSize += AS_PTR_SIZE;
+
+			// Check for null pointer
+			tempPtr = (void*)*(asPWORD*)(args);
+			if( tempPtr == 0 )
 			{
-				tempPtr = objectPointer;
+				context->SetInternalException(TXT_NULL_POINTER_ACCESS);
+				return 0;
 			}
-			else
-			{
-				// The object pointer should be popped from the context stack
-				popSize += AS_PTR_SIZE;
-
-				// Check for null pointer
-				tempPtr = (void*)*(asPWORD*)(args);
-				if( tempPtr == 0 )
-				{
-					context->SetInternalException(TXT_NULL_POINTER_ACCESS);
-					return 0;
-				}
 
-				// Add the base offset for multiple inheritance
-#if defined(__GNUC__) && defined(AS_ARM)
-				// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
-				// and the whole offset is thus shifted one bit left to keep the original
-				// offset resolution
-				tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
+			// Add the base offset for multiple inheritance
+#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
+			// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
+			// and the whole offset is thus shifted one bit left to keep the original
+			// offset resolution
+			tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
 #else
-				tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
+			tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
 #endif
 
-				// Skip the object pointer
-				args += AS_PTR_SIZE;
-			}
+			// Skip the object pointer
+			args += AS_PTR_SIZE;
 
-			objectsPtrs[continueCheckIndex] = tempPtr;
+			if( continueCheckIndex )
+				secondObj = tempPtr;
+			else
+			{
+				asASSERT( obj == 0 );
+				obj = tempPtr;
+			}
 		}
 	}
-	void *obj = &objectsPtrs[0]; // Get the pointer to first element
 #endif // AS_NO_THISCALL_FUNCTOR_METHOD
 
 	if( descr->DoesReturnOnStack() )
@@ -592,7 +677,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	context->m_callingSystemFunction = descr;
 	bool cppException = false;
 #ifdef AS_NO_EXCEPTIONS
-	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
+	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
 #else
 	// This try/catch block is to catch potential exception that may 
 	// be thrown by the registered function. The implementation of the
@@ -601,7 +686,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	// executed in case of an exception.
 	try
 	{
-		retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
+		retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
 	}
 	catch(...)
 	{
@@ -614,51 +699,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 #endif
 	context->m_callingSystemFunction = 0;
 
-#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
-	if( sysFunc->takesObjByVal )
-	{
-		// Need to free the complex objects passed by value, but that the 
-		// calling convention implicitly passes by reference behind the scene as the 
-		// calling function is the owner of that memory.
-
-		// args is pointing to the first real argument as used in CallSystemFunctionNative,
-		// i.e. hidden arguments such as the object pointer and return address have already 
-		// been skipped.
-
-		int spos = 0;
-		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
-		{
-			bool needFree = false;
-			asCDataType &dt = descr->parameterTypes[n];
-#ifdef COMPLEX_OBJS_PASSED_BY_REF
-			if( dt.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
-#endif
-#ifdef AS_LARGE_OBJS_PASSED_BY_REF
-			if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
-#endif
-			if( needFree &&
-				dt.IsObject() &&
-				!dt.IsObjectHandle() && 
-				!dt.IsReference() )
-			{
-				void *obj = (void*)*(asPWORD*)&args[spos];
-				spos += AS_PTR_SIZE;
-
-#ifndef AS_CALLEE_DESTROY_OBJ_BY_VAL
-				// If the called function doesn't destroy objects passed by value we must do so here
-				asSTypeBehaviour *beh = &dt.GetObjectType()->beh;
-				if( beh->destruct )
-					engine->CallObjectMethod(obj, beh->destruct);
-#endif
-
-				engine->CallFree(obj);
-			}
-			else
-				spos += dt.GetSizeOnStackDWords();
-		}
-	}
-#endif
-
 	// Store the returned value in our stack
 	if( descr->returnType.IsObject() && !descr->returnType.IsReference() )
 	{
@@ -777,27 +817,36 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 			context->m_regs.valueRegister = retQW;
 	}
 
-	// Release autohandles in the arguments
-	if( sysFunc->hasAutoHandles )
+	// Clean up arguments
+	const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
+	if( cleanCount )
 	{
 		args = context->m_regs.stackPointer;
-		if( callConv >= ICC_THISCALL && !objectPointer )
+		if( callConv >= ICC_THISCALL )
 			args += AS_PTR_SIZE;
 
-		int spos = 0;
-		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
+		asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
+		for( asUINT n = 0; n < cleanCount; n++, clean++ )
 		{
-			if( sysFunc->paramAutoHandles[n] && *(asPWORD*)&args[spos] != 0 )
+			void **addr = (void**)&args[clean->off];
+			if( clean->op == 0 )
 			{
-				// Call the release method on the type
-				engine->CallObjectMethod((void*)*(asPWORD*)&args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
-				*(asPWORD*)&args[spos] = 0;
+				if( *addr != 0 )
+				{
+					engine->CallObjectMethod(*addr, clean->ot->beh.release);
+					*addr = 0;
+				}
 			}
+			else 
+			{
+				asASSERT( clean->op == 1 || clean->op == 2 );
+				asASSERT( *addr );
 
-			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
-				spos += AS_PTR_SIZE;
-			else
-				spos += descr->parameterTypes[n].GetSizeOnStackDWords();
+				if( clean->op == 2 )
+					engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
+				
+				engine->CallFree(*addr);
+			}
 		}
 	}
 

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

@@ -46,6 +46,7 @@ BEGIN_AS_NAMESPACE
 class asCContext;
 class asCScriptEngine;
 class asCScriptFunction;
+class asCObjectType;
 struct asSSystemFunctionInterface;
 
 int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal);
@@ -54,7 +55,7 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
 
 int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
 
-int CallSystemFunction(int id, asCContext *context, void *objectPointer);
+int CallSystemFunction(int id, asCContext *context);
 
 inline asPWORD FuncPtrToUInt(asFUNCTION_t func)
 {
@@ -105,11 +106,18 @@ struct asSSystemFunctionInterface
 	int                  hostReturnSize;
 	int                  paramSize;
 	bool                 takesObjByVal;
-	asCArray<bool>       paramAutoHandles;
+	asCArray<bool>       paramAutoHandles; // TODO: Should be able to remove this array. Perhaps the flags can be stored together with the inOutFlags in asCScriptFunction?
 	bool                 returnAutoHandle;
-	bool                 hasAutoHandles;
 	void                *objForThiscall;
 
+	struct SClean
+	{
+		asCObjectType *ot; // argument type for clean up
+		short op;          // clean up operation: 0 = release, 1 = free, 2 = destruct then free
+		short off;         // argument offset on the stack
+	};
+	asCArray<SClean>     cleanArgs;
+
 	asSSystemFunctionInterface() {}
 
 	asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
@@ -130,8 +138,8 @@ struct asSSystemFunctionInterface
 		takesObjByVal      = in.takesObjByVal;
 		paramAutoHandles   = in.paramAutoHandles;
 		returnAutoHandle   = in.returnAutoHandle;
-		hasAutoHandles     = in.hasAutoHandles;
 		objForThiscall     = in.objForThiscall;
+		cleanArgs          = in.cleanArgs;
 		return *this;
 	}
 };

+ 9 - 49
Source/ThirdParty/AngelScript/source/as_callfunc_arm.cpp

@@ -73,7 +73,7 @@ extern "C" asQWORD armFuncR0R1      (const asDWORD *, int, asFUNCTION_t, asDWORD
 extern "C" asQWORD armFuncObjLast   (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
 extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
 {
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
@@ -89,40 +89,28 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// The return is made in memory
 		callConv++;
 	}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
 	bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
-#endif
+
 
 	asDWORD paramBuffer[64+2];
 	// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
 	// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this 
 	//                         doesn't have to be done for functions that don't have any 64bit types
 #if !defined(AS_ANDROID) && !defined(AS_LINUX)
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-	if( sysFunc->takesObjByVal )
-#else
 	// In cases of thiscall methods, the callstack is configured as a standard thiscall
 	// adding the secondObject as first or last element in callstack
 	if( sysFunc->takesObjByVal || isThisCallMethod )
-#endif
 #endif
 	{
 #if defined(AS_ANDROID) || defined(AS_LINUX)
 		// mask is used as a toggler to skip uneven registers.
 		int mask = 1;
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod )
 		{
 			mask = 0;
 		}
 		else
-#endif
 		{
 			// Check for object pointer as first argument
 			switch( callConv )
@@ -148,7 +136,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		int spos = 0;
 		int dpos = 2;
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
 			callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
 		{
@@ -156,7 +143,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			paramBuffer[dpos++] = (asDWORD)secondObject;
 			paramSize++;
 		}
-#endif
+
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 			// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
@@ -213,7 +200,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			}
 		}
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
 			callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
 		{
@@ -221,7 +207,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			paramBuffer[dpos++] = (asDWORD)secondObject;
 			paramSize++;
 		}
-#endif
+
 		// Keep a free location at the beginning
 		args = &paramBuffer[2];
 	}
@@ -238,17 +224,13 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 	case ICC_THISCALL:  // fall through
 	case ICC_CDECL_OBJFIRST:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST:
 	case ICC_THISCALL_OBJLAST:
-#endif
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		break;
 	case ICC_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 #ifdef __GNUC__
 		// On GNUC the address where the return value will be placed should be put in R0
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
@@ -261,19 +243,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST:
 	case ICC_VIRTUAL_THISCALL_OBJLAST:
-#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 #ifdef __GNUC__
@@ -316,7 +294,7 @@ extern "C" asQWORD armFuncR0R1      (const asDWORD *, int, asFUNCTION_t, asDWORD
 extern "C" asQWORD armFuncObjLast   (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
 extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
 {
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
@@ -368,14 +346,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		callConv++;
 	}
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
 	bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
-#endif
 
 	// Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
 	// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this 
@@ -384,13 +355,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// mask is used as a toggler to skip uneven registers.
 		int mask = 1;
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod )
 		{
 			mask = 0;
 		}
 		else
-#endif
 		{
 			// Check for object pointer as first argument
 			switch( callConv )
@@ -415,7 +384,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		int spos = 0;
 		int dpos = 2;
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
 			callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
 		{
@@ -423,11 +391,12 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			paramBuffer[dpos++] = (asDWORD)secondObject;
 			paramSize++;
 		}
-#endif
+
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
 			// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
-			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
+			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
+				!(descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_ARRAY) )
 			{
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
@@ -589,7 +558,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			}// else...
 		}// Loop
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 		if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
 			callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
 		{
@@ -604,7 +572,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 				stackSize++;
 			}
 		}
-#endif
+
 		// Keep a free location at the beginning
 		args = &paramBuffer[2];
 	}
@@ -623,17 +591,13 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 	case ICC_THISCALL:  // fall through
 	case ICC_CDECL_OBJFIRST:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST:
 	case ICC_THISCALL_OBJLAST:
-#endif
 		retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
 		break;
 	case ICC_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 		// On GNUC the address where the return value will be placed should be put in R0
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
@@ -641,19 +605,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST:
 	case ICC_VIRTUAL_THISCALL_OBJLAST:
-#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
 		break;
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 		// Get virtual function table from the object pointer
 		vftable = *(asFUNCTION_t**)obj;
 		// On GNUC the address where the return value will be placed should be put in R0

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

@@ -1,6 +1,6 @@
 /*
   AngelCode Scripting Library
-  Copyright (c) 2003-2013 Andreas Jonsson
+  Copyright (c) 2003-2014 Andreas Jonsson
 
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any
@@ -488,6 +488,7 @@ armFuncR0ObjLast:
     strge   r7, [r6, #8]
 
     str     r5, [r6, #12]           /* Put objlast in r6 + 12 */
+    mov     r5, #0
 
     movge   r5, #4                  /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
     add     r5, r5, #4              /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */

+ 2 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_arm_msvc.asm

@@ -1,6 +1,6 @@
 ;
 ;  AngelCode Scripting Library
-;  Copyright (c) 2003-2013 Andreas Jonsson
+;  Copyright (c) 2003-2014 Andreas Jonsson
 ;
 ;  This software is provided 'as-is', without any express or implied
 ;  warranty. In no event will the authors be held liable for any
@@ -29,7 +29,7 @@
 ;
 
 
-; Assembly routines for the ARM call convention
+; Assembly routines for the ARM call convention used for Windows CE
 ; Written by Fredrik Ehnbom in June 2009
 
 ; MSVC currently doesn't support inline assembly for the ARM platform

+ 480 - 0
Source/ThirdParty/AngelScript/source/as_callfunc_arm_vita.S

@@ -0,0 +1,480 @@
+/*
+  AngelCode Scripting Library
+  Copyright (c) 2003-2013 Andreas Jonsson
+
+  This software is provided 'as-is', without any express or implied
+  warranty. In no event will the authors be held liable for any
+  damages arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any
+  purpose, including commercial applications, and to alter it and
+  redistribute it freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you
+     must not claim that you wrote the original software. If you use
+     this software in a product, an acknowledgment in the product
+     documentation would be appreciated but is not required.
+
+  2. Altered source versions must be plainly marked as such, and
+     must not be misrepresented as being the original software.
+
+  3. This notice may not be removed or altered from any source
+     distribution.
+
+  The original version of this library can be located at:
+  http://www.angelcode.com/angelscript/
+
+  Andreas Jonsson
+  [email protected]
+*/
+
+/*
+   Assembly routines for the Playstation Vita SNC call convention.
+
+   This code was adapted from as_callfunc_arm_gcc (ARM, Linux hard float) by Brandon Bare on October 2014.
+*/
+
+#ifdef __psp2__
+
+.syntax unified
+.cpu cortex-a9
+.fpu neon
+
+.section .text.armCallFunc
+.balign 2
+.thumb
+.thumb_func
+
+.align 2
+
+.global armFunc
+.global armFuncR0
+.global armFuncR0R1
+.global armFuncObjLast
+.global armFuncR0ObjLast
+
+.type armFunc, %function
+.type armFuncR0, %function
+.type armFuncR0R1, %function
+.type armFuncObjLast, %function
+.type armFuncR0ObjLast, %function
+
+/* --------------------------------------------------------------------------------------------*/
+armFunc:
+	.fnstart
+
+    push    {r4-r8, r10, r11, lr}   /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+
+    /* Load float and double args into d0-d7 and s0-s15 */
+    add       r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
+    mov       r8, #0
+    vldmia.64 r10, {d0-d7}  /* Load contents starting at r10 into registers d0-d7 */
+
+    /* If there are no arguments to set into r0-r3 */
+    /* go check if there are arguments for the stack */
+    beq     stackargs
+
+    /* Load the first 4 arguments into r0-r3 */
+    cmp     r7, #4
+
+	it ge
+    ldrge   r0, [r6]
+    cmp     r7, #8
+
+	it ge
+    ldrge   r1, [r6, #4]
+    cmp     r7, #12
+
+	it ge
+    ldrge   r2, [r6, #8]
+    cmp     r7, #16
+
+	it ge
+    ldrge   r3, [r6, #12]
+
+stackargs:
+    ldr     r5, [r6, #268]  /* Load stack size into r5 */
+    movs    r7, r5          /* Load stack size into r7, checking for 0 args */
+
+    /* If there are no args for the stack, branch */
+    beq     nomoreargs
+
+    /* Load the rest of the arguments onto the stack */
+    /* Ensure 8-byte stack alignment */
+    mov     r8, sp
+    sub     sp, sp, r7
+    add     r6, r6, #16     /* Set r6 to point to the first arg to be placed on the stack */
+
+    sub     r12, sp, #8
+    bic     r12, r12, #7    /* thumb mode couldn't support "bic  sp, sp, #7" instruction */
+    sub     r8, r8, r12
+    mov     sp, r12         /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
+
+stackargsloop:
+    ldr     r5, [r6], #4
+    subs    r7, r7, #4
+    str     r5, [sp], #4
+    bne     stackargsloop
+    mov     sp, r12
+
+nomoreargs:
+    blx     r4
+    add     sp, sp, r8
+    vstmia.64 r10, {d0-d7}   /* Copy contents of registers d0-d7 to the address stored in r10 */
+
+    pop {r4-r8, r10, r11, pc}
+
+	.fnend
+
+/* --------------------------------------------------------------------------------------------*/
+armFuncObjLast:
+	.fnstart
+
+    push {r4-r8, r10, r11, lr}  /* We´re storing r11 just to keep the stack aligned to an 8 byte boundary */
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+
+    mov     r0, r3          /* objlast. might get overwritten */
+    mov     r5, #0          /* This will hold an offset of #4 only if objlast couldn´t be placed into an "r" register */
+
+    /* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
+    add     r10, r6, #272   /* r10 (r6 + 272) points to the first value for the VFP registers */
+    mov     r8, #0
+    vldmia.64 r10, {d0-d7}  /* Load contents starting at r10 into registers d0-d7 */
+
+    /* If there are no arguments to set into r0-r3 */
+    /* go check if there are arguments for the stack */
+    beq     stackargsFuncObjLast
+
+    mov     r5, r3          /* store objlast in r5 temporarily */
+
+    /* Load the first 4 arguments into r0-r3 */
+    cmp     r7, #4
+
+	it ge
+    ldrge   r0, [r6]
+    cmp     r7, #8
+
+	it ge
+    ldrge   r1, [r6,#4]
+
+	it lt
+    movlt   r1, r5
+    cmp     r7, #12
+
+	it ge
+    ldrge   r2, [r6,#8]
+
+	it lt
+    movlt   r2, r5
+    cmp     r7, #16
+
+	it ge
+    ldrge   r3, [r6,#12]
+
+	ittt lt
+    movlt   r3, r5
+    movlt   r5, #0                  /* If objlast got placed into a register, r5 = 0 */
+    blt     stackargsFuncObjLast    /* If objlast got placed into a register, go to stackargsFuncObjLast */
+
+    str     r5, [r6, #12]           /* Put objlast in r6 + 12 */
+    mov     r5, #4                  /* Set r5 with an offset of #4, so objlast can be loaded into the stack */
+
+stackargsFuncObjLast:
+    ldr     r7, [r6, #268]  /* Load stack size into r7 */
+    add     r7, r7, r5      /* Add the offset placed in r5 (could be #0 or #4) */
+    cmp     r7, #0          /* Check for 0 args */
+
+    /* If there are no args for the stack, branch */
+    beq     nomoreargsarmFuncObjLast
+
+    /* Load the rest of the arguments onto the stack */
+    /* Ensure 8-byte stack alignment */
+    mov     r8, sp
+    sub     sp, sp, r7
+    add     r6, r6, #16     /* Set r6 to point to the first arg to be placed on the stack */
+
+    sub     r12, sp, #8
+    sub     r6, r6, r5      /* r6 = r6 - r5 (r5 can be #0 or #4) */
+    bic     r12, r12, #7    /* thumb mode couldn't support "bic  sp, sp, #7" instruction */
+    sub     r8, r8, r12
+    mov     sp, r12         /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
+
+stackargslooparmFuncObjLast:
+    ldr     r5, [r6], #4
+    subs    r7, r7, #4
+    str     r5, [sp], #4
+    bne     stackargslooparmFuncObjLast
+    mov     sp, r12
+
+nomoreargsarmFuncObjLast:
+    blx     r4
+    add     sp, sp, r8
+    vstmia.64   r10, {d0-d7}    /* Copy contents of registers d0-d10 to the address stored in r10 */
+
+    pop   {r4-r8, r10,r11, pc}
+
+	.fnend
+
+/* --------------------------------------------------------------------------------------------*/
+armFuncR0ObjLast:
+	.fnstart
+
+    push    {r4-r8, r10, r11, lr}
+
+    ldr     r5, [sp,#32]   /* objlast to temp reg */
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+
+    mov     r0, r3      /* r0 explicitly set */
+    mov     r1, r5      /* objlast.  might get overwritten */
+    mov     r5, #0      /* This will hold an offset of #4 or #8 if objlast or one arg couldn´t be placed into an "r" register */
+
+    /* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
+    add     r10, r6, #272   /* r10 (r6 + 272) points to the first value for the VFP registers */
+    mov     r8, #0
+    vldmia.64 r10, {d0-d7}  /* Load contents starting at r10 into registers d0-d7 */
+
+    /* If there are no arguments to set into r0-r3 */
+    /* go check if there are arguments for the stack */
+    beq     stackargsFuncR0ObjLast
+
+    mov     r5, r1          /* store objlast in r5 temporarily */
+
+    /* Load the first 3 arguments into r1-r3 */
+    cmp     r7, #4
+
+	it ge
+    ldrge   r1, [r6]
+    cmp     r7, #8
+
+	it ge
+    ldrge   r2, [r6,#4]
+
+	it lt
+    movlt   r2, r5
+    cmp     r7, #12
+
+	it ge
+    ldrge   r3, [r6,#8]
+
+	ittt lt
+    movlt   r3, r5
+    movlt   r5, #0                  /* If objlast got placed into a register, r5 = 0 */
+    blt     stackargsFuncR0ObjLast  /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
+
+    cmp     r7, #16                 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
+
+	itt ge
+    ldrge   r7, [r6, #12]
+    strge   r7, [r6, #8]
+
+    str     r5, [r6, #12]           /* Put objlast in r6 + 12 */
+	mov     r5, #0
+
+	it ge
+    movge   r5, #4                  /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
+    add     r5, r5, #4              /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
+
+stackargsFuncR0ObjLast:
+    ldr     r7, [r6, #268]  /* Load stack size into r7 */
+    add     r7, r7, r5      /* Add the offset placed in r5 (could be #0 or #4) */
+    cmp     r7, #0          /* Check for 0 args */
+
+    /* If there are no args for the stack, branch */
+    beq     nomoreargsarmFuncR0ObjLast
+
+    /* Load the rest of the arguments onto the stack */
+    /* Ensure 8-byte stack alignment */
+    mov     r8, sp
+    sub     sp, sp, r7
+    add     r6, r6, #16     /* Set r6 to point to the first arg to be placed on the stack */
+
+    sub     r12, sp, #8
+    sub     r6, r6, r5      /* r6 = r6 - r5 (r5 can be #0 or #4) */
+    bic     r12, r12, #7    /* thumb mode couldn't support "bic  sp, sp, #7" instruction */
+    sub     r8, r8, r12
+    mov     sp, r12         /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
+
+stackargslooparmFuncR0ObjLast:
+    ldr     r5, [r6], #4
+    subs    r7, r7, #4
+    str     r5, [sp], #4
+    bne     stackargslooparmFuncR0ObjLast
+    mov     sp, r12
+
+nomoreargsarmFuncR0ObjLast:
+    blx     r4
+    add     sp, sp, r8
+    vstmia.64   r10, {d0-d7}    /* Copy contents of registers d0-d10 to the address stored in r10 */
+
+    pop {r4-r8, r10, r11, pc}
+
+	.fnend
+
+/* --------------------------------------------------------------------------------------------*/
+armFuncR0:
+	.fnstart
+
+    push {r4-r8, r10, r11, lr}
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r11, #0 /* This will hold an offset of #4 only if the last arg that should have been placed into an "r" reg needs to go to the stack */
+    mov     r0, r3  /* r0 explicitly set */
+
+    /* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
+    add     r10, r6, #272   /* r10 (r6 + 272) points to the first value for the VFP registers */
+    mov     r8, #0
+    vldmia.64 r10, {d0-d7}  /* Load contents starting at r10 into registers d0-d7 */
+
+    /* If there are no arguments to set into r0-r3 */
+    /* go check if there are arguments for the stack */
+    beq     stackargsarmFuncR0
+
+    /* Load the first 3 arguments into r1-r3 */
+    cmp     r7, #4
+
+	it ge
+    ldrge   r1, [r6]
+    cmp     r7, #8
+
+	it ge
+    ldrge   r2, [r6, #4]
+    cmp     r7, #12
+
+	it ge
+    ldrge   r3, [r6, #8]
+    cmp     r7, #16
+
+	it ge
+    movge   r11, #4         /* If there is still one arg to be placed, set the offset in r11 to #4 */
+
+stackargsarmFuncR0:
+    ldr     r5, [r6, #268]  /* Load stack size into r5 */
+    add     r5, r11         /* Add the offset placed in r11 (could be #0 or #4) */
+    movs    r7, r5          /* Load stack size into r7, checking for 0 args */
+
+    /* If there are no args for the stack, branch */
+    beq     nomoreargsarmFuncR0
+
+    /* Load the rest of the arguments onto the stack */
+    /* Ensure 8-byte stack alignment */
+    mov     r8, sp
+    sub     sp, sp, r7
+    add     r6, r6, #16     /* Set r6 to point to the first arg to be placed on the stack */
+
+    sub     r12, sp, #8
+    sub     r6, r6, r11     /* r6 = r6 - r11 (r11 can be #0 or #4) */
+    bic     r12, r12, #7    /* thumb mode couldn't support "bic  sp, sp, #7" instruction */
+    sub     r8, r8, r12
+    mov     sp, r12         /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
+
+stackargslooparmFuncR0:
+    ldr     r5, [r6], #4
+    subs    r7, r7, #4
+    str     r5, [sp], #4
+    bne     stackargslooparmFuncR0
+    mov     sp, r12
+
+nomoreargsarmFuncR0:
+    blx     r4
+    add     sp, sp, r8
+    vstmia.64   r10, {d0-d7}    /* Copy contents of registers d0-d10 to the address stored in r10 */
+
+    pop {r4-r8, r10, r11, pc}
+
+	.fnend
+
+/* --------------------------------------------------------------------------------------------*/
+armFuncR0R1:
+	.fnstart
+
+    push {r4-r8, r10, r11, lr}
+
+    mov     r6, r0  /* arg table */
+    movs    r7, r1  /* arg size (also set the condition code flags so that we detect if there are no arguments) */
+    mov     r4, r2  /* function address */
+    mov     r11, #0 /* This will hold an offset of #4 or #8 only if the last arg (or last 2 args) that should have been placed into "r" regs need to go to the stack */
+
+    mov     r0, r3          /* r0 explicitly set */
+    ldr     r1, [sp, #32]   /* r1 explicitly set too */
+
+    /* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
+    add     r10, r6, #272   /* r10 (r6 + 272) points to the first value for the VFP registers */
+    mov     r8, #0
+    vldmia.64 r10, {d0-d7}  /* Load contents starting at r10 into registers d0-d7 */
+
+    /* If there are no arguments to set into r2-r3 */
+    /* go check if there are arguments for the stack */
+    beq     stackargsarmFuncR0R1
+
+    /* Load the first 2 arguments into r2-r3 */
+    cmp     r7, #4
+
+	it ge
+    ldrge   r2, [r6]
+    cmp     r7, #8
+
+	it ge
+    ldrge   r3, [r6, #4]
+    cmp     r7, #12
+
+	it ge
+    movge   r11, #4         /* If there is a third arg to be placed, set the offset in r11 to #4 */
+
+    cmp     r7, #16
+
+	it ge
+    movge   r11, #8         /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
+
+	itt lt
+    ldrlt   r7, [r6, #8]    /* Else copy the third arg to the correct place in the array */
+    strlt   r7, [r6, #12]
+
+stackargsarmFuncR0R1:
+    ldr     r5, [r6, #268]  /* Load stack size into r5 */
+    add     r5, r11         /* Add the offset placed in r11 (could be #0 or #4 or #8) */
+    movs    r7, r5          /* Load stack size into r7, checking for 0 args */
+
+    /* If there are no args for the stack, branch */
+    beq     nomoreargsarmFuncR0R1
+
+    /* Load the rest of the arguments onto the stack */
+    /* Ensure 8-byte stack alignment */
+    mov     r8, sp
+    sub     sp, sp, r7
+    add     r6, r6, #16     /* Set r6 to point to the first arg to be placed on the stack */
+
+    sub     r12, sp, #8
+    sub     r6, r6, r11     /* r6 = r6 - r11 (r11 can be #0 or #4 or #8) */
+    bic     r12, r12, #7    /* thumb mode couldn't support "bic  sp, sp, #7" instruction */
+    sub     r8, r8, r12
+    mov     sp, r12         /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
+
+stackargslooparmFuncR0R1:
+    ldr     r5, [r6], #4
+    subs    r7, r7, #4
+    str     r5, [sp], #4
+    bne     stackargslooparmFuncR0R1
+    mov     sp, r12
+
+nomoreargsarmFuncR0R1:
+    blx     r4
+    add     sp, sp, r8
+    vstmia.64   r10, {d0-d7}    /* Copy contents of registers d0-d10 to the address stored in r10 */
+
+    pop {r4-r8, r10, r11, pc}
+
+	.fnend
+
+#endif

+ 4 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_mips.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -221,12 +221,14 @@ asQWORD GetReturnedDouble()
 	return d;
 }
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
 {
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	int callConv = sysFunc->callConv;
 
+	// TODO: Mips does not yet support THISCALL_OBJFIRST/LAST
+
 	asQWORD retQW = 0;
 
 	void    *func              = (void*)sysFunc->func;

+ 4 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_ppc.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -482,8 +482,10 @@ static asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD* pArg
 	return ppcFunc( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
 }
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
 {
+	// TODO: PPC does not yet support THISCALL_OBJFIRST/LAST
+
 	// use a working array of types, we'll configure the final one in stackArgs
 	asBYTE argsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	memset( argsType, 0, sizeof(argsType));

+ 6 - 3
Source/ThirdParty/AngelScript/source/as_callfunc_ppc_64.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -547,8 +547,10 @@ 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*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
 {
+	// TODO: PPC 64 does not yet support THISCALL_OBJFIRST/LAST
+
 	// use a working array of types, we'll configure the final one in stackArgs
 	asBYTE argsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
 	memset( argsType, 0, sizeof(argsType));
@@ -663,7 +665,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
-			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
+			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
+				!(descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_ARRAY) )
 			{
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )

+ 4 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_sh4.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -270,8 +270,10 @@ asQWORD GetReturnedDouble()
 	return d;
 }
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
 {
+	// TODO: SH4 does not yet support THISCALL_OBJFIRST/LAST
+
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	int callConv = sysFunc->callConv;

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

@@ -162,7 +162,7 @@ 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)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
 {
 	asCScriptEngine            *engine             = context->m_engine;
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
@@ -182,16 +182,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		callConv++;
 	}
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
-	// param_post has value 2 if is an THISCALL_OBJLAST
-#endif
-
-
 #ifdef AS_NO_THISCALL_FUNCTOR_METHOD
 	// Determine the real function pointer in case of virtual method
 	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) 

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

@@ -167,7 +167,7 @@ static asQWORD GetReturnedDouble()
 	return ret;
 }
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
 {
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
@@ -197,11 +197,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		callConv == ICC_VIRTUAL_THISCALL ||
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
 #else
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
 	// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
 	if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
 		(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )

+ 11 - 31
Source/ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp

@@ -51,7 +51,7 @@ extern "C" asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int pa
 extern "C" asDWORD GetReturnedFloat();
 extern "C" asQWORD GetReturnedDouble();
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
 {
 	asCScriptEngine *engine = context->m_engine;
 	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
@@ -66,21 +66,9 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 	int callConv = sysFunc->callConv;
 
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-	if( callConv == ICC_THISCALL ||
-		callConv == ICC_THISCALL_RETURNINMEM ||
-		callConv == ICC_VIRTUAL_THISCALL || 
-		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
-#else
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
 	// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
 	if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
 		(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
-#endif
 	{
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
@@ -101,7 +89,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	else if( callConv == ICC_THISCALL_OBJFIRST ||
 		callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
@@ -110,19 +97,13 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the first parameter
 		allArgBuffer[paramSize++] = (asQWORD)secondObject;
 	}
-#endif
 
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-	if( callConv == ICC_VIRTUAL_THISCALL ||
-		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
-#else
 	if( callConv == ICC_VIRTUAL_THISCALL ||
 		callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
-#endif
 	{
 		// Get the true function pointer from the virtual function table
 		vftable = *(void***)obj;
@@ -134,10 +115,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asUINT spos = 0;
 	for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 	{
-		if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
+		asCDataType &dt = descr->parameterTypes[n];
+		if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
 		{
-			if( descr->parameterTypes[n].GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
-				(descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )
+			if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
+				(dt.GetObjectType()->flags & COMPLEX_MASK) )
 			{
 				allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
 				spos += AS_PTR_SIZE;
@@ -146,18 +128,18 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 			else
 			{
 				// Copy the object's memory to the buffer
-				memcpy(&allArgBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
+				memcpy(&allArgBuffer[dpos], *(void**)(args+spos), dt.GetSizeInMemoryBytes());
 
 				// Delete the original memory
 				engine->CallFree(*(char**)(args+spos));
 				spos += AS_PTR_SIZE;
-				asUINT dwords = descr->parameterTypes[n].GetSizeInMemoryDWords();
+				asUINT dwords = dt.GetSizeInMemoryDWords();
 				asUINT qwords = (dwords >> 1) + (dwords & 1);
 				dpos      += qwords;
 				paramSize += qwords;
 			}
 		}
-		else if( descr->parameterTypes[n].GetTokenType() == ttQuestion )
+		else if( dt.GetTokenType() == ttQuestion )
 		{
 			// Copy the reference and the type id
 			allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
@@ -168,14 +150,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		else
 		{
 			// Copy the value directly
-			asUINT dwords = descr->parameterTypes[n].GetSizeOnStackDWords();
+			asUINT dwords = dt.GetSizeOnStackDWords();
 			if( dwords > 1 )
 			{
 				allArgBuffer[dpos] = *(asQWORD*)&args[spos];
 
 				// Double arguments are moved to a separate buffer in order to be placed in the XMM registers,
 				// though this is only done for first 4 arguments, the rest are placed on the stack
-				if( paramSize < 4 && descr->parameterTypes[n].IsDoubleType() )
+				if( paramSize < 4 && dt.IsDoubleType() )
 					floatArgBuffer[dpos] = *(asQWORD*)&args[spos];
 
 				dpos++;
@@ -187,7 +169,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 
 				// Float arguments are moved to a separate buffer in order to be placed in the XMM registers,
 				// though this is only done for first 4 arguments, the rest are placed on the stack
-				if( paramSize < 4 && descr->parameterTypes[n].IsFloatType() )
+				if( paramSize < 4 && dt.IsFloatType() )
 					floatArgBuffer[dpos] = args[spos];
 				
 				dpos++;
@@ -204,7 +186,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the last parameter
 		allArgBuffer[paramSize++] = (asQWORD)obj;
 	}
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	else if( callConv == ICC_THISCALL_OBJLAST ||
 		callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
 		callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
@@ -213,7 +194,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		// Add the object pointer as the last parameter
 		allArgBuffer[paramSize++] = (asQWORD)secondObject;
 	}
-#endif
 
 	retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
 

+ 2 - 28
Source/ThirdParty/AngelScript/source/as_callfunc_x86.cpp

@@ -28,7 +28,6 @@
    [email protected]
 */
 
-// Modified by Skrylar for Urho3D
 
 //
 // as_callfunc_x86.cpp
@@ -90,7 +89,7 @@ asQWORD CallThisCallFunctionRetByRef(const void *, const asDWORD *, int, asFUNCT
 asDWORD GetReturnedFloat();
 asQWORD GetReturnedDouble();
 
-asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
 {
 	asCScriptEngine            *engine    = context->m_engine;
 	asSSystemFunctionInterface *sysFunc   = descr->sysFuncIntf;
@@ -101,19 +100,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	asDWORD paramBuffer[64];
 	int callConv = sysFunc->callConv;
 
-#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
-	int paramSize = sysFunc->paramSize;
-	if( sysFunc->takesObjByVal )
-	{
-		paramSize = 0;
-		int spos = 0;
-		int dpos = 1;
-#else
-	// Unpack the two object pointers
-	void **objectsPtrs  = (void**)obj;
-	void  *secondObject = objectsPtrs[1];
-	obj                 = objectsPtrs[0];
-
 	// Changed because need check for ICC_THISCALL_OBJFIRST or
 	// ICC_THISCALL_OBJLAST if sysFunc->takesObjByVal (avoid copy code)
 	// Check if is THISCALL_OBJ* calling convention (in this case needs to add secondObject pointer into stack).
@@ -134,7 +120,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	if( sysFunc->takesObjByVal || isThisCallMethod )
 	{
 		int spos = 0;
-#endif // AS_NO_THISCALL_FUNCTOR_METHOD
 
 		for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 		{
@@ -180,7 +165,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		args = &paramBuffer[1];
 	}
 
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	if( isThisCallMethod && 
 		(callConv >= ICC_THISCALL_OBJLAST &&
 		 callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
@@ -189,7 +173,6 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		paramBuffer[dpos++] = (asDWORD)secondObject;
 		paramSize++;
 	}
-#endif // AS_NO_THISCALL_FUNCTOR_METHOD
 
 	// Make the actual call
 	asFUNCTION_t func = sysFunc->func;
@@ -220,26 +203,20 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 
 	case ICC_THISCALL:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST:
 	case ICC_THISCALL_OBJLAST:
-#endif
 		retQW = CallThisCallFunction(obj, args, paramSize<<2, func);
 		break;
 
 	case ICC_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 		retQW = CallThisCallFunctionRetByRef(obj, args, paramSize<<2, func, retPointer);
 		break;
 
 	case ICC_VIRTUAL_THISCALL:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST:
 	case ICC_VIRTUAL_THISCALL_OBJLAST:
-#endif
 		{
 			// Get virtual function table from the object pointer
 			asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;
@@ -248,10 +225,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		break;
 
 	case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
 	case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
 	case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
-#endif
 		{
 			// Get virtual function table from the object pointer
 			asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;
@@ -1288,8 +1263,7 @@ endcopy:
 		"subl  $4, %%ecx       \n"
 		"jne   copyloop3       \n"
 		"endcopy3:             \n"
-// Urho3D: modified to use a define set in as_config.h
-#ifdef AS_MINGW47_WORKAROUND
+#if defined(__MINGW32__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || __GNUC__ > 4)
         // MinGW made some strange choices with 4.7, and the thiscall calling convention
         // when returning an object in memory is completely different from when not returning
         // in memory

+ 4 - 2
Source/ThirdParty/AngelScript/source/as_callfunc_xenon.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -498,8 +498,10 @@ 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*/)
+asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
 {
+	// TODO: Xenon does not yet support THISCALL_OBJFIRST/LAST
+
 	asCScriptEngine            *engine    = context->m_engine;
 	asSSystemFunctionInterface *sysFunc   = descr->sysFuncIntf;	
 	int                         callConv  = sysFunc->callConv;

文件差异内容过多而无法显示
+ 417 - 276
Source/ThirdParty/AngelScript/source/as_compiler.cpp


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

@@ -103,6 +103,7 @@ struct asSExprContext
 		property_handle = false;
 		property_ref    = false;
 		methodName      = "";
+		enumValue       = "";
 	}
 	bool IsClassMethod()
 	{
@@ -213,13 +214,13 @@ protected:
 	int  CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
 	void CompileConstructCall(asCScriptNode *node, asSExprContext *out);
 	void CompileConversion(asCScriptNode *node, asSExprContext *out);
-	int  CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	void CompileOperatorOnHandles(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	void CompileMathOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	void CompileBitwiseOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	void CompileComparisonOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	void CompileBooleanOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
-	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool isHandle = false);
+	int  CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	void CompileOperatorOnHandles(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	void CompileMathOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	void CompileBitwiseOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	void CompileComparisonOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	void CompileBooleanOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
+	bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool isHandle = false, eTokenType opToken = ttUnrecognizedToken);
 	int  CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
 
 	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
@@ -240,6 +241,7 @@ protected:
 	// Helper functions
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
+	int  ProcessPropertyGetSetAccessor(asSExprContext *ctx, asSExprContext *lctx, asSExprContext *rctx, eTokenType op, asCScriptNode *errNode);
 	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
 	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, bool forceOnHeap = false);
@@ -260,7 +262,7 @@ protected:
 	int  PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
 	void PrepareArgument2(asSExprContext *ctx, asSExprContext *arg, asCDataType *paramType, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
 	bool IsLValue(asCTypeInfo &type);
-	int  DoAssignment(asSExprContext *out, asSExprContext *lctx, asSExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, int op, asCScriptNode *opNode);
+	int  DoAssignment(asSExprContext *out, asSExprContext *lctx, asSExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, eTokenType op, asCScriptNode *opNode);
 	void MergeExprBytecode(asSExprContext *before, asSExprContext *after);
 	void MergeExprBytecodeAndType(asSExprContext *before, asSExprContext *after);
 	void FilterConst(asCArray<int> &funcs, bool removeConst = true);

+ 40 - 11
Source/ThirdParty/AngelScript/source/as_config.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -241,6 +241,7 @@
 // AS_XBOX      - Microsoft XBox
 // AS_XBOX360   - Microsoft XBox 360
 // AS_PSP       - Sony Playstation Portable
+// AS_PSVITA    - Sony Playstation Vita
 // AS_PS2       - Sony Playstation 2
 // AS_PS3       - Sony Playstation 3
 // AS_DC        - Sega Dreamcast
@@ -490,7 +491,12 @@
 		#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 		#define COMPLEX_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
 		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
-		#define AS_SOFTFP
+	
+		// Windows CE uses softfp calling convention, while Windows RT uses hardfp calling convention
+		// ref: http://stackoverflow.com/questions/16375355/what-is-the-windows-rt-on-arm-native-code-calling-convention
+		#if defined(_WIN32_WCE)
+			#define AS_SOFTFP
+		#endif
 	#endif
 
 	#ifndef COMPLEX_MASK
@@ -530,13 +536,26 @@
 
 // SN Systems ProDG
 #if defined(__SNC__) || defined(SNSYS)
-	#define GNU_STYLE_VIRTUAL_METHOD
 	#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
 	#define CALLEE_POPS_HIDDEN_RETURN_POINTER
 	#define COMPLEX_OBJS_PASSED_BY_REF
-	#define ASM_AT_N_T  // AT&T style inline assembly
-	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
-	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+
+	#ifdef __psp2__
+		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+		#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+		#define CDECL_RETURN_SIMPLE_IN_MEMORY
+		#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+		#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+		#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+		#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
+	#else
+		#define GNU_STYLE_VIRTUAL_METHOD
+		#define ASM_AT_N_T  // AT&T style inline assembly
+		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+	#endif
+
 	#define AS_SIZEOF_BOOL 1
 	#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 
@@ -560,11 +579,22 @@
 		// Support native calling conventions on PS3
 		#define AS_PS3
 		#define AS_PPC_64
+		#define AS_NO_MEMORY_H
+		#define AS_NO_EXCEPTIONS
+		#include <stdlib.h>
 	// PSP
 	#elif defined(__psp__)
 		#define AS_NO_MEMORY_H
 		#define AS_MIPS
 		#define AS_PSP
+	// PSVita
+	#elif defined(__psp2__)
+		#define AS_PSVITA
+		#define AS_ARM
+		#define AS_NO_MEMORY_H
+		#define AS_NO_EXCEPTIONS
+		#define AS_CALLEE_DESTROY_OBJ_BY_VAL
+		#undef AS_NO_THISCALL_FUNCTOR_METHOD
 	#endif
 
 	#define UNREACHABLE_RETURN
@@ -574,11 +604,7 @@
 // Use the following command to determine predefined macros: echo . | g++ -dM -E -
 #if (defined(__GNUC__) && !defined(__SNC__)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
 	#define GNU_STYLE_VIRTUAL_METHOD
-#if !defined( __amd64__ )
-	#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
-#else
-	#define MULTI_BASE_OFFSET(x) (*((asQWORD*)(&x)+1))
-#endif
+	#define MULTI_BASE_OFFSET(x) (*((asPWORD*)(&x)+1))
 	#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 	#define CALLEE_POPS_HIDDEN_RETURN_POINTER
 	#define COMPLEX_OBJS_PASSED_BY_REF
@@ -833,6 +859,9 @@
 		#elif defined(__ARMEL__) || defined(__arm__)
 			#define AS_ARM
 
+			// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
+			#define AS_NO_EXCEPTIONS
+
 			#undef STDCALL
 			#define STDCALL
 

+ 30 - 71
Source/ThirdParty/AngelScript/source/as_configgroup.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -88,10 +88,29 @@ void asCConfigGroup::RefConfigGroup(asCConfigGroup *group)
 	group->AddRef();
 }
 
+void asCConfigGroup::AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func)
+{
+	AddReferencesForType(engine, func->returnType.GetObjectType());
+	for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
+		AddReferencesForType(engine, func->parameterTypes[n].GetObjectType());
+}
+
+void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCObjectType *type)
+{
+	if( type == 0 ) return;
+
+	// Keep reference to other groups
+	RefConfigGroup(engine->FindConfigGroupForObjectType(type));
+
+	// Keep track of which generated template instances the config group uses
+	if( type->flags & asOBJ_TEMPLATE && engine->generatedTemplateTypes.Exists(type) && !generatedTemplateInstances.Exists(type) )
+		generatedTemplateInstances.PushLast(type);
+}
+
 bool asCConfigGroup::HasLiveObjects()
 {
 	for( asUINT n = 0; n < objTypes.GetLength(); n++ )
-		if( objTypes[n]->GetRefCount() != 0 )
+		if( objTypes[n]->externalRefCount.get() != 0 )
 			return true;
 
 	return false;
@@ -123,7 +142,7 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 		int index = engine->registeredGlobalFuncs.GetIndex(scriptFunctions[n]);
 		if( index >= 0 )
 			engine->registeredGlobalFuncs.Erase(index);
-		scriptFunctions[n]->Release();
+		scriptFunctions[n]->ReleaseInternal();
 		if( engine->stringFactory == scriptFunctions[n] )
 			engine->stringFactory = 0;
 	}
@@ -141,12 +160,12 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 	for( n = 0; n < funcDefs.GetLength(); n++ )
 	{
 		engine->registeredFuncDefs.RemoveValue(funcDefs[n]);
-		funcDefs[n]->Release();
+		funcDefs[n]->ReleaseInternal();
+		engine->RemoveFuncdef(funcDefs[n]);
+		funcDefs[n]->ReleaseInternal();
 	}
 	funcDefs.SetLength(0);
 
-	engine->ClearUnusedTypes();
-
 	// Remove object types (skip this if it is possible other groups are still using the types)
 	if( !notUsed )
 	{
@@ -157,11 +176,8 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 			if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
 				cursor->value == t )
 			{
-#ifdef AS_DEBUG
-				ValidateNoUsage(engine, t);
-#endif
-
 				engine->allRegisteredTypes.Erase(cursor);
+
 				if( engine->defaultArrayObjectType == t )
 					engine->defaultArrayObjectType = 0;
 
@@ -174,21 +190,17 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 				else
 					engine->registeredObjTypes.RemoveValue(t);
 
-				asDELETE(t, asCObjectType);
+				t->DestroyInternal();
+				t->ReleaseInternal();
 			}
 			else
 			{
 				int idx = engine->templateInstanceTypes.IndexOf(t);
 				if( idx >= 0 )
 				{
-#ifdef AS_DEBUG
-					ValidateNoUsage(engine, t);
-#endif
-
 					engine->templateInstanceTypes.RemoveIndexUnordered(idx);
-					t->templateSubTypes.SetLength(0);
-
-					asDELETE(t, asCObjectType);
+					t->DestroyInternal();
+					t->ReleaseInternal();
 				}
 			}
 		}
@@ -201,57 +213,4 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
 	referencedConfigGroups.SetLength(0);
 }
 
-#ifdef AS_DEBUG
-void asCConfigGroup::ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type)
-{
-	for( asUINT n = 0; n < engine->scriptFunctions.GetLength(); n++ )
-	{
-		asCScriptFunction *func = engine->scriptFunctions[n];
-		if( func == 0 ) continue;
-
-		// Ignore factory, list factory, and members
-		if( func->name == "_beh_3_" || func->name == "_beh_4_" || func->objectType == type )
-			continue;
-
-		// Ignore function definitions too, as they aren't released until the engine is destroyed
-		if( func->funcType == asFUNC_FUNCDEF )
-			continue;
-
-		// Ignore functions whose object type has already reached refCount 0 as they are to be removed
-		if( func->objectType && func->objectType->GetRefCount() == 0 )
-			continue;
-
-		if( func->returnType.GetObjectType() == type )
-		{
-			asCString msg;
-			// We can only use the function name here, because the types used by the function may have been deleted already
-			msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
-			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
-		}
-		else
-		{
-			for( asUINT p = 0; p < func->parameterTypes.GetLength(); p++ )
-			{
-				if( func->parameterTypes[p].GetObjectType() == type )
-				{
-					asCString msg;
-					// We can only use the function name here, because the types used by the function may have been deleted already
-					msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
-					engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
-					break;
-				}
-			}
-		}	
-	}
-
-	// TODO: Check also usage of the type in global variables 
-
-	// TODO: Check also usage of the type in local variables in script functions
-
-	// TODO: Check also usage of the type as members of classes
-
-	// TODO: Check also usage of the type as sub types in other types
-}
-#endif
-
 END_AS_NAMESPACE

+ 7 - 4
Source/ThirdParty/AngelScript/source/as_configgroup.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -63,9 +63,8 @@ public:
 	bool HasLiveObjects();
 	void RemoveConfiguration(asCScriptEngine *engine, bool notUsed = false);
 
-#ifdef AS_DEBUG
-	void ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type);
-#endif
+	void AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func);
+	void AddReferencesForType(asCScriptEngine *engine, asCObjectType *type);
 
 	asCString groupName;
 	int refCount;
@@ -75,6 +74,10 @@ public:
 	asCArray<asCGlobalProperty*> globalProps;
 	asCArray<asCConfigGroup*>    referencedConfigGroups;
 	asCArray<asCScriptFunction*> funcDefs;
+
+	// This array holds the generated template instances that are used 
+	// by the config group as part of function signature or property
+	asCArray<asCObjectType*>     generatedTemplateInstances;
 };
 
 END_AS_NAMESPACE

+ 257 - 66
Source/ThirdParty/AngelScript/source/as_context.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -61,7 +61,6 @@ const int RESERVE_STACK = 2*AS_PTR_SIZE;
 // For each script function call we push 9 PTRs on the call stack
 const int CALLSTACK_FRAME_SIZE = 9;
 
-
 #if defined(AS_DEBUG)
 
 class asCDebugStats
@@ -254,7 +253,11 @@ void asCContext::DetachEngine()
 	{
 		if( m_stackBlocks[n] )
 		{
+#ifndef WIP_16BYTE_ALIGN
 			asDELETEARRAY(m_stackBlocks[n]);
+#else
+			asDELETEARRAYALIGNED(m_stackBlocks[n]);
+#endif
 		}
 	}
 	m_stackBlocks.SetLength(0);
@@ -1048,6 +1051,44 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
 	return 0;
 }
 
+int asCContext::SetArgVarType(asUINT arg, void *ptr, int typeId)
+{
+	if( m_status != asEXECUTION_PREPARED )
+		return asCONTEXT_NOT_PREPARED;
+
+	if( arg >= (unsigned)m_initialFunction->parameterTypes.GetLength() )
+	{
+		m_status = asEXECUTION_ERROR;
+		return asINVALID_ARG;
+	}
+
+	// Verify the type of the argument
+	asCDataType *dt = &m_initialFunction->parameterTypes[arg];
+	if( dt->GetTokenType() != ttQuestion )
+	{
+		m_status = asEXECUTION_ERROR;
+		return asINVALID_TYPE;
+	}
+
+	// Determine the position of the argument
+	int offset = 0;
+	if( m_initialFunction->objectType )
+		offset += AS_PTR_SIZE;
+
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( m_returnValueSize )
+		offset += AS_PTR_SIZE;
+
+	for( asUINT n = 0; n < arg; n++ )
+		offset += m_initialFunction->parameterTypes[n].GetSizeOnStackDWords();
+
+	// Set the typeId and pointer
+	*(asPWORD*)(&m_regs.stackFramePointer[offset]) = (asPWORD)ptr;
+	offset += AS_PTR_SIZE;
+	*(int*)(&m_regs.stackFramePointer[offset]) = typeId;
+
+	return 0;
+}
 
 // TODO: Instead of GetAddressOfArg, maybe we need a SetArgValue(int arg, void *value, bool takeOwnership) instead.
 
@@ -1190,6 +1231,14 @@ int asCContext::Execute()
 					SetInternalException(TXT_NULL_POINTER_ACCESS);
 			}
 		}
+		else if( m_currentFunction->funcType == asFUNC_IMPORTED )
+		{
+			int funcId = m_engine->importedFunctions[m_currentFunction->id & ~FUNC_IMPORTED]->boundFunctionId;
+			if( funcId > 0 )
+				m_currentFunction = m_engine->scriptFunctions[funcId];
+			else
+				SetInternalException(TXT_UNBOUND_FUNCTION);
+		}
 
 		if( m_currentFunction->funcType == asFUNC_SCRIPT )
 		{
@@ -1203,7 +1252,7 @@ int asCContext::Execute()
 			// The current function is an application registered function
 
 			// Call the function directly
-			CallSystemFunction(m_currentFunction->id, this, 0);
+			CallSystemFunction(m_currentFunction->id, this);
 
 			// Was the call successful?
 			if( m_status == asEXECUTION_ACTIVE )
@@ -1500,22 +1549,46 @@ int asCContext::GetLineNumber(asUINT stackLevel, int *column, const char **secti
 // internal
 bool asCContext::ReserveStackSpace(asUINT size)
 {
+#ifdef WIP_16BYTE_ALIGN
+	// Pad size to a multiple of MAX_TYPE_ALIGNMENT.
+	const asUINT remainder = size % MAX_TYPE_ALIGNMENT;
+	if(remainder != 0)
+	{
+		size = size + (MAX_TYPE_ALIGNMENT - (size % MAX_TYPE_ALIGNMENT));
+	}
+#endif
+
 	// Make sure the first stack block is allocated
 	if( m_stackBlocks.GetLength() == 0 )
 	{
 		m_stackBlockSize = m_engine->initialContextStackSize;
 		asASSERT( m_stackBlockSize > 0 );
 
+#ifndef WIP_16BYTE_ALIGN
 		asDWORD *stack = asNEWARRAY(asDWORD,m_stackBlockSize);
+#else
+		asDWORD *stack = asNEWARRAYALIGNED(asDWORD, m_stackBlockSize, MAX_TYPE_ALIGNMENT);
+#endif
 		if( stack == 0 )
 		{
 			// Out of memory
 			return false;
 		}
 
+#ifdef WIP_16BYTE_ALIGN
+		asASSERT( isAligned(stack, MAX_TYPE_ALIGNMENT) );
+#endif
+
 		m_stackBlocks.PushLast(stack);
 		m_stackIndex = 0;
 		m_regs.stackPointer = m_stackBlocks[0] + m_stackBlockSize;
+
+#ifdef WIP_16BYTE_ALIGN
+		// Align the stack pointer. This is necessary as the m_stackBlockSize is not necessarily evenly divisable with the max alignment
+		((asPWORD&)m_regs.stackPointer) &= ~(MAX_TYPE_ALIGNMENT-1);
+
+		asASSERT( isAligned(m_regs.stackPointer, MAX_TYPE_ALIGNMENT) );
+#endif
 	}
 
 	// Check if there is enough space on the current stack block, otherwise move
@@ -1542,7 +1615,11 @@ bool asCContext::ReserveStackSpace(asUINT size)
 		if( m_stackBlocks.GetLength() == m_stackIndex )
 		{
 			// Allocate the new stack block, with twice the size of the previous
-			asDWORD *stack = asNEWARRAY(asDWORD,(m_stackBlockSize << m_stackIndex));
+#ifndef WIP_16BYTE_ALIGN
+			asDWORD *stack = asNEWARRAY(asDWORD, (m_stackBlockSize << m_stackIndex));
+#else
+			asDWORD *stack = asNEWARRAYALIGNED(asDWORD, (m_stackBlockSize << m_stackIndex), MAX_TYPE_ALIGNMENT);
+#endif
 			if( stack == 0 )
 			{
 				// Out of memory
@@ -1554,6 +1631,11 @@ bool asCContext::ReserveStackSpace(asUINT size)
 				SetInternalException(TXT_STACK_OVERFLOW);
 				return false;
 			}
+
+#ifdef WIP_16BYTE_ALIGN
+			asASSERT( isAligned(stack, MAX_TYPE_ALIGNMENT) );
+#endif
+
 			m_stackBlocks.PushLast(stack);
 		}
 
@@ -1564,6 +1646,13 @@ bool asCContext::ReserveStackSpace(asUINT size)
 			                  m_currentFunction->GetSpaceNeededForArguments() -
 			                  (m_currentFunction->objectType ? AS_PTR_SIZE : 0) -
 			                  (m_currentFunction->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
+
+#ifdef WIP_16BYTE_ALIGN
+		// Align the stack pointer 
+		(asPWORD&)m_regs.stackPointer &= ~(MAX_TYPE_ALIGNMENT-1);
+
+		asASSERT( isAligned(m_regs.stackPointer, MAX_TYPE_ALIGNMENT) );
+#endif
 	}
 
 	return true;
@@ -2401,7 +2490,7 @@ void asCContext::ExecuteNext()
 			m_regs.stackPointer      = l_sp;
 			m_regs.stackFramePointer = l_fp;
 
-			l_sp += CallSystemFunction(i, this, 0);
+			l_sp += CallSystemFunction(i, this);
 
 			// Update the program position after the call so that line number is correct
 			l_bc += 2;
@@ -2433,9 +2522,9 @@ void asCContext::ExecuteNext()
 
 	case asBC_CALLBND:
 		{
+			// TODO: Clean-up: This code is very similar to asBC_CallPtr. Create a shared method for them
 			// Get the function ID from the stack
 			int i = asBC_INTARG(l_bc);
-			l_bc += 2;
 
 			asASSERT( i >= 0 );
 			asASSERT( i & FUNC_IMPORTED );
@@ -2448,6 +2537,9 @@ void asCContext::ExecuteNext()
 			int funcId = m_engine->importedFunctions[i & ~FUNC_IMPORTED]->boundFunctionId;
 			if( funcId == -1 )
 			{
+				// Need to update the program pointer for the exception handler
+				m_regs.programPointer += 2;
+
 				// Tell the exception handler to clean up the arguments to this function
 				m_needToCleanupArgs = true;
 				SetInternalException(TXT_UNBOUND_FUNCTION);
@@ -2456,8 +2548,46 @@ void asCContext::ExecuteNext()
 			else
 			{
 				asCScriptFunction *func = m_engine->GetScriptFunction(funcId);
+				if( func->funcType == asFUNC_SCRIPT )
+				{
+					m_regs.programPointer += 2;
+					CallScriptFunction(func);
+				}
+				else if( func->funcType == asFUNC_DELEGATE )
+				{
+					// Push the object pointer on the stack. There is always a reserved space for this so
+					// we don't don't need to worry about overflowing the allocated memory buffer
+					asASSERT( m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex] );
+					m_regs.stackPointer -= AS_PTR_SIZE;
+					*(asPWORD*)m_regs.stackPointer = asPWORD(func->objForDelegate);
+
+					// Call the delegated method
+					if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
+					{
+						m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
+
+						// Update program position after the call so the line number
+						// is correct in case the system function queries it
+						m_regs.programPointer += 2;
+					}
+					else
+					{
+						m_regs.programPointer += 2;
+
+						// TODO: run-time optimize: The true method could be figured out when creating the delegate
+						CallInterfaceMethod(func->funcForDelegate);
+					}
+				}
+				else
+				{
+					asASSERT( func->funcType == asFUNC_SYSTEM );
+
+					m_regs.stackPointer += CallSystemFunction(func->id, this);
 
-				CallScriptFunction(func);
+					// Update program position after the call so the line number
+					// is correct in case the system function queries it
+					m_regs.programPointer += 2;
+				}
 			}
 
 			// Extract the values from the context again
@@ -2548,13 +2678,17 @@ void asCContext::ExecuteNext()
 
 				if( func )
 				{
+					// Push the object pointer on the stack (it will be popped by the function)
+					l_sp -= AS_PTR_SIZE;
+					*(asPWORD*)l_sp = (asPWORD)mem;
+
 					// Need to move the values back to the context as the called functions
 					// may use the debug interface to inspect the registers
 					m_regs.programPointer    = l_bc;
 					m_regs.stackPointer      = l_sp;
 					m_regs.stackFramePointer = l_fp;
 
-					l_sp += CallSystemFunction(func, this, mem);
+					l_sp += CallSystemFunction(func, this);
 				}
 
 				// Pop the variable address from the stack
@@ -3424,7 +3558,7 @@ void asCContext::ExecuteNext()
 		break;
 
 	case asBC_u64TOf:
-#if _MSC_VER <= 1200 // MSVC6
+#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC6
 		{
 			// MSVC6 doesn't permit UINT64 to double
 			asINT64 v = *(asINT64*)(l_fp - asBC_SWORDARG1(l_bc));
@@ -3445,7 +3579,7 @@ void asCContext::ExecuteNext()
 		break;
 
 	case asBC_u64TOd:
-#if _MSC_VER <= 1200 // MSVC6
+#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC6
 		{
 			// MSVC6 doesn't permit UINT64 to double
 			asINT64 v = *(asINT64*)(l_fp - asBC_SWORDARG0(l_bc));
@@ -3727,7 +3861,7 @@ void asCContext::ExecuteNext()
 					// Call the delegated method
 					if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
 					{
-						m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this, 0);
+						m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
 
 						// Update program position after the call so the line number
 						// is correct in case the system function queries it
@@ -3745,7 +3879,7 @@ void asCContext::ExecuteNext()
 				{
 					asASSERT( func->funcType == asFUNC_SYSTEM );
 
-					m_regs.stackPointer += CallSystemFunction(func->id, this, 0);
+					m_regs.stackPointer += CallSystemFunction(func->id, this);
 
 					// Update program position after the call so the line number
 					// is correct in case the system function queries it
@@ -3978,7 +4112,11 @@ void asCContext::ExecuteNext()
 
 			asUINT size = asBC_DWORDARG(l_bc);
 			asBYTE **var = (asBYTE**)(l_fp - asBC_SWORDARG0(l_bc));
+#ifndef WIP_16BYTE_ALIGN
 			*var = asNEWARRAY(asBYTE, size);
+#else
+			*var = asNEWARRAYALIGNED(asBYTE, size, MAX_TYPE_ALIGNMENT);
+#endif
 
 			// Clear the buffer for the pointers that will be placed in it
 			memset(*var, 0, size);
@@ -4163,6 +4301,67 @@ void asCContext::ExecuteNext()
 		}
 		l_bc += 2;
 		break;
+	case asBC_Thiscall1:
+		// This instruction is a faster version of asBC_CALLSYS. It is faster because
+		// it has much less runtime overhead with determining the calling convention 
+		// and no dynamic code for loading the parameters. The instruction can only
+		// be used to call functions with the following signatures:
+		//
+		//  type &obj::func(int)
+		//  type &obj::func(uint)
+		//  void  obj::func(int)
+		//  void  obj::func(uint)
+		{
+			// Get function ID from the argument
+			int i = asBC_INTARG(l_bc);
+
+			// Need to move the values back to the context as the called functions
+			// may use the debug interface to inspect the registers
+			m_regs.programPointer    = l_bc;
+			m_regs.stackPointer      = l_sp;
+			m_regs.stackFramePointer = l_fp;
+
+			// Pop the thispointer from the stack
+			void *obj = *(void**)l_sp;
+			l_sp += AS_PTR_SIZE;
+
+			// Pop the int arg from the stack
+			int arg = *(int*)l_sp;
+			l_sp++;
+
+			// Call the method
+			m_callingSystemFunction = m_engine->scriptFunctions[i];
+			void *ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
+			m_callingSystemFunction = 0;
+			*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
+
+			// Update the program position after the call so that line number is correct
+			l_bc += 2;
+
+			if( m_regs.doProcessSuspend )
+			{
+				// Should the execution be suspended?
+				if( m_doSuspend )
+				{
+					m_regs.programPointer    = l_bc;
+					m_regs.stackPointer      = l_sp;
+					m_regs.stackFramePointer = l_fp;
+
+					m_status = asEXECUTION_SUSPENDED;
+					return;
+				}
+				// An exception might have been raised
+				if( m_status != asEXECUTION_ACTIVE )
+				{
+					m_regs.programPointer    = l_bc;
+					m_regs.stackPointer      = l_sp;
+					m_regs.stackFramePointer = l_fp;
+
+					return;
+				}
+			}
+		}
+		break;
 
 	// Don't let the optimizer optimize for size,
 	// since it requires extra conditions and jumps
@@ -4784,13 +4983,14 @@ asEContextState asCContext::GetState() const
 // interface
 int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
 {
-	m_lineCallback = true;
-	m_regs.doProcessSuspend = true;
+	// First turn off the line callback to avoid a second thread 
+	// attempting to call it while the new one is still being set
+	m_lineCallback = false;
+
 	m_lineCallbackObj = obj;
 	bool isObj = false;
 	if( (unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST )
 	{
-		m_lineCallback = false;
 		m_regs.doProcessSuspend = m_doSuspend;
 		return asNOT_SUPPORTED;
 	}
@@ -4799,15 +4999,18 @@ int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
 		isObj = true;
 		if( obj == 0 )
 		{
-			m_lineCallback = false;
 			m_regs.doProcessSuspend = m_doSuspend;
 			return asINVALID_ARG;
 		}
 	}
 
 	int r = DetectCallingConvention(isObj, callback, callConv, 0, &m_lineCallbackFunc);
-	if( r < 0 ) m_lineCallback = false;
+	
+	// Turn on the line callback after setting both the function pointer and object pointer
+	if( r >= 0 ) m_lineCallback = true;
 
+	// The BC_SUSPEND instruction should be processed if either line 
+	// callback is set or if the application has requested a suspension
 	m_regs.doProcessSuspend = m_doSuspend || m_lineCallback;
 
 	return r;
@@ -4864,91 +5067,79 @@ void asCContext::ClearExceptionCallback()
 	m_exceptionCallback = false;
 }
 
-int asCContext::CallGeneric(int id, void *objectPointer)
+int asCContext::CallGeneric(asCScriptFunction *descr)
 {
-	asCScriptFunction *sysFunction = m_engine->scriptFunctions[id];
-	asSSystemFunctionInterface *sysFunc = sysFunction->sysFuncIntf;
+	asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
 	void (*func)(asIScriptGeneric*) = (void (*)(asIScriptGeneric*))sysFunc->func;
 	int popSize = sysFunc->paramSize;
 	asDWORD *args = m_regs.stackPointer;
 
 	// Verify the object pointer if it is a class method
 	void *currentObject = 0;
+	asASSERT( sysFunc->callConv == ICC_GENERIC_FUNC || sysFunc->callConv == ICC_GENERIC_METHOD );
 	if( sysFunc->callConv == ICC_GENERIC_METHOD )
 	{
-		if( objectPointer )
-		{
-			currentObject = objectPointer;
+		// The object pointer should be popped from the context stack
+		popSize += AS_PTR_SIZE;
 
-			// Don't increase the reference of this pointer
-			// since it will not have been constructed yet
-		}
-		else
+		// Check for null pointer
+		currentObject = (void*)*(asPWORD*)(args);
+		if( currentObject == 0 )
 		{
-			// The object pointer should be popped from the context stack
-			popSize += AS_PTR_SIZE;
-
-			// Check for null pointer
-			currentObject = (void*)*(asPWORD*)(args);
-			if( currentObject == 0 )
-			{
-				SetInternalException(TXT_NULL_POINTER_ACCESS);
-				return 0;
-			}
+			SetInternalException(TXT_NULL_POINTER_ACCESS);
+			return 0;
+		}
 
-			// Add the base offset for multiple inheritance
-			currentObject = (void*)(asPWORD(currentObject) + sysFunc->baseOffset);
+		asASSERT( sysFunc->baseOffset == 0 );
 
-			// Skip object pointer
-			args += AS_PTR_SIZE;
-		}
+		// Skip object pointer
+		args += AS_PTR_SIZE;
 	}
 
-	if( sysFunction->DoesReturnOnStack() )
+	if( descr->DoesReturnOnStack() )
 	{
 		// Skip the address where the return value will be stored
 		args += AS_PTR_SIZE;
 		popSize += AS_PTR_SIZE;
 	}
 
-	asCGeneric gen(m_engine, sysFunction, currentObject, args);
+	asCGeneric gen(m_engine, descr, currentObject, args);
 
-	m_callingSystemFunction = sysFunction;
+	m_callingSystemFunction = descr;
 	func(&gen);
 	m_callingSystemFunction = 0;
 
 	m_regs.valueRegister = gen.returnVal;
 	m_regs.objectRegister = gen.objectRegister;
-	m_regs.objectType = sysFunction->returnType.GetObjectType();
+	m_regs.objectType = descr->returnType.GetObjectType();
 
-	// Clean up function parameters
-	int offset = 0;
-	for( asUINT n = 0; n < sysFunction->parameterTypes.GetLength(); n++ )
+	// Clean up arguments
+	const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
+	if( cleanCount )
 	{
-		if( sysFunction->parameterTypes[n].IsObject() && !sysFunction->parameterTypes[n].IsReference() )
+		asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
+		for( asUINT n = 0; n < cleanCount; n++, clean++ )
 		{
-			void *obj = *(void**)&args[offset];
-			if( obj )
+			void **addr = (void**)&args[clean->off];
+			if( clean->op == 0 )
 			{
-				// Release the object
-				asSTypeBehaviour *beh = &sysFunction->parameterTypes[n].GetObjectType()->beh;
-				if( sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
+				if( *addr != 0 )
 				{
-					asASSERT( (sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
-					if( beh->release )
-						m_engine->CallObjectMethod(obj, beh->release);
+					m_engine->CallObjectMethod(*addr, clean->ot->beh.release);
+					*addr = 0;
 				}
-				else
-				{
-					// Call the destructor then free the memory
-					if( beh->destruct )
-						m_engine->CallObjectMethod(obj, beh->destruct);
+			}
+			else 
+			{
+				asASSERT( clean->op == 1 || clean->op == 2 );
+				asASSERT( *addr );
 
-					m_engine->CallFree(obj);
-				}
+				if( clean->op == 2 )
+					m_engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
+				
+				m_engine->CallFree(*addr);
 			}
 		}
-		offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
 	}
 
 	// Return how much should be popped from the stack

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

@@ -76,14 +76,15 @@ public:
 	int SetObject(void *obj);
 
 	// Arguments
-	int SetArgByte(asUINT arg, asBYTE value);
-	int SetArgWord(asUINT arg, asWORD value);
-	int SetArgDWord(asUINT arg, asDWORD value);
-	int SetArgQWord(asUINT arg, asQWORD value);
-	int SetArgFloat(asUINT arg, float value);
-	int SetArgDouble(asUINT arg, double value);
-	int SetArgAddress(asUINT arg, void *addr);
-	int SetArgObject(asUINT arg, void *obj);
+	int   SetArgByte(asUINT arg, asBYTE value);
+	int   SetArgWord(asUINT arg, asWORD value);
+	int   SetArgDWord(asUINT arg, asDWORD value);
+	int   SetArgQWord(asUINT arg, asQWORD value);
+	int   SetArgFloat(asUINT arg, float value);
+	int   SetArgDouble(asUINT arg, double value);
+	int   SetArgAddress(asUINT arg, void *addr);
+	int   SetArgObject(asUINT arg, void *obj);
+	int   SetArgVarType(asUINT arg, void *ptr, int typeId);
 	void *GetAddressOfArg(asUINT arg);
 
 	// Return value
@@ -136,7 +137,7 @@ public:
 	void CallLineCallback();
 	void CallExceptionCallback();
 
-	int  CallGeneric(int funcID, void *objectPointer);
+	int  CallGeneric(asCScriptFunction *func);
 
 	void DetachEngine();
 

+ 39 - 11
Source/ThirdParty/AngelScript/source/as_datatype.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -159,7 +159,7 @@ bool asCDataType::IsNullHandle() const
 	return false;
 }
 
-asCString asCDataType::Format(bool includeNamespace) const
+asCString asCDataType::Format(asSNameSpace *currNs, bool includeNamespace) const
 {
 	if( IsNullHandle() )
 		return "<null handle>";
@@ -169,11 +169,13 @@ asCString asCDataType::Format(bool includeNamespace) const
 	if( isReadOnly )
 		str = "const ";
 
-	if( includeNamespace )
+	// If the type is not declared in the current namespace, then the namespace 
+	// must always be informed to guarantee that the correct type is informed
+	if( includeNamespace || (objectType && objectType->nameSpace != currNs) || (funcDef && funcDef->nameSpace != currNs) )
 	{
-		if( objectType )
+		if( objectType && objectType->nameSpace->name != "" )
 			str += objectType->nameSpace->name + "::";
-		else if( funcDef )
+		else if( funcDef && funcDef->nameSpace->name != "" )
 			str += funcDef->nameSpace->name + "::";
 	}
 
@@ -184,7 +186,7 @@ asCString asCDataType::Format(bool includeNamespace) const
 	else if( IsArrayType() && objectType && !objectType->engine->ep.expandDefaultArrayToTemplate )
 	{
 		asASSERT( objectType->templateSubTypes.GetLength() == 1 );
-		str += objectType->templateSubTypes[0].Format(includeNamespace);
+		str += objectType->templateSubTypes[0].Format(currNs, includeNamespace);
 		str += "[]";
 	}
 	else if( funcDef )
@@ -199,7 +201,7 @@ asCString asCDataType::Format(bool includeNamespace) const
 			str += "<";
 			for( asUINT subtypeIndex = 0; subtypeIndex < objectType->templateSubTypes.GetLength(); subtypeIndex++ )
 			{
-				str += objectType->templateSubTypes[subtypeIndex].Format(includeNamespace);
+				str += objectType->templateSubTypes[subtypeIndex].Format(currNs, includeNamespace);
 				if( subtypeIndex != objectType->templateSubTypes.GetLength()-1 )
 					str += ",";
 			}
@@ -225,7 +227,7 @@ asCString asCDataType::Format(bool includeNamespace) const
 			str += "const";
 	}
 
-    if( isReference )
+	if( isReference )
 		str += "&";
 
 	return str;
@@ -289,7 +291,7 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
 	return 0;
 }
 
-int asCDataType::MakeArray(asCScriptEngine *engine)
+int asCDataType::MakeArray(asCScriptEngine *engine, asCModule *module)
 {
 	if( engine->defaultArrayObjectType == 0 )
 		return asINVALID_TYPE;
@@ -298,7 +300,7 @@ int asCDataType::MakeArray(asCScriptEngine *engine)
 	isReadOnly = false;
 	asCArray<asCDataType> subTypes;
 	subTypes.PushLast(*this);
-	asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes);
+	asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes, module);
 	isReadOnly = tmpIsReadOnly;
 
 	isObjectHandle = false;
@@ -504,7 +506,7 @@ bool asCDataType::IsEqualExceptConst(const asCDataType &dt) const
 
 bool asCDataType::IsPrimitive() const
 {
-	//	Enumerations are primitives
+	// Enumerations are primitives
 	if( IsEnumType() )
 		return true;
 
@@ -519,6 +521,16 @@ bool asCDataType::IsPrimitive() const
 	return true;
 }
 
+bool asCDataType::IsMathType() const
+{
+	if( tokenType == ttInt || tokenType == ttInt8 || tokenType == ttInt16 || tokenType == ttInt64 ||
+		tokenType == ttUInt || tokenType == ttUInt8 || tokenType == ttUInt16 || tokenType == ttUInt64 ||
+		tokenType == ttFloat || tokenType == ttDouble )
+		return true;
+
+	return false;
+}
+
 bool asCDataType::IsIntegerType() const
 {
 	if( tokenType == ttInt ||
@@ -633,6 +645,19 @@ int asCDataType::GetSizeOnStackDWords() const
 	return GetSizeInMemoryDWords() + size;
 }
 
+#ifdef WIP_16BYTE_ALIGN
+int  asCDataType::GetAlignment() const
+{
+	if( objectType == NULL )
+	{
+		// TODO: Small primitives should not be aligned to 4 byte boundaries
+		return 4; //Default alignment
+	}
+
+	return objectType->alignment;
+}
+#endif
+
 asSTypeBehaviour *asCDataType::GetBehaviour() const
 { 
 	return objectType ? &objectType->beh : 0; 
@@ -640,6 +665,9 @@ asSTypeBehaviour *asCDataType::GetBehaviour() const
 
 bool asCDataType::IsEnumType() const
 {
+	// Do a sanity check on the objectType, to verify that we aren't trying to access memory after it has been released
+	asASSERT( objectType == 0 || objectType->name.GetLength() < 100 );
+
 	if( objectType && (objectType->flags & asOBJ_ENUM) )
 		return true;
 

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -49,6 +49,8 @@ struct asSTypeBehaviour;
 class asCScriptEngine;
 class asCObjectType;
 class asCScriptFunction;
+class asCModule;
+struct asSNameSpace;
 
 // TODO: refactor: Reference should not be part of the datatype. This should be stored separately, e.g. in asCTypeInfo
 //                 MakeReference, MakeReadOnly, IsReference, IsReadOnly should be removed
@@ -62,7 +64,7 @@ public:
 
 	bool IsValid() const;
 
-	asCString Format(bool includeNamespace = false) const;
+	asCString Format(asSNameSpace *currNs, bool includeNamespace = false) const;
 
 	static asCDataType CreatePrimitive(eTokenType tt, bool isConst);
 	static asCDataType CreateObject(asCObjectType *ot, bool isConst);
@@ -72,7 +74,7 @@ public:
 	static asCDataType CreateNullHandle();
 
 	int MakeHandle(bool b, bool acceptHandleForScope = false);
-	int MakeArray(asCScriptEngine *engine);
+	int MakeArray(asCScriptEngine *engine, asCModule *requestingModule);
 	int MakeReference(bool b);
 	int MakeReadOnly(bool b);
 	int MakeHandleToConst(bool b);
@@ -80,6 +82,7 @@ public:
 	bool IsTemplate()             const;
 	bool IsScriptObject()         const;
 	bool IsPrimitive()            const;
+	bool IsMathType()             const;
 	bool IsObject()               const;
 	bool IsReference()            const {return isReference;}
 	bool IsAuto()                 const {return isAuto;}
@@ -121,6 +124,9 @@ public:
 	int  GetSizeOnStackDWords()  const;
 	int  GetSizeInMemoryBytes()  const;
 	int  GetSizeInMemoryDWords() const;
+#ifdef WIP_16BYTE_ALIGN
+	int  GetAlignment()          const;
+#endif
 
 	void SetTokenType(eTokenType tt)         {tokenType = tt;}
 	void SetObjectType(asCObjectType *obj)   {objectType = obj;}

+ 5 - 0
Source/ThirdParty/AngelScript/source/as_debug.h

@@ -46,6 +46,8 @@
 #ifndef _WIN32_WCE
 // Neither does WinCE
 
+#ifndef AS_PSVITA
+// Possible on PSVita, but requires SDK access
 
 #if defined(__GNUC__) || defined( AS_MARMALADE )
 
@@ -256,6 +258,9 @@ END_AS_NAMESPACE
 
 
 
+
+
+#endif // AS_PSVITA
 #endif // _WIN32_WCE
 #endif // AS_WII
 

+ 1 - 11
Source/ThirdParty/AngelScript/source/as_gc.cpp

@@ -217,17 +217,7 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags, asUINT iterations)
 				if( count != (unsigned int)(gcOldObjects.GetLength()) )
 					count = (unsigned int)(gcOldObjects.GetLength());
 				else
-				{
-					// Let the engine destroy the types that reached refCount 0
-					// If none were destroyed, then leave the GC
-					// TODO: The asCObjectType should destroy its content when refCount reaches 0
-					//       since no-one is using them. The registered types should have their
-					//       refcount increased by the config groups. Doing it like that will allow 
-					//       me to remove this call to ClearUnusedTypes() that the GC really 
-					//       shouldn't be calling.
-					if( engine->ClearUnusedTypes() == 0 )
-						break;
-				}
+					break;
 			}
 
 			isProcessing = false;

+ 21 - 139
Source/ThirdParty/AngelScript/source/as_globalproperty.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -50,31 +50,32 @@ asCGlobalProperty::asCGlobalProperty()
 
 asCGlobalProperty::~asCGlobalProperty()
 { 
+#ifndef WIP_16BYTE_ALIGNED
 	if( memoryAllocated ) { asDELETEARRAY(memory); } 
+#else
+	if( memoryAllocated ) { asDELETEARRAYALIGNED(memory); } 
+#endif
+
 	if( initFunc )
-		initFunc->Release();
+		initFunc->ReleaseInternal();
 }
 
 void asCGlobalProperty::AddRef()
 {
-	gcFlag = false;
 	refCount.atomicInc();
 }
 
 void asCGlobalProperty::Release()
 {
-	gcFlag = false;
+	if( refCount.atomicDec() == 0 )
+		asDELETE(this, asCGlobalProperty);
+}
 
-	// The property doesn't delete itself. The  
-	// engine will do that at a later time
-	if( refCount.atomicDec() == 2 && initFunc )
+void asCGlobalProperty::DestroyInternal()
+{
+	if( initFunc )
 	{
-		// Since the initFunc holds references to the property,
-		// we'll release it when we reach refCount 2. This will
-		// break the circle and allow the engine to free the property
-		// without the need for the GC to attempt finding circular 
-		// references.
-		initFunc->Release();
+		initFunc->ReleaseInternal();
 		initFunc = 0;
 	}
 }
@@ -92,14 +93,19 @@ void asCGlobalProperty::AllocateMemory()
 { 
 	if( type.GetSizeOnStackDWords() > 2 ) 
 	{ 
+#ifndef WIP_16BYTE_ALIGNED
 		memory = asNEWARRAY(asDWORD, type.GetSizeOnStackDWords()); 
+#else
+		// TODO: Avoid aligned allocation if not needed to reduce the waste of memory for the alignment
+		memory = asNEWARRAYALIGNED(asDWORD, type.GetSizeOnStackDWords(), type.GetAlignment()); 
+#endif
 		memoryAllocated = true; 
 	} 
 }
 
 void asCGlobalProperty::SetRegisteredAddress(void *p) 
 { 
-	realAddress = p; 	
+	realAddress = p;
 	if( type.IsObject() && !type.IsReference() && !type.IsObjectHandle() )
 	{
 		// The global property is a pointer to a pointer 
@@ -114,60 +120,13 @@ void *asCGlobalProperty::GetRegisteredAddress() const
 	return realAddress;
 }
 
-int asCGlobalProperty::GetRefCount()
-{
-	return refCount.get();
-}
-
-void asCGlobalProperty::SetGCFlag()
-{
-	gcFlag = true;
-}
-
-bool asCGlobalProperty::GetGCFlag()
-{
-	return gcFlag;
-}
-
-void asCGlobalProperty::EnumReferences(asIScriptEngine *engine)
-{
-	engine->GCEnumCallback(initFunc);
-}
-
-void asCGlobalProperty::ReleaseAllHandles(asIScriptEngine *)
-{
-	if( initFunc )
-	{
-		initFunc->Release();
-		initFunc = 0;
-	}
-}
-
-void asCGlobalProperty::Orphan(asCModule *module)
-{
-	if( initFunc && initFunc->module == module )
-	{
-		// The owning module is releasing the property, so we need to notify 
-		// the GC in order to resolve any circular references that may exists
-
-		// This will add the property
-		initFunc->engine->gc.AddScriptObjectToGC(this, &initFunc->engine->globalPropertyBehaviours);
-
-		// This will add the function
-		initFunc->AddRef();
-		initFunc->Orphan(module);
-	}
-
-	Release();
-}
-
 void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
 {
 	// This should only be done once
 	asASSERT( this->initFunc == 0 );
 
 	this->initFunc = initFunc;
-	this->initFunc->AddRef();
+	this->initFunc->AddRefInternal();
 }
 
 asCScriptFunction *asCGlobalProperty::GetInitFunc()
@@ -175,81 +134,4 @@ asCScriptFunction *asCGlobalProperty::GetInitFunc()
 	return initFunc;
 }
 
-
-#ifdef AS_MAX_PORTABILITY
-
-static void GlobalProperty_AddRef_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	self->AddRef();
-}
-
-static void GlobalProperty_Release_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	self->Release();
-}
-
-static void GlobalProperty_GetRefCount_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
-}
-
-static void GlobalProperty_SetGCFlag_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	self->SetGCFlag();
-}
-
-static void GlobalProperty_GetGCFlag_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	*(bool*)gen->GetAddressOfReturnLocation() = self->GetGCFlag();
-}
-
-static void GlobalProperty_EnumReferences_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
-	self->EnumReferences(engine);
-}
-
-static void GlobalProperty_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
-{
-	asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
-	asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
-	self->ReleaseAllHandles(engine);
-}
-
-#endif
-
-
-void asCGlobalProperty::RegisterGCBehaviours(asCScriptEngine *engine)
-{
-	// Register the gc behaviours for the global properties
-	int r = 0;
-	UNUSED_VAR(r); // It is only used in debug mode
-	engine->globalPropertyBehaviours.engine = engine;
-	engine->globalPropertyBehaviours.flags = asOBJ_REF | asOBJ_GC;
-	engine->globalPropertyBehaviours.name = "_builtin_globalprop_";
-#ifndef AS_MAX_PORTABILITY
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCGlobalProperty,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASE, "void f()", asMETHOD(asCGlobalProperty,Release), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(asCGlobalProperty,GetRefCount), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_SETGCFLAG, "void f()", asMETHOD(asCGlobalProperty,SetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCGlobalProperty,GetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCGlobalProperty,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCGlobalProperty,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-#else
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(GlobalProperty_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASE, "void f()", asFUNCTION(GlobalProperty_Release_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(GlobalProperty_GetRefCount_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(GlobalProperty_SetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(GlobalProperty_GetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(GlobalProperty_EnumReferences_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(GlobalProperty_ReleaseAllHandles_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-#endif
-}
-
 END_AS_NAMESPACE

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -49,6 +49,63 @@
 
 BEGIN_AS_NAMESPACE
 
+#ifdef WIP_16BYTE_ALIGN
+
+// TODO: Add support for 16byte aligned application types (e.g. __m128). The following is a list of things that needs to be implemented:
+//
+//  ok  - The script context must make sure to always allocate the local stack memory buffer on 16byte aligned boundaries (asCContext::ReserveStackSpace)
+//  ok  - The engine must make sure to always allocate the memory for the script objects on 16byte aligned boundaries (asCScriptEngine::CallAlloc)
+//  ok  - The application needs to inform a new flag when registering types that require 16byte alignment, e.g. asOBJ_APP_ALIGN16 (asCScriptEngine::RegisterObjectType)
+//  ok  - The script object type must make sure to align member properties of these types correctly (asCObjectType::AddPropertyToClass)
+//  ok  - Script global properties must allocate memory on 16byte boundaries if holding these types (asCGlobalProperty::AllocateMemory)
+// TODO - The script compiler must make sure to allocate the local variables on 16byte boundaries (asCCompiler::AllocateVariable)
+// TODO - The script compiler must add pad bytes on the stack for all function calls to guarantee that the stack position is 16byte aligned on entry in the called function (asCCompiler)
+// TODO - The bytecode serializer must be capable of adjusting these pad bytes to guarantee platform independent saved bytecode. Remember that the registered type may not be 16byte aligned on all platforms (asCWriter & asCReader) 
+// TODO - The bytecode serializer must also be prepared to adjust the position of the local variables according to the need fro 16byte alignment (asCWriter & asCReader)
+// TODO - The code for the native calling conventions must be adjusted for all platforms that should support 16byte aligned types (as_callfunc...)
+//  ok  - When the context needs to grow the local stack memory it must copy the function arguments so that the stack entry position is 16byte aligned (asCContext::CallScriptFunction)
+// TODO - When the context is prepared for a new call, it must set the initial stack position so the stack entry position is 16byte aligned (asCContext::Prepare)
+//
+// http://www.gamedev.net/topic/650555-alignment-requirements/
+
+
+// TODO: Allow user to register its own aligned memory routines
+// Wrappers for aligned allocations
+void *debugAlignedMalloc(size_t size, size_t align, const char *file, int line)
+{
+	void *mem = ((asALLOCFUNCDEBUG_t)userAlloc)(size + (align-1) + sizeof(void*), file, line);
+
+	char *amem = ((char*)mem) + sizeof(void*);
+	if( (uintptr_t)amem & (align - 1) )
+		amem += align - ((uintptr_t)amem & (align - 1));
+
+	((void**)amem)[-1] = mem;
+	return amem;
+}
+
+void *alignedMalloc(size_t size, size_t align)
+{
+	void *mem = userAlloc(size + (align-1) + sizeof(void*));
+
+	char *amem = ((char*)mem) + sizeof(void*);
+	if( (uintptr_t)amem & (align - 1) )
+		amem += align - ((uintptr_t)amem & (align - 1));
+
+	((void**)amem)[-1] = mem;
+	return amem;
+}
+
+void alignedFree(void *mem)
+{
+	userFree( ((void**)mem)[-1] );
+}
+
+bool isAligned(const void* const pointer, asUINT alignment)
+{
+	return (uintptr_t(pointer) % alignment) == 0;
+}
+#endif
+
 // By default we'll use the standard memory management functions
 
 // Make sure these globals are initialized first. Otherwise the
@@ -61,10 +118,22 @@ BEGIN_AS_NAMESPACE
 #pragma init_seg(lib)
 asALLOCFUNC_t userAlloc = malloc;
 asFREEFUNC_t  userFree  = free;
+#ifdef WIP_16BYTE_ALIGN
+#ifdef AS_DEBUG
+asALLOCALIGNEDFUNC_t userAllocAligned = (asALLOCALIGNEDFUNC_t)debugAlignedMalloc;
+#else
+asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
+#endif
+asFREEALIGNEDFUNC_t  userFreeAligned  = alignedFree;
+#endif
 #else
 // Other compilers will just have to rely on luck.
 asALLOCFUNC_t userAlloc = malloc;
 asFREEFUNC_t  userFree  = free;
+#ifdef WIP_16BYTE_ALIGN
+asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
+asFREEALIGNEDFUNC_t  userFreeAligned  = alignedFree;
+#endif
 #endif
 
 extern "C"
@@ -73,6 +142,11 @@ extern "C"
 // interface
 int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
 {
+	// Clean-up thread local memory before changing the allocation routines to avoid 
+	// potential problem with trying to free memory using a different allocation
+	// routine than used when allocating it.
+	asThreadCleanup();
+
 	userAlloc = allocFunc;
 	userFree  = freeFunc;
 
@@ -82,6 +156,9 @@ int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
 // interface
 int asResetGlobalMemoryFunctions()
 {
+	// Clean-up thread local memory before changing the allocation routines to avoid 
+	// potential problem with trying to free memory using a different allocation
+	// routine than used when allocating it.
 	asThreadCleanup();
 
 	userAlloc = malloc;

+ 31 - 1
Source/ThirdParty/AngelScript/source/as_memory.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -48,6 +48,25 @@ BEGIN_AS_NAMESPACE
 extern asALLOCFUNC_t userAlloc;
 extern asFREEFUNC_t  userFree;
 
+#ifdef WIP_16BYTE_ALIGN
+
+// TODO: This declaration should be in angelscript.h
+//       when the application can register it's own
+//       aligned memory routines
+typedef void *(*asALLOCALIGNEDFUNC_t)(size_t, size_t);
+typedef void (*asFREEALIGNEDFUNC_t)(void *);
+extern asALLOCALIGNEDFUNC_t userAllocAligned;
+extern asFREEALIGNEDFUNC_t  userFreeAligned;
+typedef void *(*asALLOCALIGNEDFUNCDEBUG_t)(size_t, size_t, const char *, unsigned int);
+
+// The maximum type alignment supported.
+const int MAX_TYPE_ALIGNMENT = 16;
+
+// Utility function used for assertions.
+bool isAligned(const void* const pointer, asUINT alignment);
+
+#endif // WIP_16BYTE_ALIGN
+
 // We don't overload the new operator as that would affect the application as well
 
 #ifndef AS_DEBUG
@@ -58,6 +77,11 @@ extern asFREEFUNC_t  userFree;
 	#define asNEWARRAY(x,cnt)  (x*)userAlloc(sizeof(x)*cnt)
 	#define asDELETEARRAY(ptr) userFree(ptr)
 
+#ifdef WIP_16BYTE_ALIGN
+	#define asNEWARRAYALIGNED(x,cnt, alignment)  (x*)userAllocAligned(sizeof(x)*cnt, alignment)
+	#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
+#endif
+
 #else
 
 	typedef void *(*asALLOCFUNCDEBUG_t)(size_t, const char *, unsigned int);
@@ -68,6 +92,12 @@ extern asFREEFUNC_t  userFree;
 	#define asNEWARRAY(x,cnt)  (x*)((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(x)*cnt, __FILE__, __LINE__)
 	#define asDELETEARRAY(ptr) userFree(ptr)
 
+#ifdef WIP_16BYTE_ALIGN
+	//TODO: Equivalent of debug allocation function with alignment?
+	#define asNEWARRAYALIGNED(x,cnt, alignment)  (x*)userAllocAligned(sizeof(x)*cnt, alignment)
+	#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
+#endif
+
 #endif
 
 END_AS_NAMESPACE

+ 421 - 94
Source/ThirdParty/AngelScript/source/as_module.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -46,6 +46,33 @@
 
 BEGIN_AS_NAMESPACE
 
+// TODO: 2.30.0: redesign: Improved method for discarding modules (faster clean-up, less abuse of garbage collector)
+//
+// I need to separate the reference counter for internal references and outside references:
+//
+//  - Internal references are for example, when the module refers to a function or object since it is declared in the module, or when
+//    a function refers to another function since it is being called in the code.
+//  - Outside references are for example object instances holding a reference to the object type, or a context currently
+//    executing a function.
+//
+// If no object instances are alive or no contexts are alive it is known that functions from a discarded module
+// can be called, so they can be destroyed without any need to execute the complex garbage collection routines.
+//
+// If there are live objects, the entire module should be kept for safe keeping, though no longer visible.
+//
+// TODO: It may not be necessary to keep track of internal references. Without keeping track of internal references, can I still
+//       handle RemoveFunction and RemoveGlobalVariable correctly?
+//
+// TODO: How to avoid global variables keeping code alive? For example a script object, or a funcdef?
+//       Can I do a quick check of the object types and functions to count number of outside references, and then do another
+//       check over the global variables to subtract the outside references coming from these? What if the outside reference
+//       is added by an application type in a global variable that the engine doesn't know about? Example, a global dictionary 
+//       holding object instances. Should discarding a module immediately destroy the content of the global variables? What if
+//       a live object tries to access the global variable after it has been discarded? Throwing a script exception is acceptable?
+//       Perhaps I need to allow the user to provide a clean-up routine that will be executed before destroying the objects. 
+//       Or I might just put that responsibility on the application.
+
+
 // internal
 asCModule::asCModule(const char *name, asCScriptEngine *engine)
 {
@@ -66,6 +93,8 @@ asCModule::~asCModule()
 {
 	InternalReset();
 
+	// The builder is not removed by InternalReset because it holds the script 
+	// sections that will be built, so we need to explictly remove it now if it exists
 	if( builder )
 	{
 		asDELETE(builder,asCBuilder);
@@ -86,16 +115,50 @@ asCModule::~asCModule()
 		}
 
 		// Remove the module from the engine
-		if( engine->lastModule == this )
-			engine->lastModule = 0;
-		engine->scriptModules.RemoveValue(this);
+		ACQUIREEXCLUSIVE(engine->engineRWLock);
+		// The module must have been discarded before it is deleted
+		asASSERT( !engine->scriptModules.Exists(this) );
+		engine->discardedModules.RemoveValue(this);
+		RELEASEEXCLUSIVE(engine->engineRWLock);
 	}
 }
 
 // interface
 void asCModule::Discard()
 {
-	asDELETE(this,asCModule);
+	// Reset the global variables already so that no object in the global variables keep the module alive forever.
+	// If any live object tries to access the global variables during clean up they will fail with a script exception,
+	// so the application must keep that in mind before discarding a module.
+	CallExit();
+
+	// Keep a local copy of the engine pointer, because once the module is moved do the discarded
+	// pile, it is possible that another thread might discard it while we are still in here. So no
+	// further access to members may be done after that
+	asCScriptEngine *lEngine = engine;
+
+	// Instead of deleting the module immediately, move it to the discarded pile
+	// This will turn it invisible to the application, yet keep it alive until all 
+	// external references to its entities have been released.
+	ACQUIREEXCLUSIVE(engine->engineRWLock);
+	if( lEngine->lastModule == this )
+		lEngine->lastModule = 0;
+	lEngine->scriptModules.RemoveValue(this);
+	lEngine->discardedModules.PushLast(this);
+	RELEASEEXCLUSIVE(lEngine->engineRWLock);
+
+	// Allow the engine to go over the list of discarded modules to see what can be cleaned up at this moment.
+	// Don't do this if the engine is already shutting down, as it will be done explicitly by the engine itself with error reporting
+	if( !lEngine->shuttingDown )
+	{
+		if( lEngine->ep.autoGarbageCollect )
+			lEngine->GarbageCollect();
+		else
+		{
+			// GarbageCollect calls DeleteDiscardedModules, so no need
+			// to call it again if we already called GarbageCollect
+			lEngine->DeleteDiscardedModules();
+		}
+	}
 }
 
 // interface
@@ -140,8 +203,9 @@ void *asCModule::GetUserData(asPWORD type) const
 	{
 		if( userData[n] == type )
 		{
+			void *ud = reinterpret_cast<void*>(userData[n+1]);
 			RELEASESHARED(engine->engineRWLock);
-			return reinterpret_cast<void*>(userData[n+1]);
+			return ud;
 		}
 	}
 
@@ -249,6 +313,15 @@ int asCModule::Build()
 #else
 	TimeIt("asCModule::Build");
 
+	// Don't allow the module to be rebuilt if there are still 
+	// external references that will need the previous code
+	// TODO: 2.30.0: interface: The asIScriptModule must have a method for querying if the module is used
+	if( HasExternalReferences(false) )
+	{
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_MODULE_IS_IN_USE);
+		return asMODULE_IS_IN_USE;
+	}
+
 	// Only one thread may build at one time
 	// TODO: It should be possible to have multiple threads perform compilations
 	int r = engine->RequestBuild();
@@ -263,7 +336,7 @@ int asCModule::Build()
 		return asINVALID_CONFIGURATION;
 	}
 
- 	InternalReset();
+	InternalReset();
 
 	if( !builder )
 	{
@@ -446,33 +519,98 @@ void asCModule::CallExit()
 	isGlobalVarInitialized = false;
 }
 
+// internal
+bool asCModule::HasExternalReferences(bool shuttingDown)
+{
+	// Check all entiteis in the module for any external references.
+	// If there are any external references the module cannot be deleted yet.
+	
+	for( asUINT n = 0; n < scriptFunctions.GetLength(); n++ )
+		if( scriptFunctions[n] && scriptFunctions[n]->externalRefCount.get() )
+		{
+			if( !shuttingDown )
+				return true;
+			else
+			{
+				asCString msg;
+				msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
+
+				msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, scriptFunctions[n]->GetName(), scriptFunctions[n]->GetFuncType());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
+			}
+		}
+
+	for( asUINT n = 0; n < classTypes.GetLength(); n++ )
+		if( classTypes[n] && classTypes[n]->externalRefCount.get() )
+		{
+			if( !shuttingDown )
+				return true;
+			else
+			{
+				asCString msg;
+				msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
+
+				msg.Format(TXT_PREV_TYPE_IS_NAMED_s, classTypes[n]->GetName());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
+			}
+		}
+
+	for( asUINT n = 0; n < funcDefs.GetLength(); n++ )
+		if( funcDefs[n] && funcDefs[n]->externalRefCount.get() )
+		{
+			if( !shuttingDown )
+				return true;
+			else
+			{
+				asCString msg;
+				msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
+
+				msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, funcDefs[n]->GetName(), funcDefs[n]->GetFuncType());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
+			}
+		}
+
+	for( asUINT n = 0; n < templateInstances.GetLength(); n++ )
+		if( templateInstances[n] && templateInstances[n]->externalRefCount.get() )
+		{
+			if( !shuttingDown )
+				return true;
+			else
+			{
+				asCString msg;
+				msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
+
+				msg.Format(TXT_PREV_TYPE_IS_NAMED_s, templateInstances[n]->GetName());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
+			}
+		}
+
+	return false;
+}
+
 // internal
 void asCModule::InternalReset()
 {
 	CallExit();
 
-	size_t n;
+	asUINT n;
 
-	// Release all global functions
-	asCSymbolTable<asCScriptFunction>::iterator funcIt = globalFunctions.List();
-	for( ; funcIt; funcIt++ )
-		(*funcIt)->Release();
+	// Remove all global functions
 	globalFunctions.Clear();
 
-	// First release all compiled functions
-	for( n = 0; n < scriptFunctions.GetLength(); n++ )
-		if( scriptFunctions[n] )
-			scriptFunctions[n]->Orphan(this);
-	scriptFunctions.SetLength(0);
-
-	// Release the global properties declared in the module
+	// Destroy the internals of the global properties here, but do not yet remove them from the 
+	// engine, because functions need the engine's varAddressMap to get to the property. If the
+	// property is removed already, it may leak as the refCount doesn't reach 0.
 	asCSymbolTableIterator<asCGlobalProperty> globIt = scriptGlobals.List();
 	while( globIt )
 	{
-		(*globIt)->Orphan(this);
+		(*globIt)->DestroyInternal();
 		globIt++;
 	}
-	scriptGlobals.Clear();
 
 	UnbindAllImportedFunctions();
 
@@ -481,39 +619,156 @@ void asCModule::InternalReset()
 	{
 		if( bindInformations[n] )
 		{
-			asUINT id = bindInformations[n]->importedFunctionSignature->id & ~FUNC_IMPORTED;
-			engine->importedFunctions[id] = 0;
-			engine->freeImportedFunctionIdxs.PushLast(id);
+			bindInformations[n]->importedFunctionSignature->ReleaseInternal();
 
-			asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
 			asDELETE(bindInformations[n], sBindInfo);
 		}
 	}
 	bindInformations.SetLength(0);
 
 	// Free declared types, including classes, typedefs, and enums
-	// TODO: optimize: Check if it is possible to destroy the object directly without notifying the GC
+	for( n = 0; n < templateInstances.GetLength(); n++ )
+	{
+		asCObjectType *type = templateInstances[n];
+		if( engine->FindNewOwnerForSharedType(type, this) != this )
+		{
+			// The type is owned by another module, just release our reference
+			type->ReleaseInternal();
+			continue;
+		}
+
+		// Orphan the template instance
+		type->module = 0;
+
+		// No other module is holding the template type
+		engine->RemoveTemplateInstanceType(type);
+		type->ReleaseInternal();
+	}
+	templateInstances.SetLength(0);
 	for( n = 0; n < classTypes.GetLength(); n++ )
-		classTypes[n]->Orphan(this);
+	{
+		asCObjectType *type = classTypes[n];
+		if( type->IsShared() )
+		{
+			// The type is shared, so transfer ownership to another module that also uses it
+			if( engine->FindNewOwnerForSharedType(type, this) != this )
+			{
+				// The type is owned by another module, just release our reference
+				type->ReleaseInternal();
+				continue;
+			}
+		}
+
+		// The type should be destroyed now
+		type->DestroyInternal();
+
+		// Remove the type from the engine
+		if( type->IsShared() )
+		{
+			engine->sharedScriptTypes.RemoveValue(type);
+			type->ReleaseInternal();
+		}
+
+		// Release it from the module
+		type->module = 0;
+		type->ReleaseInternal();
+	}
 	classTypes.SetLength(0);
 	for( n = 0; n < enumTypes.GetLength(); n++ )
-		enumTypes[n]->Release();
+	{
+		asCObjectType *type = enumTypes[n];
+		if( type->IsShared() )
+		{
+			// The type is shared, so transfer ownership to another module that also uses it
+			if( engine->FindNewOwnerForSharedType(type, this) != this )
+			{
+				// The type is owned by another module, just release our reference
+				type->ReleaseInternal();
+				continue;
+			}
+		}
+
+		// The type should be destroyed now
+		type->DestroyInternal();
+
+		// Remove the type from the engine
+		if( type->IsShared() )
+		{
+			engine->sharedScriptTypes.RemoveValue(type);
+			type->ReleaseInternal();
+		}
+
+		// Release it from the module
+		type->module = 0;
+		type->ReleaseInternal();
+	}
 	enumTypes.SetLength(0);
 	for( n = 0; n < typeDefs.GetLength(); n++ )
-		typeDefs[n]->Release();
+	{
+		asCObjectType *type = typeDefs[n];
+
+		// The type should be destroyed now
+		type->DestroyInternal();
+
+		// Release it from the module
+		type->module = 0;
+		type->ReleaseInternal();
+	}
 	typeDefs.SetLength(0);
 
 	// Free funcdefs
 	for( n = 0; n < funcDefs.GetLength(); n++ )
 	{
-		// The funcdefs are not removed from the engine at this moment as they may still be referred
-		// to by other types. The engine's ClearUnusedTypes will take care of the clean up.
-		funcDefs[n]->Release();
+		asCScriptFunction *func = funcDefs[n];
+		if( func->IsShared() )
+		{
+			// The func is shared, so transfer ownership to another module that also uses it
+			if( engine->FindNewOwnerForSharedFunc(func, this) != this )
+			{
+				// The func is owned by another module, just release our reference
+				func->ReleaseInternal();
+				continue;
+			}
+		}
+
+		func->DestroyInternal();
+		engine->RemoveFuncdef(func);
+		func->module = 0;
+		func->ReleaseInternal();
 	}
 	funcDefs.SetLength(0);
 
-	// Allow the engine to clean up what is not used
-	engine->CleanupAfterDiscardModule();
+	// Then release the functions
+	for( n = 0; n < scriptFunctions.GetLength(); n++ )
+	{
+		asCScriptFunction *func = scriptFunctions[n];
+		if( func->IsShared() )
+		{
+			// The func is shared, so transfer ownership to another module that also uses it
+			if( engine->FindNewOwnerForSharedFunc(func, this) != this )
+			{
+				// The func is owned by another module, just release our reference
+				func->ReleaseInternal();
+				continue;
+			}
+		}
+
+		func->DestroyInternal();
+		func->module = 0;
+		func->ReleaseInternal();
+	}
+	scriptFunctions.SetLength(0);
+
+	// Now remove and release the global properties as there are no more references to them
+	globIt = scriptGlobals.List();
+	while( globIt )
+	{
+		engine->RemoveGlobalProperty(*globIt);
+		asASSERT( (*globIt)->refCount.get() == 1 );
+		(*globIt)->Release();
+		globIt++;
+	}
+	scriptGlobals.Clear();
 
 	asASSERT( IsEmpty() );
 }
@@ -521,12 +776,22 @@ void asCModule::InternalReset()
 // interface
 asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
 {
-	const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(defaultNamespace, name);
-	if( idxs.GetLength() != 1 )
-		return 0;
+	asSNameSpace *ns = defaultNamespace;
+	while( ns )
+	{
+		const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, name);
+		if( idxs.GetLength() != 1 )
+			return 0;
+
+		const asIScriptFunction *func = globalFunctions.Get(idxs[0]);
+		if( func )
+			return const_cast<asIScriptFunction*>(func);
+
+		// Recursively search parent namespaces
+		ns = engine->GetParentNameSpace(ns);
+	}
 
-	const asIScriptFunction *func = globalFunctions.Get(idxs[0]);
-	return const_cast<asIScriptFunction*>(func);
+	return 0;
 }
 
 // interface
@@ -607,38 +872,49 @@ asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
 	asSNameSpace *ns = func.nameSpace == engine->nameSpaces[0] ? defaultNamespace : func.nameSpace;
 
 	// Search script functions for matching interface
-	asIScriptFunction *f = 0;
-	const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, func.name);
-	for( unsigned int n = 0; n < idxs.GetLength(); n++ )
+	while( ns )
 	{
-		const asCScriptFunction *funcPtr = globalFunctions.Get(idxs[n]);
-		if( funcPtr->objectType == 0 &&
-			func.returnType                 == funcPtr->returnType &&
-			func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
-			)
+		asIScriptFunction *f = 0;
+		const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, func.name);
+		for( unsigned int n = 0; n < idxs.GetLength(); n++ )
 		{
-			bool match = true;
-			for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
+			const asCScriptFunction *funcPtr = globalFunctions.Get(idxs[n]);
+			if( funcPtr->objectType == 0 &&
+				func.returnType                 == funcPtr->returnType &&
+				func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
+				)
 			{
-				if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
+				bool match = true;
+				for( asUINT p = 0; p < func.parameterTypes.GetLength(); ++p )
 				{
-					match = false;
-					break;
+					if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
+					{
+						match = false;
+						break;
+					}
 				}
-			}
 
-			if( match )
-			{
-				if( f == 0 )
-					f = const_cast<asCScriptFunction*>(funcPtr);
-				else
-					// Multiple functions
-					return 0;
+				if( match )
+				{
+					if( f == 0 )
+						f = const_cast<asCScriptFunction*>(funcPtr);
+					else
+						// Multiple functions
+						return 0;
+				}
 			}
 		}
+
+		if( f )
+			return f;
+		else
+		{
+			// Search for matching functions in the parent namespace
+			ns = engine->GetParentNameSpace(ns);
+		}
 	}
 
-	return f;
+	return 0;
 }
 
 // interface
@@ -650,21 +926,41 @@ asUINT asCModule::GetGlobalVarCount() const
 // interface
 int asCModule::GetGlobalVarIndexByName(const char *name) const
 {
+	asSNameSpace *ns = defaultNamespace;
+
 	// Find the global var id
-	int id = scriptGlobals.GetFirstIndex(defaultNamespace, name);
+	while( ns )
+	{
+		int id = scriptGlobals.GetFirstIndex(ns, name);
+		if( id >= 0 ) return id;
 
-	if( id == -1 ) return asNO_GLOBAL_VAR;
+		// Recursively search parent namespaces
+		ns = engine->GetParentNameSpace(ns);
+	}
 
-	return id;
+	return asNO_GLOBAL_VAR;
 }
 
 // interface
 int asCModule::RemoveGlobalVar(asUINT index)
 {
+	// TODO: 2.30.0: redesign: Before removing the variable, clear it to free the object
+	//                         The property shouldn't be orphaned.
+
 	asCGlobalProperty *prop = scriptGlobals.Get(index);
 	if( !prop )
 		return asINVALID_ARG;
-	prop->Orphan(this);
+
+	// Destroy the internal of the global variable (removes the initialization function)
+	prop->DestroyInternal();
+
+	// Check if the module is the only one referring to the module, if so remove it from the engine too
+	// If the property is not removed now, it will be removed later when the module is discarded
+	if( prop->refCount.get() == 2 )
+		engine->RemoveGlobalProperty(prop);
+
+	// Remove the global variable from the module
+	prop->Release();
 	scriptGlobals.Erase(index);
 
 	return 0;
@@ -686,9 +982,15 @@ int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
 		return r;
 
 	// Search global variables for a match
-	int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
-	if( id != -1 )
-		return id;
+	while( nameSpace )
+	{
+		int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
+		if( id != -1 )
+			return id;
+
+		// Recursively search parent namespace
+		nameSpace = engine->GetParentNameSpace(nameSpace);
+	}
 
 	return asNO_GLOBAL_VAR;
 }
@@ -715,9 +1017,9 @@ const char *asCModule::GetGlobalVarDeclaration(asUINT index, bool includeNamespa
 	if (!prop) return 0;
 
 	asCString *tempString = &asCThreadManager::GetLocalData()->string;
-	*tempString = prop->type.Format();
+	*tempString = prop->type.Format(defaultNamespace);
 	*tempString += " ";
-	if( includeNamespace )
+	if( includeNamespace && prop->nameSpace->name != "" )
 		*tempString += prop->nameSpace->name + "::";
 	*tempString += prop->name;
 
@@ -760,12 +1062,19 @@ asIObjectType *asCModule::GetObjectTypeByIndex(asUINT index) const
 // interface
 asIObjectType *asCModule::GetObjectTypeByName(const char *name) const
 {
-	for( asUINT n = 0; n < classTypes.GetLength(); n++ )
+	asSNameSpace *ns = defaultNamespace;
+	while( ns )
 	{
-		if( classTypes[n] &&
-			classTypes[n]->name == name &&
-			classTypes[n]->nameSpace == defaultNamespace )
-			return classTypes[n];
+		for( asUINT n = 0; n < classTypes.GetLength(); n++ )
+		{
+			if( classTypes[n] &&
+				classTypes[n]->name == name &&
+				classTypes[n]->nameSpace == ns )
+				return classTypes[n];
+		}
+
+		// Recursively search parent namespace
+		ns = engine->GetParentNameSpace(ns);
 	}
 
 	return 0;
@@ -890,7 +1199,7 @@ int asCModule::GetNextImportedFunctionId()
 
 #ifndef AS_NO_COMPILER
 // internal
-int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
+int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isProtected, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
 {
 	asASSERT(id >= 0);
 
@@ -927,8 +1236,11 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
 	func->inOutFlags       = inOutFlags;
 	func->defaultArgs      = defaultArgs;
 	func->objectType       = objType;
+	if( objType )
+		objType->AddRefInternal();
 	func->isReadOnly       = isConstMethod;
 	func->isPrivate        = isPrivate;
+	func->isProtected      = isProtected;
 	func->isFinal          = isFinal;
 	func->isOverride       = isOverride;
 	func->isShared         = isShared;
@@ -939,9 +1251,9 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
 	asASSERT( !(!objType && isFinal) );
 	asASSERT( !(!objType && isOverride) );
 
-	// The script function's refCount was initialized to 1
+	// The internal ref count was already set by the constructor
 	scriptFunctions.PushLast(func);
-	engine->SetScriptFunction(func);
+	engine->AddScriptFunction(func);
 
 	// Compute the signature id
 	if( objType )
@@ -949,10 +1261,7 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
 
 	// Add reference
 	if( isGlobalFunction )
-	{
 		globalFunctions.Put(func);
-		func->AddRef();
-	}
 
 	return 0;
 }
@@ -961,8 +1270,8 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
 int asCModule::AddScriptFunction(asCScriptFunction *func)
 {
 	scriptFunctions.PushLast(func);
-	func->AddRef();
-	engine->SetScriptFunction(func);
+	func->AddRefInternal();
+	engine->AddScriptFunction(func);
 
 	return 0;
 }
@@ -1046,14 +1355,14 @@ int asCModule::BindImportedFunction(asUINT index, asIScriptFunction *func)
 	if( dst->parameterTypes.GetLength() != src->parameterTypes.GetLength() )
 		return asINVALID_INTERFACE;
 
-	for( size_t n = 0; n < dst->parameterTypes.GetLength(); ++n )
+	for( asUINT n = 0; n < dst->parameterTypes.GetLength(); ++n )
 	{
 		if( dst->parameterTypes[n] != src->parameterTypes[n] )
 			return asINVALID_INTERFACE;
 	}
 
 	bindInformations[index]->boundFunctionId = src->GetId();
-	src->AddRef();
+	src->AddRefInternal();
 
 	return asSUCCESS;
 }
@@ -1071,7 +1380,7 @@ int asCModule::UnbindImportedFunction(asUINT index)
 		if( oldFuncID != -1 )
 		{
 			bindInformations[index]->boundFunctionId = -1;
-			engine->scriptFunctions[oldFuncID]->Release();
+			engine->scriptFunctions[oldFuncID]->ReleaseInternal();
 		}
 	}
 
@@ -1111,7 +1420,7 @@ int asCModule::BindAllImportedFunctions()
 		asCScriptFunction *importFunc = GetImportedFunction(n);
 		if( importFunc == 0 ) return asERROR;
 
-		asCString str = importFunc->GetDeclarationStr();
+		asCString str = importFunc->GetDeclarationStr(false, true);
 
 		// Get module name from where the function should be imported
 		const char *moduleName = GetImportedFunctionSourceModule(n);
@@ -1150,7 +1459,7 @@ int asCModule::UnbindAllImportedFunctions()
 // internal
 asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns)
 {
-	size_t n;
+	asUINT n;
 
 	// TODO: optimize: Improve linear search
 	for( n = 0; n < classTypes.GetLength(); n++ )
@@ -1185,8 +1494,9 @@ asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asC
 	// Make an entry in the address to variable map
 	engine->varAddressMap.Insert(prop->GetAddressOfValue(), prop);
 
-	// Store the variable in the module scope (the reference count is already set to 1)
+	// Store the variable in the module scope
 	scriptGlobals.Put(prop);
+	prop->AddRef();
 
 	return prop;
 }
@@ -1230,6 +1540,14 @@ int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
 {
 	if( in == 0 ) return asINVALID_ARG;
 
+	// Don't allow the module to be rebuilt if there are still 
+	// external references that will need the previous code
+	if( HasExternalReferences(false) )
+	{
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_MODULE_IS_IN_USE);
+		return asMODULE_IS_IN_USE;
+	}
+
 	// Only permit loading bytecode if no other thread is currently compiling
 	// TODO: It should be possible to have multiple threads perform compilations
 	int r = engine->RequestBuild();
@@ -1366,14 +1684,14 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
 
 	if( r >= 0 && outFunc && func )
 	{
-		// Return the function to the caller
+		// Return the function to the caller and add an external reference
 		*outFunc = func;
 		func->AddRef();
 	}
 
 	// Release our reference to the function
 	if( func )
-		func->Release();
+		func->ReleaseInternal();
 
 	return r;
 #endif
@@ -1382,15 +1700,24 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
 // interface
 int asCModule::RemoveFunction(asIScriptFunction *func)
 {
+	// TODO: 2.30.0: redesign: Check if there are any references before removing the function
+	//                         if there are, just hide it from the visible but do not destroy or 
+	//                         remove it from the module.
+	//
+	//                         Only if the function has no live references, nor internal references
+	//                         can it be immediately removed, and its internal references released.
+	//
+	//                         Check if any previously hidden functions are without references,
+	//                         if so they should removed too.
+
 	// Find the global function
 	asCScriptFunction *f = static_cast<asCScriptFunction*>(func);
 	int idx = globalFunctions.GetIndex(f);
 	if( idx >= 0 )
 	{
 		globalFunctions.Erase(idx);
-		f->Release();
 		scriptFunctions.RemoveValue(f);
-		f->Orphan(this);
+		f->ReleaseInternal();
 		return 0;
 	}
 
@@ -1412,7 +1739,7 @@ int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
 
 	engine->funcDefs.PushLast(func);
 	func->id = engine->GetNextScriptFunctionId();
-	engine->SetScriptFunction(func);
+	engine->AddScriptFunction(func);
 
 	return (int)funcDefs.GetLength()-1;
 }

+ 17 - 12
Source/ThirdParty/AngelScript/source/as_module.h

@@ -178,6 +178,7 @@ public:
 
 	void InternalReset();
 	bool IsEmpty() const;
+	bool HasExternalReferences(bool shuttingDown);
 
 	int  CallInit(asIScriptContext *ctx);
 	void CallExit();
@@ -185,7 +186,7 @@ public:
 	void JITCompile();
 
 #ifndef AS_NO_COMPILER
-	int  AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
+	int  AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isProtected = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
 	int  AddScriptFunction(asCScriptFunction *func);
 	int  AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName);
 	int  AddFuncDef(const asCString &name, asSNameSpace *ns);
@@ -204,25 +205,29 @@ public:
 	asDWORD           accessMask;
 	asSNameSpace     *defaultNamespace;
 
-	// This array holds all functions, class members, factories, etc that were compiled with the module
-	asCArray<asCScriptFunction *>     scriptFunctions;
-	// This array holds global functions declared in the module
-	asCSymbolTable<asCScriptFunction> globalFunctions;
-	// This array holds imported functions in the module
-	asCArray<sBindInfo *>             bindInformations;
+	// This array holds all functions, class members, factories, etc that were compiled with the module.
+	// These references hold an internal reference to the function object.
+	asCArray<asCScriptFunction *>     scriptFunctions; // increases ref count
+	// This array holds global functions declared in the module. These references are not counted, 
+	// as the same pointer is always present in the scriptFunctions array too.
+	asCSymbolTable<asCScriptFunction> globalFunctions; // doesn't increase ref count
+	// This array holds imported functions in the module.
+	asCArray<sBindInfo *>             bindInformations; // increases ref count
+	// This array holds template instance types created for the module's object types
+	asCArray<asCObjectType*>          templateInstances; // increases ref count
 
 	// This array holds the global variables declared in the script
-	asCSymbolTable<asCGlobalProperty> scriptGlobals;
+	asCSymbolTable<asCGlobalProperty> scriptGlobals; // increases ref count
 	bool                              isGlobalVarInitialized;
 
 	// This array holds class and interface types
-	asCArray<asCObjectType*>       classTypes;
+	asCArray<asCObjectType*>       classTypes; // increases ref count
 	// This array holds enum types
-	asCArray<asCObjectType*>       enumTypes;
+	asCArray<asCObjectType*>       enumTypes; // increases ref count
 	// This array holds typedefs
-	asCArray<asCObjectType*>       typeDefs;
+	asCArray<asCObjectType*>       typeDefs; // increases ref count
 	// This array holds the funcdefs declared in the module
-	asCArray<asCScriptFunction*>   funcDefs;
+	asCArray<asCScriptFunction*>   funcDefs; // increases ref count
 };
 
 END_AS_NAMESPACE

+ 139 - 247
Source/ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -45,140 +45,95 @@
 
 BEGIN_AS_NAMESPACE
 
-#ifdef AS_MAX_PORTABILITY
-
-static void ObjectType_AddRef_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	self->AddRef();
-}
-
-static void ObjectType_Release_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	self->Release();
-}
-
-static void ObjectType_GetRefCount_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
-}
-
-static void ObjectType_SetGCFlag_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	self->SetGCFlag();
-}
-
-static void ObjectType_GetGCFlag_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	*(bool*)gen->GetAddressOfReturnLocation() = self->GetGCFlag();
-}
-
-static void ObjectType_EnumReferences_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
-	self->EnumReferences(engine);
-}
-
-static void ObjectType_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
-{
-	asCObjectType *self = (asCObjectType*)gen->GetObject();
-	asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
-	self->ReleaseAllHandles(engine);
-}
-
-#endif
-
-
-void RegisterObjectTypeGCBehaviours(asCScriptEngine *engine)
-{
-	// Register the gc behaviours for the object types
-	int r = 0;
-	UNUSED_VAR(r); // It is only used in debug mode
-	engine->objectTypeBehaviours.engine = engine;
-	engine->objectTypeBehaviours.flags = asOBJ_REF | asOBJ_GC;
-	engine->objectTypeBehaviours.name = "_builtin_objecttype_";
-#ifndef AS_MAX_PORTABILITY
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCObjectType,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASE, "void f()", asMETHOD(asCObjectType,Release), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(asCObjectType,GetRefCount), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_SETGCFLAG, "void f()", asMETHOD(asCObjectType,SetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCObjectType,GetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCObjectType,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCObjectType,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
-#else
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(ObjectType_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASE, "void f()", asFUNCTION(ObjectType_Release_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ObjectType_GetRefCount_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ObjectType_SetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ObjectType_GetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ObjectType_EnumReferences_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-	r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ObjectType_ReleaseAllHandles_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
-#endif
-}
-
 asCObjectType::asCObjectType() 
 {
-	engine = 0; 
-	module = 0;
-	refCount.set(0); 
+	externalRefCount.set(0); 
+	internalRefCount.set(1); // start with one internal ref-count
+	engine      = 0; 
+	module      = 0;
 	derivedFrom = 0;
+	size        = 0;
 
 	acceptValueSubType = true;
-	acceptRefSubType = true;
+	acceptRefSubType   = true;
+
+	scriptSectionIdx = -1;
+	declaredAt       = 0;
 
 	accessMask = 0xFFFFFFFF;
-	nameSpace = 0;
+	nameSpace  = 0;
+#ifdef WIP_16BYTE_ALIGN
+	alignment  = 4;
+#endif
 }
 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
 {
+	externalRefCount.set(0); 
+	internalRefCount.set(1); // start with one internal ref count
 	this->engine = engine; 
-	module = 0;
-	refCount.set(0); 
+	module       = 0;
 	derivedFrom  = 0;
 
 	acceptValueSubType = true;
-	acceptRefSubType = true;
+	acceptRefSubType   = true;
+
+	scriptSectionIdx = -1;
+	declaredAt       = 0;
 
 	accessMask = 0xFFFFFFFF;
-	nameSpace = engine->nameSpaces[0];
+	nameSpace  = engine->nameSpaces[0];
+#ifdef WIP_16BYTE_ALIGN
+	alignment  = 4;
+#endif
 }
 
 int asCObjectType::AddRef() const
 {
-	gcFlag = false;
-	return refCount.atomicInc();
+	return externalRefCount.atomicInc();
 }
 
 int asCObjectType::Release() const
 {
-	gcFlag = false;
-	return refCount.atomicDec();
+	int r = externalRefCount.atomicDec();
+
+	if( r == 0 )
+	{
+		// There are no more external references, if there are also no
+		// internal references then it is time to delete the object type
+		if( internalRefCount.get() == 0 )
+		{
+			// If the engine is no longer set, then it has already been 
+			// released and we must take care of the deletion ourselves
+			asDELETE(const_cast<asCObjectType*>(this), asCObjectType);
+		}
+	}
+
+	return r;
+}
+
+int asCObjectType::AddRefInternal()
+{
+	return internalRefCount.atomicInc();
 }
 
-void asCObjectType::Orphan(asCModule *mod)
+int asCObjectType::ReleaseInternal()
 {
-	if( mod && mod == module )
+	int r = internalRefCount.atomicDec();
+
+	if( r == 0 )
 	{
-		module = 0;
-		if( flags & asOBJ_SCRIPT_OBJECT )
+		// There are no more internal references, if there are also no
+		// external references then it is time to delete the object type
+		if( externalRefCount.get() == 0 )
 		{
-			// Tell the GC that this type exists so it can resolve potential circular references
-			engine->gc.AddScriptObjectToGC(this, &engine->objectTypeBehaviours);
-
-			// It's necessary to orphan the template instance types that refer to this object type,
-			// otherwise the garbage collector cannot identify the circular references that involve 
-			// the type and the template type
-			engine->OrphanTemplateInstances(this);
+			// If the engine is no longer set, then it has already been 
+			// released and we must take care of the deletion ourselves
+			asDELETE(const_cast<asCObjectType*>(this), asCObjectType);
 		}
 	}
 
-	Release();
+	return r;
 }
 
 // interface
@@ -237,36 +192,29 @@ void *asCObjectType::GetUserData(asPWORD type) const
 	return 0;
 }
 
-int asCObjectType::GetRefCount()
-{
-	return refCount.get();
-}
-
-bool asCObjectType::GetGCFlag()
+void asCObjectType::DestroyInternal()
 {
-	return gcFlag;
-}
+	if( engine == 0 ) return;
 
-void asCObjectType::SetGCFlag()
-{
-	gcFlag = true;
-}
-
-asCObjectType::~asCObjectType()
-{
 	// Skip this for list patterns as they do not increase the references
 	if( flags & asOBJ_LIST_PATTERN )
+	{
+		// Clear the engine pointer to mark the object type as invalid
+		engine = 0;
 		return;
+	}
 
 	// Release the object types held by the templateSubTypes
 	for( asUINT subtypeIndex = 0; subtypeIndex < templateSubTypes.GetLength(); subtypeIndex++ )
 	{
 		if( templateSubTypes[subtypeIndex].GetObjectType() )
-			templateSubTypes[subtypeIndex].GetObjectType()->Release();
+			templateSubTypes[subtypeIndex].GetObjectType()->ReleaseInternal();
 	}
+	templateSubTypes.SetLength(0);
 
 	if( derivedFrom )
-		derivedFrom->Release();
+		derivedFrom->ReleaseInternal();
+	derivedFrom = 0;
 
 	ReleaseAllProperties();
 
@@ -290,6 +238,22 @@ asCObjectType::~asCObjectType()
 					engine->cleanObjectTypeFuncs[c].cleanFunc(this);
 		}
 	}
+	userData.SetLength(0);
+
+	// Remove the type from the engine
+	engine->RemoveFromTypeIdMap(this);
+
+	// Clear the engine pointer to mark the object type as invalid
+	engine = 0;
+}
+
+asCObjectType::~asCObjectType()
+{
+	if( engine == 0 )
+		return;
+
+	// TODO: 2.30.0: redesign: Shouldn't this have been done already?
+	DestroyInternal();
 }
 
 // interface
@@ -468,7 +432,7 @@ asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual
 asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
 {
 	int id = -1;
-	for( size_t n = 0; n < methods.GetLength(); n++ )
+	for( asUINT n = 0; n < methods.GetLength(); n++ )
 	{
 		if( engine->scriptFunctions[methods[n]]->name == name )
 		{
@@ -525,23 +489,26 @@ asUINT asCObjectType::GetPropertyCount() const
 }
 
 // interface
-int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference, asDWORD *accessMask) const
+int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask) const
 {
 	if( index >= properties.GetLength() )
 		return asINVALID_ARG;
 
+	asCObjectProperty *prop = properties[index];
 	if( name )
-		*name = properties[index]->name.AddressOf();
+		*name = prop->name.AddressOf();
 	if( typeId )
-		*typeId = engine->GetTypeIdFromDataType(properties[index]->type);
+		*typeId = engine->GetTypeIdFromDataType(prop->type);
 	if( isPrivate )
-		*isPrivate = properties[index]->isPrivate;
+		*isPrivate = prop->isPrivate;
+	if( isProtected )
+		*isProtected = prop->isProtected;
 	if( offset )
-		*offset = properties[index]->byteOffset;
+		*offset = prop->byteOffset;
 	if( isReference )
-		*isReference = properties[index]->type.IsReference();
+		*isReference = prop->type.IsReference();
 	if( accessMask )
-		*accessMask = properties[index]->accessMask;
+		*accessMask = prop->accessMask;
 
 	return 0;
 }
@@ -555,9 +522,11 @@ const char *asCObjectType::GetPropertyDeclaration(asUINT index, bool includeName
 	asCString *tempString = &asCThreadManager::GetLocalData()->string;
 	if( properties[index]->isPrivate )
 		*tempString = "private ";
+	else if( properties[index]->isProtected )
+		*tempString = "protected ";
 	else
 		*tempString = "";
-	*tempString += properties[index]->type.Format(includeNamespace);
+	*tempString += properties[index]->type.Format(nameSpace, includeNamespace);
 	*tempString += " ";
 	*tempString += properties[index]->name;
 
@@ -589,7 +558,6 @@ asUINT asCObjectType::GetBehaviourCount() const
 	// For reference types, the factories are also stored in the constructor
 	// list, so it is sufficient to enumerate only those
 	count += (asUINT)beh.constructors.GetLength();
-	count += (asUINT)beh.operators.GetLength() / 2;
 
 	return count;
 }
@@ -682,14 +650,6 @@ asIScriptFunction *asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviour
 	else 
 		count += (asUINT)beh.constructors.GetLength();
 
-	if( index - count < beh.operators.GetLength() / 2 )
-	{
-		index = 2*(index - count);
-
-		if( outBehaviour ) *outBehaviour = static_cast<asEBehaviours>(beh.operators[index]);
-		return engine->scriptFunctions[beh.operators[index + 1]];
-	}
-
 	return 0;
 }
 
@@ -710,7 +670,7 @@ asDWORD asCObjectType::GetAccessMask() const
 }
 
 // internal
-asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
+asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited)
 {
 	asASSERT( flags & asOBJ_SCRIPT_OBJECT );
 	asASSERT( dt.CanBeInstantiated() );
@@ -724,9 +684,11 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
 		return 0;
 	}
 
-	prop->name      = name;
-	prop->type      = dt;
-	prop->isPrivate = isPrivate;
+	prop->name        = name;
+	prop->type        = dt;
+	prop->isPrivate   = isPrivate;
+	prop->isProtected = isProtected;
+	prop->isInherited = isInherited;
 
 	int propSize;
 	if( dt.IsObject() )
@@ -748,8 +710,19 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
 		propSize = dt.GetSizeInMemoryBytes();
 
 	// Add extra bytes so that the property will be properly aligned
+#ifndef WIP_16BYTE_ALIGN
 	if( propSize == 2 && (size & 1) ) size += 1;
 	if( propSize > 2 && (size & 3) ) size += 4 - (size & 3);
+#else
+	asUINT alignment = dt.GetAlignment();
+	const asUINT propSizeAlignmentDifference = size & (alignment-1);
+	if( propSizeAlignmentDifference != 0 )
+	{
+		size += (alignment - propSizeAlignmentDifference);
+	}
+
+	asASSERT((size % alignment) == 0);
+#endif
 
 	prop->byteOffset = size;
 	size += propSize;
@@ -763,7 +736,7 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
 	// Add reference to object types
 	asCObjectType *type = prop->type.GetObjectType();
 	if( type )
-		type->AddRef();
+		type->AddRefInternal();
 
 	return prop;
 }
@@ -784,7 +757,14 @@ void asCObjectType::ReleaseAllProperties()
 				// Release references to objects types
 				asCObjectType *type = properties[n]->type.GetObjectType();
 				if( type )
-					type->Release();
+					type->ReleaseInternal();
+			}
+			else
+			{
+				// Release template instance types (ref increased by RegisterObjectProperty)
+				asCObjectType *type = properties[n]->type.GetObjectType();
+				if( type )
+					type->ReleaseInternal();
 			}
 
 			asDELETE(properties[n],asCObjectProperty);
@@ -794,13 +774,6 @@ void asCObjectType::ReleaseAllProperties()
 	properties.SetLength(0);
 }
 
-// internal
-void asCObjectType::ReleaseAllHandles(asIScriptEngine *)
-{
-	ReleaseAllFunctions();
-	ReleaseAllProperties();
-}
-
 // internal
 void asCObjectType::ReleaseAllFunctions()
 {
@@ -809,7 +782,7 @@ void asCObjectType::ReleaseAllFunctions()
 	for( asUINT a = 0; a < beh.factories.GetLength(); a++ )
 	{
 		if( engine->scriptFunctions[beh.factories[a]] ) 
-			engine->scriptFunctions[beh.factories[a]]->Release();
+			engine->scriptFunctions[beh.factories[a]]->ReleaseInternal();
 	}
 	beh.factories.SetLength(0);
 
@@ -818,155 +791,74 @@ void asCObjectType::ReleaseAllFunctions()
 	for( asUINT b = 0; b < beh.constructors.GetLength(); b++ )
 	{
 		if( engine->scriptFunctions[beh.constructors[b]] ) 
-			engine->scriptFunctions[beh.constructors[b]]->Release();
+			engine->scriptFunctions[beh.constructors[b]]->ReleaseInternal();
 	}
 	beh.constructors.SetLength(0);
 
 	if( beh.templateCallback )
-		engine->scriptFunctions[beh.templateCallback]->Release();
+		engine->scriptFunctions[beh.templateCallback]->ReleaseInternal();
 	beh.templateCallback = 0;
 
 	if( beh.listFactory )
-		engine->scriptFunctions[beh.listFactory]->Release();
+		engine->scriptFunctions[beh.listFactory]->ReleaseInternal();
 	beh.listFactory = 0;
 
 	if( beh.destruct )
-		engine->scriptFunctions[beh.destruct]->Release();
+		engine->scriptFunctions[beh.destruct]->ReleaseInternal();
 	beh.destruct  = 0;
 
 	if( beh.copy )
-		engine->scriptFunctions[beh.copy]->Release();
+		engine->scriptFunctions[beh.copy]->ReleaseInternal();
 	beh.copy = 0;
 
-	for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
-	{
-		if( engine->scriptFunctions[beh.operators[e]] )
-			engine->scriptFunctions[beh.operators[e]]->Release();
-	}
-	beh.operators.SetLength(0);
-
 	for( asUINT c = 0; c < methods.GetLength(); c++ )
 	{
 		if( engine->scriptFunctions[methods[c]] ) 
-			engine->scriptFunctions[methods[c]]->Release();
+			engine->scriptFunctions[methods[c]]->ReleaseInternal();
 	}
 	methods.SetLength(0);
 
 	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
 	{
 		if( virtualFunctionTable[d] )
-			virtualFunctionTable[d]->Release();
+			virtualFunctionTable[d]->ReleaseInternal();
 	}
 	virtualFunctionTable.SetLength(0);
 
 	// GC behaviours
 	if( beh.addref )
-		engine->scriptFunctions[beh.addref]->Release();
+		engine->scriptFunctions[beh.addref]->ReleaseInternal();
 	beh.addref = 0;
 
 	if( beh.release )
-		engine->scriptFunctions[beh.release]->Release();
+		engine->scriptFunctions[beh.release]->ReleaseInternal();
 	beh.release = 0;
 
 	if( beh.gcEnumReferences )
-		engine->scriptFunctions[beh.gcEnumReferences]->Release();
+		engine->scriptFunctions[beh.gcEnumReferences]->ReleaseInternal();
 	beh.gcEnumReferences = 0;
 
 	if( beh.gcGetFlag )
-		engine->scriptFunctions[beh.gcGetFlag]->Release();
+		engine->scriptFunctions[beh.gcGetFlag]->ReleaseInternal();
 	beh.gcGetFlag = 0;
 
 	if( beh.gcGetRefCount )
-		engine->scriptFunctions[beh.gcGetRefCount]->Release();
+		engine->scriptFunctions[beh.gcGetRefCount]->ReleaseInternal();
 	beh.gcGetRefCount = 0;
 
 	if( beh.gcReleaseAllReferences )
-		engine->scriptFunctions[beh.gcReleaseAllReferences]->Release();
+		engine->scriptFunctions[beh.gcReleaseAllReferences]->ReleaseInternal();
 	beh.gcReleaseAllReferences = 0;
 
 	if( beh.gcSetFlag )
-		engine->scriptFunctions[beh.gcSetFlag]->Release();
+		engine->scriptFunctions[beh.gcSetFlag]->ReleaseInternal();
 	beh.gcSetFlag = 0;
 
 	if ( beh.getWeakRefFlag )
-		engine->scriptFunctions[beh.getWeakRefFlag]->Release();
+		engine->scriptFunctions[beh.getWeakRefFlag]->ReleaseInternal();
 	beh.getWeakRefFlag = 0;
 }
 
-// internal
-void asCObjectType::EnumReferences(asIScriptEngine *)
-{
-	for( asUINT a = 0; a < beh.factories.GetLength(); a++ )
-		if( engine->scriptFunctions[beh.factories[a]] ) 
-			engine->GCEnumCallback(engine->scriptFunctions[beh.factories[a]]);
-
-	for( asUINT b = 0; b < beh.constructors.GetLength(); b++ )
-		if( engine->scriptFunctions[beh.constructors[b]] ) 
-			engine->GCEnumCallback(engine->scriptFunctions[beh.constructors[b]]);
-
-	if( beh.templateCallback )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.templateCallback]);
-
-	if( beh.listFactory )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.listFactory]);
-		
-	if( beh.destruct )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.destruct]);
-
-	if( beh.addref )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.addref]);
-
-	if( beh.release )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.release]);
-
-	if( beh.copy )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.copy]);
-
-	if( beh.gcEnumReferences )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.gcEnumReferences]);
-
-	if( beh.gcGetFlag )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.gcGetFlag]);
-
-	if( beh.gcGetRefCount )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.gcGetRefCount]);
-
-	if( beh.gcReleaseAllReferences )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.gcReleaseAllReferences]);
-
-	if( beh.gcSetFlag )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.gcSetFlag]);
-
-	for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
-		if( engine->scriptFunctions[beh.operators[e]] )
-			engine->GCEnumCallback(engine->scriptFunctions[beh.operators[e]]);
-
-	for( asUINT c = 0; c < methods.GetLength(); c++ )
-		if( engine->scriptFunctions[methods[c]] ) 
-			engine->GCEnumCallback(engine->scriptFunctions[methods[c]]);
-
-	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
-		if( virtualFunctionTable[d] )
-			engine->GCEnumCallback(virtualFunctionTable[d]);
-
-	for( asUINT p = 0; p < properties.GetLength(); p++ )
-	{
-		asCObjectType *type = properties[p]->type.GetObjectType();
-		if( type )
-			engine->GCEnumCallback(type);
-	}
-
-	for( asUINT t = 0; t < templateSubTypes.GetLength(); t++ )
-		if( templateSubTypes[t].GetObjectType() )
-			engine->GCEnumCallback(templateSubTypes[t].GetObjectType());
-
-	if( beh.getWeakRefFlag )
-		engine->GCEnumCallback(engine->scriptFunctions[beh.getWeakRefFlag]);
-
-	if( derivedFrom )
-		engine->GCEnumCallback(derivedFrom);
-}
-
 END_AS_NAMESPACE
 
 

+ 19 - 13
Source/ThirdParty/AngelScript/source/as_objecttype.h

@@ -97,7 +97,6 @@ struct asSTypeBehaviour
 
 	asCArray<int> factories;
 	asCArray<int> constructors;
-	asCArray<int> operators;
 };
 
 struct asSEnumValue
@@ -109,8 +108,6 @@ struct asSEnumValue
 class asCScriptEngine;
 struct asSNameSpace;
 
-void RegisterObjectTypeGCBehaviours(asCScriptEngine *engine);
-
 class asCObjectType : public asIObjectType
 {
 public:
@@ -156,7 +153,7 @@ public:
 
 	// Properties
 	asUINT      GetPropertyCount() const;
-	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference, asDWORD *accessMask) const;
+	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask) const;
 	const char *GetPropertyDeclaration(asUINT index, bool includeNamespace = false) const;
 
 	// Behaviours
@@ -173,25 +170,27 @@ public:
 public:
 	asCObjectType(asCScriptEngine *engine);
 	~asCObjectType();
+	void DestroyInternal();
 
-	void Orphan(asCModule *module);
-	int  GetRefCount();
-	void SetGCFlag();
-	bool GetGCFlag();
-	void EnumReferences(asIScriptEngine *);
-	void ReleaseAllHandles(asIScriptEngine *);
+	// Keep an internal reference counter to separate references coming from 
+	// application or script objects and references coming from the script code
+	int AddRefInternal();
+	int ReleaseInternal();
 
 	void ReleaseAllFunctions();
 
 	bool IsInterface() const;
 	bool IsShared() const;
 
-	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
+	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited);
 	void ReleaseAllProperties();
 
 	asCString                    name;
 	asSNameSpace                *nameSpace;
 	int                          size;
+#ifdef WIP_16BYTE_ALIGN
+	int                          alignment;
+#endif
 	asCArray<asCObjectProperty*> properties;
 	asCArray<int>                methods;
 	asCArray<asCObjectType*>     interfaces;
@@ -210,16 +209,23 @@ public:
 	bool                  acceptValueSubType;
 	bool                  acceptRefSubType;
 
+	// Store the script section where the code was declared
+	int                             scriptSectionIdx;
+	// Store the location where the function was declared (row in the lower 20 bits, and column in the upper 12)
+	int                             declaredAt;
+
 	asCScriptEngine  *engine;
 	asCModule        *module;
 	asCArray<asPWORD> userData;
 
 protected:
 	friend class asCScriptEngine;
+	friend class asCConfigGroup;
+	friend class asCModule;
 	asCObjectType();
 
-	mutable asCAtomic refCount;
-	mutable bool      gcFlag;
+	mutable asCAtomic externalRefCount;
+	asCAtomic         internalRefCount;
 };
 
 END_AS_NAMESPACE

+ 110 - 27
Source/ThirdParty/AngelScript/source/as_parser.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -34,6 +34,18 @@
 //
 // This class parses the script code and builds a tree for compilation
 //
+//
+// I've documented the syntax in Extended BNF. You'll find it by doing a search in 
+// this file by "BNF:". The starting point for the script language is SCRIPT ::=.
+//
+// Ref: http://matt.might.net/articles/grammars-bnf-ebnf/
+//
+// ( )  - used for grouping
+// { }  - 0 or more repetitions
+// [ ]  - optional
+//  |   - or
+// ' '  - token
+//
 
 
 
@@ -249,6 +261,13 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
 	scriptNode->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return -1;
 
+	// Allow optional '&' to indicate that the property is indirect, i.e. stored as reference
+	sToken t;
+	GetToken(&t);
+	RewindTo(&t);
+	if( t.type == ttAmp )
+		scriptNode->AddChildLast(ParseToken(ttAmp));
+
 	// Allow optional namespace to be defined before the identifier in case
 	// the declaration is to be used for searching for an existing property
 	ParseOptionalScope(scriptNode);
@@ -257,7 +276,6 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
 	if( isSyntaxError ) return -1;
 
 	// The declaration should end after the identifier
-	sToken t;
 	GetToken(&t);
 	if( t.type != ttEnd )
 	{
@@ -269,6 +287,7 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
 	return 0;
 }
 
+// BNF: SCOPE ::= [[IDENTIFIER] '::' {IDENTIFIER '::'}]
 void asCParser::ParseOptionalScope(asCScriptNode *node)
 {
 	sToken t1, t2;
@@ -321,6 +340,7 @@ asCScriptNode *asCParser::ParseFunctionDefinition()
 	return node;
 }
 
+// BNF: TYPEMOD ::= ['&' ['in' | 'out' | 'inout']]
 asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 {
 	asCScriptNode *node = CreateNode(snDataType);
@@ -361,6 +381,7 @@ asCScriptNode *asCParser::ParseTypeMod(bool isParam)
 	return node;
 }
 
+// BNF: TYPE ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | '@' }
 asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, bool allowAuto)
 {
 	asCScriptNode *node = CreateNode(snDataType);
@@ -387,9 +408,11 @@ asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, boo
 	if( isSyntaxError ) return node;
 
 	// If the datatype is a template type, then parse the subtype within the < >
+	GetToken(&t);
+	RewindTo(&t);
 	asCScriptNode *type = node->lastChild;
 	tempString.Assign(&script->code[type->tokenPos], type->tokenLength);
-	if( engine->IsTemplateType(tempString.AddressOf()) )
+	if( engine->IsTemplateType(tempString.AddressOf()) && t.type == ttLessThan )
 	{
 		GetToken(&t);
 		if( t.type != ttLessThan )
@@ -507,7 +530,7 @@ asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
 	return node;
 }
 
-
+// BNF: DATATYPE ::= (IDENTIFIER | PRIMTYPE | '?' | 'auto')
 asCScriptNode *asCParser::ParseDataType(bool allowVariableType, bool allowAuto)
 {
 	asCScriptNode *node = CreateNode(snDataType);
@@ -543,6 +566,7 @@ asCScriptNode *asCParser::ParseDataType(bool allowVariableType, bool allowAuto)
 	return node;
 }
 
+// BNF: PRIMTYPE ::= 'void' | 'int' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float' | 'double' | 'bool'
 asCScriptNode *asCParser::ParseRealType()
 {
 	asCScriptNode *node = CreateNode(snDataType);
@@ -564,6 +588,7 @@ asCScriptNode *asCParser::ParseRealType()
 	return node;
 }
 
+// BNF: IDENTIFIER ::= single token:  starts with letter or _, can include any letter and digit, same as in C++
 asCScriptNode *asCParser::ParseIdentifier()
 {
 	asCScriptNode *node = CreateNode(snIdentifier);
@@ -585,6 +610,7 @@ asCScriptNode *asCParser::ParseIdentifier()
 	return node;
 }
 
+// BNF: PARAMLIST ::= '(' ('void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]}) ')'
 asCScriptNode *asCParser::ParseParameterList()
 {
 	asCScriptNode *node = CreateNode(snParameterList);
@@ -1086,10 +1112,13 @@ bool asCParser::CheckTemplateType(sToken &t)
 	tempString.Assign(&script->code[t.pos], t.length);
 	if( engine->IsTemplateType(tempString.AddressOf()) )
 	{
-		// Expect the sub type within < >
+		// If the next token is a < then parse the sub-type too
 		GetToken(&t);
 		if( t.type != ttLessThan )
-			return false;
+		{
+			RewindTo(&t);
+			return true;
+		}
 
 		for(;;)
 		{
@@ -1153,6 +1182,7 @@ bool asCParser::CheckTemplateType(sToken &t)
 	return true;
 }
 
+// BNF: CAST ::= 'cast' '<' TYPE '>' '(' ASSIGN ')'
 asCScriptNode *asCParser::ParseCast()
 {
 	asCScriptNode *node = CreateNode(snCast);
@@ -1181,9 +1211,6 @@ asCScriptNode *asCParser::ParseCast()
 	node->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return node;
 
-	node->AddChildLast(ParseTypeMod(false));
-	if( isSyntaxError ) return node;
-
 	GetToken(&t1);
 	if( t1.type != ttGreaterThan )
 	{
@@ -1216,6 +1243,7 @@ asCScriptNode *asCParser::ParseCast()
 	return node;
 }
 
+// BNF: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')'
 asCScriptNode *asCParser::ParseExprValue()
 {
 	asCScriptNode *node = CreateNode(snExprValue);
@@ -1302,6 +1330,10 @@ asCScriptNode *asCParser::ParseExprValue()
 	return node;
 }
 
+// BNF: LITERAL ::= NUMBER | STRING | BITS | 'true' | 'false' | 'null'
+// BNF: NUMBER ::= single token:  includes integers and real numbers, same as C++
+// BNF: STRING ::= single token:  single quoted ', double quoted ", or heredoc multi-line string """
+// BNF: BITS ::= single token:  binary 0b or 0B, octal 0o or 0O, decimal 0d or 0D, hexadecimal 0x or 0X
 asCScriptNode *asCParser::ParseConstant()
 {
 	asCScriptNode *node = CreateNode(snConstant);
@@ -1354,6 +1386,7 @@ asCScriptNode *asCParser::ParseStringConstant()
 	return node;
 }
 
+// BNF: FUNCCALL ::= SCOPE IDENTIFIER ARGLIST
 asCScriptNode *asCParser::ParseFunctionCall()
 {
 	asCScriptNode *node = CreateNode(snFunctionCall);
@@ -1371,6 +1404,7 @@ asCScriptNode *asCParser::ParseFunctionCall()
 	return node;
 }
 
+// BNF: VARACCESS ::= SCOPE IDENTIFIER
 asCScriptNode *asCParser::ParseVariableAccess()
 {
 	asCScriptNode *node = CreateNode(snVariableAccess);
@@ -1385,6 +1419,7 @@ asCScriptNode *asCParser::ParseVariableAccess()
 	return node;
 }
 
+// BNF: CONSTRUCTCALL ::= TYPE ARGLIST
 asCScriptNode *asCParser::ParseConstructCall()
 {
 	asCScriptNode *node = CreateNode(snConstructCall);
@@ -1398,6 +1433,7 @@ asCScriptNode *asCParser::ParseConstructCall()
 	return node;
 }
 
+// BNF: ARGLIST ::= '(' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ')'
 asCScriptNode *asCParser::ParseArgList(bool withParenthesis)
 {
 	asCScriptNode *node = CreateNode(snArgList);
@@ -1535,6 +1571,7 @@ bool asCParser::IsFunctionCall()
 	return false;
 }
 
+// BNF: ASSIGN ::= CONDITION [ ASSIGNOP ASSIGN ]
 asCScriptNode *asCParser::ParseAssignment()
 {
 	asCScriptNode *node = CreateNode(snAssignment);
@@ -1559,6 +1596,7 @@ asCScriptNode *asCParser::ParseAssignment()
 	return node;
 }
 
+// BNF: CONDITION ::= EXPR ['?' ASSIGN ':' ASSIGN]
 asCScriptNode *asCParser::ParseCondition()
 {
 	asCScriptNode *node = CreateNode(snCondition);
@@ -1591,6 +1629,7 @@ asCScriptNode *asCParser::ParseCondition()
 	return node;
 }
 
+// BNF: EXPR ::= (TYPE '=' INILIST) | (EXPRTERM {EXPROP EXPRTERM})
 asCScriptNode *asCParser::ParseExpression()
 {
 	asCScriptNode *node = CreateNode(snExpression);
@@ -1640,6 +1679,7 @@ asCScriptNode *asCParser::ParseExpression()
 	UNREACHABLE_RETURN;
 }
 
+// BNF: EXPRTERM ::= {EXPRPREOP} EXPRVALUE {EXPRPOSTOP}
 asCScriptNode *asCParser::ParseExprTerm()
 {
 	asCScriptNode *node = CreateNode(snExprTerm);
@@ -1675,6 +1715,7 @@ asCScriptNode *asCParser::ParseExprTerm()
 	UNREACHABLE_RETURN;
 }
 
+// BNF: EXPRPREOP ::= '-' | '+' | '!' | '++' | '--' | '~' | '@'
 asCScriptNode *asCParser::ParseExprPreOp()
 {
 	asCScriptNode *node = CreateNode(snExprPreOp);
@@ -1695,6 +1736,7 @@ asCScriptNode *asCParser::ParseExprPreOp()
 	return node;
 }
 
+// BNF: EXPRPOSTOP ::= ('.' (FUNCCALL | IDENTIFIER)) | ('[' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':' ASSIGN} ']') | ARGLIST | '++' | '--'
 asCScriptNode *asCParser::ParseExprPostOp()
 {
 	asCScriptNode *node = CreateNode(snExprPostOp);
@@ -1746,6 +1788,11 @@ asCScriptNode *asCParser::ParseExprPostOp()
 	return node;
 }
 
+// BNF: EXPROP ::= MATHOP | COMPOP | LOGICOP | BITOP
+// BNF: MATHOP ::= '+' | '-' | '*' | '/' | '%' | '**'
+// BNF: COMPOP ::= '==' | '!=' | '<' | '<=' | '>' | '>=' | 'is' | '!is'
+// BNF: LOGICOP ::= '&&' | '||' | '^^' | 'and' | 'or' | 'xor'
+// BNF: BITOP ::= '&' | '|' | '^' | '<<' | '>>' | '>>>'
 asCScriptNode *asCParser::ParseExprOperator()
 {
 	asCScriptNode *node = CreateNode(snExprOperator);
@@ -1766,6 +1813,7 @@ asCScriptNode *asCParser::ParseExprOperator()
 	return node;
 }
 
+// BNF: ASSIGNOP ::= '=' | '+=' | '-=' | '*=' | '/=' | '|=' | '&=' | '^=' | '%=' | '**=' | '<<=' | '>>=' | '>>>=' 
 asCScriptNode *asCParser::ParseAssignOperator()
 {
 	asCScriptNode *node = CreateNode(snExprOperator);
@@ -1888,13 +1936,17 @@ int asCParser::ParseScript(asCScriptCode *script)
 	if( errorWhileParsing )
 		return -1;
 
+	// TODO: Should allow application to request this warning to be generated. 
+	//       It should be off by default, since pre-processor may remove all
+	//       code from a section while still being meant as valid code
+/*
 	// Warn in case there isn't anything in the script
 	if( scriptNode->firstChild == 0 )
 	{
 		if( builder )
 			builder->WriteWarning(script->name, TXT_SECTION_IS_EMPTY, 1, 1);
 	}
-
+*/
 	return 0;
 }
 
@@ -1913,6 +1965,7 @@ int asCParser::ParseExpression(asCScriptCode *script)
 	return 0;
 }
 
+// BNF: IMPORT ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST 'from' STRING ';'
 asCScriptNode *asCParser::ParseImport()
 {
 	asCScriptNode *node = CreateNode(snImport);
@@ -1980,6 +2033,7 @@ asCScriptNode *asCParser::ParseImport()
 	return node;
 }
 
+// BNF: SCRIPT ::= {IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VIRTPROP | VAR | FUNC | NAMESPACE | ';'}
 asCScriptNode *asCParser::ParseScript(bool inBlock)
 {
 	asCScriptNode *node = CreateNode(snScript);
@@ -2071,6 +2125,7 @@ asCScriptNode *asCParser::ParseScript(bool inBlock)
 	UNREACHABLE_RETURN;
 }
 
+// BNF: NAMESPACE ::= 'namespace' IDENTIFIER '{' SCRIPT '}'
 asCScriptNode *asCParser::ParseNamespace()
 {
 	asCScriptNode *node = CreateNode(snNamespace);
@@ -2147,6 +2202,7 @@ int asCParser::ParseStatementBlock(asCScriptCode *script, asCScriptNode *block)
 	return 0;
 }
 
+// BNF: ENUM ::= ['shared'] 'enum' IDENTIFIER '{' IDENTIFIER ['=' EXPR] {',' IDENTIFIER ['=' EXPR]} '}'
 asCScriptNode *asCParser::ParseEnumeration()
 {
 	asCScriptNode *ident;
@@ -2262,7 +2318,7 @@ asCScriptNode *asCParser::ParseEnumeration()
 	if( token.type != ttEndStatementBlock ) 
 	{
 		RewindTo(&token);
-		Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)), &token);
+		Error(ExpectedToken("}"), &token);
 		Error(InsteadFound(token), &token);
 		return node;
 	}
@@ -2278,10 +2334,10 @@ bool asCParser::IsVarDecl()
 	GetToken(&t);
 	RewindTo(&t);
 
-	// A class property decl can be preceded by 'private' 
+	// A class property decl can be preceded by 'private' or 'protected'
 	sToken t1;
 	GetToken(&t1);
-	if( t1.type != ttPrivate )
+	if( t1.type != ttPrivate && t1.type != ttProtected )
 		RewindTo(&t1);
 
 	// A variable decl can start with a const
@@ -2399,10 +2455,10 @@ bool asCParser::IsVirtualPropertyDecl()
 	GetToken(&t);
 	RewindTo(&t);
 
-	// A class property decl can be preceded by 'private' 
+	// A class property decl can be preceded by 'private' or 'protected'
 	sToken t1;
 	GetToken(&t1);
-	if( t1.type != ttPrivate )
+	if( t1.type != ttPrivate && t1.type != ttProtected )
 		RewindTo(&t1);
 
 	// A variable decl can start with a const
@@ -2470,10 +2526,10 @@ bool asCParser::IsFuncDecl(bool isMethod)
 
 	if( isMethod )
 	{
-		// A class method decl can be preceded by 'private' 
+		// A class method decl can be preceded by 'private' or 'protected'
 		sToken t1, t2;
 		GetToken(&t1);
-		if( t1.type != ttPrivate )
+		if( t1.type != ttPrivate && t1.type != ttProtected )
 			RewindTo(&t1);
 
 		// A class constructor starts with identifier followed by parenthesis
@@ -2610,6 +2666,7 @@ bool asCParser::IsFuncDecl(bool isMethod)
 	return false;
 }
 
+// BNF: FUNCDEF ::= 'funcdef' TYPE ['&'] IDENTIFIER PARAMLIST ';'
 asCScriptNode *asCParser::ParseFuncDef()
 {
 	asCScriptNode *node = CreateNode(snFuncDef);
@@ -2650,6 +2707,7 @@ asCScriptNode *asCParser::ParseFuncDef()
 	return node;
 }
 
+// BNF: FUNC ::= ['private' | 'protected' | 'shared'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] {'override' | 'final'} STATBLOCK 
 asCScriptNode *asCParser::ParseFunction(bool isMethod)
 {
 	asCScriptNode *node = CreateNode(snFunction);
@@ -2660,12 +2718,12 @@ asCScriptNode *asCParser::ParseFunction(bool isMethod)
 	GetToken(&t2);
 	RewindTo(&t1);
 
-	// A class method can start with private
+	// A class method can start with 'private' or 'protected'
 	if( isMethod && t1.type == ttPrivate )
-	{
 		node->AddChildLast(ParseToken(ttPrivate));
-		if( isSyntaxError ) return node;
-	}
+	else if( isMethod && t1.type == ttProtected )
+		node->AddChildLast(ParseToken(ttProtected));
+	if( isSyntaxError ) return node;
 
 	// A global function can be marked as shared
 	if( !isMethod && IdentifierIs(t1, SHARED_TOKEN) )
@@ -2718,6 +2776,7 @@ asCScriptNode *asCParser::ParseFunction(bool isMethod)
 	return node;
 }
 
+// BNF: INTFMTHD ::= TYPE ['&'] IDENTIFIER PARAMLIST ['const'] ';'
 asCScriptNode *asCParser::ParseInterfaceMethod()
 {
 	asCScriptNode *node = CreateNode(snFunction);
@@ -2755,6 +2814,7 @@ asCScriptNode *asCParser::ParseInterfaceMethod()
 	return node;
 }
 
+// BNF: VIRTPROP ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] [('override' | 'final')] (STATBLOCK | ';')} '}'
 asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
 {
 	asCScriptNode *node = CreateNode(snVirtualProperty);
@@ -2765,12 +2825,12 @@ asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterfa
 	GetToken(&t2);
 	RewindTo(&t1);
 
-	// A class method can start with private
+	// A class method can start with 'private' or 'protected'
 	if( isMethod && t1.type == ttPrivate )
-	{
 		node->AddChildLast(ParseToken(ttPrivate));
-		if( isSyntaxError ) return node;
-	}
+	else if( isMethod && t1.type == ttProtected )
+		node->AddChildLast(ParseToken(ttProtected));
+	if( isSyntaxError ) return node;
 
 	node->AddChildLast(ParseType(true));
 	if( isSyntaxError ) return node;
@@ -2859,6 +2919,7 @@ asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterfa
 	return node;
 }
 
+// BNF: INTERFACE ::= ['shared'] 'interface' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | INTFMTHD} '}'
 asCScriptNode *asCParser::ParseInterface()
 {
 	asCScriptNode *node = CreateNode(snInterface);
@@ -2955,6 +3016,7 @@ asCScriptNode *asCParser::ParseInterface()
 	return node;
 }
 
+// BNF: MIXIN ::= 'mixin' CLASS
 asCScriptNode *asCParser::ParseMixin()
 {
 	asCScriptNode *node = CreateNode(snMixin);
@@ -2978,6 +3040,7 @@ asCScriptNode *asCParser::ParseMixin()
 	return node;
 }
 
+// BNF: CLASS ::= {'shared' | 'abstract' | 'final'} 'class' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | FUNC | VAR} '}'
 asCScriptNode *asCParser::ParseClass()
 {
 	asCScriptNode *node = CreateNode(snClass);
@@ -3287,6 +3350,7 @@ asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
 	return node;
 }
 
+// BNF: STATBLOCK ::= '{' {VAR | STATEMENT} '}'
 asCScriptNode *asCParser::ParseStatementBlock()
 {
 	asCScriptNode *node = CreateNode(snStatementBlock);
@@ -3369,6 +3433,7 @@ asCScriptNode *asCParser::ParseStatementBlock()
 	UNREACHABLE_RETURN;
 }
 
+// BNF: INITLIST ::= '{' [ASSIGN | INITLIST] {',' [ASSIGN | INITLIST]} '}'
 asCScriptNode *asCParser::ParseInitList()
 {
 	asCScriptNode *node = CreateNode(snInitList);
@@ -3404,12 +3469,14 @@ asCScriptNode *asCParser::ParseInitList()
 			{
 				// No expression 
 				node->AddChildLast(CreateNode(snUndefined));
+				node->lastChild->UpdateSourcePos(t1.pos, 1);
 				
 				GetToken(&t1);
 				if( t1.type == ttEndStatementBlock )
 				{
 					// No expression
 					node->AddChildLast(CreateNode(snUndefined));
+					node->lastChild->UpdateSourcePos(t1.pos, 1);
 					node->UpdateSourcePos(t1.pos, t1.length);
 					return node;
 				}
@@ -3419,7 +3486,7 @@ asCScriptNode *asCParser::ParseInitList()
 			{
 				// No expression 
 				node->AddChildLast(CreateNode(snUndefined));
-
+				node->lastChild->UpdateSourcePos(t1.pos, 1);
 				node->UpdateSourcePos(t1.pos, t1.length);
 
 				// Statement block is finished
@@ -3477,6 +3544,7 @@ asCScriptNode *asCParser::ParseInitList()
 	UNREACHABLE_RETURN;
 }
 
+// BNF: VAR ::= ['private'|'protected'] TYPE IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST] {',' IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST]} ';'
 asCScriptNode *asCParser::ParseDeclaration(bool isClassProp, bool isGlobalVar)
 {
 	asCScriptNode *node = CreateNode(snDeclaration);
@@ -3489,6 +3557,8 @@ asCScriptNode *asCParser::ParseDeclaration(bool isClassProp, bool isGlobalVar)
 	// A class property can be preceeded by private
 	if( t.type == ttPrivate && isClassProp )
 		node->AddChildLast(ParseToken(ttPrivate));
+	else if( t.type == ttProtected && isClassProp )
+		node->AddChildLast(ParseToken(ttProtected));
 	
 	// Parse data type
 	node->AddChildLast(ParseType(true, false, !isClassProp));
@@ -3560,6 +3630,7 @@ asCScriptNode *asCParser::ParseDeclaration(bool isClassProp, bool isGlobalVar)
 	UNREACHABLE_RETURN;
 }
 
+// BNF: STATEMENT ::= (IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPRSTAT)
 asCScriptNode *asCParser::ParseStatement()
 {
 	sToken t1;
@@ -3596,6 +3667,7 @@ asCScriptNode *asCParser::ParseStatement()
 	}
 }
 
+// BNF: EXPRSTAT ::= [ASSIGN] ';'
 asCScriptNode *asCParser::ParseExpressionStatement()
 {
 	asCScriptNode *node = CreateNode(snExpressionStatement);
@@ -3628,6 +3700,7 @@ asCScriptNode *asCParser::ParseExpressionStatement()
 	return node;
 }
 
+// BNF: SWITCH ::= 'switch' '(' ASSIGN ')' '{' {CASE} '}'
 asCScriptNode *asCParser::ParseSwitch()
 {
 	asCScriptNode *node = CreateNode(snSwitch);
@@ -3702,6 +3775,7 @@ asCScriptNode *asCParser::ParseSwitch()
 	return node;
 }
 
+// BNF: CASE ::= (('case' EXPR) | 'default') ':' {STATEMENT}
 asCScriptNode *asCParser::ParseCase()
 {
 	asCScriptNode *node = CreateNode(snCase);
@@ -3757,6 +3831,7 @@ asCScriptNode *asCParser::ParseCase()
 	return node;
 }
 
+// BNF: IF ::= 'if' '(' ASSIGN ')' STATEMENT ['else' STATEMENT]
 asCScriptNode *asCParser::ParseIf()
 {
 	asCScriptNode *node = CreateNode(snIf);
@@ -3808,6 +3883,7 @@ asCScriptNode *asCParser::ParseIf()
 	return node;
 }
 
+// BNF: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN] ')' STATEMENT
 asCScriptNode *asCParser::ParseFor()
 {
 	asCScriptNode *node = CreateNode(snFor);
@@ -3866,6 +3942,7 @@ asCScriptNode *asCParser::ParseFor()
 	return node;
 }
 
+// BNF: WHILE ::= 'while' '(' ASSIGN ')' STATEMENT
 asCScriptNode *asCParser::ParseWhile()
 {
 	asCScriptNode *node = CreateNode(snWhile);
@@ -3906,6 +3983,7 @@ asCScriptNode *asCParser::ParseWhile()
 	return node;
 }
 
+// BNF: DOWHILE ::= 'do' STATEMENT 'while' '(' ASSIGN ')' ';'
 asCScriptNode *asCParser::ParseDoWhile()
 {
 	asCScriptNode *node = CreateNode(snDoWhile);
@@ -3964,6 +4042,7 @@ asCScriptNode *asCParser::ParseDoWhile()
 	return node;
 }
 
+// BNF: RETURN ::= 'return' [ASSIGN] ';'
 asCScriptNode *asCParser::ParseReturn()
 {
 	asCScriptNode *node = CreateNode(snReturn);
@@ -4005,6 +4084,7 @@ asCScriptNode *asCParser::ParseReturn()
 	return node;
 }
 
+// BNF: BREAK ::= 'break' ';'
 asCScriptNode *asCParser::ParseBreak()
 {
 	asCScriptNode *node = CreateNode(snBreak);
@@ -4033,6 +4113,7 @@ asCScriptNode *asCParser::ParseBreak()
 	return node;
 }
 
+// BNF: CONTINUE ::= 'continue' ';'
 asCScriptNode *asCParser::ParseContinue()
 {
 	asCScriptNode *node = CreateNode(snContinue);
@@ -4062,6 +4143,7 @@ asCScriptNode *asCParser::ParseContinue()
 }
 
 // TODO: typedef: Typedefs should accept complex types as well
+// BNF: TYPEDEF ::= 'typedef' PRIMTYPE IDENTIFIER ';'
 asCScriptNode *asCParser::ParseTypedef()
 {
 	// Create the typedef node
@@ -4073,7 +4155,7 @@ asCScriptNode *asCParser::ParseTypedef()
 	GetToken(&token);
 	if( token.type != ttTypedef)
 	{
-		Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)), &token);
+		Error(ExpectedToken(asCTokenizer::GetDefinition(ttTypedef)), &token);
 		Error(InsteadFound(token), &token);
 		return node;
 	}
@@ -4128,3 +4210,4 @@ void asCParser::ParseMethodOverrideBehaviors(asCScriptNode *funcNode)
 
 END_AS_NAMESPACE
 
+

+ 6 - 13
Source/ThirdParty/AngelScript/source/as_property.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2012 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -54,11 +54,14 @@ class asCObjectProperty
 {
 public:
 	asCObjectProperty() {accessMask = 0xFFFFFFFF;}
+	asCObjectProperty(const asCObjectProperty &o) : name(o.name), type(o.type), byteOffset(o.byteOffset), accessMask(o.accessMask), isPrivate(o.isPrivate), isProtected(o.isProtected), isInherited(o.isInherited) {}
 	asCString   name;
 	asCDataType type;
 	int         byteOffset;
-	bool		isPrivate;
 	asDWORD     accessMask;
+	bool        isPrivate;
+	bool        isProtected;
+	bool        isInherited;
 };
 
 class asCGlobalProperty
@@ -69,7 +72,7 @@ public:
 
 	void AddRef();
 	void Release();
-	int  GetRefCount();
+	void DestroyInternal();
 
 	void *GetAddressOfValue();
 	void  AllocateMemory();
@@ -84,16 +87,7 @@ public:
 	void SetInitFunc(asCScriptFunction *initFunc);
 	asCScriptFunction *GetInitFunc();
 
-	static void RegisterGCBehaviours(asCScriptEngine *engine);
-
 //protected:
-	void SetGCFlag();
-	bool GetGCFlag();
-	void EnumReferences(asIScriptEngine *);
-	void ReleaseAllHandles(asIScriptEngine *);
-
-	void Orphan(asCModule *module);
-
 	// This is only stored for registered properties, and keeps the pointer given by the application
 	void       *realAddress;
 
@@ -108,7 +102,6 @@ public:
 	// The global property structure is reference counted, so that the
 	// engine can keep track of how many references to the property there are.
 	asCAtomic refCount;
-	bool      gcFlag;
 };
 
 class asCCompGlobPropType : public asIFilter

+ 123 - 79
Source/ThirdParty/AngelScript/source/as_restore.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -119,7 +119,7 @@ int asCReader::Error(const char *msg)
 		error = true;
 	}
 
-	return -1;
+	return asERROR;
 }
 
 int asCReader::ReadInner() 
@@ -153,9 +153,9 @@ int asCReader::ReadInner()
 		bool sharedExists = false;
 		if( ot->IsShared() )
 		{
-			for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+			for( asUINT n = 0; n < engine->sharedScriptTypes.GetLength(); n++ )
 			{
-				asCObjectType *t = engine->classTypes[n];
+				asCObjectType *t = engine->sharedScriptTypes[n];
 				if( t && 
 					t->IsShared() &&
 					t->name == ot->name &&
@@ -171,11 +171,22 @@ int asCReader::ReadInner()
 		}
 
 		if( sharedExists )
+		{
 			existingShared.Insert(ot, true);
+			ot->AddRefInternal();
+		}
 		else
-			engine->classTypes.PushLast(ot);
+		{
+			if( ot->IsShared() )
+			{
+				engine->sharedScriptTypes.PushLast(ot);
+				ot->AddRefInternal();
+			}
+
+			// Set this module as the owner
+			ot->module = module;
+		}
 		module->enumTypes.PushLast(ot);
-		ot->AddRef();
 		ReadObjectTypeDeclaration(ot, 2);
 	}
 
@@ -200,9 +211,9 @@ int asCReader::ReadInner()
 		bool sharedExists = false;
 		if( ot->IsShared() )
 		{
-			for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+			for( asUINT n = 0; n < engine->sharedScriptTypes.GetLength(); n++ )
 			{
-				asCObjectType *t = engine->classTypes[n];
+				asCObjectType *t = engine->sharedScriptTypes[n];
 				if( t &&
 					t->IsShared() &&
 					t->name == ot->name &&
@@ -218,16 +229,22 @@ int asCReader::ReadInner()
 		}
 
 		if( sharedExists )
+		{
 			existingShared.Insert(ot, true);
+			ot->AddRefInternal();
+		}
 		else
 		{
-			engine->classTypes.PushLast(ot);
+			if( ot->IsShared() )
+			{
+				engine->sharedScriptTypes.PushLast(ot);
+				ot->AddRefInternal();
+			}
 
 			// Set this module as the owner
 			ot->module = module;
 		}
 		module->classTypes.PushLast(ot);
-		ot->AddRef();
 	}
 
 	if( error ) return asERROR;
@@ -258,16 +275,13 @@ int asCReader::ReadInner()
 				{
 					// Replace our funcdef for the existing one
 					module->funcDefs[module->funcDefs.IndexOf(func)] = f2;
-					f2->AddRef();
+					f2->AddRefInternal();
 
 					engine->funcDefs.RemoveValue(func);
 
 					savedFunctions[savedFunctions.IndexOf(func)] = f2;
 
-					func->Release();
-
-					// Funcdefs aren't deleted when the ref count reaches zero so we must manually delete it here
-					asDELETE(func,asCScriptFunction);
+					func->ReleaseInternal();
 					break;
 				}
 			}
@@ -312,9 +326,8 @@ int asCReader::ReadInner()
 		}
 
 		ReadObjectTypeDeclaration(ot, 1);
-		engine->classTypes.PushLast(ot);
+		ot->module = module;
 		module->typeDefs.PushLast(ot);
-		ot->AddRef();
 		ReadObjectTypeDeclaration(ot, 2);
 	}
 
@@ -361,9 +374,9 @@ int asCReader::ReadInner()
 				{
 					// Replace the recently created function with the pre-existing function
 					module->scriptFunctions[module->scriptFunctions.GetLength()-1] = realFunc;
-					realFunc->AddRef();
+					realFunc->AddRefInternal();
 					savedFunctions[savedFunctions.GetLength()-1] = realFunc;
-					engine->FreeScriptFunctionId(func->id);
+					engine->RemoveScriptFunction(func);
 
 					// Insert the function in the dontTranslate array
 					dontTranslate.Insert(realFunc, true);
@@ -371,7 +384,7 @@ int asCReader::ReadInner()
 					// Release the function, but make sure nothing else is released
 					func->id = 0;
 					func->scriptData->byteCode.SetLength(0);
-					func->Release();
+					func->ReleaseInternal();
 					break;
 				}
 			}
@@ -387,11 +400,10 @@ int asCReader::ReadInner()
 		if( func )
 		{
 			// All the global functions were already loaded while loading the scriptFunctions, here
-			// we're just re-reading the refernces to know which goes into the globalFunctions array
+			// we're just re-reading the references to know which goes into the globalFunctions array
 			asASSERT( !isNew );
 
 			module->globalFunctions.Put(func);
-			func->AddRef();
 		}
 		else
 			Error(TXT_INVALID_BYTECODE_d);
@@ -479,11 +491,11 @@ int asCReader::ReadInner()
 			asCScriptFunction *callback = engine->scriptFunctions[usedTypes[i]->beh.templateCallback];
 			if( !engine->CallGlobalFunctionRetBool(usedTypes[i], &dontGarbageCollect, callback->sysFuncIntf, callback) )
 			{
-				asCString sub = usedTypes[i]->templateSubTypes[0].Format();
+				asCString sub = usedTypes[i]->templateSubTypes[0].Format(usedTypes[i]->nameSpace);
 				for( asUINT n = 1; n < usedTypes[i]->templateSubTypes.GetLength(); n++ )
 				{
 					sub += ",";
-					sub += usedTypes[i]->templateSubTypes[n].Format();
+					sub += usedTypes[i]->templateSubTypes[n].Format(usedTypes[i]->nameSpace);
 				}
 				asCString str;
 				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), sub.AddressOf());
@@ -589,17 +601,35 @@ void asCReader::ReadUsedFunctions()
 			// Find the correct function
 			if( c == 'm' )
 			{
-				for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
+				if( func.funcType == asFUNC_IMPORTED )
 				{
-					asCScriptFunction *f = module->scriptFunctions[i];
-					if( !func.IsSignatureEqual(f) ||
-						func.objectType != f->objectType ||
-						func.funcType != f->funcType || 
-						func.nameSpace != f->nameSpace )
-						continue;
-
-					usedFunctions[n] = f;
-					break;
+					for( asUINT i = 0; i < module->bindInformations.GetLength(); i++ )
+					{
+						asCScriptFunction *f = module->bindInformations[i]->importedFunctionSignature;
+						if( !func.IsSignatureEqual(f) ||
+							func.objectType != f->objectType ||
+							func.funcType != f->funcType || 
+							func.nameSpace != f->nameSpace )
+							continue;
+
+						usedFunctions[n] = f;
+						break;
+					}
+				}
+				else
+				{
+					for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
+					{
+						asCScriptFunction *f = module->scriptFunctions[i];
+						if( !func.IsSignatureEqual(f) ||
+							func.objectType != f->objectType ||
+							func.funcType != f->funcType || 
+							func.nameSpace != f->nameSpace )
+							continue;
+
+						usedFunctions[n] = f;
+						break;
+					}
 				}
 			}
 			else
@@ -725,10 +755,13 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
 	func->objectType = ReadObjectType();
 	if( func->objectType )
 	{
+		func->objectType->AddRefInternal();
+
 		asBYTE b;
 		ReadData(&b, 1);
 		func->isReadOnly = (b & 1) ? true : false;
 		func->isPrivate  = (b & 2) ? true : false;
+		func->isProtected = (b & 4) ? true : false;
 		func->nameSpace = engine->nameSpaces[0];
 	}
 	else
@@ -950,7 +983,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
 	if( addToEngine )
 	{
 		func->id = engine->GetNextScriptFunctionId();
-		engine->SetScriptFunction(func);
+		engine->AddScriptFunction(func);
 	}
 	if( func->objectType )
 		func->ComputeSignatureId();
@@ -980,18 +1013,16 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 		ot->beh.factory = 0;
 		ot->beh.constructors.PopLast(); // These will be read from the file
 		ot->beh.factories.PopLast(); // These will be read from the file
-		engine->scriptFunctions[ot->beh.addref]->AddRef();
-		engine->scriptFunctions[ot->beh.release]->AddRef();
-		engine->scriptFunctions[ot->beh.gcEnumReferences]->AddRef();
-		engine->scriptFunctions[ot->beh.gcGetFlag]->AddRef();
-		engine->scriptFunctions[ot->beh.gcGetRefCount]->AddRef();
-		engine->scriptFunctions[ot->beh.gcReleaseAllReferences]->AddRef();
-		engine->scriptFunctions[ot->beh.gcSetFlag]->AddRef();
-		engine->scriptFunctions[ot->beh.copy]->AddRef();
+		engine->scriptFunctions[ot->beh.addref]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.release]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.gcEnumReferences]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.gcGetFlag]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.gcGetRefCount]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.gcReleaseAllReferences]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.gcSetFlag]->AddRefInternal();
+		engine->scriptFunctions[ot->beh.copy]->AddRefInternal();
 		// TODO: weak: Should not do this if the class has been declared with 'noweak'
-		engine->scriptFunctions[ot->beh.getWeakRefFlag]->AddRef();
-		for( asUINT i = 1; i < ot->beh.operators.GetLength(); i += 2 )
-			engine->scriptFunctions[ot->beh.operators[i]]->AddRef();
+		engine->scriptFunctions[ot->beh.getWeakRefFlag]->AddRefInternal();
 	}
 	else if( phase == 2 )
 	{
@@ -1070,7 +1101,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			{
 				ot->derivedFrom = ReadObjectType();
 				if( ot->derivedFrom )
-					ot->derivedFrom->AddRef();
+					ot->derivedFrom->AddRefInternal();
 			}
 
 			// interfaces[] / interfaceVFTOffsets[]
@@ -1134,10 +1165,10 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							// Destroy the function without releasing any references
 							func->id = 0;
 							func->scriptData->byteCode.SetLength(0);
-							func->Release();
+							func->ReleaseInternal();
 						}
 						module->scriptFunctions.PushLast(realFunc);
-						realFunc->AddRef();
+						realFunc->AddRefInternal();
 						dontTranslate.Insert(realFunc, true);
 					}
 				}
@@ -1146,7 +1177,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 					if( func )
 					{
 						ot->beh.destruct = func->id;
-						func->AddRef();
+						func->AddRefInternal();
 					}
 					else
 						ot->beh.destruct = 0;
@@ -1173,7 +1204,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									found = true;
 									module->scriptFunctions.PushLast(realFunc);
-									realFunc->AddRef();
+									realFunc->AddRefInternal();
 									dontTranslate.Insert(realFunc, true);
 									break;
 								}
@@ -1190,13 +1221,13 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 								// Destroy the function without releasing any references
 								func->id = 0;
 								func->scriptData->byteCode.SetLength(0);
-								func->Release();
+								func->ReleaseInternal();
 							}
 						}
 						else
 						{
 							ot->beh.constructors.PushLast(func->id);
-							func->AddRef();
+							func->AddRefInternal();
 
 							if( func->parameterTypes.GetLength() == 0 )
 								ot->beh.construct = func->id;
@@ -1224,7 +1255,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 									found = true;
 									module->scriptFunctions.PushLast(realFunc);
-									realFunc->AddRef();
+									realFunc->AddRefInternal();
 									dontTranslate.Insert(realFunc, true);
 									break;
 								}
@@ -1241,13 +1272,13 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 								// Destroy the function without releasing any references
 								func->id = 0;
 								func->scriptData->byteCode.SetLength(0);
-								func->Release();
+								func->ReleaseInternal();
 							}
 						}
 						else
 						{
 							ot->beh.factories.PushLast(func->id);
-							func->AddRef();
+							func->AddRefInternal();
 
 							if( func->parameterTypes.GetLength() == 0 )
 								ot->beh.factory = func->id;
@@ -1283,7 +1314,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 								found = true;
 								module->scriptFunctions.PushLast(realFunc);
-								realFunc->AddRef();
+								realFunc->AddRefInternal();
 								dontTranslate.Insert(realFunc, true);
 								break;
 							}
@@ -1301,7 +1332,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							func->id = 0;
 							if( func->scriptData )
 								func->scriptData->byteCode.SetLength(0);
-							func->Release();
+							func->ReleaseInternal();
 						}
 					}
 					else
@@ -1311,13 +1342,13 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							func->parameterTypes[0].GetObjectType() == func->objectType &&
 							(func->inOutFlags[0] & asTM_INREF) )
 						{
-							engine->scriptFunctions[ot->beh.copy]->Release();
+							engine->scriptFunctions[ot->beh.copy]->ReleaseInternal();
 							ot->beh.copy = func->id;
-							func->AddRef();
+							func->AddRefInternal();
 						}
 						
 						ot->methods.PushLast(func->id);
-						func->AddRef();
+						func->AddRefInternal();
 					}
 				}
 				else
@@ -1348,7 +1379,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
 								found = true;
 								module->scriptFunctions.PushLast(realFunc);
-								realFunc->AddRef();
+								realFunc->AddRefInternal();
 								dontTranslate.Insert(realFunc, true);
 								break;
 							}
@@ -1366,13 +1397,13 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 							func->id = 0;
 							if( func->scriptData )
 								func->scriptData->byteCode.SetLength(0);
-							func->Release();
+							func->ReleaseInternal();
 						}
 					}
 					else
 					{
 						ot->virtualFunctionTable.PushLast(func);
-						func->AddRef();
+						func->AddRefInternal();
 					}
 				}
 				else
@@ -1539,7 +1570,7 @@ void asCReader::ReadGlobalProperty()
 		func->module = module;
 
 		prop->SetInitFunc(func);
-		func->Release();
+		func->ReleaseInternal();
 	}
 }
 
@@ -1549,13 +1580,15 @@ void asCReader::ReadObjectProperty(asCObjectType *ot)
 	ReadString(&name);
 	asCDataType dt;
 	ReadDataType(&dt);
-	bool isPrivate;
-	ReadData(&isPrivate, 1);
+	int flags = ReadEncodedUInt();
+	bool isPrivate = (flags & 1) ? true : false;
+	bool isProtected = (flags & 2) ? true : false;
+	bool isInherited = (flags & 4) ? true : false;
 
 	// TODO: shared: If the type is shared and pre-existing, we should just 
 	//               validate that the loaded methods match the original 
 	if( !existingShared.MoveTo(0, ot) )
-		ot->AddPropertyToClass(name, dt, isPrivate);
+		ot->AddPropertyToClass(name, dt, isPrivate, isProtected, isInherited);
 }
 
 void asCReader::ReadDataType(asCDataType *dt) 
@@ -1573,7 +1606,7 @@ void asCReader::ReadDataType(asCDataType *dt)
 	eTokenType tokenType = (eTokenType)ReadEncodedUInt();
 
 	// Reserve a spot in the savedDataTypes
-	size_t saveSlot = savedDataTypes.GetLength();
+	asUINT saveSlot = savedDataTypes.GetLength();
 	savedDataTypes.PushLast(asCDataType());
 
 	// Read the datatype for the first time
@@ -1694,17 +1727,17 @@ asCObjectType* asCReader::ReadObjectType()
 		else
 		{
 			// Get the template instance type based on the loaded subtypes
-			ot = engine->GetTemplateInstanceType(tmpl, subTypes);
+			ot = engine->GetTemplateInstanceType(tmpl, subTypes, module);
 		}
 
 		if( ot == 0 )
 		{
 			// Show all subtypes in error message
-			asCString sub = subTypes[0].Format();
+			asCString sub = subTypes[0].Format(nameSpace);
 			for( asUINT n = 1; n < subTypes.GetLength(); n++ )
 			{
 				sub += ",";
-				sub += subTypes[n].Format();
+				sub += subTypes[n].Format(nameSpace);
 			}
 			asCString str;
 			str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), sub.AddressOf());
@@ -2260,7 +2293,8 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
 		}
 		else if( c == asBC_CALL ||
 				 c == asBC_CALLINTF ||
-				 c == asBC_CALLSYS )
+				 c == asBC_CALLSYS ||
+				 c == asBC_Thiscall1 )
 		{
 			// Translate the index to the func id
 			int *fid = (int*)&bc[n+1];
@@ -2767,7 +2801,8 @@ void asCReader::CalculateStackNeeded(asCScriptFunction *func)
 		{
 			// Determine the true delta from the instruction arguments
 			if( bc == asBC_CALL ||
-			    bc == asBC_CALLSYS ||
+				bc == asBC_CALLSYS ||
+				bc == asBC_Thiscall1 ||
 				bc == asBC_CALLBND ||
 				bc == asBC_ALLOC ||
 				bc == asBC_CALLINTF ||
@@ -2997,6 +3032,7 @@ asCScriptFunction *asCReader::GetCalledFunction(asCScriptFunction *func, asDWORD
 
 	if( bc == asBC_CALL ||
 		bc == asBC_CALLSYS ||
+		bc == asBC_Thiscall1 ||
 		bc == asBC_CALLINTF )
 	{
 		// Find the function from the function id in bytecode
@@ -3057,6 +3093,7 @@ int asCReader::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 		asBYTE bc = *(asBYTE*)&func->scriptData->byteCode[n];
 		if( bc == asBC_CALL ||
 			bc == asBC_CALLSYS ||
+			bc == asBC_Thiscall1 ||
 			bc == asBC_CALLINTF || 
 			bc == asBC_ALLOC ||
 			bc == asBC_CALLBND ||
@@ -3384,6 +3421,7 @@ void asCWriter::WriteFunctionSignature(asCScriptFunction *func)
 		asBYTE b = 0;
 		b += func->isReadOnly ? 1 : 0;
 		b += func->isPrivate  ? 2 : 0;
+		b += func->isProtected ? 4 : 0;
 		WriteData(&b, 1);
 	}
 	else
@@ -3772,7 +3810,11 @@ void asCWriter::WriteObjectProperty(asCObjectProperty* prop)
 {
 	WriteString(&prop->name);
 	WriteDataType(&prop->type);
-	WriteData(&prop->isPrivate, 1);
+	int flags = 0;
+	if( prop->isPrivate ) flags |= 1;
+	if( prop->isProtected ) flags |= 2;
+	if( prop->isInherited ) flags |= 4;
+	WriteEncodedInt64(flags);
 }
 
 void asCWriter::WriteDataType(const asCDataType *dt) 
@@ -3970,7 +4012,7 @@ void asCWriter::CalculateAdjustmentByPos(asCScriptFunction *func)
 	}
 
 	// Compute the sequence number of each bytecode instruction in order to update the jump offsets
-	size_t length = func->scriptData->byteCode.GetLength();
+	asUINT length = func->scriptData->byteCode.GetLength();
 	asDWORD *bc = func->scriptData->byteCode.AddressOf();
 	bytecodeNbrByPos.SetLength(length);
 	asUINT num;
@@ -4020,6 +4062,7 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
 		asBYTE bc = *(asBYTE*)&func->scriptData->byteCode[n];
 		if( bc == asBC_CALL ||
 			bc == asBC_CALLSYS ||
+			bc == asBC_Thiscall1 ||
 			bc == asBC_CALLINTF )
 		{
 			// Find the function from the function id in bytecode
@@ -4224,7 +4267,8 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
 		}
 		else if( c == asBC_CALL ||     // DW_ARG
 				 c == asBC_CALLINTF || // DW_ARG
-				 c == asBC_CALLSYS )   // DW_ARG
+				 c == asBC_CALLSYS ||  // DW_ARG
+				 c == asBC_Thiscall1 ) // DW_ARG
 		{
 			// Translate the function id
 			*(int*)(tmp+1) = FindFunctionIndex(engine->scriptFunctions[*(int*)(tmp+1)]);
@@ -4279,9 +4323,9 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
 			int offset = *(int*)(tmp+1);
 
 			// Determine instruction number for next instruction and destination
-			int bcSeqNum = bytecodeNbrByPos[bc - startBC] + 1;
+			int bcSeqNum = bytecodeNbrByPos[asUINT(bc - startBC)] + 1;
 			asDWORD *targetBC = bc + 2 + offset;
-			int targetBcSeqNum = bytecodeNbrByPos[targetBC - startBC];
+			int targetBcSeqNum = bytecodeNbrByPos[asUINT(targetBC - startBC)];
 
 			// Set the offset in number of instructions
 			*(int*)(tmp+1) = targetBcSeqNum - bcSeqNum;

文件差异内容过多而无法显示
+ 314 - 338
Source/ThirdParty/AngelScript/source/as_scriptengine.cpp


+ 74 - 42
Source/ThirdParty/AngelScript/source/as_scriptengine.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -70,6 +70,7 @@ public:
 	// Memory management
 	virtual int AddRef() const;
 	virtual int Release() const;
+	virtual int ShutDownAndRelease();
 
 	// Engine properties
 	virtual int     SetEngineProperty(asEEngineProp property, asPWORD value);
@@ -166,14 +167,14 @@ public:
 	virtual void                  *CreateScriptObjectCopy(void *obj, const asIObjectType *type);
 	virtual void                  *CreateUninitializedScriptObject(const asIObjectType *type);
 	virtual asIScriptFunction     *CreateDelegate(asIScriptFunction *func, void *obj);
-	virtual void                   AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type);
+	virtual int                    AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type);
 	virtual void                   ReleaseScriptObject(void *obj, const asIObjectType *type);
 	virtual void                   AddRefScriptObject(void *obj, const asIObjectType *type);
-	// TODO: interface: Should have a method void *CastObject(void *obj, asIObjectType *fromType, asIObjectType *toType); 
-	//                  For script objects it should simply check if the object implements or derives from the toType
-	//                  For application objects it should look for ref cast behaviours and call the matching one
-	//                  Once implemented the IsHandleCompatibleWithObject should be removed from the engine
+	virtual int                    RefCastObject(void *obj, asIObjectType *fromType, asIObjectType *toType, void **newPtr, bool useOnlyImplicitCast = false);
+#ifdef AS_DEPRECATED
+	// Deprecated since 2.30.0, 2014-11-04
 	virtual bool                   IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
+#endif
 	virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const;
 
 	// Context pooling
@@ -182,7 +183,7 @@ public:
 	virtual int               SetContextCallbacks(asREQUESTCONTEXTFUNC_t requestCtx, asRETURNCONTEXTFUNC_t returnCtx, void *param = 0);
 
 	// String interpretation
-	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, int *tokenLength = 0) const;
+	virtual asETokenClass ParseToken(const char *string, size_t stringLength = 0, asUINT *tokenLength = 0) const;
 
 	// Garbage collection
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1);
@@ -199,6 +200,7 @@ public:
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type);
 	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type);
+	virtual void  SetScriptObjectUserDataCleanupCallback(asCLEANSCRIPTOBJECTFUNC_t callback, asPWORD type);
 
 //===========================================================
 // internal methods
@@ -236,16 +238,16 @@ public:
 	bool  CallObjectMethodRetBool(void *obj, int func) const;
 	int   CallObjectMethodRetInt(void *obj, int func) const;
 	void *CallObjectMethodRetPtr(void *obj, int func) const;
+	void *CallObjectMethodRetPtr(void *obj, int param1, asCScriptFunction *func) const;
 	void  CallGlobalFunction(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc) const;
 	bool  CallGlobalFunctionRetBool(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc) const;
 
 	void ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type);
 
-	void CleanupAfterDiscardModule();
+	void DeleteDiscardedModules();
 
-	int  ClearUnusedTypes();
 	void RemoveTemplateInstanceType(asCObjectType *t);
-	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
+	void RemoveTypeAndRelatedFromList(asCMap<asCObjectType*,char> &types, asCObjectType *ot);
 
 	asCConfigGroup *FindConfigGroupForFunction(int funcId) const;
 	asCConfigGroup *FindConfigGroupForGlobalVar(int gvarId) const;
@@ -279,8 +281,9 @@ public:
 	int  GetFactoryIdByDecl(const asCObjectType *ot, const char *decl);
 
 	int  GetNextScriptFunctionId();
-	void SetScriptFunction(asCScriptFunction *func);
-	void FreeScriptFunctionId(int id);
+	void AddScriptFunction(asCScriptFunction *func);
+	void RemoveScriptFunction(asCScriptFunction *func);
+	void RemoveFuncdef(asCScriptFunction *func);
 
 	int ConfigError(int err, const char *funcName, const char *arg1, const char *arg2);
 
@@ -290,11 +293,14 @@ public:
 	void               RemoveFromTypeIdMap(asCObjectType *type);
 
 	bool               IsTemplateType(const char *name) const;
-	asCObjectType     *GetTemplateInstanceType(asCObjectType *templateType, asCArray<asCDataType> &subTypes);
+	asCObjectType     *GetTemplateInstanceType(asCObjectType *templateType, asCArray<asCDataType> &subTypes, asCModule *requestingModule);
 	asCScriptFunction *GenerateTemplateFactoryStub(asCObjectType *templateType, asCObjectType *templateInstanceType, int origFactoryId);
 	bool               GenerateNewTemplateFunction(asCObjectType *templateType, asCObjectType *templateInstanceType, asCScriptFunction *templateFunc, asCScriptFunction **newFunc);
-	void               OrphanTemplateInstances(asCObjectType *subType);
 	asCDataType        DetermineTypeForTemplate(const asCDataType &orig, asCObjectType *tmpl, asCObjectType *ot);
+	bool               RequireTypeReplacement(asCDataType &type, asCObjectType *templateType);
+
+	asCModule         *FindNewOwnerForSharedType(asCObjectType *type, asCModule *mod);
+	asCModule         *FindNewOwnerForSharedFunc(asCScriptFunction *func, asCModule *mod);
 
 	// String constants
 	// TODO: Must free unused string constants, thus the ref count for each must be tracked
@@ -303,13 +309,14 @@ public:
 
 	// Global property management
 	asCGlobalProperty *AllocateGlobalProperty();
-	void FreeUnusedGlobalProperties();
+	void RemoveGlobalProperty(asCGlobalProperty *prop);
 
 	int GetScriptSectionNameIndex(const char *name);
 
 	// Namespace management
 	asSNameSpace *AddNameSpace(const char *name);
-	asSNameSpace *FindNameSpace(const char *name);
+	asSNameSpace *FindNameSpace(const char *name) const;
+	asSNameSpace *GetParentNameSpace(asSNameSpace *ns) const;
 
 //===========================================================
 // internal properties
@@ -321,14 +328,12 @@ public:
 	asCObjectType   *defaultArrayObjectType;
 	asCObjectType    scriptTypeBehaviours;
 	asCObjectType    functionBehaviours;
-	asCObjectType    objectTypeBehaviours;
-	asCObjectType    globalPropertyBehaviours;
 
 	// Registered interface
 	asCArray<asCObjectType *>         registeredObjTypes;
 	asCArray<asCObjectType *>         registeredTypeDefs;
 	asCArray<asCObjectType *>         registeredEnums;
-	asCSymbolTable<asCGlobalProperty> registeredGlobalProps; // TODO: memory savings: Since there can be only one property with the same name a simpler symbol table should be used
+	asCSymbolTable<asCGlobalProperty> registeredGlobalProps; // increases ref count // TODO: memory savings: Since there can be only one property with the same name a simpler symbol table should be used
 	asCSymbolTable<asCScriptFunction> registeredGlobalFuncs;
 	asCArray<asCScriptFunction *>     registeredFuncDefs;
 	asCArray<asCObjectType *>         registeredTemplateTypes;
@@ -336,7 +341,7 @@ public:
 	bool configFailed;
 
 	// Stores all registered types except funcdefs
-	asCMap<asSNameSpaceNamePair, asCObjectType*> allRegisteredTypes;  
+	asCMap<asSNameSpaceNamePair, asCObjectType*> allRegisteredTypes; // increases ref count
 
 	// Dummy types used to name the subtypes in the template objects 
 	asCArray<asCObjectType *>      templateSubTypes;
@@ -344,46 +349,61 @@ public:
 	// Store information about template types
 	// This list will contain all instances of templates, both registered specialized 
 	// types and those automacially instantiated from scripts
-	asCArray<asCObjectType *>      templateInstanceTypes;
+	asCArray<asCObjectType *>      templateInstanceTypes; // increases ref count
 
 	// Store information about list patterns
-	asCArray<asCObjectType *>      listPatternTypes;
+	asCArray<asCObjectType *>      listPatternTypes; // increases ref count
 
 	// Stores all global properties, both those registered by application, and those declared by scripts.
 	// The id of a global property is the index in this array.
-	asCArray<asCGlobalProperty *> globalProperties;
+	asCArray<asCGlobalProperty *> globalProperties; // increases ref count
+	asCArray<int>                 freeGlobalPropertyIds;
 
 	// This map is used to quickly find a property by its memory address
 	// It is used principally during building, cleanup, and garbage detection for script functions
-	asCMap<void*, asCGlobalProperty*> varAddressMap;
-
-	asCArray<int>                 freeGlobalPropertyIds;
+	asCMap<void*, asCGlobalProperty*> varAddressMap; // doesn't increase ref count
 
 	// Stores all functions, i.e. registered functions, script functions, class methods, behaviours, etc.
-	asCArray<asCScriptFunction *> scriptFunctions;
+	asCArray<asCScriptFunction *> scriptFunctions;       // doesn't increase ref count
 	asCArray<int>                 freeScriptFunctionIds;
 	asCArray<asCScriptFunction *> signatureIds;
 
 	// An array with all module imported functions
-	asCArray<sBindInfo *>  importedFunctions;
+	asCArray<sBindInfo *>  importedFunctions; // doesn't increase ref count
 	asCArray<int>          freeImportedFunctionIdxs;
 
-	// These resources must be protected for multiple accesses
+	// Synchronized
 	mutable asCAtomic      refCount;
+	// Synchronized with engineRWLock
+	// This array holds all live script modules
 	asCArray<asCModule *>  scriptModules;
+	// Synchronized with engineRWLock
+	// This is a pointer to the last module that was requested. It is used for performance 
+	// improvement, since it is common that the same module is accessed many times in a row
 	asCModule             *lastModule;
+	// Synchronized with engineRWLock
+	// This flag is true if a script is currently being compiled. It is used to prevent multiple
+	// threads from requesting builds at the same time (without blocking)
 	bool                   isBuilding;
+	// Synchronized with engineRWLock
+	// This array holds modules that have been discard (thus are no longer visible to the application)
+	// but cannot yet be deleted due to having external references to some of the entities in them
+	asCArray<asCModule *>  discardedModules;
+	// This flag is set to true during compilations of scripts (or loading pre-compiled scripts) 
+	// to delay the validation of template types until the subtypes have been fully declared 
 	bool                   deferValidationOfTemplateTypes;
 
 	// Tokenizer is instantiated once to share resources
 	asCTokenizer tok;
 
-	// Stores script declared object types
-	asCArray<asCObjectType *> classTypes;
+	// Stores shared script declared types (classes, interfaces, enums)
+	asCArray<asCObjectType *> sharedScriptTypes; // increases ref count
 	// This array stores the template instances types that have been automatically generated from template types
 	asCArray<asCObjectType *> generatedTemplateTypes;
 	// Stores the funcdefs
-	asCArray<asCScriptFunction *> funcDefs;
+	// TODO: 2.30.0: redesign: Only shared funcdefs should be stored here
+	//                         a funcdef becomes shared if all arguments and the return type are shared (or application registered)
+	asCArray<asCScriptFunction *> funcDefs; // doesn't increase ref count
 
 	// Stores the names of the script sections for debugging purposes
 	asCArray<asCString *> scriptSectionNames;
@@ -438,16 +458,18 @@ public:
 	// User data
 	asCArray<asPWORD>       userData;
 
-	struct SEngineClean   { asPWORD type; asCLEANENGINEFUNC_t     cleanFunc; };
-	asCArray<SEngineClean>   cleanEngineFuncs;
-	struct SModuleClean   { asPWORD type; asCLEANMODULEFUNC_t     cleanFunc; };
-	asCArray<SModuleClean>   cleanModuleFuncs;
-	struct SContextClean  { asPWORD type; asCLEANCONTEXTFUNC_t    cleanFunc; };
-	asCArray<SContextClean>  cleanContextFuncs;
-	struct SFunctionClean { asPWORD type; asCLEANFUNCTIONFUNC_t   cleanFunc; };
-	asCArray<SFunctionClean> cleanFunctionFuncs;
-	struct SObjTypeClean  { asPWORD type; asCLEANOBJECTTYPEFUNC_t cleanFunc; };
-	asCArray<SObjTypeClean>  cleanObjectTypeFuncs;
+	struct SEngineClean    { asPWORD type; asCLEANENGINEFUNC_t      cleanFunc; };
+	asCArray<SEngineClean>    cleanEngineFuncs;
+	struct SModuleClean    { asPWORD type; asCLEANMODULEFUNC_t      cleanFunc; };
+	asCArray<SModuleClean>    cleanModuleFuncs;
+	struct SContextClean   { asPWORD type; asCLEANCONTEXTFUNC_t     cleanFunc; };
+	asCArray<SContextClean>   cleanContextFuncs;
+	struct SFunctionClean  { asPWORD type; asCLEANFUNCTIONFUNC_t    cleanFunc; };
+	asCArray<SFunctionClean>  cleanFunctionFuncs;
+	struct SObjTypeClean   { asPWORD type; asCLEANOBJECTTYPEFUNC_t  cleanFunc; };
+	asCArray<SObjTypeClean>   cleanObjectTypeFuncs;
+	struct SScriptObjClean { asPWORD type; asCLEANSCRIPTOBJECTFUNC_t cleanFunc; };
+	asCArray<SScriptObjClean> cleanScriptObjectFuncs;
 
 	// Synchronization for threads
 	DECLAREREADWRITELOCK(mutable engineRWLock)
@@ -475,11 +497,21 @@ public:
 		bool   alwaysImplDefaultConstruct;
 		int    compilerWarnings;
 		bool   disallowValueAssignForRefType;
+		// TODO: 3.0.0: Remove the alterSyntaxNamedArgs
 		int    alterSyntaxNamedArgs;
+		bool   disableIntegerDivision;
+		bool   disallowEmptyListElements;
+		// TODO: 3.0.0: Remove the privatePropAsProtected
+		bool   privatePropAsProtected;
 	} ep;
 
 	// This flag is to allow a quicker shutdown when releasing the engine
 	bool shuttingDown;
+
+	// This flag is set when the engine's destructor is called, this is to 
+	// avoid recursive calls if an object happens to increment/decrement
+	// the ref counter during shutdown
+	bool inDestructor;
 };
 
 END_AS_NAMESPACE

+ 156 - 243
Source/ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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
@@ -332,15 +332,27 @@ int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char
 // internal
 asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType _funcType)
 {
-	refCount.set(1);
+	funcType               = _funcType;
+	if( funcType == asFUNC_DELEGATE )
+	{
+		// Delegates behave like object instances, rather than script code
+		externalRefCount.set(1);
+		internalRefCount.set(0);
+	}
+	else
+	{
+		internalRefCount.set(1);
+		externalRefCount.set(0);
+	}
+
 	this->engine           = engine;
 	this->scriptData       = 0;
-	funcType               = _funcType;
 	module                 = mod;
 	objectType             = 0;
 	name                   = "";
 	isReadOnly             = false;
 	isPrivate              = false;
+	isProtected            = false;
 	isFinal                = false;
 	isOverride             = false;
 	sysFuncIntf            = 0;
@@ -360,8 +372,8 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
 	if( funcType == asFUNC_SCRIPT )
 		AllocateScriptFunctionData();
 
-	// Notify the GC of script functions
-	if( (funcType == asFUNC_SCRIPT && mod == 0) || (funcType == asFUNC_DELEGATE) )
+	// Notify the GC of delegates
+	if( funcType == asFUNC_DELEGATE )
 		engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
 }
 
@@ -393,24 +405,23 @@ void asCScriptFunction::DeallocateScriptFunctionData()
 // internal
 asCScriptFunction::~asCScriptFunction()
 {
-	// Imported functions are not reference counted, nor are dummy
-	// functions that are allocated on the stack
+	// Dummy functions that are allocated on the stack are not reference counted
 	asASSERT( funcType == asFUNC_DUMMY    ||
-		      funcType == asFUNC_IMPORTED ||
-		      refCount.get() == 0         );
+		      (externalRefCount.get() == 0 && internalRefCount.get() == 0) );
+
+	// Remove the script function from the engine's scriptFunctions array here
+	// Don't remove it before, because there may still be functions referring to it
+	// by index until now. If it was removed in DestroyInternal, those would not
+	// be able to release the refcount, thus causing memory leak.
+	if( engine && id != 0 && funcType != asFUNC_DUMMY )
+		engine->RemoveScriptFunction(this);
 
 	// If the engine pointer is 0, then DestroyInternal has already been called and there is nothing more to do
 	if( engine == 0 ) return;
 
+	// TODO: 2.30.0: redesign: Shouldn't this have been done already?
 	DestroyInternal();
 
-	// Tell engine to free the function id. This will make it impossible to
-	// refer to the function by id. Where this is done, it is quite possible
-	// they will leak.
-	if( funcType != -1 && funcType != asFUNC_IMPORTED && id )
-		engine->FreeScriptFunctionId(id);
-	id = 0;
-
 	// Finally set the engine pointer to 0 because it must not be accessed again
 	engine = 0;
 }
@@ -418,7 +429,7 @@ asCScriptFunction::~asCScriptFunction()
 // internal
 void asCScriptFunction::DestroyHalfCreated()
 {
-	asASSERT( refCount.get() == 1 );
+	asASSERT( externalRefCount.get() == 0 && internalRefCount.get() == 1 );
 
 	// Set the funcType to dummy so the destructor won't complain
 	funcType = asFUNC_DUMMY;
@@ -429,7 +440,7 @@ void asCScriptFunction::DestroyHalfCreated()
 	if( scriptData )
 		scriptData->byteCode.SetLength(0);
 
-	delete this;
+	asDELETE(this, asCScriptFunction);
 }
 
 // internal
@@ -461,6 +472,12 @@ void asCScriptFunction::DestroyInternal()
 		asDELETE(sysFuncIntf,asSSystemFunctionInterface);
 	sysFuncIntf = 0;
 
+	if( objectType )
+	{
+		objectType->ReleaseInternal();
+		objectType = 0;
+	}
+
 	DeallocateScriptFunctionData();
 
 	// Deallocate list pattern data
@@ -482,38 +499,54 @@ int asCScriptFunction::GetId() const
 int asCScriptFunction::AddRef() const
 {
 	gcFlag = false;
-	asASSERT( funcType != asFUNC_IMPORTED );
-	return refCount.atomicInc();
+	return externalRefCount.atomicInc();
 }
 
 // interface
 int asCScriptFunction::Release() const
 {
 	gcFlag = false;
-	asASSERT( funcType != asFUNC_IMPORTED );
-	int r = refCount.atomicDec();
+	int r = externalRefCount.atomicDec();
 	if( r == 0 &&
-		funcType != asFUNC_FUNCDEF && // Funcdefs are treated as object types and will be deleted by ClearUnusedTypes()
 		funcType != asFUNC_DUMMY )    // Dummy functions are allocated on the stack and cannot be deleted
-		asDELETE(const_cast<asCScriptFunction*>(this),asCScriptFunction);
+	{
+		// There are no more external references, if there are also no
+		// internal references then it is time to delete the function
+		if( internalRefCount.get() == 0 )
+		{
+			// If there are no internal references, then no module is owning the function
+			// For example if the function was dynamically compiled without adding it to the scope of the module
+			asASSERT( module == 0 );
+
+			asDELETE(const_cast<asCScriptFunction*>(this),asCScriptFunction);
+		}
+	}
 
 	return r;
 }
 
 // internal
-void asCScriptFunction::Orphan(asIScriptModule *mod)
+int asCScriptFunction::AddRefInternal()
+{
+	return internalRefCount.atomicInc();
+}
+
+// internal
+int asCScriptFunction::ReleaseInternal()
 {
-	if( mod && module == mod )
+	int r = internalRefCount.atomicDec();
+	if( r == 0 &&
+		funcType != asFUNC_DUMMY )
 	{
-		module = 0;
-		if( funcType == asFUNC_SCRIPT && refCount.get() > 1 )
+		// There are no more internal references, if there are also no
+		// external references then it is time to delete the function
+		if( externalRefCount.get() == 0 )
 		{
-			// This function is being orphaned, so notify the GC so it can check for circular references
-			engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
+			asDELETE(const_cast<asCScriptFunction*>(this),asCScriptFunction);
 		}
 	}
 
-	Release();
+	return r;
 }
 
 // interface
@@ -600,6 +633,12 @@ bool asCScriptFunction::IsPrivate() const
 	return isPrivate;
 }
 
+// interface
+bool asCScriptFunction::IsProtected() const
+{
+	return isProtected;
+}
+
 // internal
 int asCScriptFunction::GetSpaceNeededForArguments()
 {
@@ -641,12 +680,12 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 		  (name == objectType->name || (name.GetLength() > 0 && name[0] == '~') ||
 		   name == "_beh_0_" || name == "_beh_2_")) )
 	{
-		str = returnType.Format();
+		str = returnType.Format(nameSpace, includeNamespace);
 		str += " ";
 	}
 	if( objectType && includeObjectName )
 	{
-		if( includeNamespace )
+		if( includeNamespace && objectType->nameSpace->name != "" )
 			str += objectType->nameSpace->name + "::";
 
 		if( objectType->name != "" )
@@ -654,7 +693,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 		else
 			str += "_unnamed_type_::";
 	}
-	else if( includeNamespace )
+	else if( includeNamespace && nameSpace->name != "" )
 	{
 		str += nameSpace->name + "::";
 	}
@@ -679,7 +718,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 		asUINT n;
 		for( n = 0; n < parameterTypes.GetLength() - 1; n++ )
 		{
-			str += parameterTypes[n].Format();
+			str += parameterTypes[n].Format(nameSpace, includeNamespace);
 			if( parameterTypes[n].IsReference() && inOutFlags.GetLength() > n )
 			{
 				if( inOutFlags[n] == asTM_INREF ) str += "in";
@@ -704,7 +743,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 		}
 
 		// Add the last parameter
-		str += parameterTypes[n].Format();
+		str += parameterTypes[n].Format(nameSpace, includeNamespace);
 		if( parameterTypes[n].IsReference() && inOutFlags.GetLength() > n )
 		{
 			if( inOutFlags[n] == asTM_INREF ) str += "in";
@@ -761,7 +800,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
 				}
 				else
 					str += ", ";
-				str += reinterpret_cast<asSListPatternDataTypeNode*>(n)->dataType.Format();
+				str += reinterpret_cast<asSListPatternDataTypeNode*>(n)->dataType.Format(nameSpace, includeNamespace);
 			}
 
 			n = n->next;
@@ -907,7 +946,7 @@ const char *asCScriptFunction::GetVarDecl(asUINT index, bool includeNamespace) c
 		return 0;
 
 	asCString *tempString = &asCThreadManager::GetLocalData()->string;
-	*tempString = scriptData->variables[index]->type.Format(includeNamespace);
+	*tempString = scriptData->variables[index]->type.Format(nameSpace, includeNamespace);
 	*tempString += " " + scriptData->variables[index]->name;
 
 	return tempString->AddressOf();
@@ -1024,16 +1063,31 @@ void asCScriptFunction::AddReferences()
 	// Only count references if there is any bytecode
 	if( scriptData && scriptData->byteCode.GetLength() )
 	{
-		if( returnType.IsObject() )
-			returnType.GetObjectType()->AddRef();
+		if( returnType.GetObjectType() )
+		{
+			returnType.GetObjectType()->AddRefInternal();
+
+			asCConfigGroup *group = engine->FindConfigGroupForObjectType(returnType.GetObjectType());
+			if( group != 0 ) group->AddRef();
+		}
 
 		for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
-			if( parameterTypes[p].IsObject() )
-				parameterTypes[p].GetObjectType()->AddRef();
+			if( parameterTypes[p].GetObjectType() )
+			{
+				parameterTypes[p].GetObjectType()->AddRefInternal();
+
+				asCConfigGroup *group = engine->FindConfigGroupForObjectType(parameterTypes[p].GetObjectType());
+				if( group != 0 ) group->AddRef();
+			}
 
 		for( asUINT v = 0; v < scriptData->objVariableTypes.GetLength(); v++ )
 			if( scriptData->objVariableTypes[v] ) // The null handle is also stored, but it doesn't have an object type
-				scriptData->objVariableTypes[v]->AddRef();
+			{
+				scriptData->objVariableTypes[v]->AddRefInternal();
+
+				asCConfigGroup *group = engine->FindConfigGroupForObjectType(scriptData->objVariableTypes[v]);
+				if( group != 0 ) group->AddRef();
+			}
 
 		// Go through the byte code and add references to all resources used by the function
 		asCArray<asDWORD> &bc = scriptData->byteCode;
@@ -1048,7 +1102,9 @@ void asCScriptFunction::AddReferences()
 			case asBC_RefCpyV:
 				{
 					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					objType->AddRef();
+					asASSERT( objType );
+					if( objType )
+						objType->AddRefInternal();
 				}
 				break;
 
@@ -1056,11 +1112,13 @@ void asCScriptFunction::AddReferences()
 			case asBC_ALLOC:
 				{
 					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					objType->AddRef();
+					asASSERT( objType );
+					if( objType )
+						objType->AddRefInternal();
 
-					int func = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
-					if( func )
-						engine->scriptFunctions[func]->AddRef();
+					int funcId = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
+					if( funcId )
+						engine->scriptFunctions[funcId]->AddRefInternal();
 				}
 				break;
 
@@ -1099,7 +1157,9 @@ void asCScriptFunction::AddReferences()
 					asCConfigGroup *group = engine->FindConfigGroupForFunction(funcId);
 					if( group != 0 ) group->AddRef();
 
-					engine->scriptFunctions[funcId]->AddRef();
+					asASSERT( funcId > 0 );
+					if( funcId > 0 )
+						engine->scriptFunctions[funcId]->AddRefInternal();
 				}
 				break;
 
@@ -1107,8 +1167,10 @@ void asCScriptFunction::AddReferences()
 			case asBC_CALL:
 			case asBC_CALLINTF:
 				{
-					int func = asBC_INTARG(&bc[n]);
-					engine->scriptFunctions[func]->AddRef();
+					int funcId = asBC_INTARG(&bc[n]);
+					asASSERT( funcId > 0 );
+					if( funcId > 0 )
+						engine->scriptFunctions[funcId]->AddRefInternal();
 				}
 				break;
 
@@ -1116,7 +1178,9 @@ void asCScriptFunction::AddReferences()
 			case asBC_FuncPtr:
 				{
 					asCScriptFunction *func = (asCScriptFunction*)asBC_PTRARG(&bc[n]);
-					func->AddRef();
+					asASSERT( func );
+					if( func )
+						func->AddRefInternal();
 				}
 				break;
 			}
@@ -1132,16 +1196,31 @@ void asCScriptFunction::ReleaseReferences()
 	// Only count references if there is any bytecode
 	if( scriptData && scriptData->byteCode.GetLength() )
 	{
-		if( returnType.IsObject() )
-			returnType.GetObjectType()->Release();
+		if( returnType.GetObjectType() )
+		{
+			returnType.GetObjectType()->ReleaseInternal();
+
+			asCConfigGroup *group = engine->FindConfigGroupForObjectType(returnType.GetObjectType());
+			if( group != 0 ) group->Release();
+		}
 
 		for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
-			if( parameterTypes[p].IsObject() )
-				parameterTypes[p].GetObjectType()->Release();
+			if( parameterTypes[p].GetObjectType() )
+			{
+				parameterTypes[p].GetObjectType()->ReleaseInternal();
+
+				asCConfigGroup *group = engine->FindConfigGroupForObjectType(parameterTypes[p].GetObjectType());
+				if( group != 0 ) group->Release();
+			}
 
 		for( asUINT v = 0; v < scriptData->objVariableTypes.GetLength(); v++ )
-			if( scriptData->objVariableTypes[v] )
-				scriptData->objVariableTypes[v]->Release();
+			if( scriptData->objVariableTypes[v] ) // The null handle is also stored, but it doesn't have an object type
+			{
+				scriptData->objVariableTypes[v]->ReleaseInternal();
+
+				asCConfigGroup *group = engine->FindConfigGroupForObjectType(scriptData->objVariableTypes[v]);
+				if( group != 0 ) group->Release();
+			}
 
 		// Go through the byte code and release references to all resources used by the function
 		asCArray<asDWORD> &bc = scriptData->byteCode;
@@ -1157,7 +1236,7 @@ void asCScriptFunction::ReleaseReferences()
 				{
 					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
 					if( objType )
-						objType->Release();
+						objType->ReleaseInternal();
 				}
 				break;
 
@@ -1166,14 +1245,14 @@ void asCScriptFunction::ReleaseReferences()
 				{
 					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
 					if( objType )
-						objType->Release();
+						objType->ReleaseInternal();
 
-					int func = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
-					if( func )
+					int funcId = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
+					if( funcId > 0 )
 					{
-						asCScriptFunction *fptr = engine->scriptFunctions[func];
+						asCScriptFunction *fptr = engine->scriptFunctions[funcId];
 						if( fptr )
-							fptr->Release();
+							fptr->ReleaseInternal();
 
 						// The engine may have been forced to destroy the function internals early
 						// and this may will make it impossible to find the function by id anymore.
@@ -1220,7 +1299,7 @@ void asCScriptFunction::ReleaseReferences()
 					if( group != 0 ) group->Release();
 
 					if( funcId )
-						engine->scriptFunctions[funcId]->Release();
+						engine->scriptFunctions[funcId]->ReleaseInternal();
 				}
 				break;
 
@@ -1228,12 +1307,12 @@ void asCScriptFunction::ReleaseReferences()
 			case asBC_CALL:
 			case asBC_CALLINTF:
 				{
-					int func = asBC_INTARG(&bc[n]);
-					if( func )
+					int funcId = asBC_INTARG(&bc[n]);
+					if( funcId )
 					{
-						asCScriptFunction *fptr = engine->scriptFunctions[func];
+						asCScriptFunction *fptr = engine->scriptFunctions[funcId];
 						if( fptr )
-							fptr->Release();
+							fptr->ReleaseInternal();
 
 						// The engine may have been forced to destroy the function internals early
 						// and this may will make it impossible to find the function by id anymore.
@@ -1249,7 +1328,7 @@ void asCScriptFunction::ReleaseReferences()
 				{
 					asCScriptFunction *func = (asCScriptFunction*)asBC_PTRARG(&bc[n]);
 					if( func )
-						func->Release();
+						func->ReleaseInternal();
 				}
 				break;
 			}
@@ -1523,7 +1602,9 @@ asCGlobalProperty *asCScriptFunction::GetPropertyByGlobalVarPtr(void *gvarPtr)
 // internal
 int asCScriptFunction::GetRefCount()
 {
-	return refCount.get();
+	asASSERT( funcType == asFUNC_DELEGATE );
+
+	return externalRefCount.get();
 }
 
 // internal
@@ -1541,193 +1622,24 @@ bool asCScriptFunction::GetFlag()
 // internal
 void asCScriptFunction::EnumReferences(asIScriptEngine *)
 {
-	// Notify the GC of all object types used
-	if( returnType.IsObject() )
-		engine->GCEnumCallback(returnType.GetObjectType());
-
-	for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
-		if( parameterTypes[p].IsObject() )
-			engine->GCEnumCallback(parameterTypes[p].GetObjectType());
-
-	if( scriptData )
-	{
-		for( asUINT t = 0; t < scriptData->objVariableTypes.GetLength(); t++ )
-			engine->GCEnumCallback(scriptData->objVariableTypes[t]);
-
-		// Notify the GC of all script functions that is accessed
-		asCArray<asDWORD> &bc = scriptData->byteCode;
-		for( asUINT n = 0; n < bc.GetLength(); n += asBCTypeSize[asBCInfo[*(asBYTE*)&bc[n]].type] )
-		{
-			switch( *(asBYTE*)&bc[n] )
-			{
-			case asBC_OBJTYPE:
-			case asBC_FREE:
-			case asBC_REFCPY:
-			case asBC_RefCpyV:
-				{
-					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					engine->GCEnumCallback(objType);
-				}
-				break;
-
-			case asBC_ALLOC:
-				{
-					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					engine->GCEnumCallback(objType);
-
-					int func = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
-					if( func )
-						engine->GCEnumCallback(engine->scriptFunctions[func]);
-				}
-				break;
-
-			case asBC_CALL:
-			case asBC_CALLINTF:
-				{
-					int func = asBC_INTARG(&bc[n]);
-					if( func )
-						engine->GCEnumCallback(engine->scriptFunctions[func]);
-				}
-				break;
-
-			// Function pointers
-			case asBC_FuncPtr:
-				{
-					asCScriptFunction *func = (asCScriptFunction*)asBC_PTRARG(&bc[n]);
-					if( func )
-						engine->GCEnumCallback(func);
-				}
-				break;
-
-			// Global variables
-			case asBC_PGA:
-			case asBC_PshGPtr:
-			case asBC_LDG:
-			case asBC_PshG4:
-			case asBC_LdGRdR4:
-			case asBC_CpyGtoV4:
-			case asBC_CpyVtoG4:
-			case asBC_SetG4:
-				// Need to enumerate the reference for each global variable
-				{
-					// TODO: optimize: Keep an array of accessed global properties
-					void *gvarPtr = (void*)asBC_PTRARG(&bc[n]);
-					asCGlobalProperty *prop = GetPropertyByGlobalVarPtr(gvarPtr);
-
-					engine->GCEnumCallback(prop);
-				}
-				break;
-			}
-		}
-	}
+	asASSERT( funcType == asFUNC_DELEGATE );
 
 	// Delegate
 	if( objForDelegate )
 		engine->GCEnumCallback(objForDelegate);
-	if( funcForDelegate )
-		engine->GCEnumCallback(funcForDelegate);
 }
 
 // internal
 void asCScriptFunction::ReleaseAllHandles(asIScriptEngine *)
 {
-	// Release paramaters
-	if( scriptData && scriptData->byteCode.GetLength() )
-	{
-		if( returnType.IsObject() )
-		{
-			returnType.GetObjectType()->Release();
-			returnType = asCDataType::CreatePrimitive(ttVoid, false);
-		}
-
-		for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
-			if( parameterTypes[p].IsObject() )
-			{
-				parameterTypes[p].GetObjectType()->Release();
-				parameterTypes[p] = asCDataType::CreatePrimitive(ttInt, false);
-			}
-
-		for( asUINT n = 0; n < scriptData->objVariableTypes.GetLength(); n++ )
-			if( scriptData->objVariableTypes[n] ) // Null handle is also stored, but it doesn't have an object type
-				scriptData->objVariableTypes[n]->Release();
-		scriptData->objVariableTypes.SetLength(0);
+	asASSERT( funcType == asFUNC_DELEGATE );
 
-		// Release all script functions
-		asCArray<asDWORD> &bc = scriptData->byteCode;
-		for( asUINT n = 0; n < bc.GetLength(); n += asBCTypeSize[asBCInfo[*(asBYTE*)&bc[n]].type] )
-		{
-			switch( *(asBYTE*)&bc[n] )
-			{
-			// Object types
-			case asBC_OBJTYPE:
-			case asBC_FREE:
-			case asBC_REFCPY:
-			case asBC_RefCpyV:
-				{
-					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					if( objType )
-					{
-						objType->Release();
-						*(asPWORD*)&bc[n+1] = 0;
-					}
-				}
-				break;
-
-			case asBC_ALLOC:
-				{
-					asCObjectType *objType = (asCObjectType*)asBC_PTRARG(&bc[n]);
-					if( objType )
-					{
-						objType->Release();
-						*(asPWORD*)&bc[n+1] = 0;
-					}
-
-					int func = asBC_INTARG(&bc[n]+AS_PTR_SIZE);
-					if( func )
-					{
-						engine->scriptFunctions[func]->Release();
-						bc[n+AS_PTR_SIZE+1] = 0;
-					}
-				}
-				break;
-
-			case asBC_CALL:
-			case asBC_CALLINTF:
-				{
-					int func = asBC_INTARG(&bc[n]);
-					if( func )
-					{
-						engine->scriptFunctions[func]->Release();
-						bc[n+1] = 0;
-					}
-				}
-				break;
-
-			// Function pointers
-			case asBC_FuncPtr:
-				{
-					asCScriptFunction *func = (asCScriptFunction*)asBC_PTRARG(&bc[n]);
-					if( func )
-					{
-						func->Release();
-						*(asPWORD*)&bc[n+1] = 0;
-					}
-				}
-				break;
-
-			// The global variables are not released here. It is enough that the global
-			// variable itself release the function to break the circle
-			}
-		}
-	}
+	// Release paramaters
 
 	// Delegate
 	if( objForDelegate )
 		engine->ReleaseScriptObject(objForDelegate, funcForDelegate->GetObjectType());
 	objForDelegate = 0;
-	if( funcForDelegate )
-		funcForDelegate->Release();
-	funcForDelegate = 0;
 }
 
 // internal
@@ -1737,6 +1649,7 @@ bool asCScriptFunction::IsShared() const
 	if( funcType == asFUNC_SYSTEM ) return true;
 
 	// All class methods for shared classes are also shared
+	asASSERT( objectType == 0 || objectType->engine == engine || objectType->engine == 0 );
 	if( objectType && (objectType->flags & asOBJ_SHARED) ) return true;
 
 	// Functions that have been specifically marked as shared are shared

+ 11 - 4
Source/ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -138,6 +138,7 @@ public:
 	const char          *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const;
 	bool                 IsReadOnly() const;
 	bool                 IsPrivate() const;
+	bool                 IsProtected() const;
 	bool                 IsFinal() const;
 	bool                 IsOverride() const;
 	bool                 IsShared() const;
@@ -178,6 +179,11 @@ public:
 	asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
 	~asCScriptFunction();
 
+	// Keep an internal reference counter to separate references coming from 
+	// application or script objects and references coming from the script code
+	int AddRefInternal();
+	int ReleaseInternal();
+
 	void     DestroyHalfCreated();
 
 	// TODO: 2.29.0: operator==
@@ -189,7 +195,6 @@ public:
 	//bool      operator==(const asCScriptFunction &other) const;
 
 	void      DestroyInternal();
-	void      Orphan(asIScriptModule *mod);
 
 	void      AddVariable(asCString &name, asCDataType &type, int stackOffset);
 
@@ -224,7 +229,7 @@ public:
 
 	asCGlobalProperty *GetPropertyByGlobalVarPtr(void *gvarPtr);
 
-	// GC methods
+	// GC methods (for delegates)
 	int  GetRefCount();
 	void SetFlag();
 	bool GetFlag();
@@ -235,7 +240,8 @@ public:
 	//-----------------------------------
 	// Properties
 
-	mutable asCAtomic            refCount;
+	mutable asCAtomic            externalRefCount; // Used for external referneces
+	        asCAtomic            internalRefCount; // Used for internal references
 	mutable bool                 gcFlag;
 	asCScriptEngine             *engine;
 	asCModule                   *module;
@@ -251,6 +257,7 @@ public:
 	asCArray<asCString *>        defaultArgs;
 	bool                         isReadOnly;
 	bool                         isPrivate;
+	bool                         isProtected;
 	bool                         isFinal;
 	bool                         isOverride;
 	asCObjectType               *objectType;
@@ -305,7 +312,7 @@ public:
 		asCArray<int>                   lineNumbers;
 		// Store the script section where the code was declared
 		int                             scriptSectionIdx;
-		// Store the location where the function was declared
+		// Store the location where the function was declared  (row in the lower 20 bits, and column in the upper 12)
 		int                             declaredAt;
 		// Store position/index pairs if the bytecode is compiled from multiple script sections
 		asCArray<int>                   sectionIdxs;

+ 101 - 29
Source/ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -28,7 +28,6 @@
    [email protected]
 */
 
-// Modified by Lasse Oorni for Urho3D
 
 #include <new>
 #include "as_config.h"
@@ -241,7 +240,7 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 	objType = ot;
 	objType->AddRef();
 	isDestructCalled = false;
-	weakRefFlag = 0;
+	extra = 0;
 	hasRefCountReachedZero = false;
 
 	// Notify the garbage collector of this object
@@ -291,9 +290,6 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
 			}
 		}
 	}
-	
-	// Urho3D: initialize userdata
-	userData = 0;
 }
 
 void asCScriptObject::Destruct()
@@ -302,15 +298,40 @@ void asCScriptObject::Destruct()
 	this->~asCScriptObject();
 
 	// Free the memory
+#ifndef WIP_16BYTE_ALIGN
 	userFree(this);
+#else
+	// Script object memory is allocated through asCScriptEngine::CallAlloc()
+	// This free call must match the allocator used in CallAlloc().
+	userFreeAligned(this);
+#endif
 }
 
 asCScriptObject::~asCScriptObject()
 {
-	if( weakRefFlag )
+	if( extra )
 	{
-		weakRefFlag->Release();
-		weakRefFlag = 0;
+		if( extra->weakRefFlag )
+		{
+			extra->weakRefFlag->Release();
+			extra->weakRefFlag = 0;
+		}
+
+		if( objType->engine )
+		{
+			// Clean the user data
+			for( asUINT n = 0; n < extra->userData.GetLength(); n += 2 )
+			{
+				if( extra->userData[n+1] )
+				{
+					for( asUINT c = 0; c < objType->engine->cleanScriptObjectFuncs.GetLength(); c++ )
+						if( objType->engine->cleanScriptObjectFuncs[c].type == extra->userData[n] )
+							objType->engine->cleanScriptObjectFuncs[c].cleanFunc(this);
+				}
+			}
+		}
+
+		asDELETE(extra, SExtra);
 	}
 
 	// The engine pointer should be available from the objectType
@@ -364,8 +385,8 @@ asILockableSharedBool *asCScriptObject::GetWeakRefFlag() const
 	// If the object's refCount has already reached zero then the object is already
 	// about to be destroyed so it's ok to return null if the weakRefFlag doesn't already
 	// exist
-	if( weakRefFlag || hasRefCountReachedZero )
-		return weakRefFlag;
+	if( (extra && extra->weakRefFlag) || hasRefCountReachedZero )
+		return extra->weakRefFlag;
 
 	// Lock globally so no other thread can attempt
 	// to create a shared bool at the same time.
@@ -376,12 +397,77 @@ asILockableSharedBool *asCScriptObject::GetWeakRefFlag() const
 
 	// Make sure another thread didn't create the 
 	// flag while we waited for the lock
-	if( !weakRefFlag )
-		weakRefFlag = asNEW(asCLockableSharedBool);
+	if( !extra )
+		extra = asNEW(SExtra);
+	if( !extra->weakRefFlag )
+		extra->weakRefFlag = asNEW(asCLockableSharedBool);
 
 	asReleaseExclusiveLock();
 
-	return weakRefFlag;
+	return extra->weakRefFlag;
+}
+
+void *asCScriptObject::GetUserData(asPWORD type) const
+{
+	if( !extra )
+		return 0;
+
+	// There may be multiple threads reading, but when
+	// setting the user data nobody must be reading.
+	// TODO: runtime optimize: Would it be worth it to have a rwlock per object type?
+	asAcquireSharedLock();
+
+	for( asUINT n = 0; n < extra->userData.GetLength(); n += 2 )
+	{
+		if( extra->userData[n] == type )
+		{
+			void *userData = reinterpret_cast<void*>(extra->userData[n+1]);
+			asReleaseSharedLock();
+			return userData;
+		}
+	}
+
+	asReleaseSharedLock();
+
+	return 0;
+}
+
+void *asCScriptObject::SetUserData(void *data, asPWORD type)
+{
+	// Lock globally so no other thread can attempt
+	// to manipulate the extra data at the same time.
+	// TODO: runtime optimize: Instead of locking globally, it would be possible to have 
+	//                         a critical section per object type. This would reduce the 
+	//                         chances of two threads lock on the same critical section.
+	asAcquireExclusiveLock();
+
+	// Make sure another thread didn't create the 
+	// flag while we waited for the lock
+	if( !extra )
+		extra = asNEW(SExtra);
+
+	// It is not intended to store a lot of different types of userdata,
+	// so a more complex structure like a associative map would just have
+	// more overhead than a simple array.
+	for( asUINT n = 0; n < extra->userData.GetLength(); n += 2 )
+	{
+		if( extra->userData[n] == type )
+		{
+			void *oldData = reinterpret_cast<void*>(extra->userData[n+1]);
+			extra->userData[n+1] = reinterpret_cast<asPWORD>(data);
+
+			asReleaseExclusiveLock();
+
+			return oldData;
+		}
+	}
+
+	extra->userData.PushLast(type);
+	extra->userData.PushLast(reinterpret_cast<asPWORD>(data));
+
+	asReleaseExclusiveLock();
+
+	return 0;
 }
 
 asIScriptEngine *asCScriptObject::GetEngine() const
@@ -420,14 +506,14 @@ int asCScriptObject::Release() const
 	// is ok to check the existance of the weakRefFlag without locking here
 	// because if the refCount is 1 then no other thread is currently 
 	// creating the weakRefFlag.
-	if( refCount.get() == 1 && weakRefFlag )
+	if( refCount.get() == 1 && extra && extra->weakRefFlag )
 	{
 		// Set the flag to tell others that the object is no longer alive
 		// We must do this before decreasing the refCount to 0 so we don't
 		// end up with a race condition between this thread attempting to 
 		// destroy the object and the other that temporary added a strong
 		// ref from the weak ref.
-		weakRefFlag->Set(true);
+		extra->weakRefFlag->Set(true);
 	}
 
 	// Call the script destructor behaviour if the reference counter is 1.
@@ -578,20 +664,6 @@ int asCScriptObject::GetTypeId() const
 	return objType->engine->GetTypeIdFromDataType(dt);
 }
 
-// Urho3D: added function
-void *asCScriptObject::SetUserData(void *data)
-{
-	void *oldData = userData;
-	userData = data;
-	return oldData;
-}
-
-// Urho3D: added function
-void *asCScriptObject::GetUserData() const
-{
-	return userData;
-}
-
 asUINT asCScriptObject::GetPropertyCount() const
 {
 	return asUINT(objType->properties.GetLength());

+ 28 - 22
Source/ThirdParty/AngelScript/source/as_scriptobject.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
@@ -28,7 +28,6 @@
    [email protected]
 */
 
-// Modified by Lasse Oorni for Urho3D
 
 
 //
@@ -77,11 +76,11 @@ public:
 //===================================
 // From asIScriptObject
 //===================================
-	asIScriptEngine *GetEngine() const;
 
 	// Memory management
-	int AddRef() const;
-	int Release() const;
+	int                    AddRef() const;
+	int                    Release() const;
+	asILockableSharedBool *GetWeakRefFlag() const;
 
 	// Type info
 	int            GetTypeId() const;
@@ -93,11 +92,13 @@ public:
 	const char *GetPropertyName(asUINT prop) const;
 	void       *GetAddressOfProperty(asUINT prop);
 
-	int         CopyFrom(asIScriptObject *other);
+	// Miscellaneous
+	asIScriptEngine *GetEngine() const;
+	int              CopyFrom(asIScriptObject *other);
 
-	// Urho3D: added userdata
-	void *SetUserData(void *data);
-	void *GetUserData() const;
+	// User data
+	void *SetUserData(void *data, asPWORD type = 0);
+	void *GetUserData(asPWORD type = 0) const;
 
 //====================================
 // Internal
@@ -115,9 +116,6 @@ public:
 	void EnumReferences(asIScriptEngine *engine);
 	void ReleaseAllHandles(asIScriptEngine *engine);
 
-	// Weakref methods
-	asILockableSharedBool *GetWeakRefFlag() const;
-
 	// Used for properties
 	void *AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine);
 	void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
@@ -129,18 +127,26 @@ public:
 //=============================================
 // Properties
 //=============================================
-public:
-	asCObjectType *objType;
-
 protected:
+	friend class asCContext;
+	asCObjectType    *objType;
+
 	mutable asCAtomic refCount;
-	mutable asBYTE gcFlag:1;
-	mutable asBYTE hasRefCountReachedZero:1;
-	bool isDestructCalled;
-	mutable asCLockableSharedBool *weakRefFlag;
-	
-	// Urho3D: added userdata
-	void* userData;
+	mutable asBYTE    gcFlag:1;
+	mutable asBYTE    hasRefCountReachedZero:1;
+	bool              isDestructCalled;
+
+	// Most script classes instances won't have neither the weakRefFlags nor
+	// userData so we only allocate this if requested. Even when used it is 
+	// not something that will be accessed all the time so having the extra
+	// indirection will not affect the performance significantly.
+	struct SExtra
+	{
+		SExtra() : weakRefFlag(0) {};
+		asCLockableSharedBool *weakRefFlag;
+		asCArray<asPWORD>      userData;
+	};
+	mutable SExtra *extra;
 };
 
 void ScriptObject_Construct(asCObjectType *objType, asCScriptObject *self);

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

@@ -78,7 +78,7 @@ double asStringScanDouble(const char *string, size_t *numScanned)
 {
 	// I decided to do my own implementation of strtod() because this function
 	// doesn't seem to be present on all systems. iOS 5 for example doesn't appear 
-	// to include the function in the standard lib. 
+	// to include the function in the standard lib.
 	
 	// Another reason is that the standard implementation of strtod() is dependent
 	// on the locale on some systems, i.e. it may use comma instead of dot for 

+ 43 - 42
Source/ThirdParty/AngelScript/source/as_symboltable.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2012-2014 Andreas Jonsson
+   Copyright (c) 2012-2015 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
@@ -59,6 +59,7 @@ BEGIN_AS_NAMESPACE
 struct asIFilter
 {
 	virtual bool operator()(const void*) const = 0;
+	virtual ~asIFilter() {};
 };
 
 
@@ -107,7 +108,7 @@ public:
 	typedef asCSymbolTableIterator<T, T> iterator;
 	typedef asCSymbolTableIterator<T, const T> const_iterator;
 
-	asCSymbolTable(unsigned int initialCapacity = 0);
+	asCSymbolTable(asUINT initialCapacity = 0);
 
 	int      GetFirstIndex(const asSNameSpace *ns, const asCString &name, const asIFilter &comparator) const;
 	int      GetFirstIndex(const asSNameSpace *ns, const asCString &name) const;
@@ -118,22 +119,22 @@ public:
 	T*       GetFirst(const asSNameSpace *ns, const asCString &name, const asIFilter &comparator) const;
 	T*       GetFirst(const asSNameSpace *ns, const asCString &name);
 	const T* GetFirst(const asSNameSpace *ns, const asCString &name) const;
-	T*       Get(unsigned int index);
-	const T* Get(unsigned int index) const;
+	T*       Get(asUINT index);
+	const T* Get(asUINT index) const;
 	T*       GetLast();
 	const T* GetLast() const;
 
-	const asCArray<unsigned int> &GetIndexes(const asSNameSpace *ns, const asCString &name) const;
+	const asCArray<asUINT> &GetIndexes(const asSNameSpace *ns, const asCString &name) const;
 
-	int      Put(T* entry);
+	asUINT   Put(T* entry);
 
-	unsigned int GetSize() const;
+	asUINT   GetSize() const;
 
 	void SwapWith(asCSymbolTable<T> &other);
 
 	void Clear();
-	bool Erase(unsigned int idx);
-	void Allocate(unsigned int elem_cnt, bool keep_data);
+	bool Erase(asUINT idx);
+	void Allocate(asUINT elem_cnt, bool keep_data);
 
 	iterator List();
 	const_iterator List() const;
@@ -146,11 +147,11 @@ private:
 	friend class asCSymbolTableIterator<T, const T>;
 
 	void GetKey(const T *entry, asSNameSpaceNamePair &key) const;
-	bool CheckIdx(unsigned idx) const;
+	bool CheckIdx(asUINT idx) const;
 
-	asCMap<asSNameSpaceNamePair, asCArray<unsigned int> > m_map;
-	asCArray<T*>                                          m_entries;
-	unsigned int                                          m_size;
+	asCMap<asSNameSpaceNamePair, asCArray<asUINT> > m_map;
+	asCArray<T*>                                    m_entries;
+	unsigned int                                    m_size;
 };
 
 
@@ -162,7 +163,7 @@ void asCSymbolTable<T>::SwapWith(asCSymbolTable<T> &other)
 	m_map.SwapWith(other.m_map);
 	m_entries.SwapWith(other.m_entries);
 
-	unsigned int tmp = m_size;
+	asUINT tmp = m_size;
 	m_size = other.m_size;
 	other.m_size = tmp;
 }
@@ -173,7 +174,7 @@ void asCSymbolTable<T>::SwapWith(asCSymbolTable<T> &other)
 // Constructor
 // initialCapacity gives the number of entries to allocate in advance
 template<class T>
-asCSymbolTable<T>::asCSymbolTable(unsigned initialCapacity) : m_entries(initialCapacity)
+asCSymbolTable<T>::asCSymbolTable(asUINT initialCapacity) : m_entries(initialCapacity)
 {
 	m_size = 0;
 }
@@ -188,11 +189,11 @@ int asCSymbolTable<T>::GetFirstIndex(
 {
 	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<asUINT> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 	{
-		const asCArray<unsigned int> &arr = m_map.GetValue(cursor);
-		for( unsigned int n = 0; n < arr.GetLength(); n++ )
+		const asCArray<asUINT> &arr = m_map.GetValue(cursor);
+		for( asUINT n = 0; n < arr.GetLength(); n++ )
 		{
 			T *entry = m_entries[arr[n]];
 			if( entry && filter(entry) )
@@ -206,15 +207,15 @@ int asCSymbolTable<T>::GetFirstIndex(
 
 
 template<class T>
-const asCArray<unsigned int> &asCSymbolTable<T>::GetIndexes(const asSNameSpace *ns, const asCString &name) const
+const asCArray<asUINT> &asCSymbolTable<T>::GetIndexes(const asSNameSpace *ns, const asCString &name) const
 {
 	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<asUINT> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 		return m_map.GetValue(cursor);
 
-	static asCArray<unsigned int> dummy;
+	static asCArray<asUINT> dummy;
 	return dummy;
 }
 
@@ -237,7 +238,7 @@ int asCSymbolTable<T>::GetFirstIndex(const asSNameSpace *ns, const asCString &na
 {
 	asSNameSpaceNamePair key(ns, name);
 
-	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<asUINT> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 		return m_map.GetValue(cursor)[0];
 
@@ -252,7 +253,7 @@ int asCSymbolTable<T>::GetFirstIndex(const asSNameSpace *ns, const asCString &na
 template<class T>
 int asCSymbolTable<T>::GetIndex(const T* entry) const
 {
-	for( unsigned int n = 0; n < m_entries.GetLength(); n++ )
+	for( asUINT n = 0; n < m_entries.GetLength(); n++ )
 		if( m_entries[n] == entry )
 			return n;
 
@@ -265,7 +266,7 @@ int asCSymbolTable<T>::GetIndex(const T* entry) const
 
 
 template<class T>
-T* asCSymbolTable<T>::Get(unsigned idx)
+T* asCSymbolTable<T>::Get(asUINT idx)
 {
 	if( !CheckIdx(idx) )
 		return 0;
@@ -274,7 +275,7 @@ T* asCSymbolTable<T>::Get(unsigned idx)
 }
 
 template<class T>
-const T* asCSymbolTable<T>::Get(unsigned idx) const
+const T* asCSymbolTable<T>::Get(asUINT idx) const
 {
 	return const_cast< asCSymbolTable<T>* >(this)->Get(idx);
 }
@@ -331,7 +332,7 @@ void asCSymbolTable<T>::Clear()
 
 // Pre-allocate slots for elemCnt entries
 template<class T>
-void asCSymbolTable<T>::Allocate(unsigned elemCnt, bool keepData)
+void asCSymbolTable<T>::Allocate(asUINT elemCnt, bool keepData)
 {
 	asASSERT( elemCnt >= m_entries.GetLength() );
 	m_entries.Allocate(elemCnt, keepData);
@@ -342,7 +343,7 @@ void asCSymbolTable<T>::Allocate(unsigned elemCnt, bool keepData)
 
 
 template<class T>
-bool asCSymbolTable<T>::Erase(unsigned idx)
+bool asCSymbolTable<T>::Erase(asUINT idx)
 {
 	if( !CheckIdx(idx) )
 	{
@@ -359,10 +360,10 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 	asSNameSpaceNamePair key;
 	GetKey(entry, key);
 
-	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<asUINT> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 	{
-		asCArray<unsigned int> &arr = m_map.GetValue(cursor);
+		asCArray<asUINT> &arr = m_map.GetValue(cursor);
 		arr.RemoveValue(idx);
 		if( arr.GetLength() == 0 )
 			m_map.Erase(cursor);
@@ -384,7 +385,7 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 		GetKey(entry, key);
 		if( m_map.MoveTo(&cursor, key) )
 		{
-			asCArray<unsigned int> &arr = m_map.GetValue(cursor);
+			asCArray<asUINT> &arr = m_map.GetValue(cursor);
 			arr[arr.IndexOf(prevIdx)] = idx;
 		}
 		else
@@ -399,18 +400,18 @@ bool asCSymbolTable<T>::Erase(unsigned idx)
 
 
 template<class T>
-int asCSymbolTable<T>::Put(T *entry)
+asUINT asCSymbolTable<T>::Put(T *entry)
 {
-	unsigned int idx = (unsigned int)(m_entries.GetLength());
+	asUINT idx = m_entries.GetLength();
 	asSNameSpaceNamePair key;
 	GetKey(entry, key);
 
-	asSMapNode<asSNameSpaceNamePair, asCArray<unsigned int> > *cursor;
+	asSMapNode<asSNameSpaceNamePair, asCArray<asUINT> > *cursor;
 	if( m_map.MoveTo(&cursor, key) )
 		m_map.GetValue(cursor).PushLast(idx);
 	else
 	{
-		asCArray<unsigned int> arr(1);
+		asCArray<asUINT> arr(1);
 		arr.PushLast(idx);
 		m_map.Insert(key, arr);
 	}
@@ -434,7 +435,7 @@ void asCSymbolTable<T>::GetKey(const T *entry, asSNameSpaceNamePair &key) const
 
 
 template<class T>
-unsigned int asCSymbolTable<T>::GetSize() const
+asUINT asCSymbolTable<T>::GetSize() const
 {
 	return m_size;
 }
@@ -443,7 +444,7 @@ unsigned int asCSymbolTable<T>::GetSize() const
 
 
 template<class T>
-bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
+bool asCSymbolTable<T>::CheckIdx(asUINT idx) const
 {
 	return idx < m_entries.GetLength();
 }
@@ -454,9 +455,9 @@ bool asCSymbolTable<T>::CheckIdx(unsigned int idx) const
 template<class T>
 int asCSymbolTable<T>::GetLastIndex() const
 {
-	unsigned int idx = (unsigned int)(m_entries.GetLength()) - 1;
-	asASSERT( idx == asUINT(-1) || m_entries[idx] );
-	return int(idx);
+	int idx = int(m_entries.GetLength()) - 1;
+	asASSERT( idx == -1 || m_entries[idx] );
+	return idx;
 }
 
 
@@ -485,7 +486,7 @@ typename asCSymbolTable<T>::const_iterator asCSymbolTable<T>::List() const
 template<class T, class T2>
 asCSymbolTableIterator<T, T2>::asCSymbolTableIterator(asCSymbolTable<T> *table) : m_table(table), m_idx(0)
 {
-	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	asUINT sz = m_table->m_entries.GetLength();
 	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
 		m_idx++;
 }
@@ -533,7 +534,7 @@ asCSymbolTableIterator<T, T2>::operator bool() const
 template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Next()
 {
-	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	asUINT sz = m_table->m_entries.GetLength();
 	m_idx++;
 	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
 		m_idx++;
@@ -545,7 +546,7 @@ template<class T, class T2>
 void asCSymbolTableIterator<T, T2>::Previous()
 {
 	// overflow on stepping over first element
-	unsigned int sz = (unsigned int)(m_table->m_entries.GetLength());
+	asUINT sz = m_table->m_entries.GetLength();
 	m_idx--;
 	while( m_idx < sz && m_table->m_entries[m_idx] == 0 )
 		m_idx--;

+ 51 - 36
Source/ThirdParty/AngelScript/source/as_texts.h

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2014 Andreas Jonsson
+   Copyright (c) 2003-2015 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 
@@ -41,10 +41,12 @@
 
 // Compiler messages
 
-#define TXT_s_ALREADY_DECLARED                    "'%s' is already declared"
+#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_ACCESSING_PRIVATE_PROP_s                "Accessing private property '%s' of parent class"
+#define TXT_ARG_NOT_LVALUE                          "Output argument expression is not assignable"
+#define TXT_ATTR_s_INFORMED_MULTIPLE_TIMES          "Attribute '%s' informed multiple times"
+#define TXT_AUTO_NOT_ALLOWED                        "Auto is not allowed here"
 
 #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"
@@ -59,49 +61,50 @@
 #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_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_RESOLVE_AUTO                     "Unable to resolve auto type"
 #define TXT_CANNOT_RETURN_REF_TO_LOCAL             "Can't return reference to local value."
+#define TXT_CANT_CONSTRUCT_s_USE_REF_CAST          "Can't construct handle '%s'. Use ref cast instead"
 #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"
+#define TXT_COMPOUND_ASGN_ON_VALUE_TYPE            "Compound assignments with property accessors on value types are not supported"
+#define TXT_COMPOUND_ASGN_WITH_IDX_PROP            "Compound assignments with indexed property accessors are not supported"
+#define TXT_COMPOUND_ASGN_REQUIRE_GET_SET          "Compound assignments with property accessors require both get and set accessors"
 
 #define TXT_DATA_TYPE_CANT_BE_s                     "Data type can't be '%s'"
-#define TXT_CANNOT_RESOLVE_AUTO                     "Unable to resolve auto type"
-#define TXT_AUTO_NOT_ALLOWED                        "Auto is not allowed here"
 #define TXT_DECL_IN_SWITCH                          "Variables cannot be declared in switch cases, except inside statement blocks"
 #define TXT_DEFAULT_MUST_BE_LAST                    "The default case must be the last one"
 #define TXT_DEF_ARG_MISSING_IN_FUNC_s               "All subsequent parameters after the first default value must have default values in function '%s'"
 #define TXT_DEF_ARG_TYPE_DOESNT_MATCH               "The type of the default argument expression doesn't match the function parameter type"
-#define TXT_POS_ARG_AFTER_NAMED_ARG                 "Positional arguments cannot be passed after named arguments"
 #define TXT_DUPLICATE_NAMED_ARG                     "Duplicate named argument"
 #define TXT_DERIVED_METHOD_MUST_HAVE_SAME_RETTYPE_s "The method in the derived class must have the same return type as in the base class: '%s'"
 #define TXT_DESTRUCTOR_MAY_NOT_HAVE_PARM            "The destructor must not have any parameters"
+#define TXT_DESTRUCTOR_s_s_NAME_ERROR              "The name of the destructor '%s::~%s' must be the same as the class"
 #define TXT_DISALLOW_ASSIGN_ON_REF_TYPE             "Value assignment on reference types is not allowed. Did you mean to do a handle assignment?"
 #define TXT_DISALLOW_COMPOUND_ASSIGN_ON_REF_TYPE    "Compound assignment on reference types is not allowed"
 #define TXT_DUPLICATE_SWITCH_CASE                   "Duplicate switch case"
 
-#define TXT_ELSE_WITH_EMPTY_STATEMENT     "Else with empty statement"
-#define TXT_EMPTY_SWITCH                  "Empty switch statement"
-#define TXT_EXPECTED_s                    "Expected '%s'"
-#define TXT_EXPECTED_CONSTANT             "Expected constant"
-#define TXT_EXPECTED_DATA_TYPE            "Expected data type"
-#define TXT_EXPECTED_EXPRESSION_VALUE     "Expected expression value"
-#define TXT_EXPECTED_IDENTIFIER           "Expected identifier"
-#define TXT_EXPECTED_LIST                 "Expected a list enclosed by { } to match pattern"
-#define TXT_EXPECTED_METHOD_OR_PROPERTY   "Expected method or property"
-#define TXT_EXPECTED_ONE_OF               "Expected one of: "
-#define TXT_EXPECTED_OPERATOR             "Expected operator"
-#define TXT_EXPECTED_s_OR_s               "Expected '%s' or '%s'"
-#define TXT_EXPECTED_POST_OPERATOR        "Expected post operator"
-#define TXT_EXPECTED_PRE_OPERATOR         "Expected pre operator"
-#define TXT_EXPECTED_STRING               "Expected string"
-#define TXT_EXPR_DOESNT_EVAL_TO_FUNC      "Expression doesn't evaluate to a function"
-#define TXT_EXPR_MUST_BE_BOOL             "Expression must be of boolean type"
+#define TXT_ELSE_WITH_EMPTY_STATEMENT         "Else with empty statement"
+#define TXT_EMPTY_LIST_ELEMENT_IS_NOT_ALLOWED "Empty list element is not allowed"
+#define TXT_EMPTY_SWITCH                      "Empty switch statement"
+#define TXT_EXPECTED_s                        "Expected '%s'"
+#define TXT_EXPECTED_CONSTANT                 "Expected constant"
+#define TXT_EXPECTED_DATA_TYPE                "Expected data type"
+#define TXT_EXPECTED_EXPRESSION_VALUE         "Expected expression value"
+#define TXT_EXPECTED_IDENTIFIER               "Expected identifier"
+#define TXT_EXPECTED_LIST                     "Expected a list enclosed by { } to match pattern"
+#define TXT_EXPECTED_METHOD_OR_PROPERTY       "Expected method or property"
+#define TXT_EXPECTED_ONE_OF                   "Expected one of: "
+#define TXT_EXPECTED_OPERATOR                 "Expected operator"
+#define TXT_EXPECTED_s_OR_s                   "Expected '%s' or '%s'"
+#define TXT_EXPECTED_POST_OPERATOR            "Expected post operator"
+#define TXT_EXPECTED_PRE_OPERATOR             "Expected pre operator"
+#define TXT_EXPECTED_STRING                   "Expected string"
+#define TXT_EXPR_DOESNT_EVAL_TO_FUNC          "Expression doesn't evaluate to a function"
+#define TXT_EXPR_MUST_BE_BOOL                 "Expression must be of boolean type"
 
 #define TXT_FAILED_TO_COMPILE_DEF_ARG_d_IN_FUNC_s "Failed while compiling default arg for parameter %d in function '%s'"
 #define TXT_FAILED_TO_CREATE_TEMP_OBJ             "Previous error occurred while attempting to create a temporary copy of object"
@@ -116,6 +119,7 @@
 #define TXT_HANDLE_ASSIGN_ON_NON_HANDLE_PROP     "It is not allowed to perform a handle assignment on a non-handle property"
 #define TXT_HANDLE_COMPARISON                    "The operand is implicitly converted to handle in order to compare them"
 #define TXT_HANDLE_OF_HANDLE_IS_NOT_ALLOWED      "Handle to handle is not allowed"
+#define TXT_s_HIDES_VAR_IN_OUTER_SCOPE           "Variable '%s' hides another variable of same name in outer scope"
 
 #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"
@@ -127,7 +131,9 @@
 #define TXT_ILLEGAL_OPERATION_ON_s                 "Illegal operation on '%s'"
 #define TXT_ILLEGAL_TARGET_TYPE_FOR_REF_CAST       "Illegal target type for reference cast"
 #define TXT_ILLEGAL_VARIABLE_NAME_s                "Illegal variable name '%s'."
+#define TXT_INHERITED_PRIVATE_PROP_ACCESS_s        "Illegal access to inherited private property '%s'"
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s        "Initialization lists cannot be used with '%s'"
+#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s         "Attempting to instantiate invalid template type '%s<%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"
@@ -135,7 +141,7 @@
 #define TXT_INVALID_CHAR_LITERAL                   "Invalid character literal"
 #define TXT_INVALID_CONTINUE                       "Invalid 'continue'"
 #define TXT_INVALID_ESCAPE_SEQUENCE                "Invalid escape sequence"
-#define TXT_INVALID_EXPRESSION_AMBIGUOUS_NAME     "Invalid expression: ambiguous name"
+#define TXT_INVALID_EXPRESSION_AMBIGUOUS_NAME      "Invalid expression: ambiguous name"
 #define TXT_INVALID_OP_ON_METHOD                   "Invalid operation on method"
 #define TXT_INVALID_REF_PROP_ACCESS                "Invalid reference. Property accessors cannot be used in combined read/write operations"
 #define TXT_INVALID_SCOPE                          "Invalid scope resolution"
@@ -147,6 +153,7 @@
 #define TXT_METHOD_CANNOT_OVERRIDE_s                "Method '%s' declared as final and cannot be overridden"
 #define TXT_METHOD_CANT_HAVE_NAME_OF_CLASS          "The method cannot be named with the class name"
 #define TXT_METHOD_s_DOES_NOT_OVERRIDE              "Method '%s' marked as override but does not replace any base class or interface method"
+#define TXT_METHOD_s_s_HAS_NO_RETURN_TYPE           "Method '%s::%s' is missing the return type, nor is it the same name as object to be a constructor"
 #define TXT_MISSING_IMPLEMENTATION_OF_s             "Missing implementation of '%s'"
 #define TXT_MIXIN_CANNOT_BE_DECLARED_AS_s           "Mixin class cannot be declared as '%s'"
 #define TXT_MIXIN_CANNOT_HAVE_CONSTRUCTOR           "Mixin classes cannot have constructors or destructors"
@@ -196,18 +203,22 @@
 #define TXT_NOT_VALID_LVALUE                       "Not a valid lvalue"
 #define TXT_NOTHING_WAS_BUILT                      "Nothing was built in the module"
 
-#define TXT_OBJECT_DOESNT_SUPPORT_INDEX_OP "Type '%s' doesn't support the indexing operator"
-#define TXT_OBJECT_HANDLE_NOT_SUPPORTED    "Object handle is not supported for this type"
-#define TXT_ONLY_OBJECTS_MAY_USE_REF_INOUT "Only object types that support object handles can use &inout. Use &in or &out instead"
-#define TXT_ONLY_ONE_ARGUMENT_IN_CAST      "A cast operator has one argument"
-#define TXT_ONLY_ONE_FUNCTION_ALLOWED      "The code must contain one and only one function"
-#define TXT_ONLY_ONE_VARIABLE_ALLOWED      "The code must contain one and only one global variable"
-#define TXT_OPERANDS_MUST_BE_HANDLES       "Both operands must be handles when comparing identity"
+#define TXT_OBJECT_DOESNT_SUPPORT_INDEX_OP          "Type '%s' doesn't support the indexing operator"
+#define TXT_OBJECT_HANDLE_NOT_SUPPORTED             "Object handle is not supported for this type"
+#define TXT_ONLY_OBJECTS_MAY_USE_REF_INOUT          "Only object types that support object handles can use &inout. Use &in or &out instead"
+#define TXT_ONLY_ONE_ARGUMENT_IN_CAST               "A cast operator has one argument"
+#define TXT_ONLY_ONE_FUNCTION_ALLOWED               "The code must contain one and only one function"
+#define TXT_ONLY_ONE_VARIABLE_ALLOWED               "The code must contain one and only one global variable"
+#define TXT_OPERANDS_MUST_BE_HANDLES                "Both operands must be handles when comparing identity"
+#define TXT_OVERLOAD_CONFLICTS_DUE_TO_DEFAULT_ARGS  "The overloaded functions are identical on initial parameters without default arguments"
 
 #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 instantiated."
+#define TXT_POS_ARG_AFTER_NAMED_ARG               "Positional arguments cannot be passed after named arguments"
 #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_PROTECTED_METHOD_CALL_s               "Illegal call to protected method '%s'"
+#define TXT_PROTECTED_PROP_ACCESS_s               "Illegal access to protected property '%s'"
 #define TXT_PROPERTY_ACCESSOR_DISABLED            "Property accessors have been disabled by the application"
 #define TXT_PROPERTY_ACCESSOR_MUST_BE_IMPLEMENTED "Property accessor must be implemented"
 #define TXT_PROPERTY_CANT_BE_CONST                "Class properties cannot be declared as const"
@@ -215,6 +226,7 @@
 #define TXT_PROPERTY_HAS_NO_SET_ACCESSOR          "The property has no set accessor"
 #define TXT_PROPERTY_WITHOUT_ACCESSOR             "Virtual property must have at least one get or set accessor"
 
+#define TXT_REF_CANT_BE_TO_LOCAL_VAR            "Resulting reference cannot be returned. Returned references must not refer to local variables."
 #define TXT_REF_CANT_BE_RETURNED_DEFERRED_PARAM "Resulting reference cannot be returned. There are deferred arguments that may invalidate it."
 #define TXT_REF_CANT_BE_RETURNED_LOCAL_VARS     "Resulting reference cannot be returned. The expression uses objects that during cleanup may invalidate it."
 #define TXT_REF_IS_READ_ONLY                    "Reference is read-only"
@@ -240,6 +252,7 @@
 #define TXT_TOO_MANY_JUMP_LABELS               "The function has too many jump labels to handle. Split the function into smaller ones."
 #define TXT_TOO_MANY_VALUES_FOR_LIST           "Too many values to match pattern"
 #define TXT_TYPE_s_NOT_AVAILABLE_FOR_MODULE    "Type '%s' is not available for this module"
+#define TXT_TYPE_s_NOT_TEMPLATE                "Type '%s' is not a template type"
 
 #define TXT_UNEXPECTED_END_OF_FILE             "Unexpected end of file"
 #define TXT_UNEXPECTED_TOKEN_s                 "Unexpected token '%s'"
@@ -287,12 +300,12 @@
 #define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s               "Object {%d}. GC cannot destroy an object of type '%s' as it doesn't know how many references to there are."
 #define TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s_REF_COUNT_d   "Object {%d}. GC cannot destroy an object of type '%s' as it can't see all references. Current ref count is %d."
 #define TXT_OBJECT_TYPE_s_DOESNT_EXIST                   "Object type '%s' doesn't exist"
+#define TXT_TEMPLATE_s_ALREADY_GENERATED_CANT_REGISTER   "Cannot register. The template type instance '%s' has already been generated."
 #define TXT_TEMPLATE_TYPE_s_DOESNT_EXIST                 "Template type '%s' doesn't exist"
 #define TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST              "Template subtype '%s' doesn't exist"
 #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 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)"
@@ -305,6 +318,8 @@
 #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"
+#define TXT_MODULE_IS_IN_USE                             "The module is still in use and cannot be rebuilt. Discard it and request another module"
+#define TXT_EXTRNL_REF_TO_MODULE_s                       "There is an external reference to an object in module '%s', preventing it from being deleted"
 
 // Internal names
 

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

@@ -171,6 +171,7 @@ enum eTokenType
 	ttEnum,                // enum
 	ttCast,                // cast
 	ttPrivate,             // private
+	ttProtected,           // protected
 	ttNamespace,           // namespace
 	ttMixin,               // mixin
 	ttAuto                 // auto
@@ -279,6 +280,7 @@ sTokenWord const tokenWords[] =
 	asTokenDef("or"        , ttOr),
 	asTokenDef("out"       , ttOut),
 	asTokenDef("private"   , ttPrivate),
+	asTokenDef("protected" , ttProtected),
 	asTokenDef("return"    , ttReturn),
 	asTokenDef("switch"    , ttSwitch),
 	asTokenDef("true"      , ttTrue),

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -54,6 +54,7 @@ asCTypeInfo::asCTypeInfo()
 	qwordValue            = 0;
 	isLValue              = false;
 	isVoidExpression      = false;
+	isRefToLocal          = false;
 }
 
 void asCTypeInfo::Set(const asCDataType &dt)
@@ -68,6 +69,7 @@ void asCTypeInfo::Set(const asCDataType &dt)
 	qwordValue       = 0;
 	isLValue         = false;
 	isVoidExpression = false;
+	isRefToLocal     = false;
 }
 
 void asCTypeInfo::SetVariable(const asCDataType &dt, int stackOffset, bool isTemporary)

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

@@ -1,6 +1,6 @@
 /*
    AngelCode Scripting Library
-   Copyright (c) 2003-2013 Andreas Jonsson
+   Copyright (c) 2003-2014 Andreas Jonsson
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
@@ -74,7 +74,8 @@ struct asCTypeInfo
 	bool  isVariable       :  1;
 	bool  isExplicitHandle :  1;
 	bool  isVoidExpression :  1;
-	short dummy            : 10;
+	bool  isRefToLocal     :  1; // The reference may be to a local variable
+	short dummy            :  9;
 	short stackOffset;
 	union
 	{

+ 4 - 4
Source/Urho3D/AngelScript/APITemplates.h

@@ -218,11 +218,11 @@ template <class T, class U> void RegisterSubclass(asIScriptEngine* engine, const
     if (!strcmp(classNameT, classNameU))
         return;
 
-    String declReturnT(String(classNameT) + "@+ f()");
-    String declReturnU(String(classNameU) + "@+ f()");
+    String declReturnT(String(classNameT) + "@+ opImplCast()");
+    String declReturnU(String(classNameU) + "@+ opImplCast()");
 
-    engine->RegisterObjectBehaviour(classNameT, asBEHAVE_IMPLICIT_REF_CAST, declReturnU.CString(), asFUNCTION((RefCast<T, U>)), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour(classNameU, asBEHAVE_IMPLICIT_REF_CAST, declReturnT.CString(), asFUNCTION((RefCast<U, T>)), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(classNameT, declReturnU.CString(), asFUNCTION((RefCast<T, U>)), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(classNameU, declReturnT.CString(), asFUNCTION((RefCast<U, T>)), asCALL_CDECL_OBJLAST);
 }
 
 /// Template function for writing to a serializer from an array.

+ 8 - 6
Source/Urho3D/AngelScript/Addons.cpp

@@ -2081,8 +2081,10 @@ bool CScriptDictValue::Get(asIScriptEngine *engine, void *value, int typeId) con
     {
         // A handle can be retrieved if the stored type is a handle of same or compatible type
         // or if the stored type is an object that implements the interface that the handle refer to.
-        if( (m_typeId & asTYPEID_MASK_OBJECT) &&
-            engine->IsHandleCompatibleWithObject(m_valueObj, m_typeId, typeId) )
+		
+		void* cast = 0x0;
+		if ((m_typeId & asTYPEID_MASK_OBJECT) &&
+			engine->RefCastObject(m_valueObj, engine->GetObjectTypeById(m_typeId), engine->GetObjectTypeById(typeId), &cast) >= 0)
         {
             engine->AddRefScriptObject(m_valueObj, engine->GetObjectTypeById(m_typeId));
             *(void**)value = m_valueObj;
@@ -2216,10 +2218,10 @@ void RegisterDictionary(asIScriptEngine *engine)
     engine->RegisterObjectMethod("DictionaryValue", "DictionaryValue &opAssign(const ?&in)", asFUNCTIONPR(CScriptDictValue_opAssign, (void *, int, CScriptDictValue*), CScriptDictValue &), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("DictionaryValue", "DictionaryValue &opAssign(double)", asFUNCTIONPR(CScriptDictValue_opAssign, (double, CScriptDictValue*), CScriptDictValue &), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("DictionaryValue", "DictionaryValue &opAssign(int64)", asFUNCTIONPR(CScriptDictValue_opAssign, (asINT64, CScriptDictValue*), CScriptDictValue &), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("DictionaryValue", asBEHAVE_REF_CAST, "void opCast(?&out)", asFUNCTIONPR(CScriptDictValue_opCast, (void *, int, CScriptDictValue*), void), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("DictionaryValue", asBEHAVE_VALUE_CAST, "void opConv(?&out)", asFUNCTIONPR(CScriptDictValue_opCast, (void *, int, CScriptDictValue*), void), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("DictionaryValue", asBEHAVE_VALUE_CAST, "int64 opConv()", asFUNCTIONPR(CScriptDictValue_opConvInt, (CScriptDictValue*), asINT64), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("DictionaryValue", asBEHAVE_VALUE_CAST, "double opConv()", asFUNCTIONPR(CScriptDictValue_opConvDouble, (CScriptDictValue*), double), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("DictionaryValue", "void opCast(?&out)", asFUNCTIONPR(CScriptDictValue_opCast, (void *, int, CScriptDictValue*), void), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("DictionaryValue", "void opConv(?&out)", asFUNCTIONPR(CScriptDictValue_opCast, (void *, int, CScriptDictValue*), void), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("DictionaryValue", "int64 opConv()", asFUNCTIONPR(CScriptDictValue_opConvInt, (CScriptDictValue*), asINT64), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("DictionaryValue", "double opConv()", asFUNCTIONPR(CScriptDictValue_opConvDouble, (CScriptDictValue*), double), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectType("Dictionary", sizeof(CScriptDictionary), asOBJ_REF);
     engine->RegisterObjectBehaviour("Dictionary", asBEHAVE_FACTORY, "Dictionary@ f()", asFUNCTION(ScriptDictionaryFactory_Generic), asCALL_GENERIC);
     engine->RegisterObjectBehaviour("Dictionary", asBEHAVE_LIST_FACTORY, "Dictionary @f(int &in) {repeat {String, ?}}", asFUNCTION(ScriptDictionaryListFactory_Generic), asCALL_GENERIC);

+ 2 - 2
Source/Urho3D/AngelScript/ScriptFile.cpp

@@ -575,7 +575,7 @@ bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source)
     unsigned pos = 0;
     while (pos < dataSize)
     {
-        int len;
+        unsigned len;
         asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len);
         if (t == asTC_COMMENT || t == asTC_WHITESPACE)
         {
@@ -632,7 +632,7 @@ bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source)
         // Don't search includes within statement blocks or between tokens in statements
         else
         {
-            int len;
+            unsigned len;
             // Skip until ; or { whichever comes first
             while (pos < dataSize && buffer[pos] != ';' && buffer[pos] != '{')
             {

部分文件因为文件数量过多而无法显示