static void SYS_Popen( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; DString *fname; stream = DaoStream_New(); stream->attribs |= DAO_IO_PIPE; fname = stream->fname; DString_Assign( fname, p[0]->xString.data ); if( DString_Size( fname ) >0 ){ mode = DString_GetMBS( p[1]->xString.data ); stream->file = popen( DString_GetMBS( fname ), mode ); if( stream->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "error opening pipe" ); } stream->mode = 0; if( strstr( mode, "+" ) ) stream->mode = DAO_IO_WRITE | DAO_IO_READ; else{ if( strstr( mode, "r" ) ) stream->mode |= DAO_IO_READ; if( strstr( mode, "w" ) || strstr( mode, "a" ) ) stream->mode |= DAO_IO_WRITE; } }else{ DaoProcess_RaiseException( proc, DAO_ERROR, "empty command line" ); } DaoProcess_PutValue( proc, (DaoValue*)stream ); }
static void STD_Load( DaoProcess *proc, DaoValue *p[], int N ) { DString *name = p[0]->xString.data; int import = p[1]->xInteger.value; int runim = p[2]->xInteger.value; int safe = p[3]->xInteger.value; int wasProt = 0; int res = 0; DaoVmSpace *vms = proc->vmSpace; DaoNamespace *ns; DString_ToMBS( name ); if( safe ) vms->options |= DAO_OPTION_SAFE; if( vms->options & DAO_OPTION_SAFE ) wasProt = 1; DArray_PushFront( vms->pathLoading, proc->activeNamespace->path ); ns = DaoVmSpace_LoadEx( vms, DString_GetMBS( name ), runim ); DaoProcess_PutValue( proc, (DaoValue*) ns ); if( ! wasProt ) vms->options &= ~DAO_OPTION_SAFE; if( ns ){ /* in the case that it is cancelled from console */ DArray_PushFront( vms->pathLoading, ns->path ); res = DaoProcess_Call( proc, ns->mainRoutine, NULL, NULL, 0 ); if( proc->stopit | vms->stopit ){ DaoProcess_RaiseException( proc, DAO_ERROR, "loading cancelled" ); }else if( res ){ DaoProcess_RaiseException( proc, res, "loading failed" ); } DArray_PopFront( vms->pathLoading ); }else{ DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" ); } DArray_PopFront( vms->pathLoading ); if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns ); }
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; if( DaoProcess_CheckCB( proc, "cannot send/block inside code section method" ) ) return; if( self->cap <= 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "channel is closed" ); return; } data = DaoValue_DeepCopy( par[1] ); if( data == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "invalid data for the channel" ); return; } //printf( "CHANNEL_Send: %p\n", event ); DMutex_Lock( & daoCallServer->mutex ); DArray_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 ); } }
static void SYS_PutEnv( DaoProcess *proc, DaoValue *p[], int N ) { char *name = DString_GetMBS( p[0]->xString.data ); char *value = DString_GetMBS( p[1]->xString.data ); char *buf = malloc( strlen( name ) + strlen( value ) + 2 ); if( !buf ){ DaoProcess_RaiseException( proc, DAO_ERROR, "memory allocation failed" ); return; } sprintf( buf, "%s=%s", name, value ); if( putenv( buf ) ){ DaoProcess_RaiseException( proc, DAO_ERROR, "error putting environment variable" ); free( buf ); } }
static void DaoClass_SetField( DaoValue *self0, DaoProcess *proc, DString *name, DaoValue *value ) { DaoClass *self = & self0->xClass; DNode *node = DMap_Find( self->lookupTable, name ); if( node && LOOKUP_ST( node->value.pInt ) == DAO_CLASS_VARIABLE ){ int up = LOOKUP_UP( node->value.pInt ); int id = LOOKUP_ID( node->value.pInt ); DaoVariable *dt = self->variables->items.pVar[id]; if( DaoValue_Move( value, & dt->value, dt->dtype ) ==0 ) DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "not matched" ); }else{ /* XXX permission */ DaoProcess_RaiseException( proc, DAO_ERROR_FIELD, "not exist" ); } }
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; if( DaoProcess_CheckCB( proc, "cannot select/block inside code section method" ) ) return; 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_RaiseException( proc, DAO_ERROR_PARAM, "invalid type selection" ); return; } } event = DaoCallServer_MakeEvent(); DaoTaskEvent_Init( event, DAO_EVENT_WAIT_SELECT, DAO_EVENT_WAIT, future, NULL ); GC_ShiftRC( selects, event->selects ); 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 ); }
static void CHANNEL_SetCap( DaoChannel *self, DaoValue *value, DaoProcess *proc ) { self->cap = value->xInteger.value; if( self->cap > 0 ) return; self->cap = 1; DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "channel capacity must be greater than 0" ); }
static void DaoIO_ReadFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *res = DaoProcess_PutMBString( proc, "" ); daoint silent = p[1]->xInteger.value; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } if( DString_Size( p[0]->xString.data ) ==0 ){ char buf[1024]; while(1){ size_t count = fread( buf, 1, sizeof( buf ), stdin ); if( count ==0 ) break; DString_AppendDataMBS( res, buf, count ); } }else{ FILE *fin = DaoIO_OpenFile( proc, p[0]->xString.data, "r", silent ); struct stat info; if( fin == NULL ) return; fstat( fileno( fin ), &info ); DString_Resize( res, info.st_size ); DString_Resize( res, fread( res->mbs, 1, res->size, fin ) ); fclose( fin ); } }
static void SYS_Sleep( DaoProcess *proc, DaoValue *p[], int N ) { #ifdef DAO_WITH_THREAD DMutex mutex; DCondVar condv; #endif double s = p[0]->xFloat.value; if( s < 0 ){ DaoProcess_RaiseException( proc, DAO_WARNING_VALUE, "expecting positive value" ); return; } #ifdef DAO_WITH_THREAD /* sleep only the current thread: */ DMutex_Init( & mutex ); DCondVar_Init( & condv ); DMutex_Lock( & mutex ); DCondVar_TimedWait( & condv, & mutex, s ); DMutex_Unlock( & mutex ); DMutex_Destroy( & mutex ); DCondVar_Destroy( & condv ); #elif UNIX sleep( (int)s ); /* This may cause the whole process to sleep. */ #else Sleep( s * 1000 ); #endif }
void CHANNEL_Select( DaoProcess *proc, DaoValue *par[], int n ) { DaoTaskEvent *event = NULL; DaoFuture *future = DaoProcess_GetInitFuture( proc ); DaoList *channels = (DaoList*) par[0]; float timeout = par[1]->xFloat.value; daoint i, size = DaoList_Size( channels ); for(i=0; i<size; ++i){ DaoValue *value = DaoList_GetItem( channels, i ); if( DaoValue_CheckCtype( value, dao_type_channel ) == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "invalid type selection" ); return; } } event = DaoCallServer_MakeEvent(); DaoTaskEvent_Init( event, DAO_EVENT_WAIT_SELECT, DAO_EVENT_WAIT, future, NULL ); event->channels = DArray_Copy( & channels->items ); 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 ); }
static void DaoObject_Print( DaoValue *self0, DaoProcess *proc, DaoStream *stream, DMap *cycData ) { int ec; char buf[50]; DaoObject *self = & self0->xObject; sprintf( buf, "[%p]", self ); if( self0 == self->defClass->objType->value ){ DaoStream_WriteString( stream, self->defClass->className ); DaoStream_WriteChars( stream, "[null]" ); return; } if( cycData != NULL && DMap_Find( cycData, self ) != NULL ){ DaoStream_WriteString( stream, self->defClass->className ); DaoStream_WriteChars( stream, buf ); return; } if( cycData ) MAP_Insert( cycData, self, self ); DString_SetChars( proc->mbstring, "serialize" ); DaoValue_Clear( & proc->stackValues[0] ); ec = DaoObject_InvokeMethod( self, proc->activeObject, proc, proc->mbstring, NULL,0,1,1 ); if( ec && ec != DAO_ERROR_FIELD_NOTEXIST ){ DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->mbstring->chars, NULL ); }else if( ec == DAO_ERROR_FIELD_NOTEXIST || proc->stackValues[0] == NULL ){ DaoStream_WriteString( stream, self->defClass->className ); DaoStream_WriteChars( stream, buf ); }else{ DaoValue_Print( proc->stackValues[0], proc, stream, cycData ); } }
static void DaoQueue_Merge( DaoProcess *proc, DaoValue *p[], int N ) { DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL ); DaoQueue *other = (DaoQueue*)DaoValue_CastCstruct( p[1], NULL ); int merged = 0; DaoMutex_Lock( self->mtx ); DaoMutex_Lock( other->mtx ); if( !self->capacity || self->size + other->size <= self->capacity ){ if( self->size && other->size ){ self->tail->next = other->head; other->head->previous = self->tail; } else if( !self->size ){ self->head = other->head; self->tail = other->tail; DaoCondVar_BroadCast( self->popvar ); } self->size += other->size; if( other->capacity && other->size == other->capacity ) DaoCondVar_BroadCast( other->pushvar ); other->size = 0; other->head = other->tail = NULL; merged = 1; } DaoMutex_Unlock( self->mtx ); DaoMutex_Unlock( other->mtx ); if( !merged ) DaoProcess_RaiseException( proc, DAO_ERROR, "Merging exceeds the queue capacity" ); }
static void DaoObject_GetItem( DaoValue *self0, DaoProcess *proc, DaoValue *ids[], int N ) { DaoObject *self = & self0->xObject; int rc = 0; DString_SetChars( proc->string, "[]" ); rc = DaoObject_InvokeMethod( self, proc->activeObject, proc, proc->string, ids, N,0,0 ); if( rc ) DaoProcess_RaiseException( proc, daoExceptionNames[rc], proc->string->chars, NULL ); }
/* mt module: */ static int DaoMT_PushSectionFrame( DaoProcess *proc ) { if( DaoProcess_PushSectionFrame( proc ) == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "code section not found!" ); return 0; } return 1; }
static void DaoIO_Writeln( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; if( ( self->mode & DAO_IO_WRITE ) == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not writable" ); return; } DaoIO_Writeln0( self, proc, p+1, N-1 ); }
static void TEST_AssertRange( DaoProcess *proc, DaoValue* p[], int N ) { if ( DaoValue_ComparePro( p[0], p[1]->xTuple.values[0], proc ) < 0 || DaoValue_ComparePro( p[0], p[1]->xTuple.values[1], proc ) > 0 ){ DaoTuple *tup = DaoTuple_New( 2 ); DaoTuple_SetItem( tup, p[0], 0 ); DaoTuple_SetItem( tup, p[1], 1 ); DaoProcess_RaiseException( proc, "Error::Test::AssertInRange", "", (DaoValue*)tup ); } }
static void STD_Gcmin( DaoProcess *proc, DaoValue *p[], int N ) { DaoProcess_PutInteger( proc, DaoGC_Min( -1 ) ); if( proc->vmSpace->options & DAO_OPTION_SAFE ){ if( N == 1 ) DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } if( N == 1 ) DaoGC_Min( (int)p[0]->xInteger.value ); }
static void TEST_AssertEq( DaoProcess *proc, DaoValue* p[], int N ) { if ( DaoValue_ComparePro( p[0], p[1], proc ) != 0 ){ DaoTuple *tup = DaoTuple_New( 2 ); DaoTuple_SetItem( tup, p[0], 0 ); DaoTuple_SetItem( tup, p[1], 1 ); DaoProcess_RaiseException( proc, "Error::Test::AssertEqual", "", (DaoValue*)tup ); } }
static void DaoBUF_Resize( DaoProcess *proc, DaoValue *p[], int N ) { Dao_Buffer *self = (Dao_Buffer*) p[0]; daoint size = p[1]->xInteger.value; if( size < 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "negative buffer size" ); return; } Dao_Buffer_Resize( self, size ); }
static void DaoBUF_New( DaoProcess *proc, DaoValue *p[], int N ) { daoint size = p[0]->xInteger.value; Dao_Buffer *self = Dao_Buffer_New( size >= 0 ? size : 0 ); DaoProcess_PutValue( proc, (DaoValue*) self ); if( size < 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "negative buffer size" ); return; } }
static void AUX_Restore( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fin = fopen( DString_GetMBS( p[0]->xString.data ), "r" ); if( fin == NULL ){ DaoProcess_RaiseException( proc,DAO_ERROR_FILE, DString_GetMBS( p[0]->xString.data ) ); return; } DaoNamespace_Restore( proc->activeNamespace, proc, fin ); fclose( fin ); }
static void AUX_Backup( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fout = fopen( DString_GetMBS( p[0]->xString.data ), "w+" ); if( fout == NULL ){ DaoProcess_RaiseException( proc,DAO_ERROR_FILE, DString_GetMBS( p[0]->xString.data ) ); return; } DaoNamespace_Backup( proc->activeNamespace, proc, fout, p[1]->xInteger.value ); fclose( fout ); }
static void DaoObject_SetItem( DaoValue *self0, DaoProcess *proc, DaoValue *ids[], int N, DaoValue *value ) { DaoObject *self = & self0->xObject; DaoValue *ps[ DAO_MAX_PARAM ]; int rc; memcpy( ps+1, ids, N*sizeof(DaoValue*) ); ps[0] = value; DString_SetChars( proc->string, "[]=" ); rc = DaoObject_InvokeMethod( self, proc->activeObject, proc, proc->string, ps, N+1,1,0 ); if( rc ) DaoProcess_RaiseException( proc, daoExceptionNames[rc], proc->string->chars, NULL ); }
static void TEST_AssertNEmpty( DaoProcess *proc, DaoValue* p[], int N ) { int res = 0; switch ( p[0]->type ){ case DAO_STRING:res = p[0]->xString.value->size; break; case DAO_LIST: res = p[0]->xList.value->size; break; case DAO_ARRAY: res = p[0]->xArray.size; break; case DAO_MAP: res = p[0]->xMap.value->size; break; } if ( !res ) DaoProcess_RaiseException( proc, "Error::Test::AssertNotEmpty", "", p[0] ); }
static void DaoBUF_CopyData( DaoProcess *proc, DaoValue *p[], int N ) { Dao_Buffer *self = (Dao_Buffer*) p[0]; Dao_Buffer *other = (Dao_Buffer*) p[1]; if( other->bufsize == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "invalid value" ); return; } if( self->bufsize < other->size ) Dao_Buffer_Resize( self, other->size ); memcpy( self->buffer.pVoid, other->buffer.pVoid, other->size ); self->size = other->size; }
static void DaoIO_Write0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DMap *cycData; int i; if( (self->attribs & (DAO_IO_FILE | DAO_IO_PIPE)) && self->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not open!" ); return; } cycData = DMap_New(0,0); for(i=0; i<N; i++) DaoValue_Print( p[i], proc, self, cycData ); DMap_Delete( cycData ); }
static void STD_Resource( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fin; DString *file = DString_Copy( p[0]->xString.data ); if( DaoVmSpace_SearchResource( proc->vmSpace, file ) == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "resource file not found" ); DString_Delete( file ); return; } DaoVmSpace_ReadSource( proc->vmSpace, file, file ); DaoProcess_PutString( proc, file ); DString_Delete( file ); }
static void DaoIO_Open( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } stream = DaoStream_New(); stream->attribs |= DAO_IO_FILE; if( N==0 ){ stream->file = tmpfile(); if( stream->file <= 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "failed to create temporary file" ); return; } }else{ /* XXX Error handling? */ mode = DString_GetMBS( p[1]->xString.data ); if( p[0]->type == DAO_INTEGER ){ stream->file = fdopen( p[0]->xInteger.value, mode ); }else{ DString_Assign( stream->fname, p[0]->xString.data ); DString_ToMBS( stream->fname ); stream->file = DaoIO_OpenFile( proc, stream->fname, mode, 0 ); } stream->mode = 0; if( strstr( mode, "+" ) ) stream->mode = DAO_IO_WRITE | DAO_IO_READ; else{ if( strstr( mode, "r" ) ) stream->mode |= DAO_IO_READ; if( strstr( mode, "w" ) || strstr( mode, "a" ) ) stream->mode |= DAO_IO_WRITE; } } DaoProcess_PutValue( proc, (DaoValue*)stream ); }
static int DaoDataFrame_MakeSlice( DaoxDataFrame *self, DaoProcess *proc, DaoValue *idx[], int N, DArray *slices ) { daoint *dims = self->dims; daoint i, D = 3, S = 1; DaoxDataFrame_MakeFullSlice( self, slices ); if( N > D ){ DaoProcess_RaiseException( proc, DAO_WARNING, "too many indices" ); N = D; } for(i=0; i<N; ++i) MakeSlice( proc, idx[i], dims[i], slices->items.pVector[i] ); for(i=0; i<D; ++i) S *= slices->items.pVector[i]->data.daoints[1]; return S; }
static void FRAME_SETMI( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataFrame *df, *self = (DaoxDataFrame*) p[0]; DaoValue *value = p[1]; int singleIndex1 = DaoxDF_IsSingleIndex( p[2] ); int singleIndex2 = DaoxDF_IsSingleIndex( p[3] ); int singleIndex3 = DaoxDF_IsSingleIndex( p[4] ); DaoxDataFrame_Sliced( self ); if( singleIndex1 && singleIndex2 && (singleIndex3 || self->dims[2] == 1) ){ daoint i = DaoxDF_MakeIndex( self, DAOX_DF_ROW, p[2], proc ); daoint j = DaoxDF_MakeIndex( self, DAOX_DF_COL, p[3], proc ); daoint k = DaoxDF_MakeIndex( self, DAOX_DF_DEP, p[4], proc ); daoint ik = k * self->dims[0] + i; if( i < 0 || j < 0 || k < 0 ) return; DaoxDataColumn_SetCell( (DaoxDataColumn*) self->columns->items.pVoid[j], ik, value ); }else{ int rc = 0; DaoxDataFrame df2 = *self; df = (DaoxDataFrame*) DaoValue_CastCstruct( value, daox_type_dataframe ); DaoxDataFrame_PrepareSlices( self ); DaoDataFrame_MakeSlice( self, proc, p+2, N-2, self->slices ); df2.original = self; if( value->type == DAO_ARRAY ){ DaoArray *array = (DaoArray*) value; rc = DaoxDataFrame_SetArray( & df2, array ); }else if( df != NULL ){ rc = DaoxDataFrame_SetFrame( & df2, df ); }else{ } if( rc == DAOX_DF_WRONG_SHAP ){ DaoProcess_RaiseException( proc, DAO_ERROR_INDEX, "Invalid shape" ); }else if( rc == DAOX_DF_WRONG_VALUE ){ DaoProcess_RaiseException( proc, DAO_ERROR_VALUE, "Invalid value" ); } } }