static void FRAME_GETMI( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataFrame *df, *self = (DaoxDataFrame*) p[0]; int singleIndex1 = DaoxDF_IsSingleIndex( p[1] ); int singleIndex2 = DaoxDF_IsSingleIndex( p[2] ); int singleIndex3 = DaoxDF_IsSingleIndex( p[3] ); DaoxDataFrame_Sliced( self ); if( singleIndex1 && singleIndex2 && (singleIndex3 || self->dims[2] == 1) ){ daoint i = DaoxDF_MakeIndex( self, DAOX_DF_ROW, p[1], proc ); daoint j = DaoxDF_MakeIndex( self, DAOX_DF_COL, p[2], proc ); daoint k = DaoxDF_MakeIndex( self, DAOX_DF_DEP, p[3], proc ); daoint ik = k * self->dims[0] + i; DaoValue value = {0}; if( i < 0 || j < 0 || k < 0 ) return; memset( & value, 0, sizeof(DaoValue) ); DaoxDataColumn_GetCell( (DaoxDataColumn*) self->columns->items.pVoid[j], ik, & value ); DaoProcess_PutValue( proc, & value ); }else{ df = DaoProcess_MakeReturnDataFrame( proc ); DaoxDataFrame_PrepareSlices( df ); DaoDataFrame_MakeSlice( self, proc, p+1, N-1, df->slices ); GC_ShiftRC( self, df->original ); df->original = self; DaoProcess_PutValue( proc, (DaoValue*) df ); } }
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; }
static void STD_Compile( DaoProcess *proc, DaoValue *p[], int N ) { char *source = DaoValue_TryGetMBString( p[0] ); DaoNamespace *ns = proc->activeNamespace; if( DaoProcess_Compile( proc, ns, source ) ==0 ){ DaoProcess_PutValue( proc, dao_none_value ); return; } DaoProcess_PutValue( proc, ns->mainRoutines->items.pValue[ ns->mainRoutines->size-1 ] ); }
static void DaoState_Value( DaoProcess *proc, DaoValue *p[], int N ) { DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL ); DaoMutex_Lock( self->lock ); DaoProcess_PutValue( proc, self->state ); DaoMutex_Unlock( self->lock ); }
static void UT_BinaryOper2( DaoProcess *proc, DaoValue *p[], int N, int oper ) { DaoxUserType *C = DaoxUserType_New(); DaoxUserType *A = (DaoxUserType*) p[0]; DaoxUserType *B = (DaoxUserType*) p[1]; DaoProcess_PutValue( proc, (DaoValue*) C ); }
static void UT_UnaryOper( DaoProcess *proc, DaoValue *p[], int N, int oper ) { daoint ta; DaoxUserType *A = (DaoxUserType*) p[0]; DaoxUserType *C = DaoxUserType_New(); DaoProcess_PutValue( proc, (DaoValue*) C ); }
static void DaoIO_SStream( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = DaoStream_New(); if( p[0]->xEnum.value == 1 ) DString_ToWCS( stream->streamString ); stream->attribs |= DAO_IO_STRING; 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 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 DaoxUserType* DaoProcess_PutUserPod( DaoProcess *proc, dao_integer value ) { DaoxUserType buffer = {DAO_CSTRUCT, 0}; buffer.ctype = daox_type_user_pod_type; buffer.value = value; return (DaoxUserType*) DaoProcess_PutValue( proc, (DaoValue*) & buffer ); }
void DaoCallServer_AddCall( DaoProcess *caller ) { DaoProcess *callee = DaoVmSpace_AcquireProcess( caller->vmSpace ); DaoStackFrame *frame = caller->topFrame; DaoTaskEvent *event = DaoCallServer_MakeEvent(); DaoType *type = (DaoType*) frame->routine->routType->aux; DaoFuture *future = DaoFuture_New( type, 1 ); DaoValue **params = caller->stackValues + caller->topFrame->stackBase; int i, count = caller->topFrame->parCount; future->state = DAO_CALL_PAUSED; future->actor = caller->topFrame->object; GC_IncRC( future->actor ); GC_ShiftRC( future, callee->future ); callee->future = future; future->process = callee; GC_IncRC( future->process ); callee->parCount = count; for(i=0; i<count; ++i) DaoValue_Copy( params[i], & callee->paramValues[i] ); DaoProcess_PushRoutine( callee, caller->topFrame->routine, future->actor ); DaoTaskEvent_Init( event, DAO_EVENT_RESUME_TASKLET, DAO_EVENT_RESUME, future, NULL ); DaoProcess_PopFrame( caller ); DaoProcess_PutValue( caller, (DaoValue*) future ); DaoCallServer_Add( event ); }
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; }
static void RES_LoadColladaFile( DaoProcess *proc, DaoValue *p[], int N ) { DaoxSceneResource *self = (DaoxSceneResource*) p[0]; const char *file = DaoValue_TryGetMBString( p[1] ); DaoxScene *scene = DaoxSceneResource_LoadColladaFile( self, file ); DaoProcess_PutValue( proc, (DaoValue*) scene ); }
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] ); } }
static void AUX_Deserialize( DaoProcess *proc, DaoValue *p[], int N ) { int top = proc->factory->size; DaoValue *value = NULL; DaoValue_Deserialize( & value, p[0]->xString.data, proc->activeNamespace, proc ); DaoProcess_PutValue( proc, value ); DaoProcess_PopValues( proc, proc->factory->size - top ); GC_DecRC( value ); }
DaoStream* DaoProcess_PutFile( DaoProcess *self, FILE *file ) { DaoFileStream *stream = DaoFileStream_New(); stream->file = file; stream->base.mode |= DAO_STREAM_WRITABLE | DAO_STREAM_READABLE; DaoFileStream_InitCallbacks( stream ); DaoProcess_PutValue( self, (DaoValue*) stream ); return (DaoStream*) stream; }
static void UT_CompOper2( DaoProcess *proc, DaoValue *p[], int N, int oper ) { DaoValue *C = NULL; DaoxUserType *A = (DaoxUserType*) p[0]; DaoxUserType *B = (DaoxUserType*) p[1]; daoint D = 0; if( C ) DaoProcess_PutValue( proc, C ); else DaoProcess_PutInteger( proc, D ); }
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 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; } proc->status = DAO_PROCESS_SUSPENDED; proc->pauseType = DAO_PAUSE_FUTURE_VALUE; DaoCallServer_AddWait( proc, self, -1 ); }
static void DaoSTD_Eval( DaoProcess *proc, DaoValue *p[], int N ) { DaoVmSpace *vms = proc->vmSpace; DaoNamespace *ns = proc->activeNamespace; DaoStream *prevStream = proc->stdioStream; DaoStream *redirect = (DaoStream*) p[1]; char *source = DaoValue_TryGetChars( p[0] ); if( redirect != prevStream ) GC_Assign( & proc->stdioStream, redirect ); DaoProcess_Eval( proc, ns, source ); DaoProcess_PutValue( proc, proc->stackValues[0] ); if( redirect != prevStream ) GC_Assign( & proc->stdioStream, prevStream ); }
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] ); } }
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; } if( DaoProcess_CheckCB( proc, "cannot block inside code section method" ) ) return; proc->status = DAO_PROCESS_SUSPENDED; proc->pauseType = DAO_PAUSE_FUTURE_VALUE; DaoCallServer_AddWait( proc, self, -1 ); }
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 }
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 ); }
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 ); }
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 ); } }
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 ); }
static void DaoMT_Start( DaoProcess *proc, DaoValue *p[], int n ) { DaoProcess *clone; DaoVmCode *vmc, *end; DaoVmCode *sect = DaoGetSectionCode( proc->activeCode ); DaoType *type = DaoProcess_GetReturnType( proc ); DaoFuture *future = DaoFuture_New( type, 0 ); int entry, nop = proc->activeCode[1].code == DVM_NOP; DaoProcess_PutValue( proc, (DaoValue*) future ); if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return; entry = proc->topFrame->entry; end = proc->activeRoutine->body->vmCodes->data.codes + proc->activeCode[nop+1].b; clone = DaoVmSpace_AcquireProcess( proc->vmSpace ); DaoProcess_PopFrame( proc ); DaoProcess_SetActiveFrame( proc, proc->topFrame ); DaoMT_InitProcess( proc, clone ); clone->topFrame->entry = entry; /* // Use the cloned process instead of the parent process, in case that // the cloned process will not be joined by the parent process: */ clone->topFrame->outer = clone; future->process = clone; GC_IncRC( clone ); GC_ShiftRC( future, clone->future ); clone->future = future; future->state = DAO_CALL_RUNNING; 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 ){ /* These values should be shared with the parent thread: */ GC_ShiftRC( proc->activeValues[i], clone->activeValues[i] ); clone->activeValues[i] = proc->activeValues[i]; } } DaoCallServer_AddTask( DaoMT_Start0, clone, p[0]->xEnum.value ); }
static void DaoQueue_Pop( DaoProcess *proc, DaoValue *p[], int N ) { DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL ); QueueItem *item = NULL; DaoMutex_Lock( self->mtx ); while( !self->size ) DaoCondVar_Wait( self->popvar, self->mtx ); item = self->head; self->head = item->next; if( !self->head ) self->tail = NULL; else self->head->previous = NULL; if( self->capacity && self->size == self->capacity ) DaoCondVar_Signal( self->pushvar ); self->size--; DaoMutex_Unlock( self->mtx ); DaoProcess_PutValue( proc, item->value ); DaoGC_DecRC( item->value ); dao_free( item ); }
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 == NULL ) DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" ); DArray_PopFront( vms->pathLoading ); if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns ); }