Browse Source

Migrated to AngelScript 2.22.0.

Lasse Öörni 14 years ago
parent
commit
2f0d3caecd
43 changed files with 2186 additions and 983 deletions
  1. 6 2
      Bin/Data/Scripts/Editor/EditorNodeWindow.as
  2. 1 1
      Docs/Reference.dox
  3. 1 1
      Docs/Urho3D.dox
  4. 2 2
      Engine/Script/Addons.cpp
  5. 3 3
      Engine/Script/Script.cpp
  6. 2 4
      Engine/Script/ScriptFile.cpp
  7. 1 1
      Readme.txt
  8. 81 23
      ThirdParty/AngelScript/include/angelscript.h
  9. 254 37
      ThirdParty/AngelScript/source/as_builder.cpp
  10. 5 2
      ThirdParty/AngelScript/source/as_builder.h
  11. 4 8
      ThirdParty/AngelScript/source/as_bytecode.cpp
  12. 60 7
      ThirdParty/AngelScript/source/as_callfunc.cpp
  13. 166 291
      ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp
  14. 0 200
      ThirdParty/AngelScript/source/as_callfunc_x64_msvc.asm
  15. 360 116
      ThirdParty/AngelScript/source/as_compiler.cpp
  16. 4 4
      ThirdParty/AngelScript/source/as_compiler.h
  17. 6 0
      ThirdParty/AngelScript/source/as_configgroup.cpp
  18. 10 1
      ThirdParty/AngelScript/source/as_configgroup.h
  19. 165 35
      ThirdParty/AngelScript/source/as_context.cpp
  20. 3 3
      ThirdParty/AngelScript/source/as_context.h
  21. 1 0
      ThirdParty/AngelScript/source/as_criticalsection.h
  22. 36 2
      ThirdParty/AngelScript/source/as_gc.cpp
  23. 2 0
      ThirdParty/AngelScript/source/as_gc.h
  24. 34 1
      ThirdParty/AngelScript/source/as_generic.cpp
  25. 5 1
      ThirdParty/AngelScript/source/as_generic.h
  26. 2 1
      ThirdParty/AngelScript/source/as_globalproperty.cpp
  27. 3 3
      ThirdParty/AngelScript/source/as_map.h
  28. 61 3
      ThirdParty/AngelScript/source/as_module.cpp
  29. 18 7
      ThirdParty/AngelScript/source/as_module.h
  30. 119 28
      ThirdParty/AngelScript/source/as_objecttype.cpp
  31. 21 8
      ThirdParty/AngelScript/source/as_objecttype.h
  32. 38 3
      ThirdParty/AngelScript/source/as_parser.cpp
  33. 5 1
      ThirdParty/AngelScript/source/as_property.h
  34. 333 57
      ThirdParty/AngelScript/source/as_restore.cpp
  35. 5 2
      ThirdParty/AngelScript/source/as_restore.h
  36. 260 63
      ThirdParty/AngelScript/source/as_scriptengine.cpp
  37. 42 29
      ThirdParty/AngelScript/source/as_scriptengine.h
  38. 26 18
      ThirdParty/AngelScript/source/as_scriptfunction.cpp
  39. 13 1
      ThirdParty/AngelScript/source/as_scriptfunction.h
  40. 4 5
      ThirdParty/AngelScript/source/as_scriptobject.cpp
  41. 3 3
      ThirdParty/AngelScript/source/as_scriptobject.h
  42. 16 2
      ThirdParty/AngelScript/source/as_texts.h
  43. 5 4
      ThirdParty/AngelScript/source/as_tokendef.h

+ 6 - 2
Bin/Data/Scripts/Editor/EditorNodeWindow.as

@@ -555,7 +555,9 @@ UIElement@ CreateAttributeEditor(ListView@ list, Array<Serializable@>@ serializa
     }
     }
     if (type == VAR_VARIANTMAP)
     if (type == VAR_VARIANTMAP)
     {
     {
-        VariantMap map = serializables[0].attributes[index].GetVariantMap();
+        // Get the variant first to avoid a crash with AngelScript 2.22.0 if the VariantMap is accessed directly
+        Variant value = serializables[0].attributes[index];
+        VariantMap map = value.GetVariantMap();
         Array<ShortStringHash>@ keys = map.keys;
         Array<ShortStringHash>@ keys = map.keys;
         for (uint i = 0; i < keys.length; ++i)
         for (uint i = 0; i < keys.length; ++i)
         {
         {
@@ -768,7 +770,9 @@ void StoreAttributeEditor(UIElement@ parent, Array<Serializable@>@ serializables
     {
     {
         for (uint i = 0; i < serializables.length; ++i)
         for (uint i = 0; i < serializables.length; ++i)
         {
         {
-            VariantMap map = serializables[i].attributes[index].GetVariantMap();
+            // Get the variant first to avoid a crash with AngelScript 2.22.0 if the VariantMap is accessed directly
+            Variant value = serializables[0].attributes[index];
+            VariantMap map = value.GetVariantMap();
             ShortStringHash key(parent.vars["Key"].GetUInt());
             ShortStringHash key(parent.vars["Key"].GetUInt());
             Variant newValue = GetEditorValue(parent, map[key].type, null);
             Variant newValue = GetEditorValue(parent, map[key].type, null);
             map[key] = newValue;
             map[key] = newValue;

+ 1 - 1
Docs/Reference.dox

@@ -328,7 +328,7 @@ There are some complexities of the scripting system one has to watch out for:
 
 
 - There is a maximum allowed nesting level (currently 32) for execution that moves between C++ & AngelScript. Nested execution typically occurs if you send an event to another ScriptInstance from a scripted event handler. If the nesting level is exceeded, an error will be logged and the script code that would have required the extra nesting level will not be executed.
 - There is a maximum allowed nesting level (currently 32) for execution that moves between C++ & AngelScript. Nested execution typically occurs if you send an event to another ScriptInstance from a scripted event handler. If the nesting level is exceeded, an error will be logged and the script code that would have required the extra nesting level will not be executed.
 
 
-- When the resource request for a particular ScriptFile is initially made, the script file and the files it includes are compiled into an AngelScript script module. Each script module has its own class hierarchy that is not usable from other script modules. Particularly casts to/from base classes will not work across script modules as you would expect, as the base class will actually be uniquely defined within each script module. Interfaces should work across modules. If access to a class hierarchy is needed, and using interfaces is not sufficient, it is best to ensure that only a single script module, which includes all the necessary classes, will be compiled. This could be for example the game's main program class, which would simply #include all the game object classes it needs. It may sound ugly to include a large number of files, but actually it is more memory-optimal to make one large script module, than several smaller ones which would duplicate the definition for eg. a game object base class.
+- When the resource request for a particular ScriptFile is initially made, the script file and the files it includes are compiled into an AngelScript script module. Each script module has its own class hierarchy that is not usable from other script modules, unless the classes are declared shared. See AngelScript documentation for more details.
 
 
 - If a ScriptFile resource is reloaded, all the script objects created from it will be destroyed, then recreated. They will lose any stored state as their constructors and Start() methods will be run again. This is rarely useful when running an actual game, but may be helpful during development.
 - If a ScriptFile resource is reloaded, all the script objects created from it will be destroyed, then recreated. They will lose any stored state as their constructors and Start() methods will be run again. This is rarely useful when running an actual game, but may be helpful during development.
 
 

+ 1 - 1
Docs/Urho3D.dox

@@ -59,7 +59,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.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.22.0 (http://www.angelcode.com/angelscript/)
 - 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/)
 - GLFW 3.0 WIP (http://www.glfw.org/)
 - GLFW 3.0 WIP (http://www.glfw.org/)

+ 2 - 2
Engine/Script/Addons.cpp

@@ -96,7 +96,7 @@ static bool ScriptArrayTemplateCallback(asIObjectType* ot)
                 if (beh != asBEHAVE_CONSTRUCT)
                 if (beh != asBEHAVE_CONSTRUCT)
                     continue;
                     continue;
                 
                 
-                asIScriptFunction* func = ot->GetEngine()->GetFunctionDescriptorById(funcId);
+                asIScriptFunction* func = ot->GetEngine()->GetFunctionById(funcId);
                 if (func->GetParamCount() == 0)
                 if (func->GetParamCount() == 0)
                 {
                 {
                     // Found the default constructor
                     // Found the default constructor
@@ -113,7 +113,7 @@ static bool ScriptArrayTemplateCallback(asIObjectType* ot)
             for (unsigned 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()->GetFunctionById(funcId);
                 if (func->GetParamCount() == 0)
                 if (func->GetParamCount() == 0)
                 {
                 {
                     // Found the default factory
                     // Found the default factory

+ 3 - 3
Engine/Script/Script.cpp

@@ -221,7 +221,7 @@ void Script::DumpAPI()
     for (unsigned i = 0; i < functions; ++i)
     for (unsigned i = 0; i < functions; ++i)
     {
     {
         unsigned id = scriptEngine_->GetGlobalFunctionIdByIndex(i);
         unsigned id = scriptEngine_->GetGlobalFunctionIdByIndex(i);
-        asIScriptFunction* function = scriptEngine_->GetFunctionDescriptorById(id);
+        asIScriptFunction* function = scriptEngine_->GetFunctionById(id);
         String functionName(function->GetName());
         String functionName(function->GetName());
         String declaration(function->GetDeclaration());
         String declaration(function->GetDeclaration());
         
         
@@ -279,7 +279,7 @@ void Script::DumpAPI()
             unsigned methods = type->GetMethodCount();
             unsigned methods = type->GetMethodCount();
             for (unsigned j = 0; j < methods; ++j)
             for (unsigned j = 0; j < methods; ++j)
             {
             {
-                asIScriptFunction* method = type->GetMethodDescriptorByIndex(j);
+                asIScriptFunction* method = type->GetMethodByIndex(j);
                 String methodName(method->GetName());
                 String methodName(method->GetName());
                 String declaration(method->GetDeclaration());
                 String declaration(method->GetDeclaration());
                 if (methodName.Find("get_") == String::NPOS && methodName.Find("set_") == String::NPOS)
                 if (methodName.Find("get_") == String::NPOS && methodName.Find("set_") == String::NPOS)
@@ -378,7 +378,7 @@ void Script::MessageCallback(const asSMessageInfo* msg)
 void Script::ExceptionCallback(asIScriptContext* context)
 void Script::ExceptionCallback(asIScriptContext* context)
 {
 {
     int funcId = context->GetExceptionFunction();
     int funcId = context->GetExceptionFunction();
-    const asIScriptFunction *function = scriptEngine_->GetFunctionDescriptorById(funcId);
+    const asIScriptFunction *function = scriptEngine_->GetFunctionById(funcId);
     String message = "Exception '" + String(context->GetExceptionString()) + "' in '" +
     String message = "Exception '" + String(context->GetExceptionString()) + "' in '" +
         String(function->GetDeclaration()) + "'";
         String(function->GetDeclaration()) + "'";
     
     

+ 2 - 4
Engine/Script/ScriptFile.cpp

@@ -302,8 +302,7 @@ asIScriptFunction* ScriptFile::GetFunction(const String& declaration)
     if (i != functions_.End())
     if (i != functions_.End())
         return i->second_;
         return i->second_;
     
     
-    int id = scriptModule_->GetFunctionIdByDecl(declaration.CString());
-    asIScriptFunction* function = scriptModule_->GetFunctionDescriptorById(id);
+    asIScriptFunction* function = scriptModule_->GetFunctionByDecl(declaration.CString());
     functions_[declaration] = function;
     functions_[declaration] = function;
     return function;
     return function;
 }
 }
@@ -324,8 +323,7 @@ asIScriptFunction* ScriptFile::GetMethod(asIScriptObject* object, const String&
             return j->second_;
             return j->second_;
     }
     }
     
     
-    int id = type->GetMethodIdByDecl(declaration.CString());
-    asIScriptFunction* function = scriptModule_->GetFunctionDescriptorById(id);
+    asIScriptFunction* function = type->GetMethodByDecl(declaration.CString());
     methods_[type][declaration] = function;
     methods_[type][declaration] = function;
     return function;
     return function;
 }
 }

+ 1 - 1
Readme.txt

@@ -34,7 +34,7 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org) and Horde3D
   http://warp.povusers.org/SortComparison/
   http://warp.povusers.org/SortComparison/
 
 
 Urho3D uses the following third-party libraries:
 Urho3D uses the following third-party libraries:
-- AngelScript 2.21.1 (http://www.angelcode.com/angelscript/)
+- AngelScript 2.22.0 (http://www.angelcode.com/angelscript/)
 - 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/)
 - GLFW 3.0 WIP (http://www.glfw.org/)
 - GLFW 3.0 WIP (http://www.glfw.org/)

+ 81 - 23
ThirdParty/AngelScript/include/angelscript.h

@@ -56,8 +56,8 @@ BEGIN_AS_NAMESPACE
 
 
 // AngelScript version
 // AngelScript version
 
 
-#define ANGELSCRIPT_VERSION        22101
-#define ANGELSCRIPT_VERSION_STRING "2.21.1"
+#define ANGELSCRIPT_VERSION        22200
+#define ANGELSCRIPT_VERSION_STRING "2.22.0"
 
 
 // Data types
 // Data types
 
 
@@ -91,7 +91,8 @@ enum asEEngineProp
 	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
+	asEP_AUTO_GARBAGE_COLLECT         = 16,
+	asEP_DISALLOW_GLOBAL_VARS         = 17
 };
 };
 
 
 // Calling conventions
 // Calling conventions
@@ -138,8 +139,11 @@ enum asEObjTypeFlags
 	asOBJ_APP_CLASS_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_CLASS_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_PRIMITIVE              = 0x2000,
 	asOBJ_APP_PRIMITIVE              = 0x2000,
 	asOBJ_APP_FLOAT                  = 0x4000,
 	asOBJ_APP_FLOAT                  = 0x4000,
-	asOBJ_MASK_VALID_FLAGS           = 0x7FFF,
-	asOBJ_SCRIPT_OBJECT              = 0x10000
+	asOBJ_APP_CLASS_ALLINTS          = 0x8000,
+	asOBJ_APP_CLASS_ALLFLOATS        = 0x10000,
+	asOBJ_MASK_VALID_FLAGS           = 0x1FFFF,
+	asOBJ_SCRIPT_OBJECT              = 0x80000,
+	asOBJ_SHARED                     = 0x100000
 };
 };
 
 
 // Behaviours
 // Behaviours
@@ -343,8 +347,14 @@ typedef void (*asGENFUNC_t)(asIScriptGeneric *);
 typedef void *(*asALLOCFUNC_t)(size_t);
 typedef void *(*asALLOCFUNC_t)(size_t);
 typedef void (*asFREEFUNC_t)(void *);
 typedef void (*asFREEFUNC_t)(void *);
 typedef void (*asCLEANENGINEFUNC_t)(asIScriptEngine *);
 typedef void (*asCLEANENGINEFUNC_t)(asIScriptEngine *);
+typedef void (*asCLEANMODULEFUNC_t)(asIScriptModule *);
 typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
 typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
 typedef void (*asCLEANFUNCTIONFUNC_t)(asIScriptFunction *);
 typedef void (*asCLEANFUNCTIONFUNC_t)(asIScriptFunction *);
+typedef void (*asCLEANOBJECTTYPEFUNC_t)(asIObjectType *);
+
+// This macro does basically the same thing as offsetof defined in stddef.h, but
+// GNUC should not complain about the usage as I'm not using 0 as the base pointer.
+#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)
 
 
 #define asFUNCTION(f) asFunctionPtr(f)
 #define asFUNCTION(f) asFunctionPtr(f)
 #if (defined(_MSC_VER) && _MSC_VER <= 1200) || (defined(__BORLANDC__) && __BORLANDC__ < 0x590)
 #if (defined(_MSC_VER) && _MSC_VER <= 1200) || (defined(__BORLANDC__) && __BORLANDC__ < 0x590)
@@ -492,14 +502,16 @@ public:
 	virtual asIJITCompiler *GetJITCompiler() const = 0;
 	virtual asIJITCompiler *GetJITCompiler() const = 0;
 
 
 	// Global functions
 	// Global functions
-	virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
-	virtual int GetGlobalFunctionCount() const = 0;
-	virtual int GetGlobalFunctionIdByIndex(asUINT index) const = 0;
+	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
+	virtual asUINT             GetGlobalFunctionCount() const = 0;
+	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const = 0;
+	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const = 0;
+	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const = 0;
 
 
 	// Global properties
 	// Global properties
-	virtual int RegisterGlobalProperty(const char *declaration, void *pointer) = 0;
-	virtual int GetGlobalPropertyCount() const = 0;
-	virtual int GetGlobalPropertyByIndex(asUINT index, const char **name, int *typeId = 0, bool *isConst = 0, const char **configGroup = 0, void **pointer = 0) const = 0;
+	virtual int    RegisterGlobalProperty(const char *declaration, void *pointer) = 0;
+	virtual asUINT GetGlobalPropertyCount() const = 0;
+	virtual int    GetGlobalPropertyByIndex(asUINT index, const char **name, int *typeId = 0, bool *isConst = 0, const char **configGroup = 0, void **pointer = 0) const = 0;
 
 
 	// Object types
 	// Object types
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags) = 0;
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags) = 0;
@@ -508,7 +520,7 @@ public:
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
 	virtual int            RegisterInterface(const char *name) = 0;
 	virtual int            RegisterInterface(const char *name) = 0;
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration) = 0;
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration) = 0;
-	virtual int            GetObjectTypeCount() const = 0;
+	virtual asUINT         GetObjectTypeCount() const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
 
 
 	// String factory
 	// String factory
@@ -522,33 +534,41 @@ public:
 	// Enums
 	// Enums
 	virtual int         RegisterEnum(const char *type) = 0;
 	virtual int         RegisterEnum(const char *type) = 0;
 	virtual int         RegisterEnumValue(const char *type, const char *name, int value) = 0;
 	virtual int         RegisterEnumValue(const char *type, const char *name, int value) = 0;
-	virtual int         GetEnumCount() const = 0;
+	virtual asUINT      GetEnumCount() const = 0;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **configGroup = 0) const = 0;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **configGroup = 0) 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;
 
 
 	// Funcdefs
 	// Funcdefs
 	virtual int                RegisterFuncdef(const char *decl) = 0;
 	virtual int                RegisterFuncdef(const char *decl) = 0;
-	virtual int                GetFuncdefCount() const = 0;
+	virtual asUINT             GetFuncdefCount() const = 0;
 	virtual asIScriptFunction *GetFuncdefByIndex(asUINT index, const char **configGroup = 0) const = 0;
 	virtual asIScriptFunction *GetFuncdefByIndex(asUINT index, const char **configGroup = 0) const = 0;
 
 
 	// Typedefs
 	// Typedefs
 	virtual int         RegisterTypedef(const char *type, const char *decl) = 0;
 	virtual int         RegisterTypedef(const char *type, const char *decl) = 0;
-	virtual int         GetTypedefCount() const = 0;
+	virtual asUINT      GetTypedefCount() const = 0;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **configGroup = 0) const = 0;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **configGroup = 0) const = 0;
 
 
 	// Configuration groups
 	// Configuration groups
 	virtual int BeginConfigGroup(const char *groupName) = 0;
 	virtual int BeginConfigGroup(const char *groupName) = 0;
 	virtual int EndConfigGroup() = 0;
 	virtual int EndConfigGroup() = 0;
 	virtual int RemoveConfigGroup(const char *groupName) = 0;
 	virtual int RemoveConfigGroup(const char *groupName) = 0;
+	virtual asDWORD SetDefaultAccessMask(asDWORD defaultMask) = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-04
 	virtual int SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess) = 0;
 	virtual int SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess) = 0;
+#endif
 
 
 	// Script modules
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag = asGM_ONLY_IF_EXISTS) = 0;
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag = asGM_ONLY_IF_EXISTS) = 0;
 	virtual int              DiscardModule(const char *module) = 0;
 	virtual int              DiscardModule(const char *module) = 0;
 
 
 	// Script functions
 	// Script functions
+	virtual asIScriptFunction *GetFunctionById(int funcId) const = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
+#endif
 
 
 	// Type identification
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const = 0;
 	virtual asIObjectType *GetObjectTypeById(int typeId) const = 0;
@@ -562,7 +582,9 @@ public:
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId) = 0;
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId) = 0;
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId) = 0;
 	virtual void              ReleaseScriptObject(void *obj, int typeId) = 0;
 	virtual void              ReleaseScriptObject(void *obj, int typeId) = 0;
+	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type) = 0;
 	virtual void              AddRefScriptObject(void *obj, int typeId) = 0;
 	virtual void              AddRefScriptObject(void *obj, int typeId) = 0;
+	virtual void              AddRefScriptObject(void *obj, const asIObjectType *type) = 0;
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const = 0;
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const = 0;
 
 
 	// String interpretation
 	// String interpretation
@@ -578,8 +600,10 @@ public:
 	virtual void *SetUserData(void *data) = 0;
 	virtual void *SetUserData(void *data) = 0;
 	virtual void *GetUserData() const = 0;
 	virtual void *GetUserData() const = 0;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback) = 0;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback) = 0;
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback) = 0;
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback) = 0;
 
 
 protected:
 protected:
 	virtual ~asIScriptEngine() {}
 	virtual ~asIScriptEngine() {}
@@ -593,18 +617,25 @@ public:
 	virtual const char      *GetName() const = 0;
 	virtual const char      *GetName() const = 0;
 
 
 	// Compilation
 	// Compilation
-	virtual int  AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
-	virtual int  Build() = 0;
-	virtual int  CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
-	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
+	virtual int     AddScriptSection(const char *name, const char *code, size_t codeLength = 0, int lineOffset = 0) = 0;
+	virtual int     Build() = 0;
+	virtual int     CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc) = 0;
+	virtual int     CompileGlobalVar(const char *sectionName, const char *code, int lineOffset) = 0;
+	virtual asDWORD SetAccessMask(asDWORD accessMask) = 0;
 
 
 	// Functions
 	// Functions
 	virtual asUINT             GetFunctionCount() const = 0;
 	virtual asUINT             GetFunctionCount() const = 0;
 	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
 	virtual int                GetFunctionIdByDecl(const char *decl) const = 0;
+	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const = 0;
+	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const = 0;
+	virtual asIScriptFunction *GetFunctionByName(const char *name) const = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
+#endif
 	virtual int                RemoveFunction(int funcId) = 0;
 	virtual int                RemoveFunction(int funcId) = 0;
 
 
 	// Global variables
 	// Global variables
@@ -646,6 +677,10 @@ public:
 	virtual int SaveByteCode(asIBinaryStream *out) const = 0;
 	virtual int SaveByteCode(asIBinaryStream *out) const = 0;
 	virtual int LoadByteCode(asIBinaryStream *in) = 0;
 	virtual int LoadByteCode(asIBinaryStream *in) = 0;
 
 
+	// User data
+	virtual void *SetUserData(void *data) = 0;
+	virtual void *GetUserData() const = 0;
+
 protected:
 protected:
 	virtual ~asIScriptModule() {}
 	virtual ~asIScriptModule() {}
 };
 };
@@ -661,6 +696,7 @@ public:
 	virtual asIScriptEngine *GetEngine() const = 0;
 	virtual asIScriptEngine *GetEngine() const = 0;
 
 
 	// Execution
 	// Execution
+	virtual int             Prepare(asIScriptFunction *func) = 0;
 	virtual int             Prepare(int funcId) = 0;
 	virtual int             Prepare(int funcId) = 0;
 	virtual int             Unprepare() = 0;
 	virtual int             Unprepare() = 0;
 	virtual int             SetObject(void *obj) = 0;
 	virtual int             SetObject(void *obj) = 0;
@@ -728,7 +764,11 @@ public:
 	// Miscellaneous
 	// Miscellaneous
 	virtual asIScriptEngine   *GetEngine() const = 0;
 	virtual asIScriptEngine   *GetEngine() const = 0;
 	virtual int                GetFunctionId() const = 0;
 	virtual int                GetFunctionId() const = 0;
+	virtual asIScriptFunction *GetFunction() const = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptor() const = 0;
 	virtual asIScriptFunction *GetFunctionDescriptor() const = 0;
+#endif
 	virtual void              *GetFunctionUserData() const = 0;
 	virtual void              *GetFunctionUserData() const = 0;
 
 
 	// Object
 	// Object
@@ -776,7 +816,7 @@ public:
 	virtual asIObjectType *GetObjectType() const = 0;
 	virtual asIObjectType *GetObjectType() const = 0;
 
 
 	// Class properties
 	// Class properties
-	virtual int         GetPropertyCount() const = 0;
+	virtual asUINT      GetPropertyCount() const = 0;
 	virtual int         GetPropertyTypeId(asUINT prop) const = 0;
 	virtual int         GetPropertyTypeId(asUINT prop) const = 0;
 	virtual const char *GetPropertyName(asUINT prop) const = 0;
 	virtual const char *GetPropertyName(asUINT prop) const = 0;
 	virtual void       *GetAddressOfProperty(asUINT prop) = 0;
 	virtual void       *GetAddressOfProperty(asUINT prop) = 0;
@@ -801,26 +841,37 @@ public:
 	// Type info
 	// Type info
 	virtual const char      *GetName() const = 0;
 	virtual const char      *GetName() const = 0;
 	virtual asIObjectType   *GetBaseType() const = 0;
 	virtual asIObjectType   *GetBaseType() const = 0;
+	virtual bool             DerivesFrom(const asIObjectType *objType) const = 0;
 	virtual asDWORD          GetFlags() const = 0;
 	virtual asDWORD          GetFlags() const = 0;
 	virtual asUINT           GetSize() const = 0;
 	virtual asUINT           GetSize() const = 0;
 	virtual int              GetTypeId() const = 0;
 	virtual int              GetTypeId() const = 0;
 	virtual int              GetSubTypeId() const = 0;
 	virtual int              GetSubTypeId() const = 0;
+	virtual asIObjectType   *GetSubType() const = 0;
 
 
 	// Interfaces
 	// Interfaces
 	virtual asUINT           GetInterfaceCount() const = 0;
 	virtual asUINT           GetInterfaceCount() const = 0;
 	virtual asIObjectType   *GetInterface(asUINT index) const = 0;
 	virtual asIObjectType   *GetInterface(asUINT index) const = 0;
+	virtual bool             Implements(const asIObjectType *objType) const = 0;
 
 
 	// Factories
 	// Factories
 	virtual asUINT             GetFactoryCount() const = 0;
 	virtual asUINT             GetFactoryCount() const = 0;
 	virtual int                GetFactoryIdByIndex(asUINT index) const = 0;
 	virtual int                GetFactoryIdByIndex(asUINT index) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
 	virtual int                GetFactoryIdByDecl(const char *decl) const = 0;
+	virtual asIScriptFunction *GetFactoryByIndex(asUINT index) const = 0;
+	virtual asIScriptFunction *GetFactoryByDecl(const char *decl) const = 0;
 
 
 	// Methods
 	// Methods
 	virtual asUINT             GetMethodCount() const = 0;
 	virtual asUINT             GetMethodCount() const = 0;
 	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByDecl(const char *decl, bool getVirtual = true) const = 0;
+	virtual asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual = true) const = 0;
+	virtual asIScriptFunction *GetMethodByName(const char *name, bool getVirtual = true) const = 0;
+	virtual asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual = true) const = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual = true) const = 0;
+#endif
 
 
 	// Properties
 	// Properties
 	virtual asUINT      GetPropertyCount() const = 0;
 	virtual asUINT      GetPropertyCount() const = 0;
@@ -831,6 +882,10 @@ public:
 	virtual asUINT GetBehaviourCount() const = 0;
 	virtual asUINT GetBehaviourCount() const = 0;
 	virtual int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
 	virtual int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
 
 
+	// User data
+	virtual void *SetUserData(void *data) = 0;
+	virtual void *GetUserData() const = 0;
+
 protected:
 protected:
 	virtual ~asIObjectType() {}
 	virtual ~asIObjectType() {}
 };
 };
@@ -949,7 +1004,9 @@ struct asSMethodPtr
 		// as it would mean that the size of the method pointer cannot be determined.
 		// as it would mean that the size of the method pointer cannot be determined.
 
 
 		int ERROR_UnsupportedMethodPtr[N-100];
 		int ERROR_UnsupportedMethodPtr[N-100];
-		return 0;
+
+		asSFuncPtr p;
+		return p;
 	}
 	}
 };
 };
 
 
@@ -1070,9 +1127,10 @@ struct asSVMRegisters
 	void             *objectRegister;     // temp register for objects and handles
 	void             *objectRegister;     // temp register for objects and handles
 	asIObjectType    *objectType;         // type of object held in object register
 	asIObjectType    *objectType;         // type of object held in object register
 	bool              doProcessSuspend;   // whether or not the JIT should break out when it encounters a suspend instruction
 	bool              doProcessSuspend;   // whether or not the JIT should break out when it encounters a suspend instruction
+	asIScriptContext *ctx;                // the active context
 };
 };
 
 
-typedef void (*asJITFunction)(asSVMRegisters *registers, asDWORD entryId);
+typedef void (*asJITFunction)(asSVMRegisters *registers, asPWORD jitArg);
 
 
 class asIJITCompiler
 class asIJITCompiler
 {
 {
@@ -1540,7 +1598,7 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO(CMPu64,	rW_rW_ARG,		0),
 	asBCINFO(CMPu64,	rW_rW_ARG,		0),
 	asBCINFO(ChkNullS,	W_ARG,			0),
 	asBCINFO(ChkNullS,	W_ARG,			0),
 	asBCINFO(ClrHi,		NO_ARG,			0),
 	asBCINFO(ClrHi,		NO_ARG,			0),
-	asBCINFO(JitEntry,	W_ARG,			0),
+	asBCINFO(JitEntry,	PTR_ARG,		0),
 	asBCINFO(CallPtr,   rW_ARG,         0xFFFF),
 	asBCINFO(CallPtr,   rW_ARG,         0xFFFF),
 	asBCINFO(FuncPtr,   PTR_ARG,        AS_PTR_SIZE),
 	asBCINFO(FuncPtr,   PTR_ARG,        AS_PTR_SIZE),
 	asBCINFO(LoadThisR, W_DW_ARG,       0),
 	asBCINFO(LoadThisR, W_DW_ARG,       0),

+ 254 - 37
ThirdParty/AngelScript/source/as_builder.cpp

@@ -427,6 +427,7 @@ void asCBuilder::ParseScripts()
 		for( n = 0; n < interfaceDeclarations.GetLength(); n++ )
 		for( n = 0; n < interfaceDeclarations.GetLength(); n++ )
 		{
 		{
 			sClassDeclaration *decl = interfaceDeclarations[n];
 			sClassDeclaration *decl = interfaceDeclarations[n];
+			if( decl->isExistingShared ) continue; // TODO: shared: Should really verify that the methods match the original
 
 
 			asCScriptNode *node = decl->node->firstChild->next;
 			asCScriptNode *node = decl->node->firstChild->next;
 			while( node )
 			while( node )
@@ -450,6 +451,7 @@ void asCBuilder::ParseScripts()
 		for( n = 0; n < classDeclarations.GetLength(); n++ )
 		for( n = 0; n < classDeclarations.GetLength(); n++ )
 		{
 		{
 			sClassDeclaration *decl = classDeclarations[n];
 			sClassDeclaration *decl = classDeclarations[n];
+			if( decl->isExistingShared ) continue; // TODO: shared: Should really verify that the methods match the original
 
 
 			asCScriptNode *node = decl->node->firstChild->next;
 			asCScriptNode *node = decl->node->firstChild->next;
 
 
@@ -669,22 +671,29 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
 {
 {
 	asASSERT(obj.GetObjectType() != 0);
 	asASSERT(obj.GetObjectType() != 0);
 
 
-	// TODO: Only search in config groups to which the module has access
 	// TODO: optimize: Improve linear search
 	// TODO: optimize: Improve linear search
 	asCArray<asCObjectProperty *> &props = obj.GetObjectType()->properties;
 	asCArray<asCObjectProperty *> &props = obj.GetObjectType()->properties;
 	for( asUINT n = 0; n < props.GetLength(); n++ )
 	for( asUINT n = 0; n < props.GetLength(); n++ )
+	{
 		if( props[n]->name == prop )
 		if( props[n]->name == prop )
-			return props[n];
+		{
+			if( module->accessMask & props[n]->accessMask )
+				return props[n];
+			else
+				return 0;
+		}
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue)
+asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp)
 {
 {
 	asUINT n;
 	asUINT n;
 
 
 	if( isCompiled ) *isCompiled = true;
 	if( isCompiled ) *isCompiled = true;
 	if( isPureConstant ) *isPureConstant = false;
 	if( isPureConstant ) *isPureConstant = false;
+	if( isAppProp ) *isAppProp = false;
 
 
 	// TODO: optimize: Improve linear search
 	// TODO: optimize: Improve linear search
 	// Check application registered properties
 	// Check application registered properties
@@ -694,14 +703,24 @@ asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, bool *isCompi
 		{
 		{
 			if( module )
 			if( module )
 			{
 			{
-				// Find the config group for the global property
-				asCConfigGroup *group = engine->FindConfigGroupForGlobalVar((*props)[n]->id);
-				if( !group || group->HasModuleAccess(module->name.AddressOf()) )
+				// Determine if the module has access to the property
+				if( module->accessMask & (*props)[n]->accessMask )
+				{
+#ifdef AS_DEPRECATED
+					// deprecated since 2011-10-04
+					// Find the config group for the global property
+					asCConfigGroup *group = engine->FindConfigGroupForGlobalVar((*props)[n]->id);
+					if( !group || group->HasModuleAccess(module->name.AddressOf()) )
+						continue;
+#endif
+					if( isAppProp ) *isAppProp = true;
 					return (*props)[n];
 					return (*props)[n];
+				}
 			}
 			}
 			else
 			else
 			{
 			{
 				// We're not compiling a module right now, so it must be a registered global property
 				// We're not compiling a module right now, so it must be a registered global property
+				if( isAppProp ) *isAppProp = true;
 				return (*props)[n];
 				return (*props)[n];
 			}
 			}
 		}
 		}
@@ -966,7 +985,7 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
 
 
 	// TODO: Must verify global properties in all config groups, whether the module has access or not
 	// TODO: Must verify global properties in all config groups, whether the module has access or not
 	// Check against global properties
 	// Check against global properties
-	asCGlobalProperty *prop = GetGlobalProperty(name, 0, 0, 0);
+	asCGlobalProperty *prop = GetGlobalProperty(name, 0, 0, 0, 0);
 	if( prop )
 	if( prop )
 	{
 	{
 		if( code )
 		if( code )
@@ -1115,6 +1134,14 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 
 
 int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file)
 int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file)
 {
 {
+	// Has the application disabled global vars?
+	if( engine->ep.disallowGlobalVars )
+	{
+		int r, c;
+		file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+		WriteError(file->name.AddressOf(), TXT_GLOBAL_VARS_NOT_ALLOWED, r, c);
+	}
+
 	// What data type is it?
 	// What data type is it?
 	asCDataType type = CreateDataTypeFromNode(node->firstChild, file);
 	asCDataType type = CreateDataTypeFromNode(node->firstChild, file);
 
 
@@ -1178,6 +1205,15 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 	asCScriptNode *n = node->firstChild;
 	asCScriptNode *n = node->firstChild;
 	asCString name(&file->code[n->tokenPos], n->tokenLength);
 	asCString name(&file->code[n->tokenPos], n->tokenLength);
 
 
+	bool isShared = false;
+	if( name == SHARED_TOKEN )
+	{
+		isShared = true;
+
+		n = n->next;
+		name.Assign(&file->code[n->tokenPos], n->tokenLength);
+	}
+
 	int r, c;
 	int r, c;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
 
@@ -1185,14 +1221,40 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	classDeclarations.PushLast(decl);
 	classDeclarations.PushLast(decl);
-	decl->name       = name;
-	decl->script     = file;
-	decl->validState = 0;
-	decl->node       = node;
+	decl->name             = name;
+	decl->script           = file;
+	decl->node             = node;
 
 
+	// If this type is shared and there already exist another shared 
+	// type of the same name, then that one should be used instead of
+	// creating a new one.
+	if( isShared )
+	{
+		for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+		{
+			asCObjectType *st = engine->classTypes[n];
+			if( st &&
+				st->IsShared() &&
+				st->name == name &&
+				!st->IsInterface() )
+			{
+				// We'll use the existing type
+				decl->isExistingShared = true;
+				decl->objType          = st;
+				module->classTypes.PushLast(st);
+				st->AddRef();
+				return 0;
+			}
+		}
+	}
+
+	// Create a new object type for this class
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 
 
+	if( isShared )
+		st->flags |= asOBJ_SHARED;
+
 	if( node->tokenType == ttHandle )
 	if( node->tokenType == ttHandle )
 		st->flags |= asOBJ_IMPLICIT_HANDLE;
 		st->flags |= asOBJ_IMPLICIT_HANDLE;
 
 
@@ -1204,6 +1266,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 	decl->objType = st;
 	decl->objType = st;
 
 
 	// Add script classes to the GC
 	// Add script classes to the GC
+	// TODO: optimize: Only add the class to the GC when the module won't use the type anymore
 	engine->gc.AddScriptObjectToGC(st, &engine->objectTypeBehaviours);
 	engine->gc.AddScriptObjectToGC(st, &engine->objectTypeBehaviours);
 
 
 	// Use the default script class behaviours
 	// Use the default script class behaviours
@@ -1231,6 +1294,15 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file)
 	asCScriptNode *n = node->firstChild;
 	asCScriptNode *n = node->firstChild;
 	asCString name(&file->code[n->tokenPos], n->tokenLength);
 	asCString name(&file->code[n->tokenPos], n->tokenLength);
 
 
+	bool isShared = false;
+	if( name == SHARED_TOKEN )
+	{
+		isShared = true;
+
+		n = n->next;
+		name.Assign(&file->code[n->tokenPos], n->tokenLength);
+	}
+
 	int r, c;
 	int r, c;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
 
@@ -1238,14 +1310,40 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file)
 
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	interfaceDeclarations.PushLast(decl);
 	interfaceDeclarations.PushLast(decl);
-	decl->name       = name;
-	decl->script     = file;
-	decl->validState = 0;
-	decl->node       = node;
+	decl->name             = name;
+	decl->script           = file;
+	decl->node             = node;
+
+	// If this type is shared and there already exist another shared 
+	// type of the same name, then that one should be used instead of
+	// creating a new one.
+	if( isShared )
+	{
+		for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+		{
+			asCObjectType *st = engine->classTypes[n];
+			if( st &&
+				st->IsShared() &&
+				st->name == name &&
+				st->IsInterface() )
+			{
+				// We'll use the existing type
+				decl->isExistingShared = true;
+				decl->objType          = st;
+				module->classTypes.PushLast(st);
+				st->AddRef();
+				return 0;
+			}
+		}
+	}
 
 
 	// Register the object type for the interface
 	// Register the object type for the interface
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
+
+	if( isShared )
+		st->flags |= asOBJ_SHARED;
+
 	st->size = 0; // Cannot be instanciated
 	st->size = 0; // Cannot be instanciated
 	st->name = name;
 	st->name = name;
 	module->classTypes.PushLast(st);
 	module->classTypes.PushLast(st);
@@ -1550,6 +1648,13 @@ void asCBuilder::CompileClasses()
 		// Find the base class that this class inherits from
 		// Find the base class that this class inherits from
 		bool multipleInheritance = false;
 		bool multipleInheritance = false;
 		asCScriptNode *node = decl->node->firstChild->next;
 		asCScriptNode *node = decl->node->firstChild->next;
+
+		if( decl->objType->IsShared() )
+		{
+			// Skip the keyword 'shared'
+			node = node->next;
+		}
+
 		while( node && node->nodeType == snIdentifier )
 		while( node && node->nodeType == snIdentifier )
 		{
 		{
 			// Get the interface name from the node
 			// Get the interface name from the node
@@ -1577,7 +1682,7 @@ void asCBuilder::CompileClasses()
 			else if( objType->size != 0 )
 			else if( objType->size != 0 )
 			{
 			{
 				// The class inherits from another script class
 				// The class inherits from another script class
-				if( decl->objType->derivedFrom != 0 )
+				if( !decl->isExistingShared && decl->objType->derivedFrom != 0 )
 				{
 				{
 					if( !multipleInheritance )
 					if( !multipleInheritance )
 					{
 					{
@@ -1608,15 +1713,43 @@ void asCBuilder::CompileClasses()
 
 
 					if( !error )
 					if( !error )
 					{
 					{
-						decl->objType->derivedFrom = objType;
-						objType->AddRef();
+						// A shared type may only inherit from other shared types
+						if( (decl->objType->IsShared()) && !(objType->IsShared()) )
+						{
+							int r, c;
+							file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+							asCString msg;
+							msg.Format(TXT_SHARED_CANNOT_INHERIT_FROM_NON_SHARED_s, objType->name.AddressOf());
+							WriteError(file->name.AddressOf(), msg.AddressOf(), r, c);
+							error = true;
+						}
+					}
+
+					if( !error )
+					{
+						if( decl->isExistingShared )
+						{
+							// Verify that the base class is the same as the original shared type
+							if( decl->objType->derivedFrom != objType )
+							{
+								int r, c;
+								file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+								WriteError(file->name.AddressOf(), TXT_SHARED_DOESNT_MATCH_ORIGINAL, r, c);
+							}
+						}
+						else
+						{
+							// Set the base class
+							decl->objType->derivedFrom = objType;
+							objType->AddRef();
+						}
 					}
 					}
 				}
 				}
 			}
 			}
 			else
 			else
 			{
 			{
 				// The class implements an interface
 				// The class implements an interface
-				if( decl->objType->Implements(objType) )
+				if( !decl->isExistingShared && decl->objType->Implements(objType) )
 				{
 				{
 					int r, c;
 					int r, c;
 					file->ConvertPosToRowCol(node->tokenPos, &r, &c);
 					file->ConvertPosToRowCol(node->tokenPos, &r, &c);
@@ -1626,7 +1759,32 @@ void asCBuilder::CompileClasses()
 				}
 				}
 				else
 				else
 				{
 				{
-					decl->objType->interfaces.PushLast(objType);
+					// A shared type may only implement from shared interfaces
+					if( (decl->objType->IsShared()) && !(objType->IsShared()) )
+					{
+						int r, c;
+						file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+						asCString msg;
+						msg.Format(TXT_SHARED_CANNOT_IMPLEMENT_NON_SHARED_s, objType->name.AddressOf());
+						WriteError(file->name.AddressOf(), msg.AddressOf(), r, c);
+					}
+					else
+					{
+						if( decl->isExistingShared )
+						{
+							// Verify that the original implements the same interface
+							if( !decl->objType->Implements(objType) )
+							{
+								int r, c;
+								file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+								WriteError(file->name.AddressOf(), TXT_SHARED_DOESNT_MATCH_ORIGINAL, r, c);
+							}
+						}
+						else
+						{
+							decl->objType->interfaces.PushLast(objType);
+						}
+					}
 				}
 				}
 			}
 			}
 
 
@@ -1664,6 +1822,11 @@ void asCBuilder::CompileClasses()
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 	{
 		sClassDeclaration *decl = classDeclarations[n];
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared )
+		{
+			// TODO: shared: Should really validate against original
+			continue;
+		}
 
 
 		// Add all properties and methods from the base class
 		// Add all properties and methods from the base class
 		if( decl->objType->derivedFrom )
 		if( decl->objType->derivedFrom )
@@ -1767,6 +1930,15 @@ void asCBuilder::CompileClasses()
 				asCDataType dt = CreateDataTypeFromNode(isPrivate ? node->firstChild->next : node->firstChild, file);
 				asCDataType dt = CreateDataTypeFromNode(isPrivate ? node->firstChild->next : node->firstChild, file);
 				asCString name(&file->code[node->lastChild->tokenPos], node->lastChild->tokenLength);
 				asCString name(&file->code[node->lastChild->tokenPos], node->lastChild->tokenLength);
 
 
+				if( decl->objType->IsShared() && dt.GetObjectType() && !dt.GetObjectType()->IsShared() )
+				{
+					int r, c;
+					file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+					asCString msg;
+					msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, dt.GetObjectType()->name.AddressOf());
+					WriteError(file->name.AddressOf(), msg.AddressOf(), r, c);
+				}
+
 				if( dt.IsReadOnly() )
 				if( dt.IsReadOnly() )
 				{
 				{
 					int r, c;
 					int r, c;
@@ -1793,6 +1965,7 @@ void asCBuilder::CompileClasses()
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 	{
 		sClassDeclaration *decl = classDeclarations[n];
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared ) continue;
 		for( asUINT m = 0; m < decl->objType->interfaces.GetLength(); m++ )
 		for( asUINT m = 0; m < decl->objType->interfaces.GetLength(); m++ )
 		{
 		{
 			asCObjectType *objType = decl->objType->interfaces[m];
 			asCObjectType *objType = decl->objType->interfaces[m];
@@ -1906,6 +2079,7 @@ void asCBuilder::CompileClasses()
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 	{
 		sClassDeclaration *decl = classDeclarations[n];
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared ) continue;
 		asCObjectType *ot = decl->objType;
 		asCObjectType *ot = decl->objType;
 
 
 		// Is there some path in which this structure is involved in circular references?
 		// Is there some path in which this structure is involved in circular references?
@@ -2049,6 +2223,10 @@ void asCBuilder::AddDefaultConstructor(asCObjectType *objType, asCScriptCode *fi
 	asCCompiler compiler(engine);
 	asCCompiler compiler(engine);
 	compiler.CompileFactory(this, file, engine->scriptFunctions[funcId]);
 	compiler.CompileFactory(this, file, engine->scriptFunctions[funcId]);
 	engine->scriptFunctions[funcId]->AddRef();
 	engine->scriptFunctions[funcId]->AddRef();
+
+	// If the object is shared, then the factory must also be marked as shared
+	if( objType->flags & asOBJ_SHARED )
+		engine->scriptFunctions[funcId]->isShared = true;
 }
 }
 
 
 int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file)
 int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file)
@@ -2081,11 +2259,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file)
 
 
 		// Store the location of this declaration for reference in name collisions
 		// Store the location of this declaration for reference in name collisions
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
-		decl->name       = name;
-		decl->script     = file;
-		decl->validState = 0;
-		decl->node       = NULL;
-		decl->objType    = st;
+		decl->name             = name;
+		decl->script           = file;
+		decl->objType          = st;
 		namedTypeDeclarations.PushLast(decl);
 		namedTypeDeclarations.PushLast(decl);
 
 
 		asCDataType type = CreateDataTypeFromNode(tmp, file);
 		asCDataType type = CreateDataTypeFromNode(tmp, file);
@@ -2201,11 +2377,9 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file)
 
 
 		// Store the location of this declaration for reference in name collisions
 		// Store the location of this declaration for reference in name collisions
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
 		sClassDeclaration *decl = asNEW(sClassDeclaration);
-		decl->name       = name;
-		decl->script     = file;
-		decl->validState = 0;
-		decl->node       = NULL;
-		decl->objType    = st;
+		decl->name             = name;
+		decl->script           = file;
+		decl->objType          = st;
 		namedTypeDeclarations.PushLast(decl);
 		namedTypeDeclarations.PushLast(decl);
 	}
 	}
 
 
@@ -2405,6 +2579,33 @@ int asCBuilder::RegisterScriptFunction(int funcId, asCScriptNode *node, asCScrip
 		WriteError(file->name.AddressOf(), TXT_DESTRUCTOR_MAY_NOT_HAVE_PARM, r, c);
 		WriteError(file->name.AddressOf(), TXT_DESTRUCTOR_MAY_NOT_HAVE_PARM, r, c);
 	}
 	}
 
 
+	// If class or interface is shared, then only shared types may be used in the method signature
+	if( objType && objType->IsShared() )
+	{
+		asCObjectType *ot = returnType.GetObjectType();
+		if( ot && !ot->IsShared() )
+		{
+			int r, c;
+			file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+			asCString msg;
+			msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, ot->name.AddressOf());
+			WriteError(file->name.AddressOf(), msg.AddressOf(), r, c);
+		}
+		
+		for( asUINT p = 0; p < parameterTypes.GetLength(); ++p )
+		{
+			asCObjectType *ot = parameterTypes[p].GetObjectType();
+			if( ot && !ot->IsShared() )
+			{
+				int r, c;
+				file->ConvertPosToRowCol(node->tokenPos, &r, &c);
+				asCString msg;
+				msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, ot->name.AddressOf());
+				WriteError(file->name.AddressOf(), msg.AddressOf(), r, c);
+			}
+		}
+	}
+
 	// TODO: Much of this can probably be reduced by using the IsSignatureEqual method
 	// TODO: Much of this can probably be reduced by using the IsSignatureEqual method
 	// Check that the same function hasn't been registered already
 	// Check that the same function hasn't been registered already
 	asCArray<int> funcs;
 	asCArray<int> funcs;
@@ -2485,7 +2686,11 @@ int asCBuilder::RegisterScriptFunction(int funcId, asCScriptNode *node, asCScrip
 			asCDataType dt = asCDataType::CreateObjectHandle(objType, false);
 			asCDataType dt = asCDataType::CreateObjectHandle(objType, false);
 			module->AddScriptFunction(file->idx, factoryId, name.AddressOf(), dt, parameterTypes.AddressOf(), inOutFlags.AddressOf(), defaultArgs.AddressOf(), (asUINT)parameterTypes.GetLength(), false);
 			module->AddScriptFunction(file->idx, factoryId, name.AddressOf(), dt, parameterTypes.AddressOf(), inOutFlags.AddressOf(), defaultArgs.AddressOf(), (asUINT)parameterTypes.GetLength(), false);
 
 
-			// Add a dummy function to the module so that it doesn't mix up the fund Ids
+			// If the object is shared, then the factory must also be marked as shared
+			if( objType->flags & asOBJ_SHARED )
+				engine->scriptFunctions[factoryId]->isShared = true;
+
+			// Add a dummy function to the builder so that it doesn't mix up the fund Ids
 			functions.PushLast(0);
 			functions.PushLast(0);
 
 
 			// Compile the factory immediately
 			// Compile the factory immediately
@@ -2647,10 +2852,17 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs)
 			engine->scriptFunctions[n]->objectType == 0 &&
 			engine->scriptFunctions[n]->objectType == 0 &&
 			engine->scriptFunctions[n]->name == name )
 			engine->scriptFunctions[n]->name == name )
 		{
 		{
-			// Find the config group for the global function
-			asCConfigGroup *group = engine->FindConfigGroupForFunction(engine->scriptFunctions[n]->id);
-			if( !group || group->HasModuleAccess(module->name.AddressOf()) )
+			// Verify if the module has access to the function
+			if( module->accessMask & engine->scriptFunctions[n]->accessMask )
+			{
+#ifdef AS_DEPRECATED
+				// deprecated since 2011-10-04
+				// Find the config group for the global function
+				asCConfigGroup *group = engine->FindConfigGroupForFunction(engine->scriptFunctions[n]->id);
+				if( !group || group->HasModuleAccess(module->name.AddressOf()) )
+#endif
 				funcs.PushLast(engine->scriptFunctions[n]->id);
 				funcs.PushLast(engine->scriptFunctions[n]->id);
+			}
 		}
 		}
 	}
 	}
 }
 }
@@ -2787,9 +2999,15 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 			if( ot->flags & asOBJ_IMPLICIT_HANDLE )
 			if( ot->flags & asOBJ_IMPLICIT_HANDLE )
 				isImplicitHandle = true;
 				isImplicitHandle = true;
 
 
+			// Make sure the module has access to the object type
+#ifdef AS_DEPRECATED
+			// deprecated since 2011-10-04
 			// Find the config group for the object type
 			// Find the config group for the object type
 			asCConfigGroup *group = engine->FindConfigGroupForObjectType(ot);
 			asCConfigGroup *group = engine->FindConfigGroupForObjectType(ot);
-			if( !module || !group || group->HasModuleAccess(module->name.AddressOf()) )
+			if( !module || ((module->accessMask & ot->accessMask) && (!group || group->HasModuleAccess(module->name.AddressOf()))) )
+#else
+			if( !module || (module->accessMask & ot->accessMask) )
+#endif
 			{
 			{
 				if(asOBJ_TYPEDEF == (ot->flags & asOBJ_TYPEDEF))
 				if(asOBJ_TYPEDEF == (ot->flags & asOBJ_TYPEDEF))
 				{
 				{
@@ -2995,7 +3213,6 @@ asCDataType asCBuilder::ModifyDataTypeFromNode(const asCDataType &type, asCScrip
 
 
 asCObjectType *asCBuilder::GetObjectType(const char *type)
 asCObjectType *asCBuilder::GetObjectType(const char *type)
 {
 {
-	// TODO: Only search in config groups to which the module has access
 	asCObjectType *ot = engine->GetObjectType(type);
 	asCObjectType *ot = engine->GetObjectType(type);
 	if( !ot && module )
 	if( !ot && module )
 		ot = module->GetObjectType(type);
 		ot = module->GetObjectType(type);
@@ -3007,7 +3224,7 @@ asCScriptFunction *asCBuilder::GetFuncDef(const char *type)
 {
 {
 	for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 	for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 	{
 	{
-		// TODO: Only return the definitions for the config groups that the module has access to
+		// TODO: access: Only return the definitions that the module has access to
 		if( engine->registeredFuncDefs[n]->name == type )
 		if( engine->registeredFuncDefs[n]->name == type )
 		{
 		{
 			return engine->registeredFuncDefs[n];
 			return engine->registeredFuncDefs[n];

+ 5 - 2
ThirdParty/AngelScript/source/as_builder.h

@@ -76,11 +76,14 @@ struct sGlobalVariableDescription
 
 
 struct sClassDeclaration
 struct sClassDeclaration
 {
 {
+	sClassDeclaration() {script = 0; node = 0; validState = 0; objType = 0; isExistingShared = false;}
+
 	asCScriptCode *script;
 	asCScriptCode *script;
 	asCScriptNode *node;
 	asCScriptNode *node;
 	asCString name;
 	asCString name;
 	int validState;
 	int validState;
 	asCObjectType *objType;
 	asCObjectType *objType;
+	bool isExistingShared;
 };
 };
 
 
 struct sFuncDef
 struct sFuncDef
@@ -126,9 +129,9 @@ protected:
 	friend class asCParser;
 	friend class asCParser;
 
 
 	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
 	asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
-	asCGlobalProperty *GetGlobalProperty(const char *prop, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue);
+	asCGlobalProperty *GetGlobalProperty(const char *prop, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
 
 
-	asCScriptFunction *GetFunctionDescription(int funcID);
+	asCScriptFunction *GetFunctionDescription(int funcId);
 	void GetFunctionDescriptions(const char *name, asCArray<int> &funcs);
 	void GetFunctionDescriptions(const char *name, asCArray<int> &funcs);
 	void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
 	void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
 
 

+ 4 - 8
ThirdParty/AngelScript/source/as_bytecode.cpp

@@ -1353,8 +1353,7 @@ void asCByteCode::Call(asEBCInstr instr, int funcID, int pop)
 	*((int*)ARG_DW(last->arg)) = funcID;
 	*((int*)ARG_DW(last->arg)) = funcID;
 
 
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
-    // TODO: Should this be done by the compiler?
-    InstrWORD(asBC_JitEntry, 0);
+    InstrPTR(asBC_JitEntry, 0);
 }
 }
 
 
 void asCByteCode::CallPtr(asEBCInstr instr, int funcPtrVar, int pop)
 void asCByteCode::CallPtr(asEBCInstr instr, int funcPtrVar, int pop)
@@ -1370,8 +1369,7 @@ void asCByteCode::CallPtr(asEBCInstr instr, int funcPtrVar, int pop)
 	last->wArg[0] = (short)funcPtrVar;
 	last->wArg[0] = (short)funcPtrVar;
 
 
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
-    // TODO: Should this be done by the compiler?
-    InstrWORD(asBC_JitEntry, 0);
+    InstrPTR(asBC_JitEntry, 0);
 }
 }
 
 
 void asCByteCode::Alloc(asEBCInstr instr, void *objID, int funcID, int pop)
 void asCByteCode::Alloc(asEBCInstr instr, void *objID, int funcID, int pop)
@@ -1388,8 +1386,7 @@ void asCByteCode::Alloc(asEBCInstr instr, void *objID, int funcID, int pop)
 	*((int*)(ARG_DW(last->arg)+AS_PTR_SIZE)) = funcID;
 	*((int*)(ARG_DW(last->arg)+AS_PTR_SIZE)) = funcID;
 
 
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
     // Add a JitEntry instruction after function calls so that JIT's can resume execution
-    // TODO: Should this be done by the compiler?
-    InstrWORD(asBC_JitEntry, 0);
+    InstrPTR(asBC_JitEntry, 0);
 }
 }
 
 
 void asCByteCode::Ret(int pop)
 void asCByteCode::Ret(int pop)
@@ -1448,8 +1445,7 @@ void asCByteCode::Line(int line, int column)
 	*((int*)ARG_DW(last->arg)) = (line & 0xFFFFF)|((column & 0xFFF)<<20);
 	*((int*)ARG_DW(last->arg)) = (line & 0xFFFFF)|((column & 0xFFF)<<20);
 
 
     // Add a JitEntry after the line instruction to allow the JIT function to resume after a suspend
     // Add a JitEntry after the line instruction to allow the JIT function to resume after a suspend
-    // TODO: Should this be done by the compiler?
-    InstrWORD(asBC_JitEntry, 0);
+    InstrPTR(asBC_JitEntry, 0);
 }
 }
 
 
 void asCByteCode::ObjInfo(int offset, int info)
 void asCByteCode::ObjInfo(int offset, int info)

+ 60 - 7
ThirdParty/AngelScript/source/as_callfunc.cpp

@@ -181,6 +181,10 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 				{
 				{
 					internal->hostReturnInMemory = false;
 					internal->hostReturnInMemory = false;
 					internal->hostReturnSize     = func->returnType.GetSizeInMemoryDWords();
 					internal->hostReturnSize     = func->returnType.GetSizeInMemoryDWords();
+#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
+					if( func->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS )
+						internal->hostReturnFloat = true;
+#endif
 				}
 				}
 
 
 #ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
 #ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
@@ -211,6 +215,24 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 				}
 				}
 #endif
 #endif
 			}
 			}
+
+#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
+			// It's not safe to return objects by value because different registers
+			// will be used depending on the memory layout of the object.
+			// Ref: http://www.x86-64.org/documentation/abi.pdf
+			// Ref: http://www.agner.org/optimize/calling_conventions.pdf
+			// If the application informs that the class should be treated as all integers, then we allow it
+			if( !internal->hostReturnInMemory &&
+				!(func->returnType.GetObjectType()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )	
+			{
+				engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
+
+				asCString str;
+				str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format().AddressOf());
+				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
+				engine->ConfigError(asINVALID_CONFIGURATION);
+			}
+#endif
 		}
 		}
 		else if( objType & asOBJ_APP_PRIMITIVE )
 		else if( objType & asOBJ_APP_PRIMITIVE )
 		{
 		{
@@ -291,6 +313,8 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 #ifdef SPLIT_OBJS_BY_MEMBER_TYPES
 #ifdef SPLIT_OBJS_BY_MEMBER_TYPES
 			// It's not safe to pass objects by value because different registers
 			// It's not safe to pass objects by value because different registers
 			// will be used depending on the memory layout of the object
 			// will be used depending on the memory layout of the object
+			// Ref: http://www.x86-64.org/documentation/abi.pdf
+			// Ref: http://www.agner.org/optimize/calling_conventions.pdf
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 			if( !(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )	
 			if( !(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )	
 #endif
 #endif
@@ -378,13 +402,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	void    *obj               = 0;
 	void    *obj               = 0;
 	int      popSize           = sysFunc->paramSize;
 	int      popSize           = sysFunc->paramSize;
 
 
-	context->regs.objectType = descr->returnType.GetObjectType();
-	if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
-	{
-		// Allocate the memory for the object
-		retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
-	}
-
 	if( callConv >= ICC_THISCALL )
 	if( callConv >= ICC_THISCALL )
 	{
 	{
 		if( objectPointer )
 		if( objectPointer )
@@ -421,6 +438,24 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 		}
 		}
 	}
 	}
 
 
+	context->regs.objectType = descr->returnType.GetObjectType();
+	if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
+	{
+#ifndef AS_OLD
+		// Get the address of the location for the return value from the stack
+		retPointer = (void*)*(size_t*)(args);
+		popSize += AS_PTR_SIZE;
+		args += AS_PTR_SIZE;
+
+		// When returning the value on the location allocated by the called we shouldn't set the object type in the register
+		context->regs.objectType = 0;
+#else
+		// Allocate the memory for the object
+		retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
+#endif
+	}
+
+
 	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
 	retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
 
 
 #if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
 #if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
@@ -511,6 +546,24 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 
 
 			// Store the object in the register
 			// Store the object in the register
 			context->regs.objectRegister = retPointer;
 			context->regs.objectRegister = retPointer;
+
+#ifndef AS_OLD
+			// If the value is returned on the stack we shouldn't update the object register
+			if( descr->DoesReturnOnStack() )
+			{
+				context->regs.objectRegister = 0;
+
+				if( context->status == asEXECUTION_EXCEPTION )
+				{
+					// If the function raised a script exception it really shouldn't have 
+					// initialized the object. However, as it is a soft exception there is 
+					// no way for the application to not return a value, so instead we simply
+					// destroy it here, to pretend it was never created.
+					if( descr->returnType.GetObjectType()->beh.destruct )
+						engine->CallObjectMethod(retPointer, descr->returnType.GetObjectType()->beh.destruct);
+				}
+			}
+#endif
 		}
 		}
 	}
 	}
 	else
 	else

+ 166 - 291
ThirdParty/AngelScript/source/as_callfunc_x64_gcc.cpp

@@ -46,13 +46,12 @@
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
-enum argTypes { x64ENDARG = 0, x64INTARG = 1, x64FLOATARG = 2, x64DOUBLEARG = 3, x64VARIABLE = 4 };
+enum argTypes { x64INTARG = 0, x64FLOATARG = 1 };
 typedef asQWORD ( *funcptr_t )( void );
 typedef asQWORD ( *funcptr_t )( void );
 
 
 #define X64_MAX_ARGS             32
 #define X64_MAX_ARGS             32
 #define MAX_CALL_INT_REGISTERS    6
 #define MAX_CALL_INT_REGISTERS    6
 #define MAX_CALL_SSE_REGISTERS    8
 #define MAX_CALL_SSE_REGISTERS    8
-#define CALLSTACK_MULTIPLIER      2
 #define X64_CALLSTACK_SIZE        ( X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 )
 #define X64_CALLSTACK_SIZE        ( X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 )
 
 
 // Note to self: Always remember to inform the used registers on the clobber line, 
 // Note to self: Always remember to inform the used registers on the clobber line, 
@@ -67,41 +66,6 @@ typedef asQWORD ( *funcptr_t )( void );
 		: "%rax"                                 \
 		: "%rax"                                 \
 	)
 	)
 
 
-// While movq really should be used to move from general 
-// purpose register to xmm register, this is isn't accepted
-// by older GNUC versions, where movd should be used instead.
-// Reference: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43215
-#if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
-#define POP_LONG( reg )                          \
-	__asm__ __volatile__ (                       \
-		"popq     %%rax\n"                       \
-		"movq     %%rax, %" reg                  \
-		:                                        \
-		:                                        \
-		: "%rax", reg                            \
-	)
-
-#define POP_LONG_XMM( reg )                      \
-	__asm__ __volatile__ (                       \
-		"popq     %%rax\n"                       \
-		"movd     %%rax, %" reg                  \
-		:                                        \
-		:                                        \
-		: "%rax", reg                            \
-	)
-#else
-#define POP_LONG( reg )                          \
-	__asm__ __volatile__ (                       \
-		"popq     %%rax\n"                       \
-		"movq     %%rax, %" reg                  \
-		:                                        \
-		:                                        \
-		: "%rax", reg                            \
-	)
-
-#define POP_LONG_XMM( reg ) POP_LONG( reg )
-#endif
-
 #define ASM_GET_REG( name, dest )                \
 #define ASM_GET_REG( name, dest )                \
 	__asm__ __volatile__ (                       \
 	__asm__ __volatile__ (                       \
 		"movq %" name ", %0\n"                   \
 		"movq %" name ", %0\n"                   \
@@ -121,7 +85,7 @@ static asDWORD GetReturnedFloat()
 		"movss    %%xmm0, (%%rax)"
 		"movss    %%xmm0, (%%rax)"
 		: /* no output */
 		: /* no output */
 		: "m" (retval)
 		: "m" (retval)
-		: "%rax"
+		: "%rax", "%xmm0"
 	);
 	);
 
 
 	// We need to avoid implicit conversions from float to unsigned - we need
 	// We need to avoid implicit conversions from float to unsigned - we need
@@ -141,7 +105,7 @@ static asQWORD GetReturnedDouble()
 		"movlpd  %%xmm0, (%%rax)"
 		"movlpd  %%xmm0, (%%rax)"
 		: /* no optput */
 		: /* no optput */
 		: "m" (retval)
 		: "m" (retval)
-		: "%rax"
+		: "%rax", "%xmm0"
 	);
 	);
 
 
 	// We need to avoid implicit conversions from double to unsigned long long - we need
 	// We need to avoid implicit conversions from double to unsigned long long - we need
@@ -151,55 +115,76 @@ static asQWORD GetReturnedDouble()
 	return ret;
 	return ret;
 }
 }
 
 
-// Note to self: If there is any trouble with a function when it is optimized, gcc supports
-// turning off optimization for individual functions by adding the following to the declaration:
-// __attribute__ ((optimize(0)))
+static void __attribute__((noinline)) GetReturnedXmm0Xmm1(asQWORD &a, asQWORD &b)
+{
+	__asm__ __volatile__ (
+		"lea     %0, %%rax\n"
+		"movq  %%xmm0, (%%rax)\n"
+		"lea     %1, %%rdx\n"
+		"movq  %%xmm1, (%%rdx)\n" 
+		: // no optput
+		: "m" (a), "m" (b)
+		: "%rax", "%rdx", "%xmm0", "%xmm1"
+	);
+}
 
 
-static asQWORD __attribute__ ((noinline)) X64_CallFunction( const asDWORD* pArgs, const asBYTE *pArgsType, void *func )
+static asQWORD __attribute__((noinline)) X64_CallFunction( const asQWORD *args, int cnt, void *func ) 
 {
 {
-	asQWORD retval      = 0;
+	asQWORD retval;
 	asQWORD ( *call )() = (asQWORD (*)())func;
 	asQWORD ( *call )() = (asQWORD (*)())func;
 	int     i           = 0;
 	int     i           = 0;
 
 
-	/* push the stack parameters */
-	for ( i = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS; pArgsType[i] != x64ENDARG && ( i < X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 ); i++ ) {
-		PUSH_LONG( pArgs[i * CALLSTACK_MULTIPLIER] );
-	}
-
-	/* push integer parameters */
-	for ( i = 0; i < MAX_CALL_INT_REGISTERS; i++ ) {
-		PUSH_LONG( pArgs[i * CALLSTACK_MULTIPLIER] );
-	}
-
-	/* push floating point parameters */
-	for ( i = MAX_CALL_INT_REGISTERS; i < MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS; i++ ) {
-		PUSH_LONG( pArgs[i * CALLSTACK_MULTIPLIER] );
-	}
-
-	/* now pop the registers in reverse order and make the call */
-	POP_LONG_XMM( "%xmm7" );
-	POP_LONG_XMM( "%xmm6" );
-	POP_LONG_XMM( "%xmm5" );
-	POP_LONG_XMM( "%xmm4" );
-	POP_LONG_XMM( "%xmm3" );
-	POP_LONG_XMM( "%xmm2" );
-	POP_LONG_XMM( "%xmm1" );
-	POP_LONG_XMM( "%xmm0" );
-
-	POP_LONG( "%r9" );
-	POP_LONG( "%r8" );
-	POP_LONG( "%rcx" );
-	POP_LONG( "%rdx" );
-	POP_LONG( "%rsi" );
-	POP_LONG( "%rdi" );
-
+	// Backup the stack pointer and then align it to 16 bytes.
+	// The R15 register is guaranteed to maintain its value over function
+	// calls, so it is safe for us to keep the original stack pointer here.
+	__asm__ __volatile__ (
+		"  movq %%rsp, %%r15 \n"
+		"  movq %%rsp, %%rax \n"
+		"  sub %0, %%rax \n"
+		"  and $15, %%rax \n"
+		"  sub %%rax, %%rsp \n"
+		: : "r" ((asQWORD)cnt*8) 
+		// Tell the compiler that we're using the RAX and R15.
+		// This will make sure these registers are backed up by the compiler.
+		: "%rax", "%r15", "%rsp");
+
+	// Push the stack parameters
+	for ( i = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS; cnt-- > 0; i++ )
+		PUSH_LONG( args[i] );
+
+	// Populate integer and floating point parameters
+	__asm__ __volatile__ (
+		"  mov     (%%rax), %%rdi \n"
+		"  mov    8(%%rax), %%rsi \n"
+		"  mov   16(%%rax), %%rdx \n"
+		"  mov   24(%%rax), %%rcx \n"
+		"  mov   32(%%rax), %%r8 \n"
+		"  mov   40(%%rax), %%r9 \n"
+		"  add   $48, %%rax \n"
+		"  movsd   (%%rax), %%xmm0 \n"
+		"  movsd  8(%%rax), %%xmm1 \n"
+		"  movsd 16(%%rax), %%xmm2 \n"
+		"  movsd 24(%%rax), %%xmm3 \n"
+		"  movsd 32(%%rax), %%xmm4 \n"
+		"  movsd 40(%%rax), %%xmm5 \n"
+		"  movsd 48(%%rax), %%xmm6 \n"
+		"  movsd 56(%%rax), %%xmm7 \n"
+		: 
+		: "a" (args) 
+		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 
+		  "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%9");
+		
 	// call the function with the arguments
 	// call the function with the arguments
 	retval = call();
 	retval = call();
+
+	// Restore the stack pointer
+	__asm__ __volatile__ ("  mov %%r15, %%rsp \n" : : : "%r15", "%rsp");
+
 	return retval;
 	return retval;
 }
 }
 
 
 // returns true if the given parameter is a 'variable argument'
 // returns true if the given parameter is a 'variable argument'
-inline bool IsVariableArgument( asCDataType type )
+static inline bool IsVariableArgument( asCDataType type )
 {
 {
 	return ( type.GetTokenType() == ttQuestion ) ? true : false;
 	return ( type.GetTokenType() == ttQuestion ) ? true : false;
 }
 }
@@ -208,256 +193,144 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 {
 {
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	int                         callConv           = sysFunc->callConv;
 	int                         callConv           = sysFunc->callConv;
-
 	asQWORD                     retQW              = 0;
 	asQWORD                     retQW              = 0;
 	void                       *func               = ( void * )sysFunc->func;
 	void                       *func               = ( void * )sysFunc->func;
 	asDWORD                    *stack_pointer      = args;
 	asDWORD                    *stack_pointer      = args;
 	funcptr_t                  *vftable            = NULL;
 	funcptr_t                  *vftable            = NULL;
 	int                         totalArgumentCount = 0;
 	int                         totalArgumentCount = 0;
 	int                         n                  = 0;
 	int                         n                  = 0;
-	int                         base_n             = 0;
-	int                         a                  = 0;
-	int                         param_pre          = 0;
 	int                         param_post         = 0;
 	int                         param_post         = 0;
 	int                         argIndex           = 0;
 	int                         argIndex           = 0;
-	int                         argumentCount      = 0;
-
-	asDWORD  tempBuff[CALLSTACK_MULTIPLIER * X64_CALLSTACK_SIZE] = { 0 };
-	asBYTE   tempType[X64_CALLSTACK_SIZE] = { 0 };
 
 
-	asDWORD  paramBuffer[CALLSTACK_MULTIPLIER * X64_CALLSTACK_SIZE] = { 0 };
-	asBYTE	 argsType[X64_CALLSTACK_SIZE] = { 0 };
-
-	asBYTE   argsSet[X64_CALLSTACK_SIZE]  = { 0 };
-
-	if( sysFunc->hostReturnInMemory ) {
+	if( sysFunc->hostReturnInMemory ) 
+	{
 		// The return is made in memory
 		// The return is made in memory
 		callConv++;
 		callConv++;
 	}
 	}
 
 
-	argumentCount = ( int )descr->parameterTypes.GetLength();
-	asASSERT( argumentCount <= X64_MAX_ARGS );
-
-	// TODO: optimize: argsType should be computed in PrepareSystemFunction
-	for( a = 0; a < argumentCount; ++a, ++argIndex ) {
-		// get the base type
-		argsType[argIndex] = x64INTARG;
-		if ( descr->parameterTypes[a].IsFloatType() && !descr->parameterTypes[a].IsReference() ) {
-			argsType[argIndex] = x64FLOATARG;
-		}
-		if ( descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() ) {
-			argsType[argIndex] = x64DOUBLEARG;
-		}
-		if ( descr->parameterTypes[a].GetSizeOnStackDWords() == 2 && !descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() ) {
-			argsType[argIndex] = x64INTARG;
-		}
-
-		if ( IsVariableArgument( descr->parameterTypes[a] ) ) {
-			argsType[argIndex] = x64VARIABLE;
-		}
-	}
-	asASSERT( argIndex == argumentCount );
-
-	for ( a = 0; a < argumentCount && totalArgumentCount <= X64_MAX_ARGS; a++ ) {
-		switch ( argsType[a] ) {
-			case x64ENDARG:
-			case x64INTARG:
-			case x64FLOATARG:
-			case x64DOUBLEARG: {
-				if ( totalArgumentCount < X64_MAX_ARGS )
-					tempType[totalArgumentCount++] = argsType[a];
-				break;
-			}
-			case x64VARIABLE: {
-				if ( totalArgumentCount < X64_MAX_ARGS )
-					tempType[totalArgumentCount++] = x64VARIABLE;
-				if ( totalArgumentCount < X64_MAX_ARGS )
-					tempType[totalArgumentCount++] = x64INTARG;
-				break;
-			}
-		}
-	}
-
-	asASSERT( totalArgumentCount <= X64_MAX_ARGS );
-	if ( totalArgumentCount > argumentCount ) {
-		memcpy( argsType, tempType, totalArgumentCount );
-	}
-	memset( tempType, 0, sizeof( tempType ) );
-
-	// TODO: This should be checked in PrepareSystemFunction
-#ifndef COMPLEX_OBJS_PASSED_BY_REF
-	if( sysFunc->takesObjByVal ) {
-		/* I currently know of no way we can predict register usage for passing complex
-		   objects by value when the compiler does not pass them by reference instead. I
-		   will quote the example from the AMD64 ABI to demonstrate this:
-
-		   (http://www.x86-64.org/documentation/abi.pdf - page 22)
-
-		------------------------------ BEGIN EXAMPLE -------------------------------
-
-		Let us consider the following C code:
-
-		typedef struct {
-			int a, b;
-			double d;
-		} structparm;
-
-		structparm s;
-		int e, f, g, h, i, j, k;
-		long double ld;
-		double m, n;
-
-		extern void func (int e, int f,
-			structparm s, int g, int h,
-			long double ld, double m,
-			double n, int i, int j, int k);
-
-		func (e, f, s, g, h, ld, m, n, i, j, k);
-
-		Register allocation for the call:
-		--------------------------+--------------------------+-------------------
-		General Purpose Registers | Floating Point Registers | Stack Frame Offset
-		--------------------------+--------------------------+-------------------
-		 %rdi: e                  | %xmm0: s.d               | 0:  ld
-		 %rsi: f                  | %xmm1: m                 | 16: j
-		 %rdx: s.a,s.b            | %xmm2: n                 | 24: k
-		 %rcx: g                  |                          |
-		 %r8:  h                  |                          |
-		 %r9:  i                  |                          |
-		--------------------------+--------------------------+-------------------
-		*/
-
-		context->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
-		return 0;
-	}
-#endif
-
-	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) {
+	// Determine the real function pointer in case of virtual method
+	if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) ) 
+	{
 		vftable = *( ( funcptr_t ** )obj );
 		vftable = *( ( funcptr_t ** )obj );
 		func    = ( void * )vftable[( asQWORD )func >> 3];
 		func    = ( void * )vftable[( asQWORD )func >> 3];
 	}
 	}
 
 
-	switch ( callConv ) {
+	// Determine the type of the arguments, and prepare the input array for the X64_CallFunction 
+	asQWORD  paramBuffer[X64_CALLSTACK_SIZE] = { 0 };
+	asBYTE	 argsType[X64_CALLSTACK_SIZE] = { 0 };
+
+	switch ( callConv ) 
+	{
 		case ICC_CDECL_RETURNINMEM:
 		case ICC_CDECL_RETURNINMEM:
-		case ICC_STDCALL_RETURNINMEM: {
-			if ( totalArgumentCount ) {
-				memmove( argsType + 1, argsType, totalArgumentCount );
-			}
-			memcpy( paramBuffer, &retPointer, sizeof( retPointer ) );
+		case ICC_STDCALL_RETURNINMEM: 
+		{
+			paramBuffer[0] = (size_t)retPointer;
 			argsType[0] = x64INTARG;
 			argsType[0] = x64INTARG;
-			base_n = 1;
 
 
-			param_pre = 1;
+			argIndex = 1;
 
 
 			break;
 			break;
 		}
 		}
 		case ICC_THISCALL:
 		case ICC_THISCALL:
 		case ICC_VIRTUAL_THISCALL:
 		case ICC_VIRTUAL_THISCALL:
-		case ICC_CDECL_OBJFIRST: {
-			if ( totalArgumentCount ) {
-				memmove( argsType + 1, argsType, totalArgumentCount );
-			}
-			memcpy( paramBuffer, &obj, sizeof( obj ) );
+		case ICC_CDECL_OBJFIRST: 
+		{
+			paramBuffer[0] = (size_t)obj;
 			argsType[0] = x64INTARG;
 			argsType[0] = x64INTARG;
 
 
-			param_pre = 1;
+			argIndex = 1;
 
 
 			break;
 			break;
 		}
 		}
 		case ICC_THISCALL_RETURNINMEM:
 		case ICC_THISCALL_RETURNINMEM:
 		case ICC_VIRTUAL_THISCALL_RETURNINMEM:
 		case ICC_VIRTUAL_THISCALL_RETURNINMEM:
-		case ICC_CDECL_OBJFIRST_RETURNINMEM: {
-			if ( totalArgumentCount ) {
-				memmove( argsType + 2, argsType, totalArgumentCount );
-			}
-			memcpy( paramBuffer, &retPointer, sizeof( retPointer ) );
-			memcpy( paramBuffer + CALLSTACK_MULTIPLIER, &obj, sizeof( &obj ) );
+		case ICC_CDECL_OBJFIRST_RETURNINMEM: 
+		{
+			paramBuffer[0] = (size_t)retPointer;
+			paramBuffer[1] = (size_t)obj;
 			argsType[0] = x64INTARG;
 			argsType[0] = x64INTARG;
 			argsType[1] = x64INTARG;
 			argsType[1] = x64INTARG;
 
 
-			param_pre = 2;
+			argIndex = 2;
 
 
 			break;
 			break;
 		}
 		}
-		case ICC_CDECL_OBJLAST: {
-			memcpy( paramBuffer + totalArgumentCount * CALLSTACK_MULTIPLIER, &obj, sizeof( obj ) );
-			argsType[totalArgumentCount] = x64INTARG;
-
+		case ICC_CDECL_OBJLAST: 
 			param_post = 1;
 			param_post = 1;
-
 			break;
 			break;
-		}
-		case ICC_CDECL_OBJLAST_RETURNINMEM: {
-			if ( totalArgumentCount ) {
-				memmove( argsType + 1, argsType, totalArgumentCount );
-			}
-			memcpy( paramBuffer, &retPointer, sizeof( retPointer ) );
+		case ICC_CDECL_OBJLAST_RETURNINMEM: 
+		{
+			paramBuffer[0] = (size_t)retPointer;
 			argsType[0] = x64INTARG;
 			argsType[0] = x64INTARG;
-			memcpy( paramBuffer + ( totalArgumentCount + 1 ) * CALLSTACK_MULTIPLIER, &obj, sizeof( obj ) );
-			argsType[totalArgumentCount + 1] = x64INTARG;
 
 
-			param_pre = 1;
+			argIndex = 1;
 			param_post = 1;
 			param_post = 1;
 
 
 			break;
 			break;
 		}
 		}
-		default: {
-			base_n = 0;
-			break;
-		}
 	}
 	}
 
 
-	int adjust = 0;
-	for( n = 0; n < ( int )( param_pre + totalArgumentCount + param_post ); n++ ) {
-		int copy_count = 0;
-		if ( n >= param_pre && n < ( int )( param_pre + totalArgumentCount ) ) {
-			copy_count = descr->parameterTypes[n - param_pre - adjust].GetSizeOnStackDWords();
-
-			if ( argsType[n] == x64VARIABLE ) {
-				adjust += 1;
-				argsType[n] = x64INTARG;
-				n += 1;
-			}
+	int argumentCount = ( int )descr->parameterTypes.GetLength();
+	for( int a = 0; a < argumentCount; ++a ) 
+	{
+		if ( descr->parameterTypes[a].IsFloatType() && !descr->parameterTypes[a].IsReference() ) 
+		{
+			argsType[argIndex] = x64FLOATARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(float));
+			argIndex++;
+			stack_pointer++;
+		}
+		else if ( descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() ) 
+		{
+			argsType[argIndex] = x64FLOATARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(double));
+			argIndex++;
+			stack_pointer += 2;
+		}
+		else if ( IsVariableArgument( descr->parameterTypes[a] ) ) 
+		{
+			// The variable args are really two, one pointer and one type id
+			argsType[argIndex] = x64INTARG;
+			argsType[argIndex+1] = x64INTARG;
+			memcpy(paramBuffer + argIndex, stack_pointer, sizeof(void*));
+			memcpy(paramBuffer + argIndex + 1, stack_pointer + 2, sizeof(asDWORD));
+			argIndex += 2;
+			stack_pointer += 3;
 		}
 		}
-		if ( copy_count > CALLSTACK_MULTIPLIER ) {
-			if ( copy_count > CALLSTACK_MULTIPLIER + 1 ) {
-				context->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
-				return 0;
+		else
+		{
+			argsType[argIndex] = x64INTARG;
+			if( descr->parameterTypes[a].GetSizeOnStackDWords() == 1 )
+			{
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asDWORD));
+				stack_pointer++;
 			}
 			}
-
-			memcpy( paramBuffer + ( n - 1 ) * CALLSTACK_MULTIPLIER, stack_pointer, AS_PTR_SIZE * sizeof( asDWORD ) );
-			stack_pointer += AS_PTR_SIZE;
-			memcpy( paramBuffer + n * CALLSTACK_MULTIPLIER, stack_pointer, sizeof( asDWORD ) );
-			stack_pointer += 1;
-		} else {
-			if ( copy_count ) {
-				memcpy( paramBuffer + n * CALLSTACK_MULTIPLIER, stack_pointer, copy_count * sizeof( asDWORD ) );
-				stack_pointer += copy_count;
+			else
+			{
+				memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
+				stack_pointer += 2;
 			}
 			}
+			argIndex++;
 		}
 		}
 	}
 	}
 
 
-	// If we are returning an object not by reference, we need to make the
-	// pointer to the space allocated to the object the first parameter.
-	if( descr->returnType.IsObject() && ( descr->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_CA ) == asOBJ_APP_CLASS_CA &&
-		!descr->returnType.IsReference() && !sysFunc->hostReturnInMemory )
+	// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
+	if( param_post )
 	{
 	{
-		if ( totalArgumentCount )
-		{
-			memmove( paramBuffer + CALLSTACK_MULTIPLIER, paramBuffer, ( CALLSTACK_MULTIPLIER * ( X64_CALLSTACK_SIZE - 1 ) ) );
-			memmove( argsType + 1, argsType, X64_CALLSTACK_SIZE - 1 );
-		}
-		memcpy( paramBuffer, &retPointer, sizeof( retPointer ) );
-		argsType[ 0 ] = x64INTARG;
+		paramBuffer[argIndex] = (size_t)obj;
+		argsType[argIndex] = x64INTARG;
+		argIndex++;
 	}
 	}
 
 
+	totalArgumentCount = argIndex;
+
 	/*
 	/*
 	 * Q: WTF is going on here !?
 	 * Q: WTF is going on here !?
 	 *
 	 *
 	 * A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
 	 * A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
 	 * it's little magic which must work regardless of how the compiler decides to
 	 * it's little magic which must work regardless of how the compiler decides to
 	 * allocate registers. Basically:
 	 * allocate registers. Basically:
-	 * - the first MAX_CALL_INT_REGISTERS entries in tempBuff and tempType will
+	 * - the first MAX_CALL_INT_REGISTERS entries in tempBuff will
 	 *   contain the values/types of the x64INTARG parameters - that is the ones who
 	 *   contain the values/types of the x64INTARG parameters - that is the ones who
 	 *   go into the registers. If the function has less then MAX_CALL_INT_REGISTERS
 	 *   go into the registers. If the function has less then MAX_CALL_INT_REGISTERS
 	 *   integer parameters then the last entries will be set to 0
 	 *   integer parameters then the last entries will be set to 0
@@ -470,44 +343,43 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	 *   in reverse order so that X64_CallFunction() can simply push them to the stack
 	 *   in reverse order so that X64_CallFunction() can simply push them to the stack
 	 *   without the need to perform further tests
 	 *   without the need to perform further tests
 	 */
 	 */
-	int     used_int_regs = 0;
-	int     used_sse_regs = 0;
-	int     idx           = 0;
-	base_n = 0;
-	for ( n = 0; ( n < X64_CALLSTACK_SIZE ) && ( used_int_regs < MAX_CALL_INT_REGISTERS ); n++ ) {
-		if ( argsType[n] == x64INTARG ) {
-			idx = base_n;
+	asQWORD tempBuff[X64_CALLSTACK_SIZE] = { 0 };
+	asBYTE  argsSet[X64_CALLSTACK_SIZE]  = { 0 };
+	int     used_int_regs   = 0;
+	int     used_sse_regs   = 0;
+	int     used_stack_args = 0;
+	int     idx             = 0;
+	for ( n = 0; ( n < totalArgumentCount ) && ( used_int_regs < MAX_CALL_INT_REGISTERS ); n++ ) 
+	{
+		if ( argsType[n] == x64INTARG ) 
+		{
 			argsSet[n] = 1;
 			argsSet[n] = 1;
-			tempType[idx] = argsType[n];
-			memcpy( tempBuff + idx * CALLSTACK_MULTIPLIER, paramBuffer + n * CALLSTACK_MULTIPLIER, CALLSTACK_MULTIPLIER * sizeof( asDWORD ) );
-			base_n++;
+			tempBuff[idx++] = paramBuffer[n];
 			used_int_regs++;
 			used_int_regs++;
 		}
 		}
 	}
 	}
-	base_n = 0;
-	for ( n = 0; ( n < X64_CALLSTACK_SIZE ) && ( used_sse_regs < MAX_CALL_SSE_REGISTERS ); n++ ) {
-		if ( argsType[n] == x64FLOATARG || argsType[n] == x64DOUBLEARG ) {
-			idx = MAX_CALL_INT_REGISTERS + base_n;
+	idx = MAX_CALL_INT_REGISTERS;
+	for ( n = 0; ( n < totalArgumentCount ) && ( used_sse_regs < MAX_CALL_SSE_REGISTERS ); n++ ) 
+	{
+		if ( argsType[n] == x64FLOATARG ) 
+		{
 			argsSet[n] = 1;
 			argsSet[n] = 1;
-			tempType[idx] = argsType[n];
-			memcpy( tempBuff + idx * CALLSTACK_MULTIPLIER, paramBuffer + n * CALLSTACK_MULTIPLIER, CALLSTACK_MULTIPLIER * sizeof( asDWORD ) );
-			base_n++;
+			tempBuff[idx++] = paramBuffer[n];
 			used_sse_regs++;
 			used_sse_regs++;
 		}
 		}
 	}
 	}
-	base_n = 0;
-	for ( n = X64_CALLSTACK_SIZE - 1; n >= 0; n-- ) {
-		if ( argsType[n] != x64ENDARG && !argsSet[n] ) {
-			idx = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS + base_n;
-			argsSet[n] = 1;
-			tempType[idx] = argsType[n];
-			memcpy( tempBuff + idx * CALLSTACK_MULTIPLIER, paramBuffer + n * CALLSTACK_MULTIPLIER, CALLSTACK_MULTIPLIER * sizeof( asDWORD ) );
-			base_n++;
+	idx = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS;
+	for ( n = totalArgumentCount - 1; n >= 0; n-- ) 
+	{
+		if ( !argsSet[n] ) 
+		{
+			tempBuff[idx++] = paramBuffer[n];
+			used_stack_args++;
 		}
 		}
 	}
 	}
 
 
 	context->isCallingSystemFunction = true;
 	context->isCallingSystemFunction = true;
-	retQW = X64_CallFunction( tempBuff, tempType, ( asDWORD * )func );
+	retQW = X64_CallFunction( tempBuff, used_stack_args, (asDWORD*)func );
 	ASM_GET_REG( "%rdx", retQW2 );
 	ASM_GET_REG( "%rdx", retQW2 );
 	context->isCallingSystemFunction = false;
 	context->isCallingSystemFunction = false;
 
 
@@ -516,8 +388,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	{
 	{
 		if( sysFunc->hostReturnSize == 1 )
 		if( sysFunc->hostReturnSize == 1 )
 			*(asDWORD*)&retQW = GetReturnedFloat();
 			*(asDWORD*)&retQW = GetReturnedFloat();
-		else
+		else if( sysFunc->hostReturnSize == 2 )
 			retQW = GetReturnedDouble();
 			retQW = GetReturnedDouble();
+		else
+			GetReturnedXmm0Xmm1(retQW, retQW2);
 	}
 	}
 
 
 	return retQW;
 	return retQW;
@@ -527,3 +401,4 @@ END_AS_NAMESPACE
 
 
 #endif // AS_X64_GCC
 #endif // AS_X64_GCC
 #endif // AS_MAX_PORTABILITY
 #endif // AS_MAX_PORTABILITY
+

+ 0 - 200
ThirdParty/AngelScript/source/as_callfunc_x64_msvc.asm

@@ -1,200 +0,0 @@
-;
-;  AngelCode Scripting Library
-;  Copyright (c) 2003-2010 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 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
-.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
-	add rsp, rdi
-		
-	; EPILOG: Restore stack & preserved registers
-	pop rbx
-	pop r15
-	pop r14
-	pop r13
-	pop r12
-	pop rdi
-	pop r11
-	pop rsi
-
-	; 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

+ 360 - 116
ThirdParty/AngelScript/source/as_compiler.cpp

@@ -234,6 +234,14 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 			str.Format(TXT_DATA_TYPE_CANT_BE_s, returnType.Format().AddressOf());
 			str.Format(TXT_DATA_TYPE_CANT_BE_s, returnType.Format().AddressOf());
 			Error(str.AddressOf(), func->firstChild);
 			Error(str.AddressOf(), func->firstChild);
 		}
 		}
+
+#ifndef AS_OLD
+		// If the return type is a value type returned by value the address of the
+		// location where the value will be stored is pushed on the stack before 
+		// the arguments
+		if( outFunc->DoesReturnOnStack() )
+			stackPos -= AS_PTR_SIZE;
+#endif
 	}
 	}
 	else
 	else
 	{
 	{
@@ -342,7 +350,7 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 	// Concatenate the bytecode
 	// Concatenate the bytecode
 
 
 	// Insert a JitEntry at the start of the function for JIT compilers
 	// Insert a JitEntry at the start of the function for JIT compilers
-	byteCode.InstrWORD(asBC_JitEntry, 0);
+	byteCode.InstrPTR(asBC_JitEntry, 0);
 
 
 	// Count total variable size
 	// Count total variable size
 	int varSize = GetVariableOffset((int)variableAllocations.GetLength()) - 1;
 	int varSize = GetVariableOffset((int)variableAllocations.GetLength()) - 1;
@@ -437,7 +445,7 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 	return 0;
 	return 0;
 }
 }
 
 
-int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar)
+int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar, bool derefDest)
 {
 {
 	if( !type.IsObject() )
 	if( !type.IsObject() )
 		return 0;
 		return 0;
@@ -516,6 +524,11 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 			{
 			{
 				asASSERT( !isGlobalVar );
 				asASSERT( !isGlobalVar );
 				bc->InstrSHORT(asBC_PSF, (short)offset);
 				bc->InstrSHORT(asBC_PSF, (short)offset);
+				if( derefDest )
+				{
+					// The variable is a reference to the real location, so we need to dereference it
+					bc->Instr(asBC_RDSPTR);
+				}
 			}
 			}
 
 
 			asSExprContext ctx(engine);
 			asSExprContext ctx(engine);
@@ -541,7 +554,7 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 	return -1;
 	return -1;
 }
 }
 
 
-int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar)
+int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar, bool deferDest)
 {
 {
 	if( !type.IsObject() ||
 	if( !type.IsObject() ||
 		(type.IsObjectHandle() && !(type.GetObjectType()->flags & asOBJ_ASHANDLE)) )
 		(type.IsObjectHandle() && !(type.GetObjectType()->flags & asOBJ_ASHANDLE)) )
@@ -550,6 +563,7 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 	if( type.GetObjectType()->flags & asOBJ_REF )
 	if( type.GetObjectType()->flags & asOBJ_REF )
 	{
 	{
 		asSExprContext ctx(engine);
 		asSExprContext ctx(engine);
+		ctx.exprNode = node;
 
 
 		int func = 0;
 		int func = 0;
 		asSTypeBehaviour *beh = type.GetBehaviour();
 		asSTypeBehaviour *beh = type.GetBehaviour();
@@ -603,6 +617,8 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 				{
 				{
 					// Call the constructor as a normal function
 					// Call the constructor as a normal function
 					bc->InstrSHORT(asBC_PSF, (short)offset);
 					bc->InstrSHORT(asBC_PSF, (short)offset);
+					if( deferDest )
+						bc->Instr(asBC_RDSPTR);
 					asSExprContext ctx(engine);
 					asSExprContext ctx(engine);
 					PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
 					PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
 					bc->AddCode(&ctx.bc);
 					bc->AddCode(&ctx.bc);
@@ -887,9 +903,9 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 		}
 		}
 		else
 		else
 		{
 		{
-			// TODO: copy: Here we should look for the best matching constructor, instead of
-			//             just the copy constructor. Only if no appropriate constructor is
-			//             available should the assignment operator be used.
+			// TODO: optimize: Here we should look for the best matching constructor, instead of
+			//                 just the copy constructor. Only if no appropriate constructor is
+			//                 available should the assignment operator be used.
 
 
 			if( (!gvar->datatype.IsObjectHandle() || gvar->datatype.GetObjectType()->flags & asOBJ_ASHANDLE) )
 			if( (!gvar->datatype.IsObjectHandle() || gvar->datatype.GetObjectType()->flags & asOBJ_ASHANDLE) )
 			{
 			{
@@ -930,7 +946,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 
 
 			if( !assigned )
 			if( !assigned )
 			{
 			{
-				PrepareForAssignment(&lexpr.type.dataType, &expr, node);
+				PrepareForAssignment(&lexpr.type.dataType, &expr, node, false);
 
 
 				// If the expression is constant and the variable also is constant
 				// If the expression is constant and the variable also is constant
 				// then mark the variable as pure constant. This will allow the compiler
 				// then mark the variable as pure constant. This will allow the compiler
@@ -1093,11 +1109,11 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 			{
 			{
 				IsVariableInitialized(&ctx->type, node);
 				IsVariableInitialized(&ctx->type, node);
 
 
-				if( ctx->type.dataType.IsReference() ) ConvertToVariable(ctx);
+				if( ctx->type.dataType.IsReference() ) ConvertToVariableNotIn(ctx, reservedVars);
 				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, reservedVars);
 				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, reservedVars);
 
 
 				if( !(param.IsReadOnly() && ctx->type.isVariable) )
 				if( !(param.IsReadOnly() && ctx->type.isVariable) )
-					ConvertToTempVariable(ctx);
+					ConvertToTempVariableNotIn(ctx, reservedVars);
 
 
 				PushVariableOnStack(ctx, true);
 				PushVariableOnStack(ctx, true);
 				ctx->type.dataType.MakeReadOnly(param.IsReadOnly());
 				ctx->type.dataType.MakeReadOnly(param.IsReadOnly());
@@ -1142,7 +1158,7 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 					ctx->bc.AddCode(&tmpBC);
 					ctx->bc.AddCode(&tmpBC);
 
 
 					// Assign the evaluated expression to the temporary variable
 					// Assign the evaluated expression to the temporary variable
-					PrepareForAssignment(&dt, ctx, node);
+					PrepareForAssignment(&dt, ctx, node, true);
 
 
 					dt.MakeReference(IsVariableOnHeap(offset));
 					dt.MakeReference(IsVariableOnHeap(offset));
 					asCTypeInfo type;
 					asCTypeInfo type;
@@ -1213,6 +1229,8 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		}
 		}
 		else if( refType == asTM_INOUTREF )
 		else if( refType == asTM_INOUTREF )
 		{
 		{
+			ProcessPropertyGetAccessor(ctx, node);
+
 			// Literal constants cannot be passed to inout ref arguments
 			// Literal constants cannot be passed to inout ref arguments
 			if( !ctx->type.isVariable && ctx->type.isConstant )
 			if( !ctx->type.isVariable && ctx->type.isConstant )
 			{
 			{
@@ -1278,7 +1296,7 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		{
 		{
 			IsVariableInitialized(&ctx->type, node);
 			IsVariableInitialized(&ctx->type, node);
 
 
-			if( ctx->type.dataType.IsReference() ) ConvertToVariable(ctx);
+			if( ctx->type.dataType.IsReference() ) ConvertToVariableNotIn(ctx, reservedVars);
 
 
 			// Implicitly convert primitives to the parameter type
 			// Implicitly convert primitives to the parameter type
 			ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, reservedVars);
 			ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, reservedVars);
@@ -1289,7 +1307,7 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 			}
 			}
 			else if( ctx->type.isConstant )
 			else if( ctx->type.isConstant )
 			{
 			{
-				ConvertToVariable(ctx);
+				ConvertToVariableNotIn(ctx, reservedVars);
 				PushVariableOnStack(ctx, dt.IsReference());
 				PushVariableOnStack(ctx, dt.IsReference());
 			}
 			}
 		}
 		}
@@ -1353,10 +1371,10 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 	}
 	}
 }
 }
 
 
-void asCCompiler::PrepareFunctionCall(int funcID, asCByteCode *bc, asCArray<asSExprContext *> &args)
+void asCCompiler::PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args)
 {
 {
 	// When a match has been found, compile the final byte code using correct parameter types
 	// When a match has been found, compile the final byte code using correct parameter types
-	asCScriptFunction *descr = builder->GetFunctionDescription(funcID);
+	asCScriptFunction *descr = builder->GetFunctionDescription(funcId);
 
 
 	// Add code for arguments
 	// Add code for arguments
 	asSExprContext e(engine);
 	asSExprContext e(engine);
@@ -1375,14 +1393,20 @@ void asCCompiler::PrepareFunctionCall(int funcID, asCByteCode *bc, asCArray<asSE
 	bc->AddCode(&e.bc);
 	bc->AddCode(&e.bc);
 }
 }
 
 
-void asCCompiler::MoveArgsToStack(int funcID, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset)
+void asCCompiler::MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset)
 {
 {
-	asCScriptFunction *descr = builder->GetFunctionDescription(funcID);
+	asCScriptFunction *descr = builder->GetFunctionDescription(funcId);
 
 
 	int offset = 0;
 	int offset = 0;
 	if( addOneToOffset )
 	if( addOneToOffset )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
 
 
+#ifndef AS_OLD
+	// The address of where the return value should be stored is push on top of the arguments
+	if( descr->DoesReturnOnStack() )
+		offset += AS_PTR_SIZE;
+#endif
+
 	// Move the objects that are sent by value to the stack just before the call
 	// Move the objects that are sent by value to the stack just before the call
 	for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 	for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
 	{
 	{
@@ -1578,13 +1602,20 @@ void asCCompiler::MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*>
 
 
 			if( desc->parameterTypes.GetLength() != args.GetLength() )
 			if( desc->parameterTypes.GetLength() != args.GetLength() )
 			{
 			{
-				// Count the number of default args
-				asUINT defaultArgs = 0;
-				for( asUINT d = 0; d < desc->defaultArgs.GetLength(); d++ )
-					if( desc->defaultArgs[d] )
-						defaultArgs++;
+				bool noMatch = true;
+				if( args.GetLength() < desc->parameterTypes.GetLength() )
+				{
+					// Count the number of default args
+					asUINT defaultArgs = 0;
+					for( asUINT d = 0; d < desc->defaultArgs.GetLength(); d++ )
+						if( desc->defaultArgs[d] )
+							defaultArgs++;
+
+					if( args.GetLength() >= desc->parameterTypes.GetLength() - defaultArgs )
+						noMatch = false;
+				}
 
 
-				if( args.GetLength() < desc->parameterTypes.GetLength() - defaultArgs )
+				if( noMatch )
 				{
 				{
 					// remove it from the list
 					// remove it from the list
 					if( n == funcs.GetLength()-1 )
 					if( n == funcs.GetLength()-1 )
@@ -1704,6 +1735,18 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 			type = asCDataType::CreatePrimitive(ttInt, false);
 			type = asCDataType::CreatePrimitive(ttInt, false);
 		}
 		}
 
 
+		// A shared object may not declare variables of non-shared types
+		if( outFunc->objectType && outFunc->objectType->IsShared() )
+		{
+			asCObjectType *ot = type.GetObjectType();
+			if( ot && !ot->IsShared() )
+			{
+				asCString msg;
+				msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, ot->name.AddressOf());
+				Error(msg.AddressOf(), decl);
+			}
+		}
+
 		// Get the name of the identifier
 		// Get the name of the identifier
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 
 
@@ -1873,7 +1916,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 				}
 				}
 				else
 				else
 				{
 				{
-					// TODO: We can use a copy constructor here
+					// TODO: optimize: We can use a copy constructor here
 
 
 					sVariable *v = variables->GetVariable(name.AddressOf());
 					sVariable *v = variables->GetVariable(name.AddressOf());
 
 
@@ -1916,7 +1959,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 
 
 					if( !assigned )
 					if( !assigned )
 					{
 					{
-						PrepareForAssignment(&lexpr.type.dataType, &expr, node);
+						PrepareForAssignment(&lexpr.type.dataType, &expr, node, false);
 
 
 						// If the expression is constant and the variable also is constant
 						// If the expression is constant and the variable also is constant
 						// then mark the variable as pure constant. This will allow the compiler
 						// then mark the variable as pure constant. This will allow the compiler
@@ -2689,7 +2732,7 @@ void asCCompiler::CompileForStatement(asCScriptNode *fnode, asCByteCode *bc)
 	// Add a suspend bytecode inside the loop to guarantee
 	// Add a suspend bytecode inside the loop to guarantee
 	// that the application can suspend the execution
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 
 
 
 	bc->AddCode(&expr.bc);
 	bc->AddCode(&expr.bc);
@@ -2760,7 +2803,7 @@ void asCCompiler::CompileWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 	// Add a suspend bytecode inside the loop to guarantee
 	// Add a suspend bytecode inside the loop to guarantee
 	// that the application can suspend the execution
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 
 	// Compile statement
 	// Compile statement
 	bool hasReturn;
 	bool hasReturn;
@@ -2814,7 +2857,7 @@ void asCCompiler::CompileDoWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 	// Add a suspend bytecode inside the loop to guarantee
 	// Add a suspend bytecode inside the loop to guarantee
 	// that the application can suspend the execution
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 
 	// Add a line instruction
 	// Add a line instruction
 	LineInstr(bc, wnode->lastChild->tokenPos);
 	LineInstr(bc, wnode->lastChild->tokenPos);
@@ -2960,7 +3003,7 @@ void asCCompiler::PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ct
 	if( (!dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_ASHANDLE))) &&
 	if( (!dt.IsObjectHandle() || (dt.GetObjectType() && (dt.GetObjectType()->flags & asOBJ_ASHANDLE))) &&
 		dt.GetObjectType() && (dt.GetBehaviour()->copyconstruct || dt.GetBehaviour()->copyfactory) )
 		dt.GetObjectType() && (dt.GetBehaviour()->copyconstruct || dt.GetBehaviour()->copyfactory) )
 	{
 	{
-		PrepareForAssignment(&lvalue.dataType, ctx, node);
+		PrepareForAssignment(&lvalue.dataType, ctx, node, true);
 
 
 		// Use the copy constructor/factory when available
 		// Use the copy constructor/factory when available
 		CallCopyConstructor(dt, offset, IsVariableOnHeap(offset), &ctx->bc, ctx, node);
 		CallCopyConstructor(dt, offset, IsVariableOnHeap(offset), &ctx->bc, ctx, node);
@@ -2971,7 +3014,7 @@ void asCCompiler::PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ct
 		CallDefaultConstructor(dt, offset, IsVariableOnHeap(offset), &ctx->bc, node);
 		CallDefaultConstructor(dt, offset, IsVariableOnHeap(offset), &ctx->bc, node);
 
 
 		// Assign the object to the temporary variable
 		// Assign the object to the temporary variable
-		PrepareForAssignment(&lvalue.dataType, ctx, node);
+		PrepareForAssignment(&lvalue.dataType, ctx, node, true);
 
 
 		ctx->bc.InstrSHORT(asBC_PSF, (short)offset);
 		ctx->bc.InstrSHORT(asBC_PSF, (short)offset);
 		PerformAssignment(&lvalue, &ctx->type, &ctx->bc, node);
 		PerformAssignment(&lvalue, &ctx->type, &ctx->bc, node);
@@ -3138,7 +3181,7 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 					asCString str;
 					asCString str;
 					str.Format(TXT_NO_CONVERSION_s_TO_s, expr.type.dataType.Format().AddressOf(), v->type.Format().AddressOf());
 					str.Format(TXT_NO_CONVERSION_s_TO_s, expr.type.dataType.Format().AddressOf(), v->type.Format().AddressOf());
 					Error(str.AddressOf(), rnode);
 					Error(str.AddressOf(), rnode);
-					r = -1;
+					return;
 				}
 				}
 				else
 				else
 				{
 				{
@@ -3159,25 +3202,80 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 			}
 			}
 			else if( v->type.IsObject() )
 			else if( v->type.IsObject() )
 			{
 			{
-				// Value types are still returned on the heap, so we must
-				// copy the value to an object allocated on the heap here
-				PrepareArgument(&v->type, &expr, rnode->firstChild, false, 0, 0, true);
+#ifndef AS_OLD
+				// Value types are returned on the stack, in a location
+				// that has been reserved by the calling function. 
+				if( outFunc->DoesReturnOnStack() )
+				{
+					// TODO: optimize: If the return type has a constructor that takes the type of the expression,
+					//                 it should be called directly instead of first converting the expression and 
+					//                 then copy the value.
+					if( !v->type.IsEqualExceptRefAndConst(expr.type.dataType) ) 
+					{
+						ImplicitConversion(&expr, v->type, rnode->firstChild, asIC_IMPLICIT_CONV);
+						if( !v->type.IsEqualExceptRefAndConst(expr.type.dataType) )
+						{
+							asCString str;
+							str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, expr.type.dataType.Format().AddressOf(), v->type.Format().AddressOf());
+							Error(str.AddressOf(), rnode->firstChild);
+							return;
+						}
+					}
 
 
-				// Pop the reference to the temporary variable again
-				expr.bc.Pop(AS_PTR_SIZE);
+					int offset = outFunc->objectType ? -AS_PTR_SIZE : 0;
+					if( v->type.GetObjectType()->beh.copyconstruct )
+					{
+						PrepareForAssignment(&v->type, &expr, rnode->firstChild, false);
+						CallCopyConstructor(v->type, offset, false, &expr.bc, &expr, rnode->firstChild, false, true);
+					}
+					else
+					{
+						// If the copy constructor doesn't exist, then a manual assignment needs to be done instead. 
+						CallDefaultConstructor(v->type, offset, false, &expr.bc, rnode->firstChild, false, true);
+						PrepareForAssignment(&v->type, &expr, rnode->firstChild, false);
+						expr.bc.InstrSHORT(asBC_PSF, (short)offset);
+						expr.bc.Instr(asBC_RDSPTR);
+
+						asSExprContext lexpr(engine);
+						lexpr.type.Set(v->type);
+						lexpr.type.isLValue = true;
+						PerformAssignment(&lexpr.type, &expr.type, &expr.bc, rnode->firstChild);
+						expr.bc.Pop(AS_PTR_SIZE);
+
+						// Release any temporary variable
+						ReleaseTemporaryVariable(expr.type, &expr.bc);
+					}
 
 
-				// Clean up the local variables and process deferred parameters
-				DestroyVariables(&expr.bc);
-				ProcessDeferredParams(&expr);
+					// Clean up the local variables and process deferred parameters
+					DestroyVariables(&expr.bc);
+					ProcessDeferredParams(&expr);
+				}
+				else
+#endif
+				{
+#ifndef AS_OLD
+					asASSERT( v->type.GetObjectType()->flags & asOBJ_REF );
+#endif
+					// Prepare the expression to be loaded into the object 
+					// register. This will place the reference in local variable
+					PrepareArgument(&v->type, &expr, rnode->firstChild, false, 0, 0, true);
+
+					// Pop the reference to the temporary variable
+					expr.bc.Pop(AS_PTR_SIZE);
+
+					// Clean up the local variables and process deferred parameters
+					DestroyVariables(&expr.bc);
+					ProcessDeferredParams(&expr);
 
 
-				// Load the object pointer into the object register
-				// LOADOBJ also clears the address in the variable
-				expr.bc.InstrSHORT(asBC_LOADOBJ, expr.type.stackOffset);
+					// Load the object pointer into the object register
+					// LOADOBJ also clears the address in the variable
+					expr.bc.InstrSHORT(asBC_LOADOBJ, expr.type.stackOffset);
 
 
-				// LOADOBJ cleared the address in the variable so the object will not be freed
-				// here, but the temporary variable must still be freed so the slot can be reused
-				// By releasing without the bytecode we do just that.
-				ReleaseTemporaryVariable(expr.type, 0);
+					// LOADOBJ cleared the address in the variable so the object will not be freed
+					// here, but the temporary variable must still be freed so the slot can be reused
+					// By releasing without the bytecode we do just that.
+					ReleaseTemporaryVariable(expr.type, 0);
+				}
 			}
 			}
 		}
 		}
 
 
@@ -3460,11 +3558,15 @@ void asCCompiler::ReleaseTemporaryVariable(int offset, asCByteCode *bc)
 	{
 	{
 		// We need to call the destructor on the true variable type
 		// We need to call the destructor on the true variable type
 		int n = GetVariableSlot(offset);
 		int n = GetVariableSlot(offset);
-		asCDataType dt = variableAllocations[n];
-		bool isOnHeap = variableIsOnHeap[n];
+		asASSERT( n >= 0 );
+		if( n >= 0 )
+		{
+			asCDataType dt = variableAllocations[n];
+			bool isOnHeap = variableIsOnHeap[n];
 
 
-		// Call destructor
-		CallDestructor(dt, offset, isOnHeap, bc);
+			// Call destructor
+			CallDestructor(dt, offset, isOnHeap, bc);
+		}
 	}
 	}
 
 
 	DeallocateVariable(offset);
 	DeallocateVariable(offset);
@@ -3535,7 +3637,7 @@ void asCCompiler::PrepareOperand(asSExprContext *ctx, asCScriptNode *node)
 	ProcessDeferredParams(ctx);
 	ProcessDeferredParams(ctx);
 }
 }
 
 
-void asCCompiler::PrepareForAssignment(asCDataType *lvalue, asSExprContext *rctx, asCScriptNode *node, asSExprContext *lvalueExpr)
+void asCCompiler::PrepareForAssignment(asCDataType *lvalue, asSExprContext *rctx, asCScriptNode *node, bool toTemporary, asSExprContext *lvalueExpr)
 {
 {
 	ProcessPropertyGetAccessor(rctx, node);
 	ProcessPropertyGetAccessor(rctx, node);
 
 
@@ -3578,20 +3680,20 @@ void asCCompiler::PrepareForAssignment(asCDataType *lvalue, asSExprContext *rctx
 		to.MakeReference(false);
 		to.MakeReference(false);
 
 
 		// TODO: ImplicitConversion should know to do this by itself
 		// TODO: ImplicitConversion should know to do this by itself
-		// First convert to a handle which will to a reference cast
+		// First convert to a handle which will do a reference cast
 		if( !lvalue->IsObjectHandle() &&
 		if( !lvalue->IsObjectHandle() &&
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 			to.MakeHandle(true);
 			to.MakeHandle(true);
 
 
 		// Don't allow the implicit conversion to create an object
 		// Don't allow the implicit conversion to create an object
-		ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true, 0, false);
+		ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true, 0, !toTemporary);
 
 
 		if( !lvalue->IsObjectHandle() &&
 		if( !lvalue->IsObjectHandle() &&
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 		{
 		{
 			// Then convert to a reference, which will validate the handle
 			// Then convert to a reference, which will validate the handle
 			to.MakeHandle(false);
 			to.MakeHandle(false);
-			ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true, 0, false);
+			ImplicitConversion(rctx, to, node, asIC_IMPLICIT_CONV, true, 0, !toTemporary);
 		}
 		}
 
 
 		// Check data type
 		// Check data type
@@ -3681,7 +3783,9 @@ void asCCompiler::PerformAssignment(asCTypeInfo *lvalue, asCTypeInfo *rvalue, as
 			if( lvalue->dataType.GetSizeInMemoryDWords() == 0 ||
 			if( lvalue->dataType.GetSizeInMemoryDWords() == 0 ||
 				!(lvalue->dataType.GetObjectType()->flags & asOBJ_POD) )
 				!(lvalue->dataType.GetObjectType()->flags & asOBJ_POD) )
 			{
 			{
-				Error(TXT_NO_DEFAULT_COPY_OP, node);
+				asCString msg;
+				msg.Format(TXT_NO_DEFAULT_COPY_OP_FOR_s, lvalue->dataType.GetObjectType()->name.AddressOf());
+				Error(msg.AddressOf(), node);
 			}
 			}
 
 
 			// Copy larger data types from a reference
 			// Copy larger data types from a reference
@@ -4497,7 +4601,28 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 			{
 			{
 				asCTypeInfo objType = ctx->type;
 				asCTypeInfo objType = ctx->type;
 				Dereference(ctx, true);
 				Dereference(ctx, true);
-				PerformFunctionCall(funcs[0], ctx);
+
+				bool useVariable = false;
+				int  stackOffset = 0;
+#ifndef AS_OLD
+				if( f->DoesReturnOnStack() )
+				{
+					useVariable = true;
+					stackOffset = AllocateVariable(f->returnType, true);
+
+					// Push the pointer to the pre-allocated space for the return value
+					ctx->bc.InstrSHORT(asBC_PSF, short(stackOffset));
+
+					// The object pointer is already on the stack, but should be the top 
+					// one, so we need to swap the pointers in order to get the correct
+#if AS_PTR_SIZE == 1
+					ctx->bc.Instr(asBC_SWAP4);
+#else
+					ctx->bc.Instr(asBC_SWAP8);
+#endif
+				}
+#endif
+				PerformFunctionCall(funcs[0], ctx, false, 0, 0, useVariable, stackOffset);
 				ReleaseTemporaryVariable(objType, &ctx->bc);
 				ReleaseTemporaryVariable(objType, &ctx->bc);
 			}
 			}
 			else
 			else
@@ -5357,7 +5482,7 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 		{
 		{
 			// set_opIndex has 2 arguments, where as normal setters have only 1
 			// set_opIndex has 2 arguments, where as normal setters have only 1
 			asCArray<asCDataType>& parameterTypes =
 			asCArray<asCDataType>& parameterTypes =
-				engine->scriptFunctions[lctx->property_set]->parameterTypes;
+				builder->GetFunctionDescription(lctx->property_set)->parameterTypes;
 			if( !parameterTypes[parameterTypes.GetLength() - 1].IsObjectHandle() )
 			if( !parameterTypes[parameterTypes.GetLength() - 1].IsObjectHandle() )
 			{
 			{
 				// Process the property to free the memory
 				// Process the property to free the memory
@@ -5405,7 +5530,7 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 			rctx->type = o.type;
 			rctx->type = o.type;
 
 
 			// Convert the rvalue to the right type and validate it
 			// Convert the rvalue to the right type and validate it
-			PrepareForAssignment(&lvalue.dataType, rctx, rexpr);
+			PrepareForAssignment(&lvalue.dataType, rctx, rexpr, false);
 
 
 			MergeExprBytecode(ctx, rctx);
 			MergeExprBytecode(ctx, rctx);
 			lctx->type = lvalue;
 			lctx->type = lvalue;
@@ -5415,7 +5540,7 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 		else
 		else
 		{
 		{
 			// Convert the rvalue to the right type and validate it
 			// Convert the rvalue to the right type and validate it
-			PrepareForAssignment(&lctx->type.dataType, rctx, rexpr, lctx);
+			PrepareForAssignment(&lctx->type.dataType, rctx, rexpr, false, lctx);
 
 
 			MergeExprBytecode(ctx, rctx);
 			MergeExprBytecode(ctx, rctx);
 			MergeExprBytecode(ctx, lctx);
 			MergeExprBytecode(ctx, lctx);
@@ -5732,7 +5857,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asSExprContext *ctx)
 				if( rtemp.dataType.IsObjectHandle() )
 				if( rtemp.dataType.IsObjectHandle() )
 					rtemp.isExplicitHandle = true;
 					rtemp.isExplicitHandle = true;
 
 
-				PrepareForAssignment(&rtemp.dataType, &le, cexpr->next);
+				PrepareForAssignment(&rtemp.dataType, &le, cexpr->next, true);
 				MergeExprBytecode(ctx, &le);
 				MergeExprBytecode(ctx, &le);
 
 
 				if( !rtemp.dataType.IsPrimitive() )
 				if( !rtemp.dataType.IsPrimitive() )
@@ -5753,7 +5878,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asSExprContext *ctx)
 				ctx->bc.Label((short)elseLabel);
 				ctx->bc.Label((short)elseLabel);
 
 
 				// Copy the result to the same temporary variable
 				// Copy the result to the same temporary variable
-				PrepareForAssignment(&rtemp.dataType, &re, cexpr->next);
+				PrepareForAssignment(&rtemp.dataType, &re, cexpr->next, true);
 				MergeExprBytecode(ctx, &re);
 				MergeExprBytecode(ctx, &re);
 
 
 				if( !rtemp.dataType.IsPrimitive() )
 				if( !rtemp.dataType.IsPrimitive() )
@@ -6113,8 +6238,9 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 		{
 		{
 			bool isCompiled = true;
 			bool isCompiled = true;
 			bool isPureConstant = false;
 			bool isPureConstant = false;
+			bool isAppProp = false;
 			asQWORD constantValue;
 			asQWORD constantValue;
-			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), &isCompiled, &isPureConstant, &constantValue);
+			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), &isCompiled, &isPureConstant, &constantValue, &isAppProp);
 			if( prop )
 			if( prop )
 			{
 			{
 				found = true;
 				found = true;
@@ -6136,6 +6262,20 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 						ctx->type.SetConstantQW(prop->type, constantValue);
 						ctx->type.SetConstantQW(prop->type, constantValue);
 					else
 					else
 					{
 					{
+						// A shared type must not access global vars, unless they  
+						// too are shared, e.g. application registered vars
+						if( outFunc->objectType && outFunc->objectType->IsShared() )
+						{
+							if( !isAppProp )
+							{
+								asCString str;
+								str.Format(TXT_SHARED_CANNOT_ACCESS_NON_SHARED_VAR_s, prop->name.AddressOf());
+								Error(str.AddressOf(), errNode);
+
+								// Allow the compilation to continue to catch other problems
+							}
+						}
+
 						ctx->type.Set(prop->type);
 						ctx->type.Set(prop->type);
 						ctx->type.dataType.MakeReference(true);
 						ctx->type.dataType.MakeReference(true);
 						ctx->type.isLValue = true;
 						ctx->type.isLValue = true;
@@ -6195,9 +6335,19 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 		{
 		{
 			found = true;
 			found = true;
 
 
+			// A shared object may not access global functions unless they too are shared (e.g. registered functions)
+			if( !builder->GetFunctionDescription(funcs[0])->IsShared() &&
+				outFunc->objectType && outFunc->objectType->IsShared() )
+			{
+				asCString msg;
+				msg.Format(TXT_SHARED_CANNOT_CALL_NON_SHARED_FUNC_s, builder->GetFunctionDescription(funcs[0])->GetDeclaration());
+				Error(msg.AddressOf(), errNode);
+				return -1;
+			}
+
 			// Push the function pointer on the stack
 			// Push the function pointer on the stack
-			ctx->bc.InstrPTR(asBC_FuncPtr, engine->scriptFunctions[funcs[0]]);
-			ctx->type.Set(asCDataType::CreateFuncDef(engine->scriptFunctions[funcs[0]]));
+			ctx->bc.InstrPTR(asBC_FuncPtr, builder->GetFunctionDescription(funcs[0]));
+			ctx->type.Set(asCDataType::CreateFuncDef(builder->GetFunctionDescription(funcs[0])));
 		}
 		}
 	}
 	}
 
 
@@ -6234,6 +6384,9 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 
 
 		if( found )
 		if( found )
 		{
 		{
+			// Even if the enum type is not shared, and we're compiling a shared object,
+			// the use of the values are still allowed, since they are treated as constants.
+
 			// an enum value was resolved
 			// an enum value was resolved
 			ctx->type.SetConstantDW(dt, value);
 			ctx->type.SetConstantDW(dt, value);
 		}
 		}
@@ -6429,7 +6582,19 @@ int asCCompiler::CompileExpressionValue(asCScriptNode *node, asSExprContext *ctx
 					// Register the constant string with the engine
 					// Register the constant string with the engine
 					int id = engine->AddConstantString(str.AddressOf(), str.GetLength());
 					int id = engine->AddConstantString(str.AddressOf(), str.GetLength());
 					ctx->bc.InstrWORD(asBC_STR, (asWORD)id);
 					ctx->bc.InstrWORD(asBC_STR, (asWORD)id);
-					PerformFunctionCall(descr->id, ctx);
+
+					bool useVariable = false;
+					int stackOffset  = 0;
+#ifndef AS_OLD
+					if( descr->DoesReturnOnStack() )
+					{
+						useVariable = true;
+						stackOffset = AllocateVariable(descr->returnType, true);
+						ctx->bc.InstrSHORT(asBC_PSF, short(stackOffset));
+					}
+#endif
+
+					PerformFunctionCall(descr->id, ctx, false, 0, 0, useVariable, stackOffset);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -6447,8 +6612,6 @@ int asCCompiler::CompileExpressionValue(asCScriptNode *node, asSExprContext *ctx
 	}
 	}
 	else if( vnode->nodeType == snFunctionCall )
 	else if( vnode->nodeType == snFunctionCall )
 	{
 	{
-		bool found = false;
-
 		// Determine the scope resolution
 		// Determine the scope resolution
 		asCString scope = GetScopeFromNode(vnode);
 		asCString scope = GetScopeFromNode(vnode);
 
 
@@ -6507,13 +6670,11 @@ int asCCompiler::CompileExpressionValue(asCScriptNode *node, asSExprContext *ctx
 				// TODO: optimize: This adds a CHKREF. Is that really necessary?
 				// TODO: optimize: This adds a CHKREF. Is that really necessary?
 				Dereference(ctx, true);
 				Dereference(ctx, true);
 
 
-				CompileFunctionCall(vnode, ctx, outFunc->objectType, false, scope);
-				found = true;
+				return CompileFunctionCall(vnode, ctx, outFunc->objectType, false, scope);
 			}
 			}
 		}
 		}
 
 
-		if( !found )
-			CompileFunctionCall(vnode, ctx, 0, false, scope);
+		return CompileFunctionCall(vnode, ctx, 0, false, scope);
 	}
 	}
 	else if( vnode->nodeType == snConstructCall )
 	else if( vnode->nodeType == snConstructCall )
 	{
 	{
@@ -6868,6 +7029,16 @@ void asCCompiler::CompileConversion(asCScriptNode *node, asSExprContext *ctx)
 		}
 		}
 	}
 	}
 
 
+	// Do not allow casting to non shared type if we're compiling a shared method
+	if( outFunc->objectType && outFunc->objectType->IsShared() && 
+		to.GetObjectType() && !to.GetObjectType()->IsShared() )
+	{
+		asCString msg;
+		msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, to.GetObjectType()->name.AddressOf());
+		Error(msg.AddressOf(), node);
+		anyErrors = true;
+	}
+
 	if( anyErrors )
 	if( anyErrors )
 	{
 	{
 		// Assume that the error can be fixed and allow the compilation to continue
 		// Assume that the error can be fixed and allow the compilation to continue
@@ -7103,6 +7274,15 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 		return;
 		return;
 	}
 	}
 
 
+	// Do not allow constructing non-shared types in shared functions
+	if( outFunc->objectType && outFunc->objectType->IsShared() &&
+		dt.GetObjectType() && !dt.GetObjectType()->IsShared() )
+	{
+		asCString msg;
+		msg.Format(TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s, dt.GetObjectType()->name.AddressOf());
+		Error(msg.AddressOf(), node);
+	}
+
 	// Compile the arguments
 	// Compile the arguments
 	asCArray<asSExprContext *> args;
 	asCArray<asSExprContext *> args;
 	asCArray<asCTypeInfo> temporaryVariables;
 	asCArray<asCTypeInfo> temporaryVariables;
@@ -7231,6 +7411,9 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 
 
 					PerformFunctionCall(funcs[0], ctx, onHeap, &args, tempObj.dataType.GetObjectType());
 					PerformFunctionCall(funcs[0], ctx, onHeap, &args, tempObj.dataType.GetObjectType());
 
 
+					// Add tag that the object has been initialized
+					ctx->bc.ObjInfo(tempObj.stackOffset, asOBJ_INIT);
+
 					// The constructor doesn't return anything,
 					// The constructor doesn't return anything,
 					// so we have to manually inform the type of
 					// so we have to manually inform the type of
 					// the return value
 					// the return value
@@ -7264,7 +7447,7 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 }
 }
 
 
 
 
-void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, asCObjectType *objectType, bool objIsConst, const asCString &scope)
+int asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx, asCObjectType *objectType, bool objIsConst, const asCString &scope)
 {
 {
 	asCString name;
 	asCString name;
 	asCTypeInfo tempObj;
 	asCTypeInfo tempObj;
@@ -7312,7 +7495,7 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 		asCString msg;
 		asCString msg;
 		msg.Format(TXT_NOT_A_FUNC_s_IS_VAR, name.AddressOf());
 		msg.Format(TXT_NOT_A_FUNC_s_IS_VAR, name.AddressOf());
 		Error(msg.AddressOf(), node);
 		Error(msg.AddressOf(), node);
-		return;
+		return -1;
 	}
 	}
 
 
 	if( funcs.GetLength() == 0 && funcPtr.type.dataType.GetFuncDef() )
 	if( funcs.GetLength() == 0 && funcPtr.type.dataType.GetFuncDef() )
@@ -7400,6 +7583,8 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 		{
 		{
 			asDELETE(args[n],asSExprContext);
 			asDELETE(args[n],asSExprContext);
 		}
 		}
+
+	return 0;
 }
 }
 
 
 int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx)
 int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx)
@@ -7829,7 +8014,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		builder->GetFunctionDescriptions(getName.AddressOf(), funcs);
 		builder->GetFunctionDescriptions(getName.AddressOf(), funcs);
 		for( n = 0; n < funcs.GetLength(); n++ )
 		for( n = 0; n < funcs.GetLength(); n++ )
 		{
 		{
-			asCScriptFunction *f = engine->scriptFunctions[funcs[n]];
+			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
 			// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 			// TODO: The type of the parameter should match the argument (unless the arg is a dummy)
 			if( (int)f->parameterTypes.GetLength() == (arg?1:0) )
 			if( (int)f->parameterTypes.GetLength() == (arg?1:0) )
 			{
 			{
@@ -7849,7 +8034,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		builder->GetFunctionDescriptions(setName.AddressOf(), funcs);
 		builder->GetFunctionDescriptions(setName.AddressOf(), funcs);
 		for( n = 0; n < funcs.GetLength(); n++ )
 		for( n = 0; n < funcs.GetLength(); n++ )
 		{
 		{
-			asCScriptFunction *f = engine->scriptFunctions[funcs[n]];
+			asCScriptFunction *f = builder->GetFunctionDescription(funcs[n]);
 			// TODO: getset: If the parameter is a reference, it must not be an out reference. Should we allow inout ref?
 			// TODO: getset: If the parameter is a reference, it must not be an out reference. Should we allow inout ref?
 			if( (int)f->parameterTypes.GetLength() == (arg?2:1) )
 			if( (int)f->parameterTypes.GetLength() == (arg?2:1) )
 			{
 			{
@@ -7892,8 +8077,8 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 	// Check for type compatibility between get and set accessor
 	// Check for type compatibility between get and set accessor
 	if( getId && setId )
 	if( getId && setId )
 	{
 	{
-		asCScriptFunction *getFunc = engine->scriptFunctions[getId];
-		asCScriptFunction *setFunc = engine->scriptFunctions[setId];
+		asCScriptFunction *getFunc = builder->GetFunctionDescription(getId);
+		asCScriptFunction *setFunc = builder->GetFunctionDescription(setId);
 
 
 		// It is permitted for a getter to return a handle and the setter to take a reference
 		// It is permitted for a getter to return a handle and the setter to take a reference
 		int idx = (arg?1:0);
 		int idx = (arg?1:0);
@@ -7921,12 +8106,12 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 	if( outFunc->objectType && isThisAccess )
 	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 ? builder->GetFunctionDescription(getId) : 0;
 		if( getFunc &&
 		if( getFunc &&
 			getFunc->funcType == asFUNC_VIRTUAL &&
 			getFunc->funcType == asFUNC_VIRTUAL &&
 			outFunc->objectType->DerivesFrom(getFunc->objectType) )
 			outFunc->objectType->DerivesFrom(getFunc->objectType) )
 			realGetId = outFunc->objectType->virtualFunctionTable[getFunc->vfTableIdx]->id;
 			realGetId = outFunc->objectType->virtualFunctionTable[getFunc->vfTableIdx]->id;
-		asCScriptFunction *setFunc = setId ? engine->scriptFunctions[setId] : 0;
+		asCScriptFunction *setFunc = setId ? builder->GetFunctionDescription(setId) : 0;
 		if( setFunc &&
 		if( setFunc &&
 			setFunc->funcType == asFUNC_VIRTUAL &&
 			setFunc->funcType == asFUNC_VIRTUAL &&
 			outFunc->objectType->DerivesFrom(setFunc->objectType) )
 			outFunc->objectType->DerivesFrom(setFunc->objectType) )
@@ -7946,9 +8131,9 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 	// Check if the application has disabled script written property accessors
 	// Check if the application has disabled script written property accessors
 	if( engine->ep.propertyAccessorMode == 1 )
 	if( engine->ep.propertyAccessorMode == 1 )
 	{
 	{
-		if( getId && engine->scriptFunctions[getId]->funcType != asFUNC_SYSTEM )
+		if( getId && builder->GetFunctionDescription(getId)->funcType != asFUNC_SYSTEM )
 		  getId = 0;
 		  getId = 0;
-		if( setId && engine->scriptFunctions[setId]->funcType != asFUNC_SYSTEM )
+		if( setId && builder->GetFunctionDescription(setId)->funcType != asFUNC_SYSTEM )
 		  setId = 0;
 		  setId = 0;
 	}
 	}
 
 
@@ -7978,9 +8163,9 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		// unless only the getter is available
 		// unless only the getter is available
 		asCDataType dt;
 		asCDataType dt;
 		if( setId )
 		if( setId )
-			dt = engine->scriptFunctions[setId]->parameterTypes[(arg?1:0)];
+			dt = builder->GetFunctionDescription(setId)->parameterTypes[(arg?1:0)];
 		else
 		else
-			dt = engine->scriptFunctions[getId]->returnType;
+			dt = builder->GetFunctionDescription(getId)->returnType;
 
 
 		// Just change the type, the context must still maintain information
 		// Just change the type, the context must still maintain information
 		// about previous variable offset and the indicator of temporary variable.
 		// about previous variable offset and the indicator of temporary variable.
@@ -8016,7 +8201,7 @@ int asCCompiler::ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext
 	}
 	}
 
 
 	asCTypeInfo objType = ctx->type;
 	asCTypeInfo objType = ctx->type;
-	asCScriptFunction *func = engine->scriptFunctions[ctx->property_set];
+	asCScriptFunction *func = builder->GetFunctionDescription(ctx->property_set);
 
 
 	// Make sure the arg match the property
 	// Make sure the arg match the property
 	asCArray<int> funcs;
 	asCArray<int> funcs;
@@ -8103,7 +8288,7 @@ void asCCompiler::ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode
 	}
 	}
 
 
 	asCTypeInfo objType = ctx->type;
 	asCTypeInfo objType = ctx->type;
-	asCScriptFunction *func = engine->scriptFunctions[ctx->property_get];
+	asCScriptFunction *func = builder->GetFunctionDescription(ctx->property_get);
 
 
 	// Make sure the arg match the property
 	// Make sure the arg match the property
 	asCArray<int> funcs;
 	asCArray<int> funcs;
@@ -8445,7 +8630,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 			asCTypeInfo objType = ctx->type;
 			asCTypeInfo objType = ctx->type;
 
 
 			// Compile function call
 			// Compile function call
-			CompileFunctionCall(node->firstChild, ctx, trueObj, isConst);
+			int r = CompileFunctionCall(node->firstChild, ctx, trueObj, isConst);
+			if( r < 0 ) return r;
 
 
 			// If the method returned a reference, then we can't release the original
 			// If the method returned a reference, then we can't release the original
 			// object yet, because the reference may be to a member of it
 			// object yet, because the reference may be to a member of it
@@ -8470,15 +8656,15 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 	{
 	{
 		// If the property access takes an index arg, then we should use that instead of processing it now
 		// If the property access takes an index arg, then we should use that instead of processing it now
 		asCString propertyName;
 		asCString propertyName;
-		if( (ctx->property_get && engine->scriptFunctions[ctx->property_get]->GetParamCount() == 1) ||
-			(ctx->property_set && engine->scriptFunctions[ctx->property_set]->GetParamCount() == 2) )
+		if( (ctx->property_get && builder->GetFunctionDescription(ctx->property_get)->GetParamCount() == 1) ||
+			(ctx->property_set && builder->GetFunctionDescription(ctx->property_set)->GetParamCount() == 2) )
 		{
 		{
 			// Determine the name of the property accessor
 			// Determine the name of the property accessor
 			asCScriptFunction *func = 0;
 			asCScriptFunction *func = 0;
 			if( ctx->property_get )
 			if( ctx->property_get )
-				func = engine->scriptFunctions[ctx->property_get];
+				func = builder->GetFunctionDescription(ctx->property_get);
 			else
 			else
-				func = engine->scriptFunctions[ctx->property_get];
+				func = builder->GetFunctionDescription(ctx->property_set);
 			propertyName = func->GetName();
 			propertyName = func->GetName();
 			propertyName = propertyName.SubString(4);
 			propertyName = propertyName.SubString(4);
 
 
@@ -8964,9 +9150,15 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 				(!isConst || func->isReadOnly) )
 				(!isConst || func->isReadOnly) )
 			{
 			{
 				// Make sure the method is accessible by the module
 				// Make sure the method is accessible by the module
-				asCConfigGroup *group = engine->FindConfigGroupForFunction(func->id);
-				if( !group || group->HasModuleAccess(builder->module->name.AddressOf()) )
+				if( builder->module->accessMask & func->accessMask )
+				{
+#ifdef AS_DEPRECATED
+					// deprecated since 2011-10-04
+					asCConfigGroup *group = engine->FindConfigGroupForFunction(func->id);
+					if( !group || group->HasModuleAccess(builder->module->name.AddressOf()) )
+#endif
 					funcs.PushLast(func->id);
 					funcs.PushLast(func->id);
+				}
 			}
 			}
 		}
 		}
 
 
@@ -9084,10 +9276,24 @@ void asCCompiler::MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectTyp
 			ctx->bc.ExchangeVar(args[n]->type.stackOffset, newOffset);
 			ctx->bc.ExchangeVar(args[n]->type.stackOffset, newOffset);
 			args[n]->type.stackOffset = (short)newOffset;
 			args[n]->type.stackOffset = (short)newOffset;
 			args[n]->type.isTemporary = true;
 			args[n]->type.isTemporary = true;
-			args[n]->type.isVariable = true;
+			args[n]->type.isVariable  = true;
 		}
 		}
 	}
 	}
 
 
+#ifndef AS_OLD
+	// If the function will return a value type on the stack, then we must allocate space 
+	// for that here and push the address on the stack as a hidden argument to the function
+	asCScriptFunction *func = builder->GetFunctionDescription(funcId);
+	if( func->DoesReturnOnStack() )
+	{
+		asASSERT(!useVariable);
+
+		useVariable = true;
+		stackOffset = AllocateVariable(func->returnType, true);
+		ctx->bc.InstrSHORT(asBC_PSF, short(stackOffset));
+	}
+#endif
+
 	ctx->bc.AddCode(&objBC);
 	ctx->bc.AddCode(&objBC);
 
 
 	MoveArgsToStack(funcId, &ctx->bc, args, objectType ? true : false);
 	MoveArgsToStack(funcId, &ctx->bc, args, objectType ? true : false);
@@ -9800,7 +10006,7 @@ void asCCompiler::CompileBitwiseOperator(asCScriptNode *node, asSExprContext *lc
 		else if( !lctx->type.dataType.IsUnsignedType() )
 		else if( !lctx->type.dataType.IsUnsignedType() )
 		{
 		{
 			asCDataType to;
 			asCDataType to;
-			if( lctx->type.dataType.GetSizeInMemoryDWords() == 2  )
+			if( lctx->type.dataType.GetSizeInMemoryDWords() == 2 )
 				to.SetTokenType(ttInt64);
 				to.SetTokenType(ttInt64);
 			else
 			else
 				to.SetTokenType(ttInt);
 				to.SetTokenType(ttInt);
@@ -10549,6 +10755,14 @@ void asCCompiler::PerformFunctionCall(int funcId, asSExprContext *ctx, bool isCo
 {
 {
 	asCScriptFunction *descr = builder->GetFunctionDescription(funcId);
 	asCScriptFunction *descr = builder->GetFunctionDescription(funcId);
 
 
+	// A shared object may not call non-shared functions
+	if( outFunc->objectType && outFunc->objectType->IsShared() && !descr->IsShared() )
+	{
+		asCString msg;
+		msg.Format(TXT_SHARED_CANNOT_CALL_NON_SHARED_FUNC_s, descr->GetDeclarationStr().AddressOf());
+		Error(msg.AddressOf(), ctx->exprNode);
+	}
+
 	// Check if the function is private
 	// Check if the function is private
 	if( descr->isPrivate && descr->GetObjectType() != outFunc->GetObjectType() )
 	if( descr->isPrivate && descr->GetObjectType() != outFunc->GetObjectType() )
 	{
 	{
@@ -10604,43 +10818,73 @@ void asCCompiler::PerformFunctionCall(int funcId, asSExprContext *ctx, bool isCo
 
 
 		return;
 		return;
 	}
 	}
-	else if( descr->funcType == asFUNC_IMPORTED )
-		ctx->bc.Call(asBC_CALLBND , descr->id, argSize + (descr->objectType ? AS_PTR_SIZE : 0));
-	// TODO: Maybe we need two different byte codes
-	else if( descr->funcType == asFUNC_INTERFACE || descr->funcType == asFUNC_VIRTUAL )
-		ctx->bc.Call(asBC_CALLINTF, descr->id, argSize + (descr->objectType ? AS_PTR_SIZE : 0));
-	else if( descr->funcType == asFUNC_SCRIPT )
-		ctx->bc.Call(asBC_CALL    , descr->id, argSize + (descr->objectType ? AS_PTR_SIZE : 0));
-	else if( descr->funcType == asFUNC_SYSTEM )
-		ctx->bc.Call(asBC_CALLSYS , descr->id, argSize + (descr->objectType ? AS_PTR_SIZE : 0));
-	else if( descr->funcType == asFUNC_FUNCDEF )
-		ctx->bc.CallPtr(asBC_CallPtr, funcPtrVar, argSize);
+	else
+	{
+		if( descr->objectType )
+			argSize += AS_PTR_SIZE;
+#ifndef AS_OLD
+		// If the function returns an object by value the address of the location
+		// where the value should be stored is passed as an argument too
+		if( descr->DoesReturnOnStack() )
+		{
+			argSize += AS_PTR_SIZE;
+		}
+#endif
+
+		if( descr->funcType == asFUNC_IMPORTED )
+			ctx->bc.Call(asBC_CALLBND , descr->id, argSize);
+		// TODO: Maybe we need two different byte codes
+		else if( descr->funcType == asFUNC_INTERFACE || descr->funcType == asFUNC_VIRTUAL )
+			ctx->bc.Call(asBC_CALLINTF, descr->id, argSize);
+		else if( descr->funcType == asFUNC_SCRIPT )
+			ctx->bc.Call(asBC_CALL    , descr->id, argSize);
+		else if( descr->funcType == asFUNC_SYSTEM )
+			ctx->bc.Call(asBC_CALLSYS , descr->id, argSize);
+		else if( descr->funcType == asFUNC_FUNCDEF )
+			ctx->bc.CallPtr(asBC_CallPtr, funcPtrVar, argSize);
+	}
 
 
 	if( ctx->type.dataType.IsObject() && !descr->returnType.IsReference() )
 	if( ctx->type.dataType.IsObject() && !descr->returnType.IsReference() )
 	{
 	{
 		int returnOffset = 0;
 		int returnOffset = 0;
 
 
-		if( useVariable )
+#ifndef AS_OLD
+		if( descr->DoesReturnOnStack() )
 		{
 		{
-			// Use the given variable
+			asASSERT( useVariable );
+
+			// The variable was allocated before the function was called
 			returnOffset = varOffset;
 			returnOffset = varOffset;
-			ctx->type.SetVariable(descr->returnType, returnOffset, false);
+			ctx->type.SetVariable(descr->returnType, returnOffset, true);
+
+			// The variable was initialized by the function, so we need to mark it as initialized here
+			ctx->bc.ObjInfo(varOffset, asOBJ_INIT);
 		}
 		}
 		else
 		else
+#endif
 		{
 		{
-			// Allocate a temporary variable for the returned object
-			// The returned object will actually be allocated on the heap, so
-			// we must force the allocation of the variable to do the same
-			returnOffset = AllocateVariable(descr->returnType, true, true);
-			ctx->type.SetVariable(descr->returnType, returnOffset, true);
+			if( useVariable )
+			{
+				// Use the given variable
+				returnOffset = varOffset;
+				ctx->type.SetVariable(descr->returnType, returnOffset, false);
+			}
+			else
+			{
+				// Allocate a temporary variable for the returned object
+				// The returned object will actually be allocated on the heap, so
+				// we must force the allocation of the variable to do the same
+				returnOffset = AllocateVariable(descr->returnType, true, true);
+				ctx->type.SetVariable(descr->returnType, returnOffset, true);
+			}
+
+			// Move the pointer from the object register to the temporary variable
+			ctx->bc.InstrSHORT(asBC_STOREOBJ, (short)returnOffset);
 		}
 		}
 
 
-		ctx->type.dataType.MakeReference(true);
+		ctx->type.dataType.MakeReference(IsVariableOnHeap(returnOffset));
 		ctx->type.isLValue = false; // It is a reference, but not an lvalue
 		ctx->type.isLValue = false; // It is a reference, but not an lvalue
 
 
-		// Move the pointer from the object register to the temporary variable
-		ctx->bc.InstrSHORT(asBC_STOREOBJ, (short)returnOffset);
-
 		// Clean up arguments
 		// Clean up arguments
 		if( args )
 		if( args )
 			AfterFunctionCall(funcId, *args, ctx, false);
 			AfterFunctionCall(funcId, *args, ctx, false);

+ 4 - 4
ThirdParty/AngelScript/source/as_compiler.h

@@ -142,7 +142,7 @@ protected:
 	int  CompileExpressionPreOp(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionPreOp(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionPostOp(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionPostOp(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionValue(asCScriptNode *node, asSExprContext *out);
 	int  CompileExpressionValue(asCScriptNode *node, asSExprContext *out);
-	void CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
+	int  CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
 	void CompileConstructCall(asCScriptNode *node, asSExprContext *out);
 	void CompileConstructCall(asCScriptNode *node, asSExprContext *out);
 	void CompileConversion(asCScriptNode *node, asSExprContext *out);
 	void CompileConversion(asCScriptNode *node, asSExprContext *out);
 	int  CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
 	int  CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
@@ -156,8 +156,8 @@ protected:
 
 
 	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc);
 	void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc);
 
 
-	int  CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar = false);
-	int  CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false);
+	int  CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, bool isGlobalVar = false, bool deferDest = false);
+	int  CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = false);
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
 	void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
@@ -172,7 +172,7 @@ protected:
 	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);
-	void PrepareForAssignment(asCDataType *lvalue, asSExprContext *rvalue, asCScriptNode *node, asSExprContext *lvalueExpr = 0);
+	void PrepareForAssignment(asCDataType *lvalue, asSExprContext *rvalue, asCScriptNode *node, bool toTemporary, asSExprContext *lvalueExpr = 0);
 	void PerformAssignment(asCTypeInfo *lvalue, asCTypeInfo *rvalue, asCByteCode *bc, asCScriptNode *node);
 	void PerformAssignment(asCTypeInfo *lvalue, asCTypeInfo *rvalue, asCByteCode *bc, asCScriptNode *node);
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	void Dereference(asSExprContext *ctx, bool generateCode);
 	void Dereference(asSExprContext *ctx, bool generateCode);

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

@@ -46,7 +46,10 @@ BEGIN_AS_NAMESPACE
 asCConfigGroup::asCConfigGroup()
 asCConfigGroup::asCConfigGroup()
 {
 {
 	refCount = 0;
 	refCount = 0;
+#ifdef AS_DEPRECATED
+	// Deprecated since 2011-10-04
 	defaultAccess = true;
 	defaultAccess = true;
+#endif
 }
 }
 
 
 asCConfigGroup::~asCConfigGroup()
 asCConfigGroup::~asCConfigGroup()
@@ -207,6 +210,8 @@ void asCConfigGroup::ValidateNoUsage(asCScriptEngine *engine, asCObjectType *typ
 }
 }
 #endif
 #endif
 
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-04
 int asCConfigGroup::SetModuleAccess(const char *module, bool hasAccess)
 int asCConfigGroup::SetModuleAccess(const char *module, bool hasAccess)
 {
 {
 	if( module == asALL_MODULES )
 	if( module == asALL_MODULES )
@@ -240,5 +245,6 @@ bool asCConfigGroup::HasModuleAccess(const char *module)
 	
 	
 	return defaultAccess;
 	return defaultAccess;
 }
 }
+#endif
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 10 - 1
ThirdParty/AngelScript/source/as_configgroup.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 
@@ -44,7 +44,10 @@
 #include "as_string.h"
 #include "as_string.h"
 #include "as_array.h"
 #include "as_array.h"
 #include "as_objecttype.h"
 #include "as_objecttype.h"
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-04
 #include "as_map.h"
 #include "as_map.h"
+#endif
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
@@ -64,8 +67,11 @@ public:
 	bool HasLiveObjects();
 	bool HasLiveObjects();
 	void RemoveConfiguration(asCScriptEngine *engine, bool notUsed = false);
 	void RemoveConfiguration(asCScriptEngine *engine, bool notUsed = false);
 
 
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-04
 	int SetModuleAccess(const char *module, bool hasAccess);
 	int SetModuleAccess(const char *module, bool hasAccess);
 	bool HasModuleAccess(const char *module);
 	bool HasModuleAccess(const char *module);
+#endif
 
 
 #ifdef AS_DEBUG
 #ifdef AS_DEBUG
 	void ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type);
 	void ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type);
@@ -80,9 +86,12 @@ public:
 	asCArray<asCConfigGroup*>    referencedConfigGroups;
 	asCArray<asCConfigGroup*>    referencedConfigGroups;
 	asCArray<asCScriptFunction*> funcDefs;
 	asCArray<asCScriptFunction*> funcDefs;
 
 
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-04
 	// Module access
 	// Module access
 	bool defaultAccess;
 	bool defaultAccess;
 	asCMap<asCString, bool> moduleAccess;
 	asCMap<asCString, bool> moduleAccess;
+#endif
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 165 - 35
ThirdParty/AngelScript/source/as_context.cpp

@@ -172,6 +172,8 @@ asCContext::asCContext(asCScriptEngine *engine, bool holdRef)
 	doSuspend = false;
 	doSuspend = false;
 
 
 	userData = 0;
 	userData = 0;
+
+	regs.ctx = this;
 }
 }
 
 
 asCContext::~asCContext()
 asCContext::~asCContext()
@@ -233,6 +235,7 @@ asIScriptEngine *asCContext::GetEngine() const
 	return engine;
 	return engine;
 }
 }
 
 
+// interface
 void *asCContext::SetUserData(void *data)
 void *asCContext::SetUserData(void *data)
 {
 {
 	void *oldData = userData;
 	void *oldData = userData;
@@ -240,13 +243,31 @@ void *asCContext::SetUserData(void *data)
 	return oldData;
 	return oldData;
 }
 }
 
 
+// interface
 void *asCContext::GetUserData() const
 void *asCContext::GetUserData() const
 {
 {
 	return userData;
 	return userData;
 }
 }
 
 
-int asCContext::Prepare(int funcID)
+// interface
+int asCContext::Prepare(int funcId)
+{
+	if( funcId == -1 )
+	{
+		if( initialFunction == 0 )
+			return asNO_FUNCTION;
+
+		funcId = initialFunction->GetId();
+	}
+	return Prepare(engine->GetFunctionById(funcId));
+}
+
+// interface
+int asCContext::Prepare(asIScriptFunction *func)
 {
 {
+	if( func == 0 ) 
+		return asNO_FUNCTION;
+
 	if( status == asEXECUTION_ACTIVE || status == asEXECUTION_SUSPENDED )
 	if( status == asEXECUTION_ACTIVE || status == asEXECUTION_SUSPENDED )
 		return asCONTEXT_ACTIVE;
 		return asCONTEXT_ACTIVE;
 
 
@@ -257,16 +278,9 @@ int asCContext::Prepare(int funcID)
 	// Release the returned object (if any)
 	// Release the returned object (if any)
 	CleanReturnObject();
 	CleanReturnObject();
 
 
-	if( funcID == -1 )
-	{
-		// Use the previously prepared function
-		if( initialFunction == 0 )
-			return asNO_FUNCTION;
-
-		currentFunction = initialFunction;
-	}
-	else if( initialFunction && initialFunction->id == funcID )
+	if( initialFunction && initialFunction == func )
 	{
 	{
+		// If the same function is executed again, we can skip a lot of the setup 
 		currentFunction = initialFunction;
 		currentFunction = initialFunction;
 	}
 	}
 	else
 	else
@@ -277,16 +291,27 @@ int asCContext::Prepare(int funcID)
 		if( initialFunction )
 		if( initialFunction )
 			initialFunction->Release();
 			initialFunction->Release();
 
 
-		initialFunction = engine->GetScriptFunction(funcID);
-		if( initialFunction == 0 )
-			return asNO_FUNCTION;
-
+		// We trust the application not to pass anything else but a asCScriptFunction
+		initialFunction = reinterpret_cast<asCScriptFunction *>(func);
 		initialFunction->AddRef();
 		initialFunction->AddRef();
 		currentFunction = initialFunction;
 		currentFunction = initialFunction;
 
 
-		// Determine the minimum stack size needed
 		// TODO: optimize: GetSpaceNeededForArguments() should be precomputed
 		// TODO: optimize: GetSpaceNeededForArguments() should be precomputed
-		int stackSize = currentFunction->GetSpaceNeededForArguments() + currentFunction->stackNeeded + RESERVE_STACK;
+		argumentsSize = currentFunction->GetSpaceNeededForArguments() + (currentFunction->objectType ? AS_PTR_SIZE : 0);
+
+#ifndef AS_OLD
+		// Reserve space for the arguments and return value
+		if( currentFunction->DoesReturnOnStack() )
+		{
+			returnValueSize = currentFunction->returnType.GetSizeInMemoryDWords();
+			argumentsSize += AS_PTR_SIZE;
+		}
+		else
+#endif
+			returnValueSize = 0;
+
+		// Determine the minimum stack size needed
+		int stackSize = argumentsSize + returnValueSize + currentFunction->stackNeeded + RESERVE_STACK;
 
 
 		stackSize = stackSize > engine->initialContextStackSize ? stackSize : engine->initialContextStackSize;
 		stackSize = stackSize > engine->initialContextStackSize ? stackSize : engine->initialContextStackSize;
 
 
@@ -305,12 +330,6 @@ int asCContext::Prepare(int funcID)
 			asDWORD *stack = asNEWARRAY(asDWORD,stackBlockSize);
 			asDWORD *stack = asNEWARRAY(asDWORD,stackBlockSize);
 			stackBlocks.PushLast(stack);
 			stackBlocks.PushLast(stack);
 		}
 		}
-
-		// Reserve space for the arguments and return value
-		returnValueSize = currentFunction->GetSpaceNeededForReturnValue();
-
-		// TODO: optimize: GetSpaceNeededForArguments() should be precomputed
-		argumentsSize = currentFunction->GetSpaceNeededForArguments() + (currentFunction->objectType ? AS_PTR_SIZE : 0);
 	}
 	}
 
 
 	// Reset state
 	// Reset state
@@ -329,12 +348,24 @@ int asCContext::Prepare(int funcID)
 	status = asEXECUTION_PREPARED;
 	status = asEXECUTION_PREPARED;
 
 
 	// Reserve space for the arguments and return value
 	// Reserve space for the arguments and return value
-	regs.stackFramePointer = stackBlocks[0] + stackBlockSize - argumentsSize;
+	regs.stackFramePointer = stackBlocks[0] + stackBlockSize - argumentsSize - returnValueSize;
 	regs.stackPointer      = regs.stackFramePointer;
 	regs.stackPointer      = regs.stackFramePointer;
 
 
 	// Set arguments to 0
 	// Set arguments to 0
 	memset(regs.stackPointer, 0, 4*argumentsSize);
 	memset(regs.stackPointer, 0, 4*argumentsSize);
 
 
+#ifndef AS_OLD
+	if( returnValueSize )
+	{
+		// Set the address of the location where the return value should be put
+		asDWORD *ptr = regs.stackFramePointer;
+		if( currentFunction->objectType )
+			ptr += AS_PTR_SIZE;
+
+		*(void**)ptr = (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+	}
+#endif
+
 	if( currentFunction->funcType == asFUNC_SCRIPT )
 	if( currentFunction->funcType == asFUNC_SCRIPT )
 	{
 	{
 		regs.programPointer = currentFunction->byteCode.AddressOf();
 		regs.programPointer = currentFunction->byteCode.AddressOf();
@@ -463,7 +494,13 @@ void *asCContext::GetReturnAddress()
 	if( dt->IsReference() )
 	if( dt->IsReference() )
 		return *(void**)&regs.valueRegister;
 		return *(void**)&regs.valueRegister;
 	else if( dt->IsObject() )
 	else if( dt->IsObject() )
+	{
+#ifndef AS_OLD
+		if( initialFunction->DoesReturnOnStack() )
+			return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif		
 		return regs.objectRegister;
 		return regs.objectRegister;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -479,7 +516,13 @@ void *asCContext::GetReturnObject()
 	if( dt->IsReference() )
 	if( dt->IsReference() )
 		return *(void**)(size_t)regs.valueRegister;
 		return *(void**)(size_t)regs.valueRegister;
 	else
 	else
+	{
+#ifndef AS_OLD
+		if( initialFunction->DoesReturnOnStack() )
+			return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif
 		return regs.objectRegister;
 		return regs.objectRegister;
+	}
 }
 }
 
 
 void *asCContext::GetAddressOfReturnValue()
 void *asCContext::GetAddressOfReturnValue()
@@ -493,7 +536,13 @@ void *asCContext::GetAddressOfReturnValue()
 	{
 	{
 		// Need to dereference objects 
 		// Need to dereference objects 
 		if( !dt->IsObjectHandle() )
 		if( !dt->IsObjectHandle() )
+		{
+#ifndef AS_OLD
+			if( initialFunction->DoesReturnOnStack() )
+				return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif
 			return *(void**)&regs.objectRegister;
 			return *(void**)&regs.objectRegister;
+		}
 		return &regs.objectRegister;
 		return &regs.objectRegister;
 	}
 	}
 
 
@@ -546,6 +595,11 @@ int asCContext::SetArgByte(asUINT arg, asBYTE value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -584,6 +638,11 @@ int asCContext::SetArgWord(asUINT arg, asWORD value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -622,6 +681,11 @@ int asCContext::SetArgDWord(asUINT arg, asDWORD value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -660,6 +724,11 @@ int asCContext::SetArgQWord(asUINT arg, asQWORD value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -698,6 +767,11 @@ int asCContext::SetArgFloat(asUINT arg, float value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -736,6 +810,11 @@ int asCContext::SetArgDouble(asUINT arg, double value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -768,7 +847,11 @@ int asCContext::SetArgAddress(asUINT arg, void *value)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
-
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -817,6 +900,11 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -842,6 +930,11 @@ void *asCContext::GetAddressOfArg(asUINT arg)
 	int offset = 0;
 	int offset = 0;
 	if( initialFunction->objectType )
 	if( initialFunction->objectType )
 		offset += AS_PTR_SIZE;
 		offset += AS_PTR_SIZE;
+#ifndef AS_OLD
+	// If function returns object by value an extra pointer is pushed on the stack
+	if( returnValueSize )
+		offset += AS_PTR_SIZE;
+#endif
 	for( asUINT n = 0; n < arg; n++ )
 	for( asUINT n = 0; n < arg; n++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
 
@@ -1187,11 +1280,11 @@ void asCContext::CallScriptFunction(asCScriptFunction *func)
 				stackBlocks.PushLast(stack);
 				stackBlocks.PushLast(stack);
 			}
 			}
 
 
-			regs.stackPointer = stackBlocks[stackIndex] + (stackBlockSize<<stackIndex) - func->GetSpaceNeededForArguments() - (func->objectType ? AS_PTR_SIZE : 0);
+			regs.stackPointer = stackBlocks[stackIndex] + (stackBlockSize<<stackIndex) - func->GetSpaceNeededForArguments() - (func->objectType ? AS_PTR_SIZE : 0) - (func->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
 		} 
 		} 
 
 
 		// Copy the function arguments to the new stack space
 		// Copy the function arguments to the new stack space
-		int numDwords = func->GetSpaceNeededForArguments() + (func->objectType ? AS_PTR_SIZE : 0);
+		int numDwords = func->GetSpaceNeededForArguments() + (func->objectType ? AS_PTR_SIZE : 0) + (func->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
 		memcpy(regs.stackPointer, oldStackPointer, sizeof(asDWORD)*numDwords);
 		memcpy(regs.stackPointer, oldStackPointer, sizeof(asDWORD)*numDwords);
 	}
 	}
 
 
@@ -1999,15 +2092,15 @@ void asCContext::ExecuteNext()
 			regs.stackPointer = l_sp;
 			regs.stackPointer = l_sp;
 			regs.stackFramePointer = l_fp;
 			regs.stackFramePointer = l_fp;
 
 
-			int funcID = engine->importedFunctions[i&0xFFFF]->boundFunctionId;
-			if( funcID == -1 )
+			int funcId = engine->importedFunctions[i&0xFFFF]->boundFunctionId;
+			if( funcId == -1 )
 			{
 			{
 				SetInternalException(TXT_UNBOUND_FUNCTION);
 				SetInternalException(TXT_UNBOUND_FUNCTION);
 				return;
 				return;
 			}
 			}
 			else
 			else
 			{
 			{
-				asCScriptFunction *func = engine->GetScriptFunction(funcID);
+				asCScriptFunction *func = engine->GetScriptFunction(funcId);
 
 
 				CallScriptFunction(func);
 				CallScriptFunction(func);
 			}
 			}
@@ -3129,21 +3222,25 @@ void asCContext::ExecuteNext()
 		{
 		{
 			if( currentFunction->jitFunction )
 			if( currentFunction->jitFunction )
 			{
 			{
-				unsigned int jitOffset = asBC_WORDARG0(l_bc);
+				asPWORD jitArg = asBC_PTRARG(l_bc);
 
 
-				if( jitOffset )
+				if( jitArg )
 				{
 				{
 					// Resume JIT operation
 					// Resume JIT operation
 					regs.programPointer = l_bc;
 					regs.programPointer = l_bc;
 					regs.stackPointer = l_sp;
 					regs.stackPointer = l_sp;
 					regs.stackFramePointer = l_fp;
 					regs.stackFramePointer = l_fp;
 
 
-					// TODO: JIT: We should return from this function if the jitFunction tells us to
-					(currentFunction->jitFunction)(&regs, jitOffset-1);
+					(currentFunction->jitFunction)(&regs, jitArg);
 				
 				
 					l_bc = regs.programPointer;
 					l_bc = regs.programPointer;
 					l_sp = regs.stackPointer;
 					l_sp = regs.stackPointer;
 					l_fp = regs.stackFramePointer;
 					l_fp = regs.stackFramePointer;
+
+					// If status isn't active anymore then we must stop
+					if( status != asEXECUTION_ACTIVE )
+						return;
+				
 					break;
 					break;
 				}
 				}
 			}
 			}
@@ -3405,7 +3502,8 @@ void asCContext::ExecuteNext()
 #ifdef AS_DEBUG
 #ifdef AS_DEBUG
 		asDWORD instr = *(asBYTE*)old;
 		asDWORD instr = *(asBYTE*)old;
 		if( instr != asBC_JMP && instr != asBC_JMPP && (instr < asBC_JZ || instr > asBC_JNP) &&
 		if( instr != asBC_JMP && instr != asBC_JMPP && (instr < asBC_JZ || instr > asBC_JNP) &&
-			instr != asBC_CALL && instr != asBC_CALLBND && instr != asBC_CALLINTF && instr != asBC_RET && instr != asBC_ALLOC && instr != asBC_CallPtr )
+			instr != asBC_CALL && instr != asBC_CALLBND && instr != asBC_CALLINTF && instr != asBC_RET && instr != asBC_ALLOC && instr != asBC_CallPtr && 
+			instr != asBC_JitEntry )
 		{
 		{
 			asASSERT( (l_bc - old) == asBCTypeSize[asBCInfo[instr].type] );
 			asASSERT( (l_bc - old) == asBCTypeSize[asBCInfo[instr].type] );
 		}
 		}
@@ -3448,6 +3546,17 @@ void asCContext::SetInternalException(const char *descr)
 
 
 void asCContext::CleanReturnObject()
 void asCContext::CleanReturnObject()
 {
 {
+#ifndef AS_OLD
+	if( initialFunction && initialFunction->DoesReturnOnStack() && status == asEXECUTION_FINISHED )
+	{
+		// If function returns on stack we need to call the destructor on the returned object
+		if( initialFunction->returnType.GetObjectType()->beh.destruct )
+			engine->CallObjectMethod((void*)(stackBlocks[0] + stackBlockSize - returnValueSize), initialFunction->returnType.GetObjectType()->beh.destruct);
+
+		return;
+	}
+#endif
+
 	if( regs.objectRegister == 0 ) return;
 	if( regs.objectRegister == 0 ) return;
 
 
 	asASSERT( regs.objectType != 0 );
 	asASSERT( regs.objectType != 0 );
@@ -3565,13 +3674,25 @@ void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLe
 		pos = asUINT((asDWORD*)s[2] - func->byteCode.AddressOf());
 		pos = asUINT((asDWORD*)s[2] - func->byteCode.AddressOf());
 	}
 	}
 
 
+	if( status == asEXECUTION_EXCEPTION )
+	{
+		// Don't consider the last instruction as executed, as it failed with an exception
+		// It's not actually necessary to decrease the exact size of the instruction. Just 
+		// before the current position is enough to disconsider it.
+		pos--;
+	}
+
 
 
 	// Determine which object variables that are really live ones
 	// Determine which object variables that are really live ones
 	liveObjects.SetLength(func->objVariablePos.GetLength());
 	liveObjects.SetLength(func->objVariablePos.GetLength());
 	memset(liveObjects.AddressOf(), 0, sizeof(int)*liveObjects.GetLength());
 	memset(liveObjects.AddressOf(), 0, sizeof(int)*liveObjects.GetLength());
 	for( int n = 0; n < (int)func->objVariableInfo.GetLength(); n++ )
 	for( int n = 0; n < (int)func->objVariableInfo.GetLength(); n++ )
 	{
 	{
-		if( func->objVariableInfo[n].programPos >= pos )
+		// Find the first variable info with a larger position than the current
+		// As the variable info are always placed on the instruction right after the 
+		// one that initialized or freed the object, the current position needs to be 
+		// considered as valid.
+		if( func->objVariableInfo[n].programPos > pos )
 		{
 		{
 			// We've determined how far the execution ran, now determine which variables are alive
 			// We've determined how far the execution ran, now determine which variables are alive
 			for( --n; n >= 0; n-- )
 			for( --n; n >= 0; n-- )
@@ -3894,6 +4015,15 @@ int asCContext::CallGeneric(int id, void *objectPointer)
 		}
 		}
 	}
 	}
 
 
+#ifndef AS_OLD
+	if( sysFunction->DoesReturnOnStack() )
+	{
+		// Skip the address where the return value will be stored
+		args += AS_PTR_SIZE;
+		popSize += AS_PTR_SIZE;
+	}
+#endif
+
 	asCGeneric gen(engine, sysFunction, currentObject, args);
 	asCGeneric gen(engine, sysFunction, currentObject, args);
 
 
 	isCallingSystemFunction = true;
 	isCallingSystemFunction = true;

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

@@ -51,8 +51,6 @@ BEGIN_AS_NAMESPACE
 class asCScriptFunction;
 class asCScriptFunction;
 class asCScriptEngine;
 class asCScriptEngine;
 
 
-// TODO: The context should be renamed to something that better describes it, e.g. asIVirtualMachine, asIExecuter, asIProcessor, asIScriptThread, or something like that
-
 class asCContext : public asIScriptContext
 class asCContext : public asIScriptContext
 {
 {
 public:
 public:
@@ -64,7 +62,9 @@ public:
 
 
 	asEContextState GetState() const;
 	asEContextState GetState() const;
 
 
-	int  Prepare(int functionID);
+	int  Prepare(asIScriptFunction *func);
+	// TODO: interface: deprecate this
+	int  Prepare(int functionId);
 	int  Unprepare();
 	int  Unprepare();
 
 
 	int SetArgByte(asUINT arg, asBYTE value);
 	int SetArgByte(asUINT arg, asBYTE value);

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

@@ -93,6 +93,7 @@ BEGIN_AS_NAMESPACE
 
 
 // Undefine macros that cause problems in our code
 // Undefine macros that cause problems in our code
 #undef GetObject
 #undef GetObject
+#undef RegisterClass
 
 
 class asCThreadCriticalSection
 class asCThreadCriticalSection
 {
 {

+ 36 - 2
ThirdParty/AngelScript/source/as_gc.cpp

@@ -41,6 +41,7 @@
 #include "as_gc.h"
 #include "as_gc.h"
 #include "as_scriptengine.h"
 #include "as_scriptengine.h"
 #include "as_scriptobject.h"
 #include "as_scriptobject.h"
+#include "as_texts.h"
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
@@ -365,6 +366,18 @@ int asCGarbageCollector::DestroyNewGarbage()
 	UNREACHABLE_RETURN;
 	UNREACHABLE_RETURN;
 }
 }
 
 
+void asCGarbageCollector::ReportUndestroyedObjects()
+{
+	for( asUINT n = 0; n < gcOldObjects.GetLength(); n++ )
+	{
+		asSObjTypePair gcObj = GetOldObjectAtIdx(n);
+
+		asCString msg;
+		msg.Format(TXT_GC_CANNOT_FREE_OBJ_OF_TYPE_s, gcObj.type->name.AddressOf());
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
+	}
+}
+
 int asCGarbageCollector::DestroyOldGarbage()
 int asCGarbageCollector::DestroyOldGarbage()
 {
 {
 	for(;;)
 	for(;;)
@@ -395,7 +408,24 @@ int asCGarbageCollector::DestroyOldGarbage()
 			if( ++destroyOldIdx < gcOldObjects.GetLength() )
 			if( ++destroyOldIdx < gcOldObjects.GetLength() )
 			{
 			{
 				asSObjTypePair gcObj = GetOldObjectAtIdx(destroyOldIdx);
 				asSObjTypePair gcObj = GetOldObjectAtIdx(destroyOldIdx);
-				if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
+
+				if( gcObj.type->beh.gcGetRefCount == 0 )
+				{
+					// If circular references are formed with registered types that hasn't 
+					// registered the GC behaviours, then the engine may be forced to free
+					// the object type before the actual object instance. In this case we
+					// will be forced to skip the destruction of the objects, so as not to 
+					// crash the application.
+					asCString msg;
+					msg.Format(TXT_GC_CANNOT_FREE_OBJ_OF_TYPE_s, gcObj.type->name.AddressOf());
+					engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
+
+					// Just remove the object, as we will not bother to destroy it
+					numDestroyed++;
+					RemoveOldObjectAtIdx(destroyOldIdx);
+					destroyOldIdx--;
+				}
+				else if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
 				{
 				{
 					// Release the object immediately
 					// Release the object immediately
 
 
@@ -510,7 +540,11 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			{
 			{
 				// Add the gc count for this object
 				// Add the gc count for this object
 				asSObjTypePair gcObj = GetOldObjectAtIdx(detectIdx);
 				asSObjTypePair gcObj = GetOldObjectAtIdx(detectIdx);
-				int refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
+	
+				int refCount = 0;
+				if( gcObj.type->beh.gcGetRefCount )
+					refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
+
 				if( refCount > 1 )
 				if( refCount > 1 )
 				{
 				{
 					asSIntTypePair it = {refCount-1, gcObj.type};
 					asSIntTypePair it = {refCount-1, gcObj.type};

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

@@ -60,6 +60,8 @@ public:
 	void GCEnumCallback(void *reference);
 	void GCEnumCallback(void *reference);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
 	void AddScriptObjectToGC(void *obj, asCObjectType *objType);
 
 
+	void ReportUndestroyedObjects();
+
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
 
 
 protected:
 protected:

+ 34 - 1
ThirdParty/AngelScript/source/as_generic.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 
@@ -74,11 +74,20 @@ int asCGeneric::GetFunctionId() const
 	return sysFunction->id;
 	return sysFunction->id;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 // interface
 // interface
 asIScriptFunction *asCGeneric::GetFunctionDescriptor() const
 asIScriptFunction *asCGeneric::GetFunctionDescriptor() const
 {
 {
 	return sysFunction;
 	return sysFunction;
 }
 }
+#endif
+
+// interface
+asIScriptFunction *asCGeneric::GetFunction() const
+{
+	return sysFunction;
+}
 
 
 // interface
 // interface
 void *asCGeneric::GetFunctionUserData() const
 void *asCGeneric::GetFunctionUserData() const
@@ -465,7 +474,16 @@ int asCGeneric::SetReturnObject(void *obj)
 	}
 	}
 	else
 	else
 	{
 	{
+#ifndef AS_OLD
+		// If function returns object by value the memory is already allocated.
+		// Here we should just initialize that memory by calling the copy constructor
+		// or the default constructor followed by the assignment operator
+		void *mem = (void*)*(size_t*)&stackPointer[-AS_PTR_SIZE];
+		engine->ConstructScriptObjectCopy(mem, obj, dt->GetObjectType());
+		return 0;
+#else
 		obj = engine->CreateScriptObjectCopy(obj, engine->GetTypeIdFromDataType(*dt));
 		obj = engine->CreateScriptObjectCopy(obj, engine->GetTypeIdFromDataType(*dt));
+#endif
 	}
 	}
 
 
 	objectRegister = obj;
 	objectRegister = obj;
@@ -479,7 +497,13 @@ void *asCGeneric::GetReturnPointer()
 	asCDataType &dt = sysFunction->returnType;
 	asCDataType &dt = sysFunction->returnType;
 
 
 	if( dt.IsObject() && !dt.IsReference() )
 	if( dt.IsObject() && !dt.IsReference() )
+	{
+		// This function doesn't support returning on the stack but the use of 
+		// the function doesn't require it so we don't need to implement it here.
+		asASSERT( !sysFunction->DoesReturnOnStack() );
+
 		return &objectRegister;
 		return &objectRegister;
+	}
 
 
 	return &returnVal;
 	return &returnVal;
 }
 }
@@ -491,6 +515,14 @@ void *asCGeneric::GetAddressOfReturnLocation()
 
 
 	if( dt.IsObject() && !dt.IsReference() )
 	if( dt.IsObject() && !dt.IsReference() )
 	{
 	{
+#ifndef AS_OLD
+		if( sysFunction->DoesReturnOnStack() )
+		{
+			// The memory is already preallocated on the stack,
+			// and the pointer to the location is found before the first arg
+			return (void*)*(size_t*)&stackPointer[-AS_PTR_SIZE];
+		}
+#else
 		if( dt.GetObjectType()->flags & asOBJ_VALUE )
 		if( dt.GetObjectType()->flags & asOBJ_VALUE )
 		{
 		{
 			// Allocate the necessary memory for this object, 
 			// Allocate the necessary memory for this object, 
@@ -501,6 +533,7 @@ void *asCGeneric::GetAddressOfReturnLocation()
 
 
 			return objectRegister;
 			return objectRegister;
 		}
 		}
+#endif
 
 
 		// Reference types store the handle in the objectReference
 		// Reference types store the handle in the objectReference
 		return &objectRegister;
 		return &objectRegister;

+ 5 - 1
ThirdParty/AngelScript/source/as_generic.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 
@@ -55,7 +55,11 @@ public:
 	// Miscellaneous
 	// Miscellaneous
 	asIScriptEngine   *GetEngine() const;
 	asIScriptEngine   *GetEngine() const;
 	int                GetFunctionId() const;
 	int                GetFunctionId() const;
+	asIScriptFunction *GetFunction() const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	asIScriptFunction *GetFunctionDescriptor() const;
 	asIScriptFunction *GetFunctionDescriptor() const;
+#endif
 	void              *GetFunctionUserData() const;
 	void              *GetFunctionUserData() const;
 
 
 	// Object
 	// Object

+ 2 - 1
ThirdParty/AngelScript/source/as_globalproperty.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 
@@ -43,6 +43,7 @@ asCGlobalProperty::asCGlobalProperty()
 	memoryAllocated = false; 
 	memoryAllocated = false; 
 	realAddress = 0; 
 	realAddress = 0; 
 	initFunc = 0;
 	initFunc = 0;
+	accessMask = 0xFFFFFFFF;
 
 
 	refCount.set(1);
 	refCount.set(1);
 }
 }

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

@@ -1,6 +1,6 @@
 /*
 /*
    AngelCode Scripting Library
    AngelCode Scripting Library
-   Copyright (c) 2003-2007 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 
@@ -324,14 +324,14 @@ bool asCMap<KEY, VAL>::MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key)
 			p = p->left;
 			p = p->left;
 		else if( key == p->key )
 		else if( key == p->key )
 		{
 		{
-			*out = p;
+			if( out ) *out = p;
 			return true;
 			return true;
 		}
 		}
 		else 
 		else 
 			p = p->right;
 			p = p->right;
 	}
 	}
 
 
-	*out = 0;
+	if( out ) *out = 0;
 	return false;
 	return false;
 }
 }
 
 

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

@@ -50,8 +50,11 @@ asCModule::asCModule(const char *name, asCScriptEngine *engine)
 	this->name     = name;
 	this->name     = name;
 	this->engine   = engine;
 	this->engine   = engine;
 
 
+	userData = 0;
 	builder = 0;
 	builder = 0;
 	isGlobalVarInitialized = false;
 	isGlobalVarInitialized = false;
+
+	accessMask = 1;
 }
 }
 
 
 // internal
 // internal
@@ -65,6 +68,10 @@ asCModule::~asCModule()
 		builder = 0;
 		builder = 0;
 	}
 	}
 
 
+	// Clean the user data
+	if( userData && engine->cleanModuleFunc )
+		engine->cleanModuleFunc(this);
+
 	// Remove the module from the engine
 	// Remove the module from the engine
 	if( engine )
 	if( engine )
 	{
 	{
@@ -75,6 +82,20 @@ asCModule::~asCModule()
 	}
 	}
 }
 }
 
 
+// interface
+void *asCModule::SetUserData(void *data)
+{
+	void *oldData = userData;
+	userData = data;
+	return oldData;
+}
+
+// interface
+void *asCModule::GetUserData() const
+{
+	return userData;
+}
+
 // interface
 // interface
 asIScriptEngine *asCModule::GetEngine() const
 asIScriptEngine *asCModule::GetEngine() const
 {
 {
@@ -180,6 +201,15 @@ int asCModule::GetFunctionIdByIndex(asUINT index) const
 	return globalFunctions[index]->id;
 	return globalFunctions[index]->id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
+{
+	if( index >= globalFunctions.GetLength() )
+		return 0;
+
+	return globalFunctions[index];
+}
+
 // internal
 // internal
 int asCModule::CallInit(asIScriptContext *myCtx)
 int asCModule::CallInit(asIScriptContext *myCtx)
 {
 {
@@ -229,7 +259,7 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 					if( r == asEXECUTION_EXCEPTION )
 					if( r == asEXECUTION_EXCEPTION )
 					{
 					{
 						int funcId = ctx->GetExceptionFunction();
 						int funcId = ctx->GetExceptionFunction();
-						const asIScriptFunction *function = engine->GetFunctionDescriptorById(funcId);
+						const asIScriptFunction *function = engine->GetFunctionById(funcId);
 
 
 						msg.Format(TXT_EXCEPTION_s_IN_s, ctx->GetExceptionString(), function->GetDeclaration());
 						msg.Format(TXT_EXCEPTION_s_IN_s, ctx->GetExceptionString(), function->GetDeclaration());
 
 
@@ -384,6 +414,16 @@ int asCModule::GetFunctionIdByName(const char *name) const
 	return id;
 	return id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
+{
+	int id = GetFunctionIdByName(name);
+	if( id < 0 )
+		return 0;
+
+	return engine->GetFunctionById(id);
+}
+
 // interface
 // interface
 asUINT asCModule::GetImportedFunctionCount() const
 asUINT asCModule::GetImportedFunctionCount() const
 {
 {
@@ -483,6 +523,13 @@ int asCModule::GetFunctionIdByDecl(const char *decl) const
 	return id;
 	return id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
+{
+	int id = GetFunctionIdByDecl(decl);
+	return engine->GetFunctionById(id);
+}
+
 // interface
 // interface
 asUINT asCModule::GetGlobalVarCount() const
 asUINT asCModule::GetGlobalVarCount() const
 {
 {
@@ -520,6 +567,8 @@ int asCModule::RemoveGlobalVar(asUINT index)
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 // interface
 // interface
 asIScriptFunction *asCModule::GetFunctionDescriptorByIndex(asUINT index) const
 asIScriptFunction *asCModule::GetFunctionDescriptorByIndex(asUINT index) const
 {
 {
@@ -534,6 +583,7 @@ asIScriptFunction *asCModule::GetFunctionDescriptorById(int funcId) const
 {
 {
 	return engine->GetFunctionDescriptorById(funcId);
 	return engine->GetFunctionDescriptorById(funcId);
 }
 }
+#endif
 
 
 // interface
 // interface
 int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
 int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
@@ -1155,8 +1205,8 @@ bool asCModule::AreInterfacesEqual(asCObjectType *a, asCObjectType *b, asCArray<
 	{
 	{
 		match = false;
 		match = false;
 
 
-		asCScriptFunction *funcA = (asCScriptFunction*)engine->GetFunctionDescriptorById(a->methods[n]);
-		asCScriptFunction *funcB = (asCScriptFunction*)engine->GetFunctionDescriptorById(b->methods[n]);
+		asCScriptFunction *funcA = (asCScriptFunction*)engine->GetFunctionById(a->methods[n]);
+		asCScriptFunction *funcB = (asCScriptFunction*)engine->GetFunctionById(b->methods[n]);
 
 
 		// funcB can be null if the module that created the interface has been  
 		// funcB can be null if the module that created the interface has been  
 		// discarded but the type has not yet been released by the engine.
 		// discarded but the type has not yet been released by the engine.
@@ -1420,5 +1470,13 @@ int asCModule::AddFuncDef(const char *name)
 	return (int)funcDefs.GetLength()-1;
 	return (int)funcDefs.GetLength()-1;
 }
 }
 
 
+// interface
+asDWORD asCModule::SetAccessMask(asDWORD mask)
+{
+	asDWORD old = accessMask;
+	accessMask = mask;
+	return old;
+}
+
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

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

@@ -87,9 +87,6 @@ struct sObjectTypePair
 //       then it should simply replace the bytecode within the functions without
 //       then it should simply replace the bytecode within the functions without
 //       changing the values of existing global properties, etc.
 //       changing the values of existing global properties, etc.
 
 
-// TODO: interface: Should have user data in the modules as well. This may be 
-//                  used to store extra information, such as meta-data and source code files
-
 class asCModule : public asIScriptModule
 class asCModule : public asIScriptModule
 {
 {
 //-------------------------------------------
 //-------------------------------------------
@@ -101,18 +98,25 @@ public:
 	virtual const char      *GetName() const;
 	virtual const char      *GetName() const;
 
 
 	// Compilation
 	// Compilation
-	virtual int  AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset);
-	virtual int  Build();
-	virtual int  CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD reserved, asIScriptFunction **outFunc);
-	virtual int  CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
+	virtual int     AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset);
+	virtual int     Build();
+	virtual int     CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD reserved, asIScriptFunction **outFunc);
+	virtual int     CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
+	virtual asDWORD SetAccessMask(asDWORD accessMask);
 
 
 	// Script functions
 	// Script functions
 	virtual asUINT             GetFunctionCount() const;
 	virtual asUINT             GetFunctionCount() const;
 	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByName(const char *name) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
 	virtual int                GetFunctionIdByDecl(const char *decl) const;
+	virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const;
+	virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const;
+	virtual asIScriptFunction *GetFunctionByName(const char *name) const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetFunctionDescriptorByIndex(asUINT index) const;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
+#endif
 	virtual int                RemoveFunction(int funcId);
 	virtual int                RemoveFunction(int funcId);
 
 
 	// Script global variables
 	// Script global variables
@@ -128,6 +132,7 @@ public:
 	// Type identification
 	// Type identification
 	virtual asUINT         GetObjectTypeCount() const;
 	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
+	// TODO: interface: Should have GetObjectTypeByName
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 
 
 	// Enums
 	// Enums
@@ -154,6 +159,10 @@ public:
 	virtual int SaveByteCode(asIBinaryStream *out) const;
 	virtual int SaveByteCode(asIBinaryStream *out) const;
 	virtual int LoadByteCode(asIBinaryStream *in);
 	virtual int LoadByteCode(asIBinaryStream *in);
 
 
+	// User data
+	virtual void *SetUserData(void *data);
+	virtual void *GetUserData() const;
+
 //-----------------------------------------------
 //-----------------------------------------------
 // Internal
 // Internal
 //-----------------------------------------------
 //-----------------------------------------------
@@ -196,6 +205,8 @@ public:
 
 
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
 	asCBuilder      *builder;
 	asCBuilder      *builder;
+	void            *userData;
+	asDWORD          accessMask;
 
 
 	// This array holds all functions, class members, factories, etc that were compiled with the module
 	// This array holds all functions, class members, factories, etc that were compiled with the module
 	asCArray<asCScriptFunction *>  scriptFunctions;
 	asCArray<asCScriptFunction *>  scriptFunctions;

+ 119 - 28
ThirdParty/AngelScript/source/as_objecttype.cpp

@@ -127,7 +127,11 @@ asCObjectType::asCObjectType()
 	derivedFrom = 0;
 	derivedFrom = 0;
 
 
 	acceptValueSubType = true;
 	acceptValueSubType = true;
-	acceptRefSubType = true;
+	acceptRefSubType   = true;
+
+	accessMask = 0xFFFFFFFF;
+
+	userData = 0;
 }
 }
 
 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
@@ -138,6 +142,10 @@ asCObjectType::asCObjectType(asCScriptEngine *engine)
 
 
 	acceptValueSubType = true;
 	acceptValueSubType = true;
 	acceptRefSubType = true;
 	acceptRefSubType = true;
+
+	accessMask = 0xFFFFFFFF;
+
+	userData = 0;
 }
 }
 
 
 int asCObjectType::AddRef() const
 int asCObjectType::AddRef() const
@@ -152,6 +160,18 @@ int asCObjectType::Release() const
 	return refCount.atomicDec();
 	return refCount.atomicDec();
 }
 }
 
 
+void *asCObjectType::SetUserData(void *data)
+{
+	void *oldData = userData;
+	userData = data;
+	return oldData;
+}
+
+void *asCObjectType::GetUserData() const
+{
+	return userData;
+}
+
 int asCObjectType::GetRefCount()
 int asCObjectType::GetRefCount()
 {
 {
 	return refCount.get();
 	return refCount.get();
@@ -201,9 +221,14 @@ asCObjectType::~asCObjectType()
 	}
 	}
 
 
 	enumValues.SetLength(0);
 	enumValues.SetLength(0);
+
+	// Clean the user data
+	if( userData && engine->cleanObjectTypeFunc )
+		engine->cleanObjectTypeFunc(this);
 }
 }
 
 
-bool asCObjectType::Implements(const asCObjectType *objType) const
+// interface
+bool asCObjectType::Implements(const asIObjectType *objType) const
 {
 {
 	if( this == objType )
 	if( this == objType )
 		return true;
 		return true;
@@ -214,7 +239,8 @@ bool asCObjectType::Implements(const asCObjectType *objType) const
 	return false;
 	return false;
 }
 }
 
 
-bool asCObjectType::DerivesFrom(const asCObjectType *objType) const
+// interface
+bool asCObjectType::DerivesFrom(const asIObjectType *objType) const
 {
 {
 	if( this == objType )
 	if( this == objType )
 		return true;
 		return true;
@@ -231,6 +257,15 @@ bool asCObjectType::DerivesFrom(const asCObjectType *objType) const
 	return false;
 	return false;
 }
 }
 
 
+bool asCObjectType::IsShared() const
+{
+	// Objects that can be declared by scripts need to have the explicit flag asOBJ_SHARED
+	if( flags & (asOBJ_SCRIPT_OBJECT|asOBJ_ENUM) ) return flags & asOBJ_SHARED ? true : false;
+
+	// Otherwise we assume the object to be shared
+	return true;
+}
+
 // interface
 // interface
 const char *asCObjectType::GetName() const
 const char *asCObjectType::GetName() const
 {
 {
@@ -274,6 +309,18 @@ int asCObjectType::GetSubTypeId() const
 	return asERROR;
 	return asERROR;
 }
 }
 
 
+// interface
+asIObjectType *asCObjectType::GetSubType() const
+{
+	// TODO: template: This method should allow indexing multiple template subtypes
+	if( flags & asOBJ_TEMPLATE )
+	{
+		return templateSubType.GetObjectType();
+	}
+
+	return 0;
+}
+
 asUINT asCObjectType::GetInterfaceCount() const
 asUINT asCObjectType::GetInterfaceCount() const
 {
 {
 	return (asUINT)interfaces.GetLength();
 	return (asUINT)interfaces.GetLength();
@@ -298,11 +345,13 @@ asIScriptEngine *asCObjectType::GetEngine() const
 	return engine;
 	return engine;
 }
 }
 
 
+// interface
 asUINT asCObjectType::GetFactoryCount() const
 asUINT asCObjectType::GetFactoryCount() const
 {
 {
 	return (asUINT)beh.factories.GetLength();
 	return (asUINT)beh.factories.GetLength();
 }
 }
 
 
+// interface
 int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 {
 {
 	if( index >= beh.factories.GetLength() )
 	if( index >= beh.factories.GetLength() )
@@ -311,6 +360,16 @@ int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 	return beh.factories[index];
 	return beh.factories[index];
 }
 }
 
 
+// interface
+asIScriptFunction *asCObjectType::GetFactoryByIndex(asUINT index) const
+{
+	if( index >= beh.factories.GetLength() )
+		return 0;
+
+	return engine->GetFunctionById(beh.factories[index]);
+}
+
+// interface
 int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 {
 {
 	if( beh.factories.GetLength() == 0 )
 	if( beh.factories.GetLength() == 0 )
@@ -320,6 +379,16 @@ int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 	return engine->GetFactoryIdByDecl(this, decl);
 	return engine->GetFactoryIdByDecl(this, decl);
 }
 }
 
 
+// interface
+asIScriptFunction *asCObjectType::GetFactoryByDecl(const char *decl) const
+{
+	if( beh.factories.GetLength() == 0 )
+		return 0;
+
+	// Let the engine parse the string and find the appropriate factory function
+	return engine->GetFunctionById(engine->GetFactoryIdByDecl(this, decl));
+}
+
 // interface
 // interface
 asUINT asCObjectType::GetMethodCount() const
 asUINT asCObjectType::GetMethodCount() const
 {
 {
@@ -342,6 +411,12 @@ int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 	return methods[index];
 	return methods[index];
 }
 }
 
 
+// interface
+asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual) const
+{
+	return engine->GetFunctionById(GetMethodIdByIndex(index, getVirtual));
+}
+
 // interface
 // interface
 int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 {
 {
@@ -369,6 +444,12 @@ int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 	return id;
 	return id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
+{
+	return engine->GetFunctionById(GetMethodIdByName(name, getVirtual));
+}
+
 // interface
 // interface
 int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 {
 {
@@ -396,6 +477,14 @@ int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 	return id;
 	return id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCObjectType::GetMethodByDecl(const char *decl, bool getVirtual) const
+{
+	return engine->GetFunctionById(GetMethodIdByDecl(decl, getVirtual));
+}
+
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 // interface
 // interface
 asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const
 asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const
 {
 {
@@ -411,6 +500,7 @@ asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool
 
 
 	return engine->scriptFunctions[methods[index]];
 	return engine->scriptFunctions[methods[index]];
 }
 }
+#endif
 
 
 // interface
 // interface
 asUINT asCObjectType::GetPropertyCount() const
 asUINT asCObjectType::GetPropertyCount() const
@@ -659,6 +749,32 @@ void asCObjectType::ReleaseAllFunctions()
 		engine->scriptFunctions[beh.destruct]->Release();
 		engine->scriptFunctions[beh.destruct]->Release();
 	beh.destruct  = 0;
 	beh.destruct  = 0;
 
 
+	if( beh.copy )
+		engine->scriptFunctions[beh.copy]->Release();
+	beh.copy = 0;
+
+	for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
+	{
+		if( engine->scriptFunctions[beh.operators[e]] )
+			engine->scriptFunctions[beh.operators[e]]->Release();
+	}
+	beh.operators.SetLength(0);
+
+	for( asUINT c = 0; c < methods.GetLength(); c++ )
+	{
+		if( engine->scriptFunctions[methods[c]] ) 
+			engine->scriptFunctions[methods[c]]->Release();
+	}
+	methods.SetLength(0);
+
+	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
+	{
+		if( virtualFunctionTable[d] )
+			virtualFunctionTable[d]->Release();
+	}
+	virtualFunctionTable.SetLength(0);
+
+	// GC behaviours
 	if( beh.addref )
 	if( beh.addref )
 		engine->scriptFunctions[beh.addref]->Release();
 		engine->scriptFunctions[beh.addref]->Release();
 	beh.addref = 0;
 	beh.addref = 0;
@@ -667,10 +783,6 @@ void asCObjectType::ReleaseAllFunctions()
 		engine->scriptFunctions[beh.release]->Release();
 		engine->scriptFunctions[beh.release]->Release();
 	beh.release = 0;
 	beh.release = 0;
 
 
-	if( beh.copy )
-		engine->scriptFunctions[beh.copy]->Release();
-	beh.copy = 0;
-
 	if( beh.gcEnumReferences )
 	if( beh.gcEnumReferences )
 		engine->scriptFunctions[beh.gcEnumReferences]->Release();
 		engine->scriptFunctions[beh.gcEnumReferences]->Release();
 	beh.gcEnumReferences = 0;
 	beh.gcEnumReferences = 0;
@@ -690,27 +802,6 @@ void asCObjectType::ReleaseAllFunctions()
 	if( beh.gcSetFlag )
 	if( beh.gcSetFlag )
 		engine->scriptFunctions[beh.gcSetFlag]->Release();
 		engine->scriptFunctions[beh.gcSetFlag]->Release();
 	beh.gcSetFlag = 0;
 	beh.gcSetFlag = 0;
-
-	for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
-	{
-		if( engine->scriptFunctions[beh.operators[e]] )
-			engine->scriptFunctions[beh.operators[e]]->Release();
-	}
-	beh.operators.SetLength(0);
-
-	for( asUINT c = 0; c < methods.GetLength(); c++ )
-	{
-		if( engine->scriptFunctions[methods[c]] ) 
-			engine->scriptFunctions[methods[c]]->Release();
-	}
-	methods.SetLength(0);
-
-	for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
-	{
-		if( virtualFunctionTable[d] )
-			virtualFunctionTable[d]->Release();
-	}
-	virtualFunctionTable.SetLength(0);
 }
 }
 
 
 // internal
 // internal

+ 21 - 8
ThirdParty/AngelScript/source/as_objecttype.h

@@ -54,14 +54,13 @@ BEGIN_AS_NAMESPACE
 // TODO: The type id should have flags for diferenciating between value types and reference types. It should also have a flag for differenciating interface types.
 // TODO: The type id should have flags for diferenciating between value types and reference types. It should also have a flag for differenciating interface types.
 
 
 // Additional flag to the class object type
 // Additional flag to the class object type
-const asDWORD asOBJ_IMPLICIT_HANDLE  = 0x40000;
+const asDWORD asOBJ_IMPLICIT_HANDLE  = 0x00400000;
 const asDWORD asOBJ_TYPEDEF          = 0x40000000;
 const asDWORD asOBJ_TYPEDEF          = 0x40000000;
 const asDWORD asOBJ_ENUM             = 0x10000000;
 const asDWORD asOBJ_ENUM             = 0x10000000;
 const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
 const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
 
 
 
 
 
 
-
 // asOBJ_GC is used to indicate that the type can potentially 
 // asOBJ_GC is used to indicate that the type can potentially 
 // form circular references, thus is garbage collected.
 // form circular references, thus is garbage collected.
 
 
@@ -74,10 +73,6 @@ const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
 // automatically make garbage collected as well, because we cannot know what type
 // automatically make garbage collected as well, because we cannot know what type
 // of references that object can contain, and must assume the worst.
 // of references that object can contain, and must assume the worst.
 
 
-// TODO: interface: asIObjectType should have methods for setting/getting user data
-//                  this can for example be used to store cached function ids for quicker
-//                  executions of class methods
-
 struct asSTypeBehaviour
 struct asSTypeBehaviour
 {
 {
 	asSTypeBehaviour() 
 	asSTypeBehaviour() 
@@ -148,28 +143,41 @@ public:
 	// Type info
 	// Type info
 	const char      *GetName() const;
 	const char      *GetName() const;
 	asIObjectType   *GetBaseType() const;
 	asIObjectType   *GetBaseType() const;
+	bool             DerivesFrom(const asIObjectType *objType) const;
 	asDWORD          GetFlags() const;
 	asDWORD          GetFlags() const;
 	asUINT           GetSize() const;
 	asUINT           GetSize() const;
 	int              GetTypeId() const;
 	int              GetTypeId() const;
 	int              GetSubTypeId() const;
 	int              GetSubTypeId() const;
+	asIObjectType   *GetSubType() const;
+	// TODO: access: Get/Set access mask for type
 
 
 	// Interfaces
 	// Interfaces
 	asUINT           GetInterfaceCount() const;
 	asUINT           GetInterfaceCount() const;
 	asIObjectType   *GetInterface(asUINT index) const;
 	asIObjectType   *GetInterface(asUINT index) const;
+	bool             Implements(const asIObjectType *objType) const;
 
 
 	// Factories
 	// Factories
 	asUINT             GetFactoryCount() const;
 	asUINT             GetFactoryCount() const;
 	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
+	asIScriptFunction *GetFactoryByIndex(asUINT index) const;
+	asIScriptFunction *GetFactoryByDecl(const char *decl) const;
 
 
 	// Methods
 	// Methods
 	asUINT             GetMethodCount() const;
 	asUINT             GetMethodCount() const;
 	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
 	int                GetMethodIdByDecl(const char *decl, bool getVirtual) const;
+	asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual) const;
+	asIScriptFunction *GetMethodByName(const char *name, bool getVirtual) const;
+	asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual) const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const;
 	asIScriptFunction *GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const;
+#endif
 
 
 	// Properties
 	// Properties
+	// TODO: access: Allow getting and setting property access mask
 	asUINT      GetPropertyCount() const;
 	asUINT      GetPropertyCount() const;
 	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference) 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;
@@ -178,6 +186,10 @@ public:
 	asUINT GetBehaviourCount() const;
 	asUINT GetBehaviourCount() const;
 	int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
 	int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
 
 
+	// User data
+	void *SetUserData(void *data);
+	void *GetUserData() const;
+
 //===========================================
 //===========================================
 // Internal
 // Internal
 //===========================================
 //===========================================
@@ -194,9 +206,8 @@ public:
 
 
 	void ReleaseAllFunctions();
 	void ReleaseAllFunctions();
 
 
-	bool Implements(const asCObjectType *objType) const;
-	bool DerivesFrom(const asCObjectType *objType) const;
 	bool IsInterface() const;
 	bool IsInterface() const;
+	bool IsShared() const;
 
 
 	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
 	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
 
 
@@ -210,6 +221,7 @@ public:
 	asCArray<asCScriptFunction*> virtualFunctionTable;
 	asCArray<asCScriptFunction*> virtualFunctionTable;
 
 
 	asDWORD flags;
 	asDWORD flags;
+	asDWORD accessMask;
 
 
 	asSTypeBehaviour beh;
 	asSTypeBehaviour beh;
 
 
@@ -219,6 +231,7 @@ public:
 	bool           acceptRefSubType;
 	bool           acceptRefSubType;
 
 
 	asCScriptEngine *engine;
 	asCScriptEngine *engine;
+	void            *userData;
 
 
 protected:
 protected:
 	mutable asCAtomic refCount;
 	mutable asCAtomic refCount;

+ 38 - 3
ThirdParty/AngelScript/source/as_parser.cpp

@@ -335,13 +335,14 @@ asCScriptNode *asCParser::ParseScript()
 	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snScript);
 	asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snScript);
 
 
 	// Determine type of node
 	// Determine type of node
-	sToken t1;
+	sToken t1, t2;
 
 
 	for(;;)
 	for(;;)
 	{
 	{
 		while( !isSyntaxError )
 		while( !isSyntaxError )
 		{
 		{
 			GetToken(&t1);
 			GetToken(&t1);
+			GetToken(&t2);
 			RewindTo(&t1);
 			RewindTo(&t1);
 
 
 			if( t1.type == ttImport )
 			if( t1.type == ttImport )
@@ -350,9 +351,9 @@ asCScriptNode *asCParser::ParseScript()
 				node->AddChildLast(ParseEnumeration());	//	Handle enumerations
 				node->AddChildLast(ParseEnumeration());	//	Handle enumerations
 			else if( t1.type == ttTypedef )
 			else if( t1.type == ttTypedef )
 				node->AddChildLast(ParseTypedef());		//	Handle primitive typedefs
 				node->AddChildLast(ParseTypedef());		//	Handle primitive typedefs
-			else if( t1.type == ttClass )
+			else if( t1.type == ttClass || (t1.type == ttIdentifier && t2.type == ttClass) )
 				node->AddChildLast(ParseClass());
 				node->AddChildLast(ParseClass());
-			else if( t1.type == ttInterface )
+			else if( t1.type == ttInterface || (t1.type == ttIdentifier && t2.type == ttInterface) )
 				node->AddChildLast(ParseInterface());
 				node->AddChildLast(ParseInterface());
 			else if( t1.type == ttFuncDef )
 			else if( t1.type == ttFuncDef )
 				node->AddChildLast(ParseFuncDef());
 				node->AddChildLast(ParseFuncDef());
@@ -918,6 +919,23 @@ asCScriptNode *asCParser::ParseInterface()
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
+
+	// Allow keyword 'shared' before 'interface'
+	if( t.type == ttIdentifier )
+	{
+		asCString str;
+		str.Assign(&script->code[t.pos], t.length);
+		if( str != SHARED_TOKEN )
+		{
+			Error(ExpectedToken(SHARED_TOKEN).AddressOf(), &t);
+			return node;
+		}
+
+		RewindTo(&t);
+		node->AddChildLast(ParseIdentifier());
+		GetToken(&t);
+	}
+
 	if( t.type != ttInterface )
 	if( t.type != ttInterface )
 	{
 	{
 		Error(ExpectedToken("interface").AddressOf(), &t);
 		Error(ExpectedToken("interface").AddressOf(), &t);
@@ -966,6 +984,23 @@ asCScriptNode *asCParser::ParseClass()
 
 
 	sToken t;
 	sToken t;
 	GetToken(&t);
 	GetToken(&t);
+
+	// Allow the keyword 'shared' before 'class'
+	if( t.type == ttIdentifier )
+	{
+		asCString str;
+		str.Assign(&script->code[t.pos], t.length);
+		if( str != SHARED_TOKEN )
+		{
+			Error(ExpectedToken(SHARED_TOKEN).AddressOf(), &t);
+			return node;
+		}
+
+		RewindTo(&t);
+		node->AddChildLast(ParseIdentifier());
+		GetToken(&t);
+	}
+
 	if( t.type != ttClass )
 	if( t.type != ttClass )
 	{
 	{
 		Error(ExpectedToken("class").AddressOf(), &t);
 		Error(ExpectedToken("class").AddressOf(), &t);

+ 5 - 1
ThirdParty/AngelScript/source/as_property.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 
@@ -50,10 +50,12 @@ BEGIN_AS_NAMESPACE
 class asCObjectProperty
 class asCObjectProperty
 {
 {
 public:
 public:
+	asCObjectProperty() {accessMask = 0xFFFFFFFF;}
 	asCString   name;
 	asCString   name;
 	asCDataType type;
 	asCDataType type;
 	int         byteOffset;
 	int         byteOffset;
 	bool		isPrivate;
 	bool		isPrivate;
+	asDWORD     accessMask;
 };
 };
 
 
 class asCGlobalProperty
 class asCGlobalProperty
@@ -98,6 +100,8 @@ public:
 
 
 	asCScriptFunction *initFunc;
 	asCScriptFunction *initFunc;
 
 
+	asDWORD accessMask;
+
 	// The global property structure is reference counted, so that the
 	// The global property structure is reference counted, so that the
 	// engine can keep track of how many references to the property there are.
 	// engine can keep track of how many references to the property there are.
 	asCAtomic refCount;
 	asCAtomic refCount;

+ 333 - 57
ThirdParty/AngelScript/source/as_restore.cpp

@@ -39,6 +39,7 @@
 #include "as_restore.h"
 #include "as_restore.h"
 #include "as_bytecode.h"
 #include "as_bytecode.h"
 #include "as_scriptobject.h"
 #include "as_scriptobject.h"
+#include "as_texts.h"
 
 
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
@@ -251,13 +252,39 @@ int asCRestore::Restore()
 	{
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		ReadObjectTypeDeclaration(ot, 1);
 		ReadObjectTypeDeclaration(ot, 1);
-		engine->classTypes.PushLast(ot);
+
+		// If the type is shared, then we should use the original if it exists
+		bool sharedExists = false;
+		if( ot->IsShared() )
+		{
+			for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
+			{
+				asCObjectType *t = engine->classTypes[n];
+				if( t &&
+					t->IsShared() &&
+					t->name == ot->name &&
+					t->IsInterface() == ot->IsInterface() )
+				{
+					asDELETE(ot, asCObjectType);
+					ot = t;
+					sharedExists = true;
+					break;
+				}
+			}
+		}
+
+		if( sharedExists )
+			existingShared.Insert(ot, true);
+		else
+		{
+			engine->classTypes.PushLast(ot);
+
+			// Add script classes to the GC
+			if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && !ot->IsInterface() )
+				engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
+		}
 		module->classTypes.PushLast(ot);
 		module->classTypes.PushLast(ot);
 		ot->AddRef();
 		ot->AddRef();
-
-		// Add script classes to the GC
-		if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && ot->GetSize() > 0 )
-			engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
 	}
 	}
 
 
 	// Read func defs
 	// Read func defs
@@ -327,6 +354,11 @@ int asCRestore::Restore()
 
 
 	// scriptGlobals[]
 	// scriptGlobals[]
 	count = ReadEncodedUInt();
 	count = ReadEncodedUInt();
+	if( engine->ep.disallowGlobalVars )
+	{
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
+		error = true;
+	}
 	module->scriptGlobals.Allocate(count, 0);
 	module->scriptGlobals.Allocate(count, 0);
 	for( i = 0; i < count; ++i ) 
 	for( i = 0; i < count; ++i ) 
 	{
 	{
@@ -428,11 +460,12 @@ int asCRestore::Restore()
 	// Init system functions properly
 	// Init system functions properly
 	engine->PrepareEngine();
 	engine->PrepareEngine();
 
 
-	// Add references for all functions
+	// Add references for all functions (except for the pre-existing shared code)
 	if( !error )
 	if( !error )
 	{
 	{
 		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
 		for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
-			module->scriptFunctions[i]->AddReferences();
+			if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
+				module->scriptFunctions[i]->AddReferences();
 		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
 		for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
 			if( module->scriptGlobals[i]->GetInitFunc() )
 			if( module->scriptGlobals[i]->GetInitFunc() )
 				module->scriptGlobals[i]->GetInitFunc()->AddReferences();
 				module->scriptGlobals[i]->GetInitFunc()->AddReferences();
@@ -723,7 +756,7 @@ void asCRestore::WriteFunction(asCScriptFunction* func)
 	}
 	}
 }
 }
 
 
-asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine) 
+asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine, bool addToGC) 
 {
 {
 	char c;
 	char c;
 	READ_NUM(c);
 	READ_NUM(c);
@@ -762,7 +795,8 @@ asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine)
 
 
 	if( func->funcType == asFUNC_SCRIPT )
 	if( func->funcType == asFUNC_SCRIPT )
 	{
 	{
-		engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
+		if( addToGC )
+			engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
 		
 		
 		count = ReadEncodedUInt();
 		count = ReadEncodedUInt();
 		func->byteCode.Allocate(count, 0);
 		func->byteCode.Allocate(count, 0);
@@ -959,76 +993,281 @@ void asCRestore::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 		}
 		}
 		else
 		else
 		{
 		{
-			ot->derivedFrom = ReadObjectType();
-			if( ot->derivedFrom )
-				ot->derivedFrom->AddRef();
+			// If the type is shared and pre-existing, we should just 
+			// validate that the loaded methods match the original 
+			bool sharedExists = existingShared.MoveTo(0, ot);
+			if( sharedExists )
+			{
+				asCObjectType *dt = ReadObjectType();
+				if( ot->derivedFrom != dt )
+				{
+					// TODO: Write message
+					error = true;
+				}
+			}
+			else
+			{
+				ot->derivedFrom = ReadObjectType();
+				if( ot->derivedFrom )
+					ot->derivedFrom->AddRef();
+			}
 
 
 			// interfaces[]
 			// interfaces[]
 			int size = ReadEncodedUInt();
 			int size = ReadEncodedUInt();
-			ot->interfaces.Allocate(size,0);
-			int n;
-			for( n = 0; n < size; n++ )
+			if( sharedExists )
 			{
 			{
-				asCObjectType *intf = ReadObjectType();
-				ot->interfaces.PushLast(intf);
+				for( int n = 0; n < size; n++ )
+				{
+					asCObjectType *intf = ReadObjectType();
+					if( !ot->Implements(intf) )
+					{
+						// TODO: Write message
+						error = true;
+					}
+				}
+			}
+			else
+			{
+				ot->interfaces.Allocate(size,0);
+				for( int n = 0; n < size; n++ )
+				{
+					asCObjectType *intf = ReadObjectType();
+					ot->interfaces.PushLast(intf);
+				}
 			}
 			}
 
 
 			// behaviours
 			// behaviours
 			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
 			if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
 			{
 			{
-				asCScriptFunction *func = ReadFunction();
+				// For existing types we don't want to make any updates
+				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
-					engine->scriptFunctions[ot->beh.construct]->Release();
-					ot->beh.construct = func->id;
-					ot->beh.constructors[0] = func->id;
-					func->AddRef();
+					if( sharedExists )
+					{
+						// Find the real function in the object, and update the savedFunctions array
+						asCScriptFunction *realFunc = engine->GetScriptFunction(ot->beh.construct);
+						if( realFunc->IsSignatureEqual(func) )
+						{
+							// If the function is not the last, then the substitution has already occurred before
+							if( savedFunctions[savedFunctions.GetLength()-1] == func )
+								savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+						}
+						else
+						{
+							// TODO: Write message
+							error = true;
+						}
+						// Destroy the function without releasing any references
+						func->id = 0;
+						func->byteCode.SetLength(0);
+						func->Release();
+						module->scriptFunctions.PushLast(realFunc);
+						realFunc->AddRef();
+						dontTranslate.Insert(realFunc, true);
+					}
+					else 
+					{
+						engine->scriptFunctions[ot->beh.construct]->Release();
+						ot->beh.construct = func->id;
+						ot->beh.constructors[0] = func->id;
+						func->AddRef();
+					}
 				}
 				}
 
 
-				func = ReadFunction();
+				func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
-					ot->beh.destruct = func->id;
-					func->AddRef();
+					if( sharedExists )
+					{
+						// Find the real function in the object, and update the savedFunctions array
+						asCScriptFunction *realFunc = engine->GetScriptFunction(ot->beh.destruct);
+						if( realFunc->IsSignatureEqual(func) )
+						{
+							// If the function is not the last, then the substitution has already occurred before
+							if( savedFunctions[savedFunctions.GetLength()-1] == func )
+								savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+						}
+						else
+						{
+							// TODO: Write message
+							error = true;
+						}
+						// Destroy the function without releasing any references
+						func->id = 0;
+						func->byteCode.SetLength(0);
+						func->Release();
+						module->scriptFunctions.PushLast(realFunc);
+						realFunc->AddRef();
+						dontTranslate.Insert(realFunc, true);
+					}
+					else
+					{
+						ot->beh.destruct = func->id;
+						func->AddRef();
+					}
 				}
 				}
 
 
-				func = ReadFunction();
+				func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
-					engine->scriptFunctions[ot->beh.factory]->Release();
-					ot->beh.factory = func->id;
-					ot->beh.factories[0] = func->id;
-					func->AddRef();
+					if( sharedExists )
+					{
+						// Find the real function in the object, and update the savedFunctions array
+						asCScriptFunction *realFunc = engine->GetScriptFunction(ot->beh.factory);
+						if( realFunc->IsSignatureEqual(func) )
+						{
+							// If the function is not the last, then the substitution has already occurred before
+							if( savedFunctions[savedFunctions.GetLength()-1] == func )
+								savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+						}
+						else
+						{
+							// TODO: Write message
+							error = true;
+						}
+						// Destroy the function without releasing any references
+						func->id = 0;
+						func->byteCode.SetLength(0);
+						func->Release();
+						module->scriptFunctions.PushLast(realFunc);
+						realFunc->AddRef();
+						dontTranslate.Insert(realFunc, true);
+					}
+					else
+					{
+						engine->scriptFunctions[ot->beh.factory]->Release();
+						ot->beh.factory = func->id;
+						ot->beh.factories[0] = func->id;
+						func->AddRef();
+					}
 				}
 				}
 
 
 				size = ReadEncodedUInt();
 				size = ReadEncodedUInt();
-				for( n = 0; n < size; n++ )
+				for( int n = 0; n < size; n++ )
 				{
 				{
-					asCScriptFunction *func = ReadFunction();
+					asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 					if( func )
 					if( func )
 					{
 					{
-						ot->beh.constructors.PushLast(func->id);
-						func->AddRef();
+						if( sharedExists )
+						{
+							// Find the real function in the object, and update the savedFunctions array
+							bool found = false;
+							for( asUINT n = 0; n < ot->beh.constructors.GetLength(); n++ )
+							{
+								asCScriptFunction *realFunc = engine->GetScriptFunction(ot->beh.constructors[n]);
+								if( realFunc->IsSignatureEqual(func) )
+								{
+									// If the function is not the last, then the substitution has already occurred before
+									if( savedFunctions[savedFunctions.GetLength()-1] == func )
+										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+									found = true;
+									module->scriptFunctions.PushLast(realFunc);
+									realFunc->AddRef();
+									dontTranslate.Insert(realFunc, true);
+									break;
+								}
+							}
+							if( !found )
+							{
+								// TODO: Write message
+								error = true;
+							}
+							// Destroy the function without releasing any references
+							func->id = 0;
+							func->byteCode.SetLength(0);
+							func->Release();
+						}
+						else
+						{
+							ot->beh.constructors.PushLast(func->id);
+							func->AddRef();
+						}
 					}
 					}
 
 
-					func = ReadFunction();
+					func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 					if( func )
 					if( func )
 					{
 					{
-						ot->beh.factories.PushLast(func->id);
-						func->AddRef();
+						if( sharedExists )
+						{
+							// Find the real function in the object, and update the savedFunctions array
+							bool found = false;
+							for( asUINT n = 0; n < ot->beh.factories.GetLength(); n++ )
+							{
+								asCScriptFunction *realFunc = engine->GetScriptFunction(ot->beh.factories[n]);
+								if( realFunc->IsSignatureEqual(func) )
+								{
+									// If the function is not the last, then the substitution has already occurred before
+									if( savedFunctions[savedFunctions.GetLength()-1] == func )
+										savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+									found = true;
+									module->scriptFunctions.PushLast(realFunc);
+									realFunc->AddRef();
+									dontTranslate.Insert(realFunc, true);
+									break;
+								}
+							}
+							if( !found )
+							{
+								// TODO: Write message
+								error = true;
+							}
+							// Destroy the function without releasing any references
+							func->id = 0;
+							func->byteCode.SetLength(0);
+							func->Release();
+						}
+						else
+						{
+							ot->beh.factories.PushLast(func->id);
+							func->AddRef();
+						}
 					}
 					}
 				}
 				}
 			}
 			}
 
 
 			// methods[]
 			// methods[]
 			size = ReadEncodedUInt();
 			size = ReadEncodedUInt();
+			int n;
 			for( n = 0; n < size; n++ ) 
 			for( n = 0; n < size; n++ ) 
 			{
 			{
-				asCScriptFunction *func = ReadFunction();
+				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
-					ot->methods.PushLast(func->id);
-					func->AddRef();
+					if( sharedExists )
+					{
+						// Find the real function in the object, and update the savedFunctions array
+						bool found = false;
+						for( asUINT n = 0; n < ot->methods.GetLength(); n++ )
+						{
+							asCScriptFunction *realFunc = engine->GetScriptFunction(ot->methods[n]);
+							if( realFunc->IsSignatureEqual(func) )
+							{
+								// If the function is not the last, then the substitution has already occurred before
+								if( savedFunctions[savedFunctions.GetLength()-1] == func )
+									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+								found = true;
+								module->scriptFunctions.PushLast(realFunc);
+								realFunc->AddRef();
+								dontTranslate.Insert(realFunc, true);
+								break;
+							}
+						}
+						if( !found )
+						{
+							// TODO: Write message
+							error = true;
+						}
+						// Destroy the function without releasing any references
+						func->id = 0;
+						func->byteCode.SetLength(0);
+						func->Release();
+					}
+					else
+					{
+						ot->methods.PushLast(func->id);
+						func->AddRef();
+					}
 				}
 				}
 			}
 			}
 
 
@@ -1036,11 +1275,43 @@ void asCRestore::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 			size = ReadEncodedUInt();
 			size = ReadEncodedUInt();
 			for( n = 0; n < size; n++ )
 			for( n = 0; n < size; n++ )
 			{
 			{
-				asCScriptFunction *func = ReadFunction();
+				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				if( func )
 				if( func )
 				{
 				{
-					ot->virtualFunctionTable.PushLast(func);
-					func->AddRef();
+					if( sharedExists )
+					{
+						// Find the real function in the object, and update the savedFunctions array
+						bool found = false;
+						for( asUINT n = 0; n < ot->virtualFunctionTable.GetLength(); n++ )
+						{
+							asCScriptFunction *realFunc = ot->virtualFunctionTable[n];
+							if( realFunc->IsSignatureEqual(func) )
+							{
+								// If the function is not the last, then the substitution has already occurred before
+								if( savedFunctions[savedFunctions.GetLength()-1] == func )
+									savedFunctions[savedFunctions.GetLength()-1] = realFunc;
+								found = true;
+								module->scriptFunctions.PushLast(realFunc);
+								realFunc->AddRef();
+								dontTranslate.Insert(realFunc, true);
+								break;
+							}
+						}
+						if( !found )
+						{
+							// TODO: Write message
+							error = true;
+						}
+						// Destroy the function without releasing any references
+						func->id = 0;
+						func->byteCode.SetLength(0);
+						func->Release();
+					}
+					else
+					{
+						ot->virtualFunctionTable.PushLast(func);
+						func->AddRef();
+					}
 				}
 				}
 			}
 			}
 		}
 		}
@@ -1272,7 +1543,10 @@ void asCRestore::ReadObjectProperty(asCObjectType *ot)
 	bool isPrivate;
 	bool isPrivate;
 	READ_NUM(isPrivate);
 	READ_NUM(isPrivate);
 
 
-	ot->AddPropertyToClass(name, dt, isPrivate);
+	// TODO: shared: If the type is shared and pre-existing, we should just 
+	//               validate that the loaded methods match the original 
+	if( !existingShared.MoveTo(0, ot) )
+		ot->AddPropertyToClass(name, dt, isPrivate);
 }
 }
 
 
 void asCRestore::WriteDataType(const asCDataType *dt) 
 void asCRestore::WriteDataType(const asCDataType *dt) 
@@ -1350,7 +1624,7 @@ void asCRestore::ReadDataType(asCDataType *dt)
 		ReadFunctionSignature(&func);
 		ReadFunctionSignature(&func);
 		for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 		for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
 		{
 		{
-			// TODO: Only return the definitions for the config groups that the module has access to
+			// TODO: access: Only return the definitions that the module has access to
 			if( engine->registeredFuncDefs[n]->name == func.name )
 			if( engine->registeredFuncDefs[n]->name == func.name )
 			{
 			{
 				funcDef = engine->registeredFuncDefs[n];
 				funcDef = engine->registeredFuncDefs[n];
@@ -1457,9 +1731,8 @@ asCObjectType* asCRestore::ReadObjectType()
 		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf());
 		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf());
 		if( tmpl == 0 )
 		if( tmpl == 0 )
 		{
 		{
-			// TODO: Move text to as_texts.h
 			asCString str;
 			asCString str;
-			str.Format("Template type '%s' doesn't exist", typeName.AddressOf());
+			str.Format(TXT_TEMPLATE_TYPE_s_DOESNT_EXIST, typeName.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 			error = true;
 			error = true;
 			return 0;
 			return 0;
@@ -1471,9 +1744,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			ot = ReadObjectType();
 			ot = ReadObjectType();
 			if( ot == 0 )
 			if( ot == 0 )
 			{
 			{
-				// TODO: Move text to as_texts.h
 				asCString str;
 				asCString str;
-				str.Format("Failed to read subtype of template type '%s'", typeName.AddressOf());
+				str.Format(TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s, typeName.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				error = true;
 				error = true;
 				return 0;
 				return 0;
@@ -1492,9 +1764,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			
 			if( ot == 0 )
 			if( ot == 0 )
 			{
 			{
-				// TODO: Move text to as_texts.h
 				asCString str;
 				asCString str;
-				str.Format("Attempting to instanciate invalid template type '%s<%s>'", typeName.AddressOf(), dt.Format().AddressOf());
+				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				error = true;
 				error = true;
 				return 0;
 				return 0;
@@ -1510,9 +1781,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			
 			if( ot == 0 )
 			if( ot == 0 )
 			{
 			{
-				// TODO: Move text to as_texts.h
 				asCString str;
 				asCString str;
-				str.Format("Attempting to instanciate invalid template type '%s<%s>'", typeName.AddressOf(), dt.Format().AddressOf());
+				str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				error = true;
 				error = true;
 				return 0;
 				return 0;
@@ -1538,9 +1808,8 @@ asCObjectType* asCRestore::ReadObjectType()
 
 
 		if( ot == 0 )
 		if( ot == 0 )
 		{
 		{
-			// TODO: Move text to as_texts.h
 			asCString str;
 			asCString str;
-			str.Format("Template subtype type '%s' doesn't exist", typeName.AddressOf());
+			str.Format(TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST, typeName.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 			engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 			error = true;
 			error = true;
 			return 0;
 			return 0;
@@ -1561,9 +1830,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			
 			if( ot == 0 )
 			if( ot == 0 )
 			{
 			{
-				// TODO: Move text to as_texts.h
 				asCString str;
 				asCString str;
-				str.Format("Object type '%s' doesn't exist", typeName.AddressOf());
+				str.Format(TXT_OBJECT_TYPE_s_DOESNT_EXIST, typeName.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
 				error = true;
 				error = true;
 				return 0;
 				return 0;
@@ -1617,6 +1885,11 @@ void asCRestore::WriteByteCode(asDWORD *bc, int length)
 			// Translate object type pointers into indices
 			// Translate object type pointers into indices
 			*(int*)(tmp+1) = FindObjectTypeIdx(*(asCObjectType**)(tmp+1));
 			*(int*)(tmp+1) = FindObjectTypeIdx(*(asCObjectType**)(tmp+1));
 		}
 		}
+		else if( c == asBC_JitEntry ) // PTR_ARG
+		{
+			// We don't store the JIT argument
+			*(asPWORD*)(tmp+1) = 0;
+		}
 		else if( c == asBC_TYPEID || // DW_ARG
 		else if( c == asBC_TYPEID || // DW_ARG
 			     c == asBC_Cast )   // DW_ARG
 			     c == asBC_Cast )   // DW_ARG
 		{
 		{
@@ -2335,6 +2608,9 @@ asCScriptFunction *asCRestore::FindFunction(int idx)
 
 
 void asCRestore::TranslateFunction(asCScriptFunction *func)
 void asCRestore::TranslateFunction(asCScriptFunction *func)
 {
 {
+	// Skip this if the function is part of an pre-existing shared object
+	if( dontTranslate.MoveTo(0, func) ) return;
+
 	asUINT n;
 	asUINT n;
 	asDWORD *bc = func->byteCode.AddressOf();
 	asDWORD *bc = func->byteCode.AddressOf();
 	for( n = 0; n < func->byteCode.GetLength(); )
 	for( n = 0; n < func->byteCode.GetLength(); )

+ 5 - 2
ThirdParty/AngelScript/source/as_restore.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 
@@ -77,7 +77,7 @@ protected:
 	void WriteEncodedUInt(asUINT i);
 	void WriteEncodedUInt(asUINT i);
 
 
 	void ReadString(asCString *str);
 	void ReadString(asCString *str);
-	asCScriptFunction *ReadFunction(bool addToModule = true, bool addToEngine = true);
+	asCScriptFunction *ReadFunction(bool addToModule = true, bool addToEngine = true, bool addToGC = true);
 	void ReadFunctionSignature(asCScriptFunction *func);
 	void ReadFunctionSignature(asCScriptFunction *func);
 	void ReadGlobalProperty();
 	void ReadGlobalProperty();
 	void ReadObjectProperty(asCObjectType *ot);
 	void ReadObjectProperty(asCObjectType *ot);
@@ -139,6 +139,9 @@ protected:
 		asUINT         oldSize;
 		asUINT         oldSize;
 	};
 	};
 	asCArray<SObjChangeSize>     oldObjectSizes;
 	asCArray<SObjChangeSize>     oldObjectSizes;
+
+	asCMap<void*,bool>              existingShared;
+	asCMap<asCScriptFunction*,bool> dontTranslate;
 };
 };
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE

+ 260 - 63
ThirdParty/AngelScript/source/as_scriptengine.cpp

@@ -292,6 +292,10 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
 		ep.autoGarbageCollect = value ? true : false;
 		ep.autoGarbageCollect = value ? true : false;
 		break;
 		break;
 
 
+	case asEP_DISALLOW_GLOBAL_VARS:
+		ep.disallowGlobalVars = value ? true : false;
+		break;
+
 	default:
 	default:
 		return asINVALID_ARG;
 		return asINVALID_ARG;
 	}
 	}
@@ -350,6 +354,9 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 
 
 	case asEP_AUTO_GARBAGE_COLLECT:
 	case asEP_AUTO_GARBAGE_COLLECT:
 		return ep.autoGarbageCollect;
 		return ep.autoGarbageCollect;
+
+	case asEP_DISALLOW_GLOBAL_VARS:
+		return ep.disallowGlobalVars;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -393,6 +400,7 @@ asCScriptEngine::asCScriptEngine()
 		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;
 		ep.autoGarbageCollect           = true;
+		ep.disallowGlobalVars           = false;
 	}
 	}
 
 
 	gc.engine = this;
 	gc.engine = this;
@@ -405,17 +413,20 @@ asCScriptEngine::asCScriptEngine()
 	lastModule = 0;
 	lastModule = 0;
 
 
 	// User data
 	// User data
-	userData          = 0;
-	cleanEngineFunc   = 0;
-	cleanContextFunc  = 0;
-	cleanFunctionFunc = 0;
+	userData            = 0;
+	cleanEngineFunc     = 0;
+	cleanModuleFunc     = 0;
+	cleanContextFunc    = 0;
+	cleanFunctionFunc   = 0;
+	cleanObjectTypeFunc = 0;
 
 
 
 
 	initialContextStackSize = 1024;      // 4 KB (1024 * sizeof(asDWORD)
 	initialContextStackSize = 1024;      // 4 KB (1024 * sizeof(asDWORD)
 
 
 
 
-	typeIdSeqNbr = 0;
-	currentGroup = &defaultGroup;
+	typeIdSeqNbr      = 0;
+	currentGroup      = &defaultGroup;
+	defaultAccessMask = 1;
 
 
 	msgCallback = 0;
 	msgCallback = 0;
     jitCompiler = 0;
     jitCompiler = 0;
@@ -531,6 +542,11 @@ asCScriptEngine::~asCScriptEngine()
 	GarbageCollect(asGC_FULL_CYCLE);
 	GarbageCollect(asGC_FULL_CYCLE);
 	ClearUnusedTypes();
 	ClearUnusedTypes();
 
 
+	// If the application hasn't registered GC behaviours for all types 
+	// that can form circular references with script types, then there
+	// may still be objects in the GC.
+	gc.ReportUndestroyedObjects();
+
 	asSMapNode<int,asCDataType*> *cursor = 0;
 	asSMapNode<int,asCDataType*> *cursor = 0;
 	while( mapTypeIdToDataType.MoveFirst(&cursor) )
 	while( mapTypeIdToDataType.MoveFirst(&cursor) )
 	{
 	{
@@ -782,6 +798,9 @@ int asCScriptEngine::DiscardModule(const char *module)
 	FreeUnusedGlobalProperties();
 	FreeUnusedGlobalProperties();
 	ClearUnusedTypes();
 	ClearUnusedTypes();
 
 
+	if( ep.autoGarbageCollect )
+		GarbageCollect();
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -993,10 +1012,10 @@ int asCScriptEngine::GetMethodIdByDecl(const asCObjectType *ot, const char *decl
 
 
 
 
 // Internal
 // Internal
-asCString asCScriptEngine::GetFunctionDeclaration(int funcID)
+asCString asCScriptEngine::GetFunctionDeclaration(int funcId)
 {
 {
 	asCString str;
 	asCString str;
-	asCScriptFunction *func = GetScriptFunction(funcID);
+	asCScriptFunction *func = GetScriptFunction(funcId);
 	if( func )
 	if( func )
 		str = func->GetDeclarationStr();
 		str = func->GetDeclarationStr();
 
 
@@ -1060,6 +1079,7 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 	prop->type       = type;
 	prop->type       = type;
 	prop->byteOffset = byteOffset;
 	prop->byteOffset = byteOffset;
 	prop->isPrivate  = false;
 	prop->isPrivate  = false;
+	prop->accessMask = defaultAccessMask;
 
 
 	dt.GetObjectType()->properties.PushLast(prop);
 	dt.GetObjectType()->properties.PushLast(prop);
 
 
@@ -1104,7 +1124,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
 
 
 	// Register the object type for the interface
 	// Register the object type for the interface
 	asCObjectType *st = asNEW(asCObjectType)(this);
 	asCObjectType *st = asNEW(asCObjectType)(this);
-	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
+	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT | asOBJ_SHARED;
 	st->size = 0; // Cannot be instanciated
 	st->size = 0; // Cannot be instanciated
 	st->name = name;
 	st->name = name;
 
 
@@ -1225,26 +1245,35 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		else if( flags & asOBJ_APP_PRIMITIVE )
 		else if( flags & asOBJ_APP_PRIMITIVE )
 		{
 		{
 			// Must not set the class flags nor the float flag
 			// Must not set the class flags nor the float flag
-			if( flags & (asOBJ_APP_CLASS             |
-				         asOBJ_APP_CLASS_CONSTRUCTOR |
-						 asOBJ_APP_CLASS_DESTRUCTOR  |
-						 asOBJ_APP_CLASS_ASSIGNMENT  |
-						 asOBJ_APP_FLOAT) )
+			if( flags & (asOBJ_APP_CLASS                  |
+				         asOBJ_APP_CLASS_CONSTRUCTOR      |
+						 asOBJ_APP_CLASS_DESTRUCTOR       |
+						 asOBJ_APP_CLASS_ASSIGNMENT       |
+						 asOBJ_APP_CLASS_COPY_CONSTRUCTOR |
+						 asOBJ_APP_FLOAT                  |
+						 asOBJ_APP_CLASS_ALLINTS          |
+						 asOBJ_APP_CLASS_ALLFLOATS) )
 				return ConfigError(asINVALID_ARG);
 				return ConfigError(asINVALID_ARG);
 		}
 		}
 		else if( flags & asOBJ_APP_FLOAT )
 		else if( flags & asOBJ_APP_FLOAT )
 		{
 		{
 			// Must not set the class flags nor the primitive flag
 			// Must not set the class flags nor the primitive flag
-			if( flags & (asOBJ_APP_CLASS             |
-				         asOBJ_APP_CLASS_CONSTRUCTOR |
-						 asOBJ_APP_CLASS_DESTRUCTOR  |
-						 asOBJ_APP_CLASS_ASSIGNMENT  |
-						 asOBJ_APP_PRIMITIVE) )
+			if( flags & (asOBJ_APP_CLASS                  |
+				         asOBJ_APP_CLASS_CONSTRUCTOR      |
+						 asOBJ_APP_CLASS_DESTRUCTOR       |
+						 asOBJ_APP_CLASS_ASSIGNMENT       |
+						 asOBJ_APP_CLASS_COPY_CONSTRUCTOR |
+						 asOBJ_APP_PRIMITIVE              |
+						 asOBJ_APP_CLASS_ALLINTS          |
+						 asOBJ_APP_CLASS_ALLFLOATS) )
 				return ConfigError(asINVALID_ARG);
 				return ConfigError(asINVALID_ARG);
 		}
 		}
-		else if( flags & (asOBJ_APP_CLASS_CONSTRUCTOR |
-		                  asOBJ_APP_CLASS_DESTRUCTOR  |
-		                  asOBJ_APP_CLASS_ASSIGNMENT) )
+		else if( flags & (asOBJ_APP_CLASS_CONSTRUCTOR      |
+		                  asOBJ_APP_CLASS_DESTRUCTOR       |
+		                  asOBJ_APP_CLASS_ASSIGNMENT       |
+						  asOBJ_APP_CLASS_COPY_CONSTRUCTOR |
+						  asOBJ_APP_CLASS_ALLINTS          |
+						  asOBJ_APP_CLASS_ALLFLOATS) )
 		{
 		{
 			// Must not set the class properties, without the class flag
 			// Must not set the class properties, without the class flag
 			return ConfigError(asINVALID_ARG);
 			return ConfigError(asINVALID_ARG);
@@ -1286,9 +1315,10 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		}
 		}
 
 
 		asCObjectType *type = asNEW(asCObjectType)(this);
 		asCObjectType *type = asNEW(asCObjectType)(this);
-		type->name      = typeName;
-		type->size      = byteSize;
-		type->flags     = flags;
+		type->name       = typeName;
+		type->size       = byteSize;
+		type->flags      = flags;
+		type->accessMask = defaultAccessMask;
 
 
 		// Store it in the object types
 		// Store it in the object types
 		objectTypes.PushLast(type);
 		objectTypes.PushLast(type);
@@ -1369,9 +1399,10 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 
 			// Put the data type in the list
 			// Put the data type in the list
 			asCObjectType *type = asNEW(asCObjectType)(this);
 			asCObjectType *type = asNEW(asCObjectType)(this);
-			type->name      = typeName;
-			type->size      = byteSize;
-			type->flags     = flags;
+			type->name       = typeName;
+			type->size       = byteSize;
+			type->flags      = flags;
+			type->accessMask = defaultAccessMask;
 
 
 			objectTypes.PushLast(type);
 			objectTypes.PushLast(type);
 			registeredObjTypes.PushLast(type);
 			registeredObjTypes.PushLast(type);
@@ -1406,11 +1437,12 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 
 			// Put the data type in the list
 			// Put the data type in the list
 			asCObjectType *type = asNEW(asCObjectType)(this);
 			asCObjectType *type = asNEW(asCObjectType)(this);
-			type->name      = dt.GetObjectType()->name;
+			type->name       = dt.GetObjectType()->name;
 			type->templateSubType = dt.GetSubType();
 			type->templateSubType = dt.GetSubType();
 			if( type->templateSubType.GetObjectType() ) type->templateSubType.GetObjectType()->AddRef();
 			if( type->templateSubType.GetObjectType() ) type->templateSubType.GetObjectType()->AddRef();
-			type->size      = byteSize;
-			type->flags     = flags;
+			type->size       = byteSize;
+			type->flags      = flags;
+			type->accessMask = defaultAccessMask;
 
 
 			templateTypes.PushLast(type);
 			templateTypes.PushLast(type);
 
 
@@ -1853,17 +1885,20 @@ int asCScriptEngine::AddBehaviourFunction(asCScriptFunction &func, asSSystemFunc
 
 
 	asCScriptFunction *f = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asCScriptFunction *f = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	asASSERT(func.name != "" && func.name != "f");
 	asASSERT(func.name != "" && func.name != "f");
-	f->name        = func.name;
-	f->sysFuncIntf = newInterface;
-	f->returnType  = func.returnType;
-	f->objectType  = func.objectType;
-	f->id          = id;
-	f->isReadOnly  = func.isReadOnly;
-	for( n = 0; n < func.parameterTypes.GetLength(); n++ )
-	{
-		f->parameterTypes.PushLast(func.parameterTypes[n]);
-		f->inOutFlags.PushLast(func.inOutFlags[n]);
-	}
+	f->name           = func.name;
+	f->sysFuncIntf    = newInterface;
+	f->returnType     = func.returnType;
+	f->objectType     = func.objectType;
+	f->id             = id;
+	f->isReadOnly     = func.isReadOnly;
+	f->accessMask     = defaultAccessMask;
+	f->parameterTypes = func.parameterTypes;
+	f->inOutFlags     = func.inOutFlags;
+	for( n = 0; n < func.defaultArgs.GetLength(); n++ )
+		if( func.defaultArgs[n] )
+			f->defaultArgs.PushLast(asNEW(asCString)(*func.defaultArgs[n]));
+		else
+			f->defaultArgs.PushLast(0);
 
 
 	SetScriptFunction(f);
 	SetScriptFunction(f);
 
 
@@ -1904,6 +1939,7 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
 	asCGlobalProperty *prop = AllocateGlobalProperty();
 	asCGlobalProperty *prop = AllocateGlobalProperty();
 	prop->name        = name;
 	prop->name        = name;
 	prop->type        = type;
 	prop->type        = type;
+	prop->accessMask  = defaultAccessMask;
 
 
 	prop->SetRegisteredAddress(pointer);
 	prop->SetRegisteredAddress(pointer);
 	
 	
@@ -1953,9 +1989,9 @@ void asCScriptEngine::FreeUnusedGlobalProperties()
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetGlobalPropertyCount() const
+asUINT asCScriptEngine::GetGlobalPropertyCount() const
 {
 {
-	return (int)registeredGlobalProps.GetLength();
+	return registeredGlobalProps.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -2057,6 +2093,7 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 
 
 	func->id = GetNextScriptFunctionId();
 	func->id = GetNextScriptFunctionId();
 	func->objectType->methods.PushLast(func->id);
 	func->objectType->methods.PushLast(func->id);
+	func->accessMask = defaultAccessMask;
 	SetScriptFunction(func);
 	SetScriptFunction(func);
 
 
 	// TODO: This code is repeated in many places
 	// TODO: This code is repeated in many places
@@ -2160,6 +2197,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 	SetScriptFunction(func);
 	SetScriptFunction(func);
 
 
 	currentGroup->scriptFunctions.PushLast(func);
 	currentGroup->scriptFunctions.PushLast(func);
+	func->accessMask = defaultAccessMask;
 	registeredGlobalFuncs.PushLast(func);
 	registeredGlobalFuncs.PushLast(func);
 
 
 	// If parameter type from other groups are used, add references
 	// If parameter type from other groups are used, add references
@@ -2182,9 +2220,9 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetGlobalFunctionCount() const
+asUINT asCScriptEngine::GetGlobalFunctionCount() const
 {
 {
-	return (int)registeredGlobalFuncs.GetLength();
+	return registeredGlobalFuncs.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -2196,8 +2234,59 @@ int asCScriptEngine::GetGlobalFunctionIdByIndex(asUINT index) const
 	return registeredGlobalFuncs[index]->id;
 	return registeredGlobalFuncs[index]->id;
 }
 }
 
 
+// interface
+asIScriptFunction *asCScriptEngine::GetGlobalFunctionByIndex(asUINT index) const
+{
+	if( index >= registeredGlobalFuncs.GetLength() )
+		return 0;
+
+	return registeredGlobalFuncs[index];
+}
+
+// interface
+asIScriptFunction *asCScriptEngine::GetGlobalFunctionByDecl(const char *decl) const
+{
+	asCBuilder bld(const_cast<asCScriptEngine*>(this), 0);
+
+	asCScriptFunction func(const_cast<asCScriptEngine*>(this), 0, asFUNC_DUMMY);
+	int r = bld.ParseFunctionDeclaration(0, decl, &func, false);
+	if( r < 0 )
+		return 0;
+
+	// TODO: optimize: Improve linear search
+	// Search registered functions for matching interface
+	int id = -1;
+	for( size_t n = 0; n < registeredGlobalFuncs.GetLength(); ++n )
+	{
+		if( registeredGlobalFuncs[n]->objectType == 0 && 
+			func.name == registeredGlobalFuncs[n]->name && 
+			func.returnType == registeredGlobalFuncs[n]->returnType &&
+			func.parameterTypes.GetLength() == registeredGlobalFuncs[n]->parameterTypes.GetLength() )
+		{
+			bool match = true;
+			for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
+			{
+				if( func.parameterTypes[p] != registeredGlobalFuncs[n]->parameterTypes[p] )
+				{
+					match = false;
+					break;
+				}
+			}
+
+			if( match )
+			{
+				if( id == -1 )
+					id = registeredGlobalFuncs[n]->id;
+				else
+					return 0; // Multiple matches
+			}
+		}
+	}
 
 
+	if( id < 0 ) return 0; // No matches
 
 
+	return registeredGlobalFuncs[id];
+}
 
 
 
 
 asCObjectType *asCScriptEngine::GetObjectType(const char *type)
 asCObjectType *asCScriptEngine::GetObjectType(const char *type)
@@ -2820,6 +2909,7 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
 void asCScriptEngine::CallObjectMethod(void *obj, int func)
 void asCScriptEngine::CallObjectMethod(void *obj, int func)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	CallObjectMethod(obj, s->sysFuncIntf, s);
 	CallObjectMethod(obj, s->sysFuncIntf, s);
 }
 }
 
 
@@ -2889,6 +2979,7 @@ void asCScriptEngine::CallObjectMethod(void *obj, asSSystemFunctionInterface *i,
 bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
@@ -2956,6 +3047,7 @@ bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
@@ -3023,12 +3115,14 @@ int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func)
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	return CallGlobalFunctionRetPtr(s->sysFuncIntf, s);
 	return CallGlobalFunctionRetPtr(s->sysFuncIntf, s);
 }
 }
 
 
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func, void *param1)
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func, void *param1)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	return CallGlobalFunctionRetPtr(s->sysFuncIntf, s, param1);
 	return CallGlobalFunctionRetPtr(s->sysFuncIntf, s, param1);
 }
 }
 
 
@@ -3077,6 +3171,7 @@ void *asCScriptEngine::CallGlobalFunctionRetPtr(asSSystemFunctionInterface *i, a
 void asCScriptEngine::CallObjectMethod(void *obj, void *param, int func)
 void asCScriptEngine::CallObjectMethod(void *obj, void *param, int func)
 {
 {
 	asCScriptFunction *s = scriptFunctions[func];
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	CallObjectMethod(obj, param, s->sysFuncIntf, s);
 	CallObjectMethod(obj, param, s->sysFuncIntf, s);
 }
 }
 
 
@@ -3346,8 +3441,7 @@ int asCScriptEngine::GetTypeIdByDecl(const char *decl) const
 	return GetTypeIdFromDataType(dt);
 	return GetTypeIdFromDataType(dt);
 }
 }
 
 
-
-
+// interface
 const char *asCScriptEngine::GetTypeDeclaration(int typeId) const
 const char *asCScriptEngine::GetTypeDeclaration(int typeId) const
 {
 {
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
@@ -3360,6 +3454,7 @@ const char *asCScriptEngine::GetTypeDeclaration(int typeId) const
 	return tempString->AddressOf();
 	return tempString->AddressOf();
 }
 }
 
 
+// TODO: interface: Deprecate. This function is not necessary now that all primitive types have fixed typeIds
 int asCScriptEngine::GetSizeOfPrimitiveType(int typeId) const
 int asCScriptEngine::GetSizeOfPrimitiveType(int typeId) const
 {
 {
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
@@ -3369,7 +3464,7 @@ int asCScriptEngine::GetSizeOfPrimitiveType(int typeId) const
 	return dt->GetSizeInMemoryBytes();
 	return dt->GetSizeInMemoryBytes();
 }
 }
 
 
-// TODO: interface: Should be able to take a pointer to asIObjectType directly
+// TODO: interface: Should deprecate this. The application should be calling the factory directly
 void *asCScriptEngine::CreateScriptObject(int typeId)
 void *asCScriptEngine::CreateScriptObject(int typeId)
 {
 {
 	// Make sure the type id is for an object type, and not a primitive or a handle
 	// Make sure the type id is for an object type, and not a primitive or a handle
@@ -3404,6 +3499,7 @@ void *asCScriptEngine::CreateScriptObject(int typeId)
 	return ptr;
 	return ptr;
 }
 }
 
 
+// TODO: interface: Should deprecate this. The application should be calling the factory directly
 void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 {
 {
 	void *newObj = CreateScriptObject(typeId);
 	void *newObj = CreateScriptObject(typeId);
@@ -3414,6 +3510,21 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 	return newObj;
 	return newObj;
 }
 }
 
 
+// internal
+void asCScriptEngine::ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type)
+{
+	// This function is only meant to be used for value types
+	asASSERT( type->flags & asOBJ_VALUE );
+
+	// TODO: Should use the copy constructor when available
+	int funcIndex = type->beh.construct;
+	if( funcIndex )
+		CallObjectMethod(mem, funcIndex);
+
+	CopyScriptObject(mem, obj, type->GetTypeId());
+}
+
+// TODO: interface: Should deprecate this. The application should be calling the opAssign method directly
 void asCScriptEngine::CopyScriptObject(void *dstObj, void *srcObj, int typeId)
 void asCScriptEngine::CopyScriptObject(void *dstObj, void *srcObj, int typeId)
 {
 {
 	// TODO: optimize: Use the copy constructor when available
 	// TODO: optimize: Use the copy constructor when available
@@ -3441,7 +3552,7 @@ void asCScriptEngine::CopyScriptObject(void *dstObj, void *srcObj, int typeId)
 	}
 	}
 }
 }
 
 
-// TODO: interface: Should be able to take a pointer to asIObjectType directly
+// interface
 void asCScriptEngine::AddRefScriptObject(void *obj, int typeId)
 void asCScriptEngine::AddRefScriptObject(void *obj, int typeId)
 {
 {
 	// Make sure it is not a null pointer
 	// Make sure it is not a null pointer
@@ -3464,7 +3575,21 @@ void asCScriptEngine::AddRefScriptObject(void *obj, int typeId)
 	}
 	}
 }
 }
 
 
-// TODO: interface: Should be able to take a pointer to asIObjectType directly
+// interface
+void asCScriptEngine::AddRefScriptObject(void *obj, const asIObjectType *type)
+{
+	// Make sure it is not a null pointer
+	if( obj == 0 ) return;
+
+	const asCObjectType *objType = static_cast<const asCObjectType *>(type);
+	if( objType->beh.addref )
+	{
+		// Call the addref behaviour
+		CallObjectMethod(obj, objType->beh.addref);
+	}
+}
+
+// interface
 void asCScriptEngine::ReleaseScriptObject(void *obj, int typeId)
 void asCScriptEngine::ReleaseScriptObject(void *obj, int typeId)
 {
 {
 	// Make sure it is not a null pointer
 	// Make sure it is not a null pointer
@@ -3485,6 +3610,31 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, int typeId)
 		// Call the release behaviour
 		// Call the release behaviour
 		CallObjectMethod(obj, objType->beh.release);
 		CallObjectMethod(obj, objType->beh.release);
 	}
 	}
+	// TODO: interface: shouldn't work on non reference types
+	else
+	{
+		// Call the destructor
+		if( objType->beh.destruct )
+			CallObjectMethod(obj, objType->beh.destruct);
+
+		// Then free the memory
+		CallFree(obj);
+	}
+}
+
+// interface
+void asCScriptEngine::ReleaseScriptObject(void *obj, const asIObjectType *type)
+{
+	// Make sure it is not a null pointer
+	if( obj == 0 ) return;
+	
+	const asCObjectType *objType = static_cast<const asCObjectType *>(type);
+	if( objType->beh.release )
+	{
+		// Call the release behaviour
+		CallObjectMethod(obj, objType->beh.release);
+	}
+	// TODO: interface: shouldn't work on non reference types
 	else
 	else
 	{
 	{
 		// Call the destructor
 		// Call the destructor
@@ -3552,7 +3702,7 @@ int asCScriptEngine::EndConfigGroup()
 {
 {
 	// Raise error if trying to end the default config
 	// Raise error if trying to end the default config
 	if( currentGroup == &defaultGroup )
 	if( currentGroup == &defaultGroup )
-		return asNOT_SUPPORTED;
+		return asERROR;
 
 
 	currentGroup = &defaultGroup;
 	currentGroup = &defaultGroup;
 
 
@@ -3656,6 +3806,8 @@ asCConfigGroup *asCScriptEngine::FindConfigGroupForFuncDef(asCScriptFunction *fu
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-04
 int asCScriptEngine::SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess)
 int asCScriptEngine::SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess)
 {
 {
 	asCConfigGroup *group = 0;
 	asCConfigGroup *group = 0;
@@ -3675,6 +3827,15 @@ int asCScriptEngine::SetConfigGroupModuleAccess(const char *groupName, const cha
 
 
 	return group->SetModuleAccess(module, hasAccess);
 	return group->SetModuleAccess(module, hasAccess);
 }
 }
+#endif
+
+// interface
+asDWORD asCScriptEngine::SetDefaultAccessMask(asDWORD defaultMask)
+{
+	asDWORD old = defaultAccessMask;
+	defaultAccessMask = defaultMask;
+	return old;
+}
 
 
 int asCScriptEngine::GetNextScriptFunctionId()
 int asCScriptEngine::GetNextScriptFunctionId()
 {
 {
@@ -3790,9 +3951,9 @@ int asCScriptEngine::RegisterFuncdef(const char *decl)
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetFuncdefCount() const
+asUINT asCScriptEngine::GetFuncdefCount() const
 {
 {
-	return (int)registeredFuncDefs.GetLength();
+	return registeredFuncDefs.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -3889,9 +4050,9 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetTypedefCount() const
+asUINT asCScriptEngine::GetTypedefCount() const
 {
 {
-	return (int)registeredTypeDefs.GetLength();
+	return registeredTypeDefs.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -3953,7 +4114,7 @@ int asCScriptEngine::RegisterEnum(const char *name)
 	asCDataType dataType;
 	asCDataType dataType;
 	dataType.CreatePrimitive(ttInt, false);
 	dataType.CreatePrimitive(ttInt, false);
 
 
-	st->flags = asOBJ_ENUM;
+	st->flags = asOBJ_ENUM | asOBJ_SHARED;
 	st->size = 4;
 	st->size = 4;
 	st->name = name;
 	st->name = name;
 
 
@@ -4008,9 +4169,9 @@ int asCScriptEngine::RegisterEnumValue(const char *typeName, const char *valueNa
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetEnumCount() const
+asUINT asCScriptEngine::GetEnumCount() const
 {
 {
-	return (int)registeredEnums.GetLength();
+	return registeredEnums.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -4064,9 +4225,9 @@ const char *asCScriptEngine::GetEnumValueByIndex(int enumTypeId, asUINT index, i
 }
 }
 
 
 // interface
 // interface
-int asCScriptEngine::GetObjectTypeCount() const
+asUINT asCScriptEngine::GetObjectTypeCount() const
 {
 {
-	return (int)registeredObjTypes.GetLength();
+	return registeredObjTypes.GetLength();
 }
 }
 
 
 // interface
 // interface
@@ -4093,12 +4254,19 @@ asIObjectType *asCScriptEngine::GetObjectTypeById(int typeId) const
 	return dt->GetObjectType();
 	return dt->GetObjectType();
 }
 }
 
 
+// interface
+asIScriptFunction *asCScriptEngine::GetFunctionById(int funcId) const
+{
+	return GetScriptFunction(funcId);
+}
 
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 asIScriptFunction *asCScriptEngine::GetFunctionDescriptorById(int funcId) const
 asIScriptFunction *asCScriptEngine::GetFunctionDescriptorById(int funcId) const
 {
 {
 	return GetScriptFunction(funcId);
 	return GetScriptFunction(funcId);
 }
 }
-
+#endif
 
 
 // internal
 // internal
 bool asCScriptEngine::IsTemplateType(const char *name) const
 bool asCScriptEngine::IsTemplateType(const char *name) const
@@ -4164,6 +4332,36 @@ int asCScriptEngine::GetScriptSectionNameIndex(const char *name)
 	return int(scriptSectionNames.GetLength()-1);
 	return int(scriptSectionNames.GetLength()-1);
 }
 }
 
 
+// interface 
+void asCScriptEngine::SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback)
+{
+	cleanEngineFunc = callback;
+}
+
+// interface 
+void asCScriptEngine::SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback)
+{
+	cleanModuleFunc = callback;
+}
+
+// interface
+void asCScriptEngine::SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback)
+{
+	cleanContextFunc = callback;
+}
+
+// interface
+void asCScriptEngine::SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback)
+{
+	cleanFunctionFunc = callback;
+}
+
+// interface
+void asCScriptEngine::SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback)
+{
+	cleanObjectTypeFunc = callback;
+}
+
 // Urho3D: modified for smaller executable size
 // Urho3D: modified for smaller executable size
 asSFuncPtr::asSFuncPtr()
 asSFuncPtr::asSFuncPtr()
 {
 {
@@ -4176,6 +4374,5 @@ asSFuncPtr::asSFuncPtr(asBYTE f)
 	flag = f;
 	flag = f;
 }
 }
 
 
-
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

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

@@ -61,10 +61,6 @@ class asCContext;
 // TODO: import: Remove this when import is removed
 // TODO: import: Remove this when import is removed
 struct sBindInfo;
 struct sBindInfo;
 
 
-// TODO: Deprecate CreateScriptObject. Objects should be created by calling the factory function instead.
-// TODO: Deprecate GetSizeOfPrimitiveType. This function is not necessary now that all primitive types have fixed typeIds
-
-
 // TODO: DiscardModule should take an optional pointer to asIScriptModule instead of module name. If null, nothing is done.
 // TODO: DiscardModule should take an optional pointer to asIScriptModule instead of module name. If null, nothing is done.
 
 
 // TODO: Should have a CreateModule/GetModule instead of just GetModule with parameters.
 // TODO: Should have a CreateModule/GetModule instead of just GetModule with parameters.
@@ -96,16 +92,18 @@ public:
     virtual asIJITCompiler *GetJITCompiler() const;
     virtual asIJITCompiler *GetJITCompiler() const;
 
 
 	// Global functions
 	// Global functions
-	virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
-	// TODO: interface: Should return asUINT
-	virtual int GetGlobalFunctionCount() const;
-	virtual int GetGlobalFunctionIdByIndex(asUINT index) const;
+	virtual int                RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
+	virtual asUINT             GetGlobalFunctionCount() const;
+	virtual int                GetGlobalFunctionIdByIndex(asUINT index) const;
+	virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const;
+	virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const;
 
 
 	// Global properties
 	// Global properties
-	virtual int RegisterGlobalProperty(const char *declaration, void *pointer);
-	// TODO: interface: Should return asUINT
-	virtual int GetGlobalPropertyCount() const;
-	virtual int GetGlobalPropertyByIndex(asUINT index, const char **name, int *typeId = 0, bool *isConst = 0, const char **configGroup = 0, void **pointer = 0) const;
+	virtual int    RegisterGlobalProperty(const char *declaration, void *pointer);
+	virtual asUINT GetGlobalPropertyCount() const;
+	// TODO: access: Return the current access mask
+	virtual int    GetGlobalPropertyByIndex(asUINT index, const char **name, int *typeId = 0, bool *isConst = 0, const char **configGroup = 0, void **pointer = 0) const;
+	// TODO: access: Allow changing the access mask
 	
 	
 	// Type registration
 	// Type registration
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags);
 	virtual int            RegisterObjectType(const char *obj, int byteSize, asDWORD flags);
@@ -114,8 +112,7 @@ public:
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
 	virtual int            RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
 	virtual int            RegisterInterface(const char *name);
 	virtual int            RegisterInterface(const char *name);
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration);
 	virtual int            RegisterInterfaceMethod(const char *intf, const char *declaration);
-	// TODO: interface: Should return asUINT
-	virtual int            GetObjectTypeCount() const;
+	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
 	
 	
 	// String factory
 	// String factory
@@ -129,36 +126,41 @@ public:
 	// Enums
 	// Enums
 	virtual int         RegisterEnum(const char *type);
 	virtual int         RegisterEnum(const char *type);
 	virtual int         RegisterEnumValue(const char *type, const char *name, int value);
 	virtual int         RegisterEnumValue(const char *type, const char *name, int value);
-	// TODO: interface: Should return asUINT
-	virtual int         GetEnumCount() const;
+	virtual asUINT      GetEnumCount() const;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **configGroup = 0) const;
 	virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **configGroup = 0) 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;
 
 
 	// Funcdefs
 	// Funcdefs
 	virtual int                RegisterFuncdef(const char *decl);
 	virtual int                RegisterFuncdef(const char *decl);
-	// TODO: interface: Should return asUINT
-	virtual int                GetFuncdefCount() const;
+	virtual asUINT             GetFuncdefCount() const;
 	virtual asIScriptFunction *GetFuncdefByIndex(asUINT index, const char **configGroup = 0) const;
 	virtual asIScriptFunction *GetFuncdefByIndex(asUINT index, const char **configGroup = 0) const;
 
 
 	// Typedefs
 	// Typedefs
 	virtual int         RegisterTypedef(const char *type, const char *decl);
 	virtual int         RegisterTypedef(const char *type, const char *decl);
-	// TODO: interface: Should return asUINT
-	virtual int         GetTypedefCount() const;
+	virtual asUINT      GetTypedefCount() const;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **configGroup = 0) const;
 	virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **configGroup = 0) const;
 
 
 	// Configuration groups
 	// Configuration groups
-	virtual int BeginConfigGroup(const char *groupName);
-	virtual int EndConfigGroup();
-	virtual int RemoveConfigGroup(const char *groupName);
+	virtual int     BeginConfigGroup(const char *groupName);
+	virtual int     EndConfigGroup();
+	virtual int     RemoveConfigGroup(const char *groupName);
+	virtual asDWORD SetDefaultAccessMask(asDWORD defaultMask);
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-04
 	virtual int SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess);
 	virtual int SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess);
+#endif
 
 
 	// Script modules
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag);
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag);
 	virtual int              DiscardModule(const char *module);
 	virtual int              DiscardModule(const char *module);
 
 
 	// Script functions
 	// Script functions
+	virtual asIScriptFunction *GetFunctionById(int funcId) const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
+#endif
 
 
 	// Type identification
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const;
 	virtual asIObjectType *GetObjectTypeById(int typeId) const;
@@ -172,7 +174,9 @@ public:
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId);
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId);
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId);
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, int typeId);
 	virtual void              ReleaseScriptObject(void *obj, int typeId);
 	virtual void              ReleaseScriptObject(void *obj, int typeId);
+	virtual void              ReleaseScriptObject(void *obj, const asIObjectType *type);
 	virtual void              AddRefScriptObject(void *obj, int typeId);
 	virtual void              AddRefScriptObject(void *obj, int typeId);
+	virtual void              AddRefScriptObject(void *obj, const asIObjectType *type);
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
 
 
 	// String interpretation
 	// String interpretation
@@ -181,6 +185,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, asUINT *newObjects, asUINT *totalNewDestroyed) const;
 	virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
+	// TODO: interface: Should have a version that takes the asIObjectType pointer
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId);
 	virtual void NotifyGarbageCollectorOfNewObject(void *obj, int typeId);
 	virtual void GCEnumCallback(void *reference);
 	virtual void GCEnumCallback(void *reference);
 
 
@@ -188,8 +193,10 @@ public:
 	virtual void *SetUserData(void *data);
 	virtual void *SetUserData(void *data);
 	virtual void *GetUserData() const;
 	virtual void *GetUserData() const;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback);
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback);
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback);
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback);
 
 
 //===========================================================
 //===========================================================
 // internal methods
 // internal methods
@@ -228,6 +235,8 @@ public:
 	void  CallGlobalFunction(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc);
 	void  CallGlobalFunction(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc);
 	bool  CallGlobalFunctionRetBool(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc);
 	bool  CallGlobalFunctionRetBool(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc);
 
 
+	void ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type);
+
 	void ClearUnusedTypes();
 	void ClearUnusedTypes();
 	void RemoveTemplateInstanceType(asCObjectType *t);
 	void RemoveTemplateInstanceType(asCObjectType *t);
 	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
 	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
@@ -249,9 +258,9 @@ public:
 
 
 	int AddBehaviourFunction(asCScriptFunction &func, asSSystemFunctionInterface &internal);
 	int AddBehaviourFunction(asCScriptFunction &func, asSSystemFunctionInterface &internal);
 
 
-	asCString GetFunctionDeclaration(int funcID);
+	asCString GetFunctionDeclaration(int funcId);
 
 
-	asCScriptFunction *GetScriptFunction(int funcID) const;
+	asCScriptFunction *GetScriptFunction(int funcId) const;
 
 
 	asCModule *GetModule(const char *name, bool create);
 	asCModule *GetModule(const char *name, bool create);
 	asCModule *GetModuleFromFuncId(int funcId);
 	asCModule *GetModuleFromFuncId(int funcId);
@@ -357,6 +366,7 @@ public:
 	asCConfigGroup             defaultGroup;
 	asCConfigGroup             defaultGroup;
 	asCArray<asCConfigGroup*>  configGroups;
 	asCArray<asCConfigGroup*>  configGroups;
 	asCConfigGroup            *currentGroup;
 	asCConfigGroup            *currentGroup;
+	asDWORD                    defaultAccessMask;
 
 
 	// Message callback
 	// Message callback
 	bool                        msgCallback;
 	bool                        msgCallback;
@@ -369,10 +379,12 @@ public:
 	asCArray<asCString*>        stringConstants;
 	asCArray<asCString*>        stringConstants;
 
 
 	// User data
 	// User data
-	void                  *userData;
-	asCLEANENGINEFUNC_t    cleanEngineFunc;
-	asCLEANCONTEXTFUNC_t   cleanContextFunc;
-	asCLEANFUNCTIONFUNC_t  cleanFunctionFunc;
+	void                   *userData;
+	asCLEANENGINEFUNC_t     cleanEngineFunc;
+	asCLEANMODULEFUNC_t     cleanModuleFunc;
+	asCLEANCONTEXTFUNC_t    cleanContextFunc;
+	asCLEANFUNCTIONFUNC_t   cleanFunctionFunc;
+	asCLEANOBJECTTYPEFUNC_t cleanObjectTypeFunc;
 
 
 	// Critical sections for threads
 	// Critical sections for threads
 	DECLARECRITICALSECTION(engineCritical);
 	DECLARECRITICALSECTION(engineCritical);
@@ -396,6 +408,7 @@ public:
 		int  propertyAccessorMode;
 		int  propertyAccessorMode;
 		bool expandDefaultArrayToTemplate;
 		bool expandDefaultArrayToTemplate;
 		bool autoGarbageCollect;
 		bool autoGarbageCollect;
+		bool disallowGlobalVars;
 	} ep;
 	} ep;
 };
 };
 
 

+ 26 - 18
ThirdParty/AngelScript/source/as_scriptfunction.cpp

@@ -143,6 +143,8 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
 	gcFlag                 = false;
 	gcFlag                 = false;
 	userData               = 0;
 	userData               = 0;
 	id                     = 0;
 	id                     = 0;
+	accessMask             = 0xFFFFFFFF;
+	isShared               = false;
 
 
 	// TODO: optimize: The engine could notify the GC just before it wants to
 	// TODO: optimize: The engine could notify the GC just before it wants to
 	//                 discard the function. That way the GC won't waste time
 	//                 discard the function. That way the GC won't waste time
@@ -215,24 +217,6 @@ int asCScriptFunction::Release() const
 	return r;
 	return r;
 }
 }
 
 
-// interface 
-void asCScriptEngine::SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback)
-{
-	cleanEngineFunc = callback;
-}
-
-// interface
-void asCScriptEngine::SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback)
-{
-	cleanContextFunc = callback;
-}
-
-// interface
-void asCScriptEngine::SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback)
-{
-	cleanFunctionFunc = callback;
-}
-
 // interface
 // interface
 const char *asCScriptFunction::GetModuleName() const
 const char *asCScriptFunction::GetModuleName() const
 {
 {
@@ -294,6 +278,17 @@ int asCScriptFunction::GetSpaceNeededForReturnValue()
 	return returnType.GetSizeOnStackDWords();
 	return returnType.GetSizeOnStackDWords();
 }
 }
 
 
+// internal
+bool asCScriptFunction::DoesReturnOnStack() const
+{
+	if( returnType.GetObjectType() &&
+		(returnType.GetObjectType()->flags & asOBJ_VALUE) &&
+		!returnType.IsReference() )
+		return true;
+		
+	return false;
+}
+
 // internal
 // internal
 asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName) const
 asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName) const
 {
 {
@@ -1054,5 +1049,18 @@ void asCScriptFunction::ReleaseAllHandles(asIScriptEngine *)
 	}
 	}
 }
 }
 
 
+// internal
+bool asCScriptFunction::IsShared() const
+{
+	// All system functions are shared
+	if( funcType == asFUNC_SYSTEM ) return true;
+
+	// All class methods for shared classes are also shared
+	if( objectType && (objectType->flags & asOBJ_SHARED) ) return true;
+
+	// Functions that have been specifically marked as shared are shared
+	return isShared;
+}
+
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

+ 13 - 1
ThirdParty/AngelScript/source/as_scriptfunction.h

@@ -86,6 +86,11 @@ struct asSSystemFunctionInterface;
 //       also functions/methods that are being called. This could be used to build a 
 //       also functions/methods that are being called. This could be used to build a 
 //       code database with call graphs, etc.
 //       code database with call graphs, etc.
 
 
+// TODO: optimize: The GC should only be notified of the script function when the last module
+//                 removes it from the scope. Must make sure it is only added to the GC once
+//                 in case the function is added to another module after the GC already knows 
+//                 about the function.
+
 void RegisterScriptFunction(asCScriptEngine *engine);
 void RegisterScriptFunction(asCScriptEngine *engine);
 
 
 class asCScriptFunction : public asIScriptFunction
 class asCScriptFunction : public asIScriptFunction
@@ -109,6 +114,7 @@ public:
 	const char          *GetConfigGroup() const;
 	const char          *GetConfigGroup() const;
 	bool                 IsReadOnly() const;
 	bool                 IsReadOnly() const;
 	bool                 IsPrivate() const;
 	bool                 IsPrivate() const;
+	// TODO: access: Get/Set access mask for function
 
 
 	asUINT               GetParamCount() const;
 	asUINT               GetParamCount() const;
 	int                  GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
 	int                  GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
@@ -144,11 +150,15 @@ public:
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCScriptFunction *func) const;
 
 
-    void      JITCompile();
+	bool      DoesReturnOnStack() const;
+
+	void      JITCompile();
 
 
 	void      AddReferences();
 	void      AddReferences();
 	void      ReleaseReferences();
 	void      ReleaseReferences();
 
 
+	bool      IsShared() const;
+
 	asCGlobalProperty *GetPropertyByGlobalVarPtr(void *gvarPtr);
 	asCGlobalProperty *GetPropertyByGlobalVarPtr(void *gvarPtr);
 
 
 	// GC methods
 	// GC methods
@@ -183,6 +193,8 @@ public:
 	int                          id;
 	int                          id;
 
 
 	asEFuncType                  funcType;
 	asEFuncType                  funcType;
+	asDWORD                      accessMask;
+	bool                         isShared;
 
 
 	// Used by asFUNC_SCRIPT
 	// Used by asFUNC_SCRIPT
 	asCArray<asDWORD>               byteCode;
 	asCArray<asDWORD>               byteCode;

+ 4 - 5
ThirdParty/AngelScript/source/as_scriptobject.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 
@@ -37,7 +37,7 @@
 BEGIN_AS_NAMESPACE
 BEGIN_AS_NAMESPACE
 
 
 // This helper function will call the default factory, that is a script function
 // This helper function will call the default factory, that is a script function
-asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *engine)
+asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine)
 {
 {
 	asIScriptContext *ctx;
 	asIScriptContext *ctx;
 
 
@@ -339,10 +339,9 @@ int asCScriptObject::GetTypeId() const
 	return objType->engine->GetTypeIdFromDataType(dt);
 	return objType->engine->GetTypeIdFromDataType(dt);
 }
 }
 
 
-int asCScriptObject::GetPropertyCount() const
+asUINT asCScriptObject::GetPropertyCount() const
 {
 {
-	// TODO: interface: Should return asUINT, as the function cannot fail
-	return (int)objType->properties.GetLength();
+	return objType->properties.GetLength();
 }
 }
 
 
 int asCScriptObject::GetPropertyTypeId(asUINT prop) const
 int asCScriptObject::GetPropertyTypeId(asUINT prop) const

+ 3 - 3
ThirdParty/AngelScript/source/as_scriptobject.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 
@@ -68,7 +68,7 @@ public:
 	asIObjectType *GetObjectType() const;
 	asIObjectType *GetObjectType() const;
 
 
 	// Class properties
 	// Class properties
-	int         GetPropertyCount() const;
+	asUINT      GetPropertyCount() const;
 	int         GetPropertyTypeId(asUINT prop) const;
 	int         GetPropertyTypeId(asUINT prop) const;
 	const char *GetPropertyName(asUINT prop) const;
 	const char *GetPropertyName(asUINT prop) const;
 	void       *GetAddressOfProperty(asUINT prop);
 	void       *GetAddressOfProperty(asUINT prop);
@@ -115,7 +115,7 @@ void ScriptObject_Assignment_Generic(asIScriptGeneric *gen);
 
 
 void RegisterScriptObject(asCScriptEngine *engine);
 void RegisterScriptObject(asCScriptEngine *engine);
 
 
-asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *engine);
+asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine);
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE
 
 

+ 16 - 2
ThirdParty/AngelScript/source/as_texts.h

@@ -92,6 +92,7 @@
 #define TXT_FUNCTION_s_NOT_FOUND          "Function '%s' not found"
 #define TXT_FUNCTION_s_NOT_FOUND          "Function '%s' not found"
 
 
 #define TXT_GET_SET_ACCESSOR_TYPE_MISMATCH_FOR_s "The property '%s' has mismatching types for the get and set accessors"
 #define TXT_GET_SET_ACCESSOR_TYPE_MISMATCH_FOR_s "The property '%s' has mismatching types for the get and set accessors"
+#define TXT_GLOBAL_VARS_NOT_ALLOWED              "Global variables have been disabled by the application"
 
 
 #define TXT_HANDLE_ASSIGN_ON_NON_HANDLE_PROP     "It is not allowed to perform a handle assignment on a non-handle property"
 #define TXT_HANDLE_ASSIGN_ON_NON_HANDLE_PROP     "It is not allowed to perform a handle assignment on a non-handle property"
 #define TXT_HANDLE_COMPARISON                    "The operand is implicitly converted to handle in order to compare them"
 #define TXT_HANDLE_COMPARISON                    "The operand is implicitly converted to handle in order to compare them"
@@ -142,7 +143,7 @@
 #define TXT_NO_CONVERSION_s_TO_MATH_TYPE           "No conversion from '%s' to math type available."
 #define TXT_NO_CONVERSION_s_TO_MATH_TYPE           "No conversion from '%s' to math type available."
 #define TXT_NO_DEFAULT_ARRAY_TYPE                  "The application doesn't support the default array type."
 #define TXT_NO_DEFAULT_ARRAY_TYPE                  "The application doesn't support the default array type."
 #define TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s           "No default constructor for object of type '%s'."
 #define TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s           "No default constructor for object of type '%s'."
-#define TXT_NO_DEFAULT_COPY_OP                     "There is no copy operator for this type available."
+#define TXT_NO_DEFAULT_COPY_OP_FOR_s               "There is no copy operator for the type '%s' available."
 #define TXT_NO_COPY_CONSTRUCTOR_FOR_s              "No copy constructor for object of type '%s'."
 #define TXT_NO_COPY_CONSTRUCTOR_FOR_s              "No copy constructor for object of type '%s'."
 #define TXT_NO_MATCHING_SIGNATURES_TO_s            "No matching signatures to '%s'"
 #define TXT_NO_MATCHING_SIGNATURES_TO_s            "No matching signatures to '%s'"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
 #define TXT_NO_MATCHING_OP_FOUND_FOR_TYPE_s        "No matching operator that takes the type '%s' found"
@@ -180,6 +181,12 @@
 #define TXT_REF_CANT_BE_RETURNED_DEFERRED_PARAM "Resulting reference cannot be returned. There are deferred arguments that may invalidate it."
 #define TXT_REF_CANT_BE_RETURNED_DEFERRED_PARAM "Resulting reference cannot be returned. There are deferred arguments that may invalidate it."
 #define TXT_REF_CANT_BE_RETURNED_LOCAL_VARS     "Resulting reference cannot be returned. The expression uses objects that during cleanup may invalidate it."
 #define TXT_REF_CANT_BE_RETURNED_LOCAL_VARS     "Resulting reference cannot be returned. The expression uses objects that during cleanup may invalidate it."
 
 
+#define TXT_SHARED_CANNOT_ACCESS_NON_SHARED_VAR_s      "Shared code cannot access non-shared global variable '%s'"
+#define TXT_SHARED_CANNOT_CALL_NON_SHARED_FUNC_s       "Shared code cannot call non-shared function '%s'"
+#define TXT_SHARED_CANNOT_IMPLEMENT_NON_SHARED_s       "Shared class cannot implement non-shared interface '%s'"
+#define TXT_SHARED_CANNOT_INHERIT_FROM_NON_SHARED_s    "Shared class cannot inherit from non-shared class '%s'"
+#define TXT_SHARED_CANNOT_USE_NON_SHARED_TYPE_s        "Shared code cannot use non-shared type '%s'"
+#define TXT_SHARED_DOESNT_MATCH_ORIGINAL               "Shared type doesn't match the original declaration in other module"
 #define TXT_SIGNED_UNSIGNED_MISMATCH                   "Signed/Unsigned mismatch"
 #define TXT_SIGNED_UNSIGNED_MISMATCH                   "Signed/Unsigned mismatch"
 #define TXT_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #define TXT_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #define TXT_SWITCH_CASE_MUST_BE_CONSTANT               "Case expressions must be constants"
 #define TXT_SWITCH_CASE_MUST_BE_CONSTANT               "Case expressions must be constants"
@@ -212,7 +219,14 @@
 #define TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR "A non-pod value type must have the default constructor and destructor behaviours"
 #define TXT_NON_POD_REQUIRE_CONSTR_DESTR_BEHAVIOUR "A non-pod value type must have the default constructor and destructor behaviours"
 #define TXT_CANNOT_PASS_TYPE_s_BY_VAL              "Can't pass type '%s' by value unless the application type is informed in the registration"
 #define TXT_CANNOT_PASS_TYPE_s_BY_VAL              "Can't pass type '%s' by value unless the application type is informed in the registration"
 #define TXT_CANNOT_RET_TYPE_s_BY_VAL               "Can't return type '%s' by value unless the application type is informed in the registration"
 #define TXT_CANNOT_RET_TYPE_s_BY_VAL               "Can't return type '%s' by value unless the application type is informed in the registration"
-#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL             "Don't support passing type '%s' by value to application"
+#define TXT_DONT_SUPPORT_TYPE_s_BY_VAL             "Don't support passing type '%s' by value to application. Use generic calling convention instead"
+#define TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL         "Don't support returning type '%s' by value from application. Use generic calling convention instead"
+#define TXT_GC_CANNOT_FREE_OBJ_OF_TYPE_s           "GC cannot free an object of type '%s'. Make sure all types that can form circular references have the GC behaviours"
+#define TXT_OBJECT_TYPE_s_DOESNT_EXIST             "Object type '%s' doesn't exist"
+#define TXT_TEMPLATE_TYPE_s_DOESNT_EXIST           "Template type '%s' doesn't exist"
+#define TXT_TEMPLATE_SUBTYPE_s_DOESNT_EXIST        "Template subtype '%s' doesn't exist"
+#define TXT_FAILED_READ_SUBTYPE_OF_TEMPLATE_s      "Failed to read subtype of template type '%s'"
+#define TXT_INSTANCING_INVLD_TMPL_TYPE_s_s         "Attempting to instanciate invalid template type '%s<%s>'"
 
 
 // Internal names
 // Internal names
 
 

+ 5 - 4
ThirdParty/AngelScript/source/as_tokendef.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 
@@ -285,9 +285,10 @@ const unsigned int numTokenWords = sizeof(tokenWords)/sizeof(sTokenWord);
 const char * const whiteSpace = " \t\r\n";
 const char * const whiteSpace = " \t\r\n";
 
 
 // Some keywords that are not considered tokens by the parser
 // Some keywords that are not considered tokens by the parser
-const char * const THIS_TOKEN = "this";
-const char * const FROM_TOKEN = "from";
-const char * const SUPER_TOKEN = "super";
+const char * const THIS_TOKEN   = "this";
+const char * const FROM_TOKEN   = "from";
+const char * const SUPER_TOKEN  = "super";
+const char * const SHARED_TOKEN = "shared";
 
 
 END_AS_NAMESPACE
 END_AS_NAMESPACE