Example #1
0
void DaoCinType_DeriveMethods( DaoCinType *self )
{
	daoint i, k, m, N = self->supers->size;
	DaoCinType *super;
	DNode *it;
	for(i=0; i<N; i++){
		super = (DaoCinType*) self->supers->items.pValue[i];
		self->citype->bases = DList_New( DAO_DATA_VALUE );
		self->vatype->bases = DList_New( DAO_DATA_VALUE );
		DList_Append( self->citype->bases, super->citype );
		DList_Append( self->vatype->bases, super->vatype );
		for(it=DMap_First(super->methods); it; it=DMap_Next( super->methods, it )){
			if( it->value.pRoutine->overloads ){
				DRoutines *routs = it->value.pRoutine->overloads;
				for(k=0,m=routs->routines->size; k<m; k++){
					DaoRoutine *rout = routs->routines->items.pRoutine[i];
					DaoMethods_Insert( self->methods, rout, NULL, self->vatype );
				}
			}else{
				DaoMethods_Insert( self->methods, it->value.pRoutine, NULL, self->vatype );
			}
		}
	}
	self->derived = 1;
}
Example #2
0
/*
// Only activate one event per channel:
*/
void DaoChannel_ActivateEvent( DaoChannel *self, int type )
{
	DaoCallServer *server = daoCallServer;
	DNode *node;
	daoint i;

	for(i=0; i<server->events2->size; ++i){
		DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i];
		if( event->type != type ) continue;
		if( DaoCallServer_CheckEvent( event, NULL, self ) ){
			DList_Append( server->events, event );
			DList_Erase( server->events2, i, 1 );
			return;
		}
	}
	for(node=DMap_First(server->waitings); node; node=DMap_Next(server->waitings,node)){
		DaoTaskEvent *event = (DaoTaskEvent*) node->value.pValue;
		if( event->type != type ) continue;
		if( DaoCallServer_CheckEvent( event, NULL, self ) ){
			DList_Append( server->events, event );
			DMap_EraseNode( server->waitings, node );
			return;
		}
	}
}
Example #3
0
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;
}
Example #4
0
/*
// Activate all events waiting on a future value:
*/
void DaoFuture_ActivateEvent( DaoFuture *self )
{
	DaoCallServer *server = daoCallServer;
	DList *array = DList_New(0);
	DNode *node;
	daoint i;

	DMutex_Lock( & server->mutex );
	for(i=0; i<server->events2->size; ++i){
		DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i];
		if( DaoCallServer_CheckEvent( event, self, NULL ) ){
			event->state = DAO_EVENT_RESUME;
			DList_Append( server->events, event );
			DList_Erase( server->events2, i, 1 );
			i -= 1;
		}
	}
	for(node=DMap_First(server->waitings); node; node=DMap_Next(server->waitings,node)){
		DaoTaskEvent *event = (DaoTaskEvent*) node->value.pValue;
		/* remove from timed waiting list: */
		if( DaoCallServer_CheckEvent( event, self, NULL ) ){
			event->state = DAO_EVENT_RESUME;
			DList_Append( server->events, event );
			DList_Append( array, node->key.pVoid );
		}
	}
	for(i=0; i<array->size; i++) DMap_Erase( server->waitings, array->items.pVoid[i] );
	DCondVar_Signal( & server->condv );
	DMutex_Unlock( & server->mutex );
	DList_Delete( array );
}
Example #5
0
static void DaoxGraph_HandleGC( DaoValue *p, DList *values, DList *arrays, DList *maps, int remove )
{
	daoint i, n;
	DaoxGraph *self = (DaoxGraph*) p;
	DList_Append( arrays, self->nodes );
	DList_Append( arrays, self->edges );
	if( self->nodeType ) DList_Append( values, self->nodeType );
	if( self->edgeType ) DList_Append( values, self->edgeType );
	if( remove ){
		self->nodeType = NULL;
		self->edgeType = NULL;
		for(i=0,n=self->nodes->size; i<n; i++){
			DaoxNode *node = self->nodes->items.pgNode[i];
			if( node->ins ) DList_Clear( node->ins );
			DList_Clear( node->outs );
			node->graph = NULL;
		}
		for(i=0,n=self->edges->size; i<n; i++){
			DaoxEdge *edge = self->edges->items.pgEdge[i];
			edge->graph = NULL;
			edge->first = NULL;
			edge->second = NULL;
		}
	}
}
Example #6
0
static void DaoxWindow_GetGCFields( void *p, DList *values, DList *lists, DList *maps, int remove )
{
	DaoxWindow *self = (DaoxWindow*) p;
	DList_Append( values, self->context );
	if( self->painter ) DList_Append( values, self->painter );
	if( self->renderer ) DList_Append( values, self->renderer );
	if( self->widget ) DList_Append( values, self->widget );
	if( self->model ) DList_Append( values, self->model );
	if( remove ){
		self->context = NULL;
		self->painter = NULL;
		self->renderer = NULL;
		self->widget = NULL;
		self->model = NULL;
	}
}
Example #7
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 );
}
Example #8
0
static void DaoSTD_Error3( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoType *etype = p[0]->xCtype.cdtype;
	DaoException *exception = DaoException_New( etype );
	DaoException_Init( exception, proc, p[1]->xString.value->chars, p[2] );
	DList_Append( proc->exceptions, exception );
}
Example #9
0
static void CHANNEL_Send( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoValue *data;
	DaoFuture *future = DaoProcess_GetInitFuture( proc );
	DaoChannel *self = (DaoChannel*) par[0];
	float timeout = par[2]->xFloat.value;

	DaoProcess_PutInteger( proc, 1 );
	if( self->cap <= 0 ){
		DaoProcess_RaiseError( proc, "Param", "channel is closed" );
		return;
	}

	data = DaoValue_DeepCopy( par[1] );
	if( data == NULL ){
		DaoProcess_RaiseError( proc, "Param", "invalid data for the channel" );
		return;
	}

	//printf( "CHANNEL_Send: %p\n", event );
	DMutex_Lock( & daoCallServer->mutex );
	DList_Append( self->buffer, data );
	DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_RECEIVING );
	DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_SELECT );
	DCondVar_Signal( & daoCallServer->condv );
	DMutex_Unlock( & daoCallServer->mutex );

	if( self->buffer->size >= self->cap ){
		DaoTaskEvent *event = DaoCallServer_MakeEvent();
		DaoTaskEvent_Init( event, DAO_EVENT_WAIT_SENDING, DAO_EVENT_WAIT, future, self );
		proc->status = DAO_PROCESS_SUSPENDED;
		proc->pauseType = DAO_PAUSE_CHANNEL_SEND;
		DaoCallServer_AddTimedWait( proc, event, timeout );
	}
}
Example #10
0
static void DaoSTD_Error( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoType *etype = DaoVmSpace_MakeExceptionType( proc->vmSpace, "Exception::Error" );
	DaoException *exception = DaoException_New( etype );

	DaoException_Init( exception, proc, p[0]->xString.value->chars, NULL );
	DList_Append( proc->exceptions, exception );
}
Example #11
0
void DaoChannel_Send( DaoChannel *self, DaoValue *data )
{
	DMutex_Lock( & daoCallServer->mutex );
	DList_Append( self->buffer, data );
	DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_RECEIVING );
	DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_SELECT );
	DCondVar_Signal( & daoCallServer->condv );
	DMutex_Unlock( & daoCallServer->mutex );
}
Example #12
0
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;
}
Example #13
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 );
	}
}
Example #14
0
static void DaoCallServer_ActivateEvents()
{
	DaoCallServer *server = daoCallServer;
	char message[128];
	daoint i, j, count = 0;

	if( server->finishing == 0 ) return;
	if( server->idle != server->total ) return;
	if( server->events->size != 0 ) return;
	if( server->events2->size == 0 ) return;

#ifdef DEBUG
	sprintf( message, "WARNING: try activating events (%i,%i,%i,%i)!\n", server->total,
			server->idle, (int)server->events->size, (int)server->events2->size );
	DaoStream_WriteChars( mainVmSpace->errorStream, message );
#endif
	for(i=0; i<server->events2->size; ++i){
		DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i];
		DaoChannel *chan = event->channel;
		DaoFuture *fut = event->future;
		int move = 0, closed = 0;
		switch( event->type ){
		case DAO_EVENT_WAIT_TASKLET :
			move = fut->precond == NULL || fut->precond->state == DAO_CALL_FINISHED;
			break;
		case DAO_EVENT_WAIT_RECEIVING :
			move = chan->buffer->size > 0;
			if( chan->cap <= 0 && chan->buffer->size == 0 ) move = 1;
			break;
		case DAO_EVENT_WAIT_SENDING :
			move = chan->buffer->size < chan->cap;
			break;
		case DAO_EVENT_WAIT_SELECT :
			if( event->selects == NULL ) continue;
			move = DaoTaskEvent_CheckSelect( event );
			break;
		default: break;
		}
		if( move ){
			DList_Append( server->events, event );
			DList_Erase( server->events2, i, 1 );
			count += 1;
			i -= 1;
		}
	}
	DCondVar_Signal( & server->condv );
	if( count == 0 ){
		DaoStream *stream = mainVmSpace->errorStream;
		DaoStream_WriteChars( stream, "ERROR: All tasklets are suspended - deadlock!\n" );
#if DEBUG
		fprintf( stderr, "ERROR: All tasklets are suspended - deadlock!\n" );
#endif
		exit(1);
	}
}
Example #15
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 );
	}
}
Example #16
0
void DaoCallServer_AddThread( DThreadTask func, void *param )
{
	DaoCallThread *calth;
	DaoCallServer_TryInit( mainVmSpace );
	calth = DaoCallThread_New( func, param );
	DMutex_Lock( & daoCallServer->mutex );
	daoCallServer->total += 1;
	DList_Append( daoCallServer->threads, calth );
	DMutex_Unlock( & daoCallServer->mutex );
	if( DThread_Start( & calth->thread, (DThreadTask) DaoCallThread_Run, calth ) == 0 ){
		if( func != NULL || daoCallServer->total == 0 ){
			dao_abort( "failed to create a task thread" );
		}
	}
}
Example #17
0
void DaoVmSpace_AddTaskletThread( DaoVmSpace *self, DThreadTask func, void *param, void *proc )
{
	DaoTaskletThread *taskthd;
	DaoTaskletServer *server = DaoTaskletServer_TryInit( self );
	taskthd = DaoTaskletThread_New( server, func, param );
	taskthd->taskOwner = proc;
	DMutex_Lock( & server->mutex );
	server->total += 1;
	DList_Append( server->threads, taskthd );
	DMutex_Unlock( & server->mutex );
	if( DThread_Start( & taskthd->thread, (DThreadTask) DaoTaskletThread_Run, taskthd ) == 0 ){
		if( func != NULL || server->total == 0 ){
			dao_abort( "failed to create a task thread" );
		}
	}
}
Example #18
0
DaoxEdge* DaoxGraph_AddEdge( DaoxGraph *self, DaoxNode *first, DaoxNode *second )
{
	DaoxEdge *edge = DaoxEdge_New( self );
	DList_PushFront( first->outs, edge );
	if( self->directed ){
		if( second->ins == NULL ) second->ins = DList_New(DAO_DATA_VALUE);
		DList_PushBack( second->ins, edge );
	}else{
		DList_PushBack( second->outs, edge );
	}

	DList_Append( self->edges, edge );
	edge->first = first;
	edge->second = second;
	return edge;
}
Example #19
0
void DaoXmlDOM_CacheNode( DaoXmlDOM *self, DaoXmlNode *node )
{
	daoint i;
	for(i=0; i<node->children->size; ++i){
		DaoXmlDOM_CacheNode( self, (DaoXmlNode*) node->children->items.pVoid[i] );
	}
	node->id = 0;
	node->parent = NULL;
	node->data = NULL;
	node->children->size = 0;
	node->name->size = 0;
	/* Most nodes will have empty contents, and some may have long contents,
	// so it is better to clear the string: */
	DString_Clear( node->content );
	DMap_Reset( node->attributes );
	DList_Append( self->caches, node );
}
Example #20
0
static void DaoCallServer_Timer( void *p )
{
	DaoCallServer *server = daoCallServer;
	double time = 0.0;
	daoint i, timeout;

	server->timing = 1;
	while( server->finishing == 0 || server->stopped != server->total ){
		DMutex_Lock( & server->mutex );
		while( server->waitings->size == 0 ){
			if( server->idle == server->total && server->events2->size ){
				DaoCallServer_ActivateEvents();
			}
			if( server->finishing && server->stopped == server->total ) break;
			DCondVar_TimedWait( & server->condv2, & server->mutex, 0.01 );
		}
		if( server->waitings->size ){
			DNode *node = DMap_First( server->waitings );
			time = node->key.pComplex->real;
			time -= Dao_GetCurrentTime();
			/* wait the right amount of time for the closest arriving timeout: */
			if( time > 0 ) DCondVar_TimedWait( & server->condv2, & server->mutex, time );
		}
		DMutex_Unlock( & server->mutex );
		if( server->finishing && server->stopped == server->total ) break;

		DMutex_Lock( & server->mutex );
		if( server->waitings->size ){ /* a new wait timed out: */
			DNode *node = DMap_First( server->waitings );
			time = Dao_GetCurrentTime();
			if( node->key.pComplex->real < time ){
				DaoTaskEvent *event = (DaoTaskEvent*) node->value.pVoid;
				event->state = DAO_EVENT_RESUME;
				event->timeout = 1;
				event->expiring = MIN_TIME;
				DList_Append( server->events, node->value.pVoid );
				DMap_EraseNode( server->waitings, node );
			}
		}
		DCondVar_Signal( & server->condv );
		DMutex_Unlock( & server->mutex );
	}
	server->timing = 0;
}
Example #21
0
static void GRAPH_RemoveSingletonNodes( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxGraph *self = (DaoxGraph*) p[0];
	DaoxGraph *save = (DaoxGraph*) p[1];
	daoint i, k, n, removed = 0;
	for(i=0,k=0,n=self->nodes->size; i<n; i++){
		DaoxNode *node = (DaoxNode*) self->nodes->items.pVoid[i];
		/* Ensure no duplication of the reference (for the Concurrent GC): */
		self->nodes->items.pVoid[i] = NULL;
		if( (node->ins->size + node->outs->size) == 0 ){
			if( save ) DList_Append( save->nodes, node );
			GC_DecRC( node );
			continue;
		}
		self->nodes->items.pVoid[k++] = node;
	}
	DaoProcess_PutInteger( proc, self->nodes->size - k );
	self->nodes->size = k;
}
Example #22
0
void DList_Assign( DList *left, DList *right )
{
	daoint i;
	assert( left->type == right->type || (left->type == DAO_DATA_VALUE && right->type == 0) );

	if( left == right ) return;
	if( right->size == 0 ){
		DList_Clear( left );
		return;
	}
	if( left->type ){
		DList_Clear( left);
		for( i=0; i<right->size; i++ ) DList_Append( left, right->items.pVoid[i] );
	}else{
		DList_Resize( left, right->size, NULL );
		if( left->type == DAO_DATA_VALUE ) DaoGC_LockData();
		for( i=0; i<right->size; i++ ) left->items.pVoid[i] = right->items.pVoid[i];
		if( left->type == DAO_DATA_VALUE ) DaoGC_UnlockData();
	}
}
Example #23
0
int DaoXmlParser_ParseNodeContent( DaoXmlParser *self, DaoXmlDOM *dom, DaoXmlNode *node )
{
	DaoXmlNode *child;
	while( self->source < self->end ){
		if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
		if( self->source >= self->end ) return 1;
		if( *self->source == '<' ){
			char *current = self->source;
			self->source += 1;
			if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
			if( *self->source == '/' ){
				self->source = current;
				return 0;
			}else if( *self->source == '!' ){
				self->source += 1;
				if( strncmp( self->source, "[CDATA[", 7 ) == 0 ){
					self->source = strstr( self->source + 7, "]]>" );
					if( self->source == NULL ) return 1;
					self->source += 3;
					continue;
				}else if( strncmp( self->source, "--", 2 ) == 0 ){
					self->source = strstr( self->source + 7, "-->" );
					if( self->source == NULL ) return 1;
					self->source += 3;
					continue;
				}
			}

			child = DaoXmlDOM_NewNode( dom );
			child->parent = node;
			DList_Append( node->children, child );
			self->source = current;
			DaoXmlParser_ParseNode( self, dom, child );
		}else{
			while( self->source < self->end && *self->source != '<' ){
				if( DaoXmlParser_ParseFormatedChar( self, node->content ) ) return 1;
			}
		}
	}
	return 0;
}
Example #24
0
static void DaoFuture_GetGCFields( void *p, DList *values, DList *lists, DList *maps, int remove )
{
	DaoFuture *self = (DaoFuture*) p;
	if( self->value ) DList_Append( values, self->value );
	if( self->actor ) DList_Append( values, self->actor );
	if( self->message ) DList_Append( values, self->message );
	if( self->selected ) DList_Append( values, self->selected );
	if( self->process ) DList_Append( values, self->process );
	if( self->precond ) DList_Append( values, self->precond );
	if( remove ){
		self->value = NULL;
		self->actor = NULL;
		self->message = NULL;
		self->selected = NULL;
		self->process = NULL;
		self->precond = NULL;
	}
}
Example #25
0
static void DaoSTD_Assert( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoType *etype;
	DaoException *exception;
	DaoRoutine *rout = proc->activeRoutine;
	DString *file = proc->activeNamespace->name;
	int line, id = (ushort_t) (proc->activeCode - proc->topFrame->active->codes);

	if( p[0]->xBoolean.value ) return;

	line = rout->defLine;
	if( id < rout->body->vmCodes->size ) line = rout->body->annotCodes->items.pVmc[id]->line;

	etype = DaoVmSpace_MakeExceptionType( proc->vmSpace, "Error::Assertion" );
	exception = DaoException_New( etype );
	DList_Append( proc->exceptions, exception );

	DaoException_Init( exception, proc, NULL, NULL );

	DString_Reserve( exception->info, file->size + 100 );
	id = sprintf( exception->info->chars, dao_assertion_format, line, file->chars );
	if( id ) exception->info->size = id;
	DString_Append( exception->info, p[1]->xString.value );
}
Example #26
0
void DaoInterface_DeriveMethods( DaoInterface *self )
{
	daoint i, k, m, N = self->bases->size;
	DaoNamespace *ns = self->nameSpace;
	DaoInterface *base;
	DNode *it;
	for(i=0; i<N; i++){
		base = (DaoInterface*) self->bases->items.pValue[i];
		if( self->abtype->bases == NULL ) self->abtype->bases = DList_New( DAO_DATA_VALUE );
		DList_Append( self->abtype->bases, base->abtype );
		for(it=DMap_First(base->methods); it; it=DMap_Next( base->methods, it )){
			if( it->value.pRoutine->overloads ){
				DRoutines *routs = it->value.pRoutine->overloads;
				for(k=0,m=routs->routines->size; k<m; k++){
					DaoRoutine *rout = routs->routines->items.pRoutine[i];
					DaoMethods_Insert( self->methods, rout, ns, self->abtype );
				}
			}else{
				DaoMethods_Insert( self->methods, it->value.pRoutine, ns, self->abtype );
			}
		}
	}
	self->derived = 1;
}
Example #27
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;
}
Example #28
0
static void DaoChannel_GetGCFields( void *p, DList *vs, DList *lists, DList *ms, int rm )
{
	DaoChannel *self = (DaoChannel*) p;
	DList_Append( lists, self->buffer );
}
Example #29
0
bool DaoxDebugger::EditContinue ( DaoProcess *process, int newEntryLine, QList<int> & lineMap, QStringList & newCodes, QStringList & routCodes )
{
	DaoRoutine *oldrout = process->activeRoutine;
	int i, j, k, dest = 0;
	//printf( "=======%s\n", routCodes.join("\n").toLocal8Bit().data() );
	//printf( "=======%s\n", newCodes.join("\n").toLocal8Bit().data() );
	if( routCodes.size() == newCodes.size() ){
		DaoLexer *lexer = DaoLexer_New();
		bool eq = true;
		for(i=0; i<routCodes.size(); i++){
			QString s1 = NormalizeCodes( routCodes[i], lexer );
			QString s2 = NormalizeCodes( newCodes[i], lexer );
			if( s1 != s2 ){
				eq = false;
				break;
			}
		}
		DaoLexer_Delete( lexer );
		if( eq ) return true;
	}
	QString codes = newCodes.join( "\n" );
	DaoParser *parser = DaoParser_New();
	DaoRoutine *routine = DaoRoutine_New( oldrout->nameSpace, oldrout->routHost, 1 );
	routine->routType = oldrout->routType;
	routine->parCount = oldrout->parCount;
	routine->attribs = oldrout->attribs;
	routine->defLine = oldrout->defLine;
	parser->routine = routine;
	parser->nameSpace = routine->nameSpace = oldrout->nameSpace;
	parser->vmSpace = oldrout->nameSpace->vmSpace;
	DString_Assign( parser->fileName, oldrout->nameSpace->name );
	routine->body->codeStart = oldrout->body->codeStart;
	routine->body->codeEnd = oldrout->body->codeStart + newCodes.size() + 1;
	parser->regCount = routine->parCount;
	parser->levelBase = oldrout->defLine != 0;
	bool res = DaoParser_LexCode( parser, codes.toLocal8Bit().data(), 1 );
	for(i=0; i<(int)parser->tokens->size; i++){
		parser->tokens->items.pToken[i]->line += routine->body->codeStart;
	}
	for(i=0; i<(int)oldrout->body->defLocals->size; i++){
		DaoToken *tok = oldrout->body->defLocals->items.pToken[i];
		if( tok->index >= oldrout->parCount || tok->type ==0 ) break;
		MAP_Insert( DList_Top( parser->lookupTables ), & tok->string, i );
		DList_Append( routine->body->defLocals, tok );
	}
	res = res && DaoParser_ParseRoutine( parser );
	DaoParser_Delete( parser );
	if( res == false ){
		DaoRoutine_Delete( routine );
		return false;
	}
	if( (process->stackSize - process->stackTop) < (routine->body->regCount + DAO_MAX_PARAM) ){
		DaoProcess_PushFrame( process, routine->body->regCount );
		DaoProcess_PopFrame( process );
	}
	DaoType **regTypes = routine->body->regType->items.pType;
	DaoValue **newValues = process->activeValues;
	DaoValue **oldValues = (DaoValue**)calloc( oldrout->body->regCount, sizeof(DaoValue*) );

	memcpy( oldValues, newValues, oldrout->body->regCount * sizeof(DaoValue*) );
	memset( newValues, 0, oldrout->body->regCount * sizeof(DaoValue*) );
	DaoProcess_InitTopFrame( process, routine, process->activeObject );

#if 0
	DaoStream *stream = DaoStream_New();
	DaoRoutine_PrintCode( oldrout, stream );
	DaoRoutine_PrintCode( routine, stream );
#endif

	regmap.clear();
	for(i=0; i<oldrout->parCount; i++) regmap[i] = i;

	DaoVmCode   *oldVMC = oldrout->body->vmCodes->data.codes;
	DaoVmCode   *newVMC = routine->body->vmCodes->data.codes;
	DaoVmCodeX **oldAnnot = oldrout->body->annotCodes->items.pVmc;
	DaoVmCodeX **newAnnot = routine->body->annotCodes->items.pVmc;
	int M = oldrout->body->vmCodes->size;
	int N = routine->body->vmCodes->size;
	j = k = 0;
	for(i=0; i<lineMap.size(); i++){
		QList<DaoVmCode> oldLineCodes;
		QList<DaoVmCode> newLineCodes;
		if( lineMap[i] <0 ) continue;
		int old = lineMap[i] + oldrout->body->codeStart + 1;
		int niu = i + routine->body->codeStart + 1;
		//printf( "%3i  %3i: %3i  %3i;  %3i  %3i\n", j, k, i, niu, lineMap[i], old );
		while( j<M && oldAnnot[j]->line < old ) ++j;
		while( k<N && newAnnot[k]->line < niu ) ++k;
		while( j<M && oldAnnot[j]->line == old ){
			oldLineCodes.append( oldVMC[j] );
			++j;
		}
		while( k<N && newAnnot[k]->line == niu ){
			newLineCodes.append( newVMC[k] );
			++k;
		}
		Matching( oldLineCodes, newLineCodes );
	}
	QMap<int,int>::iterator it, end = regmap.end();
	for(it=regmap.begin(); it != end; ++it){
		j = it.key();
		i = it.value();
		DaoValue_Move( oldValues[j], & newValues[i], regTypes[i] );
	}

	int offset = 0;
	if( newEntryLine <0 ){
		DaoVmCodeX **annotCodes = oldrout->body->annotCodes->items.pVmc;
		int entry = (process->activeCode - process->topFrame->codes) + 1;
		int entryline = oldrout->body->annotCodes->items.pVmc[entry]->line;
		/* if the entry line is NOT modified, use it */
		entryline -= oldrout->body->codeStart + 1;
		for(i=0; i<lineMap.size(); i++) if( lineMap[i] == entryline ) break;
		int newEntryLine = i < lineMap.size() ? i : -1;
		if( newEntryLine >=0 ){
			entryline += oldrout->body->codeStart + 1;
			while( (--entry) >=0 && annotCodes[entry]->line == entryline ) offset ++;
		}
		/* if the entry line IS modified, set the entry line to the first modified line */
		if( newEntryLine <0 ){
			for(i=0; i<lineMap.size(); i++) if( lineMap[i] <0 ) break;
			newEntryLine = i;
		}
		/* if the entry line is manually set: */
		newEntryLine += routine->body->codeStart + 1;
	}

	//XXX GC_ShiftRC( routine, oldrout );
	GC_IncRC( routine );
	oldrout->body->revised = routine;
	process->activeRoutine = routine;
	process->activeTypes = regTypes;
	process->topFrame->codes = routine->body->vmCodes->data.codes;

	ResetExecution( process, newEntryLine, offset );

	i = newCodes.size() - routCodes.size();
	DaoNS_UpdateLineInfo( routine->nameSpace, routine->body->codeStart, i );
	return true;
}
Example #30
0
static void DaoCallServer_AddEvent( DaoTaskEvent *event )
{
	DaoCallServer *server = daoCallServer;
	DList_Append( server->events, event );
	DMap_Insert( server->pending, event, NULL );
}