Ejemplo n.º 1
1
DaoxGlyph* DaoxFont_LoadGlyph( DaoxFont *self, size_t codepoint )
{
	DaoxGlyph *glyph = DaoxGlyph_New();
	stbtt_vertex *vertices = NULL;
	int id = stbtt_FindGlyphIndex( & self->info, codepoint );
	int i, num_verts = stbtt_GetGlyphShape( & self->info, id, & vertices );

	stbtt_GetGlyphHMetrics( & self->info, id, & glyph->advanceWidth, & glyph->leftSideBearing );

	DMap_Insert( self->glyphs, (void*) codepoint, glyph );
	DaoxPath_SetRelativeMode( glyph->shape, 0 );
	for(i=0; i<num_verts; ++i){
		stbtt_vertex_type x = vertices[i].x;
		stbtt_vertex_type y = vertices[i].y;
		stbtt_vertex_type cx = vertices[i].cx;
		stbtt_vertex_type cy = vertices[i].cy;
		switch( vertices[i].type ){
		case STBTT_vmove :
			if( i ) DaoxPath_Close( glyph->shape );
			DaoxPath_MoveTo( glyph->shape, x, y );
			break;
		case STBTT_vline :
			DaoxPath_LineTo( glyph->shape, x, y );
			break;
		case STBTT_vcurve :
			DaoxPath_QuadTo( glyph->shape, cx, cy, x, y );
			break;
		}
	}
	if( i ) DaoxPath_Close( glyph->shape );
	stbtt_FreeShape( & self->info, vertices );

	return glyph;
}
Ejemplo n.º 2
0
static void DMap_SortMethods( DMap *hash, DList *methods )
{
	DMap *map = DMap_New( DAO_DATA_STRING, 0 );
	DString *name = DString_New();
	DNode *it;
	daoint i, n;
	for(it=DMap_First(hash); it; it=DMap_Next(hash,it)){
		if( it->value.pRoutine->overloads ){
			DRoutines *one = it->value.pRoutine->overloads;
			for(i=0,n=one->routines->size; i<n; i++){
				DaoRoutine *rout = one->routines->items.pRoutine[i];
				DString_Assign( name, rout->routName );
				DString_AppendChars( name, " " );
				DString_Append( name, rout->routType->name );
				DMap_Insert( map, name, (void*)rout );
			}
		}else{
			DaoRoutine *rout = it->value.pRoutine;
			DString_Assign( name, rout->routName );
			DString_AppendChars( name, " " );
			DString_Append( name, rout->routType->name );
			DMap_Insert( map, name, (void*)rout );
		}
	}
	DList_Clear( methods );
	for(it=DMap_First(map); it; it=DMap_Next(map,it))
		DList_Append( methods, it->value.pVoid );
	DMap_Delete( map );
	DString_Delete( name );
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
void DaoCallServer_AddTimedWait( DaoProcess *wait, DaoTaskEvent *event, double timeout )
{
	DaoCallServer *server;
	if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace );
	server = daoCallServer;

	DMutex_Lock( & server->mutex );
	if( timeout >= 1E-27 ){
		server->timestamp.value.real = timeout + Dao_GetCurrentTime();
		server->timestamp.value.imag += 1;
		event->expiring = server->timestamp.value.real;
		DMap_Insert( server->waitings, & server->timestamp, event );
		DMap_Insert( server->pending, event, NULL );
		DCondVar_Signal( & server->condv2 );
	}else{
		event->expiring = -1.0;
		DaoCallServer_AddEvent( event );
		DCondVar_Signal( & server->condv );
	}
	if( wait->condv ){
		/*
		// Need to suspend the native thread, for suspending inside code sections
		// for functional methods such as std.iterate(), mt.iterate() etc:
		*/
		wait->pauseType = DAO_PAUSE_NATIVE_THREAD;
		if( timeout > 0 ){
			DCondVar_TimedWait( wait->condv, & server->mutex, timeout );
		}else{
			DCondVar_Wait( wait->condv, & server->mutex );
		}
		wait->status = DAO_PROCESS_RUNNING;
	}
	DMutex_Unlock( & server->mutex );
}
Ejemplo n.º 5
0
void DaoCallServer_AddTimedWait( DaoProcess *wait, DaoTaskEvent *event, double timeout )
{
	DaoCallServer *server = daoCallServer;

	/*
	// The "wait" process may not be running in the thread pool,
	// so it may have not been added to active process list.
	// It is necessary to add it to the active list now,
	// to avoid it being activated immediately after it is blocked.
	// Activating it immediately may cause a race condition,
	// because it may have not been blocked completely
	// (namely, it may be still running).
	*/
	DaoCallServer_MarkActiveProcess( wait, 1 );

	DMutex_Lock( & server->mutex );
	if( timeout >= 1E-27 ){
		server->timestamp.real = timeout + Dao_GetCurrentTime();
		server->timestamp.imag += 1;
		event->expiring = server->timestamp.real;
		DMap_Insert( server->waitings, & server->timestamp, event );
		DMap_Insert( server->pending, event, NULL );
		DCondVar_Signal( & server->condv2 );
	}else{
		event->expiring = -1.0;
		DaoCallServer_AddEvent( event );
		DCondVar_Signal( & server->condv );
	}
	DMutex_Unlock( & server->mutex );
}
Ejemplo n.º 6
0
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 );
}
Ejemplo n.º 7
0
int DaoXmlParser_ParseNode( DaoXmlParser *self, DaoXmlDOM *dom, DaoXmlNode *node )
{
	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	if( self->source >= self->end ) return 1;
	if( *self->source != '<' ) return 1;
	self->source += 1;

	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	if( DaoXmlParser_ParseIdentifier( self, node->name ) ) return 1;

	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	while( self->source < self->end && isalpha( *self->source ) ){
		DaoXmlParser_ParseAttribute( self, self->key, self->value );
		DMap_Insert( node->attributes, self->key, self->value );
		if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	}
	if( self->source >= self->end ) return 1;
	if( *self->source == '/' ){
		self->source += 1;
		if( self->source >= self->end ) return 1;
		if( *self->source != '>' ) return 1;
		self->source += 1;
		return 0;
	}
	if( *self->source != '>' ) return 1;
	self->source += 1;

	if( DaoXmlParser_ParseNodeContent( self, dom, node ) ) return 1;
	if( DaoXmlParser_ParseChar( self, '<' ) ) return 1;
	if( DaoXmlParser_ParseChar( self, '/' ) ) return 1;
	if( DaoXmlParser_ParseIdentifier( self, self->value ) ) return 1;
	if( DString_EQ( node->name, self->value ) == 0 ) return 1;
	if( DaoXmlParser_ParseChar( self, '>' ) ) return 1;
	return 0;
}
Ejemplo n.º 8
0
static DaoComplex* DaoProcess_GetTimeData( DaoProcess *self, DaoStackFrame *frame )
{
	DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}};
	DMap *mapTime = DaoProcess_GetTimeMap( self );
	DNode *it = DMap_Find( mapTime, frame );
	if( it == NULL ) it = DMap_Insert( mapTime, frame, & com );
	return (DaoComplex*) it->value.pValue;
}
Ejemplo n.º 9
0
void DaoxDataFrame_AddLabel( DaoxDataFrame *self, int dim, const char *lab, daoint idx )
{
	DString slab = DString_WrapMBS( lab );
	DMap *labmap = NULL;
	if( dim < 0 || dim >= 3 ) return;
	if( idx < 0 || idx >= self->dims[dim] ) return;
	if( self->groups[dim] >= self->labels[dim]->size ) return;
	labmap = self->labels[dim]->items.pMap[ self->groups[dim] ];
	if( labmap != NULL ) DMap_Insert( labmap, & slab, (void*)(size_t) idx );
}
Ejemplo n.º 10
0
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 );
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
static void DaoInterface_TempBind( DaoInterface *self, DaoType *type, DMap *binds )
{
	daoint i, N = self->supers->size;
	void *pvoid[2];
	pvoid[0] = type;
	pvoid[1] = self->abtype;
	if( DMap_Find( binds, pvoid ) ) return;
	DMap_Insert( binds, pvoid, NULL );
	for(i=0; i<N; i++){
		DaoInterface *super = (DaoInterface*) self->supers->items.pValue[i];
		DaoInterface_TempBind( super, type, binds );
	}
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
static void DaoxProfiler_Update( DaoxProfiler *self, DaoStackFrame *frame, double time )
{
	DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}};
	DaoRoutine *caller = frame->prev ? frame->prev->routine : NULL;
	DaoRoutine *callee = frame->routine;
	DNode *it, *it2;

	if( frame->returning == 0xffff ) caller = NULL;
	while( caller && caller->original ) caller = caller->original;
	while( callee && callee->original ) callee = callee->original;

	DMutex_Lock( & self->mutex );
	{
		it = DMap_Find( self->profile, callee );
		if( it == NULL ) it = DMap_Insert( self->profile, callee, self->one );

		it2 = DMap_Find( it->value.pMap, caller );
		if( it2 == NULL ) it2 = DMap_Insert( it->value.pMap, caller, & com );
		it2->value.pValue->xComplex.value.real += time;
		it2->value.pValue->xComplex.value.imag += 1;
	}
	DMutex_Unlock( & self->mutex );
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
void DaoProcess_MarkActiveTasklet( DaoProcess *self, int active )
{
	DaoTaskletServer *server = DaoTaskletServer_TryInit( self->vmSpace );

	if( self->active == active ) return;

	DMutex_Lock( & server->mutex );
	if( active ){
		DMap_Insert( server->active, self, NULL );
		self->active = 1;
	}else{
		DMap_Erase( server->active, self );
		self->active = 0;
	}
	DMutex_Unlock( & server->mutex );
}
Ejemplo n.º 18
0
void DaoCallServer_MarkActiveProcess( DaoProcess *process, int active )
{
	DaoCallServer *server = daoCallServer;

	if( daoCallServer == NULL ) return;
	if( process->active == active ) return;

	DMutex_Lock( & server->mutex );
	if( active ){
		DMap_Insert( server->active, process, NULL );
		process->active = 1;
	}else{
		DMap_Erase( server->active, process );
		process->active = 0;
	}
	DMutex_Unlock( & server->mutex );
}
Ejemplo n.º 19
0
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 );
}
Ejemplo n.º 20
0
void DaoCallServer_AddTask( DThreadTask func, void *param, int now )
{
	int scheduled = 0;
	DaoCallServer *server = DaoCallServer_TryInit( mainVmSpace );
	DMutex_Lock( & server->mutex );
	if( server->idle > server->parameters->size || now == 0 ){
		scheduled = 1;
		DList_Append( server->functions, func );
		DList_Append( server->parameters, param );
		DMap_Insert( server->pending, param, NULL );
		DCondVar_Signal( & server->condv );
	}
	DMutex_Unlock( & server->mutex );
	if( scheduled ){
		if( now == 0 ) DaoCallServer_TryAddThread( NULL, NULL, server->parameters->size );
	}else{
		DaoCallServer_AddThread( func, param );
	}
}
Ejemplo n.º 21
0
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 );
}
Ejemplo n.º 22
0
void DaoVmSpace_AddTaskletJob( DaoVmSpace *self, DThreadTask func, void *param, void *proc )
{
	int scheduled = 0;
	DaoTaskletServer *server = DaoTaskletServer_TryInit( self );
	DMutex_Lock( & server->mutex );
	if( server->vacant > server->parameters->size || proc == NULL ){
		scheduled = 1;
		DList_Append( server->functions, func );
		DList_Append( server->parameters, param );
		DList_Append( server->owners, proc );
		DMap_Insert( server->pending, param, NULL );
		DCondVar_Signal( & server->condv );
	}
	DMutex_Unlock( & server->mutex );
	if( scheduled ){
		if( proc == NULL ){
			DaoVmSpace_TryAddTaskletThread( self, NULL, NULL, server->parameters->size );
		}
	}else{
		DaoVmSpace_AddTaskletThread( self, func, param, proc );
	}
}
Ejemplo n.º 23
0
static void DaoClass_SetupMethodFields( DaoClass *self, DaoMethodFields *mf )
{
	DaoValue *cst;
	DMap *overloads = DMap_New(D_STRING,0);
	DNode *it, *search;
	daoint i, id, pm, pm2;

	for(i=0; i<mf->names->size; ++i){
		DString *name = mf->names->items.pString[i];
		it = DMap_Find( self->lookupTable, name );
		if( it == NULL ) continue;
		if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue;

		id = LOOKUP_ID( it->value.pInt );
		DMap_Insert( overloads, name, self->constants->items.pConst[id]->value );
	}

	for(i=0; i<mf->names->size; ++i){
		DString *name = mf->names->items.pString[i];
		it = DMap_Find( self->lookupTable, name );
		if( it == NULL ) continue;
		if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue;

		cst = mf->routines->items.pValue[i];
		search = DMap_Find( overloads, name );
		if( cst == search->value.pValue ) continue;

		pm = LOOKUP_PM( it->value.pInt );
		pm2 = mf->perms->items.pInt[i];
		if( pm2 > pm ) pm = pm2;
		/*
		// Add again the overloaded methods, so that a new overloading structure
		// will be created for the host class. This is necessary to avoid messing
		// the function calls in the methods of the mixins.
		*/
		DaoClass_AddConst( self, name, cst, pm );
	}
	DMap_Delete( overloads );
}
Ejemplo n.º 24
0
DaoxImage* DaoxResource_LoadImage( DaoxResource *self, DString *fname, DString *path )
{
	DaoxImage *image = NULL;
	DString *file = DString_Copy( fname );
	DString *source = DString_New();

	DString_Change( file, "\\\\", "/", 0 );
	DString_Change( file, "\\", "/", 0 );
	if( DaoxResource_SearchFile( self, file, path ) ){
		DNode *it = DMap_Find( self->images, file );
		if( it != NULL ){
			image = (DaoxImage*) it->value.pValue;
		}else if( DaoxResource_ReadFile( self, file, source ) ){
			image = DaoxImage_New();
			DaoxImage_Decode( image, source );
			DMap_Insert( self->images, file, image );
		}
	}
	DString_Delete( source );
	DString_Delete( file );
	return image;
}
Ejemplo n.º 25
0
static void DaoCallThread_Run( DaoCallThread *self )
{
	DaoCallServer *server = daoCallServer;
	double wt = 0.001;
	daoint i, count, timeout;

	self->thdData = DThread_GetSpecific();
	if( self->taskFunc ){
		self->taskFunc( self->taskParam );
		self->taskOwner = NULL;
	}
	while( server->vmspace->stopit == 0 ){
		DaoProcess *process = NULL;
		DaoFuture *future = NULL;
		DThreadTask function = NULL;
		void *parameter = NULL;

		if( self->thdData != NULL ) self->thdData->state = 0;
		DMutex_Lock( & server->mutex );
		server->idle += 1;
		server->vacant += self->taskOwner == NULL;
		while( server->pending->size == (server->events2->size + server->waitings->size) ){
			//printf( "%p %i %i %i %i\n", self, server->events->size, server->pending->size, server->events2->size, server->waitings->size );
			if( server->vmspace->stopit ) break;
			if( server->finishing && server->vacant == server->total ){
				if( (server->events2->size + server->waitings->size) == 0 ) break;
			}
			wt = 0.01*(server->idle == server->total) + 0.001;
			timeout = DCondVar_TimedWait( & server->condv, & server->mutex, wt );
		}
		for(i=0; i<server->parameters->size; ++i){
			void *param = server->parameters->items.pVoid[i];
			if( DMap_Find( server->active, param ) ) continue;
			DMap_Insert( server->active, param, NULL );
			self->taskOwner = server->owners->items.pVoid[i];
			function = (DThreadTask) server->functions->items.pVoid[i];
			parameter = param;
			DList_Erase( server->functions, i, 1 );
			DList_Erase( server->parameters, i, 1 );
			DList_Erase( server->owners, i, 1 );
			DMap_Erase( server->pending, parameter );
			server->idle -= 1;
			server->vacant -= 1;
			break;
		}
		DMutex_Unlock( & server->mutex );

		if( server->vmspace->stopit ) break;
		if( function ){
			(*function)( parameter );
			self->taskOwner = NULL;
			DMutex_Lock( & server->mutex );
			DMap_Erase( server->active, parameter );
			DMutex_Unlock( & server->mutex );
			continue;
		}

		if( server->pending->size == 0 && server->finishing && server->vacant == server->total ) break;

		DMutex_Lock( & server->mutex );
		server->idle -= 1;
		server->vacant -= self->taskOwner == NULL;
		future = DaoCallServer_GetNextFuture();
		DMutex_Unlock( & server->mutex );

		if( future == NULL ) continue;

		process = future->process;
		if( process == NULL ){
			GC_DecRC( future );
			continue;
		}

		count = process->exceptions->size;
		future->state = DAO_CALL_RUNNING;
		DaoProcess_InterceptReturnValue( process );
		DaoProcess_Start( process );
		if( process->exceptions->size > count ) DaoProcess_PrintException( process, NULL, 1 );
		if( process->status <= DAO_PROCESS_ABORTED ) self->taskOwner = NULL;

		if( future->actor ){
			int erase = 1;
			DMutex_Lock( & server->mutex );
			if( future->actor->rootObject->isAsync ){
				erase = process->status == DAO_PROCESS_FINISHED;
			}
			if( erase ) DMap_Erase( server->active, future->actor->rootObject );
			DMutex_Unlock( & server->mutex );
		}
		DMutex_Lock( & server->mutex );
		DMap_Erase( server->active, process );
		process->active = 0;
		DMutex_Unlock( & server->mutex );

		DaoProcess_ReturnFutureValue( process, future );
		if( future->state == DAO_CALL_FINISHED ) DaoFuture_ActivateEvent( future );
		GC_DecRC( future );
	}
	DMutex_Lock( & server->mutex );
	server->stopped += 1;
	DMutex_Unlock( & server->mutex );
}
Ejemplo n.º 26
0
static DaoFuture* DaoCallServer_GetNextFuture()
{
	DaoCallServer *server = daoCallServer;
	DaoFuture *first, *future, *precond;
	DList *events = server->events;
	DMap *pending = server->pending;
	DMap *active = server->active;
	DNode *it;
	daoint i, j;

	for(i=0; i<events->size; i++){
		DaoTaskEvent *event = (DaoTaskEvent*) events->items.pVoid[i];
		DaoFuture *future = event->future;
		DaoObject *actor = future->actor;
		DaoChannel *channel = event->channel;
		DaoChannel *closed = NULL;
		DaoChannel *chselect = NULL;
		DaoFuture *futselect = NULL;
		DaoValue *selected = NULL;
		DaoValue *message = NULL;
		int type = event->type;

		if( event->state == DAO_EVENT_WAIT && future->precond != NULL ){
			if( future->precond->state != DAO_CALL_FINISHED ) goto MoveToWaiting;
		}
		switch( event->type ){
		case DAO_EVENT_WAIT_SENDING :
			if( channel->buffer->size >= channel->cap ){
				if( event->state == DAO_EVENT_WAIT ){
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_RECEIVING );
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SELECT );
					goto MoveToWaiting;
				}
			}
			event->type = DAO_EVENT_RESUME_TASKLET;
			break;
		case DAO_EVENT_WAIT_RECEIVING :
			if( channel->buffer->size == 0 ){
				if( channel->cap > 0 && event->state == DAO_EVENT_WAIT ){
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SENDING );
					goto MoveToWaiting;
				}
				message = dao_none_value;
			}else{
				message = channel->buffer->items.pValue[0];
			}
			GC_Assign( & event->message, message );
			event->auxiliary = channel->cap <= 0 && channel->buffer->size == 0;
			event->type = DAO_EVENT_RESUME_TASKLET;
			DList_PopFront( channel->buffer );
			if( channel->buffer->size < channel->cap )
				DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SENDING );
			if( channel->buffer->size )
				DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_RECEIVING );
			break;
		case DAO_EVENT_WAIT_SELECT :
			message = dao_none_value;
			for(it=DaoMap_First(event->selects); it; it=DaoMap_Next(event->selects,it)){
				if( DaoValue_CheckCtype( it->key.pValue, dao_type_channel ) ){
					DaoChannel *chan = (DaoChannel*) it->key.pValue;
					if( chan->buffer->size > 0 ){
						chselect = chan;
						selected = it->key.pValue;
						message = chan->buffer->items.pValue[0];
						closed = NULL;
						break;
					}else if( chan->cap == 0 ){
						closed = chan;
					}
				}else{
					DaoFuture *fut = (DaoFuture*) it->key.pValue;
					if( fut->state == DAO_CALL_FINISHED ){
						futselect = fut;
						selected = it->key.pValue;
						message = fut->value;
						break;
					}
				}
			}
			if( selected == NULL ) selected = (DaoValue*) closed;
			if( event->state == DAO_EVENT_WAIT && event->selects->value->size ){
				if( selected == NULL ) goto MoveToWaiting;
			}

			GC_Assign( & event->message, message );
			GC_Assign( & event->selected, selected );
			event->auxiliary = event->selects->value->size == 0;
			event->type = DAO_EVENT_RESUME_TASKLET;
			/* change status to not finished: */
			if( chselect != NULL || futselect != NULL ) event->auxiliary = 0;
			if( chselect ){
				DList_PopFront( chselect->buffer );
				if( chselect->buffer->size < chselect->cap )
					DaoChannel_ActivateEvent( chselect, DAO_EVENT_WAIT_SENDING );
				if( chselect->buffer->size )
					DaoChannel_ActivateEvent( chselect, DAO_EVENT_WAIT_SELECT );
			}
			if( futselect != NULL || closed != NULL ){
				void *key = futselect ? (void*)futselect : (void*)closed;
				DMap_Erase( event->selects->value, key );
			}
			break;
		default: break;
		}
		if( actor ){
			DNode *it = DMap_Find( active, actor->rootObject );
			if( actor->rootObject->isAsync ){
				if( it && it->value.pVoid != (void*) future ) continue;
			}else if( it ){
				continue;
			}
		}
		if( future->process && DMap_Find( active, future->process ) ) continue;
		DList_Erase( events, i, 1 );
		DMap_Erase( pending, event );
		if( actor ){
			void *value = actor->rootObject->isAsync ? future : NULL;
			DMap_Insert( active, actor->rootObject, value );
		}
		if( future->process ){
			DMap_Insert( active, future->process, NULL );
			future->process->active = 1;
		}

		/*
		// DaoValue_Move() should be used instead of GC_Assign() for thread safety.
		// Because using GC_Assign() here, may caused "future->message" of primitive
		// type being deleted, right after DaoFuture_GetGCFields() has retrieved it
		// for GC scanning.
		 */
		DaoValue_Move( event->message, & future->message, NULL );
		DaoValue_Move( event->selected, & future->selected, NULL );
		future->aux1 = event->auxiliary;
		future->timeout = event->timeout;

		GC_IncRC( future ); /* To be decreased at the end of tasklet; */
		DaoCallServer_CacheEvent( event );
		return future;
MoveToWaiting:
		if( event->expiring >= 0.0 && event->expiring < MIN_TIME ) continue;
		if( event->expiring >= MIN_TIME ){
			dao_complex com = {0.0,0.0};
			com.real = event->expiring;
			DMap_Insert( server->waitings, & com, event );
			DCondVar_Signal( & server->condv2 );
		}else{
			DList_Append( server->events2, event );
		}
		DList_Erase( server->events, i, 1 );
		i -= 1;
	}
	return NULL;
}
Ejemplo n.º 27
0
static void DaoCallServer_AddEvent( DaoTaskEvent *event )
{
	DaoCallServer *server = daoCallServer;
	DList_Append( server->events, event );
	DMap_Insert( server->pending, event, NULL );
}
Ejemplo n.º 28
0
static void DaoTaskletServer_AddEvent( DaoTaskletServer *self, DaoTaskletEvent *event )
{
	DList_Append( self->events, event );
	DMap_Insert( self->pending, event, NULL );
}
Ejemplo n.º 29
0
/*
// 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;
}
Ejemplo n.º 30
0
void DaoProfiler_Report( DaoProfiler *self0, DaoStream *stream )
{
	DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}};
	DaoxProfiler *self = (DaoxProfiler*) self0;
	DMap *summary = DMap_New( DAO_DATA_VALUE, 0 );
	DMap *summary2 = DMap_New( DAO_DATA_VALUE, 0 );
	DString *name1 = DString_New();
	DString *name2 = DString_New();
	DNode *it, *it2;
	int count, max = 20;
	char buf1[32];
	char buf2[24];
	char buf[120];

	for(it=DMap_First(self->profile); it; it=DMap_Next(self->profile,it)){
		DaoRoutine *callee = (DaoRoutine*) it->key.pValue;
		com.value = DaoProfiler_Sum( it->value.pMap );
		com.value.real = - com.value.real;
		com.value.imag = - com.value.imag;
		DMap_Insert( summary, & com, it );
	}

	DaoStream_WriteChars( stream, "\n" );
	DaoStream_WriteChars( stream, delimiter );
	DaoStream_WriteChars( stream, delimiter2 );
	snprintf( buf, sizeof(buf), header_format, "Routine", "#Calls", "CPU Time" );
	DaoStream_WriteChars( stream, buf );
	DaoStream_WriteChars( stream, delimiter2 );
	for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){
		DNode *it2 = (DNode*) it->value.pVoid;
		dao_complex data = it->key.pValue->xComplex.value;
		DaoRoutine *callee = (DaoRoutine*) it2->key.pValue;
		DaoRoutine_MakeName( callee, name1, 28, 10, 2 );
		snprintf( buf, sizeof(buf), row_format, name1->chars, (int) -data.imag, -data.real );
		DaoStream_WriteChars( stream, buf );
		if( count == 0 ) break;
	}

	DaoStream_WriteChars( stream, "\n" );
	DaoStream_WriteChars( stream, delimiter3 );
	snprintf( buf, sizeof(buf), header_format2, "Routine", "Caller", "#Calls", "CPU Time" );
	DaoStream_WriteChars( stream, buf );
	DaoStream_WriteChars( stream, delimiter3 );
	for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){
		DNode *it2 = (DNode*) it->value.pVoid;
		DaoRoutine *callee = (DaoRoutine*) it2->key.pValue;
		DMap *profile = it2->value.pMap;

		DaoRoutine_MakeName( callee, name1, 30, 0, 0 );

		DMap_Reset( summary2 );
		for(it2=DMap_First(profile); it2; it2=DMap_Next(profile,it2)){
			DaoRoutine *caller = (DaoRoutine*) it2->key.pValue;
			DaoComplex *data = (DaoComplex*) it2->value.pValue;
			com.value.real = - data->value.real;
			com.value.imag = - data->value.imag;
			DMap_Insert( summary2, & com, caller );
		}
		for(it2=DMap_First(summary2); it2; it2=DMap_Next(summary2,it2)){
			DaoRoutine *caller = (DaoRoutine*) it2->value.pValue;
			dao_complex data = it2->key.pValue->xComplex.value;
			DString_Reset( name2, 0 );
			if( caller ) DaoRoutine_MakeName( caller, name2, 22, 0, 0 );
			snprintf( buf, sizeof(buf), row_format2, name1->chars, name2->chars, (int) -data.imag, -data.real );
			DaoStream_WriteChars( stream, buf );
			DString_Reset( name1, 0 );
		}
		if( count == 0 ) break;
	}
	DString_Delete( name1 );
	DString_Delete( name2 );
}