/* assumed to be called after parsing class body */ void DaoClass_DeriveObjectData( DaoClass *self ) { DaoType *type; DaoValue *value; DArray *parents, *offsets; DString *mbs; DNode *search; daoint i, id, perm, index, offset = 0; self->objDefCount = self->objDataName->size; offset = self->objDataName->size; mbs = DString_New(1); parents = DArray_New(0); offsets = DArray_New(0); DaoClass_Parents( self, parents, offsets ); for( i=0; i<self->superClass->size; i++){ if( self->superClass->items.pValue[i]->type == DAO_CLASS ){ DaoClass *klass = self->superClass->items.pClass[i]; /* for properly arrangement object data: */ for( id=0; id<klass->objDataName->size; id ++ ){ DString *name = klass->objDataName->items.pString[id]; DaoVariable *var = klass->instvars->items.pVar[id]; var = DaoVariable_New( var->value, var->dtype ); DArray_Append( self->objDataName, name ); DArray_Append( self->instvars, var ); DaoValue_MarkConst( (DaoValue*) var->value ); } offset += klass->objDataName->size; } } for(i=1; i<parents->size; i++){ DaoClass *klass = parents->items.pClass[i]; offset = offsets->items.pInt[i]; /* plus self */ if( klass->type == DAO_CLASS ){ /* For object data: */ for( id=0; id<klass->objDataName->size; id ++ ){ DString *name = klass->objDataName->items.pString[id]; search = MAP_Find( klass->lookupTable, name ); perm = LOOKUP_PM( search->value.pInt ); /* NO deriving private member: */ if( perm <= DAO_DATA_PRIVATE ) continue; search = MAP_Find( self->lookupTable, name ); if( search == NULL ){ /* To not overide data and routine: */ index = LOOKUP_BIND( DAO_OBJECT_VARIABLE, perm, i, (offset+id) ); MAP_Insert( self->lookupTable, name, index ); } } } } self->derived = 1; DString_Delete( mbs ); DArray_Delete( parents ); DArray_Delete( offsets ); DaoObject_Init( & self->objType->value->xObject, NULL, 0 ); self->objType->value->xObject.trait &= ~DAO_VALUE_CONST; DaoValue_MarkConst( self->objType->value ); DaoValue_MarkConst( self->constants->items.pConst[1]->value ); /* ::default */ }
DaoObject* DaoObject_New( DaoClass *klass ) { DaoObject *self = DaoObject_Allocate( klass, klass->objDataName->size ); GC_IncRC( self ); self->rootObject = self; DaoObject_Init( self, NULL, 0 ); return self; }
void DaoObject_Init( DaoObject *self, DaoObject *that, int offset ) { DaoClass *klass = self->defClass; daoint i; if( that ){ GC_ShiftRC( that, self->rootObject ); self->rootObject = that; self->objValues = that->objValues + offset; }else if( self->rootObject == NULL ){ GC_ShiftRC( self, self->rootObject ); self->rootObject = self; if( self->isNull ){ /* no value space is allocated for null object yet! */ self->valueCount = klass->objDataName->size; self->objValues = (DaoValue**) dao_calloc( self->valueCount, sizeof(DaoValue*) ); } } offset += self->defClass->objDefCount; if( klass->parent != NULL && klass->parent->type == DAO_CLASS ){ DaoObject *sup = NULL; if( self->isNull ){ sup = & klass->parent->xClass.objType->value->xObject; }else{ sup = DaoObject_Allocate( (DaoClass*) klass->parent, 0 ); sup->isRoot = 0; DaoObject_Init( sup, self->rootObject, offset ); } GC_ShiftRC( sup, self->parent ); self->parent = (DaoValue*)sup; } GC_ShiftRC( self, self->objValues[0] ); self->objValues[0] = (DaoValue*) self; if( self->isRoot == 0 ) return; for(i=1; i<klass->instvars->size; i++){ DaoVariable *var = klass->instvars->items.pVar[i]; DaoValue **value = self->objValues + i; /* for data type such as list/map/array, * its .ctype may need to be set properaly */ if( var->value ){ DaoValue_Move( var->value, value, var->dtype ); continue; }else if( *value == NULL && var->dtype && var->dtype->value ){ DaoValue_Copy( var->dtype->value, value ); } } }