+#define _Noreturn
+
namespace com;
-// #define DISABLE_MEMMGR
+#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)
#undef __BLOCKS__
+#if !defined(__EMSCRIPTEN__)
#if !defined(ECERE_BOOTSTRAP)
import "Mutex"
#endif
+#endif
+
+#if defined(__EMSCRIPTEN__)
+#define GetCurrentThreadID() 0
+#endif
// #define MEMINFO
/*
#define REDZONE 256
#endif
*/
-#ifndef REDZONE
+
+#if defined(JUST_CHECK_LEAKS) || !defined(REDZONE)
+#undef REDZONE
#define REDZONE 0
#endif
#endif
#ifdef MEMINFO
+#if !defined(__EMSCRIPTEN__)
import "Thread"
+#endif
static define MAX_MEMORY_LOC = 40;
static define MAX_STACK_FRAMES = 1000;
#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)
{
#ifdef MEMINFO
MemStack stack;
+#if !defined(__EMSCRIPTEN__)
memMutex.Wait();
+#endif
stack = (MemStack)memStacks.Find(GetCurrentThreadID());
if(!stack)
{
}
if(stack.pos < MAX_STACK_FRAMES)
stack.frames[stack.pos++] = loc;
+#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--;
}
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
+#endif
}
#ifdef ECERE_STATIC
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;
static uint OUTSIDE_MEM = 0;
#endif
+#if !defined(__EMSCRIPTEN__)
#if !defined(ECERE_BOOTSTRAP)
static Mutex memMutex { };
#endif
+#endif
private class MemBlock : struct
{
void Remove(MemBlock block)
{
+ MemPart part = block.part;
/*if(blockSize == 28)
printf("BlockPool::Remove (%d)\n", blockSize);*/
if(block.prev)
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)
break;
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return pos;
}
{
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return (uint)current;
}
return (uint)current;
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return (uint)current;
}
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);
}
}
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
#else
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
memset(pointer, 0xAB, REDZONE);
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));
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
+#endif
}
if(!recurse && !stack.recurse)
pointer = realloc(pointer, size);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
memset(pointer, 0xAB, REDZONE);
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));
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
+#endif
}
if(!recurse && !stack.recurse)
pointer = crealloc(pointer, size);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
free(pointer);
#else
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
if(memMutex != pointer) memMutex.Wait();
#endif
}
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)
{
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;
}
free(pointer);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
if(memMutex != pointer) memMutex.Release();
#endif
// _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
if(type == normalClass || type == noHeadClass)
+ {
// 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
}
{
NameSpace * ns = _class.nameSpace;
- while(ns->parent &&
+ while(ns != nameSpace &&
+ ns->parent &&
!ns->classes.first &&
!ns->functions.first &&
!ns->defines.first &&
!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;
}
{
case type:
delete (void *)template.templateArgs[id].dataTypeString;
+ template.templateArgs[id].dataTypeClass = null;
break;
case identifier:
delete (void *)template.templateArgs[id].memberString;
{
case type:
delete (void *)template.templateArgs[id].dataTypeString;
+ template.templateArgs[id].dataTypeClass = null;
break;
case identifier:
delete (void *)template.templateArgs[id].memberString;
if(link)
template.nameSpace->classes.Delete((BTNode)link);
}
- FreeTemplateArgs(template);
- delete (void *)template.fullName;
- delete (void *)template.name;
- delete (void *)template.templateArgs;
- delete (void *)template.dataTypeString;
+ FreeTemplatesDerivatives(template);
+ FreeTemplateArgs(template);
while((deriv = template.derivatives.first))
{
template.derivatives.Delete(deriv);
}
+ delete (void *)template.fullName;
+ delete (void *)template.name;
+ delete template.templateArgs;
+ delete (void *)template.dataTypeString;
+
if(template.module)
template.module.classes.Delete(template);
else
}
FreeTemplateArgs(_class);
- //if(_class.templateArgs)
- //printf("Deleting Template args for %s\n", _class.name);
delete _class.templateArgs;
delete (void *)_class.dataTypeString;
FreeTemplates(_class);
- FreeTemplateArgs(_class);
- delete _class.templateArgs;
-
while((template = _class.templatized.first))
{
FreeTemplate(template.data);
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;
}
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;
}
switch(param.type)
{
case type:
- arg.dataTypeString = CopyString(arg.dataTypeString);
+ arg.dataTypeString = CopyString(arg.dataTypeString);
break;
case expression:
{
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];
{
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;
}
}
{
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);
if(method.vid >= _class.vTblSize)
printf("error: virtual methods overriding failure\n");
else
- _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
{
Class derivClass = deriv.data;
Method method
{
name = CopyString(name),
- function = function ? function : DefaultFunction;
+ function = function ? function : null; //DefaultFunction;
_class = _class;
dataTypeString = CopyString(type);
memberAccess = declMode;
if(method.vid >= _class.vTblSize)
printf("error: virtual methods overriding failure\n");
else
- _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
}
else
base = null;
Method method
{
name = CopyString(name);
- function = function ? function : DefaultFunction;
+ function = function ? function : null; //DefaultFunction;
type = virtualMethod;
_class = _class;
vid = _class.vTblSize++;
};
_class.methods.Add((BTNode)method);
_class._vTbl = renew _class._vTbl void *[_class.vTblSize];
- _class._vTbl[method.vid] = function ? function : (void *)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;
}
}
#ifdef MEMINFO
#undef malloc
+#if !defined(__EMSCRIPTEN__)
memMutex.Wait();
+#endif
//allocateClass = _class;
allocateClass = malloc(strlen(_class.name)+1);
allocateInternal = _class.module == __thisModule;
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
+#endif
#if !defined(MEMINFO) && defined(MEMTRACKING)
{
}
#endif
- if(_class.type == normalClass)
+ 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;
memcpy(instance._vTbl, instance._class._vTbl,
sizeof(int(*)()) * instance._class.vTblSize);
}
- instance._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ instance._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
}
}
}
}
}
- if(pointerAlignment) alignment = sizeof(void *);
+ if(pointerAlignment) alignment = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
if(pointerAlignment && _class.structAlignment <= 4)
_class.pointerAlignment = 1;
_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);
}
if(alignment)
{
bool pointerAlignment = alignment == 0xF000F000;
- if(pointerAlignment) alignment = sizeof(void *);
+ 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;
#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)
// --- Stdio ---
eSystem_RegisterFunction("sprintf", "int sprintf(char *, const char *, ...)", sprintf, module, baseSystemAccess);
- eSystem_RegisterFunction("snprintf", "int sprintf(char *, uintsize, const char *, ...)", snprintf, 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);
return app;
}
+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)
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)
{
blocksByClass.Free();
sizeByClass.Free();
+#if !defined(__EMSCRIPTEN__)
memMutex.Wait();
+#endif
for(p = 0; pools && p < NUM_POOLS; p++)
{
BlockPool * pool = &pools[p];
sizeByClass[c] += block.size;
}
}
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
//for(c : blocksByClass)
{