Beispiel #1
0
static void STD_Map( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *res, *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoMap *map = DaoProcess_PutMap( proc, p[1]->xInteger.value );
	daoint i, entry, size = p[0]->xInteger.value;

	if( sect == NULL || size < 0 ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=0; i<size; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		res = proc->stackValues[0];
		if( res->type == DAO_TUPLE && res->xTuple.size == 2 )
			DaoMap_Insert( map, res->xTuple.items[0], res->xTuple.items[1] );
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
}
Beispiel #2
0
static void DaoStream_ReadLines( DaoStream *self, DaoList *list, DaoProcess *proc, int count, int chop )
{
	DaoValue *res;
	DaoString *line;
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 );
	daoint i = 0;

	if( sect == NULL ){
		line = DaoString_New();
		while( (count == 0 || (i++) < count) && DaoStream_ReadLine( self, line->value ) ){
			if( line->value->size == 0 && self->AtEnd != NULL && self->AtEnd( self ) ) break;
			if( chop ) DString_Chop( line->value, 0 );
			DaoList_Append( list, (DaoValue*) line );
		}
		DaoString_Delete( line );
	}else{
		ushort_t entry = proc->topFrame->entry;
		if( sect->b ){
			DaoString tmp = {DAO_STRING,0,0,0,1,NULL};
			DString tmp2 = DString_WrapChars( "" );
			tmp.value = & tmp2;
			line = (DaoString*) DaoProcess_SetValue( proc, sect->a, (DaoValue*)(void*) &tmp );
		}
		while( (count == 0 || (i++) < count) && DaoStream_ReadLine( self, line->value ) ){
			if( line->value->size == 0 && self->AtEnd != NULL && self->AtEnd( self ) ) break;
			if( chop ) DString_Chop( line->value, 0 );
			proc->topFrame->entry = entry;
			DaoProcess_Execute( proc );
			if( proc->status == DAO_PROCESS_ABORTED ) break;
			res = proc->stackValues[0];
			if( res && res->type != DAO_NONE ) DaoList_Append( list, res );
		}
		DaoProcess_PopFrame( proc );
	}
}
Beispiel #3
0
static void STD_List( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *res = p[N==2], *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoList *list = DaoProcess_PutList( proc );
	daoint i, entry, size = p[0]->xInteger.value;
	daoint fold = N == 2;

	if( fold ) DaoList_Append( list, res );
	if( sect == NULL || size < 0 ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=fold; i<size; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		if( sect->b >1 && N ==2 ) DaoProcess_SetValue( proc, sect->a+1, res );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		res = proc->stackValues[0];
		DaoList_Append( list, res );
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
}
Beispiel #4
0
static void TEST_AssertError( DaoProcess *proc, DaoValue* p[], int N )
{
	DString *expected = p[0]->xString.value;
	DString *actual = NULL;
	DList *errors = proc->exceptions;
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 );
	int catched = 0;
	int size = errors->size;
	if( sect == NULL ) return;
	DaoProcess_Execute( proc );
	if ( proc->status == DAO_PROCESS_ABORTED && errors->size > size ){
		DaoException *e = (DaoException*)&errors->items.pValue[errors->size - 1]->xCdata;
		if ( DString_Compare( expected, e->ctype->name ) != 0 )
			actual = DString_Copy( e->ctype->name );
		else
			catched = 1;
		DList_Clear( errors );
	}
	DaoProcess_PopFrame( proc );
	if ( !catched ){
		char buf[512];
		if ( actual ){
			snprintf( buf, sizeof(buf), "expected %s error, intercepted %s", expected->chars, actual->chars );
			DString_Delete( actual );
		}
		else
			snprintf( buf, sizeof(buf), "expected %s error, intercepted nothing", expected->chars );
		DaoProcess_RaiseError( proc, "Test::AssertError", buf );
	}
}
Beispiel #5
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 );
}
Beispiel #6
0
static void DaoIO_WriteLines( DaoProcess *proc, DaoValue *p[], int N )
{
	DString *string;
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *res, *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	daoint i, entry, lines = p[1]->xInteger.value;
	FILE *fout = stdout;

	if( p[0]->type == DAO_STRING ){
		fout = DaoIO_OpenFile( proc, p[0]->xString.data, "w+", 0 );
		if( fout == NULL ) return;
	}else{
		if( p[0]->xStream.file ) fout = p[0]->xStream.file;
	}
	if( sect == NULL || DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	for(i=0; i<lines; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		string = proc->stackValues[0]->xString.data;
		if( string->mbs ){
			fprintf( fout, "%s", string->mbs );
		}else{
			fprintf( fout, "%ls", string->wcs );
		}
	}
	DaoProcess_PopFrame( proc );
}
Beispiel #7
0
static void DaoMT_RunArrayFunctional( void *p )
{
	DaoValue **idval;
	DaoValue *elem, *res = NULL;
	DaoValue tidint = {DAO_INTEGER};
	DaoValue com = {DAO_COMPLEX};
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoArray *param = (DaoArray*) self->param;
	DaoArray *result = (DaoArray*) self->result;
	DaoArray *original = param->original;
	DaoArray *array = original ? original : param;
	DArray *slices = param->slices;
	daoint *dims = array->dims;
	daoint i, id, id2, n = DaoArray_SliceSize( param );
	int j, D = array->ndim;
	int isvec = (D == 2 && (dims[0] ==1 || dims[1] == 1));
	int stackBase, vdim = sect->b - 1;

	DaoMT_InitProcess( self->proto, clone );
	tidint.xInteger.value = self->first;

	stackBase = clone->topFrame->active->stackBase;
	idval = clone->activeValues + sect->a + 1;
	for(j=0; j<vdim; j++) idval[j]->xInteger.value = 0;
	for(i=self->first; i<n; i+=self->step){
		idval = clone->stackValues + stackBase + sect->a + 1;
		id = id2 = (original ? DaoArray_IndexFromSlice( original, slices, i ) : i);
		if( isvec ){
			if( vdim >0 ) idval[0]->xInteger.value = id2;
			if( vdim >1 ) idval[1]->xInteger.value = id2;
		}else{
			for( j=D-1; j>=0; j--){
				int k = id2 % dims[j];
				id2 /= dims[j];
				if( j < vdim ) idval[j]->xInteger.value = k;
			}
		}
		elem = clone->stackValues[ stackBase + sect->a ];
		if( elem == NULL || elem->type != array->etype ){
			elem = (DaoValue*)&com;
			elem->type = array->etype;
			elem = DaoProcess_SetValue( clone, sect->a, elem );
		}
		DaoArray_GetValue( array, id, elem );
		if( sect->b > 6 ) DaoProcess_SetValue( clone, sect->a+6, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			DaoArray_SetValue( result, i, res );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			DaoArray_SetValue( array, id, res );
		}
	}
}
Beispiel #8
0
static void DaoMT_Critical( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	if( proc->mutex ) DMutex_Lock( proc->mutex );
	DaoProcess_Execute( proc );
	if( proc->mutex ) DMutex_Unlock( proc->mutex );
	DaoProcess_PopFrame( proc );
}
Beispiel #9
0
static void DaoMutex_Lib_Protect( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoMutex *self = (DaoMutex*) p[0];
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	DaoMutex_Lock( self );
	DaoProcess_Execute( proc );
	DaoMutex_Unlock( self );
	DaoProcess_PopFrame( proc );
}
Beispiel #10
0
static void DaoSema_Lib_Protect( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoSema *self = (DaoSema*) p[0];
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	DSema_Wait( & self->mySema );
	DaoProcess_Execute( proc );
	DSema_Post( & self->mySema );
	DaoProcess_PopFrame( proc );
}
Beispiel #11
0
static DaoCdata* DaoCdata_MakeObject( DaoCdata *self, DaoValue *param, DaoProcess *proc )
{
	DaoValue *value;
	DaoRoutine *routine = DaoType_FindFunction( self->ctype, self->ctype->name );
	if( DaoProcess_PushCallable( proc, routine, NULL, & param, 1 ) ) return NULL;
	proc->topFrame->active = proc->firstFrame;
	DaoProcess_SetActiveFrame( proc, proc->firstFrame ); /* return value in stackValues[0] */
	if( DaoProcess_Execute( proc ) == 0 ) return NULL;
	value = proc->stackValues[0];
	if( value && (value->type == DAO_CDATA || value->type == DAO_CSTRUCT) ) return & value->xCdata;
	return NULL;
}
Beispiel #12
0
static DaoObject* DaoClass_MakeObject( DaoClass *self, DaoValue *param, DaoProcess *proc )
{
	DaoObject *object = DaoObject_New( self );
	DaoProcess_CacheValue( proc, (DaoValue*) object );
	if( DaoProcess_PushCallable( proc, self->classRoutines, (DaoValue*)object, & param, 1 ) ==0 ){
		GC_ShiftRC( object, proc->topFrame->object );
		proc->topFrame->object = object;
		proc->topFrame->returning = -1;
		if( DaoProcess_Execute( proc ) ) return object;
	}
	return NULL;
}
Beispiel #13
0
static void DaoMT_Start0( void *p )
{
	DaoProcess *proc = (DaoProcess*)p;
	int count = proc->exceptions->size;
	DaoProcess_Execute( proc );
	DaoProcess_ReturnFutureValue( proc, proc->future );
	if( proc->exceptions->size > count ) DaoProcess_PrintException( proc, 1 );
	if( proc->future->state == DAO_CALL_FINISHED ){
		DaoFuture_ActivateEvent( proc->future );
		DaoVmSpace_ReleaseProcess( proc->vmSpace, proc );
	}
}
Beispiel #14
0
static void NODE_Search( DaoProcess *proc, DaoValue *p[], int N )
{
	DList *nodes;
	DaoList *list = DaoProcess_PutList( proc );
	DaoxNode *self = (DaoxNode*) p[0];
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 );
	daoint method = p[1]->xEnum.value;
	daoint which = p[2]->xEnum.value;
	daoint i, j, entry;

	if( sect == NULL ) return;
	for(i=0; i<self->graph->nodes->size; i++){
		DaoxNode *node = (DaoxNode*) self->graph->nodes->items.pVoid[i];
		node->state = 0;
	}
	nodes = DList_New(0);
	DList_PushBack( nodes, self );

	entry = proc->topFrame->entry;
	while( nodes->size ){
		DaoxNode *node = NULL;
		if( method ){
			node = (DaoxNode*) DList_Front( nodes );
			DList_PopFront( nodes );
		}else{
			node = (DaoxNode*) DList_Back( nodes );
			DList_PopBack( nodes );
		}
		if( node->state ) continue;
		node->state = 1;

		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, (DaoValue*) node );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		if( proc->stackValues[0]->xInteger.value ){
			DaoList_PushBack( list, (DaoValue*) node );
			if( which == 0 ) break;
		}

		for(j=0; j<node->outs->size; j++){
			DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j];
			DaoxNode *node2 = node == edge->first ? edge->second : edge->first;
			DList_PushBack( nodes, node2 );
		}
	}
	DaoProcess_PopFrame( proc );
	DList_Delete( nodes );
}
Beispiel #15
0
int DaoObject_InvokeMethod( DaoObject *self, DaoObject *othis, DaoProcess *proc,
		DString *name, DaoValue *P[], int N, int ignore_return, int execute )
{
	DaoValue *V = NULL;
	DaoValue *O = (DaoValue*)self;
	int errcode = DaoObject_GetData( self, name, &V, othis );
	if( errcode ) return errcode;
	if( V == NULL || V->type != DAO_ROUTINE ) return DAO_ERROR_TYPE;
	if( DaoProcess_PushCallable( proc, (DaoRoutine*) V, O, P, N ) ) goto InvalidParam;
	if( ignore_return ) DaoProcess_InterceptReturnValue( proc );
	if( execute ) DaoProcess_Execute( proc );
	return 0;
InvalidParam:
	DaoProcess_ShowCallError( proc, (DaoRoutine*)V, O, P, N, DVM_CALL );
	return DAO_ERROR_PARAM;
}
Beispiel #16
0
static void DaoSTD_Exec( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 );
	int ecount = proc->exceptions->size;

	if( sect == NULL ) return;
	DaoProcess_Execute( proc );
	DaoProcess_PopFrame( proc );
	if( proc->exceptions->size > ecount ){
		if( n > 0 ){
			DaoProcess_PutValue( proc, p[0] );
			DList_Erase( proc->exceptions, ecount, -1 );
		}
	}else{
		DaoProcess_PutValue( proc, proc->stackValues[0] );
	}
}
Beispiel #17
0
static void DaoMT_RunMapFunctional( void *p )
{
	DaoValue *res;
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoMap *map = (DaoMap*) self->param;
	DaoList *list2 = (DaoList*) self->result;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoType *type = map->ctype;
	DNode *node = NULL;
	daoint i = 0;

	DaoMT_InitProcess( self->proto, clone, 3 );
	tidint.value = self->first;
	type = type && type->nested->size > 1 ? type->nested->items.pType[1] : NULL;
	for(node=DMap_First( map->value ); node; node=DMap_Next(map->value, node) ){
		if( (i++) % self->step != self->first ) continue;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, node->key.pValue );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, node->value.pValue );
		if( sect->b >2 ) DaoProcess_SetValue( clone, sect->a+2, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			self->status |= DaoList_SetItem( list2, res, i-1 );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			self->status |= DaoValue_Move( res, & node->value.pValue, type ) == 0;
		}else if( self->funct == DVM_FUNCT_FIND ){
			DNode **p = self->node;
			/* XXX: 2014-11-11 */
			if( *p && DaoValue_Compare( (*p)->key.pValue, node->key.pValue ) < 0 ) break;
			if( res->xInteger.value ){
				DMutex_Lock( self->mutex );
				if( *p == NULL || DaoValue_Compare( (*p)->key.pValue, node->key.pValue ) >0 ) *p = node;
				DMutex_Unlock( self->mutex );
				break;
			}
		}
	}
}
Beispiel #18
0
static void FRAME_ScanCells( DaoProcess *proc, DaoValue *p[], int npar )
{
	DaoxDataFrame *self = (DaoxDataFrame*) p[0];
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoInteger integer1 = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger integer2 = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger integer3 = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger *rowidx = & integer1;
	DaoInteger *colidx = & integer2;
	DaoInteger *depidx = & integer3;
	DaoValue value;
	daoint N = self->dims[0];
	daoint M = self->dims[1];
	daoint K = self->dims[2];
	daoint NK = N * K;
	daoint entry, i, j;

	value.xInteger = integer1;
	if( sect == NULL ) return;
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(j=0; j<M; ++j){
		DaoxDataColumn *column = (DaoxDataColumn*) self->columns->items.pVoid[j];
		colidx->value = j;
		for(i=0; i<NK; ++i){
			rowidx->value = i % N;
			depidx->value = i / N;
			if( sect->b >0 ){
				DaoValue *cell = DaoxDataColumn_GetCell( column, i, & value );
				DaoProcess_SetValue( proc, sect->a, cell );
			}
			if( sect->b >1 ) DaoProcess_SetValue( proc, sect->a+1, (DaoValue*) rowidx );
			if( sect->b >2 ) DaoProcess_SetValue( proc, sect->a+2, (DaoValue*) colidx );
			if( sect->b >3 ) DaoProcess_SetValue( proc, sect->a+3, (DaoValue*) depidx );
			proc->topFrame->entry = entry;
			DaoProcess_Execute( proc );
			if( proc->status == DAO_PROCESS_ABORTED ) break;
		}
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
}
Beispiel #19
0
static void DaoIO_ReadLines( DaoProcess *proc, DaoValue *p[], int N )
{
	DString *fname;
	DaoValue *res;
	DaoString *line;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoList *list = DaoProcess_PutList( proc );
	int chop = p[1]->xInteger.value;
	char buf[IO_BUF_SIZE];
	FILE *fin;
	if( proc->vmSpace->options & DAO_OPTION_SAFE ){
		DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" );
		return;
	}
	fin = DaoIO_OpenFile( proc, p[0]->xString.data, "r", 0 );
	if( fin == NULL ) return;
	if( sect == NULL || DaoProcess_PushSectionFrame( proc ) == NULL ){
		line = DaoString_New(1);
		while( DaoFile_ReadLine( fin, line->data ) ){
			if( chop ) DString_Chop( line->data );
			DaoList_Append( list, (DaoValue*) line );
		}
		DaoString_Delete( line );
	}else{
		ushort_t entry = proc->topFrame->entry;
		DaoString tmp = {DAO_STRING,0,0,0,1,NULL};
		tmp.data = p[0]->xString.data;
		line = (DaoString*) DaoProcess_SetValue( proc, sect->a, (DaoValue*)(void*) &tmp );
		DaoProcess_AcquireCV( proc );
		while( DaoFile_ReadLine( fin, line->data ) ){
			if( chop ) DString_Chop( line->data );
			proc->topFrame->entry = entry;
			DaoProcess_Execute( proc );
			if( proc->status == DAO_PROCESS_ABORTED ) break;
			res = proc->stackValues[0];
			if( res && res->type != DAO_NONE ) DaoList_Append( list, res );
		}
		DaoProcess_ReleaseCV( proc );
		DaoProcess_PopFrame( proc );
	}
	fclose( fin );
}
Beispiel #20
0
static void DaoMT_RunListFunctional( void *p )
{
	DaoValue *res;
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoList *list = (DaoList*) self->param;
	DaoList *list2 = (DaoList*) self->result;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoValue **items = list->items.items.pValue;
	daoint i, n = list->items.size;

	DaoMT_InitProcess( self->proto, clone );
	tidint.value = self->first;
	for(i=self->first; i<n; i+=self->step){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, items[i] );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, index );
		if( sect->b >2 ) DaoProcess_SetValue( clone, sect->a+2, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			self->status |= DaoList_SetItem( list2, res, i );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			self->status |= DaoList_SetItem( list, res, i );
		}else if( self->funct == DVM_FUNCT_FIND ){
			if( *self->index >= 0 && *self->index < i ) break;
			if( res->xInteger.value ){
				DMutex_Lock( self->mutex );
				if( *self->index < 0 || i < *self->index ) *self->index = i;
				DMutex_Unlock( self->mutex );
				break;
			}
		}
	}
}
Beispiel #21
0
static void DaoSTD_Try( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 );
	int i, ecount = proc->exceptions->size;

	if( sect == NULL ) return;
	DaoProcess_Execute( proc );
	DaoProcess_PopFrame( proc );
	if( proc->exceptions->size > (ecount+1) ){
		DaoList *list = DaoProcess_PutList( proc );
		for(i=ecount; i<proc->exceptions->size; ++i){
			DaoList_Append( list, proc->exceptions->items.pValue[i] );
		}
		DList_Erase( proc->exceptions, ecount, -1 );
	}else if( proc->exceptions->size > ecount ){
		DaoProcess_PutValue( proc, proc->exceptions->items.pValue[proc->exceptions->size-1] );
		DList_PopBack( proc->exceptions );
	}else{
		DaoProcess_PutValue( proc, proc->stackValues[0] );
	}
}
Beispiel #22
0
static void STD_Iterate( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	daoint i, entry, times = p[0]->xInteger.value;

	if( sect == NULL || times < 0 ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=0; i<times; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
}
Beispiel #23
0
static void DaoMT_RunIterateFunctional( void *p )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	daoint i, n = self->param->xInteger.value;

	DaoMT_InitProcess( self->proto, clone );
	tidint.value = self->first;
	for(i=self->first; i<n; i+=self->step){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, index );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
	}
}
Beispiel #24
0
static void GRAPH_FindEdges( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxGraph *self = (DaoxGraph*) p[0];
	DaoList *list = DaoProcess_PutList( proc );
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 );
	daoint which = p[1]->xEnum.value;
	daoint i, j, entry;

	if( sect == NULL ) return;
	entry = proc->topFrame->entry;
	for(i=0; i<self->edges->size; i++){
		DaoxEdge *edge = (DaoxEdge*) self->edges->items.pVoid[i];
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, (DaoValue*) edge );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		if( proc->stackValues[0]->xInteger.value ){
			DaoList_PushBack( list, (DaoValue*) edge );
			if( which == 0 ) break;
		}
	}
	DaoProcess_PopFrame( proc );
}
Beispiel #25
0
static void DaoIO_ReadLines2( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoValue *res;
	DaoString *line;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoList *list = DaoProcess_PutList( proc );
	DaoStream *self = & p[0]->xStream;
	daoint i = 0, count = p[1]->xInteger.value;
	int chop = p[2]->xInteger.value;

	if( sect == NULL || DaoProcess_PushSectionFrame( proc ) == NULL ){
		line = DaoString_New(1);
		while( (i++) < count && DaoStream_ReadLine( self, line->data ) ){
			if( chop ) DString_Chop( line->data );
			DaoList_Append( list, (DaoValue*) line );
		}
		DaoString_Delete( line );
	}else{
		ushort_t entry = proc->topFrame->entry;
		DaoString tmp = {DAO_STRING,0,0,0,1,NULL};
		DString tmp2 = DString_WrapMBS( "" );
		tmp.data = & tmp2;
		line = (DaoString*) DaoProcess_SetValue( proc, sect->a, (DaoValue*)(void*) &tmp );
		DaoProcess_AcquireCV( proc );
		while( (i++) < count && DaoStream_ReadLine( self, line->data ) ){
			if( chop ) DString_Chop( line->data );
			proc->topFrame->entry = entry;
			DaoProcess_Execute( proc );
			if( proc->status == DAO_PROCESS_ABORTED ) break;
			res = proc->stackValues[0];
			if( res && res->type != DAO_NONE ) DaoList_Append( list, res );
		}
		DaoProcess_ReleaseCV( proc );
		DaoProcess_PopFrame( proc );
	}
}
Beispiel #26
0
static void STD_String( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DString *string = DaoProcess_PutMBString( proc, "" );
	daoint i, entry, size = p[0]->xInteger.value;

	if( p[1]->xEnum.value ) DString_ToWCS( string );
	if( sect == NULL || size < 0 ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=0; i<size; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		DString_AppendWChar( string, proc->stackValues[0]->xInteger.value );
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
}
Beispiel #27
0
void DaoCallServer_AddCall( DaoProcess *caller )
{
	DaoFuture *future;
	DaoTaskEvent *event;
	DaoProcess *callee = DaoVmSpace_AcquireProcess( caller->vmSpace );
	DaoStackFrame *frame = caller->topFrame;
	DaoRoutine *routine = frame->routine;
	DaoType *type = (DaoType*) routine->routType->aux;
	DaoValue **params = caller->stackValues + caller->topFrame->stackBase;
	int i, count = caller->topFrame->parCount;

	if( caller->activeCode->b & DAO_CALL_BLOCK ){
		DaoValue **calleeValues, **callerValues = caller->activeValues;
		DaoStackFrame *sectFrame = DaoProcess_FindSectionFrame( caller );
		DaoStackFrame *callerFrame = caller->topFrame->prev;
		DaoVmCode *vmc, *end, *sect;
		if( sectFrame != callerFrame ){
			DaoVmSpace_ReleaseProcess( caller->vmSpace, callee );
			DaoProcess_RaiseError( caller, NULL, "Invalid code section" );
			return;
		}
		if( routine->body ){
			DaoProcess_PushRoutine( callee, callerFrame->routine, callerFrame->object );
			callerValues = caller->stackValues + callerFrame->stackBase;
		}else{
			DaoProcess_PushRoutine( callee, caller->activeRoutine, caller->activeObject );
		}
		DaoProcess_SetActiveFrame( callee, callee->topFrame );
		calleeValues = callee->stackValues + callee->topFrame->stackBase;
		callee->activeCode = caller->activeCode;
		vmc = callerFrame->routine->body->vmCodes->data.codes + callerFrame->entry;
		end = callerFrame->routine->body->vmCodes->data.codes + vmc->b;
		sect = vmc + 1;
		for(vmc=sect; vmc!=end; vmc++){
			int i = -1, code = vmc->code;
			if( code == DVM_GETVH || (code >= DVM_GETVH_I && code <= DVM_GETVH_C) ){
				i = vmc->b;
			}else if( code == DVM_SETVH || (code >= DVM_SETVH_II && code <= DVM_SETVH_CC) ){
				i = vmc->b;
			}
			if( i >= 0 ) DaoValue_Move( callerValues[i], & calleeValues[i], NULL );
		}
	}

	future = DaoFuture_New( type, 1 );
	future->state = DAO_CALL_PAUSED;
	future->actor = caller->topFrame->object;
	GC_IncRC( future->actor );

	GC_Assign( & future->process, callee );
 	GC_Assign( & callee->future, future );

	callee->parCount = count;
	/* Use routine->parCount instead of caller->topFrame->parCount, for default parameters: */
	for(i=0; i<routine->parCount; ++i) DaoValue_Copy( params[i], & callee->paramValues[i] );
	if( routine->body ){
		DaoProcess_PushRoutine( callee, routine, future->actor );
	}else{
		DaoProcess_PushFunction( callee, routine );
		callee->activeNamespace = caller->activeNamespace;
	}
	if( caller->activeCode->b & DAO_CALL_BLOCK ){
		callee->topFrame->host = callee->topFrame;
		callee->topFrame->retmode = DVM_RET_PROCESS;
		callee->topFrame->returning = 0;
	}

#ifdef DAO_WITH_CONCURRENT
	DaoCallServer_TryInit( mainVmSpace );
	event = DaoCallServer_MakeEvent();
	DaoTaskEvent_Init( event, DAO_EVENT_RESUME_TASKLET, DAO_EVENT_RESUME, future, NULL );

	DaoProcess_PopFrame( caller );
	DaoProcess_PutValue( caller, (DaoValue*) future );

	DaoCallServer_Add( event );
#else
	DaoProcess_PopFrame( caller );
	DaoProcess_PutValue( caller, (DaoValue*) future );
	DaoProcess_InterceptReturnValue( callee );
	DaoProcess_Execute( callee );
	DaoProcess_ReturnFutureValue( callee, future );
	DaoVmSpace_ReleaseProcess( caller->vmSpace, callee );
#endif
}
Beispiel #28
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 );
	while(1){
		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;
		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->finishing && server->idle == server->total ){
				if( (server->events2->size + server->waitings->size) == 0 ) break;
			}
			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 );
			function = (DThreadTask) server->functions->items.pVoid[i];
			parameter = param;
			DArray_Erase( server->functions, i, 1 );
			DArray_Erase( server->parameters, i, 1 );
			DMap_Erase( server->pending, parameter );
			server->idle -= 1;
			break;
		}
		DMutex_Unlock( & server->mutex );

		if( function ){
			(*function)( parameter );
			DMutex_Lock( & server->mutex );
			DMap_Erase( server->active, parameter );
			DMutex_Unlock( & server->mutex );
			continue;
		}

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

		DMutex_Lock( & server->mutex );
		server->idle -= 1;
		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_Execute( process );
		if( process->exceptions->size > count ) DaoProcess_PrintException( process, 1 );

		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 );
}
Beispiel #29
0
static void STD_Array( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *res, *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoArray *array = DaoProcess_PutArray( proc );
	DaoArray *first = NULL;
	DaoArray *sub = NULL;
	daoint i, j, k, entry, size = 1;

	/* if multi-dimensional array is disabled, DaoProcess_PutArray() will raise exception. */
#ifdef DAO_WITH_NUMARRAY
	for(i=0; i<N; i++){
		daoint d = p[i]->xInteger.value;
		if( d < 0 ){
			DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, NULL );
			break;
		}
		size *= d;
	}
	if( size == 0 ) return;
	if( sect == NULL ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=0; i<size; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		res = proc->stackValues[0];
		if( i == 0 ){
			int D = N;
			DaoArray_SetDimCount( array, N + (res->type == DAO_ARRAY ? res->xArray.ndim : 0) );
			for(j=0; j<N; j++) array->dims[j] = p[j]->xInteger.value;
			if( res->type == DAO_ARRAY ){
				first = DaoArray_Copy( (DaoArray*) res );
				if( first->ndim == 2 && (first->dims[0] == 1 || first->dims[1] == 1) ){
					D += 1;
					array->dims[N] = first->dims[ first->dims[0] == 1 ];
				}else{
					D += first->ndim;
					memmove( array->dims + N, first->dims, first->ndim*sizeof(daoint) );
				}
			}
			DaoArray_ResizeArray( array, array->dims, D );
		}
		if( res->type == DAO_ARRAY ){
			sub = (DaoArray*) res;
			if( first == NULL || DaoArray_AlignShape( sub, NULL, first->dims, first->ndim ) ==0 ){
				DaoProcess_RaiseException( proc, DAO_ERROR, "inconsistent elements or subarrays" );
				break;
			}
			k = i * sub->size;
			for(j=0; j<sub->size; j++){
				switch( array->etype ){
				case DAO_INTEGER : array->data.i[k+j] = DaoArray_GetInteger( sub, j ); break;
				case DAO_FLOAT   : array->data.f[k+j] = DaoArray_GetFloat( sub, j ); break;
				case DAO_DOUBLE  : array->data.d[k+j] = DaoArray_GetDouble( sub, j ); break;
				case DAO_COMPLEX : array->data.c[k+j] = DaoArray_GetComplex( sub, j ); break;
				}
			}
		}else{
			switch( array->etype ){
			case DAO_INTEGER : array->data.i[i] = DaoValue_GetInteger( res ); break;
			case DAO_FLOAT   : array->data.f[i] = DaoValue_GetFloat( res ); break;
			case DAO_DOUBLE  : array->data.d[i] = DaoValue_GetDouble( res ); break;
			case DAO_COMPLEX : array->data.c[i] = DaoValue_GetComplex( res ); break;
			}
		}
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
	if( first ) DaoArray_Delete( first );
#endif
}