+#define _Noreturn
+
namespace com;
-// #define DISABLE_MEMMGR
+#if defined(__ANDROID__)
+ #define DISABLE_MEMMGR
+#endif
+
+#if defined(__EMSCRIPTEN__)
+ #define DISABLE_MEMMGR
+ #define _NOMUTEX
+#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(ECERE_BOOTSTRAP)
+#if defined(ECERE_BOOTSTRAP)
+ #define _NOMUTEX
+#endif
+
+#if !defined(_NOMUTEX)
import "Mutex"
+#else
+#if defined(MEMINFO)
+int GetCurrentThreadID() { return 0; }
+#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
+
+#ifdef _DEBUG
+// #define MEMTRACKING
+#endif
+
#ifdef MEMINFO
+#if !defined(_NOMUTEX)
import "Thread"
+#endif
static define MAX_MEMORY_LOC = 40;
static define MAX_STACK_FRAMES = 1000;
#if defined(__ANDROID__)
-default const char * AndroidInterface_GetLibLocation();
+default const char * AndroidInterface_GetLibLocation(Module m);
#include <android/log.h>
#include <android/native_activity.h>
#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(_NOMUTEX)
memMutex.Wait();
+#endif
stack = (MemStack)memStacks.Find(GetCurrentThreadID());
if(!stack)
{
}
if(stack.pos < MAX_STACK_FRAMES)
stack.frames[stack.pos++] = loc;
+#if !defined(_NOMUTEX)
memMutex.Release();
#endif
+#endif
}
public dllexport void MemoryGuard_PopLoc()
{
#ifdef MEMINFO
MemStack stack;
+#if !defined(_NOMUTEX)
memMutex.Wait();
+#endif
stack = (MemStack)memStacks.Find(GetCurrentThreadID());
if(stack && stack.pos > 0)
{
stack.pos--;
}
+#if !defined(_NOMUTEX)
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;
+ void * bindingsClass;
property const char *
{
printf("Object of class %s\n", _class);
printf(" Allocation Stack:\n");
for(c = 0; c<MAX_MEMORY_LOC; c++)
-#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__)
+#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(__LLP64__)
if(allocLoc[c] && allocLoc[c] != (void *)0xabababababababab)
#else
if(allocLoc[c] && allocLoc[c] != (void *)0xabababab)
static uint OUTSIDE_MEM = 0;
#endif
+#if !defined(_NOMUTEX)
#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
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;
}
block = pools[p].Add();
if(block)
{
+#if defined(MEMTRACKING)
+ block._class = null;
+#endif
block.size = size;
pools[p].usedSpace += 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;
}
}
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);
}
}
TOTAL_MEM += size - newBlock.size;
OUTSIDE_MEM += size - newBlock.size;
newPointer = ((struct MemBlock *)newBlock + 1);
+ newBlock.size = size;
}
}
}
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Wait();
#endif
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(_NOMUTEX)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Release();
#endif
#else
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(_NOMUTEX)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Release();
#endif
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(_NOMUTEX)
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(_NOMUTEX)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(_NOMUTEX)
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(_NOMUTEX)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
free(pointer);
#else
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(_NOMUTEX)
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(_NOMUTEX)
if(memMutex != pointer) memMutex.Release();
#endif
{
OldLink derivative;
- ComputeClassParameters(base, strchr(base.name, '<'), null);
+ ComputeClassParameters(base, strchr(base.name, '<'), null, base.templateClass != mod);
for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
{
// _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
_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;
//const char * templateParams = strchr(template.name, '<');
template.base = base.base;
template._vTbl = base._vTbl;
- //ComputeClassParameters(template, templateParams, null);
+ //ComputeClassParameters(template, templateParams, null, true);
template.data = base.data;
template.offset = base.offset;
Class _class = null;
const char * dataTypeString = null;
Class enumBase = null;
- Class base = (baseName && baseName[0]) ? eSystem_FindClass(module, baseName) : null;
+ Class base = (baseName && baseName[0]) ? System_FindClass(module, baseName, true) : null;
Class prevBase = null;
if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass))
offsetClass = base ? base.sizeClass : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
totalSizeClass = offsetClass + sizeClass;
- _class = eSystem_FindClass(module, name);
+ _class = System_FindClass(module, name, true);
if(!_class)
{
const char * colons = RSearchString(name, "::", strlen(name), true, false);
if(colons && colons)
{
- _class = eSystem_FindClass(module, colons + 2);
+ _class = System_FindClass(module, colons + 2, true);
if(_class)
{
if(_class.internalDecl)
}
{
NameSpace * ns = _class.nameSpace;
- while(ns->parent &&
+ while(ns != nameSpace &&
+ ns->parent &&
!ns->classes.first &&
!ns->functions.first &&
!ns->defines.first &&
Class templateBase;
strcpy(templateClassName, baseName);
*strchr(templateClassName, '<') = '\0';
- templateBase = eSystem_FindClass(module, templateClassName);
+ templateBase = System_FindClass(module, templateClassName, true);
if(!templateBase)
{
templateBase = eSystem_RegisterClass(0, templateClassName, null, 0,0, null, null, module, declMode, publicAccess);
templateBase.internalDecl = true;
}
- base = eSystem_FindClass(module, baseName);
+ base = System_FindClass(module, baseName, true);
}
else
{
!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;
}
}
else if(type == bitClass || type == enumClass || type == unitClass)
{
- Class dataTypeClass = eSystem_FindClass(_class.module, dataTypeString);
+ Class dataTypeClass = System_FindClass(_class.module, dataTypeString, true);
if(dataTypeClass)
_class.typeSize = dataTypeClass.typeSize;
_class.structSize = 0;
{
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(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 (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);
}
- _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)
}
FreeTemplateArgs(_class);
- //if(_class.templateArgs)
- //printf("Deleting Template args for %s\n", _class.name);
delete _class.templateArgs;
delete (void *)_class.dataTypeString;
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);
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;
}
public dllexport Class eSystem_FindClass(Module module, const char * name)
{
+ return System_FindClass(module, name, false);
+}
+
+Class System_FindClass(Module module, const char * name, bool registerTemplatesInternalDecl)
+{
if(name && module)
{
BTNamedLink link;
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);
+ ComputeClassParameters(templatedClass, templateParams, module, registerTemplatesInternalDecl);
_class.templatized.Add(OldLink { data = templatedClass });
}
switch(param.type)
{
case type:
- arg.dataTypeString = CopyString(arg.dataTypeString);
+ arg.dataTypeString = CopyString(arg.dataTypeString);
break;
case expression:
}
}
-static void ComputeClassParameters(Class templatedClass, const char * templateParams, Module findModule)
+static void ComputeClassParameters(Class templatedClass, const char * templateParams, Module findModule, bool registerInternalDecl)
{
char ch;
const char * nextParamStart = templateParams ? (templateParams + 1) : null;
{
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 = System_FindClass(findModule, value, registerInternalDecl);
+ if(!argument.dataTypeClass)
+ argument.dataTypeClass = System_FindClass(_class.module, value, registerInternalDecl);
+ if(!argument.dataTypeClass)
+ argument.dataTypeClass = System_FindClass(_class.module.application, value, registerInternalDecl);
+ if(registerInternalDecl && !argument.dataTypeClass)
+ {
+ ClassTemplateParameter param;
+ for(param = templatedClass.templateParams.first; param; param = param.next)
+ if(!strcmp(param.name, value))
+ break;
+ if(!param)
+ {
+ argument.dataTypeClass = eSystem_RegisterClass(0, value, null, 0,0, null, null, _class.module, publicAccess, publicAccess);
+ argument.dataTypeClass.internalDecl = true;
+ }
+ }
break;
case expression:
{
- Class expClass = eSystem_FindClass(_class.module, curParam.dataTypeString);
- if(!expClass) expClass = eSystem_FindClass(_class.module.application, curParam.dataTypeString);
+ Class expClass = System_FindClass(_class.module, curParam.dataTypeString, true);
+ if(!expClass) expClass = System_FindClass(_class.module.application, curParam.dataTypeString, true);
if(expClass)
{
//if(expClass.type ==
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 = System_FindClass(findModule, param.defaultArg.dataTypeString, true);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = System_FindClass(templatedClass.module, param.defaultArg.dataTypeString, true);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = System_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString, true);
}
}
curParamID++;
{
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);
arg->dataTypeString = CopyString(templateString);
- arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
+ arg->dataTypeClass = System_FindClass(findModule, templateString, true);
+ if(!arg->dataTypeClass)
+ arg->dataTypeClass = System_FindClass(templatedClass.module, templateString, true);
if(!arg->dataTypeClass)
- arg->dataTypeClass = eSystem_FindClass(templatedClass.module.application, templateString);
+ arg->dataTypeClass = System_FindClass(templatedClass.module.application, templateString, true);
}
else
{
{
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);
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 = System_FindClass(findModule, param.defaultArg.dataTypeString, true);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = System_FindClass(templatedClass.module, param.defaultArg.dataTypeString, true);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = System_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString, true);
}
}
curParamID++;
id++;
}
}
- memberClass = eSystem_FindClass(templatedClass.module, className);
// TESTING: Added this here...
+ memberClass = System_FindClass(findModule, className, true);
if(!memberClass)
- memberClass = eSystem_FindClass(findModule, className);
+ memberClass = System_FindClass(templatedClass.module, className, true);
if(!memberClass)
- memberClass = eSystem_FindClass(templatedClass.module.application, className);
+ memberClass = System_FindClass(templatedClass.module.application, className, true);
}
if(memberClass)
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;
}
}
}
// Construct an instance
-static bool ConstructInstance(void * instance, Class _class, Class from)
+static bool ConstructInstance(void * instance, Class _class, Class from, bool bindingsAlloc)
{
if(_class.templateClass) _class = _class.templateClass;
if(_class.base && from != _class.base)
{
- if(!ConstructInstance(instance, _class.base, from))
+ if(!ConstructInstance(instance, _class.base, from, false))
return false;
}
if(_class.Initialize)
}
if(_class.Constructor)
{
- if(!_class.Constructor(instance))
+ bool result;
+ if(_class.bindingsClass)
+ result = ((bool (*)(void *, bool))(void *)_class.Constructor)(instance, bindingsAlloc);
+ else
+ result = _class.Constructor(instance);
+ if(!result)
{
for(; _class; _class = _class.base)
{
return true;
}
-public dllexport void * eInstance_New(Class _class)
+static void * Instance_New(Class _class, bool bindingsAlloc)
{
Instance instance = null;
if(_class)
#ifdef MEMINFO
#undef malloc
+#if !defined(_NOMUTEX)
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(_NOMUTEX)
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, bindingsAlloc))
{
_free(instance);
instance = null;
return instance;
}
+public dllexport void * eInstance_New(Class _class)
+{
+ return Instance_New(_class, true);
+}
+
+public dllexport void * eInstance_NewEx(Class _class, bool bindingsAlloc)
+{
+ return Instance_New(_class, bindingsAlloc);
+}
+
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;
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;
}
}
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;
}
}
}
instance._vTbl = _class._vTbl;
// We don't want to reconstruct the portion already constructed...
- if(!ConstructInstance(instance, _class, fromClass))
+ if(!ConstructInstance(instance, _class, fromClass, false))
{
_free(instance);
*instancePtr = null;
bool ownVtbl;
#ifdef MEMINFO
-#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__)
+#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(__LLP64__)
if(instance._class == (void *)0xecececececececec)
#else
if(instance._class == (void *)0xecececec)
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(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 = 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;
{
const char * libLocation = null;
#if defined(__ANDROID__)
- libLocation = AndroidInterface_GetLibLocation();
+ libLocation = AndroidInterface_GetLibLocation(fromModule.application);
#endif
library = Instance_Module_Load(libLocation, name, &Load, &Unload);
}
}
if(ensureCOM && !strcmp(name, "ecere") && module)
{
- name = !strcmp(module.name, "ecereCOM") ? "ecere" : "ecereCOM";
+ name = !strcmp(module.name, "ecereCOM") ? "ecereCOM" : "ecere";
if((!Load && !strcmp(module.name, "ecereCOM")) ||
(Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != (void *)COM_LOAD_FUNCTION))
{
}
incref module;
}
-#if defined(_DEBUG)
+#if defined(_DEBUG) && !defined(__ANDROID__)
InternalModuleLoadBreakpoint();
#endif
return module;
NameSpace * nameSpace;
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))
{
NameSpace_Free(nameSpace);
#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)
}
}
-public dllexport void eInstance_Watch(void * instance, Property _property, void * object, void (*callback)(void *, void *))
+public dllexport void eInstance_Watch(Instance instance, Property _property, void * object, void (*callback)(void *, void *))
{
if(_property.isWatchable)
{
}
/*
-#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__)
+#if (defined(__WORDSIZE) && __WORDSIZE == 8) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(__LLP64__)
#define _64BIT 1
#else
#define _64BIT 0
// --- 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);
#ifdef __ANDROID__
// Clean up global variables
+#if !defined(DISABLE_MEMMGR)
memoryInitialized = false;
pools = null;
+#endif
+
#ifdef MEMINFO
memset(&memStacks, 0, sizeof(BinaryTree));
memoryErrorsCount = 0;
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)
type = type;
(type == identifier) ? info : CopyString(info);
};
+
+ {
+ Class c = eSystem_FindClass(_class.module, name);
+ if(c && c.internalDecl)
+ {
+ c.module.classes.Remove(c);
+ eClass_Unregister(c);
+ }
+ }
if(defaultArg != null)
{
param.defaultArg = defaultArg;
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)
{
}
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(_NOMUTEX)
+ 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(_NOMUTEX)
+ 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
+}