compiler/bootstrap: Reverted to using 'uintptr' for bootstrap; Hardcoding FileListing...
[sdk] / ecere / src / com / instance.ec
index a3bea42..2f1dca8 100644 (file)
@@ -53,6 +53,12 @@ default:
 
 private:
 
+#if defined(__ANDROID__)
+#include <android/log.h>
+
+#define printf(...)  ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
+#endif
+
 #undef property
 #undef bool
 #undef uint
@@ -189,8 +195,13 @@ public dllexport void MemoryGuard_PopLoc()
 
 default:
 
+#if defined(ECERE_BOOTSTRAP)
+extern bool COM_LOAD_FUNCTION(Module module);
+extern bool COM_UNLOAD_FUNCTION(Module module);
+#else
 extern bool stdcall COM_LOAD_FUNCTION(Module module);
 extern bool stdcall COM_UNLOAD_FUNCTION(Module module);
+#endif
 
 private:
 
@@ -550,8 +561,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;
@@ -1078,7 +1089,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++)
    {
@@ -1093,7 +1104,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;
@@ -1105,7 +1116,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++)
    {
@@ -1144,8 +1155,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]);
@@ -1231,8 +1242,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;
@@ -1279,8 +1290,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;
@@ -1376,7 +1387,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;
@@ -1432,7 +1443,7 @@ static void * _calloc(int n, unsigned int size)
       MemInfo block;
       
       stack.recurse = true;
-      block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
+      block = MemInfo { size = 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;
@@ -1472,7 +1483,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");
@@ -1523,7 +1534,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;
@@ -1560,7 +1571,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");
@@ -1611,7 +1622,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;
@@ -1651,7 +1662,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;
@@ -1767,7 +1778,7 @@ public void CheckMemory()
       memoryErrorsCount++;
    }
    printf("Starting Memory Check\n");
-   for(block = (MemInfo)memBlocks.first; block; block = block.next)
+   for(block = (MemInfo)memBlocks.first; block; block = (MemInfo)block.next)
    {
       if(!block.freed && block._class)
          leakedObjects++;
@@ -1885,14 +1896,27 @@ static void FixDerivativesBase(Class base, Class mod)
       int sizeClass = _class.sizeClass - _class.offsetClass;
       Class enumBase = null;
       char * dataTypeString = null;
+      // NOTE: baseClass is class(class)
       Class baseClass;
       uint offsetBefore = _class.offset;
 
       int offsetClass, totalSizeClass;
 
       for(baseClass = base; baseClass.base; baseClass = baseClass.base);
-      
-      if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass)) type = base.type;
+
+      if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass))
+      {
+         // Normal classes inheriting off simple classes should become no head classes
+         if(base.type == structClass && type == normalClass)
+            type = noHeadClass;
+         else
+            type = base.type;
+      }
+      if(base && (_class.type == normalClass || _class.type == noHeadClass || _class.type == structClass) &&
+         (base.type == unitClass || base.type == bitClass || base.type == enumClass))
+      {
+         type = base.type;
+      }
 
       if(type == enumClass)
       {
@@ -1963,24 +1987,66 @@ static void FixDerivativesBase(Class base, Class mod)
       _class.offsetClass = offsetClass;
       _class.sizeClass = totalSizeClass;
 
-      if(mod.base && mod.base.base && mod.base.vTblSize > baseClass.vTblSize && 
-         (mod != (base.templateClass ? base.templateClass : base) || _class.vTblSize != mod.vTblSize))
       {
          Method method, next;
          Class b;
-         _class.vTblSize += mod.base.vTblSize - baseClass.vTblSize;
-         _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
-         // 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 *));
-         
-         for(method = (Method)_class.methods.first; method; method = next)
+         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)
          {
-            next = (Method)((BTNode)method).next;
-            if(method.type == virtualMethod)
-               method.vid += mod.base.vTblSize - baseClass.vTblSize;
+            _class.vTblSize += mod.base.vTblSize - baseClass.vTblSize;
+            _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
+            // 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;
+               if(method.type == virtualMethod)
+                  method.vid += mod.base.vTblSize - baseClass.vTblSize;
+            }
          }
 
-         // TO CHECK: WHY WAS THIS baseClass? ANY PROBLEMS? CRASH WHEN DECLARING A BASE CLASS LATER (WSMS)
+            for(b = mod.base; b && b != null; b = b.base)
+            {
+               Method vMethod;
+               for(vMethod = (Method)b.methods.first; vMethod; vMethod = (Method)((BTNode)vMethod).next)
+               {
+                  if(vMethod.type == virtualMethod)
+                  {
+                     method = (Method)_class.methods.FindString(vMethod.name);
+                     if(method)
+                     {
+                        if(method.function) _class._vTbl[vMethod.vid] = method.function;
+                        if(!method.symbol)
+                        {
+                           delete method.name;
+                           delete method.dataTypeString;
+                           _class.methods.Delete((BTNode)method);
+                        }
+                        else
+                        {
+                           delete method.dataTypeString;
+                           method.type = vMethod.type;
+                           method.dataTypeString = CopyString(vMethod.dataTypeString);
+                           method._class = vMethod._class;
+                        }
+                     }
+                     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];
+                  }
+               }
+            }
+         //}
+
+         // Trying to simply move out the above block of code outside the if to handle this
+         /*
+         // Also doing this now, otherwise overridden methods of base classes from intermediate classes will not be set in higher level class
+         // (e.g. OnGetString overridden in Id , Location inheriting from Id, LocationAbbreviation created later inheriting from Location would not get Id's OnGetString)
          for(b = mod.base; b && b != null; b = b.base)
          {
             Method vMethod;
@@ -1988,29 +2054,12 @@ static void FixDerivativesBase(Class base, Class mod)
             {
                if(vMethod.type == virtualMethod)
                {
-                  method = (Method)_class.methods.FindString(vMethod.name);
-                  if(method)
-                  {
-                     if(method.function) _class._vTbl[vMethod.vid] = method.function;
-                     if(!method.symbol)
-                     {
-                        delete method.name;
-                        delete method.dataTypeString;
-                        _class.methods.Delete((BTNode)method);
-                     }
-                     else
-                     {
-                        delete method.dataTypeString;
-                        method.type = vMethod.type;
-                        method.dataTypeString = CopyString(vMethod.dataTypeString);
-                        method._class = vMethod._class;
-                     }
-                  }
-                  else
+                  if(_class._vTbl[vMethod.vid] == b._vTbl[vMethod.vid] && _class._vTbl[vMethod.vid] != _class.base._vTbl[vMethod.vid])
                      _class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
                }
             }
          }
+         */
       }
 
       // _class.defaultAlignment = base ? base.defaultAlignment : 0;
@@ -2109,6 +2158,7 @@ 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;
 
    {
       nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
@@ -2413,6 +2463,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
          if(totalSizeClass)
          {
             _class.data = renew _class.data byte[totalSizeClass];
+            // Class Data is often not inherited... e.g. Window::pureVtbl problem
             // memset(_class.data, 0, totalSizeClass);
             if(base && base.type != systemClass && base.type != enumClass)
                memcpy(_class.data, base.data, offsetClass);
@@ -2502,7 +2553,24 @@ 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 ? 24 : sizeof(class Instance)));
+         if(force64Bits)
+         {
+            // For 64 bit cross-compiling from 32 bit library:
+                 if(!strcmp(name, "ecere::com::Class"))           size = 0; // 616
+            else if(!strcmp(name, "ecere::com::ClassProperty"))   size = 0; // 80
+            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(!strcmp(name, "ecere::sys::FileListing"))     size = 3*8;
+         }
          if(type == structClass)
          {
             _class.memberOffset = (base && base.structSize && base.type != systemClass) ? base.structSize : 0;
@@ -2827,7 +2895,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)
    {
@@ -4036,7 +4104,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)
    {
@@ -4044,7 +4112,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);
       }
    }
@@ -4113,28 +4181,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 });
    }
 }
 
@@ -4177,12 +4245,12 @@ public dllexport Method eClass_FindMethod(Class _class, char * name, Module modu
 }
 
 // Construct an instance
-static bool ConstructInstance(void * instance, Class _class)
+static bool ConstructInstance(void * instance, Class _class, Class from)
 {
    if(_class.templateClass) _class = _class.templateClass;
-   if(_class.base)
+   if(_class.base && from != _class.base)
    {
-      if(!ConstructInstance(instance, _class.base))
+      if(!ConstructInstance(instance, _class.base, from))
          return false;
    }
    if(_class.Initialize)
@@ -4238,7 +4306,7 @@ public dllexport void * eInstance_New(Class _class)
          // Copy the virtual table initially
          instance._vTbl = _class._vTbl;
       }
-      if(!ConstructInstance(instance, _class))
+      if(!ConstructInstance(instance, _class, null))
       {
          _free(instance);
          instance = null;
@@ -4253,11 +4321,14 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
 {
    if(_class && instancePtr && *instancePtr)
    {
+      bool wasApp = false, wasGuiApp = false;
       Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
+      Class fromClass = instance._class;
       *instancePtr = instance;
       memset(((byte *)instance) + instance._class.structSize, 0, _class.structSize - instance._class.structSize);
       // Fix pointers to application
-      if(!strcmp(instance._class.name, "Application"))
+      if((wasApp = !strcmp(instance._class.name, "Application")) ||
+         (wasGuiApp = !strcmp(instance._class.name, "GuiApplication")))
       {
          Module module;
          Application app = (Application) instance;
@@ -4322,6 +4393,21 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
                template.module = _class.module;
             }
          }
+
+         for(module = app.allModules.first; module; module = module.next)
+         {
+            for(_class = module.classes.first; _class; _class = _class.next)
+            {
+               OldLink templateLink;
+               _class.module = module;
+               for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
+               {
+                  Class template = templateLink.data;
+                  template.module = _class.module;
+               }
+            }
+         }
+
          app.application = app;
       }
 
@@ -4335,7 +4421,8 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
       // Copy the virtual table initially
       instance._vTbl = _class._vTbl;
 
-      if(!ConstructInstance(instance, _class))
+      // We don't want to reconstruct the portion already constructed...
+      if(!ConstructInstance(instance, _class, fromClass))
       {
          _free(instance);
          *instancePtr = null;
@@ -5744,6 +5831,8 @@ public bool LocateModule(char * name, char * fileName)
 
 static void LoadCOM(Module module)
 {
+   bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
+   int pointerSize = force64Bits ? 8 : sizeof(void *);
    Class applicationClass;
    Class enumClass, structClass, boolClass;
    Class moduleClass;
@@ -5767,16 +5856,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 ? 32 : sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
    eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
    enumClass.type = systemClass;
    
@@ -5803,38 +5891,39 @@ 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 + 8 + 32 + 32 + 32 + 32 + 8 + 8 + 8 + 8 + 8 + 8 + (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 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "defines", "OldList", force64Bits ? 32 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "functions", "OldList", force64Bits ? 32 : sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "modules", "OldList", force64Bits ? 32 : 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) : sizeof(NameSpace), pointerSize, publicAccess);
+   eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : sizeof(NameSpace), pointerSize, publicAccess);
    moduleClass.fixed = true;
    moduleClass.count++;
    
    // 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+8+8 + 32 + 8 + 176) : sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
    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: sizeof(OldList), pointerSize, publicAccess);
+   eClass_AddDataMember(applicationClass, "parsedCommand", "char *", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : sizeof(NameSpace), pointerSize, publicAccess);
    applicationClass.fixed = true;
    applicationClass.count++;
 
@@ -5910,8 +5999,12 @@ static void LoadCOM(Module module)
 
    // --- 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("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("puts", "int puts(char *)", puts, module, baseSystemAccess);
    eSystem_RegisterFunction("fputs", "int fputs(char *, void * stream)", fputs, module, baseSystemAccess);
 
@@ -5930,6 +6023,23 @@ public dllexport Application __ecere_COM_Initialize(bool guiApp, int argc, char
 {
    Application app;
 
+#ifdef __ANDROID__
+   // Clean up global variables
+   memoryInitialized = false;
+   pools = null;
+#ifdef MEMINFO
+   memset(&memStacks, 0, sizeof(BinaryTree));
+   memoryErrorsCount = 0;
+   memset(&memBlocks, 0, sizeof(BinaryTree));
+   recurse = false;
+   blockID = 0;
+   allocateClass = null;
+   allocateInternal = false;
+   TOTAL_MEM = 0;
+   OUTSIDE_MEM = 0;
+#endif
+#endif
+
 #ifdef _DEBUG
    // printf("Using debug ecere runtime library\n");
 #endif