Пример #1
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_PutBoolean( 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 );
	DaoChannel_Send( self, data );

	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 );
	}
}
Пример #2
0
static void DaoIO_Read( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoStream *self = proc->stdioStream;
	DString *ds = DaoProcess_PutChars( proc, "" );
	int ch, size, amount = -1; /* amount=-2: all; amount=-1: line; amount>=0: bytes; */
	char buf[IO_BUF_SIZE];

	if( self == NULL ) self = proc->vmSpace->stdioStream;
	if( N > 0 ){
		self = (DaoStream*) p[0];
		amount = -2;
	}
	if( DaoIO_CheckMode( self, proc, DAO_STREAM_READABLE ) == 0 ) return;
	if( N > 1 ){
		if( p[1]->type == DAO_INTEGER ){
			amount = p[1]->xInteger.value;
			if( amount < 0 ){
				DaoProcess_RaiseError( proc, NULL, "cannot read negative amount!" );
				return;
			}
		}else{
			amount = - 1 - p[1]->xEnum.value;
		}
	}
	DString_Reset( ds, 0 );
	self->Read( self, ds, amount );
	if( self->mode & DAO_STREAM_AUTOCONV ) DString_ToUTF8( ds );
}
Пример #3
0
static void TEST_Assert( DaoProcess *proc, DaoValue* p[], int N )
{
	if ( !p[0]->xBoolean.value ){
		DString *msg = p[1]->xString.value;
		DaoProcess_RaiseError( proc, "Test::Assert", msg->size? msg->chars : "assertion failed" );
	}
}
Пример #4
0
static void CHANNEL_SetCap( DaoChannel *self, DaoValue *value, DaoProcess *proc )
{
	self->cap = value->xInteger.value;
	if( self->cap > 0 ) return;
	self->cap = 1;
	DaoProcess_RaiseError( proc, "Param", "channel capacity must be greater than 0" );
}
Пример #5
0
static int DaoObject_DoSetField( DaoValue *self, DaoString *name, DaoValue *value, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoObject *host = proc->activeObject;
	DaoClass *hostClass = host ? host->defClass : NULL;
	int ec = DaoObject_SetData( object, name->value, value, host );
	if( ec != DAO_OK ){
		DString *field = proc->string;
		DaoRoutine *rout;

		DString_SetChars( field, "." );
		DString_Append( field, name->value );
		DString_AppendChars( field, "=" );
		rout = DaoClass_FindMethod( object->defClass, field->chars, hostClass );
		if( rout != NULL ){
			ec = DaoProcess_PushCall( proc, rout, self, & value, 1 );
		}else{
			DaoValue *args[2];
			args[0] = (DaoValue*) name;
			args[1] = value;
			rout = DaoClass_FindMethod( object->defClass, ".=", hostClass );
			if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT;
			ec = DaoProcess_PushCall( proc, rout, self, args, 2 );
		}
		if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT;
	}
	if( ec ) DaoProcess_RaiseError( proc, daoExceptionNames[ec], name->value->chars );
	return ec;
}
Пример #6
0
static DaoValue* DaoObject_DoGetField( DaoValue *self, DaoString *name, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoObject *host = proc->activeObject;
	DaoClass *hostClass = host ? host->defClass : NULL;
	DaoValue *value = NULL;
	int rc = DaoObject_GetData( object, name->value, & value, host );
	if( rc ){
		DaoRoutine *rout;
		DString *field = proc->string;

		DString_SetChars( field, "." );
		DString_Append( field, name->value );
		rout = DaoClass_FindMethod( object->defClass, field->chars, hostClass );
		if( rout != NULL ){
			rc = DaoProcess_PushCall( proc, rout, self, NULL, 0 );
		}else{
			DaoValue *arg = (DaoValue*) name;
			rout = DaoClass_FindMethod( object->defClass, ".", hostClass );
			if( rout != NULL ) rc = DaoProcess_PushCall( proc, rout, self, & arg, 1 );
		}
		if( rout == NULL ) return NULL;
	}else{
		DaoProcess_PutValue( proc, value );
	}
	if( rc ) DaoProcess_RaiseError( proc, daoExceptionNames[rc], name->value->chars );
	return NULL;
}
Пример #7
0
int DaoProcess_Resume( DaoProcess *self, DaoValue *par[], int N, DaoProcess *ret )
{
	DaoType *tp;
	DaoVmCode *vmc;
	DaoTuple *tuple;
	if( self->status != DAO_PROCESS_SUSPENDED ) return 0;
	if( self->activeCode && self->activeCode->code == DVM_MCALL ){
		tp = self->activeTypes[ self->activeCode->c ];
		if( N == 1 ){
			DaoProcess_PutValue( self, par[0] );
		}else if( N ){ /* TODO */
			tuple = DaoTuple_New( N );
			tuple->ctype = tp;
			GC_IncRC( tuple->ctype );
			DaoProcess_MakeTuple( self, tuple, par, N );
			DaoProcess_PutValue( self, (DaoValue*) tuple );
		}
	}else if( N ){ /* TODO */
		DaoRoutine *rout = self->topFrame->routine;
		self->paramValues = self->stackValues + self->topFrame->stackBase;
		if( rout ) rout = DaoProcess_PassParams( self, rout, NULL, NULL, par, NULL, N, DVM_CALL );
		self->paramValues = self->stackValues + 1;
		if( rout == NULL ){
			DaoProcess_RaiseError( ret, NULL, "invalid parameters." );
			return 0;
		}
	}
	DaoProcess_Start( self );
	DaoProcess_PutValue( ret, self->stackValues[0] );
	return 1;
}
Пример #8
0
void DaoMT_Select( DaoProcess *proc, DaoValue *par[], int n )
{
	DNode *it;
	DaoTaskEvent *event = NULL;
	DaoFuture *future = DaoProcess_GetInitFuture( proc );
	DaoMap *selects = (DaoMap*) par[0];
	float timeout = par[1]->xFloat.value;

	for(it=DaoMap_First(selects); it; it=DaoMap_Next(selects,it)){
		DaoValue *value = it->key.pValue;
		int isfut = DaoValue_CheckCtype( value, dao_type_future );
		int ischan = DaoValue_CheckCtype( value, dao_type_channel );
		if( isfut == 0 && ischan == 0 ){
			DaoProcess_RaiseError( proc, "Param", "invalid type selection" );
			return;
		}
	}

	event = DaoCallServer_MakeEvent();
	DaoTaskEvent_Init( event, DAO_EVENT_WAIT_SELECT, DAO_EVENT_WAIT, future, NULL );
	GC_Assign( & event->selects, selects );
	proc->status = DAO_PROCESS_SUSPENDED;
	proc->pauseType = DAO_PAUSE_CHANFUT_SELECT;
	DaoCallServer_AddTimedWait( proc, event, timeout );

	/* Message may have been sent before this call: */
	DMutex_Lock( & daoCallServer->mutex );
	DaoChannel_ActivateEvent( NULL, DAO_EVENT_WAIT_SELECT );
	DCondVar_Signal( & daoCallServer->condv );
	DMutex_Unlock( & daoCallServer->mutex );
}
Пример #9
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 );
	}
}
Пример #10
0
static void TEST_Run( DaoProcess *proc, DaoValue* p[], int N )
{
	DString *prefix = p[0]->xString.value;
	DList *funcs = proc->activeNamespace->definedRoutines;
	DaoStream *out = DaoVmSpace_StdioStream( proc->vmSpace );
	daoint i;
	char buf[100];
	for ( i = 0; i < funcs->size; ++i ){
		DaoRoutine *rout = funcs->items.pRoutine[i];
		// find global routines matching prefix
		if ( strncmp( rout->routName->chars, prefix->chars, prefix->size ) == 0 ){
			// ignore 'main()'
			if ( strcmp( rout->routName->chars, "main" ) == 0 )
				continue;
			// run
			if ( !( rout->attribs & DAO_ROUT_DECORATOR ) && rout->parCount == 0 ){
				if ( DaoProcess_Call( proc, rout, NULL, NULL, 0 ) == DAO_ERROR ){ // failed
					char buf[512];
					snprintf( buf, sizeof(buf), "unexpected error running '%s'", rout->routName->chars );
					DaoProcess_RaiseError( proc, "Error::Test", buf );
					return;
				}
			}
		}
	}
	DMutex_Lock( &test_mtx );
	snprintf( buf, sizeof(buf), "Summary: %i tests, %i passed, %i failed, %i skipped\n", test_count, pass_count, fail_count, skip_count );
	DaoStream_WriteChars( out, buf );
	test_count = pass_count = fail_count = skip_count = 0;
	DMutex_Unlock( &test_mtx );
}
Пример #11
0
static void DaoIO_Open( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoFileStream *self = NULL;
	char *mode;
	self = DaoFileStream_New();
	DaoProcess_PutValue( proc, (DaoValue*)self );
	if( N == 0 ){
		do
			self->file = tmpfile();
		while ( !self->file && errno == EINTR );
		self->base.Read = DaoFileStream_Read;
		self->base.Write = DaoFileStream_Write;
		self->base.AtEnd = DaoFileStream_AtEnd;
		self->base.Flush = DaoFileStream_Flush;
		self->base.mode |= DAO_STREAM_WRITABLE | DAO_STREAM_READABLE;
		if( !self->file ){
			char errbuf[512];
			GetErrorMessage( errno, errbuf, sizeof(errbuf) );
			DaoProcess_RaiseError( proc, "Stream", errbuf );
			return;
		}
	}else{
		mode = DString_GetData( p[1]->xString.value );
		if( p[0]->type == DAO_INTEGER ){
			self->file = fdopen( p[0]->xInteger.value, mode );
			if( self->file == NULL ){
				char errbuf[512];
				GetErrorMessage( errno, errbuf, sizeof(errbuf) );
				DaoProcess_RaiseError( proc, "Stream", errbuf );
				return;
			}
		}else{
			self->file = DaoIO_OpenFile( proc, p[0]->xString.value, mode, 0 );
		}
		if( strstr( mode, "+" ) ){
			self->base.mode |= DAO_STREAM_WRITABLE | DAO_STREAM_READABLE;
		}else{
			if( strstr( mode, "r" ) ){
				self->base.mode |= DAO_STREAM_READABLE;
			}
			if( strstr( mode, "w" ) || strstr( mode, "a" ) ){
				self->base.mode |= DAO_STREAM_WRITABLE;
			}
		}
		DaoFileStream_InitCallbacks( self );
	}
}
Пример #12
0
static void DaoxUserType_SetItem( DaoValue *self, DaoProcess *proc, DaoValue *ids[], int N, DaoValue *value )
{
	switch( N ){
	case 0 : DaoxUserType_SetItem1( self, proc, dao_none_value, value ); break;
	case 1 : DaoxUserType_SetItem1( self, proc, ids[0], value ); break;
	default : DaoProcess_RaiseError( proc, "Index", "not supported" );
	}
}
Пример #13
0
static DaoValue* DaoObject_DoGetItem( DaoValue *self, DaoValue *index[], int N, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoRoutine *rout = DaoClass_FindMethod( object->defClass, "[]", host );
	int rc = DaoProcess_PushCall( proc, rout, self, index, N );
	if( rc ) DaoProcess_RaiseError( proc, daoExceptionNames[rc], NULL );
	return NULL;
}
Пример #14
0
static void PIPE_Close( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoPipeStream *stream = (DaoPipeStream*) p[0];
	if ( stream->file ){
		DaoProcess_PutInteger( proc, DaoPipeStream_Close( stream ) );
	} else {
		DaoProcess_RaiseError( proc, "Param", "Stream not open" );
	}
}
Пример #15
0
static int DaoIO_CheckMode( DaoStream *self, DaoProcess *proc, int what )
{
	if( DaoStream_IsOpen( self ) == 0 ){
		DaoProcess_RaiseError( proc, NULL, "stream is not open!" );
		return 0;
	}
	if( what == DAO_STREAM_READABLE && DaoStream_EndOfStream( self ) == 1 ){
		DaoProcess_RaiseError( proc, NULL, "stream reached the end!" );
		return 0;
	}
	if( what == DAO_STREAM_READABLE && DaoStream_IsReadable( self ) == 0 ){
		DaoProcess_RaiseError( proc, NULL, "stream is not readable!" );
		return 0;
	}
	if( what == DAO_STREAM_WRITABLE && DaoStream_IsWritable( self ) == 0 ){
		DaoProcess_RaiseError( proc, NULL, "stream is not writable!" );
		return 0;
	}
	return 1;
}
Пример #16
0
static void COROUT_Resume( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxCoroutine *self = (DaoxCoroutine*) p[0];
	DaoProcess *sp = self->process;
	if( self->process == proc ){
		DaoProcess_RaiseError( proc, NULL, "coroutine can only resume in alien process." );
		return;
	}
	if( sp->status != DAO_PROCESS_SUSPENDED || sp->pauseType != DAO_PAUSE_COROUTINE_YIELD ){
		DaoProcess_RaiseError( proc, NULL, "coroutine cannot be resumed." );
		return;
	}
	DaoProcess_Resume( self->process, p+1, N-1, proc );
	if( sp->status == DAO_PROCESS_SUSPENDED && sp->pauseType != DAO_PAUSE_COROUTINE_YIELD ){
		DaoProcess_RaiseError( proc, NULL, "coroutine is not suspended properly." );
		return;
	}
	if( self->process->status == DAO_PROCESS_ABORTED )
		DaoProcess_RaiseError( proc, NULL, "coroutine execution is aborted." );
}
Пример #17
0
static void COROUT_Suspend( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxCoroutine *self = (DaoxCoroutine*) p[0];
	DaoValue *value = N > 1 ? p[1] : DaoValue_MakeNone();
	if( self->process != proc ){
		DaoProcess_RaiseError( proc, NULL, "coroutine cannot suspend in alien process." );
		return;
	}
	GC_Assign( & proc->stackValues[0], value );
	proc->status = DAO_PROCESS_SUSPENDED;
	proc->pauseType = DAO_PAUSE_COROUTINE_YIELD;
}
Пример #18
0
static void COROUT_Start( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoxCoroutine *self = (DaoxCoroutine*) par[0];
	DaoValue *params[DAO_MAX_PARAM];
	DaoValue *val = par[1];
	DaoProcess *vmProc;
	DaoRoutine *rout;
	int i, passed = 0;
	if( val == NULL || val->type != DAO_ROUTINE ){
		DaoProcess_RaiseError( proc, "Type", NULL );
		return;
	}
	params[0] = par[0];
	memcpy( params + 1, par + 2, (N-2)*sizeof(DaoValue*) );
	rout = DaoRoutine_Resolve( (DaoRoutine*)val, NULL, NULL, params, NULL, N-1, DVM_CALL );
	if( rout ) rout = DaoProcess_PassParams( proc, rout, NULL, NULL, params, NULL, N-1, DVM_CALL );
	if( rout == NULL || rout->body == NULL ){
		DaoProcess_RaiseError( proc, "Param", "not matched" );
		return;
	}
	if( self->process == NULL ){
		self->process = DaoProcess_New( proc->vmSpace );
		GC_IncRC( self->process );
	}
	vmProc = self->process;
	DaoProcess_PushRoutine( vmProc, rout, NULL );
	vmProc->activeValues = vmProc->stackValues + vmProc->topFrame->stackBase;
	for(i=0; i<rout->parCount; i++){
		vmProc->activeValues[i] = proc->paramValues[i];
		GC_IncRC( vmProc->activeValues[i] );
	}
	vmProc->status = DAO_PROCESS_SUSPENDED;
	vmProc->pauseType = DAO_PAUSE_COROUTINE_YIELD;
	DaoProcess_Start( vmProc );
	DaoProcess_PutValue( proc, vmProc->stackValues[0] );
	if( vmProc->status == DAO_PROCESS_ABORTED )
		DaoProcess_RaiseError( proc, NULL, "coroutine execution is aborted." );
}
Пример #19
0
static void FUTURE_Wait( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoFuture *self = (DaoFuture*) par[0];
	float timeout = par[1]->xFloat.value;
	DaoProcess_PutBoolean( proc, self->state == DAO_CALL_FINISHED );
	if( self->state == DAO_CALL_FINISHED || timeout == 0 ) return;
#ifdef DAO_WITH_CONCURRENT
	proc->status = DAO_PROCESS_SUSPENDED;
	proc->pauseType = DAO_PAUSE_FUTURE_WAIT;
	DaoCallServer_AddWait( proc, self, timeout );
#else
	DaoProcess_RaiseError( proc, NULL, "Invalid future value" );
#endif
}
Пример #20
0
static void DaoSTD_Resource( DaoProcess *proc, DaoValue *p[], int N )
{
	FILE *fin;
	DString *file = DString_Copy( p[0]->xString.value );
	if( DaoVmSpace_SearchResource( proc->vmSpace, file, proc->activeNamespace->path ) == 0 ){
		DString_InsertChars( file, "resource file not found: ", 0, 0, -1 );
		DaoProcess_RaiseError( proc, NULL, file->chars );
		DString_Delete( file );
		return;
	}
	DaoVmSpace_ReadFile( proc->vmSpace, file, file );
	DaoProcess_PutString( proc, file );
	DString_Delete( file );
}
Пример #21
0
static void PIPE_New( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoPipeStream *stream = NULL;
	DString *fname = p[0]->xString.value;
	char *mode;

	stream = DaoPipeStream_New();
	DaoProcess_PutValue( proc, (DaoValue*)stream );
	if( DString_Size( fname ) == 0 ){
		DaoProcess_RaiseError( proc, "Param", "Empty command" );
		return;
	}
	mode = DString_GetData( p[1]->xString.value );
	stream->file = popen( DString_GetData( fname ), mode );
	if( stream->file == NULL ){
		char errbuf[512];
		GetErrorMessage( errno, errbuf, sizeof(errbuf) );
		DaoProcess_RaiseError( proc, "Stream", errbuf );
		return;
	}
	if( strstr( mode, "r" ) ) stream->base.mode |= DAO_STREAM_READABLE;
	if( strstr( mode, "w" ) ) stream->base.mode |= DAO_STREAM_WRITABLE;
	DaoFileStream_InitCallbacks( stream );
}
Пример #22
0
static void FUTURE_Value( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoFuture *self = (DaoFuture*) par[0];
	if( self->state == DAO_CALL_FINISHED ){
		DaoProcess_PutValue( proc, self->value );
		return;
	}
#ifdef DAO_WITH_CONCURRENT
	proc->status = DAO_PROCESS_SUSPENDED;
	proc->pauseType = DAO_PAUSE_FUTURE_VALUE;
	DaoCallServer_AddWait( proc, self, -1 );
#else
	DaoProcess_RaiseError( proc, NULL, "Invalid future value" );
#endif
}
Пример #23
0
static FILE* DaoIO_OpenFile( DaoProcess *proc, DString *name, const char *mode, int silent )
{
	DString *fname = DString_Copy( name );
	char buf[200];
	FILE *fin;

	DaoIO_MakePath( proc, fname );
	fin = Dao_OpenFile( fname->chars, mode );
	DString_Delete( fname );
	if( fin == NULL && silent == 0 ){
		snprintf( buf, sizeof(buf), "error opening file: %s", DString_GetData( name ) );
		DaoProcess_RaiseError( proc, "Stream", buf );
		return NULL;
	}
	return fin;
}
Пример #24
0
static void CHANNEL_New( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoType *retype = DaoProcess_GetReturnType( proc );
	DaoChannel *self = DaoChannel_New( retype, 0 );
	CHANNEL_SetCap( self, par[0], proc );
	if( DaoType_CheckPrimitiveType( retype->nested->items.pType[0] ) == 0 ){
		DString *s = DString_New();
		DString_AppendChars( s, "data type " );
		DString_Append( s, retype->nested->items.pType[0]->name );
		DString_AppendChars( s, " is not supported for channel" );
		DaoProcess_RaiseError( proc, NULL, s->chars );
		DString_Delete( s );
	}
	DaoProcess_PutValue( proc, (DaoValue*) self );
	DaoCallServer_TryInit( mainVmSpace );
}
Пример #25
0
static void DaoSTD_Load( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoNamespace *ns;
	DaoVmSpace *vms = proc->vmSpace;
	DString *name = p[0]->xString.value;
	int import = p[1]->xInteger.value;
	int runim = p[2]->xInteger.value;
	int res = 0;

	DList_PushFront( vms->pathLoading, proc->activeNamespace->path );
	ns = DaoVmSpace_LoadEx( vms, DString_GetData( name ), runim );
	DaoProcess_PutValue( proc, (DaoValue*) ns );
	if( ns == NULL ) DaoProcess_RaiseError( proc, NULL, "loading failed" );
	DList_PopFront( vms->pathLoading );
	if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns );
}
Пример #26
0
static void WIN_New( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxWindow *self = DaoxWindow_New();
	DString_Assign( self->title, p[2]->xString.value );
	self->width  = self->context->deviceWidth  = p[0]->xInteger.value;
	self->height = self->context->deviceHeight = p[1]->xInteger.value;
	self->handle = glfwCreateWindow( self->width, self->height, self->title->chars, NULL, NULL);
	if( self->handle == NULL ){
		DaoProcess_RaiseError( proc, NULL, "Failed to create window" );
		return;
	}
	glfwSetWindowUserPointer( self->handle, self );
	glfwSetWindowCloseCallback( self->handle, DaoxWindow_CloseCallback );
	glfwHideWindow( self->handle );
	glfwMakeContextCurrent( self->handle );
	DaoProcess_PutValue( proc, (DaoValue*) self );
}
Пример #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
}
Пример #28
0
int DaoxGraphData_IsAssociated( DaoxGraphData *self, DaoxGraph *graph, DaoProcess *proc )
{
	if( self->graph == graph ) return 1;
	DaoProcess_RaiseError( proc, NULL, "graph is not associated with the algorithm data!" );
	return 0;
}
Пример #29
0
static void TEST_SkipTest( DaoProcess *proc, DaoValue* p[], int N )
{
	DaoProcess_RaiseError( proc, "Test::Skip", p[0]->xString.value->chars );
}
Пример #30
0
static void DaoMT_Functional( DaoProcess *proc, DaoValue *P[], int N, int F )
{
	DMutex mutex;
	DCondVar condv;
	DaoTaskData *tasks;
	DaoValue *param = P[0];
	DaoValue *result = NULL;
	DaoList *list = NULL;
	DaoArray *array = NULL;
	DaoVmCode *sect = NULL;
	DaoStackFrame *frame = DaoProcess_FindSectionFrame( proc );
	int i, entry, threads = P[1]->xInteger.value;
	daoint index = -1, status = 0, joined = 0;
	DNode *node = NULL;

	switch( F ){
	case DVM_FUNCT_MAP :
		if( param->type == DAO_ARRAY ){
			array = DaoProcess_PutArray( proc );
			result = (DaoValue*) array;
		}else{
			list = DaoProcess_PutList( proc );
			result = (DaoValue*) list;
		}
		break;
	case DVM_FUNCT_FIND : DaoProcess_PutValue( proc, dao_none_value ); break;
	}
	if( threads <= 0 ) threads = 2;
	if( frame != proc->topFrame->prev ){
		DaoProcess_RaiseError( proc, NULL, "Invalid code section from non-immediate caller" );
		return;
	}
	sect = DaoProcess_InitCodeSection( proc, 0 );
	if( sect == NULL ) return;
	if( list ){
		DList_Clear( list->value );
		if( param->type == DAO_LIST ) DList_Resize( list->value, param->xList.value->size, NULL );
		if( param->type == DAO_MAP ) DList_Resize( list->value, param->xMap.value->size, NULL );
#ifdef DAO_WITH_NUMARRAY
	}else if( array && F == DVM_FUNCT_MAP ){
		DaoArray_GetSliceShape( (DaoArray*) param, & array->dims, & array->ndim );
		DaoArray_ResizeArray( array, array->dims, array->ndim );
#endif
	}

	DMutex_Init( & mutex );
	DCondVar_Init( & condv );
	entry = proc->topFrame->entry;
	tasks = (DaoTaskData*) dao_calloc( threads, sizeof(DaoTaskData) );
	DaoProcess_PopFrame( proc );
	for(i=0; i<threads; i++){
		DaoTaskData *task = tasks + i;
		task->param = param;
		task->result = result;
		task->proto = proc;
		task->sect = sect;
		task->funct = F;
		task->entry = entry;
		task->first = i;
		task->step = threads;
		task->index = & index;
		task->node = & node;
		task->joined = & joined;
		task->condv = & condv;
		task->mutex = & mutex;
		task->clone = DaoVmSpace_AcquireProcess( proc->vmSpace );
		if( i ) DaoCallServer_AddTask( DaoMT_RunFunctional, task, task->clone );
	}
	DaoMT_RunFunctional( tasks );

	DMutex_Lock( & mutex );
	while( joined < threads ) DCondVar_TimedWait( & condv, & mutex, 0.01 );
	DMutex_Unlock( & mutex );

	for(i=0; i<threads; i++){
		DaoTaskData *task = tasks + i;
		DaoVmSpace_ReleaseProcess( proc->vmSpace, task->clone );
		status |= task->status;
	}
	if( F == DVM_FUNCT_FIND ){
		DaoTuple *tuple = DaoProcess_PutTuple( proc, 2 );
		if( param->type == DAO_LIST && index != -1 ){
			DaoValue **items = param->xList.value->items.pValue;
			GC_Assign( & tuple->values[1], items[index] );
			tuple->values[0]->xInteger.value = index;
		}else if( param->type == DAO_MAP && node ){
			GC_Assign( & tuple->values[0], node->key.pValue );
			GC_Assign( & tuple->values[1], node->value.pValue );
		}
	}
	if( status ) DaoProcess_RaiseError( proc, NULL, "code section execution failed!" );
	DMutex_Destroy( & mutex );
	DCondVar_Destroy( & condv );
	dao_free( tasks );
}