DaoValue* DaoObject_DoBinary( DaoValue *self, DaoVmCode *op, DaoValue *args[2], DaoProcess *proc ) { DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL; DaoRoutine *rout = NULL; DaoValue *selfvalue = NULL; DaoType *argtypes[2]; switch( op->code ){ case DVM_ADD : case DVM_SUB : case DVM_MUL : case DVM_DIV : case DVM_MOD : case DVM_POW : case DVM_BITAND : case DVM_BITOR : case DVM_BITXOR : case DVM_BITLFT : case DVM_BITRIT : case DVM_AND : case DVM_OR : case DVM_LT : case DVM_LE : case DVM_EQ : case DVM_NE : case DVM_IN : break; default: return NULL; } argtypes[0] = proc->activeTypes[ op->a ]; argtypes[1] = proc->activeTypes[ op->b ]; if( op->c == op->a ){ const char *name = DaoVmCode_GetCompoundOperator( op->code ); rout = DaoClass_FindMethod( self->xObject.defClass, name, host ); if( rout != NULL ){ DaoProcess_PushCallWithTypes( proc, rout, self, args+1, argtypes + 1, 1 ); return NULL; } } rout = DaoClass_FindMethod( self->xObject.defClass, DaoVmCode_GetOperator( op->code ), host ); if( rout == NULL ){ switch( op->code ){ case DVM_EQ : DaoProcess_PutBoolean( proc, args[0] == args[1] ); break; case DVM_NE : DaoProcess_PutBoolean( proc, args[0] != args[1] ); break; default: break; } return NULL; } if( op->c == op->a && self == args[0] ) selfvalue = self; if( op->c == op->b && self == args[1] ) selfvalue = self; DaoProcess_PushCallWithTypes( proc, rout, selfvalue, args, argtypes, 2 ); // TODO: retc; return NULL; }
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 ); } }
static void DaoIO_Check2( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; int res = 0, what = p[1]->xEnum.value; switch( what ){ case 0 : res = (self->mode & DAO_STREAM_AUTOCONV) != 0; break; } DaoProcess_PutBoolean( proc, res ); }
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; proc->status = DAO_PROCESS_SUSPENDED; proc->pauseType = DAO_PAUSE_FUTURE_WAIT; DaoCallServer_AddWait( proc, self, timeout ); }
static void DaoIO_Check( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; int res = 0, what = p[1]->xEnum.value; switch( what ){ case 0 : res = DaoStream_IsReadable( self ); break; case 1 : res = DaoStream_IsWritable( self ); break; case 2 : res = DaoStream_IsOpen( self ); break; case 3 : res = DaoStream_EndOfStream( self ); break; } DaoProcess_PutBoolean( proc, res ); }
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 }