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)
     {
-        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;
         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)
         {
-            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());
             Variant newValue = GetEditorValue(parent, map[key].type, null);
             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.
 
-- 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.
 

+ 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:
 
-- 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/)
 - GLee 5.4 (http://elf-stone.com/)
 - 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)
                     continue;
                 
-                asIScriptFunction* func = ot->GetEngine()->GetFunctionDescriptorById(funcId);
+                asIScriptFunction* func = ot->GetEngine()->GetFunctionById(funcId);
                 if (func->GetParamCount() == 0)
                 {
                     // Found the default constructor
@@ -113,7 +113,7 @@ static bool ScriptArrayTemplateCallback(asIObjectType* ot)
             for (unsigned n = 0; n < subtype->GetFactoryCount(); ++n)
             {
                 int funcId = subtype->GetFactoryIdByIndex(n);
-                asIScriptFunction* func = ot->GetEngine()->GetFunctionDescriptorById(funcId);
+                asIScriptFunction* func = ot->GetEngine()->GetFunctionById(funcId);
                 if (func->GetParamCount() == 0)
                 {
                     // Found the default factory

+ 3 - 3
Engine/Script/Script.cpp

@@ -221,7 +221,7 @@ void Script::DumpAPI()
     for (unsigned i = 0; i < functions; ++i)
     {
         unsigned id = scriptEngine_->GetGlobalFunctionIdByIndex(i);
-        asIScriptFunction* function = scriptEngine_->GetFunctionDescriptorById(id);
+        asIScriptFunction* function = scriptEngine_->GetFunctionById(id);
         String functionName(function->GetName());
         String declaration(function->GetDeclaration());
         
@@ -279,7 +279,7 @@ void Script::DumpAPI()
             unsigned methods = type->GetMethodCount();
             for (unsigned j = 0; j < methods; ++j)
             {
-                asIScriptFunction* method = type->GetMethodDescriptorByIndex(j);
+                asIScriptFunction* method = type->GetMethodByIndex(j);
                 String methodName(method->GetName());
                 String declaration(method->GetDeclaration());
                 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)
 {
     int funcId = context->GetExceptionFunction();
-    const asIScriptFunction *function = scriptEngine_->GetFunctionDescriptorById(funcId);
+    const asIScriptFunction *function = scriptEngine_->GetFunctionById(funcId);
     String message = "Exception '" + String(context->GetExceptionString()) + "' in '" +
         String(function->GetDeclaration()) + "'";
     

+ 2 - 4
Engine/Script/ScriptFile.cpp

@@ -302,8 +302,7 @@ asIScriptFunction* ScriptFile::GetFunction(const String& declaration)
     if (i != functions_.End())
         return i->second_;
     
-    int id = scriptModule_->GetFunctionIdByDecl(declaration.CString());
-    asIScriptFunction* function = scriptModule_->GetFunctionDescriptorById(id);
+    asIScriptFunction* function = scriptModule_->GetFunctionByDecl(declaration.CString());
     functions_[declaration] = function;
     return function;
 }
@@ -324,8 +323,7 @@ asIScriptFunction* ScriptFile::GetMethod(asIScriptObject* object, const String&
             return j->second_;
     }
     
-    int id = type->GetMethodIdByDecl(declaration.CString());
-    asIScriptFunction* function = scriptModule_->GetFunctionDescriptorById(id);
+    asIScriptFunction* function = type->GetMethodByDecl(declaration.CString());
     methods_[type][declaration] = 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/
 
 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/)
 - GLee 5.4 (http://elf-stone.com/)
 - GLFW 3.0 WIP (http://www.glfw.org/)

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

@@ -56,8 +56,8 @@ BEGIN_AS_NAMESPACE
 
 // 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
 
@@ -91,7 +91,8 @@ enum asEEngineProp
 	asEP_STRING_ENCODING              = 13,
 	asEP_PROPERTY_ACCESSOR_MODE       = 14,
 	asEP_EXPAND_DEF_ARRAY_TO_TMPL     = 15,
-	asEP_AUTO_GARBAGE_COLLECT         = 16
+	asEP_AUTO_GARBAGE_COLLECT         = 16,
+	asEP_DISALLOW_GLOBAL_VARS         = 17
 };
 
 // Calling conventions
@@ -138,8 +139,11 @@ enum asEObjTypeFlags
 	asOBJ_APP_CLASS_K                = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
 	asOBJ_APP_PRIMITIVE              = 0x2000,
 	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
@@ -343,8 +347,14 @@ typedef void (*asGENFUNC_t)(asIScriptGeneric *);
 typedef void *(*asALLOCFUNC_t)(size_t);
 typedef void (*asFREEFUNC_t)(void *);
 typedef void (*asCLEANENGINEFUNC_t)(asIScriptEngine *);
+typedef void (*asCLEANMODULEFUNC_t)(asIScriptModule *);
 typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
 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)
 #if (defined(_MSC_VER) && _MSC_VER <= 1200) || (defined(__BORLANDC__) && __BORLANDC__ < 0x590)
@@ -492,14 +502,16 @@ public:
 	virtual asIJITCompiler *GetJITCompiler() const = 0;
 
 	// 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
-	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
 	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            RegisterInterface(const char *name) = 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;
 
 	// String factory
@@ -522,33 +534,41 @@ public:
 	// Enums
 	virtual int         RegisterEnum(const char *type) = 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 int         GetEnumValueCount(int enumTypeId) const = 0;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const = 0;
 
 	// Funcdefs
 	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;
 
 	// Typedefs
 	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;
 
 	// Configuration groups
 	virtual int BeginConfigGroup(const char *groupName) = 0;
 	virtual int EndConfigGroup() = 0;
 	virtual int RemoveConfigGroup(const char *groupName) = 0;
+	virtual asDWORD SetDefaultAccessMask(asDWORD defaultMask) = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-04
 	virtual int SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess) = 0;
+#endif
 
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag = asGM_ONLY_IF_EXISTS) = 0;
 	virtual int              DiscardModule(const char *module) = 0;
 
 	// Script functions
+	virtual asIScriptFunction *GetFunctionById(int funcId) const = 0;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const = 0;
+#endif
 
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const = 0;
@@ -562,7 +582,9 @@ public:
 	virtual void             *CreateScriptObjectCopy(void *obj, 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, const asIObjectType *type) = 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;
 
 	// String interpretation
@@ -578,8 +600,10 @@ public:
 	virtual void *SetUserData(void *data) = 0;
 	virtual void *GetUserData() const = 0;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback) = 0;
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback) = 0;
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback) = 0;
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback) = 0;
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback) = 0;
 
 protected:
 	virtual ~asIScriptEngine() {}
@@ -593,18 +617,25 @@ public:
 	virtual const char      *GetName() const = 0;
 
 	// 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
 	virtual asUINT             GetFunctionCount() const = 0;
 	virtual int                GetFunctionIdByIndex(asUINT index) const = 0;
 	virtual int                GetFunctionIdByName(const char *name) 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 *GetFunctionDescriptorById(int funcId) const = 0;
+#endif
 	virtual int                RemoveFunction(int funcId) = 0;
 
 	// Global variables
@@ -646,6 +677,10 @@ public:
 	virtual int SaveByteCode(asIBinaryStream *out) const = 0;
 	virtual int LoadByteCode(asIBinaryStream *in) = 0;
 
+	// User data
+	virtual void *SetUserData(void *data) = 0;
+	virtual void *GetUserData() const = 0;
+
 protected:
 	virtual ~asIScriptModule() {}
 };
@@ -661,6 +696,7 @@ public:
 	virtual asIScriptEngine *GetEngine() const = 0;
 
 	// Execution
+	virtual int             Prepare(asIScriptFunction *func) = 0;
 	virtual int             Prepare(int funcId) = 0;
 	virtual int             Unprepare() = 0;
 	virtual int             SetObject(void *obj) = 0;
@@ -728,7 +764,11 @@ public:
 	// Miscellaneous
 	virtual asIScriptEngine   *GetEngine() 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;
+#endif
 	virtual void              *GetFunctionUserData() const = 0;
 
 	// Object
@@ -776,7 +816,7 @@ public:
 	virtual asIObjectType *GetObjectType() const = 0;
 
 	// Class properties
-	virtual int         GetPropertyCount() const = 0;
+	virtual asUINT      GetPropertyCount() const = 0;
 	virtual int         GetPropertyTypeId(asUINT prop) const = 0;
 	virtual const char *GetPropertyName(asUINT prop) const = 0;
 	virtual void       *GetAddressOfProperty(asUINT prop) = 0;
@@ -801,26 +841,37 @@ public:
 	// Type info
 	virtual const char      *GetName() const = 0;
 	virtual asIObjectType   *GetBaseType() const = 0;
+	virtual bool             DerivesFrom(const asIObjectType *objType) const = 0;
 	virtual asDWORD          GetFlags() const = 0;
 	virtual asUINT           GetSize() const = 0;
 	virtual int              GetTypeId() const = 0;
 	virtual int              GetSubTypeId() const = 0;
+	virtual asIObjectType   *GetSubType() const = 0;
 
 	// Interfaces
 	virtual asUINT           GetInterfaceCount() const = 0;
 	virtual asIObjectType   *GetInterface(asUINT index) const = 0;
+	virtual bool             Implements(const asIObjectType *objType) const = 0;
 
 	// Factories
 	virtual asUINT             GetFactoryCount() const = 0;
 	virtual int                GetFactoryIdByIndex(asUINT index) 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
 	virtual asUINT             GetMethodCount() const = 0;
 	virtual int                GetMethodIdByIndex(asUINT index, bool getVirtual = true) const = 0;
 	virtual int                GetMethodIdByName(const char *name, bool getVirtual = true) const = 0;
 	virtual int                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;
+#endif
 
 	// Properties
 	virtual asUINT      GetPropertyCount() const = 0;
@@ -831,6 +882,10 @@ public:
 	virtual asUINT GetBehaviourCount() 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:
 	virtual ~asIObjectType() {}
 };
@@ -949,7 +1004,9 @@ struct asSMethodPtr
 		// as it would mean that the size of the method pointer cannot be determined.
 
 		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
 	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
+	asIScriptContext *ctx;                // the active context
 };
 
-typedef void (*asJITFunction)(asSVMRegisters *registers, asDWORD entryId);
+typedef void (*asJITFunction)(asSVMRegisters *registers, asPWORD jitArg);
 
 class asIJITCompiler
 {
@@ -1540,7 +1598,7 @@ const asSBCInfo asBCInfo[256] =
 	asBCINFO(CMPu64,	rW_rW_ARG,		0),
 	asBCINFO(ChkNullS,	W_ARG,			0),
 	asBCINFO(ClrHi,		NO_ARG,			0),
-	asBCINFO(JitEntry,	W_ARG,			0),
+	asBCINFO(JitEntry,	PTR_ARG,		0),
 	asBCINFO(CallPtr,   rW_ARG,         0xFFFF),
 	asBCINFO(FuncPtr,   PTR_ARG,        AS_PTR_SIZE),
 	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++ )
 		{
 			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;
 			while( node )
@@ -450,6 +451,7 @@ void asCBuilder::ParseScripts()
 		for( n = 0; n < classDeclarations.GetLength(); 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;
 
@@ -669,22 +671,29 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
 {
 	asASSERT(obj.GetObjectType() != 0);
 
-	// TODO: Only search in config groups to which the module has access
 	// TODO: optimize: Improve linear search
 	asCArray<asCObjectProperty *> &props = obj.GetObjectType()->properties;
 	for( asUINT n = 0; n < props.GetLength(); n++ )
+	{
 		if( props[n]->name == prop )
-			return props[n];
+		{
+			if( module->accessMask & props[n]->accessMask )
+				return props[n];
+			else
+				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;
 
 	if( isCompiled ) *isCompiled = true;
 	if( isPureConstant ) *isPureConstant = false;
+	if( isAppProp ) *isAppProp = false;
 
 	// TODO: optimize: Improve linear search
 	// Check application registered properties
@@ -694,14 +703,24 @@ asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, bool *isCompi
 		{
 			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];
+				}
 			}
 			else
 			{
 				// We're not compiling a module right now, so it must be a registered global property
+				if( isAppProp ) *isAppProp = true;
 				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
 	// Check against global properties
-	asCGlobalProperty *prop = GetGlobalProperty(name, 0, 0, 0);
+	asCGlobalProperty *prop = GetGlobalProperty(name, 0, 0, 0, 0);
 	if( prop )
 	{
 		if( code )
@@ -1115,6 +1134,14 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
 
 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?
 	asCDataType type = CreateDataTypeFromNode(node->firstChild, file);
 
@@ -1178,6 +1205,15 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 	asCScriptNode *n = node->firstChild;
 	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;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
@@ -1185,14 +1221,40 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	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);
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
 
+	if( isShared )
+		st->flags |= asOBJ_SHARED;
+
 	if( node->tokenType == ttHandle )
 		st->flags |= asOBJ_IMPLICIT_HANDLE;
 
@@ -1204,6 +1266,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
 	decl->objType = st;
 
 	// 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);
 
 	// Use the default script class behaviours
@@ -1231,6 +1294,15 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file)
 	asCScriptNode *n = node->firstChild;
 	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;
 	file->ConvertPosToRowCol(n->tokenPos, &r, &c);
 
@@ -1238,14 +1310,40 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file)
 
 	sClassDeclaration *decl = asNEW(sClassDeclaration);
 	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
 	asCObjectType *st = asNEW(asCObjectType)(engine);
 	st->flags = asOBJ_REF | asOBJ_SCRIPT_OBJECT;
+
+	if( isShared )
+		st->flags |= asOBJ_SHARED;
+
 	st->size = 0; // Cannot be instanciated
 	st->name = name;
 	module->classTypes.PushLast(st);
@@ -1550,6 +1648,13 @@ void asCBuilder::CompileClasses()
 		// Find the base class that this class inherits from
 		bool multipleInheritance = false;
 		asCScriptNode *node = decl->node->firstChild->next;
+
+		if( decl->objType->IsShared() )
+		{
+			// Skip the keyword 'shared'
+			node = node->next;
+		}
+
 		while( node && node->nodeType == snIdentifier )
 		{
 			// Get the interface name from the node
@@ -1577,7 +1682,7 @@ void asCBuilder::CompileClasses()
 			else if( objType->size != 0 )
 			{
 				// The class inherits from another script class
-				if( decl->objType->derivedFrom != 0 )
+				if( !decl->isExistingShared && decl->objType->derivedFrom != 0 )
 				{
 					if( !multipleInheritance )
 					{
@@ -1608,15 +1713,43 @@ void asCBuilder::CompileClasses()
 
 					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
 			{
 				// The class implements an interface
-				if( decl->objType->Implements(objType) )
+				if( !decl->isExistingShared && decl->objType->Implements(objType) )
 				{
 					int r, c;
 					file->ConvertPosToRowCol(node->tokenPos, &r, &c);
@@ -1626,7 +1759,32 @@ void asCBuilder::CompileClasses()
 				}
 				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++ )
 	{
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared )
+		{
+			// TODO: shared: Should really validate against original
+			continue;
+		}
 
 		// Add all properties and methods from the base class
 		if( decl->objType->derivedFrom )
@@ -1767,6 +1930,15 @@ void asCBuilder::CompileClasses()
 				asCDataType dt = CreateDataTypeFromNode(isPrivate ? node->firstChild->next : node->firstChild, file);
 				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() )
 				{
 					int r, c;
@@ -1793,6 +1965,7 @@ void asCBuilder::CompileClasses()
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared ) continue;
 		for( asUINT m = 0; m < decl->objType->interfaces.GetLength(); m++ )
 		{
 			asCObjectType *objType = decl->objType->interfaces[m];
@@ -1906,6 +2079,7 @@ void asCBuilder::CompileClasses()
 	for( n = 0; n < classDeclarations.GetLength(); n++ )
 	{
 		sClassDeclaration *decl = classDeclarations[n];
+		if( decl->isExistingShared ) continue;
 		asCObjectType *ot = decl->objType;
 
 		// 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);
 	compiler.CompileFactory(this, file, engine->scriptFunctions[funcId]);
 	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)
@@ -2081,11 +2259,9 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file)
 
 		// Store the location of this declaration for reference in name collisions
 		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);
 
 		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
 		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);
 	}
 
@@ -2405,6 +2579,33 @@ int asCBuilder::RegisterScriptFunction(int funcId, asCScriptNode *node, asCScrip
 		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
 	// Check that the same function hasn't been registered already
 	asCArray<int> funcs;
@@ -2485,7 +2686,11 @@ int asCBuilder::RegisterScriptFunction(int funcId, asCScriptNode *node, asCScrip
 			asCDataType dt = asCDataType::CreateObjectHandle(objType, 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);
 
 			// 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]->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);
+			}
 		}
 	}
 }
@@ -2787,9 +2999,15 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
 			if( ot->flags & asOBJ_IMPLICIT_HANDLE )
 				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
 			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))
 				{
@@ -2995,7 +3213,6 @@ asCDataType asCBuilder::ModifyDataTypeFromNode(const asCDataType &type, asCScrip
 
 asCObjectType *asCBuilder::GetObjectType(const char *type)
 {
-	// TODO: Only search in config groups to which the module has access
 	asCObjectType *ot = engine->GetObjectType(type);
 	if( !ot && module )
 		ot = module->GetObjectType(type);
@@ -3007,7 +3224,7 @@ asCScriptFunction *asCBuilder::GetFuncDef(const char *type)
 {
 	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 )
 		{
 			return engine->registeredFuncDefs[n];

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

@@ -76,11 +76,14 @@ struct sGlobalVariableDescription
 
 struct sClassDeclaration
 {
+	sClassDeclaration() {script = 0; node = 0; validState = 0; objType = 0; isExistingShared = false;}
+
 	asCScriptCode *script;
 	asCScriptNode *node;
 	asCString name;
 	int validState;
 	asCObjectType *objType;
+	bool isExistingShared;
 };
 
 struct sFuncDef
@@ -126,9 +129,9 @@ protected:
 	friend class asCParser;
 
 	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 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;
 
     // 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)
@@ -1370,8 +1369,7 @@ void asCByteCode::CallPtr(asEBCInstr instr, int funcPtrVar, int pop)
 	last->wArg[0] = (short)funcPtrVar;
 
     // 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)
@@ -1388,8 +1386,7 @@ void asCByteCode::Alloc(asEBCInstr instr, void *objID, int funcID, int pop)
 	*((int*)(ARG_DW(last->arg)+AS_PTR_SIZE)) = funcID;
 
     // 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)
@@ -1448,8 +1445,7 @@ void asCByteCode::Line(int line, int column)
 	*((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
-    // TODO: Should this be done by the compiler?
-    InstrWORD(asBC_JitEntry, 0);
+    InstrPTR(asBC_JitEntry, 0);
 }
 
 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->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
@@ -211,6 +215,24 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 				}
 #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 )
 		{
@@ -291,6 +313,8 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
 #ifdef SPLIT_OBJS_BY_MEMBER_TYPES
 			// It's not safe to pass 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
 #ifdef COMPLEX_OBJS_PASSED_BY_REF
 			if( !(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )	
 #endif
@@ -378,13 +402,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
 	void    *obj               = 0;
 	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( 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);
 
 #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
 			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

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

@@ -46,13 +46,12 @@
 
 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 );
 
 #define X64_MAX_ARGS             32
 #define MAX_CALL_INT_REGISTERS    6
 #define MAX_CALL_SSE_REGISTERS    8
-#define CALLSTACK_MULTIPLIER      2
 #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, 
@@ -67,41 +66,6 @@ typedef asQWORD ( *funcptr_t )( void );
 		: "%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 )                \
 	__asm__ __volatile__ (                       \
 		"movq %" name ", %0\n"                   \
@@ -121,7 +85,7 @@ static asDWORD GetReturnedFloat()
 		"movss    %%xmm0, (%%rax)"
 		: /* no output */
 		: "m" (retval)
-		: "%rax"
+		: "%rax", "%xmm0"
 	);
 
 	// We need to avoid implicit conversions from float to unsigned - we need
@@ -141,7 +105,7 @@ static asQWORD GetReturnedDouble()
 		"movlpd  %%xmm0, (%%rax)"
 		: /* no optput */
 		: "m" (retval)
-		: "%rax"
+		: "%rax", "%xmm0"
 	);
 
 	// We need to avoid implicit conversions from double to unsigned long long - we need
@@ -151,55 +115,76 @@ static asQWORD GetReturnedDouble()
 	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;
 	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
 	retval = call();
+
+	// Restore the stack pointer
+	__asm__ __volatile__ ("  mov %%r15, %%rsp \n" : : : "%r15", "%rsp");
+
 	return retval;
 }
 
 // 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;
 }
@@ -208,256 +193,144 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 {
 	asSSystemFunctionInterface *sysFunc            = descr->sysFuncIntf;
 	int                         callConv           = sysFunc->callConv;
-
 	asQWORD                     retQW              = 0;
 	void                       *func               = ( void * )sysFunc->func;
 	asDWORD                    *stack_pointer      = args;
 	funcptr_t                  *vftable            = NULL;
 	int                         totalArgumentCount = 0;
 	int                         n                  = 0;
-	int                         base_n             = 0;
-	int                         a                  = 0;
-	int                         param_pre          = 0;
 	int                         param_post         = 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
 		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 );
 		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_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;
-			base_n = 1;
 
-			param_pre = 1;
+			argIndex = 1;
 
 			break;
 		}
 		case ICC_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;
 
-			param_pre = 1;
+			argIndex = 1;
 
 			break;
 		}
 		case ICC_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[1] = x64INTARG;
 
-			param_pre = 2;
+			argIndex = 2;
 
 			break;
 		}
-		case ICC_CDECL_OBJLAST: {
-			memcpy( paramBuffer + totalArgumentCount * CALLSTACK_MULTIPLIER, &obj, sizeof( obj ) );
-			argsType[totalArgumentCount] = x64INTARG;
-
+		case ICC_CDECL_OBJLAST: 
 			param_post = 1;
-
 			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;
-			memcpy( paramBuffer + ( totalArgumentCount + 1 ) * CALLSTACK_MULTIPLIER, &obj, sizeof( obj ) );
-			argsType[totalArgumentCount + 1] = x64INTARG;
 
-			param_pre = 1;
+			argIndex = 1;
 			param_post = 1;
 
 			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 !?
 	 *
 	 * A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
 	 * it's little magic which must work regardless of how the compiler decides to
 	 * allocate registers. Basically:
-	 * - the first MAX_CALL_INT_REGISTERS entries in tempBuff 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
 	 *   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
@@ -470,44 +343,43 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	 *   in reverse order so that X64_CallFunction() can simply push them to the stack
 	 *   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;
-			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++;
 		}
 	}
-	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;
-			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++;
 		}
 	}
-	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;
-	retQW = X64_CallFunction( tempBuff, tempType, ( asDWORD * )func );
+	retQW = X64_CallFunction( tempBuff, used_stack_args, (asDWORD*)func );
 	ASM_GET_REG( "%rdx", retQW2 );
 	context->isCallingSystemFunction = false;
 
@@ -516,8 +388,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
 	{
 		if( sysFunc->hostReturnSize == 1 )
 			*(asDWORD*)&retQW = GetReturnedFloat();
-		else
+		else if( sysFunc->hostReturnSize == 2 )
 			retQW = GetReturnedDouble();
+		else
+			GetReturnedXmm0Xmm1(retQW, retQW2);
 	}
 
 	return retQW;
@@ -527,3 +401,4 @@ END_AS_NAMESPACE
 
 #endif // AS_X64_GCC
 #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());
 			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
 	{
@@ -342,7 +350,7 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 	// Concatenate the bytecode
 
 	// 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
 	int varSize = GetVariableOffset((int)variableAllocations.GetLength()) - 1;
@@ -437,7 +445,7 @@ int asCCompiler::CompileFunction(asCBuilder *builder, asCScriptCode *script, asC
 	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() )
 		return 0;
@@ -516,6 +524,11 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 			{
 				asASSERT( !isGlobalVar );
 				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);
@@ -541,7 +554,7 @@ int asCCompiler::CallCopyConstructor(asCDataType &type, int offset, bool isObjec
 	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() ||
 		(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 )
 	{
 		asSExprContext ctx(engine);
+		ctx.exprNode = node;
 
 		int func = 0;
 		asSTypeBehaviour *beh = type.GetBehaviour();
@@ -603,6 +617,8 @@ int asCCompiler::CallDefaultConstructor(asCDataType &type, int offset, bool isOb
 				{
 					// Call the constructor as a normal function
 					bc->InstrSHORT(asBC_PSF, (short)offset);
+					if( deferDest )
+						bc->Instr(asBC_RDSPTR);
 					asSExprContext ctx(engine);
 					PerformFunctionCall(func, &ctx, false, 0, type.GetObjectType());
 					bc->AddCode(&ctx.bc);
@@ -887,9 +903,9 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 		}
 		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) )
 			{
@@ -930,7 +946,7 @@ int asCCompiler::CompileGlobalVariable(asCBuilder *builder, asCScriptCode *scrip
 
 			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
 				// 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);
 
-				if( ctx->type.dataType.IsReference() ) ConvertToVariable(ctx);
+				if( ctx->type.dataType.IsReference() ) ConvertToVariableNotIn(ctx, reservedVars);
 				ImplicitConversion(ctx, dt, node, asIC_IMPLICIT_CONV, true, reservedVars);
 
 				if( !(param.IsReadOnly() && ctx->type.isVariable) )
-					ConvertToTempVariable(ctx);
+					ConvertToTempVariableNotIn(ctx, reservedVars);
 
 				PushVariableOnStack(ctx, true);
 				ctx->type.dataType.MakeReadOnly(param.IsReadOnly());
@@ -1142,7 +1158,7 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 					ctx->bc.AddCode(&tmpBC);
 
 					// Assign the evaluated expression to the temporary variable
-					PrepareForAssignment(&dt, ctx, node);
+					PrepareForAssignment(&dt, ctx, node, true);
 
 					dt.MakeReference(IsVariableOnHeap(offset));
 					asCTypeInfo type;
@@ -1213,6 +1229,8 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		}
 		else if( refType == asTM_INOUTREF )
 		{
+			ProcessPropertyGetAccessor(ctx, node);
+
 			// Literal constants cannot be passed to inout ref arguments
 			if( !ctx->type.isVariable && ctx->type.isConstant )
 			{
@@ -1278,7 +1296,7 @@ void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, a
 		{
 			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
 			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 )
 			{
-				ConvertToVariable(ctx);
+				ConvertToVariableNotIn(ctx, reservedVars);
 				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
-	asCScriptFunction *descr = builder->GetFunctionDescription(funcID);
+	asCScriptFunction *descr = builder->GetFunctionDescription(funcId);
 
 	// Add code for arguments
 	asSExprContext e(engine);
@@ -1375,14 +1393,20 @@ void asCCompiler::PrepareFunctionCall(int funcID, asCByteCode *bc, asCArray<asSE
 	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;
 	if( addOneToOffset )
 		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
 	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() )
 			{
-				// 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
 					if( n == funcs.GetLength()-1 )
@@ -1704,6 +1735,18 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 			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
 		asCString name(&script->code[node->tokenPos], node->tokenLength);
 
@@ -1873,7 +1916,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 				}
 				else
 				{
-					// TODO: We can use a copy constructor here
+					// TODO: optimize: We can use a copy constructor here
 
 					sVariable *v = variables->GetVariable(name.AddressOf());
 
@@ -1916,7 +1959,7 @@ void asCCompiler::CompileDeclaration(asCScriptNode *decl, asCByteCode *bc)
 
 					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
 						// 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
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 
 	bc->AddCode(&expr.bc);
@@ -2760,7 +2803,7 @@ void asCCompiler::CompileWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 	// Add a suspend bytecode inside the loop to guarantee
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 	// Compile statement
 	bool hasReturn;
@@ -2814,7 +2857,7 @@ void asCCompiler::CompileDoWhileStatement(asCScriptNode *wnode, asCByteCode *bc)
 	// Add a suspend bytecode inside the loop to guarantee
 	// that the application can suspend the execution
 	bc->Instr(asBC_SUSPEND);
-	bc->InstrWORD(asBC_JitEntry, 0);
+	bc->InstrPTR(asBC_JitEntry, 0);
 
 	// Add a line instruction
 	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))) &&
 		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
 		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);
 
 		// 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);
 		PerformAssignment(&lvalue, &ctx->type, &ctx->bc, node);
@@ -3138,7 +3181,7 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 					asCString str;
 					str.Format(TXT_NO_CONVERSION_s_TO_s, expr.type.dataType.Format().AddressOf(), v->type.Format().AddressOf());
 					Error(str.AddressOf(), rnode);
-					r = -1;
+					return;
 				}
 				else
 				{
@@ -3159,25 +3202,80 @@ void asCCompiler::CompileReturnStatement(asCScriptNode *rnode, asCByteCode *bc)
 			}
 			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
 		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);
@@ -3535,7 +3637,7 @@ void asCCompiler::PrepareOperand(asSExprContext *ctx, asCScriptNode *node)
 	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);
 
@@ -3578,20 +3680,20 @@ void asCCompiler::PrepareForAssignment(asCDataType *lvalue, asSExprContext *rctx
 		to.MakeReference(false);
 
 		// 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() &&
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 			to.MakeHandle(true);
 
 		// 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() &&
 			(lvalue->GetObjectType()->flags & asOBJ_SCRIPT_OBJECT) )
 		{
 			// Then convert to a reference, which will validate the handle
 			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
@@ -3681,7 +3783,9 @@ void asCCompiler::PerformAssignment(asCTypeInfo *lvalue, asCTypeInfo *rvalue, as
 			if( lvalue->dataType.GetSizeInMemoryDWords() == 0 ||
 				!(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
@@ -4497,7 +4601,28 @@ void asCCompiler::ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataT
 			{
 				asCTypeInfo objType = ctx->type;
 				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);
 			}
 			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
 			asCArray<asCDataType>& parameterTypes =
-				engine->scriptFunctions[lctx->property_set]->parameterTypes;
+				builder->GetFunctionDescription(lctx->property_set)->parameterTypes;
 			if( !parameterTypes[parameterTypes.GetLength() - 1].IsObjectHandle() )
 			{
 				// Process the property to free the memory
@@ -5405,7 +5530,7 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 			rctx->type = o.type;
 
 			// Convert the rvalue to the right type and validate it
-			PrepareForAssignment(&lvalue.dataType, rctx, rexpr);
+			PrepareForAssignment(&lvalue.dataType, rctx, rexpr, false);
 
 			MergeExprBytecode(ctx, rctx);
 			lctx->type = lvalue;
@@ -5415,7 +5540,7 @@ int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExpr
 		else
 		{
 			// 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, lctx);
@@ -5732,7 +5857,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asSExprContext *ctx)
 				if( rtemp.dataType.IsObjectHandle() )
 					rtemp.isExplicitHandle = true;
 
-				PrepareForAssignment(&rtemp.dataType, &le, cexpr->next);
+				PrepareForAssignment(&rtemp.dataType, &le, cexpr->next, true);
 				MergeExprBytecode(ctx, &le);
 
 				if( !rtemp.dataType.IsPrimitive() )
@@ -5753,7 +5878,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asSExprContext *ctx)
 				ctx->bc.Label((short)elseLabel);
 
 				// Copy the result to the same temporary variable
-				PrepareForAssignment(&rtemp.dataType, &re, cexpr->next);
+				PrepareForAssignment(&rtemp.dataType, &re, cexpr->next, true);
 				MergeExprBytecode(ctx, &re);
 
 				if( !rtemp.dataType.IsPrimitive() )
@@ -6113,8 +6238,9 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 		{
 			bool isCompiled = true;
 			bool isPureConstant = false;
+			bool isAppProp = false;
 			asQWORD constantValue;
-			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), &isCompiled, &isPureConstant, &constantValue);
+			asCGlobalProperty *prop = builder->GetGlobalProperty(name.AddressOf(), &isCompiled, &isPureConstant, &constantValue, &isAppProp);
 			if( prop )
 			{
 				found = true;
@@ -6136,6 +6262,20 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 						ctx->type.SetConstantQW(prop->type, constantValue);
 					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.dataType.MakeReference(true);
 						ctx->type.isLValue = true;
@@ -6195,9 +6335,19 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
 		{
 			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
-			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 )
 		{
+			// 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
 			ctx->type.SetConstantDW(dt, value);
 		}
@@ -6429,7 +6582,19 @@ int asCCompiler::CompileExpressionValue(asCScriptNode *node, asSExprContext *ctx
 					// Register the constant string with the engine
 					int id = engine->AddConstantString(str.AddressOf(), str.GetLength());
 					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 )
 	{
-		bool found = false;
-
 		// Determine the scope resolution
 		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?
 				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 )
 	{
@@ -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 )
 	{
 		// 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;
 	}
 
+	// 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
 	asCArray<asSExprContext *> args;
 	asCArray<asCTypeInfo> temporaryVariables;
@@ -7231,6 +7411,9 @@ void asCCompiler::CompileConstructCall(asCScriptNode *node, asSExprContext *ctx)
 
 					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,
 					// so we have to manually inform the type of
 					// 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;
 	asCTypeInfo tempObj;
@@ -7312,7 +7495,7 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 		asCString msg;
 		msg.Format(TXT_NOT_A_FUNC_s_IS_VAR, name.AddressOf());
 		Error(msg.AddressOf(), node);
-		return;
+		return -1;
 	}
 
 	if( funcs.GetLength() == 0 && funcPtr.type.dataType.GetFuncDef() )
@@ -7400,6 +7583,8 @@ void asCCompiler::CompileFunctionCall(asCScriptNode *node, asSExprContext *ctx,
 		{
 			asDELETE(args[n],asSExprContext);
 		}
+
+	return 0;
 }
 
 int asCCompiler::CompileExpressionPreOp(asCScriptNode *node, asSExprContext *ctx)
@@ -7829,7 +8014,7 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		builder->GetFunctionDescriptions(getName.AddressOf(), funcs);
 		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)
 			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);
 		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?
 			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
 	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
 		int idx = (arg?1:0);
@@ -7921,12 +8106,12 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 	if( outFunc->objectType && isThisAccess )
 	{
 		// 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 &&
 			getFunc->funcType == asFUNC_VIRTUAL &&
 			outFunc->objectType->DerivesFrom(getFunc->objectType) )
 			realGetId = outFunc->objectType->virtualFunctionTable[getFunc->vfTableIdx]->id;
-		asCScriptFunction *setFunc = setId ? engine->scriptFunctions[setId] : 0;
+		asCScriptFunction *setFunc = setId ? builder->GetFunctionDescription(setId) : 0;
 		if( setFunc &&
 			setFunc->funcType == asFUNC_VIRTUAL &&
 			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
 	if( engine->ep.propertyAccessorMode == 1 )
 	{
-		if( getId && engine->scriptFunctions[getId]->funcType != asFUNC_SYSTEM )
+		if( getId && builder->GetFunctionDescription(getId)->funcType != asFUNC_SYSTEM )
 		  getId = 0;
-		if( setId && engine->scriptFunctions[setId]->funcType != asFUNC_SYSTEM )
+		if( setId && builder->GetFunctionDescription(setId)->funcType != asFUNC_SYSTEM )
 		  setId = 0;
 	}
 
@@ -7978,9 +8163,9 @@ int asCCompiler::FindPropertyAccessor(const asCString &name, asSExprContext *ctx
 		// unless only the getter is available
 		asCDataType dt;
 		if( setId )
-			dt = engine->scriptFunctions[setId]->parameterTypes[(arg?1:0)];
+			dt = builder->GetFunctionDescription(setId)->parameterTypes[(arg?1:0)];
 		else
-			dt = engine->scriptFunctions[getId]->returnType;
+			dt = builder->GetFunctionDescription(getId)->returnType;
 
 		// Just change the type, the context must still maintain information
 		// about previous variable offset and the indicator of temporary variable.
@@ -8016,7 +8201,7 @@ int asCCompiler::ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext
 	}
 
 	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
 	asCArray<int> funcs;
@@ -8103,7 +8288,7 @@ void asCCompiler::ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode
 	}
 
 	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
 	asCArray<int> funcs;
@@ -8445,7 +8630,8 @@ int asCCompiler::CompileExpressionPostOp(asCScriptNode *node, asSExprContext *ct
 			asCTypeInfo objType = ctx->type;
 
 			// 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
 			// 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
 		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
 			asCScriptFunction *func = 0;
 			if( ctx->property_get )
-				func = engine->scriptFunctions[ctx->property_get];
+				func = builder->GetFunctionDescription(ctx->property_get);
 			else
-				func = engine->scriptFunctions[ctx->property_get];
+				func = builder->GetFunctionDescription(ctx->property_set);
 			propertyName = func->GetName();
 			propertyName = propertyName.SubString(4);
 
@@ -8964,9 +9150,15 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
 				(!isConst || func->isReadOnly) )
 			{
 				// 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);
+				}
 			}
 		}
 
@@ -9084,10 +9276,24 @@ void asCCompiler::MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectTyp
 			ctx->bc.ExchangeVar(args[n]->type.stackOffset, newOffset);
 			args[n]->type.stackOffset = (short)newOffset;
 			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);
 
 	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() )
 		{
 			asCDataType to;
-			if( lctx->type.dataType.GetSizeInMemoryDWords() == 2  )
+			if( lctx->type.dataType.GetSizeInMemoryDWords() == 2 )
 				to.SetTokenType(ttInt64);
 			else
 				to.SetTokenType(ttInt);
@@ -10549,6 +10755,14 @@ void asCCompiler::PerformFunctionCall(int funcId, asSExprContext *ctx, bool isCo
 {
 	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
 	if( descr->isPrivate && descr->GetObjectType() != outFunc->GetObjectType() )
 	{
@@ -10604,43 +10818,73 @@ void asCCompiler::PerformFunctionCall(int funcId, asSExprContext *ctx, bool isCo
 
 		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() )
 	{
 		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;
-			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
+#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
 
-		// Move the pointer from the object register to the temporary variable
-		ctx->bc.InstrSHORT(asBC_STOREOBJ, (short)returnOffset);
-
 		// Clean up arguments
 		if( args )
 			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  CompileExpressionPostOp(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 CompileConversion(asCScriptNode *node, 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);
 
-	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);
 	int  CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
 	int  CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
@@ -172,7 +172,7 @@ protected:
 	void SwapPostFixOperands(asCArray<asCScriptNode *> &postfix, asCArray<asCScriptNode *> &target);
 	void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, asCArray<int> *reservedVars, bool forceOnHeap = false);
 	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);
 	bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
 	void Dereference(asSExprContext *ctx, bool generateCode);

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

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

+ 10 - 1
ThirdParty/AngelScript/source/as_configgroup.h

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

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

@@ -172,6 +172,8 @@ asCContext::asCContext(asCScriptEngine *engine, bool holdRef)
 	doSuspend = false;
 
 	userData = 0;
+
+	regs.ctx = this;
 }
 
 asCContext::~asCContext()
@@ -233,6 +235,7 @@ asIScriptEngine *asCContext::GetEngine() const
 	return engine;
 }
 
+// interface
 void *asCContext::SetUserData(void *data)
 {
 	void *oldData = userData;
@@ -240,13 +243,31 @@ void *asCContext::SetUserData(void *data)
 	return oldData;
 }
 
+// interface
 void *asCContext::GetUserData() const
 {
 	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 )
 		return asCONTEXT_ACTIVE;
 
@@ -257,16 +278,9 @@ int asCContext::Prepare(int funcID)
 	// Release the returned object (if any)
 	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;
 	}
 	else
@@ -277,16 +291,27 @@ int asCContext::Prepare(int funcID)
 		if( initialFunction )
 			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();
 		currentFunction = initialFunction;
 
-		// Determine the minimum stack size needed
 		// 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;
 
@@ -305,12 +330,6 @@ int asCContext::Prepare(int funcID)
 			asDWORD *stack = asNEWARRAY(asDWORD,stackBlockSize);
 			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
@@ -329,12 +348,24 @@ int asCContext::Prepare(int funcID)
 	status = asEXECUTION_PREPARED;
 
 	// 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;
 
 	// Set arguments to 0
 	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 )
 	{
 		regs.programPointer = currentFunction->byteCode.AddressOf();
@@ -463,7 +494,13 @@ void *asCContext::GetReturnAddress()
 	if( dt->IsReference() )
 		return *(void**)&regs.valueRegister;
 	else if( dt->IsObject() )
+	{
+#ifndef AS_OLD
+		if( initialFunction->DoesReturnOnStack() )
+			return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif		
 		return regs.objectRegister;
+	}
 
 	return 0;
 }
@@ -479,7 +516,13 @@ void *asCContext::GetReturnObject()
 	if( dt->IsReference() )
 		return *(void**)(size_t)regs.valueRegister;
 	else
+	{
+#ifndef AS_OLD
+		if( initialFunction->DoesReturnOnStack() )
+			return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif
 		return regs.objectRegister;
+	}
 }
 
 void *asCContext::GetAddressOfReturnValue()
@@ -493,7 +536,13 @@ void *asCContext::GetAddressOfReturnValue()
 	{
 		// Need to dereference objects 
 		if( !dt->IsObjectHandle() )
+		{
+#ifndef AS_OLD
+			if( initialFunction->DoesReturnOnStack() )
+				return (void*)(stackBlocks[0] + stackBlockSize - returnValueSize);
+#endif
 			return *(void**)&regs.objectRegister;
+		}
 		return &regs.objectRegister;
 	}
 
@@ -546,6 +595,11 @@ int asCContext::SetArgByte(asUINT arg, asBYTE value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -584,6 +638,11 @@ int asCContext::SetArgWord(asUINT arg, asWORD value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -622,6 +681,11 @@ int asCContext::SetArgDWord(asUINT arg, asDWORD value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -660,6 +724,11 @@ int asCContext::SetArgQWord(asUINT arg, asQWORD value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -698,6 +767,11 @@ int asCContext::SetArgFloat(asUINT arg, float value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -736,6 +810,11 @@ int asCContext::SetArgDouble(asUINT arg, double value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -768,7 +847,11 @@ int asCContext::SetArgAddress(asUINT arg, void *value)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -817,6 +900,11 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -842,6 +930,11 @@ void *asCContext::GetAddressOfArg(asUINT arg)
 	int offset = 0;
 	if( initialFunction->objectType )
 		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++ )
 		offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
 
@@ -1187,11 +1280,11 @@ void asCContext::CallScriptFunction(asCScriptFunction *func)
 				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
-		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);
 	}
 
@@ -1999,15 +2092,15 @@ void asCContext::ExecuteNext()
 			regs.stackPointer = l_sp;
 			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);
 				return;
 			}
 			else
 			{
-				asCScriptFunction *func = engine->GetScriptFunction(funcID);
+				asCScriptFunction *func = engine->GetScriptFunction(funcId);
 
 				CallScriptFunction(func);
 			}
@@ -3129,21 +3222,25 @@ void asCContext::ExecuteNext()
 		{
 			if( currentFunction->jitFunction )
 			{
-				unsigned int jitOffset = asBC_WORDARG0(l_bc);
+				asPWORD jitArg = asBC_PTRARG(l_bc);
 
-				if( jitOffset )
+				if( jitArg )
 				{
 					// Resume JIT operation
 					regs.programPointer = l_bc;
 					regs.stackPointer = l_sp;
 					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_sp = regs.stackPointer;
 					l_fp = regs.stackFramePointer;
+
+					// If status isn't active anymore then we must stop
+					if( status != asEXECUTION_ACTIVE )
+						return;
+				
 					break;
 				}
 			}
@@ -3405,7 +3502,8 @@ void asCContext::ExecuteNext()
 #ifdef AS_DEBUG
 		asDWORD instr = *(asBYTE*)old;
 		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] );
 		}
@@ -3448,6 +3546,17 @@ void asCContext::SetInternalException(const char *descr)
 
 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;
 
 	asASSERT( regs.objectType != 0 );
@@ -3565,13 +3674,25 @@ void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLe
 		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
 	liveObjects.SetLength(func->objVariablePos.GetLength());
 	memset(liveObjects.AddressOf(), 0, sizeof(int)*liveObjects.GetLength());
 	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
 			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);
 
 	isCallingSystemFunction = true;

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

@@ -51,8 +51,6 @@ BEGIN_AS_NAMESPACE
 class asCScriptFunction;
 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
 {
 public:
@@ -64,7 +62,9 @@ public:
 
 	asEContextState GetState() const;
 
-	int  Prepare(int functionID);
+	int  Prepare(asIScriptFunction *func);
+	// TODO: interface: deprecate this
+	int  Prepare(int functionId);
 	int  Unprepare();
 
 	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
 #undef GetObject
+#undef RegisterClass
 
 class asCThreadCriticalSection
 {

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

@@ -41,6 +41,7 @@
 #include "as_gc.h"
 #include "as_scriptengine.h"
 #include "as_scriptobject.h"
+#include "as_texts.h"
 
 BEGIN_AS_NAMESPACE
 
@@ -365,6 +366,18 @@ int asCGarbageCollector::DestroyNewGarbage()
 	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()
 {
 	for(;;)
@@ -395,7 +408,24 @@ int asCGarbageCollector::DestroyOldGarbage()
 			if( ++destroyOldIdx < gcOldObjects.GetLength() )
 			{
 				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
 
@@ -510,7 +540,11 @@ int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
 			{
 				// Add the gc count for this object
 				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 )
 				{
 					asSIntTypePair it = {refCount-1, gcObj.type};

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

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

+ 34 - 1
ThirdParty/AngelScript/source/as_generic.cpp

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -74,11 +74,20 @@ int asCGeneric::GetFunctionId() const
 	return sysFunction->id;
 }
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 // interface
 asIScriptFunction *asCGeneric::GetFunctionDescriptor() const
 {
 	return sysFunction;
 }
+#endif
+
+// interface
+asIScriptFunction *asCGeneric::GetFunction() const
+{
+	return sysFunction;
+}
 
 // interface
 void *asCGeneric::GetFunctionUserData() const
@@ -465,7 +474,16 @@ int asCGeneric::SetReturnObject(void *obj)
 	}
 	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));
+#endif
 	}
 
 	objectRegister = obj;
@@ -479,7 +497,13 @@ void *asCGeneric::GetReturnPointer()
 	asCDataType &dt = sysFunction->returnType;
 
 	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 &returnVal;
 }
@@ -491,6 +515,14 @@ void *asCGeneric::GetAddressOfReturnLocation()
 
 	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 )
 		{
 			// Allocate the necessary memory for this object, 
@@ -501,6 +533,7 @@ void *asCGeneric::GetAddressOfReturnLocation()
 
 			return objectRegister;
 		}
+#endif
 
 		// Reference types store the handle in the objectReference
 		return &objectRegister;

+ 5 - 1
ThirdParty/AngelScript/source/as_generic.h

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -55,7 +55,11 @@ public:
 	// Miscellaneous
 	asIScriptEngine   *GetEngine() const;
 	int                GetFunctionId() const;
+	asIScriptFunction *GetFunction() const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	asIScriptFunction *GetFunctionDescriptor() const;
+#endif
 	void              *GetFunctionUserData() const;
 
 	// Object

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

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -43,6 +43,7 @@ asCGlobalProperty::asCGlobalProperty()
 	memoryAllocated = false; 
 	realAddress = 0; 
 	initFunc = 0;
+	accessMask = 0xFFFFFFFF;
 
 	refCount.set(1);
 }

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

@@ -1,6 +1,6 @@
 /*
    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 
    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;
 		else if( key == p->key )
 		{
-			*out = p;
+			if( out ) *out = p;
 			return true;
 		}
 		else 
 			p = p->right;
 	}
 
-	*out = 0;
+	if( out ) *out = 0;
 	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->engine   = engine;
 
+	userData = 0;
 	builder = 0;
 	isGlobalVarInitialized = false;
+
+	accessMask = 1;
 }
 
 // internal
@@ -65,6 +68,10 @@ asCModule::~asCModule()
 		builder = 0;
 	}
 
+	// Clean the user data
+	if( userData && engine->cleanModuleFunc )
+		engine->cleanModuleFunc(this);
+
 	// Remove the module from the 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
 asIScriptEngine *asCModule::GetEngine() const
 {
@@ -180,6 +201,15 @@ int asCModule::GetFunctionIdByIndex(asUINT index) const
 	return globalFunctions[index]->id;
 }
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
+{
+	if( index >= globalFunctions.GetLength() )
+		return 0;
+
+	return globalFunctions[index];
+}
+
 // internal
 int asCModule::CallInit(asIScriptContext *myCtx)
 {
@@ -229,7 +259,7 @@ int asCModule::CallInit(asIScriptContext *myCtx)
 					if( r == asEXECUTION_EXCEPTION )
 					{
 						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());
 
@@ -384,6 +414,16 @@ int asCModule::GetFunctionIdByName(const char *name) const
 	return id;
 }
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
+{
+	int id = GetFunctionIdByName(name);
+	if( id < 0 )
+		return 0;
+
+	return engine->GetFunctionById(id);
+}
+
 // interface
 asUINT asCModule::GetImportedFunctionCount() const
 {
@@ -483,6 +523,13 @@ int asCModule::GetFunctionIdByDecl(const char *decl) const
 	return id;
 }
 
+// interface
+asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
+{
+	int id = GetFunctionIdByDecl(decl);
+	return engine->GetFunctionById(id);
+}
+
 // interface
 asUINT asCModule::GetGlobalVarCount() const
 {
@@ -520,6 +567,8 @@ int asCModule::RemoveGlobalVar(asUINT index)
 	return 0;
 }
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-03
 // interface
 asIScriptFunction *asCModule::GetFunctionDescriptorByIndex(asUINT index) const
 {
@@ -534,6 +583,7 @@ asIScriptFunction *asCModule::GetFunctionDescriptorById(int funcId) const
 {
 	return engine->GetFunctionDescriptorById(funcId);
 }
+#endif
 
 // interface
 int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
@@ -1155,8 +1205,8 @@ bool asCModule::AreInterfacesEqual(asCObjectType *a, asCObjectType *b, asCArray<
 	{
 		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  
 		// 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;
 }
 
+// interface
+asDWORD asCModule::SetAccessMask(asDWORD mask)
+{
+	asDWORD old = accessMask;
+	accessMask = mask;
+	return old;
+}
+
 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
 //       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
 {
 //-------------------------------------------
@@ -101,18 +98,25 @@ public:
 	virtual const char      *GetName() const;
 
 	// 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
 	virtual asUINT             GetFunctionCount() const;
 	virtual int                GetFunctionIdByIndex(asUINT index) const;
 	virtual int                GetFunctionIdByName(const char *name) 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 *GetFunctionDescriptorById(int funcId) const;
+#endif
 	virtual int                RemoveFunction(int funcId);
 
 	// Script global variables
@@ -128,6 +132,7 @@ public:
 	// Type identification
 	virtual asUINT         GetObjectTypeCount() const;
 	virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
+	// TODO: interface: Should have GetObjectTypeByName
 	virtual int            GetTypeIdByDecl(const char *decl) const;
 
 	// Enums
@@ -154,6 +159,10 @@ public:
 	virtual int SaveByteCode(asIBinaryStream *out) const;
 	virtual int LoadByteCode(asIBinaryStream *in);
 
+	// User data
+	virtual void *SetUserData(void *data);
+	virtual void *GetUserData() const;
+
 //-----------------------------------------------
 // Internal
 //-----------------------------------------------
@@ -196,6 +205,8 @@ public:
 
 	asCScriptEngine *engine;
 	asCBuilder      *builder;
+	void            *userData;
+	asDWORD          accessMask;
 
 	// This array holds all functions, class members, factories, etc that were compiled with the module
 	asCArray<asCScriptFunction *>  scriptFunctions;

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

@@ -127,7 +127,11 @@ asCObjectType::asCObjectType()
 	derivedFrom = 0;
 
 	acceptValueSubType = true;
-	acceptRefSubType = true;
+	acceptRefSubType   = true;
+
+	accessMask = 0xFFFFFFFF;
+
+	userData = 0;
 }
 
 asCObjectType::asCObjectType(asCScriptEngine *engine) 
@@ -138,6 +142,10 @@ asCObjectType::asCObjectType(asCScriptEngine *engine)
 
 	acceptValueSubType = true;
 	acceptRefSubType = true;
+
+	accessMask = 0xFFFFFFFF;
+
+	userData = 0;
 }
 
 int asCObjectType::AddRef() const
@@ -152,6 +160,18 @@ int asCObjectType::Release() const
 	return refCount.atomicDec();
 }
 
+void *asCObjectType::SetUserData(void *data)
+{
+	void *oldData = userData;
+	userData = data;
+	return oldData;
+}
+
+void *asCObjectType::GetUserData() const
+{
+	return userData;
+}
+
 int asCObjectType::GetRefCount()
 {
 	return refCount.get();
@@ -201,9 +221,14 @@ asCObjectType::~asCObjectType()
 	}
 
 	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 )
 		return true;
@@ -214,7 +239,8 @@ bool asCObjectType::Implements(const asCObjectType *objType) const
 	return false;
 }
 
-bool asCObjectType::DerivesFrom(const asCObjectType *objType) const
+// interface
+bool asCObjectType::DerivesFrom(const asIObjectType *objType) const
 {
 	if( this == objType )
 		return true;
@@ -231,6 +257,15 @@ bool asCObjectType::DerivesFrom(const asCObjectType *objType) const
 	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
 const char *asCObjectType::GetName() const
 {
@@ -274,6 +309,18 @@ int asCObjectType::GetSubTypeId() const
 	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
 {
 	return (asUINT)interfaces.GetLength();
@@ -298,11 +345,13 @@ asIScriptEngine *asCObjectType::GetEngine() const
 	return engine;
 }
 
+// interface
 asUINT asCObjectType::GetFactoryCount() const
 {
 	return (asUINT)beh.factories.GetLength();
 }
 
+// interface
 int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 {
 	if( index >= beh.factories.GetLength() )
@@ -311,6 +360,16 @@ int asCObjectType::GetFactoryIdByIndex(asUINT index) const
 	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
 {
 	if( beh.factories.GetLength() == 0 )
@@ -320,6 +379,16 @@ int asCObjectType::GetFactoryIdByDecl(const char *decl) const
 	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
 asUINT asCObjectType::GetMethodCount() const
 {
@@ -342,6 +411,12 @@ int asCObjectType::GetMethodIdByIndex(asUINT index, bool getVirtual) const
 	return methods[index];
 }
 
+// interface
+asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual) const
+{
+	return engine->GetFunctionById(GetMethodIdByIndex(index, getVirtual));
+}
+
 // interface
 int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 {
@@ -369,6 +444,12 @@ int asCObjectType::GetMethodIdByName(const char *name, bool getVirtual) const
 	return id;
 }
 
+// interface
+asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
+{
+	return engine->GetFunctionById(GetMethodIdByName(name, getVirtual));
+}
+
 // interface
 int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 {
@@ -396,6 +477,14 @@ int asCObjectType::GetMethodIdByDecl(const char *decl, bool getVirtual) const
 	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
 asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool getVirtual) const
 {
@@ -411,6 +500,7 @@ asIScriptFunction *asCObjectType::GetMethodDescriptorByIndex(asUINT index, bool
 
 	return engine->scriptFunctions[methods[index]];
 }
+#endif
 
 // interface
 asUINT asCObjectType::GetPropertyCount() const
@@ -659,6 +749,32 @@ void asCObjectType::ReleaseAllFunctions()
 		engine->scriptFunctions[beh.destruct]->Release();
 	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 )
 		engine->scriptFunctions[beh.addref]->Release();
 	beh.addref = 0;
@@ -667,10 +783,6 @@ void asCObjectType::ReleaseAllFunctions()
 		engine->scriptFunctions[beh.release]->Release();
 	beh.release = 0;
 
-	if( beh.copy )
-		engine->scriptFunctions[beh.copy]->Release();
-	beh.copy = 0;
-
 	if( beh.gcEnumReferences )
 		engine->scriptFunctions[beh.gcEnumReferences]->Release();
 	beh.gcEnumReferences = 0;
@@ -690,27 +802,6 @@ void asCObjectType::ReleaseAllFunctions()
 	if( beh.gcSetFlag )
 		engine->scriptFunctions[beh.gcSetFlag]->Release();
 	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

+ 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.
 
 // 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_ENUM             = 0x10000000;
 const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
 
 
 
-
 // asOBJ_GC is used to indicate that the type can potentially 
 // 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
 // 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
 {
 	asSTypeBehaviour() 
@@ -148,28 +143,41 @@ public:
 	// Type info
 	const char      *GetName() const;
 	asIObjectType   *GetBaseType() const;
+	bool             DerivesFrom(const asIObjectType *objType) const;
 	asDWORD          GetFlags() const;
 	asUINT           GetSize() const;
 	int              GetTypeId() const;
 	int              GetSubTypeId() const;
+	asIObjectType   *GetSubType() const;
+	// TODO: access: Get/Set access mask for type
 
 	// Interfaces
 	asUINT           GetInterfaceCount() const;
 	asIObjectType   *GetInterface(asUINT index) const;
+	bool             Implements(const asIObjectType *objType) const;
 
 	// Factories
 	asUINT             GetFactoryCount() const;
 	int                GetFactoryIdByIndex(asUINT index) const;
 	int                GetFactoryIdByDecl(const char *decl) const;
+	asIScriptFunction *GetFactoryByIndex(asUINT index) const;
+	asIScriptFunction *GetFactoryByDecl(const char *decl) const;
 
 	// Methods
 	asUINT             GetMethodCount() const;
 	int                GetMethodIdByIndex(asUINT index, bool getVirtual) const;
 	int                GetMethodIdByName(const char *name, 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;
+#endif
 
 	// Properties
+	// TODO: access: Allow getting and setting property access mask
 	asUINT      GetPropertyCount() const;
 	int         GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference) const;
 	const char *GetPropertyDeclaration(asUINT index) const;
@@ -178,6 +186,10 @@ public:
 	asUINT GetBehaviourCount() const;
 	int    GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
 
+	// User data
+	void *SetUserData(void *data);
+	void *GetUserData() const;
+
 //===========================================
 // Internal
 //===========================================
@@ -194,9 +206,8 @@ public:
 
 	void ReleaseAllFunctions();
 
-	bool Implements(const asCObjectType *objType) const;
-	bool DerivesFrom(const asCObjectType *objType) const;
 	bool IsInterface() const;
+	bool IsShared() const;
 
 	asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate);
 
@@ -210,6 +221,7 @@ public:
 	asCArray<asCScriptFunction*> virtualFunctionTable;
 
 	asDWORD flags;
+	asDWORD accessMask;
 
 	asSTypeBehaviour beh;
 
@@ -219,6 +231,7 @@ public:
 	bool           acceptRefSubType;
 
 	asCScriptEngine *engine;
+	void            *userData;
 
 protected:
 	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);
 
 	// Determine type of node
-	sToken t1;
+	sToken t1, t2;
 
 	for(;;)
 	{
 		while( !isSyntaxError )
 		{
 			GetToken(&t1);
+			GetToken(&t2);
 			RewindTo(&t1);
 
 			if( t1.type == ttImport )
@@ -350,9 +351,9 @@ asCScriptNode *asCParser::ParseScript()
 				node->AddChildLast(ParseEnumeration());	//	Handle enumerations
 			else if( t1.type == ttTypedef )
 				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());
-			else if( t1.type == ttInterface )
+			else if( t1.type == ttInterface || (t1.type == ttIdentifier && t2.type == ttInterface) )
 				node->AddChildLast(ParseInterface());
 			else if( t1.type == ttFuncDef )
 				node->AddChildLast(ParseFuncDef());
@@ -918,6 +919,23 @@ asCScriptNode *asCParser::ParseInterface()
 
 	sToken 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 )
 	{
 		Error(ExpectedToken("interface").AddressOf(), &t);
@@ -966,6 +984,23 @@ asCScriptNode *asCParser::ParseClass()
 
 	sToken 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 )
 	{
 		Error(ExpectedToken("class").AddressOf(), &t);

+ 5 - 1
ThirdParty/AngelScript/source/as_property.h

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

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

@@ -39,6 +39,7 @@
 #include "as_restore.h"
 #include "as_bytecode.h"
 #include "as_scriptobject.h"
+#include "as_texts.h"
 
 BEGIN_AS_NAMESPACE
 
@@ -251,13 +252,39 @@ int asCRestore::Restore()
 	{
 		asCObjectType *ot = asNEW(asCObjectType)(engine);
 		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);
 		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
@@ -327,6 +354,11 @@ int asCRestore::Restore()
 
 	// scriptGlobals[]
 	count = ReadEncodedUInt();
+	if( engine->ep.disallowGlobalVars )
+	{
+		engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
+		error = true;
+	}
 	module->scriptGlobals.Allocate(count, 0);
 	for( i = 0; i < count; ++i ) 
 	{
@@ -428,11 +460,12 @@ int asCRestore::Restore()
 	// Init system functions properly
 	engine->PrepareEngine();
 
-	// Add references for all functions
+	// Add references for all functions (except for the pre-existing shared code)
 	if( !error )
 	{
 		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++ )
 			if( module->scriptGlobals[i]->GetInitFunc() )
 				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;
 	READ_NUM(c);
@@ -762,7 +795,8 @@ asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine)
 
 	if( func->funcType == asFUNC_SCRIPT )
 	{
-		engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
+		if( addToGC )
+			engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
 		
 		count = ReadEncodedUInt();
 		func->byteCode.Allocate(count, 0);
@@ -959,76 +993,281 @@ void asCRestore::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
 		}
 		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[]
 			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
 			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 )
 				{
-					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 )
 				{
-					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 )
 				{
-					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();
-				for( n = 0; n < size; n++ )
+				for( int n = 0; n < size; n++ )
 				{
-					asCScriptFunction *func = ReadFunction();
+					asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 					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 )
 					{
-						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[]
 			size = ReadEncodedUInt();
+			int n;
 			for( n = 0; n < size; n++ ) 
 			{
-				asCScriptFunction *func = ReadFunction();
+				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				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();
 			for( n = 0; n < size; n++ )
 			{
-				asCScriptFunction *func = ReadFunction();
+				asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
 				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;
 	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) 
@@ -1350,7 +1624,7 @@ void asCRestore::ReadDataType(asCDataType *dt)
 		ReadFunctionSignature(&func);
 		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 )
 			{
 				funcDef = engine->registeredFuncDefs[n];
@@ -1457,9 +1731,8 @@ asCObjectType* asCRestore::ReadObjectType()
 		asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf());
 		if( tmpl == 0 )
 		{
-			// TODO: Move text to as_texts.h
 			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());
 			error = true;
 			return 0;
@@ -1471,9 +1744,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			ot = ReadObjectType();
 			if( ot == 0 )
 			{
-				// TODO: Move text to as_texts.h
 				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());
 				error = true;
 				return 0;
@@ -1492,9 +1764,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			if( ot == 0 )
 			{
-				// TODO: Move text to as_texts.h
 				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());
 				error = true;
 				return 0;
@@ -1510,9 +1781,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			if( ot == 0 )
 			{
-				// TODO: Move text to as_texts.h
 				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());
 				error = true;
 				return 0;
@@ -1538,9 +1808,8 @@ asCObjectType* asCRestore::ReadObjectType()
 
 		if( ot == 0 )
 		{
-			// TODO: Move text to as_texts.h
 			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());
 			error = true;
 			return 0;
@@ -1561,9 +1830,8 @@ asCObjectType* asCRestore::ReadObjectType()
 			
 			if( ot == 0 )
 			{
-				// TODO: Move text to as_texts.h
 				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());
 				error = true;
 				return 0;
@@ -1617,6 +1885,11 @@ void asCRestore::WriteByteCode(asDWORD *bc, int length)
 			// Translate object type pointers into indices
 			*(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
 			     c == asBC_Cast )   // DW_ARG
 		{
@@ -2335,6 +2608,9 @@ asCScriptFunction *asCRestore::FindFunction(int idx)
 
 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;
 	asDWORD *bc = func->byteCode.AddressOf();
 	for( n = 0; n < func->byteCode.GetLength(); )

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

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -77,7 +77,7 @@ protected:
 	void WriteEncodedUInt(asUINT i);
 
 	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 ReadGlobalProperty();
 	void ReadObjectProperty(asCObjectType *ot);
@@ -139,6 +139,9 @@ protected:
 		asUINT         oldSize;
 	};
 	asCArray<SObjChangeSize>     oldObjectSizes;
+
+	asCMap<void*,bool>              existingShared;
+	asCMap<asCScriptFunction*,bool> dontTranslate;
 };
 
 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;
 		break;
 
+	case asEP_DISALLOW_GLOBAL_VARS:
+		ep.disallowGlobalVars = value ? true : false;
+		break;
+
 	default:
 		return asINVALID_ARG;
 	}
@@ -350,6 +354,9 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
 
 	case asEP_AUTO_GARBAGE_COLLECT:
 		return ep.autoGarbageCollect;
+
+	case asEP_DISALLOW_GLOBAL_VARS:
+		return ep.disallowGlobalVars;
 	}
 
 	return 0;
@@ -393,6 +400,7 @@ asCScriptEngine::asCScriptEngine()
 		ep.propertyAccessorMode         = 2;         // 0 = disable, 1 = app registered only, 2 = app and script created
 		ep.expandDefaultArrayToTemplate = false;
 		ep.autoGarbageCollect           = true;
+		ep.disallowGlobalVars           = false;
 	}
 
 	gc.engine = this;
@@ -405,17 +413,20 @@ asCScriptEngine::asCScriptEngine()
 	lastModule = 0;
 
 	// 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)
 
 
-	typeIdSeqNbr = 0;
-	currentGroup = &defaultGroup;
+	typeIdSeqNbr      = 0;
+	currentGroup      = &defaultGroup;
+	defaultAccessMask = 1;
 
 	msgCallback = 0;
     jitCompiler = 0;
@@ -531,6 +542,11 @@ asCScriptEngine::~asCScriptEngine()
 	GarbageCollect(asGC_FULL_CYCLE);
 	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;
 	while( mapTypeIdToDataType.MoveFirst(&cursor) )
 	{
@@ -782,6 +798,9 @@ int asCScriptEngine::DiscardModule(const char *module)
 	FreeUnusedGlobalProperties();
 	ClearUnusedTypes();
 
+	if( ep.autoGarbageCollect )
+		GarbageCollect();
+
 	return 0;
 }
 
@@ -993,10 +1012,10 @@ int asCScriptEngine::GetMethodIdByDecl(const asCObjectType *ot, const char *decl
 
 
 // Internal
-asCString asCScriptEngine::GetFunctionDeclaration(int funcID)
+asCString asCScriptEngine::GetFunctionDeclaration(int funcId)
 {
 	asCString str;
-	asCScriptFunction *func = GetScriptFunction(funcID);
+	asCScriptFunction *func = GetScriptFunction(funcId);
 	if( func )
 		str = func->GetDeclarationStr();
 
@@ -1060,6 +1079,7 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
 	prop->type       = type;
 	prop->byteOffset = byteOffset;
 	prop->isPrivate  = false;
+	prop->accessMask = defaultAccessMask;
 
 	dt.GetObjectType()->properties.PushLast(prop);
 
@@ -1104,7 +1124,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
 
 	// Register the object type for the interface
 	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->name = name;
 
@@ -1225,26 +1245,35 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		else if( flags & asOBJ_APP_PRIMITIVE )
 		{
 			// 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);
 		}
 		else if( flags & asOBJ_APP_FLOAT )
 		{
 			// 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);
 		}
-		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
 			return ConfigError(asINVALID_ARG);
@@ -1286,9 +1315,10 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 		}
 
 		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
 		objectTypes.PushLast(type);
@@ -1369,9 +1399,10 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 			// Put the data type in the list
 			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);
 			registeredObjTypes.PushLast(type);
@@ -1406,11 +1437,12 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
 
 			// Put the data type in the list
 			asCObjectType *type = asNEW(asCObjectType)(this);
-			type->name      = dt.GetObjectType()->name;
+			type->name       = dt.GetObjectType()->name;
 			type->templateSubType = dt.GetSubType();
 			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);
 
@@ -1853,17 +1885,20 @@ int asCScriptEngine::AddBehaviourFunction(asCScriptFunction &func, asSSystemFunc
 
 	asCScriptFunction *f = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
 	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);
 
@@ -1904,6 +1939,7 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
 	asCGlobalProperty *prop = AllocateGlobalProperty();
 	prop->name        = name;
 	prop->type        = type;
+	prop->accessMask  = defaultAccessMask;
 
 	prop->SetRegisteredAddress(pointer);
 	
@@ -1953,9 +1989,9 @@ void asCScriptEngine::FreeUnusedGlobalProperties()
 }
 
 // interface
-int asCScriptEngine::GetGlobalPropertyCount() const
+asUINT asCScriptEngine::GetGlobalPropertyCount() const
 {
-	return (int)registeredGlobalProps.GetLength();
+	return registeredGlobalProps.GetLength();
 }
 
 // interface
@@ -2057,6 +2093,7 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
 
 	func->id = GetNextScriptFunctionId();
 	func->objectType->methods.PushLast(func->id);
+	func->accessMask = defaultAccessMask;
 	SetScriptFunction(func);
 
 	// TODO: This code is repeated in many places
@@ -2160,6 +2197,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 	SetScriptFunction(func);
 
 	currentGroup->scriptFunctions.PushLast(func);
+	func->accessMask = defaultAccessMask;
 	registeredGlobalFuncs.PushLast(func);
 
 	// If parameter type from other groups are used, add references
@@ -2182,9 +2220,9 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
 }
 
 // interface
-int asCScriptEngine::GetGlobalFunctionCount() const
+asUINT asCScriptEngine::GetGlobalFunctionCount() const
 {
-	return (int)registeredGlobalFuncs.GetLength();
+	return registeredGlobalFuncs.GetLength();
 }
 
 // interface
@@ -2196,8 +2234,59 @@ int asCScriptEngine::GetGlobalFunctionIdByIndex(asUINT index) const
 	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)
@@ -2820,6 +2909,7 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
 void asCScriptEngine::CallObjectMethod(void *obj, int func)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	CallObjectMethod(obj, s->sysFuncIntf, s);
 }
 
@@ -2889,6 +2979,7 @@ void asCScriptEngine::CallObjectMethod(void *obj, asSSystemFunctionInterface *i,
 bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 
 #ifdef __GNUC__
@@ -2956,6 +3047,7 @@ bool asCScriptEngine::CallObjectMethodRetBool(void *obj, int func)
 int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	asSSystemFunctionInterface *i = s->sysFuncIntf;
 
 #ifdef __GNUC__
@@ -3023,12 +3115,14 @@ int asCScriptEngine::CallObjectMethodRetInt(void *obj, int func)
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	return CallGlobalFunctionRetPtr(s->sysFuncIntf, s);
 }
 
 void *asCScriptEngine::CallGlobalFunctionRetPtr(int func, void *param1)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	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)
 {
 	asCScriptFunction *s = scriptFunctions[func];
+	asASSERT( s != 0 );
 	CallObjectMethod(obj, param, s->sysFuncIntf, s);
 }
 
@@ -3346,8 +3441,7 @@ int asCScriptEngine::GetTypeIdByDecl(const char *decl) const
 	return GetTypeIdFromDataType(dt);
 }
 
-
-
+// interface
 const char *asCScriptEngine::GetTypeDeclaration(int typeId) const
 {
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
@@ -3360,6 +3454,7 @@ const char *asCScriptEngine::GetTypeDeclaration(int typeId) const
 	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
 {
 	const asCDataType *dt = GetDataTypeFromTypeId(typeId);
@@ -3369,7 +3464,7 @@ int asCScriptEngine::GetSizeOfPrimitiveType(int typeId) const
 	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)
 {
 	// 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;
 }
 
+// TODO: interface: Should deprecate this. The application should be calling the factory directly
 void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 {
 	void *newObj = CreateScriptObject(typeId);
@@ -3414,6 +3510,21 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, int typeId)
 	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)
 {
 	// 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)
 {
 	// 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)
 {
 	// Make sure it is not a null pointer
@@ -3485,6 +3610,31 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, int typeId)
 		// Call the release behaviour
 		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
 	{
 		// Call the destructor
@@ -3552,7 +3702,7 @@ int asCScriptEngine::EndConfigGroup()
 {
 	// Raise error if trying to end the default config
 	if( currentGroup == &defaultGroup )
-		return asNOT_SUPPORTED;
+		return asERROR;
 
 	currentGroup = &defaultGroup;
 
@@ -3656,6 +3806,8 @@ asCConfigGroup *asCScriptEngine::FindConfigGroupForFuncDef(asCScriptFunction *fu
 	return 0;
 }
 
+#ifdef AS_DEPRECATED
+// deprecated since 2011-10-04
 int asCScriptEngine::SetConfigGroupModuleAccess(const char *groupName, const char *module, bool hasAccess)
 {
 	asCConfigGroup *group = 0;
@@ -3675,6 +3827,15 @@ int asCScriptEngine::SetConfigGroupModuleAccess(const char *groupName, const cha
 
 	return group->SetModuleAccess(module, hasAccess);
 }
+#endif
+
+// interface
+asDWORD asCScriptEngine::SetDefaultAccessMask(asDWORD defaultMask)
+{
+	asDWORD old = defaultAccessMask;
+	defaultAccessMask = defaultMask;
+	return old;
+}
 
 int asCScriptEngine::GetNextScriptFunctionId()
 {
@@ -3790,9 +3951,9 @@ int asCScriptEngine::RegisterFuncdef(const char *decl)
 }
 
 // interface
-int asCScriptEngine::GetFuncdefCount() const
+asUINT asCScriptEngine::GetFuncdefCount() const
 {
-	return (int)registeredFuncDefs.GetLength();
+	return registeredFuncDefs.GetLength();
 }
 
 // interface
@@ -3889,9 +4050,9 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
 }
 
 // interface
-int asCScriptEngine::GetTypedefCount() const
+asUINT asCScriptEngine::GetTypedefCount() const
 {
-	return (int)registeredTypeDefs.GetLength();
+	return registeredTypeDefs.GetLength();
 }
 
 // interface
@@ -3953,7 +4114,7 @@ int asCScriptEngine::RegisterEnum(const char *name)
 	asCDataType dataType;
 	dataType.CreatePrimitive(ttInt, false);
 
-	st->flags = asOBJ_ENUM;
+	st->flags = asOBJ_ENUM | asOBJ_SHARED;
 	st->size = 4;
 	st->name = name;
 
@@ -4008,9 +4169,9 @@ int asCScriptEngine::RegisterEnumValue(const char *typeName, const char *valueNa
 }
 
 // interface
-int asCScriptEngine::GetEnumCount() const
+asUINT asCScriptEngine::GetEnumCount() const
 {
-	return (int)registeredEnums.GetLength();
+	return registeredEnums.GetLength();
 }
 
 // interface
@@ -4064,9 +4225,9 @@ const char *asCScriptEngine::GetEnumValueByIndex(int enumTypeId, asUINT index, i
 }
 
 // interface
-int asCScriptEngine::GetObjectTypeCount() const
+asUINT asCScriptEngine::GetObjectTypeCount() const
 {
-	return (int)registeredObjTypes.GetLength();
+	return registeredObjTypes.GetLength();
 }
 
 // interface
@@ -4093,12 +4254,19 @@ asIObjectType *asCScriptEngine::GetObjectTypeById(int typeId) const
 	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
 {
 	return GetScriptFunction(funcId);
 }
-
+#endif
 
 // internal
 bool asCScriptEngine::IsTemplateType(const char *name) const
@@ -4164,6 +4332,36 @@ int asCScriptEngine::GetScriptSectionNameIndex(const char *name)
 	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
 asSFuncPtr::asSFuncPtr()
 {
@@ -4176,6 +4374,5 @@ asSFuncPtr::asSFuncPtr(asBYTE f)
 	flag = f;
 }
 
-
 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
 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: Should have a CreateModule/GetModule instead of just GetModule with parameters.
@@ -96,16 +92,18 @@ public:
     virtual asIJITCompiler *GetJITCompiler() const;
 
 	// 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
-	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
 	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            RegisterInterface(const char *name);
 	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;
 	
 	// String factory
@@ -129,36 +126,41 @@ public:
 	// Enums
 	virtual int         RegisterEnum(const char *type);
 	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 int         GetEnumValueCount(int enumTypeId) const;
 	virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const;
 
 	// Funcdefs
 	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;
 
 	// Typedefs
 	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;
 
 	// 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);
+#endif
 
 	// Script modules
 	virtual asIScriptModule *GetModule(const char *module, asEGMFlags flag);
 	virtual int              DiscardModule(const char *module);
 
 	// Script functions
+	virtual asIScriptFunction *GetFunctionById(int funcId) const;
+#ifdef AS_DEPRECATED
+	// deprecated since 2011-10-03
 	virtual asIScriptFunction *GetFunctionDescriptorById(int funcId) const;
+#endif
 
 	// Type identification
 	virtual asIObjectType *GetObjectTypeById(int typeId) const;
@@ -172,7 +174,9 @@ public:
 	virtual void             *CreateScriptObjectCopy(void *obj, int typeId);
 	virtual void              CopyScriptObject(void *dstObj, void *srcObj, 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, const asIObjectType *type);
 	virtual bool              IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
 
 	// String interpretation
@@ -181,6 +185,7 @@ public:
 	// Garbage collection
 	virtual int  GarbageCollect(asDWORD flags = asGC_FULL_CYCLE);
 	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 GCEnumCallback(void *reference);
 
@@ -188,8 +193,10 @@ public:
 	virtual void *SetUserData(void *data);
 	virtual void *GetUserData() const;
 	virtual void  SetEngineUserDataCleanupCallback(asCLEANENGINEFUNC_t callback);
+	virtual void  SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback);
 	virtual void  SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback);
 	virtual void  SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback);
+	virtual void  SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback);
 
 //===========================================================
 // internal methods
@@ -228,6 +235,8 @@ public:
 	void  CallGlobalFunction(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 RemoveTemplateInstanceType(asCObjectType *t);
 	void RemoveTypeAndRelatedFromList(asCArray<asCObjectType*> &types, asCObjectType *ot);
@@ -249,9 +258,9 @@ public:
 
 	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 *GetModuleFromFuncId(int funcId);
@@ -357,6 +366,7 @@ public:
 	asCConfigGroup             defaultGroup;
 	asCArray<asCConfigGroup*>  configGroups;
 	asCConfigGroup            *currentGroup;
+	asDWORD                    defaultAccessMask;
 
 	// Message callback
 	bool                        msgCallback;
@@ -369,10 +379,12 @@ public:
 	asCArray<asCString*>        stringConstants;
 
 	// 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
 	DECLARECRITICALSECTION(engineCritical);
@@ -396,6 +408,7 @@ public:
 		int  propertyAccessorMode;
 		bool expandDefaultArrayToTemplate;
 		bool autoGarbageCollect;
+		bool disallowGlobalVars;
 	} ep;
 };
 

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

@@ -143,6 +143,8 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
 	gcFlag                 = false;
 	userData               = 0;
 	id                     = 0;
+	accessMask             = 0xFFFFFFFF;
+	isShared               = false;
 
 	// TODO: optimize: The engine could notify the GC just before it wants to
 	//                 discard the function. That way the GC won't waste time
@@ -215,24 +217,6 @@ int asCScriptFunction::Release() const
 	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
 const char *asCScriptFunction::GetModuleName() const
 {
@@ -294,6 +278,17 @@ int asCScriptFunction::GetSpaceNeededForReturnValue()
 	return returnType.GetSizeOnStackDWords();
 }
 
+// internal
+bool asCScriptFunction::DoesReturnOnStack() const
+{
+	if( returnType.GetObjectType() &&
+		(returnType.GetObjectType()->flags & asOBJ_VALUE) &&
+		!returnType.IsReference() )
+		return true;
+		
+	return false;
+}
+
 // internal
 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
 

+ 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 
 //       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);
 
 class asCScriptFunction : public asIScriptFunction
@@ -109,6 +114,7 @@ public:
 	const char          *GetConfigGroup() const;
 	bool                 IsReadOnly() const;
 	bool                 IsPrivate() const;
+	// TODO: access: Get/Set access mask for function
 
 	asUINT               GetParamCount() const;
 	int                  GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
@@ -144,11 +150,15 @@ public:
 	bool      IsSignatureEqual(const asCScriptFunction *func) const;
 	bool      IsSignatureExceptNameEqual(const asCScriptFunction *func) const;
 
-    void      JITCompile();
+	bool      DoesReturnOnStack() const;
+
+	void      JITCompile();
 
 	void      AddReferences();
 	void      ReleaseReferences();
 
+	bool      IsShared() const;
+
 	asCGlobalProperty *GetPropertyByGlobalVarPtr(void *gvarPtr);
 
 	// GC methods
@@ -183,6 +193,8 @@ public:
 	int                          id;
 
 	asEFuncType                  funcType;
+	asDWORD                      accessMask;
+	bool                         isShared;
 
 	// Used by asFUNC_SCRIPT
 	asCArray<asDWORD>               byteCode;

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

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -37,7 +37,7 @@
 BEGIN_AS_NAMESPACE
 
 // 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;
 
@@ -339,10 +339,9 @@ int asCScriptObject::GetTypeId() const
 	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

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

@@ -1,6 +1,6 @@
 /*
    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 
    warranty. In no event will the authors be held liable for any 
@@ -68,7 +68,7 @@ public:
 	asIObjectType *GetObjectType() const;
 
 	// Class properties
-	int         GetPropertyCount() const;
+	asUINT      GetPropertyCount() const;
 	int         GetPropertyTypeId(asUINT prop) const;
 	const char *GetPropertyName(asUINT prop) const;
 	void       *GetAddressOfProperty(asUINT prop);
@@ -115,7 +115,7 @@ void ScriptObject_Assignment_Generic(asIScriptGeneric *gen);
 
 void RegisterScriptObject(asCScriptEngine *engine);
 
-asIScriptObject *ScriptObjectFactory(asCObjectType *objType, asCScriptEngine *engine);
+asIScriptObject *ScriptObjectFactory(const asCObjectType *objType, asCScriptEngine *engine);
 
 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_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_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_DEFAULT_ARRAY_TYPE                  "The application doesn't support the default array type."
 #define TXT_NO_DEFAULT_CONSTRUCTOR_FOR_s           "No default constructor for object of type '%s'."
-#define TXT_NO_DEFAULT_COPY_OP                     "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_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"
@@ -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_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_STRINGS_NOT_RECOGNIZED                     "Strings are not recognized by the application"
 #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_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_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
 

+ 5 - 4
ThirdParty/AngelScript/source/as_tokendef.h

@@ -1,6 +1,6 @@
 /*
    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 
    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";
 
 // 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