ecere/com; compiler/libec: (#1087) Fixed class:struct issues
authorJerome St-Louis <jerome@ecere.com>
Fri, 11 Jul 2014 01:36:45 +0000 (21:36 -0400)
committerJerome St-Louis <jerome@ecere.com>
Fri, 11 Jul 2014 01:44:48 +0000 (21:44 -0400)
- Watches on a derived class:struct member whose base class has end-padding did not work (e.g. AddCharAction)
- Alignment issues as derived classes are bundled together in a single struct
- Derived class offset was not correct
- OnGetString, OnGetDataFromString and JSON did not add class offset but should have
- typed_object& methods when called as a member of a class:struct did not have proper reference level (the address of the class:struct instance should be passed)

compiler/bootstrap/ecc/bootstrap/ecc.c
compiler/bootstrap/ecere/bootstrap/dataTypes.c
compiler/bootstrap/ecere/bootstrap/instance.c
compiler/bootstrap/libec/bootstrap/pass15.c
compiler/bootstrap/libec/bootstrap/pass2.c
compiler/libec/src/pass15.ec
compiler/libec/src/pass2.ec
ecere/src/com/dataTypes.ec
ecere/src/com/instance.ec
ecere/src/sys/JSON.ec
eda/drivers/sqlite/EDASQLite.ec

index 91841e2..6cba15a 100644 (file)
@@ -639,7 +639,7 @@ char *  dataTypeString;
 struct Type * dataType;
 void *  symbol;
 char *  fullName;
-char __ecere_padding[40];
+char __ecere_padding[36];
 } ecere_gcc_struct;
 
 extern struct __ecereNameSpace__ecere__com__Instance * __ecereNameSpace__ecere__com__eModule_LoadStrict(struct __ecereNameSpace__ecere__com__Instance * fromModule, const char *  name, int importAccess);
index e8aef74..9cb3bc1 100644 (file)
@@ -2305,6 +2305,7 @@ for(member = _class->membersAndProperties.first; member; member = member->next)
 char memberString[1024];
 struct __ecereNameSpace__ecere__com__Class * memberType = member->dataTypeClass;
 const char * name = member->name;
+const char * (* onGetString)(void *, void *, char *, void *, unsigned int *);
 
 if(member->id < 0)
 continue;
@@ -2313,6 +2314,7 @@ if(!memberType)
 memberType = member->dataTypeClass = __ecereNameSpace__ecere__com__eSystem_FindClass(module, member->dataTypeString);
 if(!memberType)
 memberType = member->dataTypeClass = __ecereNameSpace__ecere__com__eSystem_FindClass(module, "int");
+onGetString = memberType->_vTbl[__ecereVMethodID_class_OnGetString];
 if(member->isProperty)
 {
 struct __ecereNameSpace__ecere__com__Property * prop = (struct __ecereNameSpace__ecere__com__Property *)member;
@@ -2335,7 +2337,7 @@ value.__anon1.f = ((float (*)(void *))(void *)prop->Get)(data);
 if(value.__anon1.f)
 {
 unsigned int needClass = 1;
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, (((void *)0)), &needClass);
+const char * result = onGetString(memberType, &value, memberString, (((void *)0)), &needClass);
 
 if(result && result != memberString)
 strcpy(memberString, result);
@@ -2349,7 +2351,7 @@ value.__anon1.p = ((void * (*)(void *))(void *)prop->Get)(data);
 if(value.__anon1.p || prop->IsSet)
 {
 unsigned int needClass = 1;
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, (memberType->type == 0) ? value.__anon1.p : &value, memberString, (((void *)0)), &needClass);
+const char * result = onGetString(memberType, (memberType->type == 0) ? value.__anon1.p : &value, memberString, (((void *)0)), &needClass);
 
 if(result && result != memberString)
 strcpy(memberString, result);
@@ -2361,7 +2363,7 @@ value.__anon1.i = ((int (*)(void *))(void *)prop->Get)(data);
 if(value.__anon1.i || prop->IsSet)
 {
 unsigned int needClass = 1;
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, (((void *)0)), &needClass);
+const char * result = onGetString(memberType, &value, memberString, (((void *)0)), &needClass);
 
 if(result && result != memberString)
 strcpy(memberString, result);
@@ -2372,12 +2374,14 @@ strcpy(memberString, result);
 }
 else
 {
+unsigned int offset = member->offset + member->_class->offset;
+unsigned char * memberData = (unsigned char *)data + offset;
+
 if(member->type == 0)
 {
 if(memberType->type == 1 || memberType->type == 0)
 {
 char internalMemberString[1024];
-unsigned char * memberData = ((unsigned char *)data + (((member->_class->type == 0) ? member->_class->offset : 0) + member->offset));
 int c;
 unsigned int typeSize = (memberType->type == 0) ? memberType->typeSize : memberType->structSize;
 
@@ -2390,9 +2394,9 @@ unsigned int needClass = 1;
 const char * result;
 
 if(memberType->type == 0)
-result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, *(struct __ecereNameSpace__ecere__com__Instance **)memberData, internalMemberString, (((void *)0)), &needClass);
+result = onGetString(memberType, *(struct __ecereNameSpace__ecere__com__Instance **)memberData, internalMemberString, (((void *)0)), &needClass);
 else
-result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, memberData, internalMemberString, (((void *)0)), &needClass);
+result = onGetString(memberType, memberData, internalMemberString, (((void *)0)), &needClass);
 if(needClass && strcmp(memberType->dataTypeString, "char *"))
 {
 strcat(memberString, "{ ");
@@ -2423,7 +2427,7 @@ if(value.__anon1.ui64)
 {
 unsigned int needClass = 1;
 char internalMemberString[1024];
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, internalMemberString, (((void *)0)), &needClass);
+const char * result = onGetString(memberType, &value, internalMemberString, (((void *)0)), &needClass);
 
 if(needClass && memberType->type != 1000 && memberType->type != 4 && memberType->type != 3)
 {
@@ -2438,22 +2442,10 @@ strcpy(memberString, result);
 }
 else if(!memberType->noExpansion)
 {
-if(memberType->typeSize <= 4)
-{
-value.__anon1.i = *(int *)((unsigned char *)data + (((member->_class->type == 0) ? member->_class->offset : 0) + member->offset));
-if(value.__anon1.i)
+if(memberType->typeSize > 4 || *(int *)memberData)
 {
 unsigned int needClass = 1;
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, (((void *)0)), &needClass);
-
-if(result && memberString != result)
-strcpy(memberString, result);
-}
-}
-else
-{
-unsigned int needClass = 1;
-const char * result = ((const char * (*)(void *, void *, char *, void *, unsigned int *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetString])(memberType, ((unsigned char *)data + (((member->_class->type == 0) ? member->_class->offset : 0) + member->offset)), memberString, (((void *)0)), &needClass);
+const char * result = onGetString(memberType, memberData, memberString, (((void *)0)), &needClass);
 
 if(result && memberString != result)
 strcpy(memberString, result);
@@ -2741,16 +2733,20 @@ __ecereNameSpace__ecere__com__eClass_FindDataMemberAndOffset(_class, thisMember-
 if(found)
 {
 struct __ecereNameSpace__ecere__com__Class * memberType = thisMember->dataTypeClass;
+unsigned int offset;
+unsigned char * memberData;
 
 if(!memberType)
 memberType = thisMember->dataTypeClass = __ecereNameSpace__ecere__com__eSystem_FindClass(module, thisMember->dataTypeString);
 if(!memberType)
 memberType = thisMember->dataTypeClass = __ecereNameSpace__ecere__com__eSystem_FindClass(module, "int");
+offset = thisMember->_class->offset + memberOffset;
+memberData = (unsigned char *)data + offset;
 if(memberType->type == 1)
 {
 if(thisMember)
 {
-if(!((unsigned int (*)(void *, void *, const char *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetDataFromString])(memberType, (unsigned char *)data + (((thisMember->_class->type == 0) ? thisMember->_class->offset : 0) + memberOffset), memberString))
+if(!((unsigned int (*)(void *, void *, const char *))(void *)memberType->_vTbl[__ecereVMethodID_class_OnGetDataFromString])(memberType, memberData, memberString))
 result = 0;
 }
 }
@@ -2780,7 +2776,7 @@ struct __ecereNameSpace__ecere__com__BitMember * bitMember = (struct __ecereName
 *(unsigned int *)data = (unsigned int)(((*(unsigned int *)data & ~bitMember->mask)) | ((value.__anon1.ui64 << bitMember->pos) & bitMember->mask));
 }
 else
-*(int *)((unsigned char *)data + (((thisMember->_class->type == 0) ? thisMember->_class->offset : 0) + thisMember->offset)) = value.__anon1.i;
+*(int *)memberData = value.__anon1.i;
 }
 else if(thisMember->isProperty && ((struct __ecereNameSpace__ecere__com__Property *)thisMember)->Set)
 {
index 93d52af..27d0c40 100644 (file)
@@ -4693,7 +4693,7 @@ dataTypeString = enumBase ? enumBase->dataTypeString : base->dataTypeString;
 offsetClass = base ? (base->templateClass ? base->templateClass->sizeClass : base->sizeClass) : (type == 5 ? 0 : 0);
 totalSizeClass = offsetClass + sizeClass;
 if(type == 0 || type == 5)
-_class->offset = (base && (base->templateClass ? base->templateClass->structSize : base->structSize) && base->type != 1000) ? (base->templateClass ? base->templateClass->structSize : base->structSize) : ((type == 5) ? 0 : sizeof(struct __ecereNameSpace__ecere__com__Instance));
+_class->offset = (base && (base->templateClass ? (type == 0 ? base->templateClass->structSize : base->templateClass->memberOffset) : (type == 0 ? base->structSize : base->memberOffset)) && base->type != 1000) ? (base->templateClass ? base->templateClass->structSize : base->structSize) : ((type == 5) ? 0 : sizeof(struct __ecereNameSpace__ecere__com__Instance));
 else
 _class->offset = 0;
 if(type == 1)
@@ -5453,7 +5453,7 @@ id++;
 }
 _class->memberID = _class->startMemberID = (base && (type == 0 || type == 5 || type == 1)) ? base->memberID : 0;
 if(type == 0 || type == 5)
-_class->offset = (base && base->structSize && base->type != 1000) ? base->structSize : ((type == 5) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(struct __ecereNameSpace__ecere__com__Instance)));
+_class->offset = (base && base->structSize && base->type != 1000) ? (base->type == 0 ? base->structSize : base->memberOffset) : ((type == 5) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(struct __ecereNameSpace__ecere__com__Instance)));
 else
 _class->offset = 0;
 if(crossBits)
index 1247c53..8a060a5 100644 (file)
@@ -10688,7 +10688,7 @@ if(_class->structAlignment)
 if(_class->memberOffset % _class->structAlignment)
 extra += _class->structAlignment - (_class->memberOffset % _class->structAlignment);
 }
-_class->structSize = (_class->base ? (_class->base->templateClass ? _class->base->templateClass->structSize : _class->base->structSize) : 0) + _class->memberOffset + extra;
+_class->structSize = (_class->base ? (_class->base->templateClass ? (_class->base->type == 5 ? _class->base->templateClass->memberOffset : _class->base->templateClass->structSize) : (_class->base->type == 5 ? _class->base->memberOffset : _class->base->structSize)) : 0) + _class->memberOffset + extra;
 if(!member)
 {
 struct __ecereNameSpace__ecere__com__Property * prop;
@@ -10711,7 +10711,7 @@ struct __ecereNameSpace__ecere__com__Class * deriv = derivative->data;
 
 if(deriv->computeSize)
 {
-deriv->offset = _class->structSize;
+deriv->offset = (_class->type == 5 ? _class->memberOffset : _class->structSize);
 deriv->memberOffset = 0;
 deriv->structSize = deriv->offset;
 ComputeClassMembers(deriv, 0);
@@ -19169,7 +19169,7 @@ if(_class->fixed)
 {
 struct Expression * e;
 
-if(_class->offset && _class->offset == _class->base->structSize)
+if(_class->offset && _class->offset == (_class->base->type == 5 ? _class->base->memberOffset : _class->base->structSize))
 {
 e = MkExpClassSize(MkSpecifierName(_class->base->fullName));
 ProcessExpressionType(e);
index 446e846..e8b5d7e 100644 (file)
@@ -2919,13 +2919,20 @@ exp->__anon1.call.arguments = MkList();
 if(typedObject && memberExp->__anon1.member.exp && memberExp->__anon1.member.exp->expType)
 {
 unsigned int changeReference = 0;
+unsigned int stillAddReferenceOp = 0;
 struct Expression * memberExpMemberExp = CopyExpression(memberExp->__anon1.member.exp);
+struct Type * expType = memberExp->__anon1.member.exp->expType;
+struct __ecereNameSpace__ecere__com__Class * c = expType->kind == 8 && expType->__anon1._class ? expType->__anon1._class->__anon1.registered : (((void *)0));
 
 if(argClass && (argClass->type == 4 || argClass->type == 3 || argClass->type == 2 || argClass->type == 1000) && strcmp(argClass->fullName, "class") && strcmp(argClass->fullName, "uintptr") && strcmp(argClass->fullName, "intptr"))
 changeReference = 1;
-if(!memberExp->__anon1.member.exp->expType->classObjectType && ((((memberExp->__anon1.member.exp->expType->kind != 13 && (memberExp->__anon1.member.exp->expType->kind != 8 || !memberExp->__anon1.member.exp->expType->__anon1._class || !memberExp->__anon1.member.exp->expType->__anon1._class->__anon1.registered || memberExp->__anon1.member.exp->expType->__anon1._class->__anon1.registered->type == 1)))) || method->dataType->byReference))
+if(!expType->classObjectType && (((expType->kind != 13 && (!c || c->type == 1))) || method->dataType->byReference))
+{
+if(c && (c->type == 0 || c->type == 5))
+stillAddReferenceOp = 1;
 changeReference = 1;
-if(typedObject && memberExp->__anon1.member.exp->expType->classObjectType && memberExp->__anon1.member.exp->expType->byReference != method->dataType->byReference)
+}
+if(typedObject && expType->classObjectType && expType->byReference != method->dataType->byReference)
 changeReference = 1;
 if(changeReference)
 {
@@ -2939,7 +2946,7 @@ else if(memberExp->__anon1.member.exp->type == 4 && memberExp->__anon1.member.ex
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Insert((&*exp->__anon1.call.arguments), (((void *)0)), memberExp->__anon1.member.exp->__anon1.op.exp2);
 memberExp->__anon1.member.exp->__anon1.op.exp2 = (((void *)0));
 }
-else if(!memberExp->__anon1.member.exp->byReference)
+else if(!memberExp->__anon1.member.exp->byReference || stillAddReferenceOp)
 {
 struct Expression * checkedExp = memberExp->__anon1.member.exp;
 struct Expression * parentExp = (((void *)0));
@@ -2970,7 +2977,13 @@ disconnected = 1;
 }
 if(!parentExp)
 nullMemberExp = 1;
-newExp = (typedObject && !memberExp->__anon1.member.exp->expType->classObjectType) ? checkedExp : MkExpOp((((void *)0)), '&', checkedExp);
+if(typedObject && !expType->classObjectType && !stillAddReferenceOp)
+newExp = checkedExp;
+else
+{
+newExp = MkExpOp((((void *)0)), '&', checkedExp);
+newExp->byReference = 1;
+}
 if(parentExp && (parentExp->type == 5 || parentExp->type == 32))
 {
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Remove((&*parentExp->__anon1.list), checkedExp);
@@ -2982,7 +2995,7 @@ parentExp->__anon1.cast.exp = newExp;
 if(newExp->expType && newExp->expType->classObjectType)
 parentExp->__anon1.cast.typeName->declarator = MkDeclaratorPointer(MkPointer((((void *)0)), (((void *)0))), parentExp->__anon1.cast.typeName->declarator);
 }
-if(typedObject && !memberExp->__anon1.member.exp->expType->classObjectType)
+if(typedObject && !expType->classObjectType)
 {
 struct Type * destType = (destType = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass_Type), destType->refCount = 1, destType->kind = 8, destType->classObjectType = 3, destType);
 
index 6eaa2bb..5493f18 100644 (file)
@@ -666,7 +666,9 @@ void ComputeClassMembers(Class _class, bool isMember)
                if(_class.memberOffset % _class.structAlignment)
                   extra += _class.structAlignment - (_class.memberOffset % _class.structAlignment);
             }
-            _class.structSize = (_class.base ? (_class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize) : 0) + _class.memberOffset + extra;
+            _class.structSize = (_class.base ? (_class.base.templateClass ?
+               (_class.base.type == noHeadClass ? _class.base.templateClass.memberOffset : _class.base.templateClass.structSize) :
+                  (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize) ) : 0) + _class.memberOffset + extra;
             if(!member)
             {
                Property prop;
@@ -690,7 +692,7 @@ void ComputeClassMembers(Class _class, bool isMember)
                   if(deriv.computeSize)
                   {
                      // TESTING THIS NEW CODE HERE... TRYING TO FIX ScrollBar MEMBERS DEBUGGING
-                     deriv.offset = /*_class.offset + */_class.structSize;
+                     deriv.offset = /*_class.offset + */(_class.type == noHeadClass ? _class.memberOffset : _class.structSize);
                      deriv.memberOffset = 0;
                      // ----------------------
 
@@ -13104,7 +13106,7 @@ static void ProcessFunction(FunctionDefinition function)
             if(_class.fixed)
             {
                Expression e;
-               if(_class.offset && _class.offset == _class.base.structSize)
+               if(_class.offset && _class.offset == (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize))
                {
                   e = MkExpClassSize(MkSpecifierName(_class.base.fullName));
                   ProcessExpressionType(e);
index 1a2b55e..e955b2d 100644 (file)
@@ -1889,20 +1889,22 @@ static void ProcessExpression(Expression exp)
                   if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
                   {
                      bool changeReference = false;
+                     bool stillAddReferenceOp = false;
                      Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
+                     Type expType = memberExp.member.exp.expType;
+                     Class c = expType.kind == classType && expType._class ? expType._class.registered : null;
 
                      // Patched so that class isn't considered SYSTEM...
                      if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
                         strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
                         changeReference = true;
-                     if(!memberExp.member.exp.expType.classObjectType &&
-                        (((
-                           (memberExp.member.exp.expType.kind != pointerType &&
-                              (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
-                               !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
-                           method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
+                     if(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
+                     {
+                        if(c && (c.type == normalClass || c.type == noHeadClass))
+                           stillAddReferenceOp = true;
                         changeReference = true;
-                     if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
+                     }
+                     if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
                         changeReference = true;
                      if(changeReference)
                      {
@@ -1917,7 +1919,7 @@ static void ProcessExpression(Expression exp)
                            exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
                            memberExp.member.exp.op.exp2 = null;
                         }
-                        else if(!memberExp.member.exp.byReference)
+                        else if(!memberExp.member.exp.byReference || stillAddReferenceOp)
                         {
                            // TESTING THIS... REUSE THIS CODE?
                            Expression checkedExp = memberExp.member.exp;
@@ -1952,7 +1954,13 @@ static void ProcessExpression(Expression exp)
                            if(!parentExp)
                               nullMemberExp = true;
 
-                           newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
+                           if(typedObject && !expType.classObjectType && !stillAddReferenceOp)
+                              newExp = checkedExp;
+                           else
+                           {
+                              newExp = MkExpOp(null, '&', checkedExp);
+                              newExp.byReference = true;
+                           }
                            if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
                            {
                               parentExp.list->Remove(checkedExp);
@@ -1965,7 +1973,7 @@ static void ProcessExpression(Expression exp)
                               if(newExp.expType && newExp.expType.classObjectType)
                                  parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
                            }
-                           if(typedObject && !memberExp.member.exp.expType.classObjectType)
+                           if(typedObject && !expType.classObjectType)
                            {
                               Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
                               FreeType((parentExp ? parentExp : newExp).expType);
index 1a7df80..d4812fd 100644 (file)
@@ -596,6 +596,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
             char memberString[1024];
             Class memberType = member.dataTypeClass;
             const char * name = member.name;
+            const char *(* onGetString)(void *, void *, char *, void *, bool *);
             if(member.id < 0) continue;
 
             memberString[0] = 0;
@@ -605,6 +606,8 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
             if(!memberType)
                memberType = member.dataTypeClass = eSystem_FindClass(module, "int");
 
+            onGetString = memberType._vTbl[__ecereVMethodID_class_OnGetString];
+
             if(member.isProperty)
             {
                Property prop = (Property) member;
@@ -620,7 +623,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                         if(value.f)
                         {
                            bool needClass = true;
-                           const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, null, &needClass);
+                           const char * result = onGetString(memberType, &value, memberString, null, &needClass);
                            if(result && result != memberString)
                               strcpy(memberString, result);
                            // TESTING THIS HERE
@@ -634,7 +637,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                         if(value.p || prop.IsSet)
                         {
                            bool needClass = true;
-                           const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType,
+                           const char * result = onGetString(memberType,
                               (memberType.type == normalClass) ? value.p : &value, memberString, null, &needClass);
                            if(result && result != memberString)
                               strcpy(memberString, result);
@@ -646,7 +649,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                         if(value.i || prop.IsSet)
                         {
                            bool needClass = true;
-                           const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, null, &needClass);
+                           const char * result = onGetString(memberType, &value, memberString, null, &needClass);
                            if(result && result != memberString)
                               strcpy(memberString, result);
                         }
@@ -656,12 +659,13 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
             }
             else
             {
+               uint offset = member.offset + member._class.offset;
+               byte * memberData = (byte *)data + offset;
                if(member.type == normalMember)
                {
                   if(memberType.type == structClass || memberType.type == normalClass)
                   {
                      char internalMemberString[1024];
-                     byte * memberData = ((byte *)data + (((member._class.type == normalClass) ? member._class.offset : 0) + member.offset));
                      int c;
                      uint typeSize = (memberType.type == normalClass) ? memberType.typeSize : memberType.structSize;
                      for(c = 0; c < typeSize; c++)
@@ -672,9 +676,9 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                         bool needClass = true;
                         const char * result;
                         if(memberType.type == normalClass)
-                           result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, *(Instance *)memberData, internalMemberString, null, &needClass);
+                           result = onGetString(memberType, *(Instance *)memberData, internalMemberString, null, &needClass);
                         else
-                           result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, memberData, internalMemberString, null, &needClass);
+                           result = onGetString(memberType, memberData, internalMemberString, null, &needClass);
                         if(needClass && strcmp(memberType.dataTypeString, "char *"))
                         {
                            //strcpy(memberString, memberType.name);
@@ -701,7 +705,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                         {
                            bool needClass = true;
                            char internalMemberString[1024];
-                           const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, internalMemberString, null, &needClass);
+                           const char * result = onGetString(memberType, &value, internalMemberString, null, &needClass);
 
                            if(needClass && memberType.type != systemClass && memberType.type != enumClass && memberType.type != unitClass)
                            {
@@ -720,22 +724,11 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                      }
                      else if(!memberType.noExpansion)
                      {
-                        // TOCHECK: Is this still right??
-                        if(memberType.typeSize <= 4)
-                        {
-                           value.i = *(int *)((byte *)data + (((member._class.type == normalClass) ? member._class.offset : 0) + member.offset));
-                           if(value.i)
-                           {
-                              bool needClass = true;
-                              const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, &value, memberString, null, &needClass);
-                              if(result && memberString != result)
-                                 strcpy(memberString, result);
-                           }
-                        }
-                        else
+                        // TOCHECK: Is this null check still right??
+                        if(memberType.typeSize > 4 || *(int *)memberData)
                         {
                            bool needClass = true;
-                           const char * result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, ((byte *)data + (((member._class.type == normalClass) ? member._class.offset : 0) + member.offset)), memberString, null, &needClass);
+                           const char * result = onGetString(memberType, memberData, memberString, null, &needClass);
                            if(result && memberString != result)
                               strcpy(memberString, result);
                         }
@@ -747,7 +740,7 @@ static const char * OnGetString(Class _class, void * data, char * tempString, vo
                      byte * memberData = ((byte *)data + (((member._class.type == normalClass) ? member._class.offset : 0) + member.offset));
                      bool needClass = true;
                      const char * result;
-                     result = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetString])(memberType, memberData, internalMemberString, null, &needClass);
+                     result = onGetString(memberType, memberData, internalMemberString, null, &needClass);
                      if(needClass)
                      {
                         //strcpy(memberString, memberType.name);
@@ -1051,17 +1044,20 @@ static bool OnGetDataFromString(Class _class, void ** data, const char * string)
          if(found)
          {
             Class memberType = thisMember.dataTypeClass;
+            uint offset;
+            byte * memberData;
 
             if(!memberType)
                memberType = thisMember.dataTypeClass = eSystem_FindClass(module, thisMember.dataTypeString);
             if(!memberType)
                memberType = thisMember.dataTypeClass = eSystem_FindClass(module, "int");
+            offset = thisMember._class.offset + memberOffset;
+            memberData = (byte *)data + offset;
             if(memberType.type == structClass)
             {
                if(thisMember)
                {
-                  if(!((bool (*)(void *, void *, const char *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetDataFromString])(memberType,
-                     (byte *)data + (((thisMember._class.type == normalClass) ? thisMember._class.offset : 0) + memberOffset), memberString))
+                  if(!((bool (*)(void *, void *, const char *))(void *)memberType._vTbl[__ecereVMethodID_class_OnGetDataFromString])(memberType, memberData, memberString))
                      result = false;
                }
             }
@@ -1087,7 +1083,7 @@ static bool OnGetDataFromString(Class _class, void ** data, const char * string)
                      *(uint *)data = (uint32)(((*(uint *)data & ~bitMember.mask)) | ((value.ui64<<bitMember.pos)&bitMember.mask));
                   }
                   else
-                     *(int *)((byte *)data + (((thisMember._class.type == normalClass) ? thisMember._class.offset : 0) + thisMember.offset)) = value.i;
+                     *(int *)memberData = value.i;
                }
                else if(thisMember.isProperty && ((Property)thisMember).Set)
                {
index e1ec582..da30ff9 100644 (file)
@@ -1982,7 +1982,8 @@ static void FixDerivativesBase(Class base, Class mod)
       // _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
 
       if(type == normalClass || type == noHeadClass)
-         _class.offset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+         // Use 'memberOffset' for nohead class as the members get added without padding
+         _class.offset = (base && (base.templateClass ? (type == normalClass ? base.templateClass.structSize : base.templateClass.memberOffset) : (type == normalClass ? base.structSize : base.memberOffset)) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
       else
          _class.offset = 0; // Force set to 0
 
@@ -2642,7 +2643,9 @@ public dllexport Class eSystem_RegisterClass(ClassType type, const char * name,
          }
          _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
          if(type == normalClass || type == noHeadClass)
-            _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
+            _class.offset = (base && base.structSize && base.type != systemClass) ?
+               // Use 'memberOffset' for nohead class as the members get added without padding
+               (base.type == normalClass ? base.structSize : base.memberOffset) : ((type == noHeadClass) ? 0 : ((force64Bits && inCompiler && fixed) ? 24 : (force32Bits && inCompiler && fixed) ? 12 : sizeof(class Instance)));
          else
             _class.offset = 0;   // Force set to 0 for redefinitions
 
index f07fabd..1b94380 100644 (file)
@@ -428,6 +428,7 @@ public:
                Property prop = null;
                Class type = null;
                bool isKey = false;
+               uint offset = 0;
 
                if(objectType)
                {
@@ -451,6 +452,8 @@ public:
                         type = eSystem_FindClass(__thisModule, member.dataTypeString);
                         if(!type)
                            type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
+
+                        offset = member._class.offset + member.offset;
                      }
                      else if(!member)
                      {
@@ -472,7 +475,7 @@ public:
 
                   if(type && type.type == structClass)
                   {
-                     value.p = (byte *)*object + member._class.offset + member.offset;
+                     value.p = (byte *)*object + offset;
                   }
                   ch = 0;
                   SkipEmpty();
@@ -497,7 +500,7 @@ public:
                                     ;
                                  else if(type.type == normalClass || type.type == noHeadClass)
                                  {
-                                    void ** ptr = (void**)((byte *)*object + member._class.offset + member.offset);
+                                    void ** ptr = (void**)((byte *)*object + offset);
                                     if(eClass_IsDerived(type, class(Container)) && *ptr)
                                     {
                                        Container container = (Container)*ptr;
@@ -508,36 +511,36 @@ public:
                                  }
                                  else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
                                  {
-                                    *(double *)((byte *)*object + member._class.offset + member.offset) = value.d;
+                                    *(double *)((byte *)*object + offset) = value.d;
                                  }
                                  else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
                                  {
-                                    *(float *)((byte *)*object + member._class.offset + member.offset) = value.f;
+                                    *(float *)((byte *)*object + offset) = value.f;
                                  }
                                  else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
                                     !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
                                  {
-                                    *(uint64 *)((byte *)*object + member._class.offset + member.offset) = value.ui64;
+                                    *(uint64 *)((byte *)*object + offset) = value.ui64;
                                  }
                                  else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
                                     !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
                                  {
-                                    *(int *)((byte *)*object + member._class.offset + member.offset) = value.i;
+                                    *(int *)((byte *)*object + offset) = value.i;
                                  }
                                  else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
                                     !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
                                     !strcmp(type.dataTypeString, "int16"))
                                  {
-                                    *(short *)((byte *)*object + member._class.offset + member.offset) = value.s;
+                                    *(short *)((byte *)*object + offset) = value.s;
                                  }
                                  else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
                                     !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
                                  {
-                                    *(char *)((byte *)*object + member._class.offset + member.offset) = value.c;
+                                    *(char *)((byte *)*object + offset) = value.c;
                                  }
                                  else
                                  {
-                                    *(void **)((byte *)*object + member._class.offset + member.offset) = value.p;
+                                    *(void **)((byte *)*object + offset) = value.p;
                                  }
                               }
                               else if(prop && prop.Set)
@@ -1021,38 +1024,41 @@ static bool _WriteJSONObject(File f, Class objectType, void * object, int indent
                {
                   DataMember member = (DataMember)prop;
                   DataValue value { };
+                  uint offset;
                   Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
                   if(!type)
                      type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
 
+                  offset = member._class.offset + member.offset;
+
                   if(type)
                   {
                      if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || !strcmp(type.name, "String"))
                      {
                         if(type.type == structClass)
-                           value.p = (void *)((byte *)object + member._class.offset + member.offset);
+                           value.p = (void *)((byte *)object + offset);
                         else
-                           value.p = *(void **)((byte *)object + member._class.offset + member.offset);
+                           value.p = *(void **)((byte *)object + offset);
                         if(!value.p)
                            continue;
                      }
                      else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
                      {
-                        value.d = *(double *)((byte *)object + member._class.offset + member.offset);
+                        value.d = *(double *)((byte *)object + offset);
                      }
                      else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
                      {
-                        value.f = *(float *)((byte *)object + member._class.offset + member.offset);
+                        value.f = *(float *)((byte *)object + offset);
                      }
                      else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
                         !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
                      {
-                        value.ui64 = *(uint64 *)((byte *)object + member._class.offset + member.offset);
+                        value.ui64 = *(uint64 *)((byte *)object + offset);
                      }
                      else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
                         !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
                      {
-                        value.i = *(int *)((byte *)object + member._class.offset + member.offset);
+                        value.i = *(int *)((byte *)object + offset);
                         if(!strcmp(type.name, "bool") || type.type == enumClass)
                            if(!value.i)
                               continue;
@@ -1061,16 +1067,16 @@ static bool _WriteJSONObject(File f, Class objectType, void * object, int indent
                         !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
                         !strcmp(type.dataTypeString, "int16"))
                      {
-                        value.s = *(short *)((byte *)object + member._class.offset + member.offset);
+                        value.s = *(short *)((byte *)object + offset);
                      }
                      else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
                         !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
                      {
-                        value.c = *(char *)((byte *)object + member._class.offset + member.offset);
+                        value.c = *(char *)((byte *)object + offset);
                      }
                      else
                      {
-                        value.i = *(int *)((byte *)object + member._class.offset + member.offset);
+                        value.i = *(int *)((byte *)object + offset);
                      }
 
                      if(!isFirst) f.Puts(",\n");
index 2734c34..6b29f2a 100644 (file)
@@ -339,7 +339,7 @@ class SQLiteDatabase : Database
                      Class type = null;
                      int sqliteType = SQLITE_BLOB;
 
-                     ((Class)(&type)).OnGetDataFromString(typeName);    // TODO: THIS REQUIRES A FIX SOMEWHERE ELSE
+                     type.OnGetDataFromString(typeName);
 
                      if(type)
                      {