private:
+#if defined(__ANDROID__)
+
+default const char * AndroidInterface_GetLibLocation();
+
+#include <android/log.h>
+#include <android/native_activity.h>
+
+#define printf(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
+#endif
+
#undef property
#undef bool
#undef uint
// 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);
-void * Instance_Module_Load(char * name, void ** Load, void ** Unload);
+void * Instance_Module_Load(const char * libLocation, const char * name, void ** Load, void ** Unload);
void Instance_Module_Free(void * library);
+#if defined(_DEBUG)
+void InternalModuleLoadBreakpoint();
+#endif
private:
Class dataTypeClass;
Type dataType;
- void (*Set)();
- int (*Get)();
- bool (*IsSet)();
+ void (*Set)(void *, int);
+ int (*Get)(void *);
+ bool (*IsSet)(void *);
void * data;
void * symbol;
int vid;
default:
+#if defined(ECERE_BOOTSTRAP)
+extern bool COM_LOAD_FUNCTION(Module module);
+extern bool COM_UNLOAD_FUNCTION(Module module);
+#else
extern bool stdcall COM_LOAD_FUNCTION(Module module);
extern bool stdcall COM_UNLOAD_FUNCTION(Module module);
+#endif
private:
int typeSize;
int defaultAlignment;
void (*Initialize)();
- int memberOffset;
+ int memberOffset; // For structs, this includes all base classes structSize. Otherwise it restarts at for each class hierarchy level.
OldList selfWatchers;
char * designerClass;
bool noExpansion;
void * param; // To attach to Compiler TemplateParameter
}
-/*
-public class Module : struct
+/* // Module inherits off the Instance class (_vTbl, _class, _refCount)
+public class Module
{
class_no_expansion
- Instance inst;
Application app;
public class Application : Module
{
- Module module;
-
int argc;
char ** argv;
int exitCode;
char * name;
ClassProperty parent, left, right;
int depth;
- void (*Set)(Class, int);
- int (*Get)(Class);
+ void (*Set)(Class, int64);
+ int64 (*Get)(Class);
char * dataTypeString;
Type dataType;
bool constant;
static uint log1_5i(uint number)
{
uint pos;
- uint64 current = 4;
+ uint64 current = sizeof(void *);
for(pos=0; pos < NUM_POOLS; pos++)
{
static uint pow1_5(uint number)
{
uint pos;
- uint64 current = 4;
+ uint64 current = sizeof(void *);
for(pos=0; pos < number; pos++)
{
current = current * 3 / 2;
static uint pow1_5i(uint number)
{
uint pos;
- uint64 current = 4;
+ uint64 current = sizeof(void *);
for(pos=0; pos < NUM_POOLS; pos++)
{
int expansion;
pools[c].blockSize = NTH_SIZE(c);
- if(pools[c].blockSize % 4)
- pools[c].blockSize += 4 - (pools[c].blockSize % 4);
+ if(pools[c].blockSize % sizeof(void *))
+ pools[c].blockSize += sizeof(void *) - (pools[c].blockSize % sizeof(void *));
pools[c].blockSpace = pools[c].blockSize;
pools[c].blockSpace += sizeof(class MemBlock);
// pools[c].Expand(initNumBlocks[c]);
TOTAL_MEM += sizeof(class MemBlock) + size;
OUTSIDE_MEM += sizeof(class MemBlock) + size;
block.part = null;
+ block.size = size;
}
}
}
static void * _mycalloc(int n, unsigned int size)
{
- void * pointer = _mymalloc(size);
+ void * pointer = _mymalloc(n*size);
if(pointer)
- memset(pointer, 0, size);
+ memset(pointer, 0, n*size);
return pointer;
}
{
// if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
uint ns = NEXT_SIZE(size);
- uint mod = ns % 4;
- if(mod) ns += 4-mod;
+ uint mod = ns % sizeof(void *);
+ if(mod) ns += sizeof(void *)-mod;
if(ns == pool->blockSize)
{
newPointer = pointer;
{
// if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
uint ns = NEXT_SIZE(size);
- uint mod = ns % 4;
- if(mod) ns += 4-mod;
+ uint mod = ns % sizeof(void *);
+ if(mod) ns += sizeof(void *)-mod;
if(ns == pool->blockSize)
{
int extra = size - block.size;
memMutex.Wait();
#endif
- pointer = malloc(size + 2 * REDZONE);
+ pointer = size ? malloc(size + 2 * REDZONE) : null;
#ifdef MEMINFO
+ if(pointer)
{
MemInfo block;
MemStack stack = (MemStack)memStacks.Find(GetCurrentThreadID());
if(!recurse && !stack.recurse)
{
stack.recurse = true;
- block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+ block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memBlocks.Add(block);
stack.recurse = false;
#endif
#if REDZONE
- memset(pointer, 0xEC, REDZONE);
- memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
- // ((byte *)pointer)[0] = 0x00;
+ if(pointer)
+ {
+ memset(pointer, 0xAB, REDZONE);
+ memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
+ // ((byte *)pointer)[0] = 0x00;
+ }
#endif
- return (byte*)pointer + REDZONE;
+ return pointer ? ((byte*)pointer + REDZONE) : null;
}
static void * _calloc(int n, unsigned int size)
memMutex.Wait();
#endif
- pointer = calloc(n, size + 2 * REDZONE);
+ pointer = (n*size) ? calloc(1, n*size + 2 * REDZONE) : null;
#ifdef MEMINFO
-{
- MemStack stack;
- stack = (MemStack)memStacks.Find(GetCurrentThreadID());
- if(!stack)
- {
- stack = (MemStack)calloc(1, sizeof(class MemStack));
- stack.key = GetCurrentThreadID();
- memStacks.Add(stack);
- }
- if(!pointer)
+ if(pointer)
{
- int c;
- printf("Memory allocation of %d bytes failed\n", size);
- printf("Current Stack:\n");
- for(c = 0; c<stack.pos; c++)
- if(stack.frames[c])
- printf(" %s\n", stack.frames[c]);
- memoryErrorsCount++;
- memMutex.Release();
- return null;
- }
+ MemStack stack;
+ stack = (MemStack)memStacks.Find(GetCurrentThreadID());
+ if(!stack)
+ {
+ stack = (MemStack)calloc(1, sizeof(class MemStack));
+ stack.key = GetCurrentThreadID();
+ memStacks.Add(stack);
+ }
+ if(!pointer)
+ {
+ int c;
+ printf("Memory allocation of %d bytes failed\n", size);
+ printf("Current Stack:\n");
+ for(c = 0; c<stack.pos; c++)
+ if(stack.frames[c])
+ printf(" %s\n", stack.frames[c]);
+ memoryErrorsCount++;
+ memMutex.Release();
+ return null;
+ }
- if(!recurse && !stack.recurse)
- {
- MemInfo block;
-
- stack.recurse = true;
- block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
- memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
- memBlocks.Add(block);
- stack.recurse = false;
+ if(!recurse && !stack.recurse)
+ {
+ MemInfo block;
+
+ stack.recurse = true;
+ block = MemInfo { (unsigned int)n*size = size, key = (uintptr)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
+ memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
+ memBlocks.Add(block);
+ stack.recurse = false;
+ }
}
}
#endif
#endif
#if REDZONE
- memset(pointer, 0xEC, REDZONE);
- memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+ if(pointer)
+ {
+ memset(pointer, 0xAB, REDZONE);
+ memset((byte *)pointer + REDZONE + (unsigned int)n*size, 0xAB, REDZONE);
+ }
#endif
- return (byte*)pointer + REDZONE;
+ return pointer ? ((byte*)pointer + REDZONE) : null;
}
static void * _realloc(void * pointer, unsigned int size)
if(!recurse && !stack.recurse && pointer)
{
- block = (MemInfo)memBlocks.Find((uint)pointer);
+ block = (MemInfo)memBlocks.Find((uintptr)pointer);
if(!block)
{
printf("Reallocating Bad Memory\n");
memMutex.Release();
return null;
}
- memset(pointer, 0xEC, REDZONE);
- memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+ memset(pointer, 0xAB, REDZONE);
+ memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
if(block)
{
{
memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
- block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
- memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+ block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+ if(block.oldmem)
+ {
+ block.oldmem += REDZONE;
+ memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+ }
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
{
MemInfo block;
stack.recurse = true;
- block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+ block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memBlocks.Add(block);
stack.recurse = false;
#if !defined(ECERE_BOOTSTRAP)
memMutex.Release();
#endif
- return (byte *)pointer + REDZONE;
+ return pointer ? ((byte *)pointer + REDZONE) : null;
}
static void * _crealloc(void * pointer, unsigned int size)
if(!recurse && !stack.recurse && pointer)
{
- block = (MemInfo)memBlocks.Find((uint)pointer);
+ block = (MemInfo)memBlocks.Find((uintptr)pointer);
if(!block)
{
printf("Reallocating Bad Memory\n");
memMutex.Release();
return null;
}
- memset(pointer, 0xEC, REDZONE);
- memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
+ memset(pointer, 0xAB, REDZONE);
+ memset((byte *)pointer + REDZONE + size, 0xAB, REDZONE);
if(block)
{
{
memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
- block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
- memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+ block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+ if(block.oldmem)
+ {
+ block.oldmem += REDZONE;
+ memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
+ }
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
{
MemInfo block;
stack.recurse = true;
- block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
+ block = MemInfo { size = size, key = (uintptr)((byte *)pointer + REDZONE), id = blockID++ };
memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memBlocks.Add(block);
stack.recurse = false;
#if !defined(ECERE_BOOTSTRAP)
memMutex.Release();
#endif
- return (byte *)pointer + REDZONE;
+ return pointer ? ((byte *)pointer + REDZONE) : null;
}
static void _free(void * pointer)
{
MemInfo block;
stack.recurse = true;
- block = (MemInfo)memBlocks.Find((uint)pointer);
+ block = (MemInfo)memBlocks.Find((uintptr)pointer);
if(!block)
{
int c;
address = (byte *)block.key;
for(c = 0; c<REDZONE; c++)
{
- if(address[-c-1] != 0xEC)
+ if(address[-c-1] != 0xAB)
{
printf("Buffer Underrun\n");
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
- if(address[c + size] != 0xEC)
+ if(address[c + size] != 0xAB)
{
printf("Buffer Overrun\n");
memoryErrorsCount++;
}
block.freed = true;
- block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
- memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
+ block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
+ if(block.oldmem)
+ {
+ block.oldmem += REDZONE;
+ memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
+ }
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
memoryErrorsCount++;
}
printf("Starting Memory Check\n");
- for(block = (MemInfo)memBlocks.first; block; block = block.next)
+ for(block = (MemInfo)memBlocks.first; block; block = (MemInfo)block.next)
{
if(!block.freed && block._class)
leakedObjects++;
address = (byte *)block.key;
for(c = 0; c<REDZONE; c++)
{
- if(address[-c-1] != 0xEC)
+ if(address[-c-1] != 0xAB)
{
printf("Buffer Underrun\n");
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
- if(address[c + size] != 0xEC)
+ if(address[c + size] != 0xAB)
{
printf("Buffer Overrun\n");
memoryErrorsCount++;
int sizeClass = _class.sizeClass - _class.offsetClass;
Class enumBase = null;
char * dataTypeString = null;
+ // NOTE: baseClass is class(class)
Class baseClass;
uint offsetBefore = _class.offset;
int offsetClass, totalSizeClass;
for(baseClass = base; baseClass.base; baseClass = baseClass.base);
-
- if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass)) type = base.type;
+
+ if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass))
+ {
+ // Normal classes inheriting off simple classes should become no head classes
+ if(base.type == structClass && type == normalClass)
+ type = noHeadClass;
+ else
+ type = base.type;
+ }
+ if(base && (_class.type == normalClass || _class.type == noHeadClass || _class.type == structClass) &&
+ (base.type == unitClass || base.type == bitClass || base.type == enumClass))
+ {
+ type = base.type;
+ }
if(type == enumClass)
{
{
Method method, next;
Class b;
+ 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 &&
- (mod != (base.templateClass ? base.templateClass : base) || _class.vTblSize != mod.vTblSize))
+ if(mod.base && mod.base.base && mod.base.vTblSize > baseClass.vTblSize && needUpdate)
{
_class.vTblSize += mod.base.vTblSize - baseClass.vTblSize;
_class._vTbl = renew _class._vTbl void *[_class.vTblSize];
// memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (_class.vTblSize - mod.vTblSize) * sizeof(void *));
+ updateStart = baseClass.vTblSize;
+ updateEnd = updateStart + mod.base.vTblSize - baseClass.vTblSize;
+
for(method = (Method)_class.methods.first; method; method = next)
{
next = (Method)((BTNode)method).next;
if(method.type == virtualMethod)
method.vid += mod.base.vTblSize - baseClass.vTblSize;
}
+ }
for(b = mod.base; b && b != null; b = b.base)
{
method._class = vMethod._class;
}
}
- else
+ else if((vMethod.vid >= updateStart && vMethod.vid < updateEnd ) || _class._vTbl[vMethod.vid] == b._vTbl[vMethod.vid])
_class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
}
}
}
- }
+ //}
+ // Trying to simply move out the above block of code outside the if to handle this
+ /*
// Also doing this now, otherwise overridden methods of base classes from intermediate classes will not be set in higher level class
// (e.g. OnGetString overridden in Id , Location inheriting from Id, LocationAbbreviation created later inheriting from Location would not get Id's OnGetString)
for(b = mod.base; b && b != null; b = b.base)
{
if(vMethod.type == virtualMethod)
{
- if(_class._vTbl[vMethod.vid] == baseClass._vTbl[vMethod.vid] && _class._vTbl[vMethod.vid] != _class.base._vTbl[vMethod.vid])
+ if(_class._vTbl[vMethod.vid] == b._vTbl[vMethod.vid] && _class._vTbl[vMethod.vid] != _class.base._vTbl[vMethod.vid])
_class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
}
}
}
+ */
}
// _class.defaultAlignment = base ? base.defaultAlignment : 0;
{
int start = 0, c;
NameSpace * nameSpace = null;
+ bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
+ bool force32Bits = (module.application.isGUIApp & 4) ? true : false;
+ bool inCompiler = (module.application.isGUIApp & 8) ? true : false;
+ bool crossBits = force32Bits || force64Bits;
{
nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
if(totalSizeClass)
{
_class.data = renew _class.data byte[totalSizeClass];
+ // Class Data is often not inherited... e.g. Window::pureVtbl problem
// memset(_class.data, 0, totalSizeClass);
if(base && base.type != systemClass && base.type != enumClass)
memcpy(_class.data, base.data, offsetClass);
}
_class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
if(type == normalClass || type == noHeadClass)
- _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+ _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : (force64Bits ? 24 : (force32Bits && inCompiler) ? 12 : sizeof(class Instance)));
+
+ // For cross-bitness-compiling
+ if(crossBits)
+ {
+ // Ideally, the running library should be aware of the struct size of both 32 and 64 bit, since the compiler has no knowledge whatsoever of private members
+ if(strstr(name, "ecere::sys::EARHeader") ||
+ strstr(name, "AnchorValue") ||
+ !strcmp(name, "ecere::com::CustomAVLTree") ||
+ !strcmp(name, "ecere::com::Array") ||
+ !strcmp(name, "ecere::gui::Window") ||
+ !strcmp(name, "ecere::sys::Mutex")); // Never recompute these, they're always problematic (errors, crashes)
+ else
+ {
+ if(!strcmp(name, "ecere::sys::FileListing"))
+ {
+ 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
+ }
+ // These we want to recompute inside the IDE to help the debugger
+ else if(!strcmp(name, "ecere::com::Class")) size = 0; // 616
+ else if(!strcmp(name, "ecere::com::ClassProperty")) size = 0; // 80
+ else if(!strcmp(name, "ecere::com::NameSpace")) size = 0; // 176
+ else if(!strcmp(name, "ecere::sys::BufferedFile")) size = 0;
+ else if(!strcmp(name, "ecere::sys::BTNode")) size = 0;
+ else if(!strcmp(name, "ecere::sys::StringBTNode")) size = 0;
+ else if(!strcmp(name, "ecere::sys::OldList")) size = 0; // 32
+ else if(!strcmp(name, "ecere::sys::Item")) size = 0;
+ else if(!strcmp(name, "ecere::sys::NamedLink")) size = 0;
+ else if(!strcmp(name, "ecere::sys::OldLink")) size = 0;
+ else if(!strcmp(name, "ecere::sys::NamedItem")) size = 0;
+ else if(!strcmp(name, "ecere::sys::NamedItem64")) size = 0;
+ else if(!strcmp(name, "ecere::sys::BinaryTree")) size = 0;
+ else if(module != module.application && inCompiler)
+ {
+ // These we only want to recompute inside the compiler
+ size = 0;
+ }
+ }
+ }
if(type == structClass)
{
_class.memberOffset = (base && base.structSize && base.type != systemClass) ? base.structSize : 0;
delete template.fullName;
delete template.name;
delete template.templateArgs;
+ delete template.dataTypeString;
while((deriv = template.derivatives.first))
{
//if(_class.templateArgs)
//printf("Deleting Template args for %s\n", _class.name);
delete _class.templateArgs;
+ delete _class.dataTypeString;
while((template = _class.templatized.first))
{
static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOffset)
{
BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uint)listOffset);
- BTNamedLink link = (BTNamedLink)tree->Find((uint)name);
+ BTNamedLink link = (BTNamedLink)tree->Find((uintptr)name);
NameSpace * child;
if(!link)
{
else if(ch == '-') { sign = -1; c++; };
if(!base)
{
- if(ch == 0 && string[c+1] == 'x')
+ if(ch == '0' && string[c+1] == 'x')
{
base = 16;
c+=2;
}
for( ;(ch = string[c]); c++)
{
- if(ch == '0')
- ch = 0;
- else if(ch >= '1' && ch <= '9')
- ch -= '1';
+ if(ch >= '0' && ch <= '9')
+ ch -= '0';
else if(ch >= 'a' && ch <= 'z')
- ch -= 'a';
+ ch -= ('a' - 10);
else if(ch >= 'A' && ch <= 'Z')
- ch -= 'A';
+ ch -= ('A'- 10);
else
{
- *endString = string + c;
+ if(endString)
+ *endString = string + c;
// Invalid character
break;
}
}
else
{
- *endString = string + c;
+ if(endString)
+ *endString = string + c;
// Invalid character
break;
}
else if(ch == '-') { sign = -1; c++; };
if(!base)
{
- if(ch == 0 && string[c+1] == 'x')
+ if(ch == '0' && string[c+1] == 'x')
{
base = 16;
c+=2;
}
for( ;(ch = string[c]); c++)
{
- if(ch == '0')
- ch = 0;
- else if(ch >= '1' && ch <= '9')
- ch -= '1';
+ if(ch >= '0' && ch <= '9')
+ ch -= '0';
else if(ch >= 'a' && ch <= 'z')
- ch -= 'a';
+ ch -= ('a' - 10);
else if(ch >= 'A' && ch <= 'Z')
- ch -= 'A';
+ ch -= ('A' - 10);
else
{
- *endString = string + c;
+ if(endString)
+ *endString = string + c;
// Invalid character
break;
}
}
else
{
- *endString = string + c;
+ if(endString)
+ *endString = string + c;
// Invalid character
break;
}
templatedClass.templateClass = _class;
//templatedClass.fullName = CopyString(name);
templatedClass.fullName = CopyString(className);
+ templatedClass.dataTypeString = CopyString(_class.dataTypeString);
templatedClass.name = CopyString(templatedClass.fullName + strlen(_class.fullName) - strlen(_class.name));
templatedClass.nameSpace->classes.Add((BTNode)BTNamedLink { name = templatedClass.name, data = templatedClass });
templatedClass.templateArgs = null;
if(expClass)
{
//if(expClass.type ==
- expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString](expClass, &argument.expression, value);
+ ((bool (*)(void *, void *, const char *))(void *)expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString])(expClass, &argument.expression, value);
}
// Expression should be pre simplified here
else if(value[0] == '\"')
static void SetDelayedCPValues(Class _class, ClassProperty _property)
{
OldLink deriv;
- NamedLink value, next;
+ NamedLink64 value, next;
for(value = _class.delayedCPValues.first; value; value = next)
{
if(!strcmp(value.name, _property.name))
{
// eClass_SetProperty(_class, _property.name, value.data);
- _property.Set(_class, (int)value.data);
+ _property.Set(_class, value.data);
_class.delayedCPValues.Delete(value);
}
}
return _property;
}
-public dllexport int eClass_GetProperty(Class _class, char * name)
+public dllexport int64 eClass_GetProperty(Class _class, char * name)
{
ClassProperty _property = eClass_FindClassProperty(_class, name);
if(_property && _property.Get && _property.Get != (void *)1)
{
- int result = _property.Get(_class);
+ int64 result = _property.Get(_class);
return result;
}
return 0;
}
-public dllexport void eClass_SetProperty(Class _class, char * name, int value)
+public dllexport void eClass_SetProperty(Class _class, char * name, int64 value)
{
ClassProperty _property = eClass_FindClassProperty(_class, name);
if(_property)
{
if(_property.Set)
- _property.Set(_class, value);
+ ((void(*)(void *, int64))_property.Set)(_class, value);
}
else
{
- _class.delayedCPValues.Add(NamedLink { name = name, (void *)value });
+ _class.delayedCPValues.Add(NamedLink64 { name = name, value });
}
}
}
// Construct an instance
-static bool ConstructInstance(void * instance, Class _class)
+static bool ConstructInstance(void * instance, Class _class, Class from)
{
if(_class.templateClass) _class = _class.templateClass;
- if(_class.base)
+ if(_class.base && from != _class.base)
{
- if(!ConstructInstance(instance, _class.base))
+ if(!ConstructInstance(instance, _class.base, from))
return false;
}
if(_class.Initialize)
#endif
#endif
- instance = _calloc(1, _class.structSize);
+ {
+ int size = _class.structSize;
+ int flags = _class.module.application.isGUIApp;
+ bool inCompiler = (flags & 8) ? true : false;
+ bool force32Bits = (flags & 4) ? true : false;
+ if(force32Bits && inCompiler)
+ {
+ // Allocate 64 bit sizes for these when cross-compiling for 32 bit to allow loaded libraries to work properly
+ if(!strcmp(_class.name, "Module"))
+ size = 560;
+ else if(_class.templateClass && !strcmp(_class.templateClass.name, "Map"))
+ size = 40;
+ else
+ size *= 3;
+ }
+ instance = _calloc(1, size);
+ }
#ifdef MEMINFO
allocateClass = null;
memMutex.Release();
// Copy the virtual table initially
instance._vTbl = _class._vTbl;
}
- if(!ConstructInstance(instance, _class))
+ if(!ConstructInstance(instance, _class, null))
{
_free(instance);
instance = null;
{
if(_class && instancePtr && *instancePtr)
{
+ bool wasApp = false, wasGuiApp = false;
Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
+ Class fromClass = instance._class;
*instancePtr = instance;
memset(((byte *)instance) + instance._class.structSize, 0, _class.structSize - instance._class.structSize);
// Fix pointers to application
- if(!strcmp(instance._class.name, "Application"))
+ if((wasApp = !strcmp(instance._class.name, "Application")) ||
+ (wasGuiApp = !strcmp(instance._class.name, "GuiApplication")))
{
Module module;
Application app = (Application) instance;
template.module = _class.module;
}
}
+
+ for(module = app.allModules.first; module; module = module.next)
+ {
+ for(_class = module.classes.first; _class; _class = _class.next)
+ {
+ OldLink templateLink;
+ _class.module = module;
+ for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
+ {
+ Class template = templateLink.data;
+ template.module = _class.module;
+ }
+ }
+ }
+
app.application = app;
}
// Copy the virtual table initially
instance._vTbl = _class._vTbl;
- if(!ConstructInstance(instance, _class))
+ // We don't want to reconstruct the portion already constructed...
+ if(!ConstructInstance(instance, _class, fromClass))
{
_free(instance);
*instancePtr = null;
}
else
{
- library = Instance_Module_Load(name, &Load, &Unload);
+ char * libLocation = null;
+#if defined(__ANDROID__)
+ libLocation = AndroidInterface_GetLibLocation();
+#endif
+ library = Instance_Module_Load(libLocation, name, &Load, &Unload);
}
if(Load)
{
module.name = CopyString(name);
module.Unload = Unload;
module.origImportType = normalImport;
+
if(!Load(module))
{
eInstance_Delete((Instance)module);
module.library = null;
module.name = CopyString(name);
module.Unload = Unload;
+
if(!Load(module))
{
eInstance_Delete((Instance)module);
module = null;
}
+
fromModule.application.allModules.Add(module);
}
if(module)
}
incref module;
}
+#if defined(_DEBUG)
+ InternalModuleLoadBreakpoint();
+#endif
return module;
}
{
if(instance && _property && _property.isWatchable)
{
- OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
- Watcher watcher, next;
-
- for(watcher = watchers->first; watcher; watcher = next)
+ Module module = instance._class ? instance._class.module : null;
+ Application application = module ? module.application : null;
+ int flags = application ? application.isGUIApp : 0;
+ bool inCompiler = (flags & 8) ? true : false;
+ bool force32Bits = (flags & 4) ? true : false;
+ if(!force32Bits || !inCompiler)
{
- next = watcher.next;
- watcher.callback(watcher.object, instance);
+ OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
+ Watcher watcher, next;
+
+ for(watcher = watchers->first; watcher; watcher = next)
+ {
+ next = watcher.next;
+ watcher.callback(watcher.object, instance);
+ }
}
}
}
static void LoadCOM(Module module)
{
+ bool force64Bits = (module.application.isGUIApp & 2) ? true : false;
+ bool force32Bits = (module.application.isGUIApp & 4) ? true : false;
+ bool inCompiler = (module.application.isGUIApp & 8) ? true : false;
+ int pointerSize = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
Class applicationClass;
Class enumClass, structClass, boolClass;
Class moduleClass;
instanceClass.memberID = -3;
instanceClass.startMemberID = -3;
- // eClass_AddDataMember(instanceClass, "_vTbl", "void **", sizeof(int (**)()), 4, publicAccess);
- eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", sizeof(int (**)()), 4, publicAccess);
- eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", sizeof(Class), 4, publicAccess);
- eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int (**)()), 4, publicAccess);
+ eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", pointerSize, pointerSize, publicAccess);
+ eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", pointerSize, pointerSize, publicAccess);
+ eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int), sizeof(int), publicAccess);
}
InitializeDataTypes1(module);
// Create Enum class
- enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
+ enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, force64Bits ? 40 : sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
enumClass.type = systemClass;
eEnum_AddFixedValue(boolClass, "false", bool::false);
// Create Module class
- moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
+ moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, force64Bits ? 8 + 32 + 32 + 32 + 32 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + (32 + 8 + 8 + 4*32) + (32 + 8 + 8 + 4*32) :
+ sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
eClass_AddVirtualMethod(moduleClass, "OnLoad", "bool()", null, publicAccess);
eClass_AddVirtualMethod(moduleClass, "OnUnload", "void()", null, publicAccess);
eClass_AddMethod(moduleClass, "Load", "Module(char * name, AccessMode importAccess)", eModule_Load, publicAccess);
eClass_AddMethod(moduleClass, "Unload", "void(Module module)", eModule_Unload, publicAccess);
- eClass_AddDataMember(moduleClass, "application", "Application", sizeof(Application), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "classes", "OldList", sizeof(OldList), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "defines", "OldList", sizeof(OldList), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "functions", "OldList", sizeof(OldList), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "modules", "OldList", sizeof(OldList), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "prev", "Module", sizeof(Module), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "next", "Module", sizeof(Module), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "name", "char *", sizeof(char *), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "library", "void *", sizeof(void *), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "Unload", "void *", sizeof(void *), 4, publicAccess);
+ eClass_AddDataMember(moduleClass, "application", "Application", pointerSize, pointerSize, publicAccess);
+ eClass_AddDataMember(moduleClass, "classes", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+ eClass_AddDataMember(moduleClass, "defines", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+ eClass_AddDataMember(moduleClass, "functions", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+ 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, "library", "void *", pointerSize, pointerSize, publicAccess);
+ eClass_AddDataMember(moduleClass, "Unload", "void *", pointerSize, pointerSize, publicAccess);
eClass_AddDataMember(moduleClass, "importType", "ImportType", sizeof(ImportType), 4, publicAccess);
eClass_AddDataMember(moduleClass, "origImportType", "ImportType", sizeof(ImportType), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
- eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
+ eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
+ eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
moduleClass.fixed = true;
moduleClass.count++;
+ if(inCompiler && force32Bits)
+ moduleClass.structSize = 12 + 4 + 20 + 20 + 20 + 20 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + (16 + 4 + 4 + 4*16) + (16 + 4 + 4 + 4*16);
// Create Application class
- applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
+ applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", force64Bits ? (8+8+4+4 + 32 + 8 + 176) : sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
+ if(inCompiler && force32Bits)
+ {
+ applicationClass.offset = 12 + 4 + 20 + 20 + 20 + 20 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + (16 + 4 + 4 + 4*16) + (16 + 4 + 4 + 4*16);
+ applicationClass.structSize = applicationClass.offset + (4+4+4+4 + 20 + 4 + 88);
+ }
eClass_AddVirtualMethod(applicationClass, "Main", "void()", null, publicAccess);
eClass_AddDataMember(applicationClass, "argc", "int", sizeof(int), 4, publicAccess);
- eClass_AddDataMember(applicationClass, "argv", "char **", sizeof(char **), 4, publicAccess);
+ eClass_AddDataMember(applicationClass, "argv", "char **", pointerSize, pointerSize, publicAccess);
eClass_AddDataMember(applicationClass, "exitCode", "int", sizeof(int), 4, publicAccess);
eClass_AddDataMember(applicationClass, "isGUIApp", "bool", sizeof(bool), 4, publicAccess);
- eClass_AddDataMember(applicationClass, "allModules", "OldList", sizeof(OldList), 4, publicAccess);
- eClass_AddDataMember(applicationClass, "parsedCommand", "char *", sizeof(char *), 4, publicAccess);
- eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
+ eClass_AddDataMember(applicationClass, "allModules", "OldList", force64Bits ? 32 : force32Bits ? 20 : sizeof(OldList), pointerSize, publicAccess);
+ eClass_AddDataMember(applicationClass, "parsedCommand", "char *", pointerSize, pointerSize, publicAccess);
+ eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", force64Bits ? (32 + 8 + 8 + 4*32) : force32Bits ? (16 + 4 + 4 + 4*16) : sizeof(NameSpace), pointerSize, publicAccess);
applicationClass.fixed = true;
applicationClass.count++;
eSystem_RegisterFunction("exp", "double exp(double number)", exp, module, baseSystemAccess);
// --- Stdlib ---
- eSystem_RegisterFunction("qsort", "void qsort(void *, uint, uint, int (*)(void *, void *))", qsort, module, baseSystemAccess);
+ eSystem_RegisterFunction("qsort", "void qsort(void *, uintsize, uintsize, int (*)(void *, void *))", qsort, module, baseSystemAccess);
eSystem_RegisterFunction("strtod", "double strtod(char*, char**)", strtod, module, baseSystemAccess);
eSystem_RegisterFunction("strtol", "int strtol(char*, char**, int base)", strtol, module, baseSystemAccess);
eSystem_RegisterFunction("system", "int system(const char*)", system, module, baseSystemAccess);
eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
- eSystem_RegisterFunction("memset", "void memset(void * area, byte value, uint count)", memset, module, baseSystemAccess);
+ eSystem_RegisterFunction("memset", "void * memset(void * area, int value, uintsize count)", memset, module, baseSystemAccess);
eSystem_RegisterFunction("getenv", "char * getenv(const char * name)", getenv, module, baseSystemAccess);
eSystem_RegisterFunction("rename", "int rename(const char *oldpath, const char *newpath)", rename, module, baseSystemAccess);
// --- String --- (These might move to the string class)
- eSystem_RegisterFunction("strlen", "int strlen(const char *)", strlen, module, baseSystemAccess);
+ eSystem_RegisterFunction("strlen", "uintsize strlen(const char *)", strlen, module, baseSystemAccess);
eSystem_RegisterFunction("strcat", "char * strcat(char *, const char *)", strcat, module, baseSystemAccess);
- eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, int n)", strncat, module, baseSystemAccess);
- eSystem_RegisterFunction("strchr", "char * strchr(char *, int)", strchr, module, baseSystemAccess);
- eSystem_RegisterFunction("strstr", "char * strstr(char *, const char *)", strstr, module, baseSystemAccess);
+ eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, uintsize n)", strncat, module, baseSystemAccess);
+ eSystem_RegisterFunction("strchr", "char * strchr(const char *, int)", strchr, module, baseSystemAccess);
+ eSystem_RegisterFunction("strstr", "char * strstr(const char *, const char *)", strstr, module, baseSystemAccess);
eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
eSystem_RegisterDefine("strnicmp", "strncasecmp", module, baseSystemAccess);
eSystem_RegisterFunction("strcasecmp", "int strcasecmp(const char *, const char *)", strcmpi, module, baseSystemAccess);
- eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
+ eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, uintsize n)", strnicmp, module, baseSystemAccess);
/*
#else
eSystem_RegisterDefine("strcasecmp", "strcmpi", module, baseSystemAccess);
*/
eSystem_RegisterFunction("strcmp", "int strcmp(const char *, const char *)", strcmp, module, baseSystemAccess);
- eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, int n)", strncmp, module, baseSystemAccess);
+ eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, uintsize n)", strncmp, module, baseSystemAccess);
eSystem_RegisterFunction("strlwr", "char * strlwr(char *)", strlwr, module, baseSystemAccess);
eSystem_RegisterFunction("strupr", "char * strupr(char *)", strupr, module, baseSystemAccess);
eSystem_RegisterFunction("strcpy", "char * strcpy(char *, const char *)", strcpy, module, baseSystemAccess);
- eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, int n)", strncpy, module, baseSystemAccess);
- eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uint size)", memcpy, module, baseSystemAccess);
- eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uint size)", memmove, module, baseSystemAccess);
+ eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, uintsize n)", strncpy, module, baseSystemAccess);
+ eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uintsize size)", memcpy, module, baseSystemAccess);
+ eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uintsize size)", memmove, module, baseSystemAccess);
// --- Stdio ---
eSystem_RegisterFunction("sprintf", "int sprintf(char *, char *, ...)", sprintf, module, baseSystemAccess);
+ eSystem_RegisterFunction("snprintf", "int sprintf(char *, uintsize, char *, ...)", snprintf, module, baseSystemAccess);
eSystem_RegisterFunction("printf", "int printf(char *, ...)", printf, module, baseSystemAccess);
eSystem_RegisterFunction("vsprintf", "int vsprintf(char*, const char*, __builtin_va_list)", vsprintf, module, baseSystemAccess);
+ 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);
{
Application app;
+#ifdef __ANDROID__
+ // Clean up global variables
+ memoryInitialized = false;
+ pools = null;
+#ifdef MEMINFO
+ memset(&memStacks, 0, sizeof(BinaryTree));
+ memoryErrorsCount = 0;
+ memset(&memBlocks, 0, sizeof(BinaryTree));
+ recurse = false;
+ blockID = 0;
+ allocateClass = null;
+ allocateInternal = false;
+ TOTAL_MEM = 0;
+ OUTSIDE_MEM = 0;
+#endif
+#endif
+
#ifdef _DEBUG
// printf("Using debug ecere runtime library\n");
#endif
return d;
}
+// NOTE: UTF8GetChar now returns 0 into numBytes for the null-terminating character ('\0')
public unichar UTF8GetChar(char * string, int * numBytes)
{
unichar ch;
byte b = ((byte *)string)[0];
int i;
byte mask = 0x7F;
- int nb = 1;
+ int nb = b ? 1 : 0;
ch = 0;
if(b & 0x80)
{