ecere/com/instance: Commented out code testing Template fixes
[sdk] / ecere / src / com / instance.ec
index ce30d12..67aa56e 100644 (file)
@@ -1,5 +1,7 @@
 namespace com;
 
+// #define DISABLE_MEMMGR
+
 import "BinaryTree"
 import "OldList"
 import "String"
@@ -32,10 +34,11 @@ import "Mutex"
 #ifdef MEMINFO
 import "Thread"
 static define MAX_MEMORY_LOC = 40;
+static define MAX_STACK_FRAMES = 1000;
 
 static class MemStack : BTNode
 {
-   const char * frames[1000];
+   const char * frames[MAX_STACK_FRAMES];
    int pos;
    bool recurse;
 };
@@ -48,6 +51,28 @@ static uint memoryErrorsCount = 0;
 default:
 #define property _property
 
+#if defined(DISABLE_MEMMGR)
+
+#ifndef ECERE_BOOTSTRAP
+# include <malloc.h>
+#endif
+
+#if defined(__WIN32__)
+#ifdef ECERE_BOOTSTRAP
+uintsize _msize(void * p);
+#endif
+
+#  define msize _msize
+#else
+#ifdef ECERE_BOOTSTRAP
+uintsize malloc_usable_size(void * p);
+#endif
+
+#  define msize malloc_usable_size
+#endif
+
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 
@@ -81,6 +106,9 @@ default:
 extern int __ecereVMethodID_class_OnGetDataFromString;
 
 // IMPLEMENTATION FOR THESE IN _instance.c:
+#if defined(__MINGW32__) && !defined(_W64) && __GNUC__ < 4
+dllexport int isblank(int c);
+#endif
 bool Instance_LocateModule(const char * name, const char * fileName);
 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, const char *** argvPtr);
 void * Instance_Module_Load(const char * libLocation, const char * name, void ** Load, void ** Unload);
@@ -93,7 +121,7 @@ private:
 
 public class Angle : double;
 
-public class unichar : uint32
+public class ::unichar : uint32
 {
 
    const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
@@ -111,6 +139,11 @@ public class unichar : uint32
 
 };
 
+// Forward declarations to hook on to libec:
+class ::Type;
+class ::Instantiation;
+class ::ClassDefinition;
+
 public class Property : struct
 {
 public:
@@ -153,10 +186,8 @@ public dllexport void MemoryGuard_PushLoc(const char * loc)
       stack.key = GetCurrentThreadID();
       memStacks.Add(stack);
    }
-   if(stack.pos < 1000)
+   if(stack.pos < MAX_STACK_FRAMES)
       stack.frames[stack.pos++] = loc;
-   else
-      printf("");
    memMutex.Release();
 #endif
 }
@@ -171,8 +202,6 @@ public dllexport void MemoryGuard_PopLoc()
    {
       stack.pos--;
    }
-   else
-      printf("");
    memMutex.Release();
 #endif
 }
@@ -224,7 +253,7 @@ class SelfWatcher : struct
 {
    class_fixed
    SelfWatcher prev, next;
-   void (*callback)(Instance);
+   void (*callback)(void *);
    Property _property;
 };
 
@@ -267,10 +296,10 @@ public:
    Class prev, next;
    const char * name;
    int offset, structSize;
-   int (** _vTbl)();
+   void ** _vTbl;
    int vTblSize;
-   int (*Constructor)(Instance);
-   void (*Destructor)(Instance);
+   bool (*Constructor)(void *);
+   void (*Destructor)(void *);
 
    int offsetClass, sizeClass;
    Class base;
@@ -302,7 +331,7 @@ public:
    bool internalDecl;
    void * data;
    bool computeSize;
-   int structAlignment;
+   short structAlignment; short pointerAlignment;
    int destructionWatchOffset;
    bool fixed;
    OldList delayedCPValues;
@@ -535,7 +564,7 @@ public:
    OldList members;
    BinaryTree membersAlpha;
    int memberOffset;
-   int structAlignment;
+   short structAlignment; short pointerAlignment;
 };
 
 public class BitMember : struct
@@ -601,14 +630,14 @@ public class EnumClassData : struct
 public:
    class_fixed
    OldList values;
-   int largest;
+   int64 largest;
 };
 
 class Watcher : struct
 {
    class_fixed
    Watcher prev, next;
-   void (*callback)(Instance, Instance);
+   void (*callback)(void *, void *);
    Instance object;
 };
 
@@ -628,8 +657,8 @@ static class MemInfo : BTNode //struct
    bool freed;
    const char * _class;
    uint id;
-   const char * allocLoc[MAX_MEMORY_LOC];
-   const char * freeLoc[MAX_MEMORY_LOC];
+   char * allocLoc[MAX_MEMORY_LOC];
+   char * freeLoc[MAX_MEMORY_LOC];
    bool internal;
 
    void OutputStacks(bool showFree)
@@ -663,13 +692,15 @@ static BinaryTree memBlocks;
 bool recurse = false;
 static int blockID;
 //Class allocateClass;
-const char * allocateClass;
+char * allocateClass;
 bool allocateInternal;
 
 #endif
 
 static uint TOTAL_MEM = 0;
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static uint OUTSIDE_MEM = 0;
+#endif
 
 #if !defined(ECERE_BOOTSTRAP)
 static Mutex memMutex { };
@@ -1046,6 +1077,7 @@ private struct BlockPool
    }
 };
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static BlockPool * pools; //[NUM_POOLS];
 
 /*static uint PosFibonacci(uint number)
@@ -1096,6 +1128,7 @@ static uint NextFibonacci(uint number)
    }
 }
 */
+
 static uint log1_5i(uint number)
 {
    uint pos;
@@ -1137,6 +1170,7 @@ static uint pow1_5i(uint number)
    }
    return (uint)current;
 }
+#endif
 
 // -- Math Helpers ---
 public uint log2i(uint number)
@@ -1154,6 +1188,7 @@ public uint pow2i(uint number)
    return 1<<log2i(number);
 }
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static bool memoryInitialized = false;
 static void InitMemory()
 {
@@ -1177,7 +1212,9 @@ static void InitMemory()
          pools[c].Expand(Max(1, expansion));
    }
 }
+#endif
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static void * _mymalloc(unsigned int size)
 {
    MemBlock block = null;
@@ -1217,6 +1254,7 @@ static void * _mycalloc(int n, unsigned int size)
    return pointer;
 }
 
+
 static void _myfree(void * pointer)
 {
    if(pointer)
@@ -1270,6 +1308,7 @@ static void * _myrealloc(void * pointer, unsigned int size)
             TOTAL_MEM += size - newBlock.size;
             OUTSIDE_MEM += size - newBlock.size;
             newPointer = ((struct MemBlock *)newBlock + 1);
+            newBlock.size = size;
          }
       }
    }
@@ -1347,7 +1386,6 @@ static void * _mycrealloc(void * pointer, unsigned int size)
    return newPointer;
 }
 
-#ifndef MEMINFO
 #undef realloc
 #undef crealloc
 #undef malloc
@@ -1363,8 +1401,12 @@ static void * _mycrealloc(void * pointer, unsigned int size)
 
 static void * _malloc(unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   return size ? malloc(size) : null;
+#else
    void * pointer;
 
+
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Wait();
 #endif
@@ -1420,11 +1462,16 @@ static void * _malloc(unsigned int size)
    }
 #endif
    return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _calloc(int n, unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   return size ? calloc(n, size) : null;
+#else
    void * pointer;
+
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Wait();
 #endif
@@ -1479,11 +1526,18 @@ static void * _calloc(int n, unsigned int size)
    }
 #endif
    return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _realloc(void * pointer, unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   if(!size) { free(pointer); return null; }
+   return realloc(pointer, size);
+
+#else
    if(!size) { _free(pointer); return null; }
+
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Wait();
 #endif
@@ -1571,11 +1625,23 @@ static void * _realloc(void * pointer, unsigned int size)
    memMutex.Release();
 #endif
    return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _crealloc(void * pointer, unsigned int size)
 {
-   if(!size) return null;
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   uintsize s = pointer ? msize(pointer) : 0;
+   void * p;
+   if(!size) { free(pointer); return null; }
+
+   p = realloc(pointer, size);
+   if(size > s)
+      memset((byte *)p + s, 0, size - s);
+   return p;
+#else
+   if(!size) { _free(pointer); return null; }
+
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Wait();
 #endif
@@ -1663,12 +1729,16 @@ static void * _crealloc(void * pointer, unsigned int size)
    memMutex.Release();
 #endif
    return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
 }
 
 static void _free(void * pointer)
 {
    if(pointer)
    {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+      free(pointer);
+#else
 #if !defined(ECERE_BOOTSTRAP)
       if(memMutex != pointer) memMutex.Wait();
 #endif
@@ -1742,13 +1812,13 @@ static void _free(void * pointer)
                {
                   if(address[-c-1] != 0xAB)
                   {
-                     printf("Buffer Underrun\n");
+                     printf("Buffer Underrun (%d bytes before)\n", c+1);
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
                   if(address[c + size] != 0xAB)
                   {
-                     printf("Buffer Overrun\n");
+                     printf("Buffer Overrun (%d bytes past block)\n", c);
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
@@ -1776,6 +1846,8 @@ static void _free(void * pointer)
 #if !defined(ECERE_BOOTSTRAP)
       if(memMutex != pointer) memMutex.Release();
 #endif
+
+#endif
    }
 }
 
@@ -1794,6 +1866,14 @@ public void memswap(byte * a, byte * b, uint size)
    }
 }
 
+public void CheckConsistency()
+{
+#ifdef MEMINFO
+   if(!memBlocks.Check())
+      printf("Memory Blocks Tree Integrity Failed\n");
+#endif
+}
+
 public void CheckMemory()
 {
 #ifdef MEMINFO
@@ -1858,7 +1938,7 @@ public void CheckMemory()
       }
    }
 
-   while(block = (MemInfo)memBlocks.root)
+   while((block = (MemInfo)memBlocks.root))
    {
       byte * address;
       int c;
@@ -1884,13 +1964,13 @@ public void CheckMemory()
       {
          if(address[-c-1] != 0xAB)
          {
-            printf("Buffer Underrun\n");
+            printf("Buffer Underrun (%d bytes before)\n", c + 1);
             memoryErrorsCount++;
             block.OutputStacks(block.freed);
          }
          if(address[c + size] != 0xAB)
          {
-            printf("Buffer Overrun\n");
+            printf("Buffer Overrun (%d bytes past)\n", c);
             memoryErrorsCount++;
             block.OutputStacks(block.freed);
          }
@@ -1906,7 +1986,7 @@ public void CheckMemory()
    printf("Memory Check Completed.\n");
 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
    if(memoryErrorsCount)
-      getch();
+      system("pause");
 #endif
 #endif
 }
@@ -1970,7 +2050,10 @@ static void FixDerivativesBase(Class base, Class mod)
       // _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
 
       if(type == normalClass || type == noHeadClass)
-         _class.offset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+         // Use 'memberOffset' for nohead class as the members get added without padding
+         _class.offset = (base && (base.templateClass ? (type == normalClass ? base.templateClass.structSize : base.templateClass.memberOffset) : (type == normalClass ? base.structSize : base.memberOffset)) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+      else
+         _class.offset = 0; // Force set to 0
 
       if(type == structClass)
       {
@@ -2198,7 +2281,7 @@ static void FixDerivativesBase(Class base, Class mod)
 }
 
 public dllexport Class eSystem_RegisterClass(ClassType type, const char * name, const char * baseName, int size, int sizeClass,
-                             bool (* Constructor)(void *),void (* Destructor)(void *),
+                             bool (* Constructor)(void *), void (* Destructor)(void *),
                              Module module, AccessMode declMode, AccessMode inheritanceAccess)
 {
    int start = 0, c;
@@ -2628,7 +2711,11 @@ public dllexport Class eSystem_RegisterClass(ClassType type, const char * name,
          }
          _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
          if(type == normalClass || type == noHeadClass)
-            _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+            _class.offset = (base && base.structSize && base.type != systemClass) ?
+               // Use 'memberOffset' for nohead class as the members get added without padding
+               (base.type == normalClass ? base.structSize : base.memberOffset) : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+         else
+            _class.offset = 0;   // Force set to 0 for redefinitions
 
          // For cross-bitness-compiling
          if(crossBits)
@@ -2657,6 +2744,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, const char * name,
                {
                   size = 3*(force32Bits ? 4 : 8);
                   _class.structAlignment = force32Bits ? 4 : 8;   // FileListing is problematic because it is a struct with private data that the user allocates
+                  _class.pointerAlignment = 1;
                }
                // These we want to recompute inside the IDE to help the debugger
                else if(!strcmp(name, "ecere::com::Class"))           size = 0; // 616
@@ -2668,6 +2756,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, const char * name,
                else if(!strcmp(name, "ecere::sys::OldList"))         size = 0; // 32
                else if(!strcmp(name, "ecere::sys::Item"))            size = 0;
                else if(!strcmp(name, "ecere::sys::NamedLink"))       size = 0;
+               else if(!strcmp(name, "ecere::sys::NamedLink64"))     size = 0;
                else if(!strcmp(name, "ecere::sys::OldLink"))         size = 0;
                else if(!strcmp(name, "ecere::sys::NamedItem"))       size = 0;
                else if(!strcmp(name, "ecere::sys::NamedItem64"))     size = 0;
@@ -2700,7 +2789,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, const char * name,
          }
          _class.offsetClass = offsetClass;
          _class.sizeClass = totalSizeClass;
-         _class.Constructor = (void *)Constructor;
+         _class.Constructor = Constructor;
          _class.Destructor = Destructor;
          if(_class.type != systemClass)
             _class.type = type;
@@ -2787,7 +2876,7 @@ static void DataMember_Free(DataMember parentMember)
    }
 }
 
-static void FreeEnumValue(NamedLink value)
+static void FreeEnumValue(NamedLink64 value)
 {
    delete value.name;
 }
@@ -2854,7 +2943,8 @@ static void FreeTemplate(Class template)
    if(template.nameSpace)
    {
       BTNamedLink link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
-      template.nameSpace->classes.Delete((BTNode)link);
+      if(link)
+         template.nameSpace->classes.Delete((BTNode)link);
    }
    FreeTemplateArgs(template);
 
@@ -2904,6 +2994,22 @@ public dllexport void eClass_Unregister(Class _class)
    ClassProperty classProp;
    ClassTemplateParameter param;
 
+   if(_class.templateClass)
+   {
+      // Unregistering templates... Used in IDE to address crash on Ecere classes templatized with imported modules
+      OldLink templateLink;
+      for(templateLink = _class.templateClass.templatized.first; templateLink; templateLink = templateLink.next)
+      {
+         if(templateLink.data == _class)
+         {
+            _class.templateClass.templatized.Delete(templateLink);
+            break;
+         }
+      }
+      FreeTemplate(_class);
+      return;
+   }
+
    delete _class._vTbl;
 
    FreeTemplates(_class);
@@ -4065,7 +4171,7 @@ public dllexport Method eClass_AddMethod(Class _class, const char * name, const
                if(method.vid >= _class.vTblSize)
                   printf("error: virtual methods overriding failure\n");
                else
-                  _class._vTbl[method.vid] = function ? function : DefaultFunction;
+                  _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
                for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
                {
                   Class derivClass = deriv.data;
@@ -4134,7 +4240,7 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, const char * name,
                if(method.vid >= _class.vTblSize)
                   printf("error: virtual methods overriding failure\n");
                else
-                  _class._vTbl[method.vid] = function ? function : DefaultFunction;
+                  _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
             }
             else
                base = null;
@@ -4156,7 +4262,7 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, const char * name,
          };
          _class.methods.Add((BTNode)method);
          _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
-         _class._vTbl[method.vid] = function ? function : DefaultFunction;
+         _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
 
          // TODO: Fix derived classes
          if(_class.derivatives.first || _class.templatized.first)
@@ -5014,7 +5120,7 @@ public dllexport void eInstance_SetMethod(Instance instance, const char * name,
                memcpy(instance._vTbl, instance._class._vTbl,
                   sizeof(int(*)()) * instance._class.vTblSize);
             }
-            instance._vTbl[method.vid] = function ? function : DefaultFunction;
+            instance._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
          }
       }
    }
@@ -5071,7 +5177,7 @@ public dllexport void eClass_Resize(Class _class, int newSize)
    for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
       FixOffsets(deriv.data);
 }
-
+                                                                                                                        // F000F000 will mean a pointer size alignment
 public dllexport DataMember eClass_AddDataMember(Class _class, const char * name, const char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
 {
    if(_class && name)
@@ -5082,6 +5188,30 @@ public dllexport DataMember eClass_AddDataMember(Class _class, const char * name
 
          if(alignment)
          {
+            bool pointerAlignment = alignment == 0xF000F000;
+            bool force64Bits = (_class.module.application.isGUIApp & 2) ? true : false;
+            bool force32Bits = (_class.module.application.isGUIApp & 4) ? true : false;
+            if((force32Bits || force64Bits) && !strcmp(_class.name, "AVLNode") && !strcmp(name, "__ecerePrivateData0"))
+            {
+               if(force64Bits)
+               {
+                  type = "byte[32]";
+                  size = 32;
+               }
+               if(force32Bits)
+               {
+                  type = "byte[16]";
+                  size = 16;
+               }
+            }
+
+            if(pointerAlignment) alignment = sizeof(void *);
+
+            if(pointerAlignment && _class.structAlignment <= 4)
+               _class.pointerAlignment = 1;
+            else if(!pointerAlignment && alignment >= 8)
+               _class.pointerAlignment = 0;
+
             _class.structAlignment = Max(_class.structAlignment, alignment);
 
             if(_class.memberOffset % alignment)
@@ -5107,7 +5237,7 @@ public dllexport DataMember eClass_AddDataMember(Class _class, const char * name
    }
    return null;
 }
-
+                                                                                                                              // F000F000 will mean a pointer size alignment
 public dllexport DataMember eMember_AddDataMember(DataMember member, const char * name, const char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
 {
    if(name && !member.membersAlpha.FindString(name))
@@ -5116,6 +5246,14 @@ public dllexport DataMember eMember_AddDataMember(DataMember member, const char
 
       if(alignment)
       {
+         bool pointerAlignment = alignment == 0xF000F000;
+         if(pointerAlignment) alignment = sizeof(void *);
+
+         if(pointerAlignment && member.structAlignment <= 4)
+            member.pointerAlignment = 1;
+         else if(!pointerAlignment && alignment >= 8)
+            member.pointerAlignment = 0;
+
          member.structAlignment = Max(member.structAlignment, alignment);
 
          if(member.memberOffset % alignment)
@@ -5180,13 +5318,17 @@ public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
    else
       addTo.memberID += dataMember.memberID;
 
+   if(dataMember.pointerAlignment && dataMember.structAlignment <= 4)
+      addTo.pointerAlignment = 1;
+   else if(!dataMember.pointerAlignment && dataMember.structAlignment >= 8)
+      addTo.pointerAlignment = 0;
+
    addTo.structAlignment = Max(addTo.structAlignment, dataMember.structAlignment);
+
    dataMember.offset = (addTo.type == unionMember) ? 0 : addTo.memberOffset;
 
    if(dataMember.structAlignment)
    {
-      addTo.structAlignment = Max(addTo.structAlignment, dataMember.structAlignment);
-
       if(addTo.memberOffset % dataMember.structAlignment)
          addTo.memberOffset += dataMember.structAlignment - (addTo.memberOffset % dataMember.structAlignment);
    }
@@ -5220,6 +5362,11 @@ public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
    //dataMember.id = _class.memberID++;
    dataMember.id = _class.memberID;
 
+   if(dataMember.pointerAlignment && dataMember.structAlignment <= 4)
+      _class.pointerAlignment = 1;
+   else if(!dataMember.pointerAlignment && dataMember.structAlignment >= 8)
+      _class.pointerAlignment = 0;
+
    _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
    if(dataMember.type == unionMember)
       _class.memberID += 1;
@@ -5228,8 +5375,6 @@ public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
 
    if(dataMember.structAlignment)
    {
-      _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
-
       if(_class.memberOffset % dataMember.structAlignment)
          _class.memberOffset += dataMember.structAlignment - (_class.memberOffset % dataMember.structAlignment);
    }
@@ -5304,7 +5449,7 @@ static Module Module_Load(Module fromModule, const char * name, AccessMode impor
       }
       else
       {
-         char * libLocation = null;
+         const char * libLocation = null;
 #if defined(__ANDROID__)
          libLocation = AndroidInterface_GetLibLocation();
 #endif
@@ -5344,7 +5489,7 @@ static Module Module_Load(Module fromModule, const char * name, AccessMode impor
    {
       name = !strcmp(module.name, "ecereCOM") ? "ecere" : "ecereCOM";
       if((!Load && !strcmp(module.name, "ecereCOM")) ||
-         (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != COM_LOAD_FUNCTION))
+         (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != (void *)COM_LOAD_FUNCTION))
       {
          Module module;
          for(module = fromModule.application.allModules.first; module; module = module.next)
@@ -5456,38 +5601,38 @@ public dllexport void eModule_Unload(Module fromModule, Module module)
    }
 }
 
-public dllexport void eEnum_AddFixedValue(Class _class, const char * string, int value)
+public dllexport void eEnum_AddFixedValue(Class _class, const char * string, int64 value)
 {
    if(_class && _class.type == enumClass)
    {
       EnumClassData data = (EnumClassData)_class.data;
-      NamedLink item;
+      NamedLink64 item;
 
       for(item = data.values.first; item; item = item.next)
          if(!strcmp(item.name, string))
             break;
       if(!item)
       {
-         data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
+         data.values.Add(NamedLink64 { data = value, name = CopyString(string) });
          if(value > data.largest)
             data.largest = value;
       }
    }
 }
 
-public dllexport int eEnum_AddValue(Class _class, const char * string)
+public dllexport int64 eEnum_AddValue(Class _class, const char * string)
 {
    if(_class && _class.type == enumClass)
    {
       EnumClassData data = (EnumClassData)_class.data;
-      int value = ((int) data.largest) + 1;
-      NamedLink item;
+      int64 value = data.largest + 1;
+      NamedLink64 item;
       for(item = data.values.first; item; item = item.next)
          if(!strcmp(item.name, string))
             break;
       if(!item)
       {
-         data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
+         data.values.Add(NamedLink64 { data = value, name = CopyString(string) });
          if(value > data.largest)
             data.largest = value;
          return value;
@@ -5501,6 +5646,19 @@ static void NameSpace_Free(NameSpace parentNameSpace)
    NameSpace * nameSpace;
    delete (void *)parentNameSpace.name;
 
+         /*   {
+      BTNamedLink n, next;
+      for(n = (BTNamedLink)parentNameSpace.classes.first; n; n = next)
+      {
+         Class c = n.data;
+
+         next = (BTNamedLink)((BTNode)n).next;
+
+         if(c.templateClass)
+            eClass_Unregister(c);
+      }
+   }         */
+
    while((nameSpace = (NameSpace *)parentNameSpace.nameSpaces.first))
    {
       NameSpace_Free(nameSpace);
@@ -5512,7 +5670,7 @@ static void Application_Destructor(Application app)
 {
    if(app.parsedCommand)
    {
-      delete app.argv;
+      delete (void *)app.argv;
       delete app.parsedCommand;
    }
 }
@@ -5598,17 +5756,26 @@ static void Module_Destructor(Module module)
       if(_class.nameSpace)
       {
          BTNamedLink classLink = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
-         OldLink t;
-         for(t = _class.templatized.first; t; t = t.next)
+         if(classLink)
          {
-            Class template = t.data;
-            BTNamedLink link;
-            link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
+            OldLink t;
+            for(t = _class.templatized.first; t; t = t.next)
+            {
+               Class template = t.data;
+               BTNamedLink link;
+               link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
 
-            template.nameSpace->classes.Delete((BTNode)link);
-            template.nameSpace = null;
+               template.nameSpace->classes.Delete((BTNode)link);
+               template.nameSpace = null;
+            }
+            _class.nameSpace->classes.Delete((BTNode)classLink);
          }
-         _class.nameSpace->classes.Delete((BTNode)classLink);
+#ifdef _DEBUG
+         else
+         {
+            printf("Warning: Could not find %s in namespace classes while destructing module %s\n", _class.name, module.name);
+         }
+#endif
          _class.nameSpace = null;
       }
       _class.module = null;
@@ -5979,7 +6146,7 @@ public dllexport void eInstance_Watch(void * instance, Property _property, void
    }
 }
 
-public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(Instance, Instance))
+public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(void *, void *))
 {
    OldList * watchers = (OldList *)((byte *)instance + instance._class.destructionWatchOffset);
    watchers->Add(Watcher { callback = callback, object = object });
@@ -6061,6 +6228,36 @@ public bool LocateModule(const char * name, const char * fileName)
    return Instance_LocateModule(name, fileName);
 }
 
+/*
+#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__)
+#define _64BIT 1
+#else
+#define _64BIT 0
+#endif
+
+#define arch_PointerSize                  sizeof(void *)
+#define structSize_Instance               (_64BIT ? 24 : 12)
+#define structSize_Module                 (_64BIT ? 560 : 300)
+#define structSize_BinaryTree             (_64BIT ? 32 : 16)
+#define structSize_OldList                (_64BIT ? 32 : 20)
+#define structSize_NamedLink64            (_64BIT ? 32 : 24)
+#define structSize_ClassTemplateArgument  (_64BIT ? 16 : 8)
+#define structSize_ClassTemplateParameter (_64BIT ? 64 : 40)
+#define structSize_OldLink                (_64BIT ? 24 : 12)
+#define structSize_BTNamedLink            (_64BIT ? 48 : 24)
+#define structSize_Application            (_64BIT ? 800 : 428)
+#define structSize_Watcher                (_64BIT ? 32 : 16)
+#define structSize_SelfWatcher            (_64BIT ? 32 : 16)
+#define structSize_GlobalFunction         (_64BIT ? 72 : 36)
+#define structSize_DefinedExpression      (_64BIT ? 40 : 20)
+#define structSize_BitMember              (_64BIT ? 96 : 64)
+#define structSize_DataMember             (_64BIT ? 160 : 96)
+#define structSize_ClassProperty          (_64BIT ? 80 : 40)
+#define structSize_Method                 (_64BIT ? 96 : 52)
+#define structSize_Property               (_64BIT ? 152 : 88)
+#define structSize_Class                  (_64BIT ? 624 : 376)
+*/
+
 static void LoadCOM(Module module)
 {
    bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
@@ -6090,7 +6287,7 @@ static void LoadCOM(Module module)
       instanceClass.memberID = -3;
       instanceClass.startMemberID = -3;
 
-      eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", pointerSize, pointerSize, publicAccess);
+      eClass_AddDataMember(instanceClass, "_vTbl", "void **", pointerSize, pointerSize, publicAccess);
       eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", pointerSize, pointerSize, publicAccess);
       eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int), sizeof(int), publicAccess);
    }
@@ -6199,12 +6396,12 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("qsort", "void qsort(void *, uintsize, uintsize, int (*)(void *, void *))", qsort, module, baseSystemAccess);
    eSystem_RegisterFunction("strtod", "double strtod(const char*, char**)", strtod, module, baseSystemAccess);
    eSystem_RegisterFunction("strtol", "int strtol(const char*, char**, int base)", strtol, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoll", "int64 strtoll(const char * nptr, char ** endptr, int base)", strtoll, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoull", "uint64 strtoull(const char * nptr, char ** endptr, int base)", strtoull, module, baseSystemAccess);
    eSystem_RegisterFunction("system", "int system(const char*)", system, module, baseSystemAccess);
    eSystem_RegisterFunction("atoi", "int atoi(const char*)", atoi, module, baseSystemAccess);
    eSystem_RegisterFunction("atof", "double atof(const char*)", atof, module, baseSystemAccess);
-   eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
-   eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
-   eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
    eSystem_RegisterFunction("memset", "void * memset(void * area, int value, uintsize count)", memset, module, baseSystemAccess);
    eSystem_RegisterFunction("getenv", "char * getenv(const char * name)", getenv, module, baseSystemAccess);
    eSystem_RegisterFunction("rename", "int rename(const char *oldpath, const char *newpath)", rename, module, baseSystemAccess);
@@ -6219,7 +6416,7 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("strcspn", "uintsize strcspn(const char *, const char *)", strcspn, module, baseSystemAccess);
    eSystem_RegisterFunction("strpbrk", "char * strpbrk(const char *, const char *)", strpbrk, module, baseSystemAccess);
 
-   eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
+   eSystem_RegisterDefine("fstrcmp", "(__runtimePlatform == win32) ? strcmpi : strcmp", module, baseSystemAccess);
 
 //#if defined(__GNUC__)
    eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
@@ -6255,15 +6452,17 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("fputs", "int fputs(const char *, void * stream)", fputs, module, baseSystemAccess);
 
    // --- Ctype ---
+   eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
+   eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
+   eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
+   eSystem_RegisterFunction("isxdigit","bool isxdigit(int)", isxdigit, module, baseSystemAccess);
    eSystem_RegisterFunction("isalnum", "int isalnum(int c)", isalnum, module, baseSystemAccess);
    eSystem_RegisterFunction("isspace", "int isspace(int c)", isspace, module, baseSystemAccess);
    eSystem_RegisterFunction("isalpha", "int isalpha(int c)", isalpha, module, baseSystemAccess);
    eSystem_RegisterFunction("islower", "int islower(int c)", islower, module, baseSystemAccess);
    eSystem_RegisterFunction("isupper", "int isupper(int c)", isupper, module, baseSystemAccess);
    eSystem_RegisterFunction("isprint", "int isprint(int c)", isprint, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoll", "int64 strtoll(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoull", "uint64 strtoull(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
+   eSystem_RegisterFunction("isblank", "int isblank(int c)", isblank, module, baseSystemAccess);
 
 }
 
@@ -6666,6 +6865,7 @@ public int ISO8859_1toUTF8(const char * source, char * dest, int max)
 {
    int c;
    int d = 0;
+   byte * byteDest = (byte *)dest;
    for(c = 0; source[c]; c++)
    {
       unichar ch = ((byte *)source)[c];
@@ -6676,28 +6876,28 @@ public int ISO8859_1toUTF8(const char * source, char * dest, int max)
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
    dest[d] = 0;
@@ -6709,12 +6909,12 @@ public char * UTF16toUTF8(const uint16 * source)
    int c;
    int d = 0;
    int len;
-   char * dest;
+   byte * dest;
    uint16 u16;
    bool invert = false;
 
    for(len = 0; source[len]; len++);
-   dest = new char[len * 3 + 1];
+   dest = new byte[len * 3 + 1];
    for(c = 0; (u16 = source[c]); c++)
    {
       unichar ch;
@@ -6754,8 +6954,8 @@ public char * UTF16toUTF8(const uint16 * source)
       }
    }
    dest[d] = 0;
-   dest = renew dest char[d+1];
-   return dest;
+   dest = renew dest byte[d+1];
+   return (char *)dest;
 }
 
 public int UTF16toUTF8Buffer(const uint16 * source, char * dest, int max)
@@ -6763,6 +6963,7 @@ public int UTF16toUTF8Buffer(const uint16 * source, char * dest, int max)
    int c;
    int d = 0;
    uint16 u16;
+   byte * byteDest = (byte *)dest;
    for(c = 0; (u16 = source[c]); c++)
    {
       unichar ch;
@@ -6774,31 +6975,31 @@ public int UTF16toUTF8Buffer(const uint16 * source, char * dest, int max)
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
-   dest[d] = 0;
+   byteDest[d] = 0;
    return d;
 }
 
@@ -6895,7 +7096,7 @@ public int UTF8toUTF16Buffer(const char * source, uint16 * dest, int max)
          if(codePoint > 0xFFFF)
          {
             uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
-            uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
+            uint16 trail = (uint16)(0xDC00 | (codePoint & 0x3FF));
             if(d >= max - 1) break;
             dest[d++] = lead;
             dest[d++] = trail;
@@ -6917,36 +7118,37 @@ public int UTF32toUTF8Len(const unichar * source, int count, char * dest, int ma
    int c;
    int d = 0;
    uint32 ch;
+   byte * byteDest = (byte *)dest;
    for(c = 0; c<count && (ch = source[c]); c++)
    {
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
-   dest[d] = 0;
+   byteDest[d] = 0;
    return d;
 }
 
@@ -6990,7 +7192,7 @@ public uint16 * UTF8toUTF16(const char * source, int * wordCount)
          if(codePoint > 0xFFFF)
          {
             uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
-            uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
+            uint16 trail = (uint16)(0xDC00 | (codePoint & 0x3FF));
             dest[d++] = lead;
             dest[d++] = trail;
          }