ecere/com/instance: (Emscripten) Disabling memory manager
[sdk] / ecere / src / com / instance.ec
index cf4bee8..1eb27ef 100644 (file)
@@ -1,10 +1,20 @@
+#define _Noreturn
+
 namespace com;
 
+#if defined(__EMSCRIPTEN__)
+ #define DISABLE_MEMMGR
+#endif
+
 import "BinaryTree"
 import "OldList"
 import "String"
 import "dataTypes"
 
+//#define JUST_CHECK_LEAKS
+//#define JUST_CHECK_BOUNDARIES
+
+
 #if defined(ECERE_BOOTSTRAP) || defined(ECERE_STATIC)
 #define dllexport
 #if !defined(ECERE_BOOTSTRAP)
@@ -14,9 +24,15 @@ import "dataTypes"
 
 #undef __BLOCKS__
 
+#if !defined(__EMSCRIPTEN__)
 #if !defined(ECERE_BOOTSTRAP)
 import "Mutex"
 #endif
+#endif
+
+#if defined(__EMSCRIPTEN__)
+#define GetCurrentThreadID()  0
+#endif
 
 // #define MEMINFO
 /*
@@ -25,17 +41,27 @@ import "Mutex"
  #define REDZONE   256
 #endif
 */
-#ifndef REDZONE
+
+#if defined(JUST_CHECK_LEAKS) || !defined(REDZONE)
+#undef REDZONE
 #define REDZONE 0
 #endif
 
+
+#ifdef _DEBUG
+// #define MEMTRACKING
+#endif
+
 #ifdef MEMINFO
+#if !defined(__EMSCRIPTEN__)
 import "Thread"
+#endif
 static define MAX_MEMORY_LOC = 40;
+static define MAX_STACK_FRAMES = 1000;
 
 static class MemStack : BTNode
 {
-   char * frames[1000];
+   const char * frames[MAX_STACK_FRAMES];
    int pos;
    bool recurse;
 };
@@ -48,6 +74,28 @@ static uint memoryErrorsCount = 0;
 default:
 #define property _property
 
+#if defined(DISABLE_MEMMGR)
+
+#ifndef ECERE_BOOTSTRAP
+# include <malloc.h>
+#endif
+
+#if defined(__WIN32__)
+#ifdef ECERE_BOOTSTRAP
+uintsize _msize(void * p);
+#endif
+
+#  define msize _msize
+#else
+#ifdef ECERE_BOOTSTRAP
+uintsize malloc_usable_size(void * p);
+#endif
+
+#  define msize malloc_usable_size
+#endif
+
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 
@@ -69,7 +117,7 @@ default const char * AndroidInterface_GetLibLocation();
 
 public define null = ((void *)0);
 
-dllexport Class eSystem_FindClass(Module module, char * name);
+dllexport Class eSystem_FindClass(Module module, const char * name);
 dllexport void * eSystem_Renew(void * memory, unsigned int size);
 dllexport void * eSystem_Renew0(void * memory, unsigned int size);
 dllexport void * eSystem_New(unsigned int size);
@@ -81,8 +129,12 @@ default:
 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);
+#if defined(__MINGW32__) && !defined(_W64) && __GNUC__ < 4
+dllexport int isblank(int c);
+#endif
+bool Instance_LocateModule(const char * name, const char * fileName);
+void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, const char *** argvPtr);
+void System_SetArgs(int argc, char ** argv, int * argcPtr, const 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)
@@ -91,16 +143,18 @@ void InternalModuleLoadBreakpoint();
 
 private:
 
-public class unichar : uint32
+public class Angle : double;
+
+public class ::unichar : uint32
 {
 
-   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
    {
       UTF32toUTF8Len(&this, 1, tempString, 5);
       return tempString;
    }
 
-   bool OnGetDataFromString(char * string)
+   bool OnGetDataFromString(const char * string)
    {
       int nb;
       this = UTF8GetChar(string, &nb);
@@ -109,18 +163,23 @@ public class unichar : uint32
 
 };
 
+// Forward declarations to hook on to libec:
+class ::Type;
+class ::Instantiation;
+class ::ClassDefinition;
+
 public class Property : struct
 {
 public:
    class_fixed
    class_no_expansion
    Property prev, next;
-   char * name;
+   const char * name;
    bool isProperty;
    AccessMode memberAccess;
    int id;
    Class _class;
-   char * dataTypeString;
+   const char * dataTypeString;
    Class dataTypeClass;
    Type dataType;
 
@@ -132,18 +191,20 @@ public:
    int vid;
    bool conversion;
    uint watcherOffset;
-   char * category;
+   const char * category;
    bool compiled;
    bool selfWatchable, isWatchable;
 };
 
 dllexport void eInstance_FireWatchers(Instance instance, Property _property);
 
-public dllexport void MemoryGuard_PushLoc(char * loc)
+public dllexport void MemoryGuard_PushLoc(const char * loc)
 {
 #ifdef MEMINFO
    MemStack stack;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Wait();
+#endif
    stack = (MemStack)memStacks.Find(GetCurrentThreadID());
    if(!stack)
    {
@@ -151,28 +212,30 @@ public dllexport void MemoryGuard_PushLoc(char * loc)
       stack.key = GetCurrentThreadID();
       memStacks.Add(stack);
    }
-   if(stack.pos < 1000)
+   if(stack.pos < MAX_STACK_FRAMES)
       stack.frames[stack.pos++] = loc;
-   else
-      printf("");
+#if !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
+#endif
 }
 
 public dllexport void MemoryGuard_PopLoc()
 {
 #ifdef MEMINFO
    MemStack stack;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Wait();
+#endif
    stack = (MemStack)memStacks.Find(GetCurrentThreadID());
    if(stack && stack.pos > 0)
    {
       stack.pos--;
    }
-   else
-      printf("");
+#if !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
+#endif
 }
 
 #ifdef ECERE_STATIC
@@ -212,7 +275,7 @@ public class BTNamedLink : struct
 {
    class_fixed
 public:
-   char * name;
+   const char * name;
    BTNamedLink parent, left, right;
    int depth;
    void * data;
@@ -222,7 +285,7 @@ class SelfWatcher : struct
 {
    class_fixed
    SelfWatcher prev, next;
-   void (*callback)(Instance);
+   void (*callback)(void *);
    Property _property;
 };
 
@@ -263,12 +326,12 @@ public:
    class_fixed
    class_no_expansion
    Class prev, next;
-   char * name;
+   const char * name;
    int offset, structSize;
-   int (** _vTbl)();
+   void ** _vTbl;
    int vTblSize;
-   int (*Constructor)(Instance);
-   void (*Destructor)(Instance);
+   bool (*Constructor)(void *);
+   void (*Destructor)(void *);
 
    int offsetClass, sizeClass;
    Class base;
@@ -282,30 +345,30 @@ public:
    ClassType type;
    Module module;
    NameSpace * nameSpace;
-   char * dataTypeString;
+   const char * dataTypeString;
    Type dataType;
    int typeSize;
    int defaultAlignment;
    void (*Initialize)();
    int memberOffset;       // For structs, this includes all base classes structSize. Otherwise it restarts at for each class hierarchy level.
    OldList selfWatchers;
-   char * designerClass;
+   const char * designerClass;
    bool noExpansion;
-   char * defaultProperty;
+   const char * defaultProperty;
    bool comRedefinition;
 
    int count;     // DEBUGGING
 
-   bool isRemote;
+   int isRemote;  // TODO: Convert to an enum, can have values 0..3
    bool internalDecl;
    void * data;
    bool computeSize;
-   int structAlignment;
+   short structAlignment; short pointerAlignment;
    int destructionWatchOffset;
    bool fixed;
    OldList delayedCPValues;
    AccessMode inheritanceAccess;
-   char * fullName;
+   const char * fullName;
    void * symbol;
    OldList conversions;
 
@@ -313,11 +376,11 @@ public:
    ClassTemplateArgument * templateArgs;
    Class templateClass;
    OldList templatized;
-   int numParams;
+   int numParams;       // TOTAL number of params including all base classes; use templateParams.count for this level
    bool isInstanceClass;
    bool byValueSystemClass;
 
-   property char *
+   property const char *
    {
       get { return name; }
       set
@@ -331,12 +394,12 @@ public:
       }
    };
 
-   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
    {
       return name;
    }
 
-   bool OnGetDataFromString(char * string)
+   bool OnGetDataFromString(const char * string)
    {
       Class theClass;
       theClass = eSystem_FindClass(__thisModule, string);
@@ -381,7 +444,7 @@ public:
       // For type
       struct
       {
-         char * dataTypeString;
+         const char * dataTypeString;
          Class dataTypeClass;
          // Type dataType;
       };
@@ -391,7 +454,7 @@ public:
       // For identifier
       struct
       {
-         char * memberString;
+         const char * memberString;
          union
          {
             DataMember member;
@@ -407,12 +470,12 @@ public class ClassTemplateParameter : struct
 class_fixed
 public:
    ClassTemplateParameter prev, next;
-   char * name;
+   const char * name;
    TemplateParameterType type;
    union
    {
       // Class baseClass;                 // For type
-      char * dataTypeString;           // For expression
+      const char * dataTypeString;           // For expression
       TemplateMemberType memberType;   // For identifier
    };
    ClassTemplateArgument defaultArg;
@@ -433,7 +496,7 @@ public class Module
    OldList modules;
 
    Module prev, next;
-   char * name;
+   const char * name;
    void * library;
    void (stdcall * Unload)(Module module);
    ImportType importType;
@@ -447,11 +510,11 @@ public class Module
 public class Application : Module
 {
    int argc;
-   char ** argv;
+   const char ** argv;
    int exitCode;
    bool isGUIApp;
    OldList allModules;
-   char * parsedCommand;
+   const char * parsedCommand;
    NameSpace systemNameSpace;
 };
 */
@@ -461,7 +524,7 @@ public class Method : struct
 {
 public:
    class_fixed
-   char * name;
+   const char * name;
    Method parent, left, right;
    int depth;
    int (*function)();
@@ -469,7 +532,7 @@ public:
    MethodType type;
    Class _class;
    void * symbol;
-   char * dataTypeString;
+   const char * dataTypeString;
    Type dataType;
    AccessMode memberAccess;
 };
@@ -487,7 +550,7 @@ public enum ImportType
 
 public struct NameSpace
 {
-   char * name;
+   const char * name;
    NameSpace * btParent, * left, * right;
    int depth;
 
@@ -518,12 +581,12 @@ public class DataMember : struct
 public:
    class_fixed
    DataMember prev, next;
-   char * name;
+   const char * name;
    bool isProperty;
    AccessMode memberAccess;
    int id;
    Class _class;
-   char * dataTypeString;
+   const char * dataTypeString;
    Class dataTypeClass;
    Type dataType;
 
@@ -533,7 +596,7 @@ public:
    OldList members;
    BinaryTree membersAlpha;
    int memberOffset;
-   int structAlignment;
+   short structAlignment; short pointerAlignment;
 };
 
 public class BitMember : struct
@@ -541,12 +604,12 @@ public class BitMember : struct
 public:
    class_fixed
    BitMember prev, next;
-   char * name;
+   const char * name;
    bool isProperty;
    AccessMode memberAccess;
    int id;
    Class _class;
-   char * dataTypeString;
+   const char * dataTypeString;
    Class dataTypeClass;
    Type dataType;
 
@@ -560,12 +623,12 @@ public class ClassProperty : struct
 {
 public:
    class_fixed
-   char * name;
+   const char * name;
    ClassProperty parent, left, right;
    int depth;
    void (*Set)(Class, int64);
    int64 (*Get)(Class);
-   char * dataTypeString;
+   const char * dataTypeString;
    Type dataType;
    bool constant;
 };
@@ -575,8 +638,8 @@ public class DefinedExpression : struct
 public:
    class_fixed
    DefinedExpression prev, next;
-   char * name;
-   char * value;
+   const char * name;
+   const char * value;
    NameSpace * nameSpace;
 };
 
@@ -585,11 +648,11 @@ public class GlobalFunction : struct
 public:
    class_fixed
    GlobalFunction prev, next;
-   char * name;
+   const char * name;
    int (*function)();
    Module module;
    NameSpace * nameSpace;
-   char * dataTypeString;
+   const char * dataTypeString;
    Type dataType;
    void * symbol;
 };
@@ -599,14 +662,14 @@ public class EnumClassData : struct
 public:
    class_fixed
    OldList values;
-   int largest;
+   int64 largest;
 };
 
 class Watcher : struct
 {
    class_fixed
    Watcher prev, next;
-   void (*callback)(Instance, Instance);
+   void (*callback)(void *, void *);
    Instance object;
 };
 
@@ -624,7 +687,7 @@ static class MemInfo : BTNode //struct
    byte * oldmem;
    uint size;
    bool freed;
-   char * _class;
+   const char * _class;
    uint id;
    char * allocLoc[MAX_MEMORY_LOC];
    char * freeLoc[MAX_MEMORY_LOC];
@@ -667,17 +730,24 @@ bool allocateInternal;
 #endif
 
 static uint TOTAL_MEM = 0;
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static uint OUTSIDE_MEM = 0;
+#endif
 
+#if !defined(__EMSCRIPTEN__)
 #if !defined(ECERE_BOOTSTRAP)
 static Mutex memMutex { };
 #endif
+#endif
 
 private class MemBlock : struct
 {
    MemBlock prev, next;
    MemPart part;
    uint size;
+#if !defined(MEMINFO) && defined(MEMTRACKING)
+   Class _class;
+#endif
 };
 
 private class MemPart : struct
@@ -776,6 +846,7 @@ static uint initNumBlocks[NUM_POOLS] =
 #define SIZE_POSITION(s)   log1_5i(s)
 #define NTH_SIZE(p)        pow1_5(p)
 
+#if 0
 static int power15[] =
 {
 /*
@@ -848,6 +919,7 @@ static int power15[] =
 466624,
 699920
 };
+#endif
 
 private struct BlockPool
 {
@@ -874,8 +946,8 @@ private struct BlockPool
       {
          int c;
 #ifdef _DEBUG
-         uint totalAvailable = 0, totalAllocated = 0, totalBlocks = 0, totalUsed = 0;
-         uint totalParts = 0;
+         /*uint totalAvailable = 0, totalAllocated = 0, totalBlocks = 0, totalUsed = 0;
+         uint totalParts = 0;*/
 #endif
          MemBlock block = (MemBlock)memory;
          MemPart part = calloc(1, sizeof(class MemPart));
@@ -982,6 +1054,7 @@ private struct BlockPool
 
    void Remove(MemBlock block)
    {
+      MemPart part = block.part;
       /*if(blockSize == 28)
          printf("BlockPool::Remove (%d)\n", blockSize);*/
       if(block.prev)
@@ -1003,14 +1076,13 @@ private struct BlockPool
          printf("Setting new free block: part = %x\n", block.part);
       }*/
 
-      block.part.blocksUsed--;
+      part.blocksUsed--;
       numBlocks--;
-      block.part.pool->usedSpace -= block.size;
+      part.pool->usedSpace -= block.size;
 
-      if(!block.part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
+      if(!part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
       {
          MemBlock next = free, prev = null;
-         MemPart part = block.part;
          free = null;
          totalSize -= part.size;
          /*if(blockSize == 28)
@@ -1042,9 +1114,10 @@ private struct BlockPool
    }
 };
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static BlockPool * pools; //[NUM_POOLS];
 
-static uint PosFibonacci(uint number)
+/*static uint PosFibonacci(uint number)
 {
    uint pos;
    uint last = 1, prev = 0;
@@ -1091,6 +1164,7 @@ static uint NextFibonacci(uint number)
          return current;
    }
 }
+*/
 
 static uint log1_5i(uint number)
 {
@@ -1103,6 +1177,7 @@ static uint log1_5i(uint number)
          break;
       current = current * 3 / 2;
       if(current == 1) current = 2;
+      if(current & 7) current += 8 - (current & 7);
    }
    return pos;
 }
@@ -1115,6 +1190,7 @@ static uint pow1_5(uint number)
    {
       current = current * 3 / 2;
       if(current == 1) current = 2;
+      if(current & 7) current += 8 - (current & 7);
    }
    return (uint)current;
 }
@@ -1130,9 +1206,11 @@ static uint pow1_5i(uint number)
          return (uint)current;
       current = current * 3 / 2;
       if(current == 1) current = 2;
+      if(current & 7) current += 8 - (current & 7);
    }
    return (uint)current;
 }
+#endif
 
 // -- Math Helpers ---
 public uint log2i(uint number)
@@ -1150,6 +1228,7 @@ public uint pow2i(uint number)
    return 1<<log2i(number);
 }
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static bool memoryInitialized = false;
 static void InitMemory()
 {
@@ -1173,7 +1252,9 @@ static void InitMemory()
          pools[c].Expand(Max(1, expansion));
    }
 }
+#endif
 
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
 static void * _mymalloc(unsigned int size)
 {
    MemBlock block = null;
@@ -1186,6 +1267,9 @@ static void * _mymalloc(unsigned int size)
          block = pools[p].Add();
          if(block)
          {
+#if defined(MEMTRACKING)
+            block._class = null;
+#endif
             block.size = size;
             pools[p].usedSpace += size;
          }
@@ -1198,6 +1282,9 @@ static void * _mymalloc(unsigned int size)
             TOTAL_MEM += sizeof(class MemBlock) + size;
             OUTSIDE_MEM += sizeof(class MemBlock) + size;
             block.part = null;
+#if defined(MEMTRACKING)
+            block._class = null;
+#endif
             block.size = size;
          }
       }
@@ -1213,6 +1300,7 @@ static void * _mycalloc(int n, unsigned int size)
    return pointer;
 }
 
+
 static void _myfree(void * pointer)
 {
    if(pointer)
@@ -1224,11 +1312,20 @@ static void _myfree(void * pointer)
          printf("WARNING! pool is -1\n");
       else   */
       if(pool)
+      {
+#ifdef _DEBUG
+         memset(pointer, 0xec, block.size);
+#endif
          pool->Remove(block);
+      }
       else
       {
          TOTAL_MEM -= sizeof(class MemBlock) + block.size;
          OUTSIDE_MEM -= sizeof(class MemBlock) + block.size;
+
+#ifdef _DEBUG
+         memset(block, 0xec, sizeof(class MemBlock) + block.size);
+#endif
          free(block);
       }
    }
@@ -1266,6 +1363,7 @@ static void * _myrealloc(void * pointer, unsigned int size)
             TOTAL_MEM += size - newBlock.size;
             OUTSIDE_MEM += size - newBlock.size;
             newPointer = ((struct MemBlock *)newBlock + 1);
+            newBlock.size = size;
          }
       }
    }
@@ -1343,7 +1441,6 @@ static void * _mycrealloc(void * pointer, unsigned int size)
    return newPointer;
 }
 
-#ifndef MEMINFO
 #undef realloc
 #undef crealloc
 #undef malloc
@@ -1359,9 +1456,13 @@ static void * _mycrealloc(void * pointer, unsigned int size)
 
 static void * _malloc(unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   return size ? malloc(size) : null;
+#else
    void * pointer;
 
-#if !defined(ECERE_BOOTSTRAP)
+
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Wait();
 #endif
 
@@ -1388,7 +1489,9 @@ static void * _malloc(unsigned int size)
                printf("      %s\n", stack.frames[c]);
 
          memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
          memMutex.Release();
+#endif
          return null;
       }
 
@@ -1403,7 +1506,7 @@ static void * _malloc(unsigned int size)
    }
 #endif
 
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
 
@@ -1416,12 +1519,17 @@ static void * _malloc(unsigned int size)
    }
 #endif
    return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _calloc(int n, unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   return size ? calloc(n, size) : null;
+#else
    void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Wait();
 #endif
 
@@ -1446,7 +1554,9 @@ static void * _calloc(int n, unsigned int size)
             if(stack.frames[c])
                printf("      %s\n", stack.frames[c]);
          memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
          memMutex.Release();
+#endif
          return null;
       }
 
@@ -1463,7 +1573,7 @@ static void * _calloc(int n, unsigned int size)
    }
 #endif
 
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
 
@@ -1475,12 +1585,19 @@ static void * _calloc(int n, unsigned int size)
    }
 #endif
    return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _realloc(void * pointer, unsigned int size)
 {
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   if(!size) { free(pointer); return null; }
+   return realloc(pointer, size);
+
+#else
    if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Wait();
 #endif
 
@@ -1522,7 +1639,9 @@ static void * _realloc(void * pointer, unsigned int size)
          if(stack.frames[c])
             printf("      %s\n", stack.frames[c]);
       memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
       memMutex.Release();
+#endif
       return null;
    }
    memset(pointer, 0xAB, REDZONE);
@@ -1530,6 +1649,12 @@ static void * _realloc(void * pointer, unsigned int size)
 
    if(block)
    {
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+      memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
+      free((byte *)block.key - REDZONE);
+      memBlocks.Remove(block);
+      free(block);
+#else
       if(block.freed)
       {
          memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
@@ -1547,6 +1672,7 @@ static void * _realloc(void * pointer, unsigned int size)
          memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
          block.freed = true;
       }
+#endif
    }
 
    if(!recurse && !stack.recurse)
@@ -1563,16 +1689,28 @@ static void * _realloc(void * pointer, unsigned int size)
    pointer = realloc(pointer, size);
 #endif
 
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
    return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
 }
 
 static void * _crealloc(void * pointer, unsigned int size)
 {
-   if(!size) return null;
-#if !defined(ECERE_BOOTSTRAP)
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+   uintsize s = pointer ? msize(pointer) : 0;
+   void * p;
+   if(!size) { free(pointer); return null; }
+
+   p = realloc(pointer, size);
+   if(size > s)
+      memset((byte *)p + s, 0, size - s);
+   return p;
+#else
+   if(!size) { _free(pointer); return null; }
+
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Wait();
 #endif
 
@@ -1614,7 +1752,9 @@ static void * _crealloc(void * pointer, unsigned int size)
          if(stack.frames[c])
             printf("      %s\n", stack.frames[c]);
       memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
       memMutex.Release();
+#endif
       return null;
    }
    memset(pointer, 0xAB, REDZONE);
@@ -1622,6 +1762,12 @@ static void * _crealloc(void * pointer, unsigned int size)
 
    if(block)
    {
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+      memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
+      free((byte *)block.key - REDZONE);
+      memBlocks.Remove(block);
+      free(block);
+#else
       if(block.freed)
       {
          memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
@@ -1639,6 +1785,7 @@ static void * _crealloc(void * pointer, unsigned int size)
          memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
          block.freed = true;
       }
+#endif
    }
 
    if(!recurse && !stack.recurse)
@@ -1655,17 +1802,21 @@ static void * _crealloc(void * pointer, unsigned int size)
    pointer = crealloc(pointer, size);
 #endif
 
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
    return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
 }
 
 static void _free(void * pointer)
 {
    if(pointer)
    {
-#if !defined(ECERE_BOOTSTRAP)
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+      free(pointer);
+#else
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
       if(memMutex != pointer) memMutex.Wait();
 #endif
 
@@ -1738,13 +1889,13 @@ static void _free(void * pointer)
                {
                   if(address[-c-1] != 0xAB)
                   {
-                     printf("Buffer Underrun\n");
+                     printf("Buffer Underrun (%d bytes before)\n", c+1);
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
                   if(address[c + size] != 0xAB)
                   {
-                     printf("Buffer Overrun\n");
+                     printf("Buffer Overrun (%d bytes past block)\n", c);
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
@@ -1752,6 +1903,11 @@ static void _free(void * pointer)
             }
 
             block.freed = true;
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+            free((byte *)block.key - REDZONE);
+            memBlocks.Remove(block);
+            free(block);
+#else
             block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
             if(block.oldmem)
             {
@@ -1761,6 +1917,7 @@ static void _free(void * pointer)
             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 *));
+#endif
          }
          stack.recurse = false;
       }
@@ -1769,9 +1926,11 @@ static void _free(void * pointer)
       free(pointer);
 #endif
 
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
       if(memMutex != pointer) memMutex.Release();
 #endif
+
+#endif
    }
 }
 
@@ -1790,6 +1949,14 @@ public void memswap(byte * a, byte * b, uint size)
    }
 }
 
+public void CheckConsistency()
+{
+#ifdef MEMINFO
+   if(!memBlocks.Check())
+      printf("Memory Blocks Tree Integrity Failed\n");
+#endif
+}
+
 public void CheckMemory()
 {
 #ifdef MEMINFO
@@ -1854,7 +2021,7 @@ public void CheckMemory()
       }
    }
 
-   while(block = (MemInfo)memBlocks.root)
+   while((block = (MemInfo)memBlocks.root))
    {
       byte * address;
       int c;
@@ -1880,13 +2047,13 @@ public void CheckMemory()
       {
          if(address[-c-1] != 0xAB)
          {
-            printf("Buffer Underrun\n");
+            printf("Buffer Underrun (%d bytes before)\n", c + 1);
             memoryErrorsCount++;
             block.OutputStacks(block.freed);
          }
          if(address[c + size] != 0xAB)
          {
-            printf("Buffer Overrun\n");
+            printf("Buffer Overrun (%d bytes past)\n", c);
             memoryErrorsCount++;
             block.OutputStacks(block.freed);
          }
@@ -1902,7 +2069,7 @@ public void CheckMemory()
    printf("Memory Check Completed.\n");
 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
    if(memoryErrorsCount)
-      getch();
+      system("pause");
 #endif
 #endif
 }
@@ -1910,7 +2077,6 @@ public void CheckMemory()
 static void FixDerivativesBase(Class base, Class mod)
 {
    OldLink derivative;
-   OldLink templateLink;
 
    ComputeClassParameters(base, strchr(base.name, '<'), null);
 
@@ -1923,7 +2089,7 @@ static void FixDerivativesBase(Class base, Class mod)
       int oldSizeClass = _class.sizeClass;
       int sizeClass = _class.sizeClass - _class.offsetClass;
       Class enumBase = null;
-      char * dataTypeString = null;
+      const char * dataTypeString = null;
       // NOTE: baseClass is class(class)
       Class baseClass;
       uint offsetBefore = _class.offset;
@@ -1967,7 +2133,14 @@ static void FixDerivativesBase(Class base, Class mod)
       // _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
 
       if(type == normalClass || type == noHeadClass)
-         _class.offset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+      {
+         // Use 'memberOffset' for nohead class as the members get added without padding
+         _class.offset = (base && (base.templateClass ? (type == normalClass ? base.templateClass.structSize : base.templateClass.memberOffset) : (type == normalClass ? base.structSize : base.memberOffset)) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+         if(_class.structAlignment && (_class.offset % _class.structAlignment))
+            _class.offset += _class.structAlignment - _class.offset % _class.structAlignment;
+      }
+      else
+         _class.offset = 0; // Force set to 0
 
       if(type == structClass)
       {
@@ -1992,7 +2165,7 @@ static void FixDerivativesBase(Class base, Class mod)
 
       if(_class.type != systemClass)
          _class.type = type;
-      delete _class.dataTypeString;
+      delete (void *)_class.dataTypeString;
       _class.dataTypeString = CopyString(dataTypeString);
 
       if(totalSizeClass != oldSizeClass)
@@ -2018,7 +2191,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;
+         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)
@@ -2027,6 +2200,7 @@ static void FixDerivativesBase(Class base, Class mod)
             _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 *));
+            memcpy(_class._vTbl + baseClass.vTblSize, mod._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
 
             updateStart = baseClass.vTblSize;
             updateEnd = updateStart + mod.base.vTblSize - baseClass.vTblSize;
@@ -2052,13 +2226,13 @@ static void FixDerivativesBase(Class base, Class mod)
                         if(method.function) _class._vTbl[vMethod.vid] = method.function;
                         if(!method.symbol)
                         {
-                           delete method.name;
-                           delete method.dataTypeString;
+                           delete (void *)method.name;
+                           delete (void *)method.dataTypeString;
                            _class.methods.Delete((BTNode)method);
                         }
                         else
                         {
-                           delete method.dataTypeString;
+                           delete (void *)method.dataTypeString;
                            method.type = vMethod.type;
                            method.dataTypeString = CopyString(vMethod.dataTypeString);
                            method._class = vMethod._class;
@@ -2118,8 +2292,8 @@ static void FixDerivativesBase(Class base, Class mod)
                         }
                         _property.selfWatchable = true;
                         _class.prop.Delete((BTNode)link);
-                        delete prop.name;
-                        delete prop.dataTypeString;
+                        delete (void *)prop.name;
+                        delete (void *)prop.dataTypeString;
                         _class.membersAndProperties.Delete(prop);    // Remove only was done before?
                      }
                   }
@@ -2177,7 +2351,7 @@ static void FixDerivativesBase(Class base, Class mod)
       for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
       {
          Class template = templateLink.data;
-         char * templateParams = strchr(template.name, '<');
+         //const char * templateParams = strchr(template.name, '<');
          template.base = base.base;
          template._vTbl = base._vTbl;
          //ComputeClassParameters(template, templateParams, null);
@@ -2194,8 +2368,8 @@ static void FixDerivativesBase(Class base, Class mod)
    }
 }
 
-public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char * baseName, int size, int sizeClass,
-                             bool (* Constructor)(void *),void (* Destructor)(void *),
+public dllexport Class eSystem_RegisterClass(ClassType type, const char * name, const char * baseName, int size, int sizeClass,
+                             bool (* Constructor)(void *), void (* Destructor)(void *),
                              Module module, AccessMode declMode, AccessMode inheritanceAccess)
 {
    int start = 0, c;
@@ -2260,10 +2434,9 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
       int totalSizeClass;
       BTNamedLink classLink = null;
       Class _class = null;
-      char * dataTypeString = null;
+      const char * dataTypeString = null;
       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))
@@ -2378,7 +2551,26 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
       offsetClass = base ? base.sizeClass : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
       totalSizeClass = offsetClass + sizeClass;
 
-      if((_class = eSystem_FindClass(module, name)))
+      _class = eSystem_FindClass(module, name);
+      if(!_class)
+      {
+         const char * colons = RSearchString(name, "::", strlen(name), true, false);
+         if(colons && colons)
+         {
+            _class = eSystem_FindClass(module, colons + 2);
+            if(_class)
+            {
+               if(_class.internalDecl)
+               {
+                  delete (void *)_class.fullName;
+                  _class.fullName = CopyString(name);
+               }
+               else
+                  _class = null;
+            }
+         }
+      }
+      if(_class)
       {
          if(!_class.internalDecl)
          {
@@ -2409,7 +2601,8 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
          }
          {
             NameSpace * ns = _class.nameSpace;
-            while(ns->parent &&
+            while(ns != nameSpace &&
+               ns->parent &&
                !ns->classes.first &&
                !ns->functions.first &&
                !ns->defines.first &&
@@ -2421,7 +2614,6 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                ns = parent;
             }
          }
-         refine = true;
       }
       else
       {
@@ -2452,8 +2644,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                }
             }
 
-            refine = true;
-            delete _class.fullName;
+            delete (void *)_class.fullName;
             _class.fullName = CopyString(name);
          }
          else
@@ -2470,13 +2661,13 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
       }
       if(nameSpace)
       {
-         nameSpace->classes.Add((BTNode)BTNamedLink { name = _class.name, data = _class });
+         nameSpace->classes.Add((BTNode)BTNamedLink { name = (char *)_class.name, data = _class });
          {
             OldLink t;
             for(t = _class.templatized.first; t; t = t.next)
             {
                Class template = t.data;
-               nameSpace->classes.Add((BTNode)BTNamedLink { name = template.name, data = template });
+               nameSpace->classes.Add((BTNode)BTNamedLink { name = (char *)template.name, data = template });
             }
          }
 
@@ -2527,7 +2718,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
             memset((byte *)_class.data + offsetClass, 0, sizeClass);
          }
 
-         delete _class.dataTypeString;
+         delete (void *)_class.dataTypeString;
          _class.dataTypeString = CopyString(dataTypeString);
          _class.defaultAlignment = base ? base.defaultAlignment : 0;
 
@@ -2609,7 +2800,11 @@ 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 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+            _class.offset = (base && base.structSize && base.type != systemClass) ?
+               // Use 'memberOffset' for nohead class as the members get added without padding
+               (base.type == normalClass ? base.structSize : base.memberOffset) : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+         else
+            _class.offset = 0;   // Force set to 0 for redefinitions
 
          // For cross-bitness-compiling
          if(crossBits)
@@ -2621,7 +2816,8 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                !strcmp(name, "LineStyle") ||
                !strcmp(name, "FillStyle") ||
                !strcmp(name, "FontObject") ||
-               !strcmp(name, "SymbolStyle"))
+               !strcmp(name, "FontObject") ||
+               !strcmp(name, "ecere::sys::Thread"))
             {
                _class.offset = force32Bits ? 24 : 12;
             }
@@ -2638,6 +2834,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                {
                   size = 3*(force32Bits ? 4 : 8);
                   _class.structAlignment = force32Bits ? 4 : 8;   // FileListing is problematic because it is a struct with private data that the user allocates
+                  _class.pointerAlignment = 1;
                }
                // These we want to recompute inside the IDE to help the debugger
                else if(!strcmp(name, "ecere::com::Class"))           size = 0; // 616
@@ -2649,6 +2846,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
                else if(!strcmp(name, "ecere::sys::OldList"))         size = 0; // 32
                else if(!strcmp(name, "ecere::sys::Item"))            size = 0;
                else if(!strcmp(name, "ecere::sys::NamedLink"))       size = 0;
+               else if(!strcmp(name, "ecere::sys::NamedLink64"))     size = 0;
                else if(!strcmp(name, "ecere::sys::OldLink"))         size = 0;
                else if(!strcmp(name, "ecere::sys::NamedItem"))       size = 0;
                else if(!strcmp(name, "ecere::sys::NamedItem64"))     size = 0;
@@ -2681,7 +2879,7 @@ public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char *
          }
          _class.offsetClass = offsetClass;
          _class.sizeClass = totalSizeClass;
-         _class.Constructor = (void *)Constructor;
+         _class.Constructor = Constructor;
          _class.Destructor = Destructor;
          if(_class.type != systemClass)
             _class.type = type;
@@ -2753,8 +2951,8 @@ static void DataMember_Free(DataMember parentMember)
 {
    DataMember member;
    BTNamedLink namedLink;
-   delete parentMember.name;
-   delete parentMember.dataTypeString;
+   delete (void *)parentMember.name;
+   delete (void *)parentMember.dataTypeString;
 
    while((member = parentMember.members.first))
    {
@@ -2768,7 +2966,7 @@ static void DataMember_Free(DataMember parentMember)
    }
 }
 
-static void FreeEnumValue(NamedLink value)
+static void FreeEnumValue(NamedLink64 value)
 {
    delete value.name;
 }
@@ -2778,10 +2976,11 @@ static void FreeTemplateArg(Class template, ClassTemplateParameter param, int id
    switch(param.type)
    {
       case type:
-         delete template.templateArgs[id].dataTypeString;
+         delete (void *)template.templateArgs[id].dataTypeString;
+         template.templateArgs[id].dataTypeClass = null;
          break;
       case identifier:
-         delete template.templateArgs[id].memberString;
+         delete (void *)template.templateArgs[id].memberString;
          break;
       case expression:
 
@@ -2812,10 +3011,11 @@ static void FreeTemplateArgs(Class template)
                switch(param.type)
                {
                   case type:
-                     delete template.templateArgs[id].dataTypeString;
+                     delete (void *)template.templateArgs[id].dataTypeString;
+                     template.templateArgs[id].dataTypeClass = null;
                      break;
                   case identifier:
-                     delete template.templateArgs[id].memberString;
+                     delete (void *)template.templateArgs[id].memberString;
                      break;
                   case expression:
                      // delete template.templateArgs[id].dataTypeString;
@@ -2835,14 +3035,12 @@ static void FreeTemplate(Class template)
    if(template.nameSpace)
    {
       BTNamedLink link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
-      template.nameSpace->classes.Delete((BTNode)link);
+      if(link)
+         template.nameSpace->classes.Delete((BTNode)link);
    }
-   FreeTemplateArgs(template);
 
-   delete template.fullName;
-   delete template.name;
-   delete template.templateArgs;
-   delete template.dataTypeString;
+   FreeTemplatesDerivatives(template);
+   FreeTemplateArgs(template);
 
    while((deriv = template.derivatives.first))
    {
@@ -2850,7 +3048,15 @@ static void FreeTemplate(Class template)
       template.derivatives.Delete(deriv);
    }
 
-   _free(template);
+   delete (void *)template.fullName;
+   delete (void *)template.name;
+   delete template.templateArgs;
+   delete (void *)template.dataTypeString;
+
+   if(template.module)
+      template.module.classes.Delete(template);
+   else
+      _free(template);
 }
 
 static void FreeTemplates(Class _class)
@@ -2863,10 +3069,8 @@ static void FreeTemplates(Class _class)
    }
 
    FreeTemplateArgs(_class);
-   //if(_class.templateArgs)
-      //printf("Deleting  Template args for %s\n", _class.name);
    delete _class.templateArgs;
-   delete _class.dataTypeString;
+   delete (void *)_class.dataTypeString;
 
    while((template = _class.templatized.first))
    {
@@ -2885,13 +3089,26 @@ public dllexport void eClass_Unregister(Class _class)
    ClassProperty classProp;
    ClassTemplateParameter param;
 
+   if(_class.templateClass)
+   {
+      // Unregistering templates... Used in IDE to address crash on Ecere classes templatized with imported modules
+      OldLink templateLink;
+      for(templateLink = _class.templateClass.templatized.first; templateLink; templateLink = templateLink.next)
+      {
+         if(templateLink.data == _class)
+         {
+            _class.templateClass.templatized.Delete(templateLink);
+            break;
+         }
+      }
+      FreeTemplate(_class);
+      return;
+   }
+
    delete _class._vTbl;
 
    FreeTemplates(_class);
 
-   FreeTemplateArgs(_class);
-   delete _class.templateArgs;
-
    while((template = _class.templatized.first))
    {
       FreeTemplate(template.data);
@@ -2902,15 +3119,15 @@ public dllexport void eClass_Unregister(Class _class)
    {
       if(!member.isProperty && (member.type == unionMember || member.type == structMember))
          DataMember_Free(member);
-      delete member.name;
-      delete member.dataTypeString;
+      delete (void *)member.name;
+      delete (void *)member.dataTypeString;
       _class.membersAndProperties.Delete(member);
    }
 
    while((member = _class.conversions.first))
    {
-      delete member.name;
-      delete member.dataTypeString;
+      delete (void *)member.name;
+      delete (void *)member.dataTypeString;
       _class.conversions.Delete(member);
    }
 
@@ -2926,15 +3143,15 @@ public dllexport void eClass_Unregister(Class _class)
 
    while((classProp = (ClassProperty)_class.classProperties.first))
    {
-      delete classProp.name;
-      delete classProp.dataTypeString;
+      delete (void *)classProp.name;
+      delete (void *)classProp.dataTypeString;
       _class.classProperties.Delete((BTNode)classProp);
    }
 
    while((method = (Method)_class.methods.first))
    {
-      delete method.name;
-      delete method.dataTypeString;
+      delete (void *)method.name;
+      delete (void *)method.dataTypeString;
       _class.methods.Delete((BTNode)method);
    }
 
@@ -2972,10 +3189,10 @@ public dllexport void eClass_Unregister(Class _class)
       _class.nameSpace->classes.Delete((BTNode)link);
    }
 
-   delete _class.name;
-   delete _class.fullName;
+   delete (void *)_class.name;
+   delete (void *)_class.fullName;
 
-   delete _class.dataTypeString;
+   delete (void *)_class.dataTypeString;
 
    delete _class.data;
 
@@ -2984,17 +3201,17 @@ public dllexport void eClass_Unregister(Class _class)
       switch(param.type)
       {
          case type:
-            delete param.defaultArg.dataTypeString;
+            delete (void *)param.defaultArg.dataTypeString;
             break;
          case identifier:
-            delete param.defaultArg.memberString;
+            delete (void *)param.defaultArg.memberString;
             break;
          case expression:
 
             break;
       }
-      if(param.type != identifier) delete param.dataTypeString;
-      delete param.name;
+      if(param.type != identifier) delete (void *)param.dataTypeString;
+      delete (void *)param.name;
 
       _class.templateParams.Delete(param);
    }
@@ -3003,9 +3220,9 @@ public dllexport void eClass_Unregister(Class _class)
    _free(_class);
 }
 
-static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOffset)
+static BTNamedLink ScanNameSpace(NameSpace nameSpace, const char * name, void * listOffset)
 {
-   BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uint)listOffset);
+   BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uintptr)listOffset);
    BTNamedLink link = (BTNamedLink)tree->Find((uintptr)name);
    NameSpace * child;
    if(!link)
@@ -3020,7 +3237,7 @@ static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOf
    return link;
 }
 
-static BTNamedLink SearchNameSpace(NameSpace nameSpace, char * name, void * listOffset)
+static BTNamedLink SearchNameSpace(NameSpace nameSpace, const char * name, void * listOffset)
 {
    int start = 0, c;
    char ch;
@@ -3051,7 +3268,7 @@ static BTNamedLink SearchNameSpace(NameSpace nameSpace, char * name, void * list
    return null;
 }
 
-static BTNamedLink SearchModule(Module module, char * name, void * listOffset, bool searchPrivate)
+static BTNamedLink SearchModule(Module module, const char * name, void * listOffset, bool searchPrivate)
 {
    SubModule subModule;
    BTNamedLink link;
@@ -3080,7 +3297,7 @@ static BTNamedLink SearchModule(Module module, char * name, void * listOffset, b
    return null;
 }
 
-public int64 _strtoi64(char * string, char ** endString, int base)
+public int64 _strtoi64(const char * string, const char ** endString, int base)
 {
    int64 value = 0;
    int sign = 1;
@@ -3113,29 +3330,24 @@ public int64 _strtoi64(char * string, char ** endString, int base)
       else if(ch >= 'A' && ch <= 'Z')
          ch -= ('A'- 10);
       else
-      {
-         if(endString)
-            *endString = string + c;
          // Invalid character
          break;
-      }
       if(ch < base)
       {
          value *= base;
          value += ch;
       }
       else
-      {
-         if(endString)
-            *endString = string + c;
          // Invalid character
          break;
-      }
    }
+   if(endString)
+      *endString = string + c;
+
    return sign*value;
 }
 
-public uint64 _strtoui64(char * string, char ** endString, int base)
+public uint64 _strtoui64(const char * string, const char ** endString, int base)
 {
    uint64 value = 0;
    int sign = 1;
@@ -3168,33 +3380,28 @@ public uint64 _strtoui64(char * string, char ** endString, int base)
       else if(ch >= 'A' && ch <= 'Z')
          ch -= ('A' - 10);
       else
-      {
-         if(endString)
-            *endString = string + c;
          // Invalid character
          break;
-      }
       if(ch < base)
       {
          value *= base;
          value += ch;
       }
       else
-      {
-         if(endString)
-            *endString = string + c;
          // Invalid character
          break;
-      }
    }
+   if(endString)
+      *endString = string + c;
    return sign*value;
 }
 
-public dllexport Class eSystem_FindClass(Module module, char * name)
+public dllexport Class eSystem_FindClass(Module module, const char * name)
 {
    if(name && module)
    {
       BTNamedLink link;
+      if(!strncmp(name, "const ", 6)) name += 6;
       link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->classes);
       if(link) return link.data;
 
@@ -3243,11 +3450,17 @@ public dllexport Class eSystem_FindClass(Module module, char * 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.nameSpace->classes.Add((BTNode)BTNamedLink { name = (char *)templatedClass.name, data = templatedClass });
                templatedClass.templateArgs = null;
                templatedClass.numParams = 0;
                templatedClass.derivatives = { };
                templatedClass.templatized = { };
+               templatedClass.module = module;
+               templatedClass.count = 0; // TOCHECK: Keeping track of individual templatized classes?
+               templatedClass.prev = null;
+               templatedClass.next = null;
+
+               module.classes.Add(templatedClass);
 
                ComputeClassParameters(templatedClass, templateParams, module);
 
@@ -3265,7 +3478,7 @@ static void CopyTemplateArg(ClassTemplateParameter param, ClassTemplateArgument
    switch(param.type)
    {
       case type:
-         arg.dataTypeString = CopyString(arg.dataTypeString);
+            arg.dataTypeString = CopyString(arg.dataTypeString);
          break;
       case expression:
 
@@ -3276,10 +3489,10 @@ static void CopyTemplateArg(ClassTemplateParameter param, ClassTemplateArgument
    }
 }
 
-static void ComputeClassParameters(Class templatedClass, char * templateParams, Module findModule)
+static void ComputeClassParameters(Class templatedClass, const char * templateParams, Module findModule)
 {
    char ch;
-   char * nextParamStart = templateParams ? (templateParams + 1) : null;
+   const char * nextParamStart = templateParams ? (templateParams + 1) : null;
    ClassTemplateParameter curParam = null;
    Class lastClass = null, sClass;
    int curParamID = 0;
@@ -3343,8 +3556,8 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
 
    while(nextParamStart)
    {
-      char * paramStart = nextParamStart;
-      char * paramEnd;
+      const char * paramStart = nextParamStart;
+      const char * paramEnd;
       int level = 0;
       while(*paramStart == ' ') paramStart++;
       paramEnd = paramStart;
@@ -3359,7 +3572,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
       while(*paramEnd == ' ') paramEnd--;
       if(paramEnd > paramStart)
       {
-         char * ptr, * equal = null;
+         const char * ptr, * equal = null;
          for(ptr = paramStart; ptr <= paramEnd; ptr++)
          {
             if(*ptr == '=')
@@ -3370,7 +3583,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
          }
          if(equal)
          {
-            char * end = equal - 1;
+            const char * end = equal - 1;
             char ident[1024];
 
             while(*end == ' ') end--;
@@ -3482,9 +3695,11 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
             {
                case type:
                   argument.dataTypeString = CopyString(value);
-                  argument.dataTypeClass = eSystem_FindClass(_class.module, value);
-                  if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
-                  if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(findModule, value);
+                  argument.dataTypeClass = eSystem_FindClass(findModule, value);
+                  if(!argument.dataTypeClass)
+                     argument.dataTypeClass = eSystem_FindClass(_class.module, value);
+                  if(!argument.dataTypeClass)
+                     argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
                   break;
                case expression:
                {
@@ -3582,11 +3797,11 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
             CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
             if(param.type == type && param.defaultArg.dataTypeString)
             {
-               templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
+               templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
                if(!templatedClass.templateArgs[curParamID].dataTypeClass)
-                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
                if(!templatedClass.templateArgs[curParamID].dataTypeClass)
-                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
             }
          }
          curParamID++;
@@ -3628,6 +3843,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                         {
                            int id = p;
                            Class sClass;
+                           // NOTE: This struct 'arg' here is only to build up templateString
                            ClassTemplateArgument arg;
                            for(sClass = expClass.base; sClass; sClass = sClass.base) id += sClass.templateParams.count;
                            arg = expClass.templateArgs[id];
@@ -3639,8 +3855,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                               {
                                  if(cParam.type == type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
                                  {
-                                    arg.dataTypeString = templatedClass.templateArgs[p].dataTypeString;
-                                    arg.dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
+                                    arg = templatedClass.templateArgs[p];
                                     break;
                                  }
                               }
@@ -3710,7 +3925,9 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                      FreeTemplateArg(templatedClass, param, c);
 
                      arg->dataTypeString = CopyString(templateString);
-                     arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
+                     arg->dataTypeClass = eSystem_FindClass(findModule, templateString);
+                     if(!arg->dataTypeClass)
+                        arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
                      if(!arg->dataTypeClass)
                         arg->dataTypeClass = eSystem_FindClass(templatedClass.module.application, templateString);
                   }
@@ -3725,6 +3942,7 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                         {
                            FreeTemplateArg(templatedClass, param, c);
 
+                           // TRICKY: This copies from equivalent parameters
                            arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
                            arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
                            CopyTemplateArg(cParam, arg);
@@ -3762,11 +3980,11 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
                if(param.type == type && param.defaultArg.dataTypeString)
                {
-                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
+                  templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
                   if(!templatedClass.templateArgs[curParamID].dataTypeClass)
-                     templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+                     templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
                   if(!templatedClass.templateArgs[curParamID].dataTypeClass)
-                     templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+                     templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
                }
             }
             curParamID++;
@@ -3825,9 +4043,9 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
             if(param.type == identifier && arg->memberString)
             {
                Class memberClass = templatedClass;
-               char * memberString = arg->memberString;
-               char * colon = strstr(memberString, "::");
-               char * memberName = memberString;
+               const char * memberString = arg->memberString;
+               const char * colon = strstr(memberString, "::");
+               const char * memberName = memberString;
                if(colon) memberName = colon + 2;
                if(!colon)
                {
@@ -3864,10 +4082,10 @@ static void ComputeClassParameters(Class templatedClass, char * templateParams,
                         id++;
                      }
                   }
-                  memberClass = eSystem_FindClass(templatedClass.module, className);
                   // TESTING: Added this here...
+                  memberClass = eSystem_FindClass(findModule, className);
                   if(!memberClass)
-                     memberClass = eSystem_FindClass(findModule, className);
+                     memberClass = eSystem_FindClass(templatedClass.module, className);
                   if(!memberClass)
                      memberClass = eSystem_FindClass(templatedClass.module.application, className);
                }
@@ -3963,7 +4181,7 @@ public dllexport bool eClass_IsDerived(Class _class, Class from)
    return false;
 }
 
-static void FixDerivativeVirtualMethod(Class base, char * name, int vid, void * origFunction, char * type)
+static void FixDerivativeVirtualMethod(Class base, const char * name, int vid, void * origFunction, const char * type)
 {
    OldLink derivative;
    for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
@@ -3983,13 +4201,13 @@ static void FixDerivativeVirtualMethod(Class base, char * name, int vid, void *
 
          if(!method.symbol)
          {
-            delete method.name;
-            delete method.dataTypeString;
+            delete (void *)method.name;
+            delete (void *)method.dataTypeString;
             _class.methods.Delete((BTNode)method);
          }
          else
          {
-            delete method.dataTypeString;
+            delete (void *)method.dataTypeString;
             method.type = virtualMethod;
             method.dataTypeString = CopyString(type);
             method._class = base;
@@ -4025,17 +4243,19 @@ 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)
+public dllexport Method eClass_AddMethod(Class _class, const char * name, const char * type, void * function, AccessMode declMode)
 {
    if(_class && !_class.comRedefinition && name)
    {
       Class base;
       for(base = _class; base; base = base.base)
       {
-         Method method = (Method)base.methods.FindString(name);
+         Method method;
+         if(base.templateClass) base = base.templateClass;
+         method = (Method)base.methods.FindString(name);
          if(method)
          {
-            // If this overides a virtual method
+            // If this overrides a virtual method
             if(method.type == virtualMethod)
             {
                OldLink deriv;
@@ -4043,7 +4263,7 @@ public dllexport Method eClass_AddMethod(Class _class, char * name, char * type,
                if(method.vid >= _class.vTblSize)
                   printf("error: virtual methods overriding failure\n");
                else
-                  _class._vTbl[method.vid] = function ? function : DefaultFunction;
+                  _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
                for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
                {
                   Class derivClass = deriv.data;
@@ -4084,7 +4304,7 @@ public dllexport Method eClass_AddMethod(Class _class, char * name, char * type,
          Method method
          {
             name = CopyString(name),
-            function = function ? function : DefaultFunction;
+            function = function ? function : null; //DefaultFunction;
             _class = _class;
             dataTypeString = CopyString(type);
             memberAccess = declMode;
@@ -4096,7 +4316,7 @@ public dllexport Method eClass_AddMethod(Class _class, char * name, char * type,
    return null;
 }
 
-public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
+public dllexport Method eClass_AddVirtualMethod(Class _class, const char * name, const char * type, void * function, AccessMode declMode)
 {
    if(_class && !_class.comRedefinition && name)
    {
@@ -4112,7 +4332,7 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char
                if(method.vid >= _class.vTblSize)
                   printf("error: virtual methods overriding failure\n");
                else
-                  _class._vTbl[method.vid] = function ? function : DefaultFunction;
+                  _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
             }
             else
                base = null;
@@ -4125,7 +4345,7 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char
          Method method
          {
             name = CopyString(name);
-            function = function ? function : DefaultFunction;
+            function = function ? function : null; //DefaultFunction;
             type = virtualMethod;
             _class = _class;
             vid = _class.vTblSize++;
@@ -4134,11 +4354,11 @@ public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char
          };
          _class.methods.Add((BTNode)method);
          _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
-         _class._vTbl[method.vid] = function ? function : DefaultFunction;
+         _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
 
          // TODO: Fix derived classes
          if(_class.derivatives.first || _class.templatized.first)
-            FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : (void *)DefaultFunction, type);
+            FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : null /*(void *)DefaultFunction*/, type);
          return method;
       }
    }
@@ -4166,8 +4386,8 @@ static void FixDerivativeProperty(Class base, Property _property)
             }
             _property.selfWatchable = true;
 
-            delete prop.name;
-            delete prop.dataTypeString;
+            delete (void *)prop.name;
+            delete (void *)prop.dataTypeString;
             _class.membersAndProperties.Delete(prop);
             _class.prop.Delete((BTNode)link);
          }
@@ -4182,12 +4402,18 @@ static void FixDerivativeProperty(Class base, Property _property)
    }
 }
 
-public dllexport Property eClass_AddProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt, AccessMode declMode)
+public dllexport Property eClass_AddProperty(Class _class, const char * name, const char * dataType, void * setStmt, void * getStmt, AccessMode declMode)
 {
    Property _property = null;
    if(_class)
    {
       BTNamedLink link = (BTNamedLink)_class.prop.FindString(name ? name : dataType);
+      bool isConversion = name ? false : true;
+      if(!name && dataType && !strncmp(dataType, "const ", 6))
+      {
+         name = dataType + 6;
+         isConversion = true;
+      }
       if(link)
          _property = link.data;
       if(!_property)
@@ -4202,10 +4428,10 @@ public dllexport Property eClass_AddProperty(Class _class, char * name, char * d
             dataTypeString = CopyString(dataType);
             _class = _class;
             compiled = true;
-            conversion = name ? false : true;
+            conversion = isConversion;
             memberAccess = declMode;
          };
-         if(name)
+         if(!isConversion)
             _class.membersAndProperties.Add(_property);
          else
             _class.conversions.Add(_property);
@@ -4242,7 +4468,7 @@ static void SetDelayedCPValues(Class _class, ClassProperty _property)
    }
 }
 
-public dllexport ClassProperty eClass_AddClassProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt)
+public dllexport ClassProperty eClass_AddClassProperty(Class _class, const char * name, const char * dataType, void * setStmt, void * getStmt)
 {
    if(name && !_class.classProperties.FindString(name))
    {
@@ -4274,7 +4500,7 @@ public dllexport Time GetClassFindTime()
    return classFindTotalTime;
 }
 */
-public dllexport ClassProperty eClass_FindClassProperty(Class _class, char * name)
+public dllexport ClassProperty eClass_FindClassProperty(Class _class, const char * name)
 {
    //Time startTime = GetTime();
    ClassProperty _property = null;
@@ -4300,7 +4526,7 @@ public dllexport ClassProperty eClass_FindClassProperty(Class _class, char * nam
    return _property;
 }
 
-public dllexport int64 eClass_GetProperty(Class _class, char * name)
+public dllexport int64 eClass_GetProperty(Class _class, const char * name)
 {
    ClassProperty _property = eClass_FindClassProperty(_class, name);
    if(_property && _property.Get && _property.Get != (void *)1)
@@ -4311,7 +4537,7 @@ public dllexport int64 eClass_GetProperty(Class _class, char * name)
    return 0;
 }
 
-public dllexport void eClass_SetProperty(Class _class, char * name, int64 value)
+public dllexport void eClass_SetProperty(Class _class, const char * name, int64 value)
 {
    ClassProperty _property = eClass_FindClassProperty(_class, name);
    if(_property)
@@ -4321,11 +4547,11 @@ public dllexport void eClass_SetProperty(Class _class, char * name, int64 value)
    }
    else
    {
-      _class.delayedCPValues.Add(NamedLink64 { name = name, value });
+      _class.delayedCPValues.Add(NamedLink64 { name = (char *)name, value });
    }
 }
 
-public dllexport Method eClass_FindMethod(Class _class, char * name, Module module)
+public dllexport Method eClass_FindMethod(Class _class, const char * name, Module module)
 {
    //Time startTime = GetTime();
    if(_class && name)
@@ -4404,7 +4630,9 @@ public dllexport void * eInstance_New(Class _class)
 #ifdef MEMINFO
 
 #undef malloc
+#if !defined(__EMSCRIPTEN__)
    memMutex.Wait();
+#endif
       //allocateClass = _class;
       allocateClass = malloc(strlen(_class.name)+1);
       allocateInternal = _class.module == __thisModule;
@@ -4430,18 +4658,32 @@ public dllexport void * eInstance_New(Class _class)
                size *= 3;
          }
          instance = _calloc(1, size);
+         if(!instance && size)
+            printf("Failed to allocate memory instantiating %s object!\n", _class.name);
+         else if(!size)
+            printf("Warning: 0 size instantiating %s object!\n", _class.name);
       }
 #ifdef MEMINFO
       allocateClass = null;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
-      if(_class.type == normalClass)
+#endif
+
+#if !defined(MEMINFO) && defined(MEMTRACKING)
+      {
+         MemBlock block = (MemBlock)((byte *)instance - sizeof(class MemBlock));
+         block._class = _class;
+      }
+#endif
+
+      if(instance && _class.type == normalClass)
       {
          instance._class = _class;
          // Copy the virtual table initially
          instance._vTbl = _class._vTbl;
       }
-      if(!ConstructInstance(instance, _class, null))
+      if(instance && !ConstructInstance(instance, _class, null))
       {
          _free(instance);
          instance = null;
@@ -4457,6 +4699,7 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
    if(_class && instancePtr && *instancePtr)
    {
       bool wasApp = false, wasGuiApp = false;
+      Instance oldInstance = *instancePtr;
       Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
       Class fromClass = instance._class;
       *instancePtr = instance;
@@ -4525,7 +4768,8 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
             for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
             {
                Class template = templateLink.data;
-               template.module = _class.module;
+               if(template.module == oldInstance)
+                  template.module = _class.module;
             }
          }
 
@@ -4534,11 +4778,13 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
             for(_class = module.classes.first; _class; _class = _class.next)
             {
                OldLink templateLink;
+               Module oldModule = _class.module;
                _class.module = module;
                for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
                {
                   Class template = templateLink.data;
-                  template.module = _class.module;
+                  if(template.module == oldModule)
+                     template.module = _class.module;
                }
             }
          }
@@ -4659,11 +4905,14 @@ public dllexport void eInstance_Delete(Instance instance)
    }
 }
 
-public dllexport Property eClass_FindProperty(Class _class, char * name, Module module)
+public dllexport Property eClass_FindProperty(Class _class, const char * name, Module module)
 {
    //Time startTime = GetTime();
    if(_class && name)
    {
+      if(!strncmp(name, "const ", 6))
+         name += 6;
+
       for(; _class; _class = _class.base)
       {
          BTNamedLink link;
@@ -4701,7 +4950,7 @@ public dllexport Property eClass_FindProperty(Class _class, char * name, Module
    return null;
 }
 
-static DataMember FindDataMember(OldList list, BinaryTree alist, char * name, uint * offset, int * id, bool searchPrivate, DataMember * subMemberStack, int * subMemberStackPos)
+static DataMember FindDataMember(OldList list, BinaryTree alist, const char * name, uint * offset, int * id, bool searchPrivate, DataMember * subMemberStack, int * subMemberStackPos)
 {
    BTNamedLink link;
    DataMember dataMember;
@@ -4739,7 +4988,7 @@ static DataMember FindDataMember(OldList list, BinaryTree alist, char * name, ui
    return null;
 }
 
-public dllexport DataMember eClass_FindDataMember(Class _class, char * name, Module module, DataMember * subMemberStack, int * subMemberStackPos)
+public dllexport DataMember eClass_FindDataMember(Class _class, const char * name, Module module, DataMember * subMemberStack, int * subMemberStackPos)
 {
    //Time startTime = GetTime();
    DataMember dataMember = null;
@@ -4781,7 +5030,7 @@ public dllexport DataMember eClass_FindDataMember(Class _class, char * name, Mod
    return dataMember;
 }
 
-public dllexport DataMember eClass_FindDataMemberAndOffset(Class _class, char * name, uint * offset, Module module, DataMember * subMemberStack, int * subMemberStackPos)
+public dllexport DataMember eClass_FindDataMemberAndOffset(Class _class, const char * name, uint * offset, Module module, DataMember * subMemberStack, int * subMemberStackPos)
 {
    //Time startTime = GetTime();
    DataMember dataMember = null;
@@ -4824,7 +5073,7 @@ public dllexport DataMember eClass_FindDataMemberAndOffset(Class _class, char *
    return dataMember;
 }
 
-public dllexport DataMember eClass_FindDataMemberAndId(Class _class, char * name, int * id, Module module, DataMember * subMemberStack, int * subMemberStackPos)
+public dllexport DataMember eClass_FindDataMemberAndId(Class _class, const char * name, int * id, Module module, DataMember * subMemberStack, int * subMemberStackPos)
 {
    //Time startTime = GetTime();
    DataMember dataMember = null;
@@ -4937,8 +5186,12 @@ public dllexport void eClass_FindNextMember(Class _class, Class * curClass, Data
          else
             while(*curMember && (*curMember).name)      // ADDED THIS HERE for eComPacket packet { Connect, 0, { ECOMMUNICATOR_PROTOCOL_VERSION } };
             {
-               DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
-               if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
+               DataMember dataMember = null;
+               if(((*curMember).memberAccess != privateAccess))
+               {
+                  dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
+                  if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
+               }
                if(dataMember && dataMember.memberAccess != privateAccess && dataMember.id >= 0) // Skip _vTbl, _refCount and _class in Instance
                {
                   *curMember = dataMember;
@@ -4963,7 +5216,7 @@ public dllexport void eClass_FindNextMember(Class _class, Class * curClass, Data
    }
 }
 
-public dllexport void eInstance_SetMethod(Instance instance, char * name, void * function)     // YET TO BE DECIDED:   , Module module)
+public dllexport void eInstance_SetMethod(Instance instance, const char * name, void * function)     // YET TO BE DECIDED:   , Module module)
 {
    if(instance && name)
    {
@@ -4979,7 +5232,7 @@ public dllexport void eInstance_SetMethod(Instance instance, char * name, void *
                memcpy(instance._vTbl, instance._class._vTbl,
                   sizeof(int(*)()) * instance._class.vTblSize);
             }
-            instance._vTbl[method.vid] = function ? function : DefaultFunction;
+            instance._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
          }
       }
    }
@@ -5036,8 +5289,8 @@ public dllexport void eClass_Resize(Class _class, int newSize)
    for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
       FixOffsets(deriv.data);
 }
-
-public dllexport DataMember eClass_AddDataMember(Class _class, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
+                                                                                                                        // F000F000 will mean a pointer size alignment
+public dllexport DataMember eClass_AddDataMember(Class _class, const char * name, const char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
 {
    if(_class && name)
    {
@@ -5047,8 +5300,37 @@ public dllexport DataMember eClass_AddDataMember(Class _class, char * name, char
 
          if(alignment)
          {
+            bool pointerAlignment = alignment == 0xF000F000;
+            bool force64Bits = (_class.module.application.isGUIApp & 2) ? true : false;
+            bool force32Bits = (_class.module.application.isGUIApp & 4) ? true : false;
+            if((force32Bits || force64Bits) && !strcmp(_class.name, "AVLNode") && !strcmp(name, "__ecerePrivateData0"))
+            {
+               if(force64Bits)
+               {
+                  type = "byte[32]";
+                  size = 32;
+               }
+               if(force32Bits)
+               {
+                  type = "byte[16]";
+                  size = 16;
+               }
+            }
+
+            if(pointerAlignment) alignment = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
+
+            if(pointerAlignment && _class.structAlignment <= 4)
+               _class.pointerAlignment = 1;
+            else if(!pointerAlignment && alignment >= 8)
+               _class.pointerAlignment = 0;
+
             _class.structAlignment = Max(_class.structAlignment, alignment);
 
+            if(_class.offset % alignment)
+            {
+               _class.structSize += alignment - (_class.offset % alignment);
+               _class.offset += alignment - (_class.offset % alignment);
+            }
             if(_class.memberOffset % alignment)
                _class.memberOffset += alignment - (_class.memberOffset % alignment);
          }
@@ -5072,8 +5354,8 @@ public dllexport DataMember eClass_AddDataMember(Class _class, char * name, char
    }
    return null;
 }
-
-public dllexport DataMember eMember_AddDataMember(DataMember member, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
+                                                                                                                              // F000F000 will mean a pointer size alignment
+public dllexport DataMember eMember_AddDataMember(DataMember member, const char * name, const char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
 {
    if(name && !member.membersAlpha.FindString(name))
    {
@@ -5081,6 +5363,16 @@ public dllexport DataMember eMember_AddDataMember(DataMember member, char * name
 
       if(alignment)
       {
+         bool pointerAlignment = alignment == 0xF000F000;
+         bool force64Bits = false; //(member._class.module.application.isGUIApp & 2) ? true : false;
+         bool force32Bits = false; //(member._class.module.application.isGUIApp & 4) ? true : false;
+         if(pointerAlignment) alignment = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
+
+         if(pointerAlignment && member.structAlignment <= 4)
+            member.pointerAlignment = 1;
+         else if(!pointerAlignment && alignment >= 8)
+            member.pointerAlignment = 0;
+
          member.structAlignment = Max(member.structAlignment, alignment);
 
          if(member.memberOffset % alignment)
@@ -5145,8 +5437,21 @@ public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
    else
       addTo.memberID += dataMember.memberID;
 
+   if(dataMember.pointerAlignment && dataMember.structAlignment <= 4)
+      addTo.pointerAlignment = 1;
+   else if(!dataMember.pointerAlignment && dataMember.structAlignment >= 8)
+      addTo.pointerAlignment = 0;
+
    addTo.structAlignment = Max(addTo.structAlignment, dataMember.structAlignment);
+
    dataMember.offset = (addTo.type == unionMember) ? 0 : addTo.memberOffset;
+
+   if(dataMember.structAlignment)
+   {
+      if(addTo.memberOffset % dataMember.structAlignment)
+         addTo.memberOffset += dataMember.structAlignment - (addTo.memberOffset % dataMember.structAlignment);
+   }
+
    if(addTo.type == unionMember)
    {
       if(dataMember.memberOffset > addTo.memberOffset)
@@ -5176,17 +5481,29 @@ public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
    //dataMember.id = _class.memberID++;
    dataMember.id = _class.memberID;
 
+   if(dataMember.pointerAlignment && dataMember.structAlignment <= 4)
+      _class.pointerAlignment = 1;
+   else if(!dataMember.pointerAlignment && dataMember.structAlignment >= 8)
+      _class.pointerAlignment = 0;
+
    _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
    if(dataMember.type == unionMember)
       _class.memberID += 1;
    else
       _class.memberID += dataMember.memberID;
+
+   if(dataMember.structAlignment)
+   {
+      if(_class.memberOffset % dataMember.structAlignment)
+         _class.memberOffset += dataMember.structAlignment - (_class.memberOffset % dataMember.structAlignment);
+   }
+
    dataMember.offset = _class.memberOffset;
    _class.memberOffset += dataMember.memberOffset;
    return true;
 }
 
-public dllexport BitMember eClass_AddBitMember(Class _class, char * name, char * type, int bitSize, int bitPos, AccessMode declMode)
+public dllexport BitMember eClass_AddBitMember(Class _class, const char * name, const char * type, int bitSize, int bitPos, AccessMode declMode)
 {
    if(_class && name && !_class.members.FindString(name))
    {
@@ -5221,7 +5538,7 @@ public dllexport BitMember eClass_AddBitMember(Class _class, char * name, char *
    return null;
 }
 
-static Module Module_Load(Module fromModule, char * name, AccessMode importAccess, bool ensureCOM)
+static Module Module_Load(Module fromModule, const char * name, AccessMode importAccess, bool ensureCOM)
 {
    bool (stdcall * Load)(Module module) = null;
    bool (stdcall * Unload)(Module module) = null;
@@ -5251,7 +5568,7 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
       }
       else
       {
-         char * libLocation = null;
+         const char * libLocation = null;
 #if defined(__ANDROID__)
          libLocation = AndroidInterface_GetLibLocation();
 #endif
@@ -5291,7 +5608,7 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
    {
       name = !strcmp(module.name, "ecereCOM") ? "ecere" : "ecereCOM";
       if((!Load && !strcmp(module.name, "ecereCOM")) ||
-         (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != COM_LOAD_FUNCTION))
+         (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != (void *)COM_LOAD_FUNCTION))
       {
          Module module;
          for(module = fromModule.application.allModules.first; module; module = module.next)
@@ -5342,17 +5659,17 @@ static Module Module_Load(Module fromModule, char * name, AccessMode importAcces
    return module;
 }
 
-public dllexport Module eModule_Load(Module fromModule, char * name, AccessMode importAccess)
+public dllexport Module eModule_Load(Module fromModule, const char * name, AccessMode importAccess)
 {
    return Module_Load(fromModule, name, importAccess, true);
 }
 
-public dllexport Module eModule_LoadStrict(Module fromModule, char * name, AccessMode importAccess)
+public dllexport Module eModule_LoadStrict(Module fromModule, const char * name, AccessMode importAccess)
 {
    return Module_Load(fromModule, name, importAccess, false);
 }
 
-public dllexport Module eModule_LoadStatic(Module fromModule, char * name, AccessMode importAccess, bool (* Load)(Module module), bool (* Unload)(Module module))
+public dllexport Module eModule_LoadStatic(Module fromModule, const char * name, AccessMode importAccess, bool (* Load)(Module module), bool (* Unload)(Module module))
 {
    Module module;
    for(module = fromModule.application.allModules.first; module; module = module.next)
@@ -5403,38 +5720,38 @@ public dllexport void eModule_Unload(Module fromModule, Module module)
    }
 }
 
-public dllexport void eEnum_AddFixedValue(Class _class, char * string, int value)
+public dllexport void eEnum_AddFixedValue(Class _class, const char * string, int64 value)
 {
    if(_class && _class.type == enumClass)
    {
       EnumClassData data = (EnumClassData)_class.data;
-      NamedLink item;
+      NamedLink64 item;
 
       for(item = data.values.first; item; item = item.next)
          if(!strcmp(item.name, string))
             break;
       if(!item)
       {
-         data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
+         data.values.Add(NamedLink64 { data = value, name = CopyString(string) });
          if(value > data.largest)
             data.largest = value;
       }
    }
 }
 
-public dllexport int eEnum_AddValue(Class _class, char * string)
+public dllexport int64 eEnum_AddValue(Class _class, const char * string)
 {
    if(_class && _class.type == enumClass)
    {
       EnumClassData data = (EnumClassData)_class.data;
-      int value = ((int) data.largest) + 1;
-      NamedLink item;
+      int64 value = data.largest + 1;
+      NamedLink64 item;
       for(item = data.values.first; item; item = item.next)
          if(!strcmp(item.name, string))
             break;
       if(!item)
       {
-         data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
+         data.values.Add(NamedLink64 { data = value, name = CopyString(string) });
          if(value > data.largest)
             data.largest = value;
          return value;
@@ -5446,7 +5763,20 @@ public dllexport int eEnum_AddValue(Class _class, char * string)
 static void NameSpace_Free(NameSpace parentNameSpace)
 {
    NameSpace * nameSpace;
-   delete parentNameSpace.name;
+   delete (void *)parentNameSpace.name;
+
+         /*   {
+      BTNamedLink n, next;
+      for(n = (BTNamedLink)parentNameSpace.classes.first; n; n = next)
+      {
+         Class c = n.data;
+
+         next = (BTNamedLink)((BTNode)n).next;
+
+         if(c.templateClass)
+            eClass_Unregister(c);
+      }
+   }         */
 
    while((nameSpace = (NameSpace *)parentNameSpace.nameSpaces.first))
    {
@@ -5459,7 +5789,7 @@ static void Application_Destructor(Application app)
 {
    if(app.parsedCommand)
    {
-      delete app.argv;
+      delete (void *)app.argv;
       delete app.parsedCommand;
    }
 }
@@ -5545,17 +5875,26 @@ static void Module_Destructor(Module module)
       if(_class.nameSpace)
       {
          BTNamedLink classLink = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
-         OldLink t;
-         for(t = _class.templatized.first; t; t = t.next)
+         if(classLink)
          {
-            Class template = t.data;
-            BTNamedLink link;
-            link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
+            OldLink t;
+            for(t = _class.templatized.first; t; t = t.next)
+            {
+               Class template = t.data;
+               BTNamedLink link;
+               link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
 
-            template.nameSpace->classes.Delete((BTNode)link);
-            template.nameSpace = null;
+               template.nameSpace->classes.Delete((BTNode)link);
+               template.nameSpace = null;
+            }
+            _class.nameSpace->classes.Delete((BTNode)classLink);
          }
-         _class.nameSpace->classes.Delete((BTNode)classLink);
+#ifdef _DEBUG
+         else
+         {
+            printf("Warning: Could not find %s in namespace classes while destructing module %s\n", _class.name, module.name);
+         }
+#endif
          _class.nameSpace = null;
       }
       _class.module = null;
@@ -5583,8 +5922,8 @@ static void Module_Destructor(Module module)
                break;
             }
       }
-      delete def.name;
-      delete def.value;
+      delete (void *)def.name;
+      delete (void *)def.value;
       module.defines.Delete(def);
    }
 
@@ -5601,12 +5940,12 @@ static void Module_Destructor(Module module)
                break;
             }
       }
-      delete function.name;
-      delete function.dataTypeString;
+      delete (void *)function.name;
+      delete (void *)function.dataTypeString;
       module.functions.Delete(function);
    }
 
-   delete module.name;
+   delete (void *)module.name;
 
    NameSpace_Free(module.privateNameSpace);
    NameSpace_Free(module.publicNameSpace);
@@ -5632,7 +5971,7 @@ static int64 GetEnumSize(Class _class)
 #define strnicmp strncasecmp
 #endif
 
-#if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__))
+#if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__) && !defined(__EMSCRIPTEN__))
 #undef strlwr
 #undef strupr
 default dllexport char * strlwr(char *string)
@@ -5653,7 +5992,7 @@ default dllexport char * strupr(char *string)
 }
 #endif
 
-public dllexport DefinedExpression eSystem_RegisterDefine(char * name, char * value, Module module, AccessMode declMode)
+public dllexport DefinedExpression eSystem_RegisterDefine(const char * name, const char * value, Module module, AccessMode declMode)
 {
    NameSpace * nameSpace = null;
 
@@ -5713,7 +6052,7 @@ public dllexport DefinedExpression eSystem_RegisterDefine(char * name, char * va
    return null;
 }
 
-public dllexport GlobalFunction eSystem_RegisterFunction(char * name, char * type, void * func, Module module, AccessMode declMode)
+public dllexport GlobalFunction eSystem_RegisterFunction(const char * name, const char * type, void * func, Module module, AccessMode declMode)
 {
    NameSpace * nameSpace = null;
    int start = 0, c;
@@ -5774,7 +6113,7 @@ public dllexport GlobalFunction eSystem_RegisterFunction(char * name, char * typ
    return null;
 }
 
-public dllexport DefinedExpression eSystem_FindDefine(Module module, char * name)
+public dllexport DefinedExpression eSystem_FindDefine(Module module, const char * name)
 {
    if(name && module)
    {
@@ -5788,7 +6127,7 @@ public dllexport DefinedExpression eSystem_FindDefine(Module module, char * name
    return null;
 }
 
-public dllexport GlobalFunction eSystem_FindFunction(Module module, char * name)
+public dllexport GlobalFunction eSystem_FindFunction(Module module, const char * name)
 {
    if(name && module)
    {
@@ -5904,7 +6243,7 @@ public dllexport void eClass_DestructionWatchable(Class _class)
    }
 }
 
-public dllexport void eProperty_SelfWatch(Class _class, char * name, void (*callback)(void *))
+public dllexport void eProperty_SelfWatch(Class _class, const char * name, void (*callback)(void *))
 {
    if(_class)
    {
@@ -5926,7 +6265,7 @@ public dllexport void eInstance_Watch(void * instance, Property _property, void
    }
 }
 
-public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(Instance, Instance))
+public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(void *, void *))
 {
    OldList * watchers = (OldList *)((byte *)instance + instance._class.destructionWatchOffset);
    watchers->Add(Watcher { callback = callback, object = object });
@@ -6003,11 +6342,41 @@ public dllexport subclass(ClassDesignerBase) eInstance_GetDesigner(Instance inst
    return null;
 }
 
-public bool LocateModule(char * name, char * fileName)
+public bool LocateModule(const char * name, const char * fileName)
 {
    return Instance_LocateModule(name, fileName);
 }
 
+/*
+#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__)
+#define _64BIT 1
+#else
+#define _64BIT 0
+#endif
+
+#define arch_PointerSize                  sizeof(void *)
+#define structSize_Instance               (_64BIT ? 24 : 12)
+#define structSize_Module                 (_64BIT ? 560 : 300)
+#define structSize_BinaryTree             (_64BIT ? 32 : 16)
+#define structSize_OldList                (_64BIT ? 32 : 20)
+#define structSize_NamedLink64            (_64BIT ? 32 : 24)
+#define structSize_ClassTemplateArgument  (_64BIT ? 16 : 8)
+#define structSize_ClassTemplateParameter (_64BIT ? 64 : 40)
+#define structSize_OldLink                (_64BIT ? 24 : 12)
+#define structSize_BTNamedLink            (_64BIT ? 48 : 24)
+#define structSize_Application            (_64BIT ? 800 : 428)
+#define structSize_Watcher                (_64BIT ? 32 : 16)
+#define structSize_SelfWatcher            (_64BIT ? 32 : 16)
+#define structSize_GlobalFunction         (_64BIT ? 72 : 36)
+#define structSize_DefinedExpression      (_64BIT ? 40 : 20)
+#define structSize_BitMember              (_64BIT ? 96 : 64)
+#define structSize_DataMember             (_64BIT ? 160 : 96)
+#define structSize_ClassProperty          (_64BIT ? 80 : 40)
+#define structSize_Method                 (_64BIT ? 96 : 52)
+#define structSize_Property               (_64BIT ? 152 : 88)
+#define structSize_Class                  (_64BIT ? 624 : 376)
+*/
+
 static void LoadCOM(Module module)
 {
    bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
@@ -6037,7 +6406,7 @@ static void LoadCOM(Module module)
       instanceClass.memberID = -3;
       instanceClass.startMemberID = -3;
 
-      eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", pointerSize, pointerSize, publicAccess);
+      eClass_AddDataMember(instanceClass, "_vTbl", "void **", pointerSize, pointerSize, publicAccess);
       eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", pointerSize, pointerSize, publicAccess);
       eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int), sizeof(int), publicAccess);
    }
@@ -6049,7 +6418,7 @@ static void LoadCOM(Module module)
    eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
    enumClass.type = systemClass;
 
-   delete enumClass.dataTypeString;
+   delete (void *)enumClass.dataTypeString;
    enumClass.dataTypeString = CopyString(/*"unsigned int"*/"int");
 
    // Create Struct (simple) class
@@ -6076,7 +6445,7 @@ static void LoadCOM(Module module)
                                                                                 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, "Load", "Module(const char * name, AccessMode importAccess)", eModule_Load, publicAccess);
    eClass_AddMethod(moduleClass, "Unload", "void(Module module)", eModule_Unload, publicAccess);
    eClass_AddDataMember(moduleClass, "application", "Application", pointerSize, pointerSize, publicAccess);
    eClass_AddDataMember(moduleClass, "classes", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
@@ -6085,7 +6454,7 @@ static void LoadCOM(Module module)
    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, "name", "const 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);
@@ -6106,7 +6475,7 @@ static void LoadCOM(Module module)
    }
    eClass_AddVirtualMethod(applicationClass, "Main", "void()", null, publicAccess);
    eClass_AddDataMember(applicationClass, "argc", "int", sizeof(int), 4, publicAccess);
-   eClass_AddDataMember(applicationClass, "argv", "char **", pointerSize, pointerSize, publicAccess);
+   eClass_AddDataMember(applicationClass, "argv", "const 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", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
@@ -6130,6 +6499,9 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("asin", "Angle asin(double number)", asin, module, baseSystemAccess);
    eSystem_RegisterFunction("acos", "Angle acos(double number)", acos, module, baseSystemAccess);
    eSystem_RegisterFunction("atan", "Angle atan(double number)", atan, module, baseSystemAccess);
+   eSystem_RegisterFunction("asinh", "Angle asinh(double number)", asinh, module, baseSystemAccess);
+   eSystem_RegisterFunction("acosh", "Angle acosh(double number)", acosh, module, baseSystemAccess);
+   eSystem_RegisterFunction("atanh", "Angle atanh(double number)", atanh, module, baseSystemAccess);
    eSystem_RegisterFunction("pow", "double pow(double number, double number2)", pow, module, baseSystemAccess);
    eSystem_RegisterFunction("fmod", "double fmod(double x, double y)", fmod, module, baseSystemAccess);
    eSystem_RegisterFunction("fabs", "double fabs(double number)", fabs, module, baseSystemAccess);
@@ -6141,14 +6513,14 @@ static void LoadCOM(Module module)
 
    // --- Stdlib ---
    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("strtod", "double strtod(const char*, char**)", strtod, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtol", "int strtol(const char*, char**, int base)", strtol, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoll", "int64 strtoll(const char * nptr, char ** endptr, int base)", strtoll, module, baseSystemAccess);
+   eSystem_RegisterFunction("strtoull", "uint64 strtoull(const char * nptr, char ** endptr, int base)", strtoull, module, baseSystemAccess);
    eSystem_RegisterFunction("system", "int system(const char*)", system, module, baseSystemAccess);
    eSystem_RegisterFunction("atoi", "int atoi(const char*)", atoi, module, baseSystemAccess);
    eSystem_RegisterFunction("atof", "double atof(const char*)", atof, module, baseSystemAccess);
-   eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
-   eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
-   eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
    eSystem_RegisterFunction("memset", "void * memset(void * area, int value, uintsize count)", memset, module, baseSystemAccess);
    eSystem_RegisterFunction("getenv", "char * getenv(const char * name)", getenv, module, baseSystemAccess);
    eSystem_RegisterFunction("rename", "int rename(const char *oldpath, const char *newpath)", rename, module, baseSystemAccess);
@@ -6163,7 +6535,7 @@ static void LoadCOM(Module module)
    eSystem_RegisterFunction("strcspn", "uintsize strcspn(const char *, const char *)", strcspn, module, baseSystemAccess);
    eSystem_RegisterFunction("strpbrk", "char * strpbrk(const char *, const char *)", strpbrk, module, baseSystemAccess);
 
-   eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
+   eSystem_RegisterDefine("fstrcmp", "(__runtimePlatform == win32) ? strcmpi : strcmp", module, baseSystemAccess);
 
 //#if defined(__GNUC__)
    eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
@@ -6187,26 +6559,29 @@ static void LoadCOM(Module module)
    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);
+   eSystem_RegisterFunction("memcmp", "int memcmp(const void *, const void *, uintsize size)", memcmp, module, baseSystemAccess);
 
    // --- Stdio ---
-   eSystem_RegisterFunction("sprintf", "int sprintf(char *, char *, ...)", sprintf, module, baseSystemAccess);
-   eSystem_RegisterFunction("snprintf", "int sprintf(char *, uintsize, char *, ...)", snprintf, module, baseSystemAccess);
-   eSystem_RegisterFunction("printf", "int printf(char *, ...)", printf, module, baseSystemAccess);
+   eSystem_RegisterFunction("sprintf", "int sprintf(char *, const char *, ...)", sprintf, module, baseSystemAccess);
+   eSystem_RegisterFunction("snprintf", "int snprintf(char *, uintsize, const char *, ...)", snprintf, module, baseSystemAccess);
+   eSystem_RegisterFunction("printf", "int printf(const char *, ...)", printf, module, baseSystemAccess);
    eSystem_RegisterFunction("vsprintf", "int vsprintf(char*, const char*, __builtin_va_list)", vsprintf, 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);
+   eSystem_RegisterFunction("puts", "int puts(const char *)", puts, module, baseSystemAccess);
+   eSystem_RegisterFunction("fputs", "int fputs(const char *, void * stream)", fputs, module, baseSystemAccess);
 
    // --- Ctype ---
+   eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
+   eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
+   eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
+   eSystem_RegisterFunction("isxdigit","bool isxdigit(int)", isxdigit, module, baseSystemAccess);
    eSystem_RegisterFunction("isalnum", "int isalnum(int c)", isalnum, module, baseSystemAccess);
    eSystem_RegisterFunction("isspace", "int isspace(int c)", isspace, module, baseSystemAccess);
    eSystem_RegisterFunction("isalpha", "int isalpha(int c)", isalpha, module, baseSystemAccess);
    eSystem_RegisterFunction("islower", "int islower(int c)", islower, module, baseSystemAccess);
    eSystem_RegisterFunction("isupper", "int isupper(int c)", isupper, module, baseSystemAccess);
    eSystem_RegisterFunction("isprint", "int isprint(int c)", isprint, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoll", "int64 strtoll(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
-   eSystem_RegisterFunction("strtoull", "uint64 strtoull(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
+   eSystem_RegisterFunction("isblank", "int isblank(int c)", isblank, module, baseSystemAccess);
 
 }
 
@@ -6245,7 +6620,7 @@ public dllexport Application __ecere_COM_Initialize(bool guiApp, int argc, char
    Instance_COM_Initialize(argc, argv, &app.parsedCommand, &app.argc, &app.argv);
 
    app.application = app;
-   app.allModules.offset = sizeof(class Instance) + (uint)&((struct Module *)0)->prev;
+   app.allModules.offset = sizeof(class Instance) + (uint)(uintptr)&((struct Module *)0)->prev;
    app.isGUIApp = guiApp;
 
    LoadCOM(app);
@@ -6255,7 +6630,12 @@ public dllexport Application __ecere_COM_Initialize(bool guiApp, int argc, char
    return app;
 }
 
-public dllexport ClassTemplateParameter eClass_AddTemplateParameter(Class _class, char * name, TemplateParameterType type, void * info, ClassTemplateArgument defaultArg)
+public dllexport void eSystem_SetArgs(Application app, int argc, char * argv[])
+{
+   System_SetArgs(argc, argv, &app.argc, &app.argv);
+}
+
+public dllexport ClassTemplateParameter eClass_AddTemplateParameter(Class _class, const char * name, TemplateParameterType type, const void * info, ClassTemplateArgument defaultArg)
 {
    if(_class && name)
    {
@@ -6287,7 +6667,6 @@ public dllexport void eClass_DoneAddingTemplateParameters(Class base)
 {
    if(base)
    {
-      OldLink derivative;
       ClassTemplateParameter param;
       {
          void * first = base.templateParams.first;
@@ -6310,8 +6689,8 @@ public dllexport void eClass_DoneAddingTemplateParameters(Class base)
          if(param.type == identifier && param.defaultArg.memberString)
          {
             Class memberClass = base;
-            char * colon = strstr(param.defaultArg.memberString, "::");
-            char * memberName;
+            const char * colon = strstr(param.defaultArg.memberString, "::");
+            const char * memberName;
             if(colon)
             {
                char className[1024];
@@ -6403,7 +6782,7 @@ public enum Platform
 {
    unknown, win32, tux, apple;
 
-   property char *
+   property const char *
    {
       get { return OnGetString(null, null, null); }
       set
@@ -6419,7 +6798,7 @@ public enum Platform
       }
    };
 
-   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
    {
       if(this >= firstPlatform && this <= lastPlatform)
       {
@@ -6432,10 +6811,10 @@ public enum Platform
       return null;
    }
 
-   bool OnGetDataFromString(char * string)
+   bool OnGetDataFromString(const char * string)
    {
       this = string;
-      return this != null;
+      return this != unknown;
    }
 };
 
@@ -6471,8 +6850,8 @@ public:
 public class DesignerBase : Window
 {
 public:
-   virtual bool FindObject(Instance * instance, char * string);
-   virtual void RenameObject(ObjectInfo object, char * name);
+   virtual bool FindObject(Instance * instance, const char * string);
+   virtual void RenameObject(ObjectInfo object, const char * name);
    virtual void SelectObjectFromDesigner(ObjectInfo object);
    virtual void CodeAddObject(Instance instance, ObjectInfo * object);
    virtual void SheetAddObject(ObjectInfo object);
@@ -6484,7 +6863,7 @@ public:
    virtual void UpdateProperties(void);
 
    ClassDesignerBase classDesigner;
-   char * objectClass;
+   const char * objectClass;
    bool isDragging;
 
    // FIX THIS WITH PUBLIC:
@@ -6493,7 +6872,7 @@ public:
       get { return classDesigner; }
       set { classDesigner = value; }
    };
-   property char * objectClass
+   property const char * objectClass
    {
       get { return objectClass; }
       set { objectClass = value; }
@@ -6520,7 +6899,7 @@ public:
    virtual void ::DroppedObject(Instance instance, ObjectInfo object, bool isClass, Instance _class);
    virtual void ::DestroyObject(Instance object);
    virtual void ::FixProperty(Property prop, Instance object);
-   virtual void ::CreateNew(EditBox editBox, Size clientSize, char * name, char * inherit);
+   virtual void ::CreateNew(EditBox editBox, Size clientSize, const char * name, const char * inherit);
 }
 
 DesignerBase activeDesigner;
@@ -6549,7 +6928,7 @@ namespace sys;
 define LEAD_OFFSET      = 0xD800 - (0x10000 >> 10);
 define SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
 
-public bool UTF8Validate(char * source)
+public bool UTF8Validate(const char * source)
 {
    if(source)
    {
@@ -6606,59 +6985,86 @@ public bool UTF8Validate(char * source)
    return true;
 }
 
-public int ISO8859_1toUTF8(char * source, char * dest, int max)
+public int ISO8859_1toUTF8(const char * source, char * dest, int max)
 {
    int c;
    int d = 0;
+   byte * byteDest = (byte *)dest;
    for(c = 0; source[c]; c++)
    {
       unichar ch = ((byte *)source)[c];
       switch(ch)
       {
-         case 150: ch = (unichar)0x2012; break;
+         case 128: ch = (unichar)0x20AC; break;
+         case 130: ch = (unichar)0x201A; break;
+         case 131: ch = (unichar)0x0192; break;
+         case 132: ch = (unichar)0x201E; break;
+         case 133: ch = (unichar)0x2026; break;
+         case 134: ch = (unichar)0x2020; break;
+         case 135: ch = (unichar)0x2021; break;
+         case 136: ch = (unichar)0x02C6; break;
+         case 137: ch = (unichar)0x2030; break;
+         case 138: ch = (unichar)0x0160; break;
+         case 139: ch = (unichar)0x2039; break;
+         case 140: ch = (unichar)0x0152; break;
+         case 142: ch = (unichar)0x017D; break;
+         case 145: ch = (unichar)0x2018; break;
+         case 146: ch = (unichar)0x2019; break;
+         case 147: ch = (unichar)0x201C; break;
+         case 148: ch = (unichar)0x201D; break;
+         case 149: ch = (unichar)0x2022; break;
+         case 150: ch = (unichar)0x2013; break;
+         case 151: ch = (unichar)0x2014; break;
+         case 152: ch = (unichar)0x02DC; break;
+         case 153: ch = (unichar)0x2122; break;
+         case 154: ch = (unichar)0x0161; break;
+         case 155: ch = (unichar)0x203A; break;
+         case 156: ch = (unichar)0x0153; break;
+         case 158: ch = (unichar)0x017E; break;
+         case 159: ch = (unichar)0x0178; break;
       }
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
    dest[d] = 0;
    return d;
 }
 
-public char * UTF16toUTF8(uint16 * source)
+public char * UTF16toUTF8(const uint16 * source)
 {
    int c;
    int d = 0;
    int len;
-   char * dest;
+   byte * dest;
    uint16 u16;
    bool invert = false;
 
    for(len = 0; source[len]; len++);
-   dest = new char[len * 3 + 1];
+   dest = new byte[len * 3 + 1];
    for(c = 0; (u16 = source[c]); c++)
    {
       unichar ch;
@@ -6698,15 +7104,16 @@ public char * UTF16toUTF8(uint16 * source)
       }
    }
    dest[d] = 0;
-   dest = renew dest char[d+1];
-   return dest;
+   dest = renew dest byte[d+1];
+   return (char *)dest;
 }
 
-public int UTF16toUTF8Buffer(uint16 * source, byte * dest, int max)
+public int UTF16toUTF8Buffer(const uint16 * source, char * dest, int max)
 {
    int c;
    int d = 0;
    uint16 u16;
+   byte * byteDest = (byte *)dest;
    for(c = 0; (u16 = source[c]); c++)
    {
       unichar ch;
@@ -6718,36 +7125,36 @@ public int UTF16toUTF8Buffer(uint16 * source, byte * dest, int max)
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
-   dest[d] = 0;
+   byteDest[d] = 0;
    return d;
 }
 
 // NOTE: UTF8GetChar now returns 0 into numBytes for the null-terminating character ('\0')
-public unichar UTF8GetChar(char * string, int * numBytes)
+public unichar UTF8GetChar(const char * string, int * numBytes)
 {
    unichar ch;
    byte b = ((byte *)string)[0];
@@ -6801,7 +7208,7 @@ public unichar UTF8GetChar(char * string, int * numBytes)
    return ch;
 }
 
-public int UTF8toUTF16Buffer(char * source, uint16 * dest, int max)
+public int UTF8toUTF16Buffer(const char * source, uint16 * dest, int max)
 {
    if(source)
    {
@@ -6839,7 +7246,7 @@ public int UTF8toUTF16Buffer(char * source, uint16 * dest, int max)
          if(codePoint > 0xFFFF)
          {
             uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
-            uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
+            uint16 trail = (uint16)(0xDC00 | (codePoint & 0x3FF));
             if(d >= max - 1) break;
             dest[d++] = lead;
             dest[d++] = trail;
@@ -6856,45 +7263,46 @@ public int UTF8toUTF16Buffer(char * source, uint16 * dest, int max)
    return 0;
 }
 
-public int UTF32toUTF8Len(unichar * source, int count, byte * dest, int max)
+public int UTF32toUTF8Len(const unichar * source, int count, char * dest, int max)
 {
    int c;
    int d = 0;
    uint32 ch;
+   byte * byteDest = (byte *)dest;
    for(c = 0; c<count && (ch = source[c]); c++)
    {
       if(ch < 0x80)
       {
          if(d + 1 >= max) break;
-         dest[d++] = (char)ch;
+         byteDest[d++] = (char)ch;
       }
       else if(ch < 0x800)
       {
          if(d + 2 >= max) break;
-         dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else if(ch < 0x10000)
       {
          if(d + 3 >= max) break;
-         dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
       else
       {
          if(d + 4 >= max) break;
-         dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
-         dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
-         dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
-         dest[d++] = 0x80 | (byte)(ch & 0x03F);
+         byteDest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
+         byteDest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
+         byteDest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
+         byteDest[d++] = 0x80 | (byte)(ch & 0x03F);
       }
    }
-   dest[d] = 0;
+   byteDest[d] = 0;
    return d;
 }
 
-public uint16 * UTF8toUTF16(char * source, int * wordCount)
+public uint16 * UTF8toUTF16(const char * source, int * wordCount)
 {
    if(source)
    {
@@ -6934,7 +7342,7 @@ public uint16 * UTF8toUTF16(char * source, int * wordCount)
          if(codePoint > 0xFFFF)
          {
             uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
-            uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
+            uint16 trail = (uint16)(0xDC00 | (codePoint & 0x3FF));
             dest[d++] = lead;
             dest[d++] = trail;
          }
@@ -6951,3 +7359,86 @@ public uint16 * UTF8toUTF16(char * source, int * wordCount)
 }
 
 namespace com;
+
+#if !defined(MEMINFO) && defined(MEMTRACKING)
+import "Map"
+
+Map<Class, int> blocksByClass { };
+Map<Class, uintsize> sizeByClass { };
+#endif
+
+public void queryMemInfo(char * string)
+{
+#if !defined(MEMINFO) && defined(MEMTRACKING) && !defined(DISABLE_MEMMGR)
+   char s[1024];
+   int p;
+   uint numBlocks = 0;
+   uintsize totalMemUsed = 0;
+   sprintf(s, "Total System Memory Usage: %.02f\n", TOTAL_MEM / 1048576.0f);
+   strcat(string, s);
+
+   for(p = 0; pools && p < NUM_POOLS; p++)
+   {
+      BlockPool * pool = &pools[p];
+      if(pool->totalSize)
+      {
+         numBlocks += pool->totalSize;
+         sprintf(s, "%8d bytes: %d blocks in %d parts (%.02f mb used; taking up %.02f mb space)\n",
+            pool->blockSize, pool->numBlocks, pool->numParts, pool->usedSpace / 1048576.0f, pool->totalSize * pool->blockSpace / 1048576.0f);
+         totalMemUsed += pool->usedSpace;
+         strcat(string, s);
+      }
+   }
+
+
+   blocksByClass.Free();
+   sizeByClass.Free();
+#if !defined(__EMSCRIPTEN__)
+   memMutex.Wait();
+#endif
+   for(p = 0; pools && p < NUM_POOLS; p++)
+   {
+      BlockPool * pool = &pools[p];
+      MemBlock block;
+      for(block = pool->first; block; block = block.next)
+      {
+         Class c = block._class;
+         blocksByClass[c]++;
+         sizeByClass[c] += block.size;
+      }
+   }
+#if !defined(__EMSCRIPTEN__)
+   memMutex.Release();
+#endif
+
+   //for(c : blocksByClass)
+   {
+      MapIterator<Class, int> it { map = blocksByClass };
+      while(it.Next())
+      {
+         int c = it.data;
+         Class _class = it.key; //&c;
+         uintsize size = sizeByClass[_class];
+         float totalSize = (float) size / 1048576.0f;
+         if(totalSize > 1)
+         {
+            sprintf(s, "%s (%d bytes): %d instances (%.02f mb used)\n", _class ? _class.name : "(none)", (int)size, c, totalSize);
+            strcat(string, s);
+         }
+      }
+   }
+
+   sprintf(s, "Non-pooled memory: %.02f\n", OUTSIDE_MEM / 1048576.0f);
+   strcat(string, s);
+   sprintf(s, "Total Memory in use: %.02f\n", (float)(totalMemUsed + OUTSIDE_MEM) / 1048576.0f);
+   strcat(string, s);
+
+   sprintf(s, "Total Blocks Count: %d (%.02f mb overhead)\n", numBlocks, (float)sizeof(struct MemBlock) * numBlocks / 1048576.0f);
+   strcat(string, s);
+#ifdef MEMORYGUARD
+   sprintf(s, "MemoryGuard: %d blocks (%.02f mb RedZone, %.02f mb MemInfo)\n", memBlocks.count,
+      numBlocks * 2 * REDZONE / 1048576.0f, sizeof(struct MemInfo) * memBlocks.count / 1048576.0f);
+   strcat(string, s);
+#endif
+#endif
+}