Browse Source

Migrated to AngelScript 2.21.0.
Removed manual invocation of AngelScript garbage collection.

Lasse Öörni 14 years ago
parent
commit
40caea422e
38 changed files with 1105 additions and 454 deletions
  1. 1 1
      Docs/Urho3D.dox
  2. 0 6
      Engine/Engine/Engine.cpp
  3. 0 1
      Engine/Engine/ScriptAPI.cpp
  4. 2 2
      Engine/Script/Addons.cpp
  5. 0 10
      Engine/Script/Script.cpp
  6. 0 2
      Engine/Script/Script.h
  7. 0 3
      Engine/Script/ScriptFile.cpp
  8. 1 1
      Readme.txt
  9. 38 34
      ThirdParty/AngelScript/include/angelscript.h
  10. 2 2
      ThirdParty/AngelScript/source/as_atomic.cpp
  11. 32 20
      ThirdParty/AngelScript/source/as_builder.cpp
  12. 16 0
      ThirdParty/AngelScript/source/as_bytecode.cpp
  13. 1 0
      ThirdParty/AngelScript/source/as_bytecode.h
  14. 1 1
      ThirdParty/AngelScript/source/as_callfunc.cpp
  15. 2 2
      ThirdParty/AngelScript/source/as_callfunc_ppc_64.cpp
  16. 2 1
      ThirdParty/AngelScript/source/as_callfunc_x64_msvc.cpp
  17. 208 0
      ThirdParty/AngelScript/source/as_callfunc_x64_msvc_asm.asm
  18. 40 63
      ThirdParty/AngelScript/source/as_compiler.cpp
  19. 2 3
      ThirdParty/AngelScript/source/as_compiler.h
  20. 64 4
      ThirdParty/AngelScript/source/as_config.h
  21. 67 9
      ThirdParty/AngelScript/source/as_context.cpp
  22. 6 5
      ThirdParty/AngelScript/source/as_context.h
  23. 11 4
      ThirdParty/AngelScript/source/as_criticalsection.h
  24. 361 143
      ThirdParty/AngelScript/source/as_gc.cpp
  25. 24 12
      ThirdParty/AngelScript/source/as_gc.h
  26. 43 37
      ThirdParty/AngelScript/source/as_module.cpp
  27. 14 14
      ThirdParty/AngelScript/source/as_module.h
  28. 34 32
      ThirdParty/AngelScript/source/as_objecttype.cpp
  29. 11 11
      ThirdParty/AngelScript/source/as_objecttype.h
  30. 14 2
      ThirdParty/AngelScript/source/as_parser.cpp
  31. 16 3
      ThirdParty/AngelScript/source/as_restore.cpp
  32. 18 2
      ThirdParty/AngelScript/source/as_scriptengine.cpp
  33. 4 2
      ThirdParty/AngelScript/source/as_scriptengine.h
  34. 46 13
      ThirdParty/AngelScript/source/as_scriptfunction.cpp
  35. 5 3
      ThirdParty/AngelScript/source/as_scriptfunction.h
  36. 6 1
      ThirdParty/AngelScript/source/as_scriptobject.cpp
  37. 1 4
      ThirdParty/AngelScript/source/as_texts.h
  38. 12 1
      ThirdParty/AngelScript/source/as_thread.cpp

+ 1 - 1
Docs/Urho3D.dox

@@ -56,7 +56,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
 
 
-- AngelScript 2.21.0 WIP (http://www.angelcode.com/angelscript/)
+- AngelScript 2.21.0 (http://www.angelcode.com/angelscript/)
 - ENet 1.3.1 (http://enet.bespin.org/)
 - ENet 1.3.1 (http://enet.bespin.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - GLee 5.4 (http://elf-stone.com/)
 - GLee 5.4 (http://elf-stone.com/)

+ 0 - 6
Engine/Engine/Engine.cpp

@@ -253,12 +253,6 @@ void Engine::RunFrame()
     time->BeginFrame(timeStep_);
     time->BeginFrame(timeStep_);
     
     
     Render();
     Render();
-    
-    // If scripting initialized, garbage collect before getting the next time step
-    Script* script = GetSubsystem<Script>();
-    if (script)
-        script->GarbageCollect(false);
-    
     GetNextTimeStep();
     GetNextTimeStep();
     
     
     time->EndFrame();
     time->EndFrame();

+ 0 - 1
Engine/Engine/ScriptAPI.cpp

@@ -292,7 +292,6 @@ static void RegisterScript(asIScriptEngine* engine)
 {
 {
     RegisterObject<Script>(engine, "Script");
     RegisterObject<Script>(engine, "Script");
     engine->RegisterObjectMethod("Script", "bool Execute(const String&in)", asMETHOD(Script, Execute), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "bool Execute(const String&in)", asMETHOD(Script, Execute), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Script", "void GarbageCollect(bool)", asMETHOD(Script, GarbageCollect), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "void DumpAPI()", asMETHOD(Script, DumpAPI), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "void DumpAPI()", asMETHOD(Script, DumpAPI), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "void set_defaultScriptFile(ScriptFile@+)", asMETHOD(Script, SetDefaultScriptFile), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "void set_defaultScriptFile(ScriptFile@+)", asMETHOD(Script, SetDefaultScriptFile), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "ScriptFile@+ get_defaultScriptFile() const", asMETHOD(Script, GetDefaultScriptFile), asCALL_THISCALL);
     engine->RegisterObjectMethod("Script", "ScriptFile@+ get_defaultScriptFile() const", asMETHOD(Script, GetDefaultScriptFile), asCALL_THISCALL);

+ 2 - 2
Engine/Script/Addons.cpp

@@ -89,7 +89,7 @@ static bool ScriptArrayTemplateCallback(asIObjectType* ot)
         if ((flags & asOBJ_VALUE) && !(flags & asOBJ_POD))
         if ((flags & asOBJ_VALUE) && !(flags & asOBJ_POD))
         {
         {
             // Verify that there is a default constructor
             // Verify that there is a default constructor
-            for (int n = 0; n < subtype->GetBehaviourCount(); ++n)
+            for (unsigned n = 0; n < subtype->GetBehaviourCount(); ++n)
             {
             {
                 asEBehaviours beh;
                 asEBehaviours beh;
                 int funcId = subtype->GetBehaviourByIndex(n, &beh);
                 int funcId = subtype->GetBehaviourByIndex(n, &beh);
@@ -110,7 +110,7 @@ static bool ScriptArrayTemplateCallback(asIObjectType* ot)
         else if ((flags & asOBJ_REF))
         else if ((flags & asOBJ_REF))
         {
         {
             // Verify that there is a default factory
             // Verify that there is a default factory
-            for (int n = 0; n < subtype->GetFactoryCount(); ++n)
+            for (unsigned n = 0; n < subtype->GetFactoryCount(); ++n)
             {
             {
                 int funcId = subtype->GetFactoryIdByIndex(n);
                 int funcId = subtype->GetFactoryIdByIndex(n);
                 asIScriptFunction* func = ot->GetEngine()->GetFunctionDescriptorById(funcId);
                 asIScriptFunction* func = ot->GetEngine()->GetFunctionDescriptorById(funcId);

+ 0 - 10
Engine/Script/Script.cpp

@@ -184,16 +184,6 @@ bool Script::Execute(const String& line)
     return success;
     return success;
 }
 }
 
 
-void Script::GarbageCollect(bool fullCycle)
-{
-    PROFILE(GarbageCollect);
-    
-    if (fullCycle)
-        scriptEngine_->GarbageCollect(asGC_FULL_CYCLE);
-    else
-        scriptEngine_->GarbageCollect(asGC_ONE_STEP);
-}
-
 void Script::SetDefaultScriptFile(ScriptFile* file)
 void Script::SetDefaultScriptFile(ScriptFile* file)
 {
 {
     defaultScriptFile_ = file;
     defaultScriptFile_ = file;

+ 0 - 2
Engine/Script/Script.h

@@ -58,8 +58,6 @@ public:
     
     
     /// Compile and execute a line of script in immediate mode
     /// Compile and execute a line of script in immediate mode
     bool Execute(const String& line);
     bool Execute(const String& line);
-    /// Perform garbage collection
-    void GarbageCollect(bool fullCycle);
     /// Set immediate mode script file
     /// Set immediate mode script file
     void SetDefaultScriptFile(ScriptFile* file);
     void SetDefaultScriptFile(ScriptFile* file);
     /// Set immediate mode scene
     /// Set immediate mode scene

+ 0 - 3
Engine/Script/ScriptFile.cpp

@@ -520,9 +520,6 @@ void ScriptFile::ReleaseModule()
         methods_.Clear();
         methods_.Clear();
         UnsubscribeFromAllEventsWithUserData();
         UnsubscribeFromAllEventsWithUserData();
         
         
-        // Perform a full garbage collection cycle now
-        script_->GarbageCollect(true);
-        
         // Remove the module
         // Remove the module
         script_->GetModuleMap().Erase(scriptModule_);
         script_->GetModuleMap().Erase(scriptModule_);
         asIScriptEngine* engine = script_->GetScriptEngine();
         asIScriptEngine* engine = script_->GetScriptEngine();

+ 1 - 1
Readme.txt

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

+ 38 - 34
ThirdParty/AngelScript/include/angelscript.h

@@ -90,7 +90,8 @@ enum asEEngineProp
 	asEP_INCLUDE_JIT_INSTRUCTIONS     = 12,
 	asEP_INCLUDE_JIT_INSTRUCTIONS     = 12,
 	asEP_STRING_ENCODING              = 13,
 	asEP_STRING_ENCODING              = 13,
 	asEP_PROPERTY_ACCESSOR_MODE       = 14,
 	asEP_PROPERTY_ACCESSOR_MODE       = 14,
-	asEP_EXPAND_DEF_ARRAY_TO_TMPL     = 15
+	asEP_EXPAND_DEF_ARRAY_TO_TMPL     = 15,
+	asEP_AUTO_GARBAGE_COLLECT         = 16
 };
 };
 
 
 // Calling conventions
 // Calling conventions
@@ -568,7 +569,7 @@ public:
 
 
 	// Garbage collection
 	// Garbage collection
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE) = 0;
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE) = 0;
-	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed = 0, asUINT *totalDetected = 0) const = 0;
+	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed = 0, asUINT *totalDetected = 0, asUINT *newObjects = 0, asUINT *totalNewDestroyed = 0) const = 0;
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId) = 0;
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId) = 0;
 	virtual void GCEnumCallback(void *reference) = 0;
 	virtual void GCEnumCallback(void *reference) = 0;
 
 
@@ -591,23 +592,23 @@ public:
 	virtual const char      *GetName() const = 0;
 	virtual const char      *GetName() const = 0;
 
 
 	// Compilation
 	// Compilation
-    virtual int  AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
+	virtual int  AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
 	virtual int  Build() = 0;
 	virtual int  Build() = 0;
 	virtual int  CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
 	virtual int  CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
 	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
 	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
 
 
 	// Functions
 	// Functions
-	virtual int                GetFunctionCount() const = 0;
-	virtual int                GetFunctionIdByIndex(int index) const = 0;
+	virtual asUINT             GetFunctionCount() const = 0;
+	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
-	virtual asIScriptFunction *GetFunctionDescriptorByIndex(int index) const = 0;
+	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
 	virtual int                RemoveFunction(int funcId) = 0;
 	virtual int                RemoveFunction(int funcId) = 0;
 
 
 	// Global variables
 	// Global variables
-	virtual int         ResetGlobalVars() = 0;
-	virtual int         GetGlobalVarCount() const = 0;
+	virtual int         ResetGlobalVars(asIScriptContext *ctx = 0) = 0;
+	virtual asUINT      GetGlobalVarCount() const = 0;
 	virtual int         GetGlobalVarIndexByName(const char *name) const = 0;
 	virtual int         GetGlobalVarIndexByName(const char *name) const = 0;
 	virtual int         GetGlobalVarIndexByDecl(const char *decl) const = 0;
 	virtual int         GetGlobalVarIndexByDecl(const char *decl) const = 0;
 	virtual const char *GetGlobalVarDeclaration(asUINT index) const = 0;
 	virtual const char *GetGlobalVarDeclaration(asUINT index) const = 0;
@@ -616,27 +617,27 @@ public:
 	virtual int         RemoveGlobalVar(asUINT index) = 0;
 	virtual int         RemoveGlobalVar(asUINT index) = 0;
 
 
 	// Type identification
 	// Type identification
-	virtual int            GetObjectTypeCount() const = 0;
+	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual int            GetTypeIdByDecl(const char *decl) const = 0;
 	virtual int            GetTypeIdByDecl(const char *decl) const = 0;
 
 
 	// Enums
 	// Enums
-	virtual int         GetEnumCount() const = 0;
+	virtual asUINT      GetEnumCount() const = 0;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId) const = 0;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId) const = 0;
 	virtual int         GetEnumValueCount(int enumTypeId) const = 0;
 	virtual int         GetEnumValueCount(int enumTypeId) const = 0;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const = 0;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const = 0;
 
 
 	// Typedefs
 	// Typedefs
-	virtual int         GetTypedefCount() const = 0;
+	virtual asUINT      GetTypedefCount() const = 0;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId) const = 0;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId) const = 0;
 
 
 	// Dynamic binding between modules
 	// Dynamic binding between modules
-	virtual int         GetImportedFunctionCount() const = 0;
+	virtual asUINT      GetImportedFunctionCount() const = 0;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const = 0;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const = 0;
-	virtual const char *GetImportedFunctionDeclaration(int importIndex) const = 0;
-	virtual const char *GetImportedFunctionSourceModule(int importIndex) const = 0;
-	virtual int         BindImportedFunction(int importIndex, int funcId) = 0;
-	virtual int         UnbindImportedFunction(int importIndex) = 0;
+	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const = 0;
+	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const = 0;
+	virtual int         BindImportedFunction(asUINT importIndex, int funcId) = 0;
+	virtual int         UnbindImportedFunction(asUINT importIndex) = 0;
 	virtual int         BindAllImportedFunctions() = 0;
 	virtual int         BindAllImportedFunctions() = 0;
 	virtual int         UnbindAllImportedFunctions() = 0;
 	virtual int         UnbindAllImportedFunctions() = 0;
 
 
@@ -704,10 +705,11 @@ public:
 	virtual asIScriptFunction *GetFunction(asUINT stackLevel = 0) = 0;
 	virtual asIScriptFunction *GetFunction(asUINT stackLevel = 0) = 0;
 	virtual int                GetLineNumber(asUINT stackLevel = 0, int *column = 0, const char **sectionName = 0) = 0;
 	virtual int                GetLineNumber(asUINT stackLevel = 0, int *column = 0, const char **sectionName = 0) = 0;
 	virtual int                GetVarCount(asUINT stackLevel = 0) = 0;
 	virtual int                GetVarCount(asUINT stackLevel = 0) = 0;
-	virtual const char        *GetVarName(int varIndex, asUINT stackLevel = 0) = 0;
-	virtual const char        *GetVarDeclaration(int varIndex, asUINT stackLevel = 0) = 0;
-	virtual int                GetVarTypeId(int varIndex, asUINT stackLevel = 0) = 0;
-	virtual void              *GetAddressOfVar(int varIndex, asUINT stackLevel = 0) = 0;
+	virtual const char        *GetVarName(asUINT varIndex, asUINT stackLevel = 0) = 0;
+	virtual const char        *GetVarDeclaration(asUINT varIndex, asUINT stackLevel = 0) = 0;
+	virtual int                GetVarTypeId(asUINT varIndex, asUINT stackLevel = 0) = 0;
+	virtual void              *GetAddressOfVar(asUINT varIndex, asUINT stackLevel = 0) = 0;
+	virtual bool               IsVarInScope(asUINT varIndex, asUINT stackLevel = 0) = 0;
 	virtual int                GetThisTypeId(asUINT stackLevel = 0) = 0;
 	virtual int                GetThisTypeId(asUINT stackLevel = 0) = 0;
 	virtual void              *GetThisPointer(asUINT stackLevel = 0) = 0;
 	virtual void              *GetThisPointer(asUINT stackLevel = 0) = 0;
 
 
@@ -804,29 +806,29 @@ public:
 	virtual int              GetSubTypeId() const = 0;
 	virtual int              GetSubTypeId() const = 0;
 
 
 	// Interfaces
 	// Interfaces
-	virtual int              GetInterfaceCount() const = 0;
+	virtual asUINT           GetInterfaceCount() const = 0;
 	virtual asIObjectType   *GetInterface(asUINT index) const = 0;
 	virtual asIObjectType   *GetInterface(asUINT index) const = 0;
 
 
 	// Factories
 	// Factories
-	virtual int                GetFactoryCount() const = 0;
-	virtual int                GetFactoryIdByIndex(int index) const = 0;
+	virtual asUINT             GetFactoryCount() const = 0;
+	virtual int                GetFactoryIdByIndex(asUINT index) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
 
 
 	// Methods
 	// Methods
-	virtual int                GetMethodCount() const = 0;
-	virtual int                GetMethodIdByIndex(int index, bool getVirtual = true) const = 0;
+	virtual asUINT             GetMethodCount() const = 0;
+	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
-	virtual asIScriptFunction *GetMethodDescriptorByIndex(int index, bool getVirtual = true) const = 0;
+	virtual asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual = true) const = 0;
 
 
 	// Properties
 	// Properties
-	virtual int         GetPropertyCount() const = 0;
-	virtual int         GetProperty(asUINT index, const char **name, int *typeId = 0, bool *isPrivate = 0, int *offset = 0) const = 0;
+	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) const = 0;
 	virtual const char *GetPropertyDeclaration(asUINT index) const = 0;
 	virtual const char *GetPropertyDeclaration(asUINT index) const = 0;
 
 
 	// Behaviours
 	// Behaviours
-	virtual int GetBehaviourCount() const = 0;
-	virtual int GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
+	virtual asUINT GetBehaviourCount() const = 0;
+	virtual int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
 
 
 protected:
 protected:
 	virtual ~asIObjectType() {}
 	virtual ~asIObjectType() {}
@@ -853,14 +855,15 @@ public:
 	virtual bool             IsReadOnly() const = 0;
 	virtual bool             IsReadOnly() const = 0;
 	virtual bool             IsPrivate() const = 0;
 	virtual bool             IsPrivate() const = 0;
 
 
-	virtual int              GetParamCount() const = 0;
-	virtual int              GetParamTypeId(int index, asDWORD *flags = 0) const = 0;
+	virtual asUINT           GetParamCount() const = 0;
+	virtual int              GetParamTypeId(asUINT index, asDWORD *flags = 0) const = 0;
 	virtual int              GetReturnTypeId() const = 0;
 	virtual int              GetReturnTypeId() const = 0;
 
 
 	// Debug information
 	// Debug information
-	virtual int              GetVarCount() const = 0;
+	virtual asUINT           GetVarCount() const = 0;
 	virtual int              GetVar(asUINT index, const char **name, int *typeId = 0) const = 0;
 	virtual int              GetVar(asUINT index, const char **name, int *typeId = 0) const = 0;
 	virtual const char *     GetVarDecl(asUINT index) const = 0;
 	virtual const char *     GetVarDecl(asUINT index) const = 0;
+	virtual int              FindNextLineWithCode(int line) const = 0;
 
 
 	// For JIT compilation
 	// For JIT compilation
 	virtual asDWORD         *GetByteCode(asUINT *length = 0) = 0;
 	virtual asDWORD         *GetByteCode(asUINT *length = 0) = 0;
@@ -1272,6 +1275,7 @@ enum asEBCInstr
 	asBC_MAXBYTECODE	= 186,
 	asBC_MAXBYTECODE	= 186,
 
 
 	// Temporary tokens. Can't be output to the final program
 	// Temporary tokens. Can't be output to the final program
+	asBC_VarDecl        = 251,
 	asBC_Block          = 252,
 	asBC_Block          = 252,
 	asBC_ObjInfo		= 253,
 	asBC_ObjInfo		= 253,
 	asBC_LINE			= 254,
 	asBC_LINE			= 254,
@@ -1612,8 +1616,8 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO_DUMMY(248),
 	asBCINFO_DUMMY(248),
 	asBCINFO_DUMMY(249),
 	asBCINFO_DUMMY(249),
 	asBCINFO_DUMMY(250),
 	asBCINFO_DUMMY(250),
-	asBCINFO_DUMMY(251),
 
 
+	asBCINFO(VarDecl,   W_ARG,          0),
 	asBCINFO(Block,     INFO,           0),
 	asBCINFO(Block,     INFO,           0),
 	asBCINFO(ObjInfo,	rW_DW_ARG,		0),
 	asBCINFO(ObjInfo,	rW_DW_ARG,		0),
 	asBCINFO(LINE,		INFO,			0),
 	asBCINFO(LINE,		INFO,			0),

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -122,7 +122,7 @@ asDWORD asCAtomic::atomicDec()
 	return InterlockedDecrement((LONG*)&value);
 	return InterlockedDecrement((LONG*)&value);
 }
 }
 
 
-#elif defined(AS_LINUX) || defined(AS_BSD)
+#elif defined(AS_LINUX) || defined(AS_BSD) || defined(AS_ILLUMOS)
 
 
 //
 //
 // atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant 
 // atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant 

+ 32 - 20
ThirdParty/AngelScript/source/as_builder.cpp

@@ -1627,20 +1627,6 @@ void asCBuilder::CompileClasses()
 				else
 				else
 				{
 				{
 					decl->objType->interfaces.PushLast(objType);
 					decl->objType->interfaces.PushLast(objType);
-
-					// Make sure all the methods of the interface are implemented
-					for( asUINT i = 0; i < objType->methods.GetLength(); i++ )
-					{
-						if( !DoesMethodExist(decl->objType, objType->methods[i]) )
-						{
-							int r, c;
-							file->ConvertPosToRowCol(decl->node->tokenPos, &r, &c);
-							asCString str;
-							str.Format(TXT_MISSING_IMPLEMENTATION_OF_s,
-								engine->GetFunctionDeclaration(objType->methods[i]).AddressOf());
-							WriteError(file->name.AddressOf(), str.AddressOf(), r, c);
-						}
-					}
 				}
 				}
 			}
 			}
 
 
@@ -1802,6 +1788,29 @@ void asCBuilder::CompileClasses()
 		toValidate.PushLast(decl);
 		toValidate.PushLast(decl);
 	}
 	}
 
 
+	// Verify that all interface methods are implemented in the classes
+	// We do this here so the base class' methods have already been inherited 
+	for( n = 0; n < classDeclarations.GetLength(); n++ )
+	{
+		sClassDeclaration *decl = classDeclarations[n];
+		for( asUINT m = 0; m < decl->objType->interfaces.GetLength(); m++ )
+		{
+			asCObjectType *objType = decl->objType->interfaces[m];
+			for( asUINT i = 0; i < objType->methods.GetLength(); i++ )
+			{
+				if( !DoesMethodExist(decl->objType, objType->methods[i]) )
+				{
+					int r, c;
+					decl->script->ConvertPosToRowCol(decl->node->tokenPos, &r, &c);
+					asCString str;
+					str.Format(TXT_MISSING_IMPLEMENTATION_OF_s,
+						engine->GetFunctionDeclaration(objType->methods[i]).AddressOf());
+					WriteError(decl->script->name.AddressOf(), str.AddressOf(), r, c);
+				}
+			}
+		}
+	}
+
 	// Verify that the declared structures are valid, e.g. that the structure
 	// Verify that the declared structures are valid, e.g. that the structure
 	// doesn't contain a member of its own type directly or indirectly
 	// doesn't contain a member of its own type directly or indirectly
 	while( toValidate.GetLength() > 0 )
 	while( toValidate.GetLength() > 0 )
@@ -1890,8 +1899,6 @@ void asCBuilder::CompileClasses()
 
 
 	if( numErrors > 0 ) return;
 	if( numErrors > 0 ) return;
 
 
-	// TODO: The declarations form a graph, all circles in
-	//       the graph must be flagged as potential circles
 
 
 	// Urho3D: disable garbage collection from script classes
 	// Urho3D: disable garbage collection from script classes
 	/*
 	/*
@@ -1909,17 +1916,22 @@ void asCBuilder::CompileClasses()
 			{
 			{
 				if( dt.IsObjectHandle() )
 				if( dt.IsObjectHandle() )
 				{
 				{
-					// TODO: Can this handle really generate a circular reference?
-					//       Only if the handle is of a type that can reference this type, either directly or indirectly
+					// TODO: optimize: If it is known that the handle can't be involved in a circular reference
+					//                 then this object doesn't need to be marked as garbage collected. 
+					//                 - The application could set a flag when registering the object.
+					//                 - The script classes can be marked as final, then the compiler will 
+					//                   be able to determine whether the class is garbage collected or not.
 
 
 					ot->flags |= asOBJ_GC;
 					ot->flags |= asOBJ_GC;
+					break;
 				}
 				}
 				else if( dt.GetObjectType()->flags & asOBJ_GC )
 				else if( dt.GetObjectType()->flags & asOBJ_GC )
 				{
 				{
-					// TODO: Just because the member type is a potential circle doesn't mean that this one is
-					//       Only if the object is of a type that can reference this type, either directly or indirectly
+					// TODO: optimize: Just because the member type is a potential circle doesn't mean that this one is
+					//                 Only if the object is of a type that can reference this type, either directly or indirectly
 
 
 					ot->flags |= asOBJ_GC;
 					ot->flags |= asOBJ_GC;
+					break;
 				}
 				}
 			}
 			}
 		}
 		}

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

@@ -1261,6 +1261,10 @@ void asCByteCode::ExtractObjectVariableInfo(asCScriptFunction *outFunc)
 			info.option         = *(int*)ARG_DW(instr->arg);
 			info.option         = *(int*)ARG_DW(instr->arg);
 			outFunc->objVariableInfo.PushLast(info);
 			outFunc->objVariableInfo.PushLast(info);
 		}
 		}
+		else if( instr->op == asBC_VarDecl )
+		{
+			outFunc->variables[instr->wArg[0]]->declaredAtProgramPos = pos;
+		}
 		else
 		else
 			pos += instr->size;
 			pos += instr->size;
 
 
@@ -1473,6 +1477,18 @@ void asCByteCode::Block(bool start)
 	last->wArg[0]  = start ? 1 : 0;
 	last->wArg[0]  = start ? 1 : 0;
 }
 }
 
 
+void asCByteCode::VarDecl(int varDeclIdx)
+{
+	if( AddInstruction() < 0 )
+		return;
+
+	last->op       = asBC_VarDecl;
+	last->size     = 0;
+	last->stackInc = 0;
+	last->wArg[0]  = (asWORD)varDeclIdx;
+}
+
+
 int asCByteCode::FindLabel(int label, cByteInstruction *from, cByteInstruction **dest, int *positionDelta)
 int asCByteCode::FindLabel(int label, cByteInstruction *from, cByteInstruction **dest, int *positionDelta)
 {
 {
 	// Search forward
 	// Search forward

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

@@ -96,6 +96,7 @@ public:
 	void Line(int line, int column);
 	void Line(int line, int column);
 	void ObjInfo(int offset, int info);
 	void ObjInfo(int offset, int info);
 	void Block(bool start);
 	void Block(bool start);
+	void VarDecl(int varDeclIdx);
 	void Call(asEBCInstr bc, int funcID, int pop);
 	void Call(asEBCInstr bc, int funcID, int pop);
 	void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
 	void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
 	void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
 	void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);

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

@@ -161,7 +161,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 		else if( objType & asOBJ_APP_CLASS )
 		else if( objType & asOBJ_APP_CLASS )
 		{
 		{
 			internal->hostReturnFloat = false;
 			internal->hostReturnFloat = false;
-			if( objType & COMPLEX_MASK )
+			if( objType & COMPLEX_RETURN_MASK )
 			{
 			{
 				internal->hostReturnInMemory = true;
 				internal->hostReturnInMemory = true;
 				internal->hostReturnSize     = sizeof(void*)/4;
 				internal->hostReturnSize     = sizeof(void*)/4;

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

@@ -664,14 +664,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 		{
 		{
 			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
 			if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
 			{
 			{
-				#ifdef COMPLEX_OBJS_PASSED_BY_REF
+#ifdef COMPLEX_OBJS_PASSED_BY_REF
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
 				if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
 				{
 				{
 					paramBuffer[dpos++] = args[spos++];
 					paramBuffer[dpos++] = args[spos++];
 					++paramSize;
 					++paramSize;
 				}
 				}
 				else
 				else
-				#endif
+#endif
 				{
 				{
 					// NOTE: we may have to do endian flipping here
 					// NOTE: we may have to do endian flipping here
 
 

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

@@ -101,7 +101,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	{
 	{
 		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() )
 		{
 		{
-			if( descr->parameterTypes[n].GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE )
+			if( descr->parameterTypes[n].GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
+				(descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )
 			{
 			{
 				allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
 				allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
 				spos += AS_PTR_SIZE;
 				spos += AS_PTR_SIZE;

+ 208 - 0
ThirdParty/AngelScript/source/as_callfunc_x64_msvc_asm.asm

@@ -0,0 +1,208 @@
+;
+;  AngelCode Scripting Library
+;  Copyright (c) 2003-2011 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]
+;
+
+.code
+PUBLIC CallX64
+
+; asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int paramSize, asQWORD func)
+
+CallX64 PROC FRAME
+
+	; PROLOG
+
+	; We must save preserved registers that are used
+	; TODO: No need to save unused registers
+
+	push rbp
+.pushreg rbp
+	push rsi
+.pushreg rsi
+	push r11
+.pushreg r11
+	push rdi
+.pushreg rdi
+	push r12
+.pushreg r12
+	push r13
+.pushreg r13
+	push r14
+.pushreg r14
+	push r15
+.pushreg r15
+	push rbx
+.pushreg rbx
+	sub rsp, 050h
+.allocstack 050h
+	mov rbp, rsp
+.setframe rbp, 0
+.endprolog
+
+	; Move function param to non-scratch register
+	mov r14, r9		; r14 = function
+
+	; Allocate space on the stack for the arguments
+	; Make room for at least 4 arguments even if there are less. When
+    ; the compiler does optimizations for speed it may use these for 
+	; temporary storage.
+	mov rdi, r8
+	add rdi, 32
+
+	; Make sure the stack pointer is 16byte aligned so the
+	; whole program optimizations will work properly
+	; TODO: optimize: Can this be optimized with fewer instructions?
+	mov rsi, rsp
+	sub rsi, rdi
+	and rsi, 8h
+	add rdi, rsi	
+	sub rsp, rdi
+		
+	; Jump straight to calling the function if no parameters
+	cmp r8d, 0		; Compare paramSize with 0
+	je	callfunc	; Jump to call funtion if (paramSize == 0)
+
+	; Move params to non-scratch registers
+	mov rsi, rcx	; rsi = pArgs
+	mov r11, rdx	; r11 = pFloatArgs (can be NULL)
+	mov r12d, r8d	; r12 = paramSize
+	
+	; Copy arguments from script stack to application stack
+	; Order is (first to last):
+	; rcx, rdx, r8, r9 & everything else goes on stack
+	mov rcx, qword ptr [rsi]
+	mov rdx, qword ptr [rsi + 8]
+	mov r8,  qword ptr [rsi + 16]
+	mov r9,  qword ptr [rsi + 24]
+	
+	; Negate the 4 params from the size to be copied
+	sub r12d, 32
+	js  copyfloat	; Jump if negative result
+	jz	copyfloat	; Jump if zero result
+	
+	; Now copy all remaining params onto stack allowing space for first four
+	; params to be flushed back to the stack if required by the callee.
+	
+	add rsi, 32		; Position input pointer 4 args ahead
+	mov r13, rsp	; Put the stack pointer into r13
+	add r13, 32	 	; Leave space for first 4 args on stack
+
+copyoverflow:
+	mov r15, qword ptr [rsi]	; Read param from source stack into r15
+	mov qword ptr [r13], r15	; Copy param to real stack
+	add r13, 8					; Move virtual stack pointer
+	add rsi, 8					; Move source stack pointer
+	sub r12d, 8					; Decrement remaining count
+	jnz copyoverflow			; Continue if more params
+
+copyfloat:
+	; Any floating point params?
+	cmp r11, 0
+	je  callfunc
+	
+	movlpd xmm0, qword ptr [r11]
+	movlpd xmm1, qword ptr [r11 + 8]
+	movlpd xmm2, qword ptr [r11 + 16]
+	movlpd xmm3, qword ptr [r11 + 24]
+	
+callfunc:
+	
+	; Call function
+	call r14
+	
+	; Restore the stack
+	mov rsp, rbp
+		
+	; EPILOG: Restore stack & preserved registers
+	add rsp, 050h
+	pop rbx
+	pop r15
+	pop r14
+	pop r13
+	pop r12
+	pop rdi
+	pop r11
+	pop rsi
+	pop rbp
+
+	; return value in RAX
+	ret
+
+CallX64 ENDP
+
+
+PUBLIC GetReturnedFloat
+
+; asDWORD GetReturnedFloat()
+
+GetReturnedFloat PROC FRAME
+
+	; PROLOG: Store registers and allocate stack space
+	
+	sub rsp, 8   ; We'll need 4 bytes for temporary storage (8 bytes with alignment)
+.allocstack 8
+.endprolog
+
+	; Move the float value from the XMM0 register to RAX register
+	movss dword ptr [rsp], xmm0
+	mov   eax, dword ptr [rsp]
+	
+	; EPILOG: Clean up
+	
+	add rsp, 8
+
+	ret
+
+GetReturnedFloat ENDP
+
+
+PUBLIC GetReturnedDouble
+
+; asDWORD GetReturnedDouble()
+
+GetReturnedDouble PROC FRAME
+
+	; PROLOG: Store registers and allocate stack space
+	
+	sub rsp, 8	; We'll need 8 bytes for temporary storage
+.allocstack 8
+.endprolog
+
+	; Move the double value from the XMM0 register to the RAX register
+	movlpd qword ptr [rsp], xmm0
+	mov    rax, qword ptr [rsp]
+	
+	; EPILOG: Clean up
+	
+	add rsp, 8
+	
+	ret
+	
+GetReturnedDouble ENDP
+
+END

+ 40 - 63
ThirdParty/AngelScript/source/as_compiler.cpp

@@ -95,8 +95,6 @@ void asCCompiler::Reset(asCBuilder *builder, asCScriptCode *script, asCScriptFun
 	continueLabels.SetLength(0);
 	continueLabels.SetLength(0);
 
 
 	byteCode.ClearAll();
 	byteCode.ClearAll();
-
-	globalExpression = false;
 }
 }
 
 
 int asCCompiler::CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc)
 int asCCompiler::CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc)
@@ -282,6 +280,8 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 			if( vs.DeclareVariable(name.AddressOf(), type, stackPos, true) < 0 )
 			if( vs.DeclareVariable(name.AddressOf(), type, stackPos, true) < 0 )
 				Error(TXT_PARAMETER_ALREADY_DECLARED, node);
 				Error(TXT_PARAMETER_ALREADY_DECLARED, node);
 
 
+			// Add marker for variable declaration
+			byteCode.VarDecl((int)outFunc->variables.GetLength());
 			outFunc->AddVariable(name, type, stackPos);
 			outFunc->AddVariable(name, type, stackPos);
 
 
 			node = node->next;
 			node = node->next;
@@ -744,7 +744,6 @@ void asCCompiler::CompileStatementBlock(asCScriptNode *block, bool ownVariableSc
 int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc)
 int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc)
 {
 {
 	Reset(builder, script, outFunc);
 	Reset(builder, script, outFunc);
-	globalExpression = true;
 
 
 	// Add a variable scope (even though variables can't be declared)
 	// Add a variable scope (even though variables can't be declared)
 	AddVariableScope();
 	AddVariableScope();
@@ -1406,7 +1405,12 @@ void asCCompiler::MoveArgsToStack(int funcID, asCByteCode *bc, asCArray<asSExprC
 				{
 				{
 					// Send the object as a reference to the object, 
 					// Send the object as a reference to the object, 
 					// and not to the variable holding the object
 					// and not to the variable holding the object
-					bc->InstrWORD(asBC_GETOBJREF, (asWORD)offset);
+					if( !IsVariableOnHeap(args[n]->type.stackOffset) )
+						// TODO: optimize: Actually the reference can be pushed on the stack directly
+						//                 as the value allocated on the stack is guaranteed to be safe
+						bc->InstrWORD(asBC_GETREF, (asWORD)offset);
+					else
+						bc->InstrWORD(asBC_GETOBJREF, (asWORD)offset);
 				}
 				}
 				else
 				else
 					bc->InstrWORD(asBC_GETREF, (asWORD)offset);
 					bc->InstrWORD(asBC_GETREF, (asWORD)offset);
@@ -1710,6 +1714,8 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 			return;
 			return;
 		}
 		}
 
 
+		// Add marker that the variable has been declared
+		bc->VarDecl((int)outFunc->variables.GetLength());
 		outFunc->AddVariable(name, type, offset);
 		outFunc->AddVariable(name, type, offset);
 
 
 		// Keep the node for the variable decl
 		// Keep the node for the variable decl
@@ -3785,7 +3791,7 @@ bool asCCompiler::CompileRefCast(asSExprContext *ctx, const asCDataType &to, boo
 
 
 #ifdef AS_64BIT_PTR
 #ifdef AS_64BIT_PTR
 				int offset = AllocateVariable(asCDataType::CreatePrimitive(ttUInt64, false), true);
 				int offset = AllocateVariable(asCDataType::CreatePrimitive(ttUInt64, false), true);
-				ctx->bc.InstrW_QW(asBC_SetV8, offset, 0);
+				ctx->bc.InstrW_QW(asBC_SetV8, (asWORD)offset, 0);
 				ctx->bc.InstrW_W(asBC_CMPi64, ctx->type.stackOffset, offset);
 				ctx->bc.InstrW_W(asBC_CMPi64, ctx->type.stackOffset, offset);
 				DeallocateVariable(offset);
 				DeallocateVariable(offset);
 #else
 #else
@@ -4846,7 +4852,9 @@ void asCCompiler::ImplicitConversionConstant(asSExprContext *from, const asCData
 		if( from->type.dataType.IsFloatType() )
 		if( from->type.dataType.IsFloatType() )
 		{
 		{
 			float fc = from->type.floatValue;
 			float fc = from->type.floatValue;
-			asUINT uic = asUINT(fc);
+			// Some compilers set the value to 0 when converting a negative float to unsigned int.
+			// To maintain a consistent behaviour across compilers we convert to int first.
+			asUINT uic = asUINT(int(fc));
 
 
 			if( float(uic) != fc )
 			if( float(uic) != fc )
 			{
 			{
@@ -4862,7 +4870,9 @@ void asCCompiler::ImplicitConversionConstant(asSExprContext *from, const asCData
 		else if( from->type.dataType.IsDoubleType() )
 		else if( from->type.dataType.IsDoubleType() )
 		{
 		{
 			double fc = from->type.doubleValue;
 			double fc = from->type.doubleValue;
-			asUINT uic = asUINT(fc);
+			// Some compilers set the value to 0 when converting a negative double to unsigned int.
+			// To maintain a consistent behaviour across compilers we convert to int first.
+			asUINT uic = asUINT(int(fc));
 
 
 			if( double(uic) != fc )
 			if( double(uic) != fc )
 			{
 			{
@@ -5101,7 +5111,7 @@ void asCCompiler::ImplicitConversionConstant(asSExprContext *from, const asCData
 		}
 		}
 		else if( from->type.dataType.IsUnsignedType() && from->type.dataType.GetSizeInMemoryDWords() == 2 )
 		else if( from->type.dataType.IsUnsignedType() && from->type.dataType.GetSizeInMemoryDWords() == 2 )
 		{
 		{
-			float fc = float((signed)from->type.qwordValue);
+			float fc = float((asINT64)from->type.qwordValue);
 
 
 			if( asQWORD(fc) != from->type.qwordValue )
 			if( asQWORD(fc) != from->type.qwordValue )
 			{
 			{
@@ -5196,7 +5206,7 @@ void asCCompiler::ImplicitConversionConstant(asSExprContext *from, const asCData
 		}
 		}
 		else if( from->type.dataType.IsUnsignedType() && from->type.dataType.GetSizeInMemoryDWords() == 2 )
 		else if( from->type.dataType.IsUnsignedType() && from->type.dataType.GetSizeInMemoryDWords() == 2 )
 		{
 		{
-			double fc = double((signed)from->type.qwordValue);
+			double fc = double((asINT64)from->type.qwordValue);
 
 
 			if( asQWORD(fc) != from->type.qwordValue )
 			if( asQWORD(fc) != from->type.qwordValue )
 			{
 			{
@@ -5443,13 +5453,6 @@ int asCCompiler::CompileAssignment(asCScriptNode *expr, asSExprContext *ctx)
 	asCScriptNode *lexpr = expr->firstChild;
 	asCScriptNode *lexpr = expr->firstChild;
 	if( lexpr->next )
 	if( lexpr->next )
 	{
 	{
-		if( globalExpression )
-		{
-			Error(TXT_ASSIGN_IN_GLOBAL_EXPR, expr);
-			ctx->type.SetDummy();
-			return -1;
-		}
-
 		// Compile the two expression terms
 		// Compile the two expression terms
 		asSExprContext lctx(engine), rctx(engine);
 		asSExprContext lctx(engine), rctx(engine);
 		int rr = CompileAssignment(lexpr->next->next, &rctx);
 		int rr = CompileAssignment(lexpr->next->next, &rctx);
@@ -5856,12 +5859,12 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 			{
 			{
 				// This is an index access, check if there is a property accessor that takes an index arg
 				// This is an index access, check if there is a property accessor that takes an index arg
 				asSExprContext dummyArg(engine);
 				asSExprContext dummyArg(engine);
-				r = FindPropertyAccessor(name, &access, &dummyArg, errNode);
+				r = FindPropertyAccessor(name, &access, &dummyArg, errNode, true);
 			}
 			}
 			if( r == 0 )
 			if( r == 0 )
 			{
 			{
 				// Normal property access
 				// Normal property access
-				r = FindPropertyAccessor(name, &access, errNode);
+				r = FindPropertyAccessor(name, &access, errNode, true);
 			}
 			}
 			if( r < 0 ) return -1;
 			if( r < 0 ) return -1;
 			if( access.property_get || access.property_set )
 			if( access.property_get || access.property_set )
@@ -6944,15 +6947,6 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 		return;
 		return;
 	}
 	}
 
 
-	if( globalExpression )
-	{
-		Error(TXT_FUNCTION_IN_GLOBAL_EXPR, node);
-
-		// Output dummy code
-		ctx->type.SetDummy();
-		return;
-	}
-
 	// Compile the arguments
 	// Compile the arguments
 	asCArray<asSExprContext *> args;
 	asCArray<asSExprContext *> args;
 	asCArray<asCTypeInfo> temporaryVariables;
 	asCArray<asCTypeInfo> temporaryVariables;
@@ -7124,8 +7118,8 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 	asCScriptNode *nm = node->lastChild->prev;
 	asCScriptNode *nm = node->lastChild->prev;
 	name.Assign(&script->code[nm->tokenPos], nm->tokenLength);
 	name.Assign(&script->code[nm->tokenPos], nm->tokenLength);
 
 
-	// TODO: funcdef: First check for a local variable of a function type
-	//                Must not allow function names, nor global variables to be returned in this instance
+	// First check for a local variable of a function type
+	// Must not allow function names, nor global variables to be returned in this instance
 	asSExprContext funcPtr(engine);
 	asSExprContext funcPtr(engine);
 	if( objectType == 0 )
 	if( objectType == 0 )
 		r = CompileVariableAccess(name, scope, &funcPtr, node, true, true);
 		r = CompileVariableAccess(name, scope, &funcPtr, node, true, true);
@@ -7156,19 +7150,18 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 			// TODO: funcdef: It is still possible that there is a global variable of a function type
 			// TODO: funcdef: It is still possible that there is a global variable of a function type
 		}
 		}
 	}
 	}
-
-	if( funcs.GetLength() == 0 && funcPtr.type.dataType.GetFuncDef() )
+	else if( !funcPtr.type.dataType.GetFuncDef() )
 	{
 	{
-		funcs.PushLast(funcPtr.type.dataType.GetFuncDef()->id);
+		// The variable is not a function
+		asCString msg;
+		msg.Format(TXT_NOT_A_FUNC_s_IS_VAR, name.AddressOf());
+		Error(msg.AddressOf(), node);
+		return;
 	}
 	}
 
 
-	if( globalExpression )
+	if( funcs.GetLength() == 0 && funcPtr.type.dataType.GetFuncDef() )
 	{
 	{
-		Error(TXT_FUNCTION_IN_GLOBAL_EXPR, node);
-
-		// Output dummy code
-		ctx->type.SetDummy();
-		return;
+		funcs.PushLast(funcPtr.type.dataType.GetFuncDef()->id);
 	}
 	}
 
 
 	// Compile the arguments
 	// Compile the arguments
@@ -7510,11 +7503,6 @@ int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx
 	{
 	{
 		// Need a reference to the primitive that will be updated
 		// Need a reference to the primitive that will be updated
 		// The result of this expression is the same reference as before
 		// The result of this expression is the same reference as before
-		if( globalExpression )
-		{
-			Error(TXT_INC_OP_IN_GLOBAL_EXPR, node);
-			return -1;
-		}
 
 
 		// Make sure the reference isn't a temporary variable
 		// Make sure the reference isn't a temporary variable
 		if( ctx->type.isTemporary )
 		if( ctx->type.isTemporary )
@@ -7613,12 +7601,12 @@ void asCCompiler::ConvertToReference(asSExprContext *ctx)
 	}
 	}
 }
 }
 
 
-int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node)
+int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, bool isThisAccess)
 {
 {
-	return FindPropertyAccessor(name, ctx, 0, node);
+	return FindPropertyAccessor(name, ctx, 0, node, isThisAccess);
 }
 }
 
 
-int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node)
+int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, bool isThisAccess)
 {
 {
 	if( engine->ep.propertyAccessorMode == 0 )
 	if( engine->ep.propertyAccessorMode == 0 )
 	{
 	{
@@ -7763,7 +7751,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 	// Check if we are within one of the accessors
 	// Check if we are within one of the accessors
 	int realGetId = getId;
 	int realGetId = getId;
 	int realSetId = setId;
 	int realSetId = setId;
-	if( outFunc->objectType )
+	if( outFunc->objectType && isThisAccess )
 	{
 	{
 		// The property accessors would be virtual functions, so we need to find the real implementation
 		// The property accessors would be virtual functions, so we need to find the real implementation
 		asCScriptFunction *getFunc = getId ? engine->scriptFunctions[getId] : 0;
 		asCScriptFunction *getFunc = getId ? engine->scriptFunctions[getId] : 0;
@@ -7778,11 +7766,12 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 			realSetId = outFunc->objectType->virtualFunctionTable[setFunc->vfTableIdx]->id;
 			realSetId = outFunc->objectType->virtualFunctionTable[setFunc->vfTableIdx]->id;
 	}
 	}
 
 
-	if( (realGetId && realGetId == outFunc->id) ||
-		(realSetId && realSetId == outFunc->id) )
+	// Avoid recursive call, by not treating this as a property accessor call.
+	// This will also allow having the real property with the same name as the accessors.
+	if( (isThisAccess || outFunc->objectType == 0) &&
+		((realGetId && realGetId == outFunc->id) ||
+		 (realSetId && realSetId == outFunc->id)) )
 	{
 	{
-		// Avoid recursive call, by not treating this as a property accessor call.
-		// This will also allow having the real property with the same name as the accessors.
 		getId = 0;
 		getId = 0;
 		setId = 0;
 		setId = 0;
 	}
 	}
@@ -8093,12 +8082,6 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 	}
 	}
 	else if( op == ttInc || op == ttDec )
 	else if( op == ttInc || op == ttDec )
 	{
 	{
-		if( globalExpression )
-		{
-			Error(TXT_INC_OP_IN_GLOBAL_EXPR, node);
-			return -1;
-		}
-
 		// Make sure the reference isn't a temporary variable
 		// Make sure the reference isn't a temporary variable
 		if( ctx->type.isTemporary )
 		if( ctx->type.isTemporary )
 		{
 		{
@@ -8263,12 +8246,6 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 		}
 		}
 		else
 		else
 		{
 		{
-			if( globalExpression )
-			{
-				Error(TXT_METHOD_IN_GLOBAL_EXPR, node);
-				return -1;
-			}
-
 			// Make sure it is an object we are accessing
 			// Make sure it is an object we are accessing
 			if( !ctx->type.dataType.IsObject() )
 			if( !ctx->type.dataType.IsObject() )
 			{
 			{

+ 2 - 3
ThirdParty/AngelScript/source/as_compiler.h

@@ -167,8 +167,8 @@ protected:
 	// Helper functions
 	// Helper functions
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
 	int  ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
-	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node);
-	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
+	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, bool isThisAccess = false);
+	int  FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, bool isThisAccess = false);
 	void SwapPostFixOperands(asCArray<asCScriptNode *> &postfix, asCArray<asCScriptNode *> &target);
 	void SwapPostFixOperands(asCArray<asCScriptNode *> &postfix, asCArray<asCScriptNode *> &target);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, asCArray<int> *reservedVars, bool forceOnHeap = false);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, asCArray<int> *reservedVars, bool forceOnHeap = false);
 	void PrepareOperand(asSExprContext *ctx, asCScriptNode *node);
 	void PrepareOperand(asSExprContext *ctx, asCScriptNode *node);
@@ -259,7 +259,6 @@ protected:
 	asCArray<int>         freeVariables;
 	asCArray<int>         freeVariables;
 	asCArray<int>         tempVariables;
 	asCArray<int>         tempVariables;
 
 
-	bool globalExpression;
 	bool isCompilingDefaultArg;
 	bool isCompilingDefaultArg;
 	bool isProcessingDeferredParams;
 	bool isProcessingDeferredParams;
 	int noCodeOutput;
 	int noCodeOutput;

+ 64 - 4
ThirdParty/AngelScript/source/as_config.h

@@ -231,6 +231,7 @@
 // AS_IPHONE  - Apple IPhone
 // AS_IPHONE  - Apple IPhone
 // AS_ANDROID - Android
 // AS_ANDROID - Android
 // AS_HAIKU   - Haiku
 // AS_HAIKU   - Haiku
+// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
 
 
 
 
 
 
@@ -259,10 +260,14 @@
 // find the virtual base object. x is the method pointer received by the register
 // find the virtual base object. x is the method pointer received by the register
 // function;
 // function;
 
 
-// COMPLEX_MASK
-// This constant shows what attributes determines if an object is returned in memory
+// COMPLEX_RETURN_MASK
+// This constant shows what attributes determine if an object is returned in memory
 // or in the registers as normal structures
 // or in the registers as normal structures
 
 
+// COMPLEX_MASK
+// This constant shows what attributes determine if an object is implicitly passed 
+// by reference or not, even if the argument is declared by value
+
 // THISCALL_RETURN_SIMPLE_IN_MEMORY
 // THISCALL_RETURN_SIMPLE_IN_MEMORY
 // CDECL_RETURN_SIMPLE_IN_MEMORY
 // CDECL_RETURN_SIMPLE_IN_MEMORY
 // STDCALL_RETURN_SIMPLE_IN_MEMORY
 // STDCALL_RETURN_SIMPLE_IN_MEMORY
@@ -351,6 +356,7 @@
 
 
 	#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 	#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR)
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR)
+	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR)
 	#define STDCALL __stdcall
 	#define STDCALL __stdcall
 	#define AS_SIZEOF_BOOL 1
 	#define AS_SIZEOF_BOOL 1
 	#define AS_WINDOWS_THREADS
 	#define AS_WINDOWS_THREADS
@@ -403,7 +409,6 @@
 		#define AS_XENON
 		#define AS_XENON
 		#define AS_BIG_ENDIAN
 		#define AS_BIG_ENDIAN
 	#else
 	#else
-		// Support native calling conventions on x86, but not 64bit yet
 		#if defined(_XBOX) || (defined(_M_IX86) && !defined(__LP64__))
 		#if defined(_XBOX) || (defined(_M_IX86) && !defined(__LP64__))
 			#define AS_X86
 			#define AS_X86
 		#elif defined(_M_X64)
 		#elif defined(_M_X64)
@@ -411,6 +416,9 @@
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_CALLEE_DESTROY_OBJ_BY_VAL
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJS_PASSED_BY_REF
 			#define AS_LARGE_OBJ_MIN_SIZE 3
 			#define AS_LARGE_OBJ_MIN_SIZE 3
+			#define COMPLEX_OBJS_PASSED_BY_REF
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 		#endif
 		#endif
 	#endif
 	#endif
 
 
@@ -428,12 +436,17 @@
 		#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 		#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 		#define COMPLEX_OBJS_PASSED_BY_REF
 		#define COMPLEX_OBJS_PASSED_BY_REF
 		#define COMPLEX_MASK asOBJ_APP_CLASS_ASSIGNMENT
 		#define COMPLEX_MASK asOBJ_APP_CLASS_ASSIGNMENT
+		#define COMPLEX_RETURN_MASK asOBJ_APP_CLASS_ASSIGNMENT
 	#endif
 	#endif
 
 
 	#ifndef COMPLEX_MASK
 	#ifndef COMPLEX_MASK
 		#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
 		#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
 	#endif
 	#endif
 
 
+	#ifndef COMPLEX_RETURN_MASK
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
+	#endif
+
 	#define UNREACHABLE_RETURN
 	#define UNREACHABLE_RETURN
 #endif
 #endif
 
 
@@ -447,6 +460,7 @@
 	#define asVSNPRINTF(a, b, c, d) _vsnprintf(a, b, c, d)
 	#define asVSNPRINTF(a, b, c, d) _vsnprintf(a, b, c, d)
 	#define THISCALL_CALLEE_POPS_ARGUMENTS
 	#define THISCALL_CALLEE_POPS_ARGUMENTS
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
+	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
 	#define AS_SIZEOF_BOOL 1
 	#define AS_SIZEOF_BOOL 1
 	#define AS_WINDOWS_THREADS
 	#define AS_WINDOWS_THREADS
 	#define STDCALL __stdcall
 	#define STDCALL __stdcall
@@ -474,6 +488,7 @@
 	#define COMPLEX_OBJS_PASSED_BY_REF
 	#define COMPLEX_OBJS_PASSED_BY_REF
 	#define ASM_AT_N_T  // AT&T style inline assembly
 	#define ASM_AT_N_T  // AT&T style inline assembly
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
 	#define AS_SIZEOF_BOOL 1
 	#define AS_SIZEOF_BOOL 1
 	#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 	#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
 
 
@@ -517,6 +532,7 @@
 	#define CALLEE_POPS_HIDDEN_RETURN_POINTER
 	#define CALLEE_POPS_HIDDEN_RETURN_POINTER
 	#define COMPLEX_OBJS_PASSED_BY_REF
 	#define COMPLEX_OBJS_PASSED_BY_REF
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
 	#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
+	#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
 	#define AS_NO_MEMORY_H
 	#define AS_NO_MEMORY_H
 	#define AS_SIZEOF_BOOL 1
 	#define AS_SIZEOF_BOOL 1
 	#define STDCALL __attribute__((stdcall))
 	#define STDCALL __attribute__((stdcall))
@@ -548,6 +564,8 @@
 			#define AS_X86
 			#define AS_X86
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 		#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__)
 		#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__)
 			// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
 			// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
 			#define AS_NO_THREADS
 			#define AS_NO_THREADS
@@ -556,6 +574,8 @@
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			// STDCALL is not available on 64bit Mac
 			// STDCALL is not available on 64bit Mac
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
@@ -567,6 +587,8 @@
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 		#elif (defined(__ppc__) || defined(__PPC__)) && defined(__LP64__)
 		#elif (defined(__ppc__) || defined(__PPC__)) && defined(__LP64__)
 			#define AS_PPC_64
 			#define AS_PPC_64
 		#elif (defined(_ARM_) || defined(__arm__))
 		#elif (defined(_ARM_) || defined(__arm__))
@@ -591,6 +613,8 @@
 			#define COMPLEX_OBJS_PASSED_BY_REF
 			#define COMPLEX_OBJS_PASSED_BY_REF
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK asOBJ_APP_CLASS_DESTRUCTOR
 			#define COMPLEX_MASK asOBJ_APP_CLASS_DESTRUCTOR
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK asOBJ_APP_CLASS_DESTRUCTOR
 		#else
 		#else
 			// Unknown CPU type
 			// Unknown CPU type
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
@@ -606,6 +630,8 @@
 
 
 		#undef COMPLEX_MASK
 		#undef COMPLEX_MASK
 		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 		#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+		#undef COMPLEX_RETURN_MASK
+		#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 
 
 		#if defined(i386) && !defined(__LP64__)
 		#if defined(i386) && !defined(__LP64__)
 			// Support native calling conventions on Intel 32bit CPU
 			// Support native calling conventions on Intel 32bit CPU
@@ -631,6 +657,8 @@
 
 
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 
 
 			// Support native calling conventions on Intel 32bit CPU
 			// Support native calling conventions on Intel 32bit CPU
 			#define AS_X86
 			#define AS_X86
@@ -640,6 +668,8 @@
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			// STDCALL is not available on 64bit Linux
 			// STDCALL is not available on 64bit Linux
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
@@ -677,6 +707,8 @@
 		#if defined(i386) && !defined(__LP64__)
 		#if defined(i386) && !defined(__LP64__)
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define AS_X86
 			#define AS_X86
 		#elif defined(__LP64__)
 		#elif defined(__LP64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
@@ -684,6 +716,8 @@
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#define SPLIT_OBJS_BY_MEMBER_TYPES
 			#undef COMPLEX_MASK
 			#undef COMPLEX_MASK
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
+			#undef COMPLEX_RETURN_MASK
+			#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
 		#else
 		#else
@@ -776,6 +810,32 @@
 			#define AS_NO_ATOMIC
 			#define AS_NO_ATOMIC
 		#endif
 		#endif
 
 
+	// Illumos
+	#elif defined(__sun)
+		#if defined(__i386__) && !defined(__LP64__)
+			#define THISCALL_RETURN_SIMPLE_IN_MEMORY
+			#define CDECL_RETURN_SIMPLE_IN_MEMORY
+			#define STDCALL_RETURN_SIMPLE_IN_MEMORY
+
+			// Support native calling conventions on Intel 32bit CPU
+			#define AS_X86
+		#elif defined(__LP64__)
+			#define AS_X64_GCC
+			#define HAS_128_BIT_PRIMITIVES
+			#define SPLIT_OBJS_BY_MEMBER_TYPES
+			// STDCALL is not available on 64bit Linux
+			#undef STDCALL
+			#define STDCALL
+		#else
+			#define AS_MAX_PORTABILITY
+		#endif
+		#define AS_ILLUMOS
+		#define AS_POSIX_THREADS
+
+		#if !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
+			// Only with GCC 4.1 was the atomic instructions available
+			#define AS_NO_ATOMIC
+		#endif
 	#endif
 	#endif
 
 
 	#define I64(x) x##ll
 	#define I64(x) x##ll
@@ -829,7 +889,7 @@
 #endif
 #endif
 
 
 // Is the target a 64bit system?
 // Is the target a 64bit system?
-#if defined(__LP64__) || defined(__amd64__) || defined(_M_X64)
+#if defined(__LP64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)
 	#ifndef AS_64BIT_PTR
 	#ifndef AS_64BIT_PTR
 		#define AS_64BIT_PTR
 		#define AS_64BIT_PTR
 	#endif
 	#endif

+ 67 - 9
ThirdParty/AngelScript/source/as_context.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -1096,6 +1096,8 @@ void asCContext::PopCallState()
 // interface
 // interface
 asUINT asCContext::GetCallstackSize()
 asUINT asCContext::GetCallstackSize()
 {
 {
+	if( currentFunction == 0 ) return 0;
+
 	// The current function is accessed at stackLevel 0
 	// The current function is accessed at stackLevel 0
 	return asUINT(1 + callStack.GetLength() / CALLSTACK_FRAME_SIZE);
 	return asUINT(1 + callStack.GetLength() / CALLSTACK_FRAME_SIZE);
 }
 }
@@ -3487,6 +3489,61 @@ void asCContext::CleanStack()
 	inExceptionHandler = false;
 	inExceptionHandler = false;
 }
 }
 
 
+// Interface
+bool asCContext::IsVarInScope(asUINT varIndex, asUINT stackLevel)
+{
+	asASSERT( stackLevel < GetCallstackSize() );
+
+	asCScriptFunction *func;
+	asUINT pos;
+
+	if( stackLevel == 0 )
+	{
+		func = currentFunction;
+		pos = asUINT(regs.programPointer - func->byteCode.AddressOf());
+	}
+	else
+	{
+		size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
+		func = (asCScriptFunction*)s[1];
+		pos = asUINT((asDWORD*)s[2] - func->byteCode.AddressOf());
+	}
+
+	// First determine if the program position is after the variable declaration
+	if( func->variables.GetLength() <= varIndex ) return false;
+	if( func->variables[varIndex]->declaredAtProgramPos > pos ) return false;
+
+	asUINT declaredAt = func->variables[varIndex]->declaredAtProgramPos;
+
+	// If the program position is after the variable declaration it is necessary 
+	// determine if the program position is still inside the statement block where 
+	// the variable was delcared.
+	for( int n = 0; n < (int)func->objVariableInfo.GetLength(); n++ )
+	{
+		if( func->objVariableInfo[n].programPos >= declaredAt )
+		{
+			// If the current block ends between the declaredAt and current 
+			// program position, then we know the variable is no longer visible
+			int level = 0;
+			for( ; n < (int)func->objVariableInfo.GetLength(); n++ )
+			{
+				if( func->objVariableInfo[n].programPos > pos )
+					break;
+
+				if( func->objVariableInfo[n].option == asBLOCK_BEGIN ) level++;
+				if( func->objVariableInfo[n].option == asBLOCK_END && --level < 0 )
+					return false;
+			}
+
+			break;
+		}
+	}
+
+	// Variable is visible
+	return true;
+}
+
+// Internal
 void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLevel)
 void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLevel)
 {
 {
 	asASSERT( stackLevel < GetCallstackSize() );
 	asASSERT( stackLevel < GetCallstackSize() );
@@ -3623,10 +3680,11 @@ void asCContext::CleanStackFrame()
 			}
 			}
 		}
 		}
 
 
-		if( currentFunction->objectType )
+		// If the object is a script declared object, then we must release it
+		// as the compiler adds a reference at the entry of the function. Make sure
+		// the function has actually been entered
+		if( currentFunction->objectType && regs.programPointer != currentFunction->byteCode.AddressOf() )
 		{
 		{
-			// If the object is a script declared object, then we must release it
-			// as the compiler adds a reference at the entry of the function
 			asSTypeBehaviour *beh = &currentFunction->objectType->beh;
 			asSTypeBehaviour *beh = &currentFunction->objectType->beh;
 			if( beh->release && *(size_t*)&regs.stackFramePointer[0] != 0 )
 			if( beh->release && *(size_t*)&regs.stackFramePointer[0] != 0 )
 			{
 			{
@@ -3884,7 +3942,7 @@ int asCContext::GetVarCount(asUINT stackLevel)
 }
 }
 
 
 // interface
 // interface
-const char *asCContext::GetVarName(int varIndex, asUINT stackLevel)
+const char *asCContext::GetVarName(asUINT varIndex, asUINT stackLevel)
 {
 {
 	asIScriptFunction *func = GetFunction(stackLevel);
 	asIScriptFunction *func = GetFunction(stackLevel);
 	if( func == 0 ) return 0;
 	if( func == 0 ) return 0;
@@ -3895,7 +3953,7 @@ const char *asCContext::GetVarName(int varIndex, asUINT stackLevel)
 }
 }
 
 
 // interface
 // interface
-const char *asCContext::GetVarDeclaration(int varIndex, asUINT stackLevel)
+const char *asCContext::GetVarDeclaration(asUINT varIndex, asUINT stackLevel)
 {
 {
 	asIScriptFunction *func = GetFunction(stackLevel);
 	asIScriptFunction *func = GetFunction(stackLevel);
 	if( func == 0 ) return 0;
 	if( func == 0 ) return 0;
@@ -3904,7 +3962,7 @@ const char *asCContext::GetVarDeclaration(int varIndex, asUINT stackLevel)
 }
 }
 
 
 // interface
 // interface
-int asCContext::GetVarTypeId(int varIndex, asUINT stackLevel)
+int asCContext::GetVarTypeId(asUINT varIndex, asUINT stackLevel)
 {
 {
 	asIScriptFunction *func = GetFunction(stackLevel);
 	asIScriptFunction *func = GetFunction(stackLevel);
 	if( func == 0 ) return asINVALID_ARG;
 	if( func == 0 ) return asINVALID_ARG;
@@ -3915,7 +3973,7 @@ int asCContext::GetVarTypeId(int varIndex, asUINT stackLevel)
 }
 }
 
 
 // interface
 // interface
-void *asCContext::GetAddressOfVar(int varIndex, asUINT stackLevel)
+void *asCContext::GetAddressOfVar(asUINT varIndex, asUINT stackLevel)
 {
 {
 	if( stackLevel >= GetCallstackSize() ) return 0;
 	if( stackLevel >= GetCallstackSize() ) return 0;
 
 
@@ -3936,7 +3994,7 @@ void *asCContext::GetAddressOfVar(int varIndex, asUINT stackLevel)
 	if( func == 0 )
 	if( func == 0 )
 		return 0;
 		return 0;
 
 
-	if( varIndex < 0 || varIndex >= (signed)func->variables.GetLength() )
+	if( varIndex >= func->variables.GetLength() )
 		return 0;
 		return 0;
 
 
 	// For object variables it's necessary to dereference the pointer to get the address of the value
 	// For object variables it's necessary to dereference the pointer to get the address of the value

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -107,10 +107,11 @@ public:
 	asIScriptFunction *GetFunction(asUINT stackLevel);
 	asIScriptFunction *GetFunction(asUINT stackLevel);
 	int                GetLineNumber(asUINT stackLevel, int *column, const char **sectionName);
 	int                GetLineNumber(asUINT stackLevel, int *column, const char **sectionName);
 	int                GetVarCount(asUINT stackLevel);
 	int                GetVarCount(asUINT stackLevel);
-	const char        *GetVarName(int varIndex, asUINT stackLevel);
-	const char        *GetVarDeclaration(int varIndex, asUINT stackLevel);
-	int                GetVarTypeId(int varIndex, asUINT stackLevel);
-	void              *GetAddressOfVar(int varIndex, asUINT stackLevel);
+	const char        *GetVarName(asUINT varIndex, asUINT stackLevel);
+	const char        *GetVarDeclaration(asUINT varIndex, asUINT stackLevel);
+	int                GetVarTypeId(asUINT varIndex, asUINT stackLevel);
+	void              *GetAddressOfVar(asUINT varIndex, asUINT stackLevel);
+	bool               IsVarInScope(asUINT varIndex, asUINT stackLevel);
 	int                GetThisTypeId(asUINT stackLevel);
 	int                GetThisTypeId(asUINT stackLevel);
     void              *GetThisPointer(asUINT stackLevel);
     void              *GetThisPointer(asUINT stackLevel);
 
 

+ 11 - 4
ThirdParty/AngelScript/source/as_criticalsection.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -48,12 +48,14 @@ BEGIN_AS_NAMESPACE
 #define DECLARECRITICALSECTION(x) 
 #define DECLARECRITICALSECTION(x) 
 #define ENTERCRITICALSECTION(x) 
 #define ENTERCRITICALSECTION(x) 
 #define LEAVECRITICALSECTION(x) 
 #define LEAVECRITICALSECTION(x) 
+#define TRYENTERCRITICALSECTION(x) true
 
 
 #else
 #else
 
 
-#define DECLARECRITICALSECTION(x) asCThreadCriticalSection x
-#define ENTERCRITICALSECTION(x)   x.Enter()
-#define LEAVECRITICALSECTION(x)   x.Leave()
+#define DECLARECRITICALSECTION(x)  asCThreadCriticalSection x
+#define ENTERCRITICALSECTION(x)    x.Enter()
+#define LEAVECRITICALSECTION(x)    x.Leave()
+#define TRYENTERCRITICALSECTION(x) x.TryEnter()
 
 
 #ifdef AS_POSIX_THREADS
 #ifdef AS_POSIX_THREADS
 
 
@@ -69,6 +71,7 @@ public:
 
 
 	void Enter();
 	void Enter();
 	void Leave();
 	void Leave();
+	bool TryEnter();
 
 
 protected:
 protected:
 	pthread_mutex_t criticalSection;
 	pthread_mutex_t criticalSection;
@@ -81,6 +84,9 @@ END_AS_NAMESPACE
 #include <xtl.h>
 #include <xtl.h>
 #else
 #else
 #define WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
+#ifndef _WIN32_WINNT
+  #define _WIN32_WINNT 0x0400 // We need this to get the declaration for TryEnterCriticalSection
+#endif
 #include <windows.h>
 #include <windows.h>
 #endif
 #endif
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
@@ -96,6 +102,7 @@ public:
 
 
 	void Enter();
 	void Enter();
 	void Leave();
 	void Leave();
+	bool TryEnter();
 
 
 protected:
 protected:
 	CRITICAL_SECTION criticalSection;
 	CRITICAL_SECTION criticalSection;

+ 361 - 143
ThirdParty/AngelScript/source/as_gc.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any
    warranty. In no event will the authors be held liable for any
@@ -46,150 +46,234 @@ BEGIN_AS_NAMESPACE
 
 
 asCGarbageCollector::asCGarbageCollector()
 asCGarbageCollector::asCGarbageCollector()
 {
 {
-	engine       = 0;
-	detectState  = clearCounters_init;
-	destroyState = destroyGarbage_init;
-	numDestroyed = 0;
-	numDetected  = 0;
+	engine          = 0;
+	detectState     = clearCounters_init;
+	destroyNewState = destroyGarbage_init;
+	destroyOldState = destroyGarbage_init;
+	numDestroyed    = 0;
+	numNewDestroyed = 0;
+	numDetected     = 0;
 }
 }
 
 
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
 {
 {
 	engine->CallObjectMethod(obj, objType->beh.addref);
 	engine->CallObjectMethod(obj, objType->beh.addref);
-	asSObjTypePair ot = {obj, objType};
+	asSObjTypePair ot = {obj, objType, 0};
+
+	// Invoke the garbage collector to destroy a little garbage as new comes in
+	// This will maintain the number of objects in the GC at a maintainable level without
+	// halting the application, and without burdening the application with manually invoking the 
+	// garbage collector.
+	if( engine->ep.autoGarbageCollect && gcNewObjects.GetLength() )
+	{
+		// If the GC is already processing in another thread, then don't try this again
+		// TODO: What if it is already processing in this thread?
+		if( TRYENTERCRITICALSECTION(gcCollecting) )
+		{
+			// TODO: The number of iterations should be dynamic, and increase 
+			//       if the number of objects in the garbage collector grows high
+
+			// Run one step of DetectGarbage
+			if( gcOldObjects.GetLength() )
+			{
+				IdentifyGarbageWithCyclicRefs();
+				DestroyOldGarbage();
+			}
+
+			// Run a few steps of DestroyGarbage
+			int iter = (int)gcNewObjects.GetLength();
+			if( iter > 10 ) iter = 10;
+			while( iter-- > 0 )
+				DestroyNewGarbage();
+
+			LEAVECRITICALSECTION(gcCollecting);
+		}
+	}
 
 
 	// Add the data to the gcObjects array in a critical section as
 	// Add the data to the gcObjects array in a critical section as
 	// another thread might be calling this method at the same time
 	// another thread might be calling this method at the same time
 	ENTERCRITICALSECTION(gcCritical);
 	ENTERCRITICALSECTION(gcCritical);
-	gcObjects.PushLast(ot);
+	gcNewObjects.PushLast(ot);
 	LEAVECRITICALSECTION(gcCritical);
 	LEAVECRITICALSECTION(gcCritical);
 }
 }
 
 
 int asCGarbageCollector::GarbageCollect(asDWORD flags)
 int asCGarbageCollector::GarbageCollect(asDWORD flags)
 {
 {
-	// The application is responsible for making sure
-	// the gc is only executed by one thread at a time.
-
-	bool doDetect  = (flags & asGC_DETECT_GARBAGE)  || !(flags & asGC_DESTROY_GARBAGE);
-	bool doDestroy = (flags & asGC_DESTROY_GARBAGE) || !(flags & asGC_DETECT_GARBAGE);
-
-	if( flags & asGC_FULL_CYCLE )
+	// If the GC is already processing in another thread, then don't enter here again
+	// TODO: What if it is already processing in this thread?
+	if( TRYENTERCRITICALSECTION(gcCollecting) )
 	{
 	{
-		// Reset the state
-		if( doDetect )
-			detectState  = clearCounters_init;
-		if( doDestroy )
-			destroyState = destroyGarbage_init;
-
-		int r = 1;
-		unsigned int count = (unsigned int)gcObjects.GetLength();
-		for(;;)
+		bool doDetect  = (flags & asGC_DETECT_GARBAGE)  || !(flags & asGC_DESTROY_GARBAGE);
+		bool doDestroy = (flags & asGC_DESTROY_GARBAGE) || !(flags & asGC_DETECT_GARBAGE);
+
+		if( flags & asGC_FULL_CYCLE )
 		{
 		{
-			// Detect all garbage with cyclic references
+			// Reset the state
 			if( doDetect )
 			if( doDetect )
-				while( (r = IdentifyGarbageWithCyclicRefs()) == 1 );
-
-			// Now destroy all known garbage
+			{
+				// Move all objects to the old list, so we guarantee that all is detected
+				for( asUINT n = (asUINT)gcNewObjects.GetLength(); n-- > 0; )
+					MoveObjectToOldList(n);
+				detectState  = clearCounters_init;
+			}
 			if( doDestroy )
 			if( doDestroy )
-				while( (r = DestroyGarbage()) == 1 );
+			{
+				destroyNewState = destroyGarbage_init;
+				destroyOldState = destroyGarbage_init;
+			}
 
 
-			// Run another iteration if any garbage was destroyed
-			if( count != gcObjects.GetLength() )
-				count = (unsigned int)gcObjects.GetLength();
-			else
-				break;
-		}
+			int r = 1;
+			unsigned int count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
+			for(;;)
+			{
+				// Detect all garbage with cyclic references
+				if( doDetect )
+					while( (r = IdentifyGarbageWithCyclicRefs()) == 1 );
 
 
-		// Take the opportunity to clear unused types as well
-		engine->ClearUnusedTypes();
+				// Now destroy all known garbage
+				if( doDestroy )
+				{
+					while( (r = DestroyNewGarbage()) == 1 );
+					while( (r = DestroyOldGarbage()) == 1 );
+				}
 
 
-		return 0;
-	}
-	else
-	{
-		// Destroy the garbage that we know of
-		if( doDestroy )
-			DestroyGarbage();
+				// Run another iteration if any garbage was destroyed
+				if( count != (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength()) )
+					count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
+				else
+					break;
+			}
 
 
-		// Run another incremental step of the identification of cyclic references
-		if( doDetect )
-			IdentifyGarbageWithCyclicRefs();
-	}
+			// Take the opportunity to clear unused types as well
+			engine->ClearUnusedTypes();
+
+			LEAVECRITICALSECTION(gcCollecting);
+			return 0;
+		}
+		else
+		{
+			// Destroy the garbage that we know of
+			if( doDestroy )
+			{
+				DestroyNewGarbage();
+				DestroyOldGarbage();
+			}
 
 
+			// Run another incremental step of the identification of cyclic references
+			if( doDetect )
+				IdentifyGarbageWithCyclicRefs();
+		}
+
+		LEAVECRITICALSECTION(gcCollecting);
+	}
+	
 	// Return 1 to indicate that the cycle wasn't finished
 	// Return 1 to indicate that the cycle wasn't finished
 	return 1;
 	return 1;
 }
 }
 
 
-void asCGarbageCollector::GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected) const
+void asCGarbageCollector::GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const
 {
 {
 	// It's not necessary to protect this access, as
 	// It's not necessary to protect this access, as
 	// it doesn't matter if another thread is currently
 	// it doesn't matter if another thread is currently
 	// appending a new object.
 	// appending a new object.
 	if( currentSize )
 	if( currentSize )
-		*currentSize = (asUINT)gcObjects.GetLength();
+		*currentSize = (asUINT)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
 
 
 	if( totalDestroyed )
 	if( totalDestroyed )
 		*totalDestroyed = numDestroyed;
 		*totalDestroyed = numDestroyed;
 
 
 	if( totalDetected )
 	if( totalDetected )
 		*totalDetected = numDetected;
 		*totalDetected = numDetected;
-}
 
 
-void asCGarbageCollector::ClearMap()
-{
-	// Decrease reference counter for all objects removed from the map
-	asSMapNode<void*, asSIntTypePair> *cursor = 0;
-	gcMap.MoveFirst(&cursor);
-	while( cursor )
-	{
-		void *obj = gcMap.GetKey(cursor);
-		asSIntTypePair it = gcMap.GetValue(cursor);
+	if( newObjects )
+		*newObjects = (asUINT)gcNewObjects.GetLength();
 
 
-		engine->CallObjectMethod(obj, it.type->beh.release);
+	if( totalNewDestroyed )
+		*totalNewDestroyed = numNewDestroyed;
+}
 
 
-		gcMap.MoveNext(&cursor, cursor);
-	}
+asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetNewObjectAtIdx(int idx)
+{
+	// We need to protect this access with a critical section as
+	// another thread might be appending an object at the same time
+	ENTERCRITICALSECTION(gcCritical);
+	asSObjTypePair gcObj = gcNewObjects[idx];
+	LEAVECRITICALSECTION(gcCritical);
 
 
-	gcMap.EraseAll();
+	return gcObj;
 }
 }
 
 
-asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetObjectAtIdx(int idx)
+asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetOldObjectAtIdx(int idx)
 {
 {
 	// We need to protect this access with a critical section as
 	// We need to protect this access with a critical section as
 	// another thread might be appending an object at the same time
 	// another thread might be appending an object at the same time
 	ENTERCRITICALSECTION(gcCritical);
 	ENTERCRITICALSECTION(gcCritical);
-	asSObjTypePair gcObj = gcObjects[idx];
+	asSObjTypePair gcObj = gcOldObjects[idx];
 	LEAVECRITICALSECTION(gcCritical);
 	LEAVECRITICALSECTION(gcCritical);
 
 
 	return gcObj;
 	return gcObj;
 }
 }
 
 
-void asCGarbageCollector::RemoveObjectAtIdx(int idx)
+void asCGarbageCollector::RemoveNewObjectAtIdx(int idx)
+{
+	// We need to protect this update with a critical section as
+	// another thread might be appending an object at the same time
+	ENTERCRITICALSECTION(gcCritical);
+	if( idx == (int)gcNewObjects.GetLength() - 1)
+		gcNewObjects.PopLast();
+	else
+		gcNewObjects[idx] = gcNewObjects.PopLast();
+	LEAVECRITICALSECTION(gcCritical);
+}
+
+void asCGarbageCollector::RemoveOldObjectAtIdx(int idx)
+{
+	// We need to protect this update with a critical section as
+	// another thread might be appending an object at the same time
+	ENTERCRITICALSECTION(gcCritical);
+	if( idx == (int)gcOldObjects.GetLength() - 1)
+		gcOldObjects.PopLast();
+	else
+		gcOldObjects[idx] = gcOldObjects.PopLast();
+	LEAVECRITICALSECTION(gcCritical);
+}
+
+void asCGarbageCollector::MoveObjectToOldList(int idx)
 {
 {
 	// We need to protect this update with a critical section as
 	// We need to protect this update with a critical section as
 	// another thread might be appending an object at the same time
 	// another thread might be appending an object at the same time
 	ENTERCRITICALSECTION(gcCritical);
 	ENTERCRITICALSECTION(gcCritical);
-	if( idx == (int)gcObjects.GetLength() - 1)
-		gcObjects.PopLast();
+	gcOldObjects.PushLast(gcNewObjects[idx]);
+	if( idx == (int)gcNewObjects.GetLength() - 1)
+		gcNewObjects.PopLast();
 	else
 	else
-		gcObjects[idx] = gcObjects.PopLast();
+		gcNewObjects[idx] = gcNewObjects.PopLast();
+	LEAVECRITICALSECTION(gcCritical);
+}
+
+void asCGarbageCollector::IncreaseCounterForNewObject(int idx)
+{
+	// We need to protect this update with a critical section as
+	// another thread might be appending an object at the same time
+	ENTERCRITICALSECTION(gcCritical);
+	gcNewObjects[idx].count++;
 	LEAVECRITICALSECTION(gcCritical);
 	LEAVECRITICALSECTION(gcCritical);
 }
 }
 
 
-int asCGarbageCollector::DestroyGarbage()
+int asCGarbageCollector::DestroyNewGarbage()
 {
 {
 	for(;;)
 	for(;;)
 	{
 	{
-		switch( destroyState )
+		switch( destroyNewState )
 		{
 		{
 		case destroyGarbage_init:
 		case destroyGarbage_init:
 		{
 		{
 			// If there are no objects to be freed then don't start
 			// If there are no objects to be freed then don't start
-			if( gcObjects.GetLength() == 0 )
+			if( gcNewObjects.GetLength() == 0 )
 				return 0;
 				return 0;
 
 
-			destroyIdx = (asUINT)-1;
-			destroyState = destroyGarbage_loop;
+			destroyNewIdx = (asUINT)-1;
+			destroyNewState = destroyGarbage_loop;
 		}
 		}
 		break;
 		break;
 
 
@@ -203,9 +287,9 @@ int asCGarbageCollector::DestroyGarbage()
 			// Destroy all objects that have refCount == 1. If any objects are
 			// Destroy all objects that have refCount == 1. If any objects are
 			// destroyed, go over the list again, because it may have made more
 			// destroyed, go over the list again, because it may have made more
 			// objects reach refCount == 1.
 			// objects reach refCount == 1.
-			while( ++destroyIdx < gcObjects.GetLength() )
+			if( ++destroyNewIdx < gcNewObjects.GetLength() )
 			{
 			{
-				asSObjTypePair gcObj = GetObjectAtIdx(destroyIdx);
+				asSObjTypePair gcObj = GetNewObjectAtIdx(destroyNewIdx);
 				if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
 				if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
 				{
 				{
 					// Release the object immediately
 					// Release the object immediately
@@ -226,8 +310,9 @@ int asCGarbageCollector::DestroyGarbage()
 					if( !addRef )
 					if( !addRef )
 					{
 					{
 						numDestroyed++;
 						numDestroyed++;
-						RemoveObjectAtIdx(destroyIdx);
-						destroyIdx--;
+						numNewDestroyed++;
+						RemoveNewObjectAtIdx(destroyNewIdx);
+						destroyNewIdx--;
 					}
 					}
 					else
 					else
 					{
 					{
@@ -236,26 +321,132 @@ int asCGarbageCollector::DestroyGarbage()
 						engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
 						engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
 					}
 					}
 
 
-					destroyState = destroyGarbage_haveMore;
+					destroyNewState = destroyGarbage_haveMore;
+				}
+				else if( gcObj.count == 3 )
+				{
+					// We've already verified this object multiple times. It is likely
+					// to live for quite a long time so we'll move it to the list if old objects
+					MoveObjectToOldList(destroyNewIdx);
+					destroyNewIdx--;
+				}
+				else
+				{
+					// Increase the counter for the number of times the object has been verified
+					IncreaseCounterForNewObject(destroyNewIdx);
+				}
 
 
-					// Allow the application to work a little
-					return 1;
+				// Allow the application to work a little
+				return 1;
+			}
+			else
+			{
+				if( destroyNewState == destroyGarbage_haveMore )
+				{
+					// Restart the cycle
+					destroyNewState = destroyGarbage_init;
+				}
+				else
+				{
+					// Restart the cycle
+					destroyNewState = destroyGarbage_init;
+
+					// Return 0 to tell the application that there 
+					// is no more garbage to destroy at the moment
+					return 0;
 				}
 				}
 			}
 			}
+		}
+		break;
+		}
+	}
+
+	// Shouldn't reach this point
+	UNREACHABLE_RETURN;
+}
 
 
-			if( destroyState == destroyGarbage_haveMore )
+int asCGarbageCollector::DestroyOldGarbage()
+{
+	for(;;)
+	{
+		switch( destroyOldState )
+		{
+		case destroyGarbage_init:
+		{
+			// If there are no objects to be freed then don't start
+			if( gcOldObjects.GetLength() == 0 )
+				return 0;
+
+			destroyOldIdx = (asUINT)-1;
+			destroyOldState = destroyGarbage_loop;
+		}
+		break;
+
+		case destroyGarbage_loop:
+		case destroyGarbage_haveMore:
+		{
+			// If the refCount has reached 1, then only the GC still holds a
+			// reference to the object, thus we don't need to worry about the
+			// application touching the objects during collection.
+
+			// Destroy all objects that have refCount == 1. If any objects are
+			// destroyed, go over the list again, because it may have made more
+			// objects reach refCount == 1.
+			if( ++destroyOldIdx < gcOldObjects.GetLength() )
 			{
 			{
-				// Restart the cycle
-				destroyState = destroyGarbage_init;
+				asSObjTypePair gcObj = GetOldObjectAtIdx(destroyOldIdx);
+				if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
+				{
+					// Release the object immediately
+
+					// Make sure the refCount is really 0, because the
+					// destructor may have increased the refCount again.
+					bool addRef = false;
+					if( gcObj.type->flags & asOBJ_SCRIPT_OBJECT )
+					{
+						// Script objects may actually be resurrected in the destructor
+						int refCount = ((asCScriptObject*)gcObj.obj)->Release();
+						if( refCount > 0 ) addRef = true;
+					}
+					else
+						engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.release);
+
+					// Was the object really destroyed?
+					if( !addRef )
+					{
+						numDestroyed++;
+						RemoveOldObjectAtIdx(destroyOldIdx);
+						destroyOldIdx--;
+					}
+					else
+					{
+						// Since the object was resurrected in the
+						// destructor, we must add our reference again
+						engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
+					}
+
+					destroyOldState = destroyGarbage_haveMore;
+				}
+
+				// Allow the application to work a little
+				return 1;
 			}
 			}
 			else
 			else
 			{
 			{
-				// Restart the cycle
-				destroyState = destroyGarbage_init;
+				if( destroyOldState == destroyGarbage_haveMore )
+				{
+					// Restart the cycle
+					destroyOldState = destroyGarbage_init;
+				}
+				else
+				{
+					// Restart the cycle
+					destroyOldState = destroyGarbage_init;
 
 
-				// Return 0 to tell the application that there 
-				// is no more garbage to destroy at the moment
-				return 0;
+					// Return 0 to tell the application that there 
+					// is no more garbage to destroy at the moment
+					return 0;
+				}
 			}
 			}
 		}
 		}
 		break;
 		break;
@@ -273,14 +464,36 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 		switch( detectState )
 		switch( detectState )
 		{
 		{
 		case clearCounters_init:
 		case clearCounters_init:
-		{
-			ClearMap();
 			detectState = clearCounters_loop;
 			detectState = clearCounters_loop;
-			detectIdx = 0;
-		}
 		break;
 		break;
 
 
 		case clearCounters_loop:
 		case clearCounters_loop:
+		{
+			// Decrease reference counter for all objects removed from the map
+			asSMapNode<void*, asSIntTypePair> *cursor = 0;
+			gcMap.MoveFirst(&cursor);
+			if( cursor )
+			{
+				void *obj = gcMap.GetKey(cursor);
+				asSIntTypePair it = gcMap.GetValue(cursor);
+
+				engine->CallObjectMethod(obj, it.type->beh.release);
+
+				gcMap.Erase(cursor);
+
+				return 1;
+			}
+
+			detectState = buildMap_init;
+		}
+		break;
+
+		case buildMap_init:
+			detectIdx = 0;
+			detectState = buildMap_loop;
+		break;
+
+		case buildMap_loop:
 		{
 		{
 			// Build a map of objects that will be checked, the map will
 			// Build a map of objects that will be checked, the map will
 			// hold the object pointer as key, and the gcCount and the
 			// hold the object pointer as key, and the gcCount and the
@@ -293,10 +506,10 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			// be used during the analyzing for cyclic references. This
 			// be used during the analyzing for cyclic references. This
 			// isn't a problem, as the next time the GC cycle starts the
 			// isn't a problem, as the next time the GC cycle starts the
 			// object will be verified.
 			// object will be verified.
-			while( detectIdx < gcObjects.GetLength() )
+			if( detectIdx < gcOldObjects.GetLength() )
 			{
 			{
 				// Add the gc count for this object
 				// Add the gc count for this object
-				asSObjTypePair gcObj = GetObjectAtIdx(detectIdx);
+				asSObjTypePair gcObj = GetOldObjectAtIdx(detectIdx);
 				int refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
 				int refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
 				if( refCount > 1 )
 				if( refCount > 1 )
 				{
 				{
@@ -309,23 +522,20 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 					// Mark the object so that we can
 					// Mark the object so that we can
 					// see if it has changed since read
 					// see if it has changed since read
 					engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.gcSetFlag);
 					engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.gcSetFlag);
+				}
 
 
-					detectIdx++;
+				detectIdx++; 
 
 
-					// Let the application work a little
-					return 1;
-				}
-				else
-					detectIdx++;
+				// Let the application work a little
+				return 1;
 			}
 			}
-
-			detectState = countReferences_init;
+			else
+				detectState = countReferences_init;
 		}
 		}
 		break;
 		break;
 
 
 		case countReferences_init:
 		case countReferences_init:
 		{
 		{
-			detectIdx = (asUINT)-1;
 			gcMap.MoveFirst(&gcMapCursor);
 			gcMap.MoveFirst(&gcMapCursor);
 			detectState = countReferences_loop;
 			detectState = countReferences_loop;
 		}
 		}
@@ -344,7 +554,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 
 
 			// Any new objects created after this step in the GC cycle won't be
 			// Any new objects created after this step in the GC cycle won't be
 			// in the map, and is thus automatically considered alive.
 			// in the map, and is thus automatically considered alive.
-			while( gcMapCursor )
+			if( gcMapCursor )
 			{
 			{
 				void *obj = gcMap.GetKey(gcMapCursor);
 				void *obj = gcMap.GetKey(gcMapCursor);
 				asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
 				asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
@@ -353,19 +563,18 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				if( engine->CallObjectMethodRetBool(obj, type->beh.gcGetFlag) )
 				if( engine->CallObjectMethodRetBool(obj, type->beh.gcGetFlag) )
 				{
 				{
 					engine->CallObjectMethod(obj, engine, type->beh.gcEnumReferences);
 					engine->CallObjectMethod(obj, engine, type->beh.gcEnumReferences);
-
-					// Allow the application to work a little
-					return 1;
 				}
 				}
-			}
 
 
-			detectState = detectGarbage_init;
+				// Allow the application to work a little
+				return 1;
+			}
+			else
+				detectState = detectGarbage_init;
 		}
 		}
 		break;
 		break;
 
 
 		case detectGarbage_init:
 		case detectGarbage_init:
 		{
 		{
-			detectIdx = (asUINT)-1;
 			gcMap.MoveFirst(&gcMapCursor);
 			gcMap.MoveFirst(&gcMapCursor);
 			liveObjects.SetLength(0);
 			liveObjects.SetLength(0);
 			detectState = detectGarbage_loop1;
 			detectState = detectGarbage_loop1;
@@ -382,7 +591,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			// references were not found in the map.
 			// references were not found in the map.
 
 
 			// Add all alive objects from the map to the liveObjects array
 			// Add all alive objects from the map to the liveObjects array
-			while( gcMapCursor )
+			if( gcMapCursor )
 			{
 			{
 				asSMapNode<void*, asSIntTypePair> *cursor = gcMapCursor;
 				asSMapNode<void*, asSIntTypePair> *cursor = gcMapCursor;
 				gcMap.MoveNext(&gcMapCursor, gcMapCursor);
 				gcMap.MoveNext(&gcMapCursor, gcMapCursor);
@@ -394,13 +603,13 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				if( !gcFlag || it.i > 0 )
 				if( !gcFlag || it.i > 0 )
 				{
 				{
 					liveObjects.PushLast(obj);
 					liveObjects.PushLast(obj);
-
-					// Allow the application to work a little
-					return 1;
 				}
 				}
-			}
 
 
-			detectState = detectGarbage_loop2;
+				// Allow the application to work a little
+				return 1;
+			}
+			else
+				detectState = detectGarbage_loop2;
 		}
 		}
 		break;
 		break;
 
 
@@ -410,7 +619,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			// As the object is removed, all the objects it references are added to the
 			// As the object is removed, all the objects it references are added to the
 			// liveObjects list, by calling EnumReferences. Only objects still in the map
 			// liveObjects list, by calling EnumReferences. Only objects still in the map
 			// will be added to the liveObjects list.
 			// will be added to the liveObjects list.
-			while( liveObjects.GetLength() )
+			if( liveObjects.GetLength() )
 			{
 			{
 				void *gcObj = liveObjects.PopLast();
 				void *gcObj = liveObjects.PopLast();
 				asCObjectType *type = 0;
 				asCObjectType *type = 0;
@@ -432,18 +641,22 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				// Allow the application to work a little
 				// Allow the application to work a little
 				return 1;
 				return 1;
 			}
 			}
-
-			detectState = verifyUnmarked;
+			else
+				detectState = verifyUnmarked_init;
 		}
 		}
 		break;
 		break;
 
 
-		case verifyUnmarked:
+		case verifyUnmarked_init:
+			gcMap.MoveFirst(&gcMapCursor);
+			detectState = verifyUnmarked_loop;
+			break;
+
+		case verifyUnmarked_loop:
 		{
 		{
 			// In this step we must make sure that none of the objects still in the map
 			// In this step we must make sure that none of the objects still in the map
 			// has been touched by the application. If they have then we must run the
 			// has been touched by the application. If they have then we must run the
 			// detectGarbage loop once more.
 			// detectGarbage loop once more.
-			gcMap.MoveFirst(&gcMapCursor);
-			while( gcMapCursor )
+			if( gcMapCursor )
 			{
 			{
 				void *gcObj = gcMap.GetKey(gcMapCursor);
 				void *gcObj = gcMap.GetKey(gcMapCursor);
 				asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
 				asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
@@ -453,21 +666,24 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				{
 				{
 					// The unmarked object was touched, rerun the detectGarbage loop
 					// The unmarked object was touched, rerun the detectGarbage loop
 					detectState = detectGarbage_init;
 					detectState = detectGarbage_init;
-					return 1;
 				}
 				}
+				else
+					gcMap.MoveNext(&gcMapCursor, gcMapCursor);
 
 
-				gcMap.MoveNext(&gcMapCursor, gcMapCursor);
+				// Allow the application to work a little
+				return 1;
+			}
+			else
+			{
+				// No unmarked object was touched, we can now be sure
+				// that objects that have gcCount == 0 really is garbage
+				detectState = breakCircles_init;
 			}
 			}
-
-			// No unmarked object was touched, we can now be sure
-			// that objects that have gcCount == 0 really is garbage
-			detectState = breakCircles_init;
 		}
 		}
 		break;
 		break;
 
 
 		case breakCircles_init:
 		case breakCircles_init:
 		{
 		{
-			detectIdx = (asUINT)-1;
 			gcMap.MoveFirst(&gcMapCursor);
 			gcMap.MoveFirst(&gcMapCursor);
 			detectState = breakCircles_loop;
 			detectState = breakCircles_loop;
 		}
 		}
@@ -480,7 +696,7 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			// kept alive through circular references. To be able to free
 			// kept alive through circular references. To be able to free
 			// these objects we need to force the breaking of the circle
 			// these objects we need to force the breaking of the circle
 			// by having the objects release their references.
 			// by having the objects release their references.
-			while( gcMapCursor )
+			if( gcMapCursor )
 			{
 			{
 				numDetected++;
 				numDetected++;
 				void *gcObj = gcMap.GetKey(gcMapCursor);
 				void *gcObj = gcMap.GetKey(gcMapCursor);
@@ -494,19 +710,21 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 				// Allow the application to work a little
 				// Allow the application to work a little
 				return 1;
 				return 1;
 			}
 			}
-
-			// If no garbage was detected we can finish now
-			if( detectState != breakCircles_haveGarbage )
-			{
-				// Restart the GC
-				detectState = clearCounters_init;
-				return 0;
-			}
 			else
 			else
 			{
 			{
-				// Restart the GC
-				detectState = clearCounters_init;
-				return 1;
+				// If no garbage was detected we can finish now
+				if( detectState != breakCircles_haveGarbage )
+				{
+					// Restart the GC
+					detectState = clearCounters_init;
+					return 0;
+				}
+				else
+				{
+					// Restart the GC
+					detectState = clearCounters_init;
+					return 1;
+				}
 			}
 			}
 		}
 		}
 		break;
 		break;

+ 24 - 12
ThirdParty/AngelScript/source/as_gc.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -56,14 +56,14 @@ public:
 	asCGarbageCollector();
 	asCGarbageCollector();
 
 
 	int  GarbageCollect(asDWORD flags);
 	int  GarbageCollect(asDWORD flags);
-	void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected) const;
+	void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	void GCEnumCallback(void *reference);
 	void GCEnumCallback(void *reference);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
 
 
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
 
 
 protected:
 protected:
-	struct asSObjTypePair {void *obj; asCObjectType *type;};
+	struct asSObjTypePair {void *obj; asCObjectType *type; int count;};
 	struct asSIntTypePair {int i; asCObjectType *type;};
 	struct asSIntTypePair {int i; asCObjectType *type;};
 
 
 	enum egcDestroyState
 	enum egcDestroyState
@@ -77,25 +77,33 @@ protected:
 	{
 	{
 		clearCounters_init = 0,
 		clearCounters_init = 0,
 		clearCounters_loop,
 		clearCounters_loop,
+		buildMap_init,
+		buildMap_loop,
 		countReferences_init,
 		countReferences_init,
 		countReferences_loop,
 		countReferences_loop,
 		detectGarbage_init,
 		detectGarbage_init,
 		detectGarbage_loop1,
 		detectGarbage_loop1,
 		detectGarbage_loop2,
 		detectGarbage_loop2,
-		verifyUnmarked,
+		verifyUnmarked_init,
+		verifyUnmarked_loop,
 		breakCircles_init,
 		breakCircles_init,
 		breakCircles_loop,
 		breakCircles_loop,
 		breakCircles_haveGarbage
 		breakCircles_haveGarbage
 	};
 	};
 
 
-	int            DestroyGarbage();
+	int            DestroyNewGarbage();
+	int            DestroyOldGarbage();
 	int            IdentifyGarbageWithCyclicRefs();
 	int            IdentifyGarbageWithCyclicRefs();
-	void           ClearMap();
-	asSObjTypePair GetObjectAtIdx(int idx);
-	void           RemoveObjectAtIdx(int idx);
+	asSObjTypePair GetNewObjectAtIdx(int idx);
+	asSObjTypePair GetOldObjectAtIdx(int idx);
+	void           RemoveNewObjectAtIdx(int idx);
+	void           RemoveOldObjectAtIdx(int idx);
+	void           MoveObjectToOldList(int idx);
+	void           IncreaseCounterForNewObject(int idx);
 
 
 	// Holds all the objects known by the garbage collector
 	// Holds all the objects known by the garbage collector
-	asCArray<asSObjTypePair>           gcObjects;
+	asCArray<asSObjTypePair>           gcNewObjects;
+	asCArray<asSObjTypePair>           gcOldObjects;
 
 
 	// This array temporarily holds references to objects known to be live objects
 	// This array temporarily holds references to objects known to be live objects
 	asCArray<void*>                    liveObjects;
 	asCArray<void*>                    liveObjects;
@@ -105,16 +113,20 @@ protected:
 	asCMap<void*, asSIntTypePair>      gcMap;
 	asCMap<void*, asSIntTypePair>      gcMap;
 
 
 	// State variables
 	// State variables
-	egcDestroyState                    destroyState;
-	asUINT                             destroyIdx;
+	egcDestroyState                    destroyNewState;
+	egcDestroyState                    destroyOldState;
+	asUINT                             destroyNewIdx;
+	asUINT                             destroyOldIdx;
 	asUINT                             numDestroyed;
 	asUINT                             numDestroyed;
+	asUINT                             numNewDestroyed;
 	egcDetectState                     detectState;
 	egcDetectState                     detectState;
 	asUINT                             detectIdx;
 	asUINT                             detectIdx;
 	asUINT                             numDetected;
 	asUINT                             numDetected;
 	asSMapNode<void*, asSIntTypePair> *gcMapCursor;
 	asSMapNode<void*, asSIntTypePair> *gcMapCursor;
 
 
 	// Critical section for multithreaded access
 	// Critical section for multithreaded access
-	DECLARECRITICALSECTION(gcCritical);
+	DECLARECRITICALSECTION(gcCritical);   // Used for adding/removing objects
+	DECLARECRITICALSECTION(gcCollecting); // Used for processing
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 43 - 37
ThirdParty/AngelScript/source/as_module.cpp

@@ -157,34 +157,31 @@ int asCModule::Build()
 
 
 	// Initialize global variables
 	// Initialize global variables
 	if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
 	if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
-		r = ResetGlobalVars();
+		r = ResetGlobalVars(0);
 
 
 	return r;
 	return r;
 }
 }
 
 
 // interface
 // interface
-int asCModule::ResetGlobalVars()
+int asCModule::ResetGlobalVars(asIScriptContext *ctx)
 {
 {
 	if( isGlobalVarInitialized ) 
 	if( isGlobalVarInitialized ) 
 		CallExit();
 		CallExit();
 
 
-	// TODO: The application really should do this manually through a context
-	//       otherwise it cannot properly handle script exceptions that may be
-	//       thrown by object initializations.
-	return CallInit();
+	return CallInit(ctx);
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetFunctionIdByIndex(int index) const
+int asCModule::GetFunctionIdByIndex(asUINT index) const
 {
 {
-	if( index < 0 || index >= (int)globalFunctions.GetLength() )
+	if( index >= globalFunctions.GetLength() )
 		return asNO_FUNCTION;
 		return asNO_FUNCTION;
 
 
 	return globalFunctions[index]->id;
 	return globalFunctions[index]->id;
 }
 }
 
 
 // internal
 // internal
-int asCModule::CallInit()
+int asCModule::CallInit(asIScriptContext *myCtx)
 {
 {
 	if( isGlobalVarInitialized ) 
 	if( isGlobalVarInitialized ) 
 		return asERROR;
 		return asERROR;
@@ -200,7 +197,7 @@ int asCModule::CallInit()
 	}
 	}
 
 
 	// Call the init function for each of the global variables
 	// Call the init function for each of the global variables
-	asIScriptContext *ctx = 0;
+	asIScriptContext *ctx = myCtx;
 	int r = asEXECUTION_FINISHED;
 	int r = asEXECUTION_FINISHED;
 	for( n = 0; n < scriptGlobals.GetLength() && r == asEXECUTION_FINISHED; n++ )
 	for( n = 0; n < scriptGlobals.GetLength() && r == asEXECUTION_FINISHED; n++ )
 	{
 	{
@@ -247,7 +244,7 @@ int asCModule::CallInit()
 		}
 		}
 	}
 	}
 
 
-	if( ctx )
+	if( ctx && !myCtx )
 	{
 	{
 		ctx->Release();
 		ctx->Release();
 		ctx = 0;
 		ctx = 0;
@@ -335,7 +332,9 @@ void asCModule::InternalReset()
 	// Free bind information
 	// Free bind information
 	for( n = 0; n < bindInformations.GetLength(); n++ )
 	for( n = 0; n < bindInformations.GetLength(); n++ )
 	{
 	{
-		engine->importedFunctions[bindInformations[n]->importedFunctionSignature->id & 0xFFFF] = 0 ;
+		asUINT id = bindInformations[n]->importedFunctionSignature->id & 0xFFFF;
+		engine->importedFunctions[id] = 0;
+		engine->freeImportedFunctionIdxs.PushLast(id);
 
 
 		asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
 		asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
 		asDELETE(bindInformations[n], sBindInfo);
 		asDELETE(bindInformations[n], sBindInfo);
@@ -386,9 +385,9 @@ int asCModule::GetFunctionIdByName(const char *name) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetImportedFunctionCount() const
+asUINT asCModule::GetImportedFunctionCount() const
 {
 {
-	return (int)bindInformations.GetLength();
+	return (asUINT)bindInformations.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -434,9 +433,9 @@ int asCModule::GetImportedFunctionIndexByDecl(const char *decl) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetFunctionCount() const
+asUINT asCModule::GetFunctionCount() const
 {
 {
-	return (int)globalFunctions.GetLength();
+	return (asUINT)globalFunctions.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -485,9 +484,9 @@ int asCModule::GetFunctionIdByDecl(const char *decl) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetGlobalVarCount() const
+asUINT asCModule::GetGlobalVarCount() const
 {
 {
-	return (int)scriptGlobals.GetLength();
+	return (asUINT)scriptGlobals.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -522,9 +521,9 @@ int asCModule::RemoveGlobalVar(asUINT index)
 }
 }
 
 
 // interface
 // interface
-asIScriptFunction *asCModule::GetFunctionDescriptorByIndex(int index) const
+asIScriptFunction *asCModule::GetFunctionDescriptorByIndex(asUINT index) const
 {
 {
-	if( index < 0 || index >= (int)globalFunctions.GetLength() )
+	if( index >= globalFunctions.GetLength() )
 		return 0;
 		return 0;
 
 
 	return globalFunctions[index];
 	return globalFunctions[index];
@@ -611,9 +610,9 @@ int asCModule::GetGlobalVar(asUINT index, const char **name, int *typeId, bool *
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetObjectTypeCount() const
+asUINT asCModule::GetObjectTypeCount() const
 {
 {
-	return (int)classTypes.GetLength();
+	return (asUINT)classTypes.GetLength();
 }
 }
 
 
 // interface 
 // interface 
@@ -638,9 +637,9 @@ int asCModule::GetTypeIdByDecl(const char *decl) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetEnumCount() const
+asUINT asCModule::GetEnumCount() const
 {
 {
-	return (int)enumTypes.GetLength();
+	return (asUINT)enumTypes.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -684,9 +683,9 @@ const char *asCModule::GetEnumValueByIndex(int enumTypeId, asUINT index, int *ou
 }
 }
 
 
 // interface
 // interface
-int asCModule::GetTypedefCount() const
+asUINT asCModule::GetTypedefCount() const
 {
 {
-	return (int)typeDefs.GetLength();
+	return (asUINT)typeDefs.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -705,6 +704,10 @@ const char *asCModule::GetTypedefByIndex(asUINT index, int *typeId) const
 // internal
 // internal
 int asCModule::GetNextImportedFunctionId()
 int asCModule::GetNextImportedFunctionId()
 {
 {
+	// TODO: multithread: This will break if one thread if freeing a module, while another is being compiled
+	if( engine->freeImportedFunctionIdxs.GetLength() )
+		return FUNC_IMPORTED | (asUINT)engine->freeImportedFunctionIdxs[engine->freeImportedFunctionIdxs.GetLength()-1];
+
 	return FUNC_IMPORTED | (asUINT)engine->importedFunctions.GetLength();
 	return FUNC_IMPORTED | (asUINT)engine->importedFunctions.GetLength();
 }
 }
 
 
@@ -784,7 +787,10 @@ int asCModule::AddImportedFunction(int id, const char *name, const asCDataType &
 	bindInformations.PushLast(info);
 	bindInformations.PushLast(info);
 
 
 	// Add the info to the array in the engine
 	// Add the info to the array in the engine
-	engine->importedFunctions.PushLast(info);
+	if( engine->freeImportedFunctionIdxs.GetLength() )
+		engine->importedFunctions[engine->freeImportedFunctionIdxs.PopLast()] = info;
+	else
+		engine->importedFunctions.PushLast(info);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -796,7 +802,7 @@ asCScriptFunction *asCModule::GetImportedFunction(int index) const
 }
 }
 
 
 // interface
 // interface
-int asCModule::BindImportedFunction(int index, int sourceId)
+int asCModule::BindImportedFunction(asUINT index, int sourceId)
 {
 {
 	// First unbind the old function
 	// First unbind the old function
 	int r = UnbindImportedFunction(index);
 	int r = UnbindImportedFunction(index);
@@ -830,9 +836,9 @@ int asCModule::BindImportedFunction(int index, int sourceId)
 }
 }
 
 
 // interface
 // interface
-int asCModule::UnbindImportedFunction(int index)
+int asCModule::UnbindImportedFunction(asUINT index)
 {
 {
-	if( index < 0 || index > (int)bindInformations.GetLength() )
+	if( index >= bindInformations.GetLength() )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 
 
 	// Remove reference to old module
 	// Remove reference to old module
@@ -847,7 +853,7 @@ int asCModule::UnbindImportedFunction(int index)
 }
 }
 
 
 // interface
 // interface
-const char *asCModule::GetImportedFunctionDeclaration(int index) const
+const char *asCModule::GetImportedFunctionDeclaration(asUINT index) const
 {
 {
 	asCScriptFunction *func = GetImportedFunction(index);
 	asCScriptFunction *func = GetImportedFunction(index);
 	if( func == 0 ) return 0;
 	if( func == 0 ) return 0;
@@ -860,9 +866,9 @@ const char *asCModule::GetImportedFunctionDeclaration(int index) const
 }
 }
 
 
 // interface
 // interface
-const char *asCModule::GetImportedFunctionSourceModule(int index) const
+const char *asCModule::GetImportedFunctionSourceModule(asUINT index) const
 {
 {
-	if( index >= (int)bindInformations.GetLength() )
+	if( index >= bindInformations.GetLength() )
 		return 0;
 		return 0;
 
 
 	return bindInformations[index]->importFromModule.AddressOf();
 	return bindInformations[index]->importFromModule.AddressOf();
@@ -909,8 +915,8 @@ int asCModule::BindAllImportedFunctions()
 // interface
 // interface
 int asCModule::UnbindAllImportedFunctions()
 int asCModule::UnbindAllImportedFunctions()
 {
 {
-	int c = GetImportedFunctionCount();
-	for( int n = 0; n < c; ++n )
+	asUINT c = GetImportedFunctionCount();
+	for( asUINT n = 0; n < c; ++n )
 		UnbindImportedFunction(n);
 		UnbindImportedFunction(n);
 
 
 	return asSUCCESS;
 	return asSUCCESS;
@@ -1053,7 +1059,7 @@ void asCModule::ResolveInterfaceIds(asCArray<void*> *substitutions)
 			if( classTypes[c]->IsInterface() )
 			if( classTypes[c]->IsInterface() )
 			{
 			{
 				asCObjectType *intf = classTypes[c];
 				asCObjectType *intf = classTypes[c];
-				for( int m = 0; m < intf->GetMethodCount(); m++ )
+				for( asUINT m = 0; m < intf->GetMethodCount(); m++ )
 				{
 				{
 					asCScriptFunction *func = engine->GetScriptFunction(intf->methods[m]);
 					asCScriptFunction *func = engine->GetScriptFunction(intf->methods[m]);
 					if( func )
 					if( func )
@@ -1061,7 +1067,7 @@ void asCModule::ResolveInterfaceIds(asCArray<void*> *substitutions)
 						if( func->returnType.GetObjectType() == equals[i].a )
 						if( func->returnType.GetObjectType() == equals[i].a )
 							func->returnType.SetObjectType(equals[i].b);
 							func->returnType.SetObjectType(equals[i].b);
 
 
-						for( int p = 0; p < func->GetParamCount(); p++ )
+						for( asUINT p = 0; p < func->GetParamCount(); p++ )
 						{
 						{
 							if( func->parameterTypes[p].GetObjectType() == equals[i].a )
 							if( func->parameterTypes[p].GetObjectType() == equals[i].a )
 								func->parameterTypes[p].SetObjectType(equals[i].b);
 								func->parameterTypes[p].SetObjectType(equals[i].b);

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

@@ -105,17 +105,17 @@ public:
 	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
 	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
 
 
 	// Script functions
 	// Script functions
-	virtual int                GetFunctionCount() const;
-	virtual int                GetFunctionIdByIndex(int index) const;
+	virtual asUINT             GetFunctionCount() const;
+	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
-	virtual asIScriptFunction *GetFunctionDescriptorByIndex(int index) const;
+	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
 	virtual int                RemoveFunction(int funcId);
 	virtual int                RemoveFunction(int funcId);
 
 
 	// Script global variables
 	// Script global variables
-	virtual int         ResetGlobalVars();
-	virtual int         GetGlobalVarCount() const;
+	virtual int         ResetGlobalVars(asIScriptContext *ctx);
+	virtual asUINT      GetGlobalVarCount() const;
 	virtual int         GetGlobalVarIndexByName(const char *name) const;
 	virtual int         GetGlobalVarIndexByName(const char *name) const;
 	virtual int         GetGlobalVarIndexByDecl(const char *decl) const;
 	virtual int         GetGlobalVarIndexByDecl(const char *decl) const;
 	virtual const char *GetGlobalVarDeclaration(asUINT index) const;
 	virtual const char *GetGlobalVarDeclaration(asUINT index) const;
@@ -124,27 +124,27 @@ public:
 	virtual int         RemoveGlobalVar(asUINT index);
 	virtual int         RemoveGlobalVar(asUINT index);
 
 
 	// Type identification
 	// Type identification
-	virtual int            GetObjectTypeCount() const;
+	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 
 
 	// Enums
 	// Enums
-	virtual int         GetEnumCount() const;
+	virtual asUINT      GetEnumCount() const;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId) const;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId) const;
 	virtual int         GetEnumValueCount(int enumTypeId) const;
 	virtual int         GetEnumValueCount(int enumTypeId) const;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const;
 
 
 	// Typedefs
 	// Typedefs
-	virtual int         GetTypedefCount() const;
+	virtual asUINT      GetTypedefCount() const;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId) const;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId) const;
 
 
 	// Dynamic binding between modules
 	// Dynamic binding between modules
-	virtual int         GetImportedFunctionCount() const;
+	virtual asUINT      GetImportedFunctionCount() const;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const;
 	virtual int         GetImportedFunctionIndexByDecl(const char *decl) const;
-	virtual const char *GetImportedFunctionDeclaration(int importIndex) const;
-	virtual const char *GetImportedFunctionSourceModule(int importIndex) const;
-	virtual int         BindImportedFunction(int index, int sourceID);
-	virtual int         UnbindImportedFunction(int importIndex);
+	virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const;
+	virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const;
+	virtual int         BindImportedFunction(asUINT index, int sourceID);
+	virtual int         UnbindImportedFunction(asUINT importIndex);
 	virtual int         BindAllImportedFunctions();
 	virtual int         BindAllImportedFunctions();
 	virtual int         UnbindAllImportedFunctions();
 	virtual int         UnbindAllImportedFunctions();
 
 
@@ -167,7 +167,7 @@ public:
 
 
 	void InternalReset();
 	void InternalReset();
 
 
-	int  CallInit();
+	int  CallInit(asIScriptContext *ctx);
 	void CallExit();
 	void CallExit();
 
 
 	void JITCompile();
 	void JITCompile();

+ 34 - 32
ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -274,9 +274,9 @@ int asCObjectType::GetSubTypeId() const
 	return asERROR;
 	return asERROR;
 }
 }
 
 
-int asCObjectType::GetInterfaceCount() const
+asUINT asCObjectType::GetInterfaceCount() const
 {
 {
-	return (int)interfaces.GetLength();
+	return (asUINT)interfaces.GetLength();
 }
 }
 
 
 asIObjectType *asCObjectType::GetInterface(asUINT index) const
 asIObjectType *asCObjectType::GetInterface(asUINT index) const
@@ -298,14 +298,14 @@ asIScriptEngine *asCObjectType::GetEngine() const
 	return engine;
 	return engine;
 }
 }
 
 
-int asCObjectType::GetFactoryCount() const
+asUINT asCObjectType::GetFactoryCount() const
 {
 {
-	return (int)beh.factories.GetLength();
+	return (asUINT)beh.factories.GetLength();
 }
 }
 
 
-int asCObjectType::GetFactoryIdByIndex(int index) const
+int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 {
 {
-	if( index < 0 || (unsigned)index >= beh.factories.GetLength() )
+	if( index >= beh.factories.GetLength() )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 
 
 	return beh.factories[index];
 	return beh.factories[index];
@@ -321,15 +321,15 @@ int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 }
 }
 
 
 // interface
 // interface
-int asCObjectType::GetMethodCount() const
+asUINT asCObjectType::GetMethodCount() const
 {
 {
-	return (int)methods.GetLength();
+	return (asUINT)methods.GetLength();
 }
 }
 
 
 // interface
 // interface
-int asCObjectType::GetMethodIdByIndex(int index, bool getVirtual) const
+int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 {
 {
-	if( index < 0 || (unsigned)index >= methods.GetLength() )
+	if( index >= methods.GetLength() )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 
 
 	if( !getVirtual )
 	if( !getVirtual )
@@ -397,9 +397,9 @@ int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 }
 }
 
 
 // interface
 // interface
-asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(int index, bool getVirtual) const
+asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const
 {
 {
-	if( index < 0 || (unsigned)index >= methods.GetLength() ) 
+	if( index >= methods.GetLength() ) 
 		return 0;
 		return 0;
 
 
 	if( !getVirtual )
 	if( !getVirtual )
@@ -413,13 +413,13 @@ asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(int index, bool get
 }
 }
 
 
 // interface
 // interface
-int asCObjectType::GetPropertyCount() const
+asUINT asCObjectType::GetPropertyCount() const
 {
 {
-	return (int)properties.GetLength();
+	return (asUINT)properties.GetLength();
 }
 }
 
 
 // interface
 // interface
-int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset) const
+int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference) const
 {
 {
 	if( index >= properties.GetLength() )
 	if( index >= properties.GetLength() )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
@@ -432,6 +432,8 @@ int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, boo
 		*isPrivate = properties[index]->isPrivate;
 		*isPrivate = properties[index]->isPrivate;
 	if( offset )
 	if( offset )
 		*offset = properties[index]->byteOffset;
 		*offset = properties[index]->byteOffset;
+	if( isReference )
+		*isReference = properties[index]->type.IsReference();
 
 
 	return 0;
 	return 0;
 }
 }
@@ -460,10 +462,10 @@ asIObjectType *asCObjectType::GetBaseType() const
 	return derivedFrom; 
 	return derivedFrom; 
 }
 }
 
 
-int asCObjectType::GetBehaviourCount() const
+asUINT asCObjectType::GetBehaviourCount() const
 {
 {
 	// Count the number of behaviours (except factory functions)
 	// Count the number of behaviours (except factory functions)
-	int count = 0;
+	asUINT count = 0;
 	
 	
 	if( beh.destruct )               count++;
 	if( beh.destruct )               count++;
 	if( beh.addref )                 count++;
 	if( beh.addref )                 count++;
@@ -478,8 +480,8 @@ int asCObjectType::GetBehaviourCount() const
 
 
 	// For reference types, the factories are also stored in the constructor
 	// For reference types, the factories are also stored in the constructor
 	// list, so it is sufficient to enumerate only those
 	// list, so it is sufficient to enumerate only those
-	count += (int)beh.constructors.GetLength();
-	count += (int)beh.operators.GetLength() / 2;
+	count += (asUINT)beh.constructors.GetLength();
+	count += (asUINT)beh.operators.GetLength() / 2;
 
 
 	return count;
 	return count;
 }
 }
@@ -487,63 +489,63 @@ int asCObjectType::GetBehaviourCount() const
 int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const
 int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const
 {
 {
 	// Find the correct behaviour
 	// Find the correct behaviour
-	int count = 0;
+	asUINT count = 0;
 
 
-	if( beh.destruct && count++ == (int)index ) // only increase count if the behaviour is registered
+	if( beh.destruct && count++ == index ) // only increase count if the behaviour is registered
 	{ 
 	{ 
 		if( outBehaviour ) *outBehaviour = asBEHAVE_DESTRUCT;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_DESTRUCT;
 		return beh.destruct;
 		return beh.destruct;
 	}
 	}
 
 
-	if( beh.addref && count++ == (int)index )
+	if( beh.addref && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ADDREF;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ADDREF;
 		return beh.addref;
 		return beh.addref;
 	}
 	}
 
 
-	if( beh.release && count++ == (int)index )
+	if( beh.release && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASE;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASE;
 		return beh.release;
 		return beh.release;
 	}
 	}
 
 
-	if( beh.gcGetRefCount && count++ == (int)index )
+	if( beh.gcGetRefCount && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETREFCOUNT;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETREFCOUNT;
 		return beh.gcGetRefCount;
 		return beh.gcGetRefCount;
 	}
 	}
 
 
-	if( beh.gcSetFlag && count++ == (int)index )
+	if( beh.gcSetFlag && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_SETGCFLAG;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_SETGCFLAG;
 		return beh.gcSetFlag;
 		return beh.gcSetFlag;
 	}
 	}
 
 
-	if( beh.gcGetFlag && count++ == (int)index )
+	if( beh.gcGetFlag && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETGCFLAG;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_GETGCFLAG;
 		return beh.gcGetFlag;
 		return beh.gcGetFlag;
 	}
 	}
 
 
-	if( beh.gcEnumReferences && count++ == (int)index )
+	if( beh.gcEnumReferences && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ENUMREFS;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_ENUMREFS;
 		return beh.gcEnumReferences;
 		return beh.gcEnumReferences;
 	}
 	}
 
 
-	if( beh.gcReleaseAllReferences && count++ == (int)index )
+	if( beh.gcReleaseAllReferences && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASEREFS;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASEREFS;
 		return beh.gcReleaseAllReferences;
 		return beh.gcReleaseAllReferences;
 	}
 	}
 
 
-	if( beh.templateCallback && count++ == (int)index )
+	if( beh.templateCallback && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_TEMPLATE_CALLBACK;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_TEMPLATE_CALLBACK;
 		return beh.templateCallback;
 		return beh.templateCallback;
 	}
 	}
 
 
-	if( beh.listFactory && count++ == (int)index )
+	if( beh.listFactory && count++ == index )
 	{
 	{
 		if( outBehaviour ) *outBehaviour = asBEHAVE_LIST_FACTORY;
 		if( outBehaviour ) *outBehaviour = asBEHAVE_LIST_FACTORY;
 		return beh.listFactory;
 		return beh.listFactory;
@@ -557,7 +559,7 @@ int asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour
 		return beh.constructors[index - count];
 		return beh.constructors[index - count];
 	}
 	}
 	else 
 	else 
-		count += (int)beh.constructors.GetLength();
+		count += (asUINT)beh.constructors.GetLength();
 
 
 	if( index - count < beh.operators.GetLength() / 2 )
 	if( index - count < beh.operators.GetLength() / 2 )
 	{
 	{

+ 11 - 11
ThirdParty/AngelScript/source/as_objecttype.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -151,29 +151,29 @@ public:
 	int              GetSubTypeId() const;
 	int              GetSubTypeId() const;
 
 
 	// Interfaces
 	// Interfaces
-	int              GetInterfaceCount() const;
+	asUINT           GetInterfaceCount() const;
 	asIObjectType   *GetInterface(asUINT index) const;
 	asIObjectType   *GetInterface(asUINT index) const;
 
 
 	// Factories
 	// Factories
-	int                GetFactoryCount() const;
-	int                GetFactoryIdByIndex(int index) const;
+	asUINT             GetFactoryCount() const;
+	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
 
 
 	// Methods
 	// Methods
-	int                GetMethodCount() const;
-	int                GetMethodIdByIndex(int index, bool getVirtual) const;
+	asUINT             GetMethodCount() const;
+	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
-	asIScriptFunction *GetMethodDescriptorByIndex(int index, bool getVirtual) const;
+	asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const;
 
 
 	// Properties
 	// Properties
-	int         GetPropertyCount() const;
-	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset) const;
+	asUINT      GetPropertyCount() const;
+	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference) const;
 	const char *GetPropertyDeclaration(asUINT index) const;
 	const char *GetPropertyDeclaration(asUINT index) const;
 
 
 	// Behaviours
 	// Behaviours
-	int GetBehaviourCount() const;
-	int GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
+	asUINT GetBehaviourCount() const;
+	int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
 
 
 //===========================================
 //===========================================
 // Internal
 // Internal

+ 14 - 2
ThirdParty/AngelScript/source/as_parser.cpp

@@ -598,7 +598,11 @@ bool asCParser::IsVarDecl()
 	if( t1.type == ttConst )
 	if( t1.type == ttConst )
 		GetToken(&t1);
 		GetToken(&t1);
 
 
-	if( !IsDataType(t1) )
+	// We don't validate if the identifier is an actual declared type at this moment
+	// as it may wrongly identify the statement as a non-declaration if the user typed
+	// the name incorrectly. The real type is validated in ParseDeclaration where a
+	// proper error message can be given.
+	if( !IsRealType(t1.type) && t1.type != ttIdentifier )
 	{
 	{
 		RewindTo(&t);
 		RewindTo(&t);
 		return false;
 		return false;
@@ -1395,7 +1399,15 @@ asCScriptNode *asCParser::ParseDataType(bool allowVariableType)
 	GetToken(&t1);
 	GetToken(&t1);
 	if( !IsDataType(t1) && !(allowVariableType && t1.type == ttQuestion) )
 	if( !IsDataType(t1) && !(allowVariableType && t1.type == ttQuestion) )
 	{
 	{
-		Error(TXT_EXPECTED_DATA_TYPE, &t1);
+		if( t1.type == ttIdentifier )
+		{
+			asCString errMsg, Identifier;
+			Identifier.Assign(&script->code[t1.pos], t1.length);
+			errMsg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, Identifier.AddressOf());
+			Error(errMsg.AddressOf(), &t1);
+		}
+		else
+			Error(TXT_EXPECTED_DATA_TYPE, &t1);
 		return node;
 		return node;
 	}
 	}
 
 

+ 16 - 3
ThirdParty/AngelScript/source/as_restore.cpp

@@ -356,8 +356,17 @@ int asCRestore::Restore()
 	{
 	{
 		sBindInfo *info = asNEW(sBindInfo);
 		sBindInfo *info = asNEW(sBindInfo);
 		info->importedFunctionSignature = ReadFunction(false, false);
 		info->importedFunctionSignature = ReadFunction(false, false);
-		info->importedFunctionSignature->id = int(FUNC_IMPORTED + engine->importedFunctions.GetLength());
-		engine->importedFunctions.PushLast(info);
+		if( engine->freeImportedFunctionIdxs.GetLength() )
+		{
+			int id = engine->freeImportedFunctionIdxs.PopLast();
+			info->importedFunctionSignature->id = int(FUNC_IMPORTED + id);
+			engine->importedFunctions[id] = info;
+		}
+		else
+		{
+			info->importedFunctionSignature->id = int(FUNC_IMPORTED + engine->importedFunctions.GetLength());
+			engine->importedFunctions.PushLast(info);
+		}
 		ReadString(&info->importFromModule);
 		ReadString(&info->importFromModule);
 		info->boundFunctionId = -1;
 		info->boundFunctionId = -1;
 		module->bindInformations[i] = info;
 		module->bindInformations[i] = info;
@@ -428,7 +437,11 @@ int asCRestore::Restore()
 			if( module->scriptGlobals[i]->GetInitFunc() )
 			if( module->scriptGlobals[i]->GetInitFunc() )
 				module->scriptGlobals[i]->GetInitFunc()->AddReferences();
 				module->scriptGlobals[i]->GetInitFunc()->AddReferences();
 
 
-		module->CallInit();
+		if( engine->ep.initGlobalVarsAfterBuild )
+		{
+			int r = module->ResetGlobalVars(0);
+			if( r < 0 ) error = true;
+		}
 	}
 	}
 
 
 	return error ? asERROR : asSUCCESS;
 	return error ? asERROR : asSUCCESS;

+ 18 - 2
ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -139,6 +139,10 @@ AS_API const char * asGetLibraryOptions()
 #ifdef AS_HAIKU
 #ifdef AS_HAIKU
 		"AS_HAIKU "
 		"AS_HAIKU "
 #endif
 #endif
+#ifdef AS_ILLUMOS
+		"AS_ILLUMOS "
+#endif
+
 
 
 	// CPU family
 	// CPU family
 #ifdef AS_PPC
 #ifdef AS_PPC
@@ -284,6 +288,10 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
 		ep.expandDefaultArrayToTemplate = value ? true : false;
 		ep.expandDefaultArrayToTemplate = value ? true : false;
 		break;
 		break;
 
 
+	case asEP_AUTO_GARBAGE_COLLECT:
+		ep.autoGarbageCollect = value ? true : false;
+		break;
+
 	default:
 	default:
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 	}
 	}
@@ -339,6 +347,9 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 
 
 	case asEP_EXPAND_DEF_ARRAY_TO_TMPL:
 	case asEP_EXPAND_DEF_ARRAY_TO_TMPL:
 		return ep.expandDefaultArrayToTemplate;
 		return ep.expandDefaultArrayToTemplate;
+
+	case asEP_AUTO_GARBAGE_COLLECT:
+		return ep.autoGarbageCollect;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -381,6 +392,7 @@ asCScriptEngine::asCScriptEngine()
 		ep.stringEncoding               = 0;         // utf8. 1 = utf16
 		ep.stringEncoding               = 0;         // utf8. 1 = utf16
 		ep.propertyAccessorMode         = 2;         // 0 = disable, 1 = app registered only, 2 = app and script created
 		ep.propertyAccessorMode         = 2;         // 0 = disable, 1 = app registered only, 2 = app and script created
 		ep.expandDefaultArrayToTemplate = false;
 		ep.expandDefaultArrayToTemplate = false;
+		ep.autoGarbageCollect           = true;
 	}
 	}
 
 
 	gc.engine = this;
 	gc.engine = this;
@@ -2849,6 +2861,7 @@ void asCScriptEngine::CallObjectMethod(void *obj, asSSystemFunctionInterface *i,
 		} p;
 		} p;
 		p.func = (void (*)())(i->func);
 		p.func = (void (*)())(i->func);
 		void (asCSimpleDummy::*f)() = p.mthd;
 		void (asCSimpleDummy::*f)() = p.mthd;
+		obj = (void*)(size_t(obj) + i->baseOffset);
 		(((asCSimpleDummy*)obj)->*f)();
 		(((asCSimpleDummy*)obj)->*f)();
 	}
 	}
 	else
 	else
@@ -2914,6 +2927,7 @@ bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 		} p;
 		} p;
 		p.func = (void (*)())(i->func);
 		p.func = (void (*)())(i->func);
 		bool (asCSimpleDummy::*f)() = (bool (asCSimpleDummy::*)())p.mthd;
 		bool (asCSimpleDummy::*f)() = (bool (asCSimpleDummy::*)())p.mthd;
+		obj = (void*)(size_t(obj) + i->baseOffset);
 		return (((asCSimpleDummy*)obj)->*f)();
 		return (((asCSimpleDummy*)obj)->*f)();
 	}
 	}
 	else
 	else
@@ -2980,6 +2994,7 @@ int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 		} p;
 		} p;
 		p.func = (void (*)())(i->func);
 		p.func = (void (*)())(i->func);
 		int (asCSimpleDummy::*f)() = (int (asCSimpleDummy::*)())p.mthd;
 		int (asCSimpleDummy::*f)() = (int (asCSimpleDummy::*)())p.mthd;
+		obj = (void*)(size_t(obj) + i->baseOffset);
 		return (((asCSimpleDummy*)obj)->*f)();
 		return (((asCSimpleDummy*)obj)->*f)();
 	}
 	}
 	else
 	else
@@ -3089,6 +3104,7 @@ void asCScriptEngine::CallObjectMethod(void *obj, void *param, asSSystemFunction
 		} p;
 		} p;
 		p.func = (void (*)())(i->func);
 		p.func = (void (*)())(i->func);
 		void (asCSimpleDummy::*f)(void *) = (void (asCSimpleDummy::*)(void *))(p.mthd);
 		void (asCSimpleDummy::*f)(void *) = (void (asCSimpleDummy::*)(void *))(p.mthd);
+		obj = (void*)(size_t(obj) + i->baseOffset);
 		(((asCSimpleDummy*)obj)->*f)(param);
 		(((asCSimpleDummy*)obj)->*f)(param);
 	}
 	}
 	else
 	else
@@ -3185,9 +3201,9 @@ int asCScriptEngine::GarbageCollect(asDWORD flags)
 }
 }
 
 
 // interface
 // interface
-void asCScriptEngine::GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected) const
+void asCScriptEngine::GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const
 {
 {
-	gc.GetStatistics(currentSize, totalDestroyed, totalDetected);
+	gc.GetStatistics(currentSize, totalDestroyed, totalDetected, newObjects, totalNewDestroyed);
 }
 }
 
 
 // interface
 // interface

+ 4 - 2
ThirdParty/AngelScript/source/as_scriptengine.h

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2010 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -174,7 +174,7 @@ public:
 
 
 	// Garbage collection
 	// Garbage collection
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE);
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE);
-	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected) const;
+	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId);
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId);
 	virtual void GCEnumCallback(void *reference);
 	virtual void GCEnumCallback(void *reference);
 
 
@@ -322,6 +322,7 @@ public:
 
 
 	// An array with all module imported functions
 	// An array with all module imported functions
 	asCArray<sBindInfo *>  importedFunctions;
 	asCArray<sBindInfo *>  importedFunctions;
+	asCArray<int>          freeImportedFunctionIdxs;
 
 
 	// These resources must be protected for multiple accesses
 	// These resources must be protected for multiple accesses
 	mutable asCAtomic      refCount;
 	mutable asCAtomic      refCount;
@@ -388,6 +389,7 @@ public:
 		int  stringEncoding;
 		int  stringEncoding;
 		int  propertyAccessorMode;
 		int  propertyAccessorMode;
 		bool expandDefaultArrayToTemplate;
 		bool expandDefaultArrayToTemplate;
+		bool autoGarbageCollect;
 	} ep;
 	} ep;
 };
 };
 
 

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

@@ -144,6 +144,10 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
 	userData               = 0;
 	userData               = 0;
 	id                     = 0;
 	id                     = 0;
 
 
+	// TODO: optimize: The engine could notify the GC just before it wants to
+	//                 discard the function. That way the GC won't waste time
+	//                 trying to determine if the functions are garbage before
+	//                 they can actually be considered garbage.
 	// Notify the GC of script functions
 	// Notify the GC of script functions
 	if( funcType == asFUNC_SCRIPT )
 	if( funcType == asFUNC_SCRIPT )
 		engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
 		engine->gc.AddScriptObjectToGC(this, &engine->functionBehaviours);
@@ -365,6 +369,28 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName) const
 	return str;
 	return str;
 }
 }
 
 
+// interface
+int asCScriptFunction::FindNextLineWithCode(int line) const
+{
+	if( lineNumbers.GetLength() == 0 ) return -1;
+
+	// Check if given line is outside function
+	// TODO: should start at declaration instead of first line of code
+	if( line < (lineNumbers[1]&0xFFFFF) ) return -1;
+	if( line > (lineNumbers[lineNumbers.GetLength()-1]&0xFFFFF) ) return -1;
+
+	// Find the line with code on or right after the input line
+	// TODO: optimize: Do binary search instead
+	if( line == (lineNumbers[1]&0xFFFFF) ) return line;
+	for( asUINT n = 3; n < lineNumbers.GetLength(); n += 2 )
+	{
+		if( line <= (lineNumbers[n]&0xFFFFF) )
+			return (lineNumbers[n]&0xFFFFF);
+	}
+
+	return -1;
+}
+
 // internal
 // internal
 int asCScriptFunction::GetLineNumber(int programPosition)
 int asCScriptFunction::GetLineNumber(int programPosition)
 {
 {
@@ -409,7 +435,7 @@ asEFuncType asCScriptFunction::GetFuncType() const
 }
 }
 
 
 // interface
 // interface
-int asCScriptFunction::GetVarCount() const
+asUINT asCScriptFunction::GetVarCount() const
 {
 {
 	return int(variables.GetLength());
 	return int(variables.GetLength());
 }
 }
@@ -446,9 +472,10 @@ const char *asCScriptFunction::GetVarDecl(asUINT index) const
 void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
 void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
 {
 {
 	asSScriptVariable *var = asNEW(asSScriptVariable);
 	asSScriptVariable *var = asNEW(asSScriptVariable);
-	var->name        = name;
-	var->type        = type;
-	var->stackOffset = stackOffset;
+	var->name                 = name;
+	var->type                 = type;
+	var->stackOffset          = stackOffset;
+	var->declaredAtProgramPos = 0;
 	variables.PushLast(var);
 	variables.PushLast(var);
 }
 }
 
 
@@ -729,15 +756,15 @@ int asCScriptFunction::GetReturnTypeId() const
 }
 }
 
 
 // interface
 // interface
-int asCScriptFunction::GetParamCount() const
+asUINT asCScriptFunction::GetParamCount() const
 {
 {
-	return (int)parameterTypes.GetLength();
+	return (asUINT)parameterTypes.GetLength();
 }
 }
 
 
 // interface
 // interface
-int asCScriptFunction::GetParamTypeId(int index, asDWORD *flags) const
+int asCScriptFunction::GetParamTypeId(asUINT index, asDWORD *flags) const
 {
 {
-	if( index < 0 || (unsigned)index >= parameterTypes.GetLength() )
+	if( index >= parameterTypes.GetLength() )
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 
 
 	if( flags )
 	if( flags )
@@ -970,17 +997,23 @@ void asCScriptFunction::ReleaseAllHandles(asIScriptEngine *)
 		case asBC_FREE:
 		case asBC_FREE:
 		case asBC_REFCPY:
 		case asBC_REFCPY:
 			{
 			{
-                asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(&byteCode[n]);
-				objType->Release();
-				*(void**)&byteCode[n+1] = 0;
+				asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(&byteCode[n]);
+				if( objType )
+				{
+					objType->Release();
+					*(void**)&byteCode[n+1] = 0;
+				}
 			}
 			}
 			break;
 			break;
 
 
 		case asBC_ALLOC:
 		case asBC_ALLOC:
 			{
 			{
 				asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(&byteCode[n]);
 				asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(&byteCode[n]);
-				objType->Release();
-				*(void**)&byteCode[n+1] = 0;
+				if( objType )
+				{
+					objType->Release();
+				*	(void**)&byteCode[n+1] = 0;
+				}
 
 
 				int func = asBC_INTARG(&byteCode[n]+AS_PTR_SIZE);
 				int func = asBC_INTARG(&byteCode[n]+AS_PTR_SIZE);
 				if( func )
 				if( func )

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

@@ -58,6 +58,7 @@ struct asSScriptVariable
 	asCString   name;
 	asCString   name;
 	asCDataType type;
 	asCDataType type;
 	int         stackOffset;
 	int         stackOffset;
+	asUINT      declaredAtProgramPos;
 };
 };
 
 
 enum asEObjVarInfoOption
 enum asEObjVarInfoOption
@@ -109,14 +110,15 @@ public:
 	bool                 IsReadOnly() const;
 	bool                 IsReadOnly() const;
 	bool                 IsPrivate() const;
 	bool                 IsPrivate() const;
 
 
-	int                  GetParamCount() const;
-	int                  GetParamTypeId(int index, asDWORD *flags = 0) const;
+	asUINT               GetParamCount() const;
+	int                  GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
 	int                  GetReturnTypeId() const;
 	int                  GetReturnTypeId() const;
 
 
 	// Debug information
 	// Debug information
-	int                  GetVarCount() const;
+	asUINT               GetVarCount() const;
 	int                  GetVar(asUINT index, const char **name, int *typeId = 0) const;
 	int                  GetVar(asUINT index, const char **name, int *typeId = 0) const;
 	const char *         GetVarDecl(asUINT index) const;
 	const char *         GetVarDecl(asUINT index) const;
+	int                  FindNextLineWithCode(int line) const;
 
 
 	// For JIT compilation
 	// For JIT compilation
 	asDWORD             *GetByteCode(asUINT *length = 0);
 	asDWORD             *GetByteCode(asUINT *length = 0);

+ 6 - 1
ThirdParty/AngelScript/source/as_scriptobject.cpp

@@ -40,6 +40,12 @@ BEGIN_AS_NAMESPACE
 asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *engine)
 asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *engine)
 {
 {
 	asIScriptContext *ctx;
 	asIScriptContext *ctx;
+
+	// TODO: optimize: There should be a pool for the context so it doesn't 
+	//                 have to be allocated just for creating the script object
+
+	// TODO: It must be possible for the application to debug the creation of the object too
+
 	int r = engine->CreateContext(&ctx, true);
 	int r = engine->CreateContext(&ctx, true);
 	if( r < 0 )
 	if( r < 0 )
 		return 0;
 		return 0;
@@ -54,7 +60,6 @@ asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *en
 	r = ctx->Execute();
 	r = ctx->Execute();
 	if( r != asEXECUTION_FINISHED )
 	if( r != asEXECUTION_FINISHED )
 	{
 	{
-		// TODO: Verify that the memory for the structure have been released already
 		ctx->Release();
 		ctx->Release();
 		return 0;
 		return 0;
 	}
 	}

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

@@ -43,7 +43,6 @@
 
 
 #define TXT_s_ALREADY_DECLARED            "'%s' is already declared"
 #define TXT_s_ALREADY_DECLARED            "'%s' is already declared"
 #define TXT_ARG_NOT_LVALUE                "Argument cannot be assigned. Output will be discarded."
 #define TXT_ARG_NOT_LVALUE                "Argument cannot be assigned. Output will be discarded."
-#define TXT_ASSIGN_IN_GLOBAL_EXPR         "Assignments are not allowed in global expressions"
 
 
 #define TXT_BOTH_MUST_BE_SAME                     "Both expressions must have the same type"
 #define TXT_BOTH_MUST_BE_SAME                     "Both expressions must have the same type"
 #define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
 #define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
@@ -89,7 +88,6 @@
 
 
 #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_COMPILE_DEF_ARG_d_IN_FUNC_s "Failed while compiling default arg for parameter %d in function '%s'"
 #define TXT_FOUND_MULTIPLE_ENUM_VALUES    "Found multiple matching enum values"
 #define TXT_FOUND_MULTIPLE_ENUM_VALUES    "Found multiple matching enum values"
-#define TXT_FUNCTION_IN_GLOBAL_EXPR       "Function calls are not allowed in global expressions"
 #define TXT_FUNCTION_ALREADY_EXIST        "A function with the same name and parameters already exist"
 #define TXT_FUNCTION_ALREADY_EXIST        "A function with the same name and parameters already exist"
 #define TXT_FUNCTION_s_NOT_FOUND          "Function '%s' not found"
 #define TXT_FUNCTION_s_NOT_FOUND          "Function '%s' not found"
 
 
@@ -106,7 +104,6 @@
 #define TXT_ILLEGAL_OPERATION_ON_s              "Illegal operation on '%s'"
 #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_TARGET_TYPE_FOR_REF_CAST    "Illegal target type for reference cast"
 #define TXT_ILLEGAL_VARIABLE_NAME_s             "Illegal variable name '%s'."
 #define TXT_ILLEGAL_VARIABLE_NAME_s             "Illegal variable name '%s'."
-#define TXT_INC_OP_IN_GLOBAL_EXPR               "Incremental operators are not allowed in global expressions"
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s     "Initialization lists cannot be used with '%s'"
 #define TXT_INIT_LIST_CANNOT_BE_USED_WITH_s     "Initialization lists cannot be used with '%s'"
 #define TXT_INTERFACE_s_ALREADY_IMPLEMENTED     "The interface '%s' is already implemented"
 #define TXT_INTERFACE_s_ALREADY_IMPLEMENTED     "The interface '%s' is already implemented"
 #define TXT_INVALID_BREAK                       "Invalid 'break'"
 #define TXT_INVALID_BREAK                       "Invalid 'break'"
@@ -120,7 +117,6 @@
 #define TXT_INVALID_UNICODE_VALUE               "Invalid unicode code point"
 #define TXT_INVALID_UNICODE_VALUE               "Invalid unicode code point"
 #define TXT_INVALID_UNICODE_SEQUENCE_IN_SRC     "Invalid unicode sequence in source"
 #define TXT_INVALID_UNICODE_SEQUENCE_IN_SRC     "Invalid unicode sequence in source"
 
 
-#define TXT_METHOD_IN_GLOBAL_EXPR                   "Object method calls are not allowed in global expressions"
 #define TXT_METHOD_CANT_HAVE_NAME_OF_CLASS          "The method cannot be named with the class name"
 #define TXT_METHOD_CANT_HAVE_NAME_OF_CLASS          "The method cannot be named with the class name"
 #define TXT_MISSING_IMPLEMENTATION_OF_s             "Missing implementation of '%s'"
 #define TXT_MISSING_IMPLEMENTATION_OF_s             "Missing implementation of '%s'"
 #define TXT_MORE_THAN_ONE_MATCHING_OP               "Found more than one matching operator"
 #define TXT_MORE_THAN_ONE_MATCHING_OP               "Found more than one matching operator"
@@ -150,6 +146,7 @@
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPES_s_AND_s "No matching operator that takes the types '%s' and '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPES_s_AND_s "No matching operator that takes the types '%s' and '%s' found"
 #define TXT_NON_CONST_METHOD_ON_CONST_OBJ          "Non-const method call on read-only object reference"
 #define TXT_NON_CONST_METHOD_ON_CONST_OBJ          "Non-const method call on read-only object reference"
+#define TXT_NOT_A_FUNC_s_IS_VAR                    "Expression doesn't form a function call. '%s' is a variable of a non-function type"
 #define TXT_NOT_ALL_PATHS_RETURN                   "Not all paths return a value"
 #define TXT_NOT_ALL_PATHS_RETURN                   "Not all paths return a value"
 #define TXT_s_NOT_DECLARED                         "'%s' is not declared"
 #define TXT_s_NOT_DECLARED                         "'%s' is not declared"
 #define TXT_NOT_EXACT                              "Implicit conversion of value is not exact"
 #define TXT_NOT_EXACT                              "Implicit conversion of value is not exact"

+ 12 - 1
ThirdParty/AngelScript/source/as_thread.cpp

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2008 Andreas Jonsson
+   Copyright (c) 2003-2011 Andreas Jonsson
 
 
    This software is provided 'as-is', without any express or implied 
    This software is provided 'as-is', without any express or implied 
    warranty. In no event will the authors be held liable for any 
    warranty. In no event will the authors be held liable for any 
@@ -262,6 +262,17 @@ void asCThreadCriticalSection::Leave()
 	LeaveCriticalSection(&criticalSection);
 	LeaveCriticalSection(&criticalSection);
 #endif
 #endif
 }
 }
+
+bool asCThreadCriticalSection::TryEnter()
+{
+#if defined AS_POSIX_THREADS
+	return !pthread_mutex_trylock(&criticalSection);
+#elif defined AS_WINDOWS_THREADS
+	return TryEnterCriticalSection(&criticalSection) ? true : false;
+#else
+	return true;
+#endif
+}
 #endif
 #endif
 
 
 //========================================================================
 //========================================================================