DaoClass* DaoClass_New() { DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) ); DaoValue_Init( self, DAO_CLASS ); self->trait |= DAO_VALUE_DELAYGC; self->className = DString_New(1); self->lookupTable = DHash_New(D_STRING,0); self->ovldRoutMap = DHash_New(D_STRING,0); self->abstypes = DMap_New(D_STRING,D_VALUE); self->constants = DArray_New(D_VALUE); self->variables = DArray_New(D_VALUE); self->instvars = DArray_New(D_VALUE); self->objDataName = DArray_New(D_STRING); self->cstDataName = DArray_New(D_STRING); self->glbDataName = DArray_New(D_STRING); self->parent = NULL; self->mixinBases = DArray_New(0); /* refcount handled in ::allBases; */ self->allBases = DArray_New(D_VALUE); self->mixins = DArray_New(0); self->ranges = DVector_New(sizeof(ushort_t)); self->offsets = DVector_New(sizeof(ushort_t)); self->references = DArray_New(D_VALUE); self->inter = NULL; self->cstMixinStart = self->cstMixinEnd = self->cstMixinEnd2 = 0; self->glbMixinStart = self->glbMixinEnd = self->glbMixinEnd2 = 0; self->objMixinStart = self->objMixinEnd = self->objMixinEnd2 = 0; self->cstParentStart = self->cstParentEnd = 0; self->glbParentStart = self->glbParentEnd = 0; return self; }
int DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds ) { DNode *it; DMap *newbinds = NULL; DList *methods; void *pvoid[2]; daoint i, n, bl; /* XXX locking */ if( type->interfaces == NULL ) type->interfaces = DHash_New( DAO_DATA_VALUE, 0 ); pvoid[0] = type; pvoid[1] = self->abtype; if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pVoid != NULL; if( binds && DMap_Find( binds, pvoid ) ) return 1; if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 ); DaoInterface_TempBind( self, type, binds ); methods = DList_New(0); DMap_SortMethods( self->methods, methods ); bl = DaoInterface_CheckBind( methods, type, binds ); DList_Delete( methods ); if( newbinds ) DMap_Delete( newbinds ); DMap_Insert( type->interfaces, self, bl ? self : NULL ); if( bl == 0 ) return 0; for(i=0,n=self->supers->size; i<n; i++){ DaoInterface *super = (DaoInterface*) self->supers->items.pValue[i]; if( DMap_Find( type->interfaces, super ) ) continue; DMap_Insert( type->interfaces, super, super ); } return 1; }
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms ) { DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}}; DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) ); DMutex_Init( & self->mutex ); DCondVar_Init( & self->condv ); DCondVar_Init( & self->condv2 ); DThread_Init( & self->timer ); self->finishing = 0; self->timing = 0; self->total = 0; self->idle = 0; self->stopped = 0; self->threads = DArray_New(0); self->functions = DArray_New(0); self->parameters = DArray_New(0); self->events = DArray_New(0); self->events2 = DArray_New(0); self->waitings = DMap_New(D_VALUE,0); self->pending = DHash_New(0,0); self->active = DHash_New(0,0); self->caches = DArray_New(0); self->vmspace = vms; self->timestamp = com; return self; }
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms ) { DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) ); DMutex_Init( & self->mutex ); DCondVar_Init( & self->condv ); DCondVar_Init( & self->condv2 ); DThread_Init( & self->timer ); self->finishing = 0; self->timing = 0; self->total = 0; self->vacant = 0; self->idle = 0; self->stopped = 0; self->threads = DList_New(0); self->functions = DList_New(0); self->parameters = DList_New(0); self->owners = DList_New(0); self->events = DList_New(0); self->events2 = DList_New(0); self->waitings = DMap_New( DAO_DATA_COMPLEX, 0 ); self->pending = DHash_New(0,0); self->active = DHash_New(0,0); self->caches = DList_New(0); self->vmspace = vms; self->timestamp.real = 0.0; self->timestamp.imag = 0.0; return self; }
DaoxProfiler* DaoxProfiler_New() { DaoxProfiler *self = (DaoxProfiler*) dao_calloc(1,sizeof(DaoxProfiler)); self->profile = DHash_New( 0, DAO_DATA_MAP ); self->one = DHash_New( 0, DAO_DATA_VALUE ); self->base.EnterFrame = DaoProfiler_EnterFrame; self->base.LeaveFrame = DaoProfiler_LeaveFrame; self->base.Report = DaoProfiler_Report; self->base.Reset = DaoProfiler_Reset; DMutex_Init( & self->mutex ); return self; }
static void DaoMT_Critical( DaoProcess *proc, DaoValue *p[], int n ) { void *key; DNode *it; DMap *cache = (DMap*) DaoProcess_GetAuxData( proc, DaoMT_ProcMutexCache ); DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 ); DaoRoutine *routine = proc->activeRoutine; if( sect == NULL ) return; /* Get the original routine, if this one is a specialized copy: */ while( routine->original ) routine = routine->original; /* // Use "routine + sect->c" instead of "sect" as the key for mutex, // as "sect" may be different for different copy of specialized routine. // But "sect->c" won't change after being set during compiling. */ key = routine + sect->c; if( cache == NULL ){ cache = DHash_New(0,0); /* Local cache is used to avoid extra locking; */ DaoProcess_SetAuxData( proc, DaoMT_ProcMutexCache, cache ); } it = DMap_Find( cache, key ); /* Check local cache first; */ if( it == NULL ) it = DMap_Insert( cache, key, DaoMT_GetMutex( routine, key ) ); DMutex_Lock( (DMutex*) it->value.pVoid ); DaoProcess_Execute( proc ); DMutex_Unlock( (DMutex*) it->value.pVoid ); DaoProcess_PopFrame( proc ); }
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target ) { DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) ); DaoValue_Init( self, DAO_CINTYPE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->supers = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->citype = DaoType_New( "interface<", DAO_CINTYPE, (DaoValue*)self, NULL ); self->vatype = DaoType_New( inter->abtype->name->chars, DAO_CINVALUE, (DaoValue*)self, NULL ); self->abstract = inter; self->target = target; GC_IncRC( self->citype ); GC_IncRC( self->vatype ); GC_IncRC( self->abstract ); GC_IncRC( self->target ); self->citype->nested = DList_New( DAO_DATA_VALUE ); self->vatype->nested = DList_New( DAO_DATA_VALUE ); DList_Append( self->citype->nested, target ); DList_Append( self->vatype->nested, target ); DString_AppendChar( self->vatype->name, '<' ); DString_Append( self->vatype->name, target->name ); DString_AppendChar( self->vatype->name, '>' ); DString_Append( self->citype->name, self->vatype->name ); DString_AppendChar( self->citype->name, '>' ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
static void DaoIO_Writeln0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *params[DAO_MAX_PARAM]; DMap *cycmap = NULL; int i; if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return; for(i=0; i<N; i++){ if( p[i]->type > DAO_ARRAY ){ cycmap = DHash_New(0,0); break; } } /* // DaoValue_Print() may call user defined function and change the stack // and invalidate the parameter array: */ memmove( params, p, N*sizeof(DaoValue*) ); for(i=0; i<N; i++){ if( params[i]->type > DAO_ARRAY ) DMap_Reset( cycmap ); DaoValue_Print( params[i], self, cycmap, proc ); if( i+1<N ) DaoStream_WriteChars( self, " "); } DaoStream_WriteChars( self, "\n"); if( cycmap ) DMap_Delete( cycmap ); }
static DMap* DaoProcess_GetTimeMap( DaoProcess *self ) { DMap *mapTime = (DMap*) DaoProcess_GetAuxData( self, DMap_DeleteTimeMap ); if( mapTime ) return mapTime; mapTime = DHash_New( 0, DAO_DATA_VALUE ); DaoProcess_SetAuxData( self, DMap_DeleteTimeMap, mapTime ); return mapTime; }
DaoXmlNode* DaoXmlNode_New() { DaoXmlNode *self = (DaoXmlNode*) dao_calloc( 1, sizeof(DaoXmlNode) ); self->parent = NULL; self->children = DList_New(0); self->name = DString_New(); self->content = DString_New(); self->attributes = DHash_New( DAO_DATA_STRING, DAO_DATA_STRING ); return self; }
void DaoxDataFrame_AddLabelGroup( DaoxDataFrame *self, int dim ) { if( dim >=0 && dim < 3 ){ DMap *labmap = DHash_New(D_STRING,0); DArray *labels = self->labels[dim]; self->groups[dim] = labels->size; DArray_Append( labels, labmap ); DMap_Delete( labmap ); } }
void DaoClass_MakeInterface( DaoClass *self ) { daoint i, j; DaoType *tp; DaoRoutine *meth; DaoInterface *inter = self->inter; DMap *deftypes = DHash_New(0,0); DArray_Clear( self->inter->supers ); DMap_Clear( self->inter->methods ); if( self->parent && self->parent->type == DAO_CLASS ) DArray_Append( inter->supers, self->parent->xClass.inter ); for(i=0; i<self->cstDataName->size; ++i){ DString *name = self->cstDataName->items.pString[i]; DaoValue *value = self->constants->items.pConst[i]->value; DaoRoutine *rout = (DaoRoutine*) value; DNode *it; if( value->type != DAO_ROUTINE ) continue; if( value->xRoutine.attribs & DAO_ROUT_DECORATOR ) continue; it = MAP_Find( self->lookupTable, rout->routName ); if( it == NULL || LOOKUP_PM( it->value.pInt ) != DAO_DATA_PUBLIC ) continue; DMap_Reset( deftypes ); DMap_Insert( deftypes, rout->routHost, inter->abtype ); if( rout->overloads == NULL ){ tp = DaoType_DefineTypes( rout->routType, rout->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout->nameSpace, inter->abtype, 0 ); meth->attribs = rout->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); }else{ for(j=0; j<rout->overloads->routines->size; ++j){ DaoRoutine *rout2 = rout->overloads->routines->items.pRoutine[j]; if( rout2->attribs & DAO_ROUT_DECORATOR ) continue; tp = DaoType_DefineTypes( rout2->routType, rout2->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout2->nameSpace, inter->abtype, 0 ); meth->attribs = rout2->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); } } } DMap_Delete( deftypes ); }
int DaoValue_CompareExt( DaoValue *left, DaoValue *right, DMap *cycmap ) { DMap *input = cycmap; void *pters[2]; int res = 0; if( left == right ) return 0; if( left == NULL || right == NULL ) return left < right ? -100 : 100; if( left->type != right->type ){ double L, R; res = left->type < right->type ? -100 : 100; if( left->type < DAO_BOOLEAN || left->type > DAO_FLOAT ) return res; if( right->type < DAO_BOOLEAN || right->type > DAO_FLOAT ) return res; L = DaoValue_GetFloat( left ); R = DaoValue_GetFloat( right ); return L == R ? 0 : (L < R ? -1 : 1); } switch( left->type ){ case DAO_TUPLE : case DAO_LIST : case DAO_OBJECT : case DAO_CDATA : case DAO_CSTRUCT : pters[0] = left; pters[1] = right; if( cycmap != NULL ){ DNode *it = DMap_Find( cycmap, pters ); if( it != NULL ) return left < right ? -100 : 100; } if( cycmap == NULL ) cycmap = DHash_New(DAO_DATA_VOID2,0); DMap_Insert( cycmap, pters, NULL ); break; } switch( left->type ){ case DAO_NONE : break; case DAO_BOOLEAN : res = number_compare( left->xBoolean.value, right->xBoolean.value ); break; case DAO_INTEGER : res = number_compare( left->xInteger.value, right->xInteger.value ); break; case DAO_FLOAT : res = number_compare( left->xFloat.value, right->xFloat.value ); break; case DAO_COMPLEX : res = DaoComplex_Compare( (DaoComplex*) left, (DaoComplex*) right ); break; case DAO_STRING : res = DString_CompareUTF8( left->xString.value, right->xString.value ); break; case DAO_ENUM : res = DaoEnum_Compare( (DaoEnum*) left, (DaoEnum*) right ); break; case DAO_TUPLE : res = DaoTuple_Compare( (DaoTuple*) left, (DaoTuple*) right, cycmap ); break; case DAO_LIST : res = DaoList_Compare( (DaoList*) left, (DaoList*) right, cycmap ); break; case DAO_OBJECT : res = DaoObject_Compare( (DaoObject*)left, (DaoObject*)right, cycmap ); break; case DAO_CDATA : case DAO_CSTRUCT : res = DaoCstruct_Compare( (DaoCstruct*)left, (DaoCstruct*)right, cycmap ); break; case DAO_TYPE : res = DaoType_Compare( (DaoType*) left, (DaoType*) right ); break; #ifdef DAO_WITH_NUMARRAY case DAO_ARRAY : res = DaoArray_Compare( (DaoArray*) left, (DaoArray*) right ); break; #endif default: res = left < right ? -100 : 100; break; /* Needed for map; */ } if( cycmap != input ) DMap_Delete( cycmap ); return res; }
DaoxResource* DaoxResource_New( DaoVmSpace *vms ) { DaoxResource *self = (DaoxResource*) dao_calloc( 1, sizeof(DaoxResource) ); DaoCstruct_Init( (DaoCstruct*) self, daox_type_resource ); self->scenes = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->lights = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->cameras = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->images = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->textures = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->effects = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->materials = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->geometries = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->terrains = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->vmSpace = vms; return self; }
DaoClass* DaoClass_New() { DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) ); DaoValue_Init( self, DAO_CLASS ); self->trait |= DAO_VALUE_DELAYGC; self->className = DString_New(1); self->lookupTable = DHash_New(D_STRING,0); self->ovldRoutMap = DHash_New(D_STRING,0); self->abstypes = DMap_New(D_STRING,D_VALUE); self->constants = DArray_New(D_VALUE); self->variables = DArray_New(D_VALUE); self->instvars = DArray_New(D_VALUE); self->objDataName = DArray_New(D_STRING); self->cstDataName = DArray_New(D_STRING); self->glbDataName = DArray_New(D_STRING); self->superClass = DArray_New(D_VALUE); self->references = DArray_New(D_VALUE); return self; }
static void DaoClass_AddConst3( DaoClass *self, DString *name, DaoValue *data ) { DaoConstant *cst = DaoConstant_New( data ); DArray_Append( self->cstDataName, (void*)name ); DArray_Append( self->constants, cst ); DaoValue_MarkConst( cst->value ); if( data->type == DAO_ROUTINE && data->xRoutine.routHost != self->objType ){ if( data->xRoutine.attribs & DAO_ROUT_VIRTUAL ){ /* data->xRoutine.overloads == NULL */ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); MAP_Insert( self->vtable, data, data ); } } }
DaoRoutine* DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds ) { DNode *it; DMap *newbinds = NULL; DList *methods; DaoRoutine *incompatible; void *pvoid[2]; daoint i, n; if( self->abtype->kernel->SetupMethods ){ DaoTypeKernel *kernel = self->abtype->kernel; kernel->SetupMethods( kernel->nspace, self->abtype->core ); } /* XXX locking */ if( type->interfaces == NULL ){ type->interfaces = DHash_New( DAO_DATA_VALUE, DAO_DATA_VALUE ); } pvoid[0] = type; pvoid[1] = self->abtype; if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pRoutine; if( binds && DMap_Find( binds, pvoid ) ) return NULL; if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 ); DaoInterface_TempBind( self, type, binds ); methods = DList_New(0); DMap_SortMethods( self->methods, methods ); incompatible = DaoInterface_CheckBind( methods, type, binds ); DList_Delete( methods ); if( newbinds ) DMap_Delete( newbinds ); DMap_Insert( type->interfaces, self, incompatible ); if( incompatible ) return incompatible; for(i=0,n=self->bases->size; i<n; i++){ DaoInterface *base = (DaoInterface*) self->bases->items.pValue[i]; if( DMap_Find( type->interfaces, base ) ) continue; DMap_Insert( type->interfaces, base, NULL ); } return NULL; }
DaoInterface* DaoInterface_New( const char *name ) { DaoInterface *self = (DaoInterface*) dao_calloc( 1, sizeof(DaoInterface) ); DaoValue_Init( self, DAO_INTERFACE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->supers = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->abtype = DaoType_New( name, DAO_INTERFACE, (DaoValue*)self, NULL ); GC_IncRC( self->abtype ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
static void DaoIO_Write0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DMap *cycmap = NULL; int i; for(i=0; i<N; i++){ if( p[i]->type > DAO_ARRAY ){ cycmap = DHash_New(0,0); break; } } for(i=0; i<N; i++){ if( p[i]->type > DAO_ARRAY ) DMap_Reset( cycmap ); DaoValue_Print( p[i], self, cycmap, proc ); } if( cycmap ) DMap_Delete( cycmap ); }
void DaoObject_Print( DaoValue *self, DaoStream *stream, DMap *cycmap, DaoProcess *proc ) { int ec = 0; char buf[50]; DMap *inmap = cycmap; DaoObject *object = (DaoObject*) self; DaoValue *params[2]; DaoRoutine *meth; sprintf( buf, "[%p]", object ); if( self == object->defClass->objType->value ){ DaoStream_WriteString( stream, object->defClass->className ); DaoStream_WriteChars( stream, "[null]" ); return; } if( cycmap != NULL && DMap_Find( cycmap, object ) != NULL ){ DaoStream_WriteString( stream, object->defClass->className ); DaoStream_WriteChars( stream, buf ); return; } if( cycmap == NULL ) cycmap = DHash_New(0,0); DMap_Insert( cycmap, self, self ); DaoValue_Clear( & proc->stackValues[0] ); params[0] = (DaoValue*) dao_type_string; params[1] = (DaoValue*) stream; meth = DaoClass_FindMethod( object->defClass, "(string)", NULL ); if( meth ){ ec = DaoProcess_Call( proc, meth, self, params, 2 ); if( ec ) ec = DaoProcess_Call( proc, meth, self, params, 1 ); }else{ meth = DaoClass_FindMethod( object->defClass, "serialize", NULL ); if( meth ) ec = DaoProcess_Call( proc, meth, self, NULL, 0 ); } if( ec ){ DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL ); }else if( meth && proc->stackValues[0] ){ DaoValue_Print( proc->stackValues[0], stream, cycmap, proc ); }else{ DaoStream_WriteString( stream, object->defClass->className ); DaoStream_WriteChars( stream, buf ); } if( inmap == NULL ) DMap_Delete( cycmap ); }
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target ) { DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) ); DaoNamespace *ns = inter->nameSpace; DString *name = inter->abtype->name; DaoValue_Init( self, DAO_CINTYPE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->bases = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->citype = DaoType_New( ns, "interface<", DAO_CINTYPE, (DaoValue*)self, NULL ); self->vatype = DaoType_New( ns, name->chars, DAO_CINVALUE, (DaoValue*)self, NULL ); self->abstract = inter; self->target = target; self->citype->core = & daoCinTypeCore; self->vatype->core = & daoCinValueCore; GC_IncRC( self->citype ); GC_IncRC( self->vatype ); GC_IncRC( self->abstract ); GC_IncRC( self->target ); self->vatype->kernel = DaoTypeKernel_New( NULL ); self->vatype->kernel->abtype = self->vatype; GC_IncRC( self->vatype->kernel ); GC_IncRC( self->vatype ); self->citype->args = DList_New( DAO_DATA_VALUE ); self->vatype->args = DList_New( DAO_DATA_VALUE ); DList_Append( self->citype->args, target ); DList_Append( self->vatype->args, target ); DString_AppendChar( self->vatype->name, '<' ); DString_Append( self->vatype->name, target->name ); DString_AppendChar( self->vatype->name, '>' ); DString_Append( self->citype->name, self->vatype->name ); DString_AppendChar( self->citype->name, '>' ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
static void DaoCinValue_Print( DaoValue *self, DaoStream *stream, DMap *cycmap, DaoProcess *proc ) { int ec = 0; char buf[50]; DaoRoutine *meth; DaoValue *args[2]; DaoType *type = self->xCinValue.cintype->vatype; DMap *inmap = cycmap; if( cycmap != NULL && DMap_Find( cycmap, self ) != NULL ){ sprintf( buf, "[%p]", self ); DaoStream_WriteString( stream, type->name ); DaoStream_WriteChars( stream, buf ); return; } if( cycmap == NULL ) cycmap = DHash_New(0,0); DMap_Insert( cycmap, self, self ); args[0] = (DaoValue*) proc->vmSpace->typeString; args[1] = (DaoValue*) stream; meth = DaoType_FindFunctionChars( type, "(string)" ); if( meth ){ ec = DaoProcess_Call( proc, meth, self, args, 2 ); if( ec ) ec = DaoProcess_Call( proc, meth, self, args, 1 ); }else{ meth = DaoType_FindFunctionChars( type, "serialize" ); if( meth ) ec = DaoProcess_Call( proc, meth, self, NULL, 0 ); } if( meth == NULL ){ DaoValue_Print( self->xCinValue.value, stream, cycmap, proc ); }else if( ec ){ DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL ); }else if( meth && proc->stackValues[0] ){ DaoValue_Print( proc->stackValues[0], stream, cycmap, proc ); }else{ DaoStream_WriteString( stream, type->name ); DaoStream_WriteChars( stream, buf ); } if( inmap == NULL ) DMap_Delete( cycmap ); }
static DMutex* DaoMT_GetMutex( DaoRoutine *routine, void *key ) { DNode *it; DMap *mutexes; DMutex *mutex = NULL; DMutex_Lock( & mainVmSpace->miscMutex ); it = DMap_Find( routine->body->aux, DaoMT_RoutMutexSet ); if( it == NULL ) it = DMap_Insert( routine->body->aux, DaoMT_RoutMutexSet, DHash_New(0,0) ); mutexes = (DMap*) it->value.pVoid; it = DMap_Find( mutexes, key ); if( it == NULL ){ mutex = (DMutex*) dao_calloc(1,sizeof(DMutex)); DMutex_Init( mutex ); DMap_Insert( mutexes, key, mutex ); }else{ mutex = (DMutex*) it->value.pVoid; } DMutex_Unlock( & mainVmSpace->miscMutex ); return mutex; }
DaoXmlParser* DaoXmlParser_New() { DaoXmlParser *self = (DaoXmlParser*) dao_calloc( 1, sizeof(DaoXmlParser) ); self->key = DString_New(); self->value = DString_New(); self->escape = DString_New(); self->escapes = DHash_New( DAO_DATA_STRING, DAO_DATA_STRING ); DString_SetChars( self->key, "lt" ); DString_SetChars( self->value, "<" ); DMap_Insert( self->escapes, self->key, self->value ); DString_SetChars( self->key, "gt" ); DString_SetChars( self->value, ">" ); DMap_Insert( self->escapes, self->key, self->value ); DString_SetChars( self->key, "amp" ); DString_SetChars( self->value, "&" ); DMap_Insert( self->escapes, self->key, self->value ); DString_SetChars( self->key, "apos" ); DString_SetChars( self->value, "'" ); DMap_Insert( self->escapes, self->key, self->value ); DString_SetChars( self->key, "quot" ); DString_SetChars( self->value, "\"" ); DMap_Insert( self->escapes, self->key, self->value ); return self; }
/* // C printf format: %[parameter][flags][width][.precision][length]type // // Dao writef format: %[flags][width][.precision]type[color] // // Where 'flags', 'width' and 'precision' will conform to the C format, // but 'type' can only be: // d, i, o, u, x/X : for integer; // e/E, f/F, g/G : for float and double; // c/C : for character, C for local encoding; // s/S : for string, S for local encoding; // p : for any type, write address; // a : automatic, for any type, write in the default format; // Namely the standard ones except 'n', and plus 'a'. // // Optional 'color' format will be in form of: [foreground:background], [foreground] // or [:background]. The supported color name format will depend on the color printing // handle. Mininum requirement is the support of the following 8 color names: // black, white, red, green, blue, yellow, magenta, cyan. */ static void DaoIO_Writef0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *value; DString *fmt2; DString *fgcolor = NULL; DString *bgcolor = NULL; DMap *cycmap = NULL; const char *convs = "asSpcCdiouxXfFeEgG"; char F, *s, *end, *fg, *bg, *fmt, message[100]; int i, k, id = 0; if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return; fmt2 = DString_New(); for(i=0; i<N; i++){ if( p[i]->type > DAO_ARRAY ){ cycmap = DHash_New(0,0); break; } } s = p[0]->xString.value->chars; end = s + p[0]->xString.value->size; for(; s<end; s++){ if( *s != '%' ){ DaoStream_WriteChar( self, *s ); continue; } fmt = s; s += 1; if( *s =='%' || *s == '[' ){ DaoStream_WriteChar( self, *s ); continue; } if( ++id >= N || p[id] == NULL ) goto NullParameter; value = p[id]; /* flags: */ while( *s == '+' || *s == '-' || *s == '#' || *s == '0' || *s == ' ' ) s += 1; while( isdigit( *s ) ) s += 1; /* width; */ if( *s == '.' ){ /* precision: */ s += 1; while( isdigit( *s ) ) s += 1; } DString_SetBytes( fmt2, fmt, s - fmt + 1 ); if( strchr( convs, *s ) == NULL ){ DaoProcess_RaiseWarning( proc, NULL, "invalid format conversion" ); continue; } F = *s; s += 1; fg = bg = NULL; if( *s == '[' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; if( fgcolor == NULL ) fgcolor = DString_New(); DString_SetBytes( fgcolor, fmt, s - fmt ); if( fgcolor->size ) fg = fgcolor->chars; if( *s == ':' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; if( bgcolor == NULL ) bgcolor = DString_New(); DString_SetBytes( bgcolor, fmt, s - fmt ); if( bgcolor->size ) bg = bgcolor->chars; } if( *s != ']' ) goto WrongColor; }else{ s -= 1; } if( fg || bg ){ if( DaoStream_SetColor( self, fg, bg ) == 0 ) goto WrongColor; } self->format = fmt2->chars; if( F == 'c' || F == 'C' ){ if( value->type != DAO_INTEGER ) goto WrongParameter; DString_Reset( fmt2, 0 ); DString_AppendWChar( fmt2, value->xInteger.value ); self->format = "%s"; if( F == 'C' ) DString_ToLocal( fmt2 ); DaoStream_WriteString( self, fmt2 ); }else if( F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){ if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter; DString_InsertChars( fmt2, "ll", fmt2->size-1, 0, 2 ); self->format = fmt2->chars; DaoStream_WriteInt( self, DaoValue_GetInteger( value ) ); }else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){ if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter; DaoStream_WriteFloat( self, DaoValue_GetFloat( value ) ); }else if( F == 's' && value->type == DAO_STRING ){ DaoStream_WriteString( self, value->xString.value ); }else if( F == 'S' && value->type == DAO_STRING ){ DaoStream_WriteLocalString( self, value->xString.value ); }else if( F == 'p' ){ DaoStream_WritePointer( self, value ); }else if( F == 'a' ){ self->format = NULL; if( value->type > DAO_ARRAY ) DMap_Reset( cycmap ); DaoValue_Print( value, self, cycmap, proc ); }else{ goto WrongParameter; } self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); continue; NullParameter: sprintf( message, "%i-th parameter is null!", id ); DaoProcess_RaiseWarning( proc, NULL, message ); continue; WrongColor: sprintf( message, "%i-th parameter has wrong color format!", id ); DaoProcess_RaiseWarning( proc, NULL, message ); continue; WrongParameter: self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", id, fmt2->chars ); DaoProcess_RaiseWarning( proc, NULL, message ); } if( cycmap ) DMap_Delete( cycmap ); if( fgcolor ) DString_Delete( fgcolor ); if( bgcolor ) DString_Delete( bgcolor ); DString_Delete( fmt2 ); }
/* assumed to be called before parsing class body */ void DaoClass_DeriveClassData( DaoClass *self ) { DaoType *type; DaoValue *value; DArray *parents, *offsets; DString *mbs; DNode *it, *search; daoint i, k, id, perm, index; mbs = DString_New(1); if( self->clsType->bases == NULL ) self->clsType->bases = DArray_New(D_VALUE); if( self->objType->bases == NULL ) self->objType->bases = DArray_New(D_VALUE); DArray_Clear( self->clsType->bases ); DArray_Clear( self->objType->bases ); for(i=0; i<self->superClass->size; i++){ if( self->superClass->items.pValue[i]->type == DAO_CLASS ){ DaoValue *klass = self->superClass->items.pValue[i]; DArray_Append( self->clsType->bases, klass->xClass.clsType ); DArray_Append( self->objType->bases, klass->xClass.objType ); DString_Assign( mbs, klass->xClass.className ); DString_AppendChar( mbs, '#' ); DString_AppendInteger( mbs, i+1 ); DaoClass_AddConst( self, mbs, klass, DAO_DATA_PRIVATE ); }else if( self->superClass->items.pValue[i]->type == DAO_CTYPE ){ DaoCtype *cdata = (DaoCtype*) self->superClass->items.pValue[i]; DaoTypeKernel *kernel = cdata->ctype->kernel; DMap *values = kernel->values; DMap *methods = kernel->methods; DArray_Append( self->clsType->bases, cdata->ctype ); DArray_Append( self->objType->bases, cdata->cdtype ); if( values == NULL ){ DaoNamespace_SetupValues( kernel->nspace, kernel->typer ); values = kernel->values; } if( methods == NULL ){ DaoNamespace_SetupMethods( kernel->nspace, kernel->typer ); methods = kernel->methods; } DString_Assign( mbs, cdata->ctype->name ); // XXX DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE ); DString_AppendChar( mbs, '#' ); DString_AppendInteger( mbs, i+1 ); DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE ); } } parents = DArray_New(0); offsets = DArray_New(0); DaoClass_Parents( self, parents, offsets ); for(i=1; i<parents->size; i++){ DaoClass *klass = parents->items.pClass[i]; DaoCdata *cdata = parents->items.pCdata[i]; if( klass->type == DAO_CLASS ){ if( klass->vtable ){ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); for(it=DMap_First(klass->vtable); it; it=DMap_Next(klass->vtable,it)){ DMap_Insert( self->vtable, it->key.pVoid, it->value.pVoid ); } } /* For class data: */ for( id=0; id<klass->cstDataName->size; id++ ){ DString *name = klass->cstDataName->items.pString[id]; value = klass->constants->items.pConst[ id ]->value; search = MAP_Find( klass->lookupTable, name ); if( search == NULL ) continue; perm = LOOKUP_PM( search->value.pInt ); /* NO deriving private member: */ if( perm <= DAO_DATA_PRIVATE ) continue; if( value->type == DAO_ROUTINE ){ if( DString_EQ( value->xRoutine.routName, klass->className ) ) continue; } search = MAP_Find( self->lookupTable, name ); if( search == NULL && value->type == DAO_ROUTINE && value->xRoutine.overloads ){ /* To skip the private methods: */ DaoClass_AddConst( self, name, (DaoValue*)value, perm ); }else if( search == NULL ){ index = LOOKUP_BIND( DAO_CLASS_CONSTANT, perm, i+1, self->constants->size ); MAP_Insert( self->lookupTable, name, index ); DArray_Append( self->constants, klass->constants->items.pConst[id] ); DArray_Append( self->cstDataName, (void*)name ); if( value->type == DAO_ROUTINE && (value->xRoutine.attribs & DAO_ROUT_VIRTUAL) ){ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); MAP_Insert( self->vtable, value, value ); } }else if( value->type == DAO_ROUTINE && value->xRoutine.overloads ){ DRoutines *routs = value->xRoutine.overloads; for(k=0; k<routs->routines->size; k++){ DaoRoutine *rout = routs->routines->items.pRoutine[k]; /* skip methods not defined in this parent type */ if( rout->routHost != klass->objType ) continue; if( rout->attribs & DAO_ROUT_PRIVATE ) continue; DaoClass_AddConst( self, name, (DaoValue*)rout, perm ); } }else if( value->type == DAO_ROUTINE ){ /* skip methods not defined in this parent type */ if( value->xRoutine.routHost != klass->objType ) continue; if( value->xRoutine.attribs & DAO_ROUT_PRIVATE ) continue; DaoClass_AddConst( self, name, value, perm ); } } /* class global data */ for( id=0; id<klass->glbDataName->size; id ++ ){ DString *name = klass->glbDataName->items.pString[id]; DaoVariable *var = klass->variables->items.pVar[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 ); /* To overide data: */ if( search == NULL ){ index = LOOKUP_BIND( DAO_CLASS_VARIABLE, perm, i+1, self->variables->size ); MAP_Insert( self->lookupTable, name, index ); DArray_Append( self->variables, var ); DArray_Append( self->glbDataName, (void*)name ); } } }else if( cdata->type == DAO_CTYPE ){ DaoCtype *ctypeobj = (DaoCtype*) cdata; DaoTypeKernel *kernel = cdata->ctype->kernel; DaoTypeBase *typer = kernel->typer; DMap *values = kernel->values; DMap *methods = kernel->methods; DNode *it; int j; DaoCdataType_SpecializeMethods( cdata->ctype ); kernel = cdata->ctype->kernel; methods = kernel->methods; if( typer->numItems ){ for(j=0; typer->numItems[j].name!=NULL; j++){ DString name = DString_WrapMBS( typer->numItems[j].name ); it = DMap_Find( values, & name ); if( it && DMap_Find( self->lookupTable, & name ) == NULL ) DaoClass_AddConst( self, it->key.pString, it->value.pValue, DAO_DATA_PUBLIC ); } } for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){ DaoRoutine *func = it->value.pRoutine; DaoRoutine **funcs = & func; int k, count = 1; if( it->value.pValue->type == DAO_ROUTINE && it->value.pRoutine->overloads ){ DRoutines *routs = it->value.pRoutine->overloads; funcs = routs->routines->items.pRoutine; count = routs->routines->size; } for(k=0; k<count; k++){ DaoRoutine *func = funcs[k]; if( func->routHost != ctypeobj->cdtype ) continue; if( func->attribs & DAO_ROUT_INITOR ) continue; DaoClass_AddConst( self, it->key.pString, (DaoValue*)func, DAO_DATA_PUBLIC ); } } } } DArray_Delete( parents ); DArray_Delete( offsets ); DString_Delete( mbs ); }
/* // Note: reference count is handled for "value2"! // // Item of list/tuple etc. can be directly passed as parameter "value2", // to avoid creating unnecessary intermediate objects. */ static int DaoParser_Deserialize( DaoParser *self, int start, int end, DaoValue **value2, DArray *types, DaoNamespace *ns, DaoProcess *proc, DMap *omap ) { DaoToken **tokens = self->tokens->items.pToken; DaoType *it1 = NULL, *it2 = NULL, *type = NULL; DaoValue *value = *value2; DaoValue *tmp = NULL; DaoValue *tmp2 = NULL; DaoObject *object; DaoCdata *cdata; DaoArray *array; DaoTuple *tuple; DaoList *list; DaoMap *map; DArray *dims; DNode *node; void *key = NULL; char *str; int i, j, k, n; int minus = 0; int next = start + 1; int tok2 = start < end ? tokens[start+1]->type : 0; int maybetype = tok2 == DTOK_COLON2 || tok2 == DTOK_LT || tok2 == DTOK_LCB; if( tokens[start]->type == DTOK_AT && tok2 == DTOK_LCB ){ int rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( rb < 0 ) return next; sscanf( tokens[start+2]->string.mbs, "%p", & key ); node = DMap_Find( omap, key ); if( node ) DaoValue_Copy( node->value.pValue, value2 ); return rb + 1; } if( tokens[start]->name == DTOK_ID_SYMBOL ){ DString *mbs = DString_New(1); while( tokens[start]->name == DTOK_ID_SYMBOL ){ DString_Append( mbs, & tokens[start]->string ); start += 1; } type = DaoNamespace_MakeType( ns, mbs->mbs, DAO_ENUM, NULL, NULL, 0 ); DString_Delete( mbs ); if( type == NULL ) return start; if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; }else if( tokens[start]->type == DTOK_IDENTIFIER && maybetype ){ type = DaoParser_ParseType( self, start, end, & start, NULL ); if( type == NULL ) return next; if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; } if( type == NULL ){ type = types->items.pType[0]; if( type && type->tid >= DAO_ARRAY ){ if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; } } if( type == NULL ) return next; DaoValue_Copy( type->value, value2 ); if( start > end ) return next; if( tokens[start]->name == DTOK_SUB ){ minus = 1; start += 1; if( start > end ) return next; } if( type->nested && type->nested->size >0 ) it1 = type->nested->items.pType[0]; if( type->nested && type->nested->size >1 ) it2 = type->nested->items.pType[1]; if( tokens[start]->name == DTOK_LB ){ int rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, start, end ); if( rb < 0 ) return next; sscanf( tokens[start+1]->string.mbs, "%p", & key ); DMap_Insert( omap, key, *value2 ); start = rb + 1; } str = tokens[start]->string.mbs; #if 0 printf( "type: %s %s\n", type->name->mbs, str ); for(i=start; i<=end; i++) printf( "%s ", tokens[i]->string.mbs ); printf( "\n" ); #endif value = *value2; switch( type->tid ){ case DAO_NONE : break; case DAO_INTEGER : value->xInteger.value = DaoDecodeInteger( str ); if( minus ) value->xInteger.value = - value->xInteger.value; break; case DAO_FLOAT : value->xFloat.value = DaoDecodeDouble( str ); if( minus ) value->xFloat.value = - value->xFloat.value; break; case DAO_DOUBLE : value->xDouble.value = DaoDecodeDouble( str ); if( minus ) value->xDouble.value = - value->xDouble.value; break; case DAO_COMPLEX : value->xComplex.value.real = DaoDecodeDouble( str ); if( minus ) value->xComplex.value.real = - value->xComplex.value.real; if( start + 1 > end ) return start+1; minus = 0; if( tokens[start + 1]->name == DTOK_SUB ){ minus = 1; start += 1; if( start + 1 > end ) return start+1; } value->xComplex.value.imag = DaoDecodeDouble( tokens[start+1]->string.mbs ); if( minus ) value->xComplex.value.imag = - value->xComplex.value.imag; next = start + 2; break; #ifdef DAO_WITH_LONGINT case DAO_LONG : value->xLong.value->base = DaoDecodeInteger( str ); start += 1; if( tokens[start]->name == DTOK_ADD ){ value->xLong.value->sign = 1; start += 1; }else if( tokens[start]->name == DTOK_SUB ){ value->xLong.value->sign = -1; start += 1; } for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DLong_PushBack( value->xLong.value, DaoDecodeInteger( tokens[i]->string.mbs ) ); } break; #endif case DAO_STRING : n = tokens[start]->string.size - 1; for(i=1; i<n; i++){ char c1 = str[i]; char c2 = str[i+1]; if( c1 < 'A' || c1 > 'P' ) continue; DString_AppendChar( value->xString.data, (char)((c1-'A')*16 + (c2-'A')) ); i += 1; } if( str[0] == '\"' ) DString_ToWCS( value->xString.data ); break; case DAO_ENUM : value->xEnum.value = DaoDecodeInteger( str ); break; case DAO_ARRAY : #ifdef DAO_WITH_NUMARRAY if( tokens[start]->name != DTOK_LSB ) return next; k = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, start, end ); if( k < 0 ) return next; n = 1; for(i=start+1; i<k; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; n *= strtol( tokens[i]->string.mbs, 0, 0 ); } if( n < 0 ) return next; if( it1 == NULL || it1->tid == 0 || it1->tid > DAO_COMPLEX ) return next; array = & value->xArray; dims = DArray_New(0); for(i=start+1; i<k; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; j = strtol( tokens[i]->string.mbs, 0, 0 ); DArray_Append( dims, (size_t) j ); } n = dims->size; DaoArray_ResizeArray( array, dims->items.pInt, n ); DArray_PushFront( types, it1 ); DArray_Delete( dims ); n = 0; for(i=k+1; i<=end; i++){ j = i + 1; while( j <= end && tokens[j]->name != DTOK_COMMA ) j += 1; DaoParser_Deserialize( self, i, j-1, & tmp, types, ns, proc, omap ); switch( it1->tid ){ case DAO_INTEGER : array->data.i[n] = tmp->xInteger.value; break; case DAO_FLOAT : array->data.f[n] = tmp->xFloat.value; break; case DAO_DOUBLE : array->data.d[n] = tmp->xDouble.value; break; } i = j; n += 1; } DArray_PopFront( types ); #endif break; case DAO_LIST : list = & value->xList; DArray_PushFront( types, it1 ); n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DArray_Append( & list->items, NULL ); k = DaoParser_Deserialize( self, i, end, list->items.items.pValue + n, types, ns, proc, omap ); i = k - 1; n += 1; } DArray_PopFront( types ); break; case DAO_MAP : map = & value->xMap; n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DaoValue_Clear( & tmp ); DaoValue_Clear( & tmp2 ); DArray_PushFront( types, it1 ); i = DaoParser_Deserialize( self, i, end, &tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tokens[i]->name == DTOK_COMMA ) continue; if( map->items->size == 0 ){ if( tokens[i]->name == DTOK_COLON ){ DMap_Delete( map->items ); map->items = DHash_New( D_VALUE, D_VALUE ); } } if( tokens[i]->name == DTOK_COLON || tokens[i]->name == DTOK_FIELD ) i += 1; DArray_PushFront( types, it2 ); i = DaoParser_Deserialize( self, i, end, &tmp2, types, ns, proc, omap ); DArray_PopFront( types ); node = DMap_Insert( map->items, (void*) tmp, (void*) tmp2 ); i -= 1; n += 1; } break; case DAO_TUPLE : tuple = & value->xTuple; n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; it1 = NULL; if( type->nested && type->nested->size > n ){ it1 = type->nested->items.pType[n]; if( it1 && it1->tid == DAO_PAR_NAMED ) it1 = & it1->aux->xType; } DArray_PushFront( types, it1 ); i = DaoParser_Deserialize( self, i, end, tuple->items + n, types, ns, proc, omap ); DArray_PopFront( types ); i -= 1; n += 1; } break; case DAO_OBJECT : DArray_PushFront( types, NULL ); DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tmp == NULL ) break; object = DaoClass_MakeObject( & type->aux->xClass, tmp, proc ); if( object ) DaoValue_Copy( (DaoValue*) object, value2 ); break; case DAO_CDATA : case DAO_CSTRUCT : DArray_PushFront( types, NULL ); DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tmp == NULL ) break; cdata = DaoCdata_MakeObject( & type->aux->xCdata, tmp, proc ); if( cdata ) DaoValue_Copy( (DaoValue*) cdata, value2 ); break; } DaoValue_Clear( & tmp ); DaoValue_Clear( & tmp2 ); return next; }