ecere/gui/EditBox: Fixed hanging caused by 308c3f8a022f58c179f5d52f87be2609fba4ddd8
[sdk] / ecere / src / com / instance.ec
index 5bc5a25..21e0c55 100644 (file)
@@ -55,7 +55,8 @@ private:
 
 #if defined(__ANDROID__)
 
-import "AndroidInterface"
+default const char * AndroidInterface_GetLibLocation();
+
 #include <android/log.h>
 #include <android/native_activity.h>
 
@@ -88,6 +89,9 @@ 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(const char * libLocation, const char * name, void ** Load, void ** Unload);
 void Instance_Module_Free(void * library);
+#if defined(_DEBUG)
+void InternalModuleLoadBreakpoint();
+#endif
 
 private:
 
@@ -1192,6 +1196,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 +1205,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;
 }
 
@@ -1358,8 +1363,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());
@@ -1400,11 +1406,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,39 +1423,41 @@ 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 = (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;
+      if(!recurse && !stack.recurse)
+      {
+         MemInfo block;
+
+         stack.recurse = true;
+         block = MemInfo { (unsigned int)n*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;
+      }
    }
 }
 #endif
@@ -1456,10 +1467,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)
@@ -1510,8 +1524,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 +1537,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;
       }
@@ -1547,7 +1565,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)
@@ -1598,8 +1616,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 +1629,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;
       }
@@ -1635,7 +1657,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)
@@ -1713,13 +1735,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 +1751,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 +1877,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++;
@@ -2565,6 +2591,8 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
             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
             {
@@ -2756,6 +2784,7 @@ static void FreeTemplate(Class template)
    delete template.fullName;
    delete template.name;
    delete template.templateArgs;
+   delete template.dataTypeString;
 
    while((deriv = template.derivatives.first))
    {
@@ -2779,6 +2808,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))
    {
@@ -3153,6 +3183,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;
@@ -4320,13 +4351,18 @@ public dllexport void * eInstance_New(Class _class)
 #endif
       {
          int size = _class.structSize;
-         if(_class.module != __thisModule)
-         {
-            int flags = _class.module.application.isGUIApp;
-            bool force32Bits = (flags & 4) ? true : false;
-            bool inCompiler = (flags & 8) ? true : false;
-            if(force32Bits && inCompiler && !strcmp(_class.name, "Module"))
-               size = 12 + 8 + 32 + 32 + 32 + 32 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + (32 + 8 + 8 + 4*32) + (32 + 8 + 8 + 4*32);
+         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);
       }
@@ -5139,12 +5175,7 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
       {
          char * libLocation = null;
 #if defined(__ANDROID__)
-         char loc[MAX_LOCATION];
-         if(androidActivity)
-         {
-            sprintf(loc, "/data/data/com.ecere.%s/lib/lib", androidActivity.moduleName);
-            libLocation = loc;
-         }
+         libLocation = AndroidInterface_GetLibLocation();
 #endif
          library = Instance_Module_Load(libLocation, name, &Load, &Unload);
       }
@@ -5156,6 +5187,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);
@@ -5186,11 +5218,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)
@@ -5211,6 +5245,9 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
       }
       incref module;
    }
+#if defined(_DEBUG)
+   InternalModuleLoadBreakpoint();
+#endif
    return module;
 }
 
@@ -5729,13 +5766,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);
+         }
       }
    }
 }
@@ -6004,7 +6049,7 @@ 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);
@@ -6013,16 +6058,16 @@ static void LoadCOM(Module module)
    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);
 
@@ -6030,7 +6075,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);
@@ -6041,22 +6086,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);
 
@@ -6592,13 +6635,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)
    {