wip II
[sdk] / ecere / src / com / instance.ec
index 6a94d0d..332df66 100644 (file)
@@ -20,7 +20,11 @@ import "Mutex"
 
 // #define MEMINFO
 
-// #define REDZONE   256
+#ifdef MEMINFO
+ #undef REDZONE
+ #define REDZONE   256
+#endif
+
 #ifndef REDZONE
 #define REDZONE 0
 #endif
@@ -54,7 +58,11 @@ default:
 private:
 
 #if defined(__ANDROID__)
+
+default const char * AndroidInterface_GetLibLocation();
+
 #include <android/log.h>
+#include <android/native_activity.h>
 
 #define printf(...)  ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
 #endif
@@ -83,8 +91,11 @@ extern int __ecereVMethodID_class_OnGetDataFromString;
 // IMPLEMENTATION FOR THESE IN _instance.c:
 bool Instance_LocateModule(char * name, char * fileName);
 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, char *** argvPtr);
-void * Instance_Module_Load(char * name, void ** Load, void ** Unload);
+void * Instance_Module_Load(const char * libLocation, const char * name, void ** Load, void ** Unload);
 void Instance_Module_Free(void * library);
+#if defined(_DEBUG)
+void InternalModuleLoadBreakpoint();
+#endif
 
 private:
 
@@ -121,9 +132,9 @@ public:
    Class dataTypeClass;
    Type dataType;
 
-   void (*Set)();
-   int (*Get)();
-   bool (*IsSet)();
+   void (*Set)(void *, int);
+   int (*Get)(void *);
+   bool (*IsSet)(void *);
    void * data;
    void * symbol;
    int vid;
@@ -284,7 +295,7 @@ public:
    int typeSize;
    int defaultAlignment;
    void (*Initialize)();
-   int memberOffset;
+   int memberOffset;       // For structs, this includes all base classes structSize. Otherwise it restarts at for each class hierarchy level.
    OldList selfWatchers;
    char * designerClass;
    bool noExpansion;
@@ -311,6 +322,8 @@ public:
    Class templateClass;
    OldList templatized;
    int numParams;
+   bool isInstanceClass;
+   bool byValueSystemClass;
 
    property char *
    {
@@ -414,11 +427,10 @@ public:
    void * param;  // To attach to Compiler TemplateParameter
 }
 
-/*
-public class Module : struct
+/*    // Module inherits off the Instance class (_vTbl, _class, _refCount)
+public class Module
 {
    class_no_expansion
-   Instance inst;
 
    Application app;
 
@@ -442,8 +454,6 @@ public class Module : struct
 
 public class Application : Module
 {
-   Module module;
-
    int argc;
    char ** argv;
    int exitCode;
@@ -561,8 +571,8 @@ public:
    char * name;
    ClassProperty parent, left, right;
    int depth;
-   void (*Set)(Class, int);
-   int (*Get)(Class);
+   void (*Set)(Class, int64);
+   int64 (*Get)(Class);
    char * dataTypeString;
    Type dataType;
    bool constant;
@@ -1089,7 +1099,7 @@ static uint NextFibonacci(uint number)
 static uint log1_5i(uint number)
 {
    uint pos;
-   uint64 current = 4;
+   uint64 current = sizeof(void *);
    
    for(pos=0; pos < NUM_POOLS; pos++)
    {
@@ -1104,7 +1114,7 @@ static uint log1_5i(uint number)
 static uint pow1_5(uint number)
 {
    uint pos;
-   uint64 current = 4;
+   uint64 current = sizeof(void *);
    for(pos=0; pos < number; pos++)
    {
       current = current * 3 / 2;
@@ -1116,7 +1126,7 @@ static uint pow1_5(uint number)
 static uint pow1_5i(uint number)
 {
    uint pos;
-   uint64 current = 4;
+   uint64 current = sizeof(void *);
    
    for(pos=0; pos < NUM_POOLS; pos++)
    {
@@ -1155,8 +1165,8 @@ static void InitMemory()
       int expansion;
       
       pools[c].blockSize = NTH_SIZE(c);
-      if(pools[c].blockSize % 4)
-         pools[c].blockSize += 4 - (pools[c].blockSize % 4);
+      if(pools[c].blockSize % sizeof(void *))
+         pools[c].blockSize += sizeof(void *) - (pools[c].blockSize % sizeof(void *));
       pools[c].blockSpace = pools[c].blockSize;
       pools[c].blockSpace += sizeof(class MemBlock);      
       // pools[c].Expand(initNumBlocks[c]);
@@ -1175,7 +1185,7 @@ static void * _mymalloc(unsigned int size)
    {
       unsigned int p = SIZE_POSITION(size);
       if(!memoryInitialized) InitMemory();
-      if(p < NUM_POOLS)
+      if(!poolingDisabled && p < NUM_POOLS)
       {
          block = pools[p].Add();
          if(block)
@@ -1192,6 +1202,7 @@ static void * _mymalloc(unsigned int size)
             TOTAL_MEM += sizeof(class MemBlock) + size;
             OUTSIDE_MEM += sizeof(class MemBlock) + size;
             block.part = null;
+            block.size = size;
          }
       }
    }
@@ -1200,9 +1211,9 @@ static void * _mymalloc(unsigned int size)
 
 static void * _mycalloc(int n, unsigned int size)
 {
-   void * pointer = _mymalloc(size);
+   void * pointer = _mymalloc(n*size);
    if(pointer)
-      memset(pointer, 0, size);
+      memset(pointer, 0, n*size);
    return pointer;
 }
 
@@ -1242,8 +1253,8 @@ static void * _myrealloc(void * pointer, unsigned int size)
       {
          // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
          uint ns = NEXT_SIZE(size);
-         uint mod = ns % 4;
-         if(mod) ns += 4-mod;
+         uint mod = ns % sizeof(void *);
+         if(mod) ns += sizeof(void *)-mod;
          if(ns == pool->blockSize)
          {
             newPointer = pointer;
@@ -1290,8 +1301,8 @@ static void * _mycrealloc(void * pointer, unsigned int size)
       {
          // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
          uint ns = NEXT_SIZE(size);
-         uint mod = ns % 4;
-         if(mod) ns += 4-mod;
+         uint mod = ns % sizeof(void *);
+         if(mod) ns += sizeof(void *)-mod;
          if(ns == pool->blockSize)
          {
             int extra = size - block.size;
@@ -1358,8 +1369,9 @@ static void * _malloc(unsigned int size)
    memMutex.Wait();
 #endif
 
-   pointer = malloc(size + 2 * REDZONE);
+   pointer = size ? malloc(size + 2 * REDZONE) : null;
 #ifdef MEMINFO
+   if(pointer)
    {
       MemInfo block;
       MemStack stack = (MemStack)memStacks.Find(GetCurrentThreadID());
@@ -1387,7 +1399,7 @@ static void * _malloc(unsigned int size)
       if(!recurse && !stack.recurse)
       {
          stack.recurse = true;
-         block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+         block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
          memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
          memBlocks.Add(block);
          stack.recurse = false;
@@ -1400,11 +1412,14 @@ static void * _malloc(unsigned int size)
 #endif
 
 #if REDZONE
-   memset(pointer, 0xEC, REDZONE);
-   memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
-   // ((byte *)pointer)[0] = 0x00;
+   if(pointer)
+   {
+      memset(pointer, 0xAB, REDZONE);
+      memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
+      // ((byte *)pointer)[0] = 0x00;
+   }
 #endif
-   return (byte*)pointer + REDZONE;
+   return pointer ? ((byte*)pointer + REDZONE) : null;
 }
 
 static void * _calloc(int n, unsigned int size)
@@ -1414,41 +1429,42 @@ static void * _calloc(int n, unsigned int size)
    memMutex.Wait();
 #endif
 
-   pointer = calloc(n, size + 2 * REDZONE);
+   pointer = (n*size) ? calloc(1, n*size + 2 * REDZONE) : null;
 #ifdef MEMINFO
-{
-   MemStack stack;
-   stack = (MemStack)memStacks.Find(GetCurrentThreadID());
-   if(!stack)
-   {
-      stack = (MemStack)calloc(1, sizeof(class MemStack));
-      stack.key = GetCurrentThreadID();
-      memStacks.Add(stack);
-   }
-   if(!pointer)
+   if(pointer)
    {
-      int c;
-      printf("Memory allocation of %d bytes failed\n", size);
-      printf("Current Stack:\n");
-      for(c = 0; c<stack.pos; c++)
-         if(stack.frames[c])
-            printf("      %s\n", stack.frames[c]);
-      memoryErrorsCount++;
-      memMutex.Release();
-      return null;
-   }
+      MemStack stack;
+      stack = (MemStack)memStacks.Find(GetCurrentThreadID());
+      if(!stack)
+      {
+         stack = (MemStack)calloc(1, sizeof(class MemStack));
+         stack.key = GetCurrentThreadID();
+         memStacks.Add(stack);
+      }
+      if(!pointer)
+      {
+         int c;
+         printf("Memory allocation of %d bytes failed\n", size);
+         printf("Current Stack:\n");
+         for(c = 0; c<stack.pos; c++)
+            if(stack.frames[c])
+               printf("      %s\n", stack.frames[c]);
+         memoryErrorsCount++;
+         memMutex.Release();
+         return null;
+      }
 
-   if(!recurse && !stack.recurse)
-   {
-      MemInfo block;
-      
-      stack.recurse = true;
-      block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
-      memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
-      memBlocks.Add(block);
-      stack.recurse = false;
+      if(!recurse && !stack.recurse)
+      {
+         MemInfo block;
+
+         stack.recurse = true;
+         block = MemInfo { size = (unsigned int)n*size, key = (uintptr)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
+         memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
+         memBlocks.Add(block);
+         stack.recurse = false;
+      }
    }
-}
 #endif
 
 #if !defined(ECERE_BOOTSTRAP)
@@ -1456,10 +1472,13 @@ static void * _calloc(int n, unsigned int size)
 #endif
 
 #if REDZONE
-   memset(pointer, 0xEC, REDZONE);
-   memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+   if(pointer)
+   {
+      memset(pointer, 0xAB, REDZONE);
+      memset((byte *)pointer + REDZONE + (unsigned int)n*size, 0xAB, REDZONE);
+   }
 #endif
-   return (byte*)pointer + REDZONE;
+   return pointer ? ((byte*)pointer + REDZONE) : null;
 }
 
 static void * _realloc(void * pointer, unsigned int size)
@@ -1483,7 +1502,7 @@ static void * _realloc(void * pointer, unsigned int size)
 
    if(!recurse && !stack.recurse && pointer)
    {
-      block = (MemInfo)memBlocks.Find((uint)pointer);
+      block = (MemInfo)memBlocks.Find((uintptr)pointer);
       if(!block)
       {
          printf("Reallocating Bad Memory\n");
@@ -1510,8 +1529,8 @@ static void * _realloc(void * pointer, unsigned int size)
       memMutex.Release();
       return null;
    }
-   memset(pointer, 0xEC, REDZONE);
-   memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+   memset(pointer, 0xAB, REDZONE);
+   memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
 
    if(block)
    {
@@ -1523,8 +1542,12 @@ static void * _realloc(void * pointer, unsigned int size)
       {
          memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
          memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
-         block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
-         memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+         block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+         if(block.oldmem)
+         {
+            block.oldmem += REDZONE;
+            memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+         }
          memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
          block.freed = true;
       }
@@ -1534,7 +1557,7 @@ static void * _realloc(void * pointer, unsigned int size)
    {
       MemInfo block;
       stack.recurse = true;
-      block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+      block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
       memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
       memBlocks.Add(block);
       stack.recurse = false;
@@ -1547,7 +1570,7 @@ static void * _realloc(void * pointer, unsigned int size)
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Release();
 #endif
-   return (byte *)pointer + REDZONE;
+   return pointer ? ((byte *)pointer + REDZONE) : null;
 }
 
 static void * _crealloc(void * pointer, unsigned int size)
@@ -1571,7 +1594,7 @@ static void * _crealloc(void * pointer, unsigned int size)
 
    if(!recurse && !stack.recurse && pointer)
    {
-      block = (MemInfo)memBlocks.Find((uint)pointer);
+      block = (MemInfo)memBlocks.Find((uintptr)pointer);
       if(!block)
       {
          printf("Reallocating Bad Memory\n");
@@ -1598,8 +1621,8 @@ static void * _crealloc(void * pointer, unsigned int size)
       memMutex.Release();
       return null;
    }
-   memset(pointer, 0xEC, REDZONE);
-   memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+   memset(pointer, 0xAB, REDZONE);
+   memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
 
    if(block)
    {
@@ -1611,8 +1634,12 @@ static void * _crealloc(void * pointer, unsigned int size)
       {
          memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
          memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
-         block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
-         memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+         block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+         if(block.oldmem)
+         {
+            block.oldmem += REDZONE;
+            memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+         }
          memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
          block.freed = true;
       }
@@ -1622,7 +1649,7 @@ static void * _crealloc(void * pointer, unsigned int size)
    {
       MemInfo block;
       stack.recurse = true;
-      block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+      block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
       memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
       memBlocks.Add(block);
       stack.recurse = false;
@@ -1635,7 +1662,7 @@ static void * _crealloc(void * pointer, unsigned int size)
 #if !defined(ECERE_BOOTSTRAP)
    memMutex.Release();
 #endif
-   return (byte *)pointer + REDZONE;
+   return pointer ? ((byte *)pointer + REDZONE) : null;
 }
 
 static void _free(void * pointer)
@@ -1662,7 +1689,7 @@ static void _free(void * pointer)
       {
          MemInfo block;
          stack.recurse = true;
-         block = (MemInfo)memBlocks.Find((uint)pointer);
+         block = (MemInfo)memBlocks.Find((uintptr)pointer);
          if(!block)
          {
             int c;
@@ -1713,13 +1740,13 @@ static void _free(void * pointer)
                address = (byte *)block.key;
                for(c = 0; c<REDZONE; c++)
                {
-                  if(address[-c-1] != 0xEC)
+                  if(address[-c-1] != 0xAB)
                   {
                      printf("Buffer Underrun\n");
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
-                  if(address[c + size] != 0xEC)
+                  if(address[c + size] != 0xAB)
                   {
                      printf("Buffer Overrun\n");
                      memoryErrorsCount++;
@@ -1729,8 +1756,12 @@ static void _free(void * pointer)
             }
 
             block.freed = true;
-            block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
-            memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
+            block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+            if(block.oldmem)
+            {
+               block.oldmem += REDZONE;
+               memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
+            }
             memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
 
             memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
@@ -1851,13 +1882,13 @@ public void CheckMemory()
       address = (byte *)block.key;
       for(c = 0; c<REDZONE; c++)
       {
-         if(address[-c-1] != 0xEC)
+         if(address[-c-1] != 0xAB)
          {
             printf("Buffer Underrun\n");
             memoryErrorsCount++;
             block.OutputStacks(block.freed);
          }
-         if(address[c + size] != 0xEC)
+         if(address[c + size] != 0xAB)
          {
             printf("Buffer Overrun\n");
             memoryErrorsCount++;
@@ -1891,6 +1922,7 @@ static void FixDerivativesBase(Class base, Class mod)
    {
       Class _class = derivative.data;
       ClassType type = _class.type;
+      ClassType oldType = type;
       int size = _class.structSize - _class.offset;
       int oldSizeClass = _class.sizeClass;
       int sizeClass = _class.sizeClass - _class.offsetClass;
@@ -1991,6 +2023,7 @@ static void FixDerivativesBase(Class base, Class mod)
          Method method, next;
          Class b;
          bool needUpdate = (mod != (base.templateClass ? base.templateClass : base) || _class.vTblSize != mod.vTblSize;
+         int updateStart = -1, updateEnd = -1;
 
          if(mod.base && mod.base.base && mod.base.vTblSize > baseClass.vTblSize && needUpdate)
          {
@@ -1999,6 +2032,9 @@ static void FixDerivativesBase(Class base, Class mod)
             // memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
             memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (_class.vTblSize - mod.vTblSize) * sizeof(void *));
 
+            updateStart = baseClass.vTblSize;
+            updateEnd = updateStart + mod.base.vTblSize - baseClass.vTblSize;
+
             for(method = (Method)_class.methods.first; method; method = next)
             {
                next = (Method)((BTNode)method).next;
@@ -2032,7 +2068,7 @@ static void FixDerivativesBase(Class base, Class mod)
                            method._class = vMethod._class;
                         }
                      }
-                     else if(needUpdate || _class._vTbl[vMethod.vid] == b._vTbl[vMethod.vid])
+                     else if((vMethod.vid >= updateStart && vMethod.vid < updateEnd ) || _class._vTbl[vMethod.vid] == b._vTbl[vMethod.vid])
                         _class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
                   }
                }
@@ -2096,13 +2132,27 @@ static void FixDerivativesBase(Class base, Class mod)
          }
          // if(mod.base.memberID)
          {
-            for(member = _class.membersAndProperties.first; member; member = member.next)
+            DataMember next;
+            for(member = _class.membersAndProperties.first; member; member = next)
             {
                int offsetDiff = _class.offset - offsetBefore;
-               if(!member.isProperty && offsetDiff > 0)
+               next = member.next;
+               if(!member.isProperty)
                {
-                  member.offset += offsetDiff;
-                  member.memberOffset += offsetDiff;
+                  if(oldType == bitClass && type != bitClass)
+                  {
+                     DataMember prev = member.prev;
+                     // Correcting a bitClass to be a non-bit class (This should really never be required)
+                     _class.membersAndProperties.Remove(member);
+                     member = (DataMember)renew0 member byte[sizeof (class DataMember)];
+                     _class.membersAndProperties.Insert(prev, member);
+                  }
+
+                  if(offsetDiff > 0)
+                  {
+                     member.offset += offsetDiff;
+                     member.memberOffset += offsetDiff;
+                  }
                }
                member.id += mod.base.memberID;
             }
@@ -2154,6 +2204,19 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
 {
    int start = 0, c;
    NameSpace * nameSpace = null;
+   bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
+   bool force32Bits = (module.application.isGUIApp & 4) ? true : false;
+   bool inCompiler = (module.application.isGUIApp & 8) ? true : false;
+   bool crossBits = force32Bits || force64Bits;
+   bool fixed = false;
+   if(inCompiler && crossBits)
+   {
+      Class c = eSystem_FindClass(__thisModule.application, name);
+      if(c && c.fixed)
+         fixed = true;
+      else if(__thisModule.name && !strcmp(__thisModule.name, "ecereCOM"))
+         fixed = true;
+   }
 
    {
       nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
@@ -2205,6 +2268,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
       Class enumBase = null;
       Class base = (baseName && baseName[0]) ? eSystem_FindClass(module, baseName) : null;
       bool refine = false;
+      Class prevBase = null;
 
       if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass)) 
       {
@@ -2219,7 +2283,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
       {
          type = base.type;
       }
-      if(!base || base.type == systemClass)
+      if(!base || base.type == systemClass || base.isInstanceClass)
       {
          if(type == enumClass)
          {
@@ -2320,8 +2384,6 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
    
       if((_class = eSystem_FindClass(module, name)))
       {
-         FreeTemplatesDerivatives(_class);
-
          if(!_class.internalDecl)
          {
             if(declMode != baseSystemAccess)
@@ -2335,6 +2397,8 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
             return null;
          }
 
+         FreeTemplatesDerivatives(_class);
+
          classLink = (BTNamedLink)_class.nameSpace->classes.FindString(name + start);
          _class.nameSpace->classes.Delete((BTNode)classLink);
          {
@@ -2502,6 +2566,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
          }
 
          _class.module = module;
+         prevBase = _class.base;
          _class.base = base;
          if(base)
          {
@@ -2548,7 +2613,47 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
          }
          _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 : sizeof(class Instance));
+            _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+
+         // For cross-bitness-compiling
+         if(crossBits)
+         {
+            // Ideally, the running library should be aware of the struct size of both 32 and 64 bit, since the compiler has no knowledge whatsoever of private members
+            if(strstr(name, "ecere::sys::EARHeader") ||
+               strstr(name, "AnchorValue") ||
+               !strcmp(name, "ecere::com::CustomAVLTree") ||
+               !strcmp(name, "ecere::com::Array") ||
+               !strcmp(name, "ecere::gui::Window") ||
+               !strcmp(name, "ecere::sys::Mutex"));   // Never recompute these, they're always problematic (errors, crashes)
+            else
+            {
+               if(!strcmp(name, "ecere::sys::FileListing"))
+               {
+                  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
+               }
+               // These we want to recompute inside the IDE to help the debugger
+               else if(!strcmp(name, "ecere::com::Class"))           size = 0; // 616
+               else if(!strcmp(name, "ecere::com::ClassProperty"))   size = 0; // 80
+               else if(!strcmp(name, "ecere::com::NameSpace"))       size = 0; // 176
+               else if(!strcmp(name, "ecere::sys::BufferedFile"))    size = 0;
+               else if(!strcmp(name, "ecere::sys::BTNode"))          size = 0;
+               else if(!strcmp(name, "ecere::sys::StringBTNode"))    size = 0;
+               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::OldLink"))         size = 0;
+               else if(!strcmp(name, "ecere::sys::NamedItem"))       size = 0;
+               else if(!strcmp(name, "ecere::sys::NamedItem64"))     size = 0;
+               else if(!strcmp(name, "ecere::sys::BinaryTree"))      size = 0;
+               else if(module != module.application && inCompiler)
+               {
+                  // These we only want to recompute inside the compiler
+                  if(fixed || type == structClass)
+                     size = 0;
+               }
+            }
+         }
          if(type == structClass)
          {
             _class.memberOffset = (base && base.structSize && base.type != systemClass) ? base.structSize : 0;
@@ -2596,13 +2701,31 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                   data.largest = ((EnumClassData)(base.data)).largest;
             }
          }
-         if(base && base.vTblSize)
+         if(base)
          {
-            _class.vTblSize = base.vTblSize;
-            // OK to scrap existing virtual table?
-            delete _class._vTbl;
-            _class._vTbl = _malloc(sizeof(int(*)()) * _class.vTblSize);
-            memcpy(_class._vTbl, base._vTbl, sizeof(int(*)()) * _class.vTblSize);
+            int i;
+            uint oldSize = _class.vTblSize;
+            if(base.vTblSize && _class.vTblSize < base.vTblSize)
+            {
+               _class.vTblSize = base.vTblSize;
+               // OK to scrap existing virtual table?
+               //delete _class._vTbl;
+               //_class._vTbl = _malloc(sizeof(int(*)()) * _class.vTblSize);
+               // memcpy(_class._vTbl, base._vTbl, sizeof(int(*)()) * _class.vTblSize);
+               _class._vTbl = _realloc(_class._vTbl, sizeof(int(*)()) * _class.vTblSize);
+            }
+            if(!prevBase)
+            {
+               if(_class.type == normalClass && strcmp(_class.name, "ecere::com::Instance") && strcmp(_class.name, "enum") && strcmp(_class.name, "struct"))
+                  prevBase = eSystem_FindClass(module, "ecere::com::Instance");
+               else
+                  prevBase = eSystem_FindClass(module, "class");
+            }
+            for(i = 0; i < base.vTblSize; i++)
+            {
+               if(i >= oldSize || _class._vTbl[i] == prevBase._vTbl[i])
+                  _class._vTbl[i] = base._vTbl[i];
+            }
          }
 
          if(_class.base)
@@ -2711,6 +2834,7 @@ static void FreeTemplate(Class template)
    delete template.fullName;
    delete template.name;
    delete template.templateArgs;
+   delete template.dataTypeString;
 
    while((deriv = template.derivatives.first))
    {
@@ -2734,6 +2858,7 @@ static void FreeTemplates(Class _class)
    //if(_class.templateArgs)
       //printf("Deleting  Template args for %s\n", _class.name);
    delete _class.templateArgs;
+   delete _class.dataTypeString;
 
    while((template = _class.templatized.first))
    {
@@ -2873,7 +2998,7 @@ public dllexport void eClass_Unregister(Class _class)
 static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOffset)
 {
    BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uint)listOffset);
-   BTNamedLink link = (BTNamedLink)tree->Find((uint)name);
+   BTNamedLink link = (BTNamedLink)tree->Find((uintptr)name);
    NameSpace * child;
    if(!link)
    {
@@ -2958,7 +3083,7 @@ public int64 _strtoi64(char * string, char ** endString, int base)
    else if(ch == '-') { sign = -1; c++; };
    if(!base)
    {
-      if(ch == 0 && string[c+1] == 'x')
+      if(ch == '0' && string[c+1] == 'x')
       {
          base = 16;
          c+=2;
@@ -2973,17 +3098,16 @@ public int64 _strtoi64(char * string, char ** endString, int base)
    }
    for( ;(ch = string[c]); c++)
    {
-      if(ch == '0')
-         ch = 0;
-      else if(ch >= '1' && ch <= '9')
-         ch -= '1';
+      if(ch >= '0' && ch <= '9')
+         ch -= '0';
       else if(ch >= 'a' && ch <= 'z') 
-         ch -= 'a'
+         ch -= ('a' - 10)
       else if(ch >= 'A' && ch <= 'Z') 
-         ch -= 'A';
+         ch -= ('A'- 10);
       else
       {
-         *endString = string + c;
+         if(endString)
+            *endString = string + c;
          // Invalid character
          break;
       }
@@ -2994,7 +3118,8 @@ public int64 _strtoi64(char * string, char ** endString, int base)
       }
       else
       {
-         *endString = string + c;
+         if(endString)
+            *endString = string + c;
          // Invalid character
          break;
       }
@@ -3013,7 +3138,7 @@ public uint64 _strtoui64(char * string, char ** endString, int base)
    else if(ch == '-') { sign = -1; c++; };
    if(!base)
    {
-      if(ch == 0 && string[c+1] == 'x')
+      if(ch == '0' && string[c+1] == 'x')
       {
          base = 16;
          c+=2;
@@ -3028,17 +3153,16 @@ public uint64 _strtoui64(char * string, char ** endString, int base)
    }
    for( ;(ch = string[c]); c++)
    {
-      if(ch == '0')
-         ch = 0;
-      else if(ch >= '1' && ch <= '9')
-         ch -= '1';
+      if(ch >= '0' && ch <= '9')
+         ch -= '0';
       else if(ch >= 'a' && ch <= 'z') 
-         ch -= 'a'
+         ch -= ('a' - 10)
       else if(ch >= 'A' && ch <= 'Z') 
-         ch -= 'A';
+         ch -= ('A' - 10);
       else
       {
-         *endString = string + c;
+         if(endString)
+            *endString = string + c;
          // Invalid character
          break;
       }
@@ -3049,7 +3173,8 @@ public uint64 _strtoui64(char * string, char ** endString, int base)
       }
       else
       {
-         *endString = string + c;
+         if(endString)
+            *endString = string + c;
          // Invalid character
          break;
       }
@@ -3108,6 +3233,7 @@ public dllexport Class eSystem_FindClass(Module module, char * name)
                templatedClass.templateClass = _class;
                //templatedClass.fullName = CopyString(name);
                templatedClass.fullName = CopyString(className);
+               templatedClass.dataTypeString = CopyString(_class.dataTypeString);
                templatedClass.name = CopyString(templatedClass.fullName + strlen(_class.fullName) - strlen(_class.name));
                templatedClass.nameSpace->classes.Add((BTNode)BTNamedLink { name = templatedClass.name, data = templatedClass });
                templatedClass.templateArgs = null;
@@ -3359,7 +3485,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                   if(expClass)
                   {
                      //if(expClass.type == 
-                     expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString](expClass, &argument.expression, value);
+                     ((bool (*)(void *, void *, const char *))(void *)expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString])(expClass, &argument.expression, value);
                   }
                   // Expression should be pre simplified here
                   else if(value[0] == '\"')
@@ -3377,7 +3503,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                   }
                   else if(!strcmp(curParam.dataTypeString, "uint"))
                   {
-                     argument.expression.ui = strtoul(value, null, 0);
+                     argument.expression.ui = (uint)strtoul(value, null, 0);
                   }
                   else if(!strcmp(curParam.dataTypeString, "char"))
                   {
@@ -3413,7 +3539,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                   }
                   else // if(!strcmp(curParam.dataTypeString, "int"))
                   {
-                     argument.expression.i = strtol(value, null, 0);
+                     argument.expression.i = (int)strtol(value, null, 0);
                   }
                   break;
                } 
@@ -3822,7 +3948,7 @@ public dllexport bool eClass_IsDerived(Class _class, Class from)
    {
       for(; _class && from; _class = _class.base)
       {
-         if(_class == from || _class.templateClass == from || (_class.type == systemClass && from.name && !strcmp(_class.name, from.name)))
+         if(_class == from || _class.templateClass == from || ((_class.type == systemClass || (_class.type == normalClass && _class.isInstanceClass)) && from.name && !strcmp(_class.name, from.name)))
             return true;
       }
    }
@@ -3893,7 +4019,7 @@ static void FixDerivativeVirtualMethod(Class base, char * name, int vid, void *
 
 public dllexport Method eClass_AddMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
 {
-   if(_class && name)
+   if(_class && !_class.comRedefinition && name)
    {
       Class base;
       for(base = _class; base; base = base.base)
@@ -3906,8 +4032,8 @@ public dllexport Method eClass_AddMethod(Class _class, char * name, char * type,
             {
                OldLink deriv;
                void * oldFunction = _class._vTbl[method.vid];
-               if(method.vid > _class.vTblSize)
-                  printf("error");
+               if(method.vid >= _class.vTblSize)
+                  printf("error: virtual methods overriding failure\n");
                else
                   _class._vTbl[method.vid] = function ? function : DefaultFunction;
                for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
@@ -3964,7 +4090,7 @@ public dllexport Method eClass_AddMethod(Class _class, char * name, char * type,
 
 public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
 {
-   if(_class && name)
+   if(_class && !_class.comRedefinition && name)
    {
       Class base;
       for(base = _class; base; base = base.base)
@@ -3974,7 +4100,12 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char
          {
             // If this overides a virtual method
             if(method.type == virtualMethod)
-               _class._vTbl[method.vid] = function ? function : DefaultFunction;
+            {
+               if(method.vid >= _class.vTblSize)
+                  printf("error: virtual methods overriding failure\n");
+               else
+                  _class._vTbl[method.vid] = function ? function : DefaultFunction;
+            }
             else
                base = null;
             return method;
@@ -4013,8 +4144,7 @@ static void FixDerivativeProperty(Class base, Property _property)
    {
       Class _class = derivative.data;
       Property prop;
-      BTNamedLink link;
-      link = (BTNamedLink)_class.prop.FindString(_property.name);
+      BTNamedLink link = (BTNamedLink)_class.prop.FindString(_property.name);
       if(link)
       {
          prop = link.data;
@@ -4049,7 +4179,10 @@ public dllexport Property eClass_AddProperty(Class _class, char * name, char * d
    Property _property = null;
    if(_class)
    {
-      if(!_class.prop.FindString((name ? name : dataType))) 
+      BTNamedLink link = (BTNamedLink)_class.prop.FindString(name ? name : dataType);
+      if(link)
+         _property = link.data;
+      if(!_property)
       {
          _property =
          {
@@ -4082,7 +4215,7 @@ public dllexport Property eClass_AddProperty(Class _class, char * name, char * d
 static void SetDelayedCPValues(Class _class, ClassProperty _property)
 {
    OldLink deriv;
-   NamedLink value, next;
+   NamedLink64 value, next;
 
    for(value = _class.delayedCPValues.first; value; value = next)
    {
@@ -4090,7 +4223,7 @@ static void SetDelayedCPValues(Class _class, ClassProperty _property)
       if(!strcmp(value.name, _property.name))
       {
          // eClass_SetProperty(_class, _property.name, value.data);
-         _property.Set(_class, (int)value.data);
+         _property.Set(_class, value.data);
          _class.delayedCPValues.Delete(value);
       }
    }
@@ -4159,28 +4292,28 @@ public dllexport ClassProperty eClass_FindClassProperty(Class _class, char * nam
    return _property;
 }
 
-public dllexport int eClass_GetProperty(Class _class, char * name)
+public dllexport int64 eClass_GetProperty(Class _class, char * name)
 {
    ClassProperty _property = eClass_FindClassProperty(_class, name);
    if(_property && _property.Get && _property.Get != (void *)1)
    {
-      int result = _property.Get(_class);
+      int64 result = _property.Get(_class);
       return result;
    }
    return 0;
 }
 
-public dllexport void eClass_SetProperty(Class _class, char * name, int value)
+public dllexport void eClass_SetProperty(Class _class, char * name, int64 value)
 {
    ClassProperty _property = eClass_FindClassProperty(_class, name);
    if(_property)
    {
       if(_property.Set)
-         _property.Set(_class, value);
+         ((void(*)(void *, int64))_property.Set)(_class, value);
    }
    else
    {
-      _class.delayedCPValues.Add(NamedLink { name = name, (void *)value });
+      _class.delayedCPValues.Add(NamedLink64 { name = name, value });
    }
 }
 
@@ -4273,7 +4406,23 @@ public dllexport void * eInstance_New(Class _class)
 #endif
 
 #endif
-      instance = _calloc(1, _class.structSize);   
+      {
+         int size = _class.structSize;
+         int flags = _class.module.application.isGUIApp;
+         bool inCompiler = (flags & 8) ? true : false;
+         bool force32Bits = (flags & 4) ? true : false;
+         if(force32Bits && inCompiler)
+         {
+            // Allocate 64 bit sizes for these when cross-compiling for 32 bit to allow loaded libraries to work properly
+            if(!strcmp(_class.name, "Module"))
+               size = 560;
+            else if(_class.templateClass && !strcmp(_class.templateClass.name, "Map"))
+               size = 40;
+            else
+               size *= 3;
+         }
+         instance = _calloc(1, size);
+      }
 #ifdef MEMINFO
       allocateClass = null;
    memMutex.Release();
@@ -4419,7 +4568,7 @@ public dllexport void eInstance_Delete(Instance instance)
       bool ownVtbl;
 
 #ifdef MEMINFO
-      if(instance._class == (void *)0xecececec)
+      if(instance._class == (void *)0xecececececececec)
          _free(instance);
 #endif
 
@@ -4462,7 +4611,7 @@ public dllexport void eInstance_Delete(Instance instance)
          
 
          base = _class.base;
-         if(base && base.type == systemClass) base = null;
+         if(base && (base.type == systemClass || base.isInstanceClass)) base = null;
          if(_class.Destructor)
             _class.Destructor(instance);
 #ifdef MEMINFO
@@ -4778,7 +4927,7 @@ public dllexport void eClass_FindNextMember(Class _class, Class * curClass, Data
             {
                DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
                if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
-               if(dataMember && dataMember.memberAccess != privateAccess)
+               if(dataMember && dataMember.memberAccess != privateAccess && dataMember.id >= 0) // Skip _vTbl, _refCount and _class in Instance
                {
                   *curMember = dataMember;
                   break;
@@ -4963,7 +5112,12 @@ static void SetMemberClass(DataMember member, Class _class)
 
 public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
 {
-   if(dataMember.name && addTo.membersAlpha.FindString(dataMember.name)) return false;
+   if(dataMember.name && addTo.membersAlpha.FindString(dataMember.name))
+   {
+      DataMember_Free(dataMember);
+      delete dataMember;
+      return false;
+   }
    addTo.members.Add(dataMember);
 
    if(dataMember.name)
@@ -4994,7 +5148,11 @@ public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
 public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
 {
    if(!_class || _class.comRedefinition || (dataMember.name && _class.members.FindString(dataMember.name)))
+   {
+      DataMember_Free(dataMember);
+      delete dataMember;
       return false;
+   }
    _class.membersAndProperties.Add(dataMember);
 
    if(dataMember.name)
@@ -5081,7 +5239,11 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
       }
       else
       {
-         library = Instance_Module_Load(name, &Load, &Unload);
+         char * libLocation = null;
+#if defined(__ANDROID__)
+         libLocation = AndroidInterface_GetLibLocation();
+#endif
+         library = Instance_Module_Load(libLocation, name, &Load, &Unload);
       }
       if(Load)
       {
@@ -5091,6 +5253,7 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
          module.name = CopyString(name);
          module.Unload = Unload;
          module.origImportType = normalImport;
+
          if(!Load(module))
          {
             eInstance_Delete((Instance)module);
@@ -5121,11 +5284,13 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
             module.library = null;
             module.name = CopyString(name);
             module.Unload = Unload;
+
             if(!Load(module))
             {
                eInstance_Delete((Instance)module);
                module = null;
             }
+
             fromModule.application.allModules.Add(module);
          }
          if(module)
@@ -5146,6 +5311,9 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
       }
       incref module;
    }
+#if defined(_DEBUG)
+   InternalModuleLoadBreakpoint();
+#endif
    return module;
 }
 
@@ -5367,7 +5535,7 @@ static void Module_Destructor(Module module)
       }
       _class.module = null;
       module.classes.Remove(_class);
-      if(!_class.count || _class.type != normalClass)
+      if(_class.count <= 0 || _class.type != normalClass || _class.isInstanceClass)
          eClass_Unregister(_class);
       else
       {
@@ -5428,7 +5596,7 @@ static void Module_Destructor(Module module)
 #endif
 }
 
-static int GetEnumSize(Class _class)
+static int64 GetEnumSize(Class _class)
 {
    EnumClassData data = (EnumClassData)_class.data;
    return data.largest+1;
@@ -5664,13 +5832,21 @@ public dllexport void eInstance_FireWatchers(Instance instance, Property _proper
 {
    if(instance && _property && _property.isWatchable)
    {
-      OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
-      Watcher watcher, next;
-
-      for(watcher = watchers->first; watcher; watcher = next)
+      Module module = instance._class ? instance._class.module : null;
+      Application application = module ? module.application : null;
+      int flags = application ? application.isGUIApp : 0;
+      bool inCompiler = (flags & 8) ? true : false;
+      bool force32Bits = (flags & 4) ? true : false;
+      if(!force32Bits || !inCompiler)
       {
-         next = watcher.next;
-         watcher.callback(watcher.object, instance);
+         OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
+         Watcher watcher, next;
+
+         for(watcher = watchers->first; watcher; watcher = next)
+         {
+            next = watcher.next;
+            watcher.callback(watcher.object, instance);
+         }
       }
    }
 }
@@ -5778,7 +5954,7 @@ public dllexport void eInstance_StopWatching(Instance instance, Property _proper
                }
             }
             base = _class.base;
-            if(base && base.type == systemClass) base = null;
+            if(base && (base.type == systemClass || base.isInstanceClass)) base = null;
          }
       }
    }
@@ -5809,6 +5985,10 @@ public bool LocateModule(char * name, char * fileName)
 
 static void LoadCOM(Module module)
 {
+   bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
+   bool force32Bits = (module.application.isGUIApp & 4) ? true : false;
+   bool inCompiler = (module.application.isGUIApp & 8) ? true : false;
+   int pointerSize = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
    Class applicationClass;
    Class enumClass, structClass, boolClass;
    Class moduleClass;
@@ -5823,8 +6003,8 @@ static void LoadCOM(Module module)
 
    {
       Class instanceClass = eSystem_RegisterClass(normalClass, "ecere::com::Instance", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
-      // Instance should really be a Normal class, but inheritance checks for systemClass to see if something has a non system ancestor
-      instanceClass.type = systemClass;
+      instanceClass.type = normalClass;
+      instanceClass.isInstanceClass = true;
       instanceClass.fixed = true;
       instanceClass.memberOffset = 0;
       instanceClass.offset = 0;
@@ -5832,16 +6012,15 @@ static void LoadCOM(Module module)
       instanceClass.memberID = -3;
       instanceClass.startMemberID = -3;
 
-      // eClass_AddDataMember(instanceClass, "_vTbl", "void **", sizeof(int (**)()), 4, publicAccess);
-      eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", sizeof(int (**)()), 4, publicAccess);
-      eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", sizeof(Class), 4, publicAccess);
-      eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int (**)()), 4, publicAccess);
+      eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", pointerSize, pointerSize, publicAccess);
+      eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", pointerSize, pointerSize, publicAccess);
+      eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int), sizeof(int), publicAccess);
    }
 
    InitializeDataTypes1(module);
 
    // Create Enum class
-   enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
+   enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, force64Bits ? 40 : sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
    eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
    enumClass.type = systemClass;
    
@@ -5868,38 +6047,46 @@ static void LoadCOM(Module module)
    eEnum_AddFixedValue(boolClass, "false", bool::false);
 
    // Create Module class
-   moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
+   moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, force64Bits ? 8 + 32 + 32 + 32 + 32 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + (32 + 8 + 8 + 4*32) + (32 + 8 + 8 + 4*32) :
+                                                                                sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
    eClass_AddVirtualMethod(moduleClass, "OnLoad", "bool()", null, publicAccess);
    eClass_AddVirtualMethod(moduleClass, "OnUnload", "void()", null, publicAccess);
    eClass_AddMethod(moduleClass, "Load", "Module(char * name, AccessMode importAccess)", eModule_Load, publicAccess);
    eClass_AddMethod(moduleClass, "Unload", "void(Module module)", eModule_Unload, publicAccess);
-   eClass_AddDataMember(moduleClass, "application", "Application", sizeof(Application), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "classes", "OldList", sizeof(OldList), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "defines", "OldList", sizeof(OldList), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "functions", "OldList", sizeof(OldList), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "modules", "OldList", sizeof(OldList), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "prev", "Module", sizeof(Module), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "next", "Module", sizeof(Module), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "name", "char *", sizeof(char *), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "library", "void *", sizeof(void *), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "Unload", "void *", sizeof(void *), 4, publicAccess);
+   eClass_AddDataMember(moduleClass, "application", "Application", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "classes", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "defines", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "functions", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "modules", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "prev", "Module", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "next", "Module", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "name", "char *", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "library", "void *", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "Unload", "void *", pointerSize, pointerSize, publicAccess);
    eClass_AddDataMember(moduleClass, "importType", "ImportType", sizeof(ImportType), 4, publicAccess);
    eClass_AddDataMember(moduleClass, "origImportType", "ImportType", sizeof(ImportType), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
-   eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
+   eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace",  force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
    moduleClass.fixed = true;
    moduleClass.count++;
+   if(inCompiler && force32Bits)
+      moduleClass.structSize = 12 + 4 + 20 + 20 + 20 + 20 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + (16 + 4 + 4 + 4*16) + (16 + 4 + 4 + 4*16);
    
    // Create Application class
-   applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
+   applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", force64Bits ? (8+8+4+4 + 32 + 8 + 176) : sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
+   if(inCompiler && force32Bits)
+   {
+      applicationClass.offset = 12 + 4 + 20 + 20 + 20 + 20 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + (16 + 4 + 4 + 4*16) + (16 + 4 + 4 + 4*16);
+      applicationClass.structSize = applicationClass.offset + (4+4+4+4 + 20 + 4 + 88);
+   }
    eClass_AddVirtualMethod(applicationClass, "Main", "void()", null, publicAccess);
    eClass_AddDataMember(applicationClass, "argc", "int", sizeof(int), 4, publicAccess);
-   eClass_AddDataMember(applicationClass, "argv", "char **", sizeof(char **), 4, publicAccess);
+   eClass_AddDataMember(applicationClass, "argv", "char **", pointerSize, pointerSize, publicAccess);
    eClass_AddDataMember(applicationClass, "exitCode", "int", sizeof(int), 4, publicAccess);
    eClass_AddDataMember(applicationClass, "isGUIApp", "bool", sizeof(bool), 4, publicAccess);
-   eClass_AddDataMember(applicationClass, "allModules", "OldList", sizeof(OldList), 4, publicAccess);
-   eClass_AddDataMember(applicationClass, "parsedCommand", "char *", sizeof(char *), 4, publicAccess);
-   eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
+   eClass_AddDataMember(applicationClass, "allModules", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(applicationClass, "parsedCommand", "char *", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
    applicationClass.fixed = true;
    applicationClass.count++;
 
@@ -5928,25 +6115,25 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("exp", "double exp(double number)", exp, module, baseSystemAccess);
 
    // --- Stdlib ---
-   eSystem_RegisterFunction("qsort", "void qsort(void *, uint, uint, int (*)(void *, void *))", qsort, module, baseSystemAccess);
+   eSystem_RegisterFunction("qsort", "void qsort(void *, uintsize, uintsize, int (*)(void *, void *))", qsort, module, baseSystemAccess);
    eSystem_RegisterFunction("strtod", "double strtod(char*, char**)", strtod, module, baseSystemAccess);
    eSystem_RegisterFunction("strtol", "int strtol(char*, char**, int base)", strtol, 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", "float atof(const char*)", atof, 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, byte value, uint count)", memset, 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);
 
    // --- String --- (These might move to the string class)
-   eSystem_RegisterFunction("strlen", "int strlen(const char *)", strlen, module, baseSystemAccess);
+   eSystem_RegisterFunction("strlen", "uintsize strlen(const char *)", strlen, module, baseSystemAccess);
    eSystem_RegisterFunction("strcat", "char * strcat(char *, const char *)", strcat, module, baseSystemAccess);
-   eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, int n)", strncat, module, baseSystemAccess);
-   eSystem_RegisterFunction("strchr", "char * strchr(char *, int)", strchr, module, baseSystemAccess);
-   eSystem_RegisterFunction("strstr", "char * strstr(char *, const char *)", strstr, module, baseSystemAccess);
+   eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, uintsize n)", strncat, module, baseSystemAccess);
+   eSystem_RegisterFunction("strchr", "char * strchr(const char *, int)", strchr, module, baseSystemAccess);
+   eSystem_RegisterFunction("strstr", "char * strstr(const char *, const char *)", strstr, module, baseSystemAccess);
 
    eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
 
@@ -5954,7 +6141,7 @@ static void LoadCOM(Module module)
    eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
    eSystem_RegisterDefine("strnicmp", "strncasecmp", module, baseSystemAccess);
    eSystem_RegisterFunction("strcasecmp", "int strcasecmp(const char *, const char *)", strcmpi, module, baseSystemAccess);
-   eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
+   eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, uintsize n)", strnicmp, module, baseSystemAccess);
 /*
 #else
    eSystem_RegisterDefine("strcasecmp", "strcmpi", module, baseSystemAccess);
@@ -5965,22 +6152,20 @@ static void LoadCOM(Module module)
 */
 
    eSystem_RegisterFunction("strcmp", "int strcmp(const char *, const char *)", strcmp, module, baseSystemAccess);
-   eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, int n)", strncmp, module, baseSystemAccess);
+   eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, uintsize n)", strncmp, module, baseSystemAccess);
    eSystem_RegisterFunction("strlwr", "char * strlwr(char *)", strlwr, module, baseSystemAccess);
    eSystem_RegisterFunction("strupr", "char * strupr(char *)", strupr, module, baseSystemAccess);
    eSystem_RegisterFunction("strcpy", "char * strcpy(char *, const char *)", strcpy, module, baseSystemAccess);
-   eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, int n)", strncpy, module, baseSystemAccess);
-   eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uint size)", memcpy, module, baseSystemAccess);
-   eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uint size)", memmove, module, baseSystemAccess);
+   eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, uintsize n)", strncpy, module, baseSystemAccess);
+   eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uintsize size)", memcpy, module, baseSystemAccess);
+   eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uintsize size)", memmove, module, baseSystemAccess);
 
    // --- Stdio ---
    eSystem_RegisterFunction("sprintf", "int sprintf(char *, char *, ...)", sprintf, module, baseSystemAccess);
-   // TODO: Replace int with size_t when eC recognizes it for 64 bit port
-   eSystem_RegisterFunction("snprintf", "int sprintf(char *, int, char *, ...)", snprintf, module, baseSystemAccess);
+   eSystem_RegisterFunction("snprintf", "int sprintf(char *, uintsize, char *, ...)", snprintf, module, baseSystemAccess);
    eSystem_RegisterFunction("printf", "int printf(char *, ...)", printf, module, baseSystemAccess);
    eSystem_RegisterFunction("vsprintf", "int vsprintf(char*, const char*, __builtin_va_list)", vsprintf, module, baseSystemAccess);
-   // TODO: Replace int with size_t when eC recognizes it for 64 bit port
-   eSystem_RegisterFunction("vsnprintf", "int vsnprintf(char*, int, const char*, __builtin_va_list)", vsnprintf, module, baseSystemAccess);
+   eSystem_RegisterFunction("vsnprintf", "int vsnprintf(char*, uintsize, const char*, __builtin_va_list)", vsnprintf, module, baseSystemAccess);
    eSystem_RegisterFunction("puts", "int puts(char *)", puts, module, baseSystemAccess);
    eSystem_RegisterFunction("fputs", "int fputs(char *, void * stream)", fputs, module, baseSystemAccess);
 
@@ -6077,11 +6262,13 @@ public dllexport void eClass_DoneAddingTemplateParameters(Class base)
       {
          void * first = base.templateParams.first;
          int count = base.templateParams.count;
-         base.templateParams.first = null;
-         base.templateParams.count = 0;
 
          FreeTemplateArgs(base);
          delete base.templateArgs;
+
+         base.templateParams.first = null;
+         base.templateParams.count = 0;
+
          FreeTemplatesDerivatives(base);
 
          base.templateParams.first = first;
@@ -6317,6 +6504,14 @@ public DesignerBase GetActiveDesigner()
    return activeDesigner;
 }
 
+
+bool poolingDisabled;
+
+public dllexport void eSystem_SetPoolingDisabled(bool disabled)
+{
+   poolingDisabled = disabled;
+}
+
 namespace sys;
 
 // constants
@@ -6387,6 +6582,10 @@ public int ISO8859_1toUTF8(char * source, char * dest, int max)
    for(c = 0; source[c]; c++)
    {
       unichar ch = ((byte *)source)[c];
+      switch(ch)
+      {
+         case 150: ch = (unichar)0x2012; break;
+      }
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
@@ -6516,13 +6715,14 @@ public int UTF16toUTF8Buffer(uint16 * source, byte * dest, int max)
    return d;
 }
 
+// NOTE: UTF8GetChar now returns 0 into numBytes for the null-terminating character ('\0')
 public unichar UTF8GetChar(char * string, int * numBytes)
 {
    unichar ch;
    byte b = ((byte *)string)[0];
    int i;
    byte mask = 0x7F;
-   int nb = 1;
+   int nb = b ? 1 : 0;
    ch = 0;
    if(b & 0x80)
    {