示例#1
0
文件: daoClass.c 项目: hooloong/dao
void DaoValue_Update( DaoValue **self, DaoNamespace *ns, DMap *deftypes )
{
	DaoValue *value = *self;
	DaoType *tp, *tp2;

	if( value == NULL || value->type < DAO_ENUM ) return;
	tp = DaoNamespace_GetType( ns, value );
	/* DaoType_DefineTypes() will make proper specialization of template-like type: */
	tp2 = DaoType_DefineTypes( tp, ns, deftypes );
	if( tp == tp2 ) return;
	if( tp2->tid == DAO_OBJECT && value->type == DAO_OBJECT && value->xObject.isDefault ){
		/* "self" is supposed to be a constant, so it has to be a default instance: */
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized Dao class; */
		*self = tp2->value;
		return;
	}else if( tp2->tid == DAO_CLASS && value->type == DAO_CLASS ){
		GC_ShiftRC( tp2->aux, value ); /* specialized Dao class; */
		*self = tp2->aux;
		return;
	}else if( tp2->tid == DAO_CTYPE && value->type == DAO_CTYPE ){
		GC_ShiftRC( tp2->aux, value ); /* specialized C type; */
		*self = tp2->aux;
		return;
	}else if( tp2->tid == DAO_CDATA && value->type == DAO_CDATA ){
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized C type; */
		*self = tp2->value;
		return;
	}else if( tp2->tid == DAO_CSTRUCT && value->type == DAO_CSTRUCT ){
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized C type; */
		*self = tp2->value;
		return;
	}
	DaoValue_Move( value, self, tp2 );
}
示例#2
0
文件: daoValue.c 项目: wherby/dao
int DaoVariable_Set( DaoVariable *self, DaoValue *value, DaoType *type )
{
	if( type ){
		GC_ShiftRC( type, self->dtype );
		self->dtype = type;
	}
	return DaoValue_Move( value, & self->value, self->dtype );
}
示例#3
0
文件: daoValue.c 项目: wherby/dao
DaoVariable* DaoVariable_New( DaoValue *value, DaoType *type )
{
	DaoVariable *self = (DaoVariable*) dao_calloc( 1, sizeof(DaoVariable) );
	DaoValue_Init( self, DAO_VARIABLE );
	DaoValue_Move( value, & self->value, type );
	self->dtype = type;
	GC_IncRC( type );
	return self;
}
示例#4
0
DaoCinValue* DaoCinValue_New( DaoCinType *cintype, DaoValue *value )
{
	DaoCinValue *self = (DaoCinValue*)dao_calloc( 1, sizeof(DaoCinValue) );
	DaoValue_Init( self, DAO_CINVALUE );
	GC_Assign( & self->cintype, cintype );
	DaoValue_Move( value, & self->value, cintype->target );
#ifdef DAO_USE_GC_LOGGER
	DaoObjectLogger_LogNew( (DaoValue*) self );
#endif
	return self;
}
示例#5
0
文件: daoClass.c 项目: wherby/dao
int DaoClass_AddGlobalVar( DaoClass *self, DString *name, DaoValue *data, DaoType *t, int s )
{
	int size = self->variables->size;
	int id = LOOKUP_BIND( DAO_CLASS_VARIABLE, s, 0, size );
	DNode *node = MAP_Find( self->lookupTable, name );
	if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED;
	if( data == NULL && t ) data = t->value;
	MAP_Insert( self->lookupTable, name, id );
	DArray_Append( self->variables, DaoVariable_New( NULL, t ) );
	DArray_Append( self->glbDataName, (void*)name );
	if( data && DaoValue_Move( data, & self->variables->items.pVar[size]->value, t ) ==0 )
		return -DAO_CTW_TYPE_NOMATCH;
	return id;
}
示例#6
0
int DaoObject_SetData( DaoObject *self, DString *name, DaoValue *data, DaoObject *othis )
{
	DNode *node;
	DaoType *type;
	DaoValue **value ;
	DaoClass *klass = self->defClass;
	DaoObject *null = & klass->objType->value->xObject;
	int child = othis && DaoObject_ChildOf( (DaoValue*)othis, (DaoValue*)self );
	int id, st, up, pm, access;

	if( self == (DaoObject*)self->defClass->objType->value ) return DAO_ERROR;

	node = DMap_Find( self->defClass->lookupTable, name );
	if( node == NULL ) return DAO_ERROR_FIELD_NOTEXIST;

	pm = LOOKUP_PM( node->value.pInt );
	st = LOOKUP_ST( node->value.pInt );
	up = LOOKUP_UP( node->value.pInt );
	id = LOOKUP_ID( node->value.pInt );
	if( self == null && st == DAO_OBJECT_VARIABLE ) return DAO_ERROR_FIELD_NOTPERMIT;
	access = othis == self || pm == DAO_PERM_PUBLIC || (child && pm >= DAO_PERM_PROTECTED);
	if( access == 0 ) return DAO_ERROR_FIELD_NOTPERMIT;
	if( st == DAO_OBJECT_VARIABLE ){
		if( id <0 ) return DAO_ERROR_FIELD_NOTPERMIT;
		type = klass->instvars->items.pVar[ id ]->dtype;
		value = self->objValues + id;
		if( DaoValue_Move( data, value, type ) ==0 ) return DAO_ERROR_VALUE;
	}else if( st == DAO_CLASS_VARIABLE ){
		DaoVariable *var = klass->variables->items.pVar[id];
		if( DaoValue_Move( data, & var->value, var->dtype ) ==0 ) return DAO_ERROR_VALUE;
	}else if( st == DAO_CLASS_CONSTANT ){
		return DAO_ERROR_FIELD;
	}else{
		return DAO_ERROR_FIELD;
	}
	return 0;
}
示例#7
0
文件: daoClass.c 项目: wherby/dao
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" );
	}
}
示例#8
0
文件: daoValue.c 项目: wherby/dao
static int DaoValue_MoveVariant( DaoValue *src, DaoValue **dest, DaoType *tp )
{
	DaoType *itp = NULL;
	daoint j, k, n, mt = 0;
	for(j=0,n=tp->nested->size; j<n; j++){
		k = DaoType_MatchValue( tp->nested->items.pType[j], src, NULL );
		if( k > mt ){
			itp = tp->nested->items.pType[j];
			mt = k;
			if( mt == DAO_MT_EQ ) break;
		}
	}
	if( itp == NULL ) return 0;
	return DaoValue_Move( src, dest, itp );
}
示例#9
0
文件: daoValue.c 项目: daokoder/dao
static int DaoValue_TryCastTuple( DaoValue *src, DaoValue **dest, DaoType *tp )
{
	DaoTuple *tuple;
	DaoType **item_types = tp->args->items.pType;
	DaoType *totype = src->xTuple.ctype;
	DaoValue **data = src->xTuple.values;
	DMap *names = totype ? totype->mapNames : NULL;
	DNode *node, *search;
	daoint i, T = tp->args->size;
	int tm, eqs = 0;
	/*
	// Auto-cast tuple type, on the following conditions:
	// (1) the item values of "dest" must match exactly to the item types of "tp";
	// (2) "tp->mapNames" must contain "(*dest)->xTuple.ctype->mapNames";
	*/
	if( src->xTuple.ctype == NULL ){
		GC_IncRC( tp );
		src->xTuple.ctype = tp;
		return 1;
	}
	if( DaoType_MatchValue( tp, src, NULL ) < DAO_MT_SIM ) return 1; /* Redundant? */
	/*
	// Casting is not necessary if the tuple's field names are a superset of the
	// field names of the target type:
	*/
	if( tp->mapNames == NULL || tp->mapNames->size ==0 ) goto Finalize;
	if( names ){
		daoint count = 0;
		for(node=DMap_First(names); node; node=DMap_Next(names,node)){
			search = DMap_Find( tp->mapNames, node->key.pVoid );
			if( search && node->value.pInt != search->value.pInt ) return 0;
			count += search != NULL;
		}
		/* be superset of the field names of the target type: */
		if( count == tp->mapNames->size ) goto Finalize;
	}
Finalize:
	tuple = DaoTuple_New( T );
	for(i=0; i<T; i++){
		DaoType *it = item_types[i];
		if( it->tid == DAO_PAR_NAMED ) it = & it->aux->xType;
		DaoValue_Move( data[i], tuple->values+i, it );
	}
	GC_IncRC( tp );
	tuple->ctype = tp;
	GC_Assign( dest, tuple );
	return 1;
}
示例#10
0
文件: daoObject.c 项目: cosim/dao
void DaoObject_Init( DaoObject *self, DaoObject *that, int offset )
{
	DaoClass *klass = self->defClass;
	daoint i;

	if( that ){
		GC_ShiftRC( that, self->rootObject );
		self->rootObject = that;
		self->objValues = that->objValues + offset;
	}else if( self->rootObject == NULL ){
		GC_ShiftRC( self, self->rootObject );
		self->rootObject = self;
		if( self->isNull ){ /* no value space is allocated for null object yet! */
			self->valueCount = klass->objDataName->size;
			self->objValues = (DaoValue**) dao_calloc( self->valueCount, sizeof(DaoValue*) );
		}
	}
	offset += self->defClass->objDefCount;
	if( klass->parent != NULL && klass->parent->type == DAO_CLASS ){
		DaoObject *sup = NULL;
		if( self->isNull ){
			sup = & klass->parent->xClass.objType->value->xObject;
		}else{
			sup = DaoObject_Allocate( (DaoClass*) klass->parent, 0 );
			sup->isRoot = 0;
			DaoObject_Init( sup, self->rootObject, offset );
		}
		GC_ShiftRC( sup, self->parent );
		self->parent = (DaoValue*)sup;
	}
	GC_ShiftRC( self, self->objValues[0] );
	self->objValues[0] = (DaoValue*) self;
	if( self->isRoot == 0 ) return;
	for(i=1; i<klass->instvars->size; i++){
		DaoVariable *var = klass->instvars->items.pVar[i];
		DaoValue **value = self->objValues + i;
		/* for data type such as list/map/array,
		 * its .ctype may need to be set properaly */
		if( var->value ){
			DaoValue_Move( var->value, value, var->dtype );
			continue;
		}else if( *value == NULL && var->dtype && var->dtype->value ){
			DaoValue_Copy( var->dtype->value, value );
		}
	}
}
示例#11
0
文件: daoThread.c 项目: hooloong/dao
void DaoProcess_ReturnFutureValue( DaoProcess *self, DaoFuture *future )
{
	DaoType *type;
	if( future == NULL ) return;
	type = future->ctype;
	type = type && type->nested->size ? type->nested->items.pType[0] : NULL;
	switch( self->status ){
	case DAO_PROCESS_FINISHED :
	case DAO_PROCESS_ABORTED :
		DaoValue_Move( self->stackValues[0], & future->value, type );
		future->state = DAO_CALL_FINISHED;
		break;
	case DAO_PROCESS_SUSPENDED : future->state = DAO_CALL_PAUSED; break;
	case DAO_PROCESS_RUNNING :
	case DAO_PROCESS_STACKED : future->state = DAO_CALL_RUNNING; break;
	default : break;
	}
}
示例#12
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;
			}
		}
	}
}
示例#13
0
static void DaoMT_Start( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoProcess *clone;
	DaoVmCode *vmc, *end, *sect;
	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 );
	sect = DaoProcess_InitCodeSection( proc, 0 );
	if( sect == NULL ) 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 );
	DaoMT_InitProcess( proc, clone, 0 );
	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_Assign( & 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 ) DaoValue_Move( proc->activeValues[i], & clone->activeValues[i], NULL );
	}
	DaoCallServer_AddTask( DaoMT_Start0, clone, p[0]->xEnum.value ? clone : NULL );
}
示例#14
0
static DaoFuture* DaoCallServer_GetNextFuture()
{
	DaoCallServer *server = daoCallServer;
	DaoFuture *first, *future, *precond;
	DList *events = server->events;
	DMap *pending = server->pending;
	DMap *active = server->active;
	DNode *it;
	daoint i, j;

	for(i=0; i<events->size; i++){
		DaoTaskEvent *event = (DaoTaskEvent*) events->items.pVoid[i];
		DaoFuture *future = event->future;
		DaoObject *actor = future->actor;
		DaoChannel *channel = event->channel;
		DaoChannel *closed = NULL;
		DaoChannel *chselect = NULL;
		DaoFuture *futselect = NULL;
		DaoValue *selected = NULL;
		DaoValue *message = NULL;
		int type = event->type;

		if( event->state == DAO_EVENT_WAIT && future->precond != NULL ){
			if( future->precond->state != DAO_CALL_FINISHED ) goto MoveToWaiting;
		}
		switch( event->type ){
		case DAO_EVENT_WAIT_SENDING :
			if( channel->buffer->size >= channel->cap ){
				if( event->state == DAO_EVENT_WAIT ){
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_RECEIVING );
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SELECT );
					goto MoveToWaiting;
				}
			}
			event->type = DAO_EVENT_RESUME_TASKLET;
			break;
		case DAO_EVENT_WAIT_RECEIVING :
			if( channel->buffer->size == 0 ){
				if( channel->cap > 0 && event->state == DAO_EVENT_WAIT ){
					DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SENDING );
					goto MoveToWaiting;
				}
				message = dao_none_value;
			}else{
				message = channel->buffer->items.pValue[0];
			}
			GC_Assign( & event->message, message );
			event->auxiliary = channel->cap <= 0 && channel->buffer->size == 0;
			event->type = DAO_EVENT_RESUME_TASKLET;
			DList_PopFront( channel->buffer );
			if( channel->buffer->size < channel->cap )
				DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_SENDING );
			if( channel->buffer->size )
				DaoChannel_ActivateEvent( channel, DAO_EVENT_WAIT_RECEIVING );
			break;
		case DAO_EVENT_WAIT_SELECT :
			message = dao_none_value;
			for(it=DaoMap_First(event->selects); it; it=DaoMap_Next(event->selects,it)){
				if( DaoValue_CheckCtype( it->key.pValue, dao_type_channel ) ){
					DaoChannel *chan = (DaoChannel*) it->key.pValue;
					if( chan->buffer->size > 0 ){
						chselect = chan;
						selected = it->key.pValue;
						message = chan->buffer->items.pValue[0];
						closed = NULL;
						break;
					}else if( chan->cap == 0 ){
						closed = chan;
					}
				}else{
					DaoFuture *fut = (DaoFuture*) it->key.pValue;
					if( fut->state == DAO_CALL_FINISHED ){
						futselect = fut;
						selected = it->key.pValue;
						message = fut->value;
						break;
					}
				}
			}
			if( selected == NULL ) selected = (DaoValue*) closed;
			if( event->state == DAO_EVENT_WAIT && event->selects->value->size ){
				if( selected == NULL ) goto MoveToWaiting;
			}

			GC_Assign( & event->message, message );
			GC_Assign( & event->selected, selected );
			event->auxiliary = event->selects->value->size == 0;
			event->type = DAO_EVENT_RESUME_TASKLET;
			/* change status to not finished: */
			if( chselect != NULL || futselect != NULL ) event->auxiliary = 0;
			if( chselect ){
				DList_PopFront( chselect->buffer );
				if( chselect->buffer->size < chselect->cap )
					DaoChannel_ActivateEvent( chselect, DAO_EVENT_WAIT_SENDING );
				if( chselect->buffer->size )
					DaoChannel_ActivateEvent( chselect, DAO_EVENT_WAIT_SELECT );
			}
			if( futselect != NULL || closed != NULL ){
				void *key = futselect ? (void*)futselect : (void*)closed;
				DMap_Erase( event->selects->value, key );
			}
			break;
		default: break;
		}
		if( actor ){
			DNode *it = DMap_Find( active, actor->rootObject );
			if( actor->rootObject->isAsync ){
				if( it && it->value.pVoid != (void*) future ) continue;
			}else if( it ){
				continue;
			}
		}
		if( future->process && DMap_Find( active, future->process ) ) continue;
		DList_Erase( events, i, 1 );
		DMap_Erase( pending, event );
		if( actor ){
			void *value = actor->rootObject->isAsync ? future : NULL;
			DMap_Insert( active, actor->rootObject, value );
		}
		if( future->process ){
			DMap_Insert( active, future->process, NULL );
			future->process->active = 1;
		}

		/*
		// DaoValue_Move() should be used instead of GC_Assign() for thread safety.
		// Because using GC_Assign() here, may caused "future->message" of primitive
		// type being deleted, right after DaoFuture_GetGCFields() has retrieved it
		// for GC scanning.
		 */
		DaoValue_Move( event->message, & future->message, NULL );
		DaoValue_Move( event->selected, & future->selected, NULL );
		future->aux1 = event->auxiliary;
		future->timeout = event->timeout;

		GC_IncRC( future ); /* To be decreased at the end of tasklet; */
		DaoCallServer_CacheEvent( event );
		return future;
MoveToWaiting:
		if( event->expiring >= 0.0 && event->expiring < MIN_TIME ) continue;
		if( event->expiring >= MIN_TIME ){
			dao_complex com = {0.0,0.0};
			com.real = event->expiring;
			DMap_Insert( server->waitings, & com, event );
			DCondVar_Signal( & server->condv2 );
		}else{
			DList_Append( server->events2, event );
		}
		DList_Erase( server->events, i, 1 );
		i -= 1;
	}
	return NULL;
}
示例#15
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
}
示例#16
0
bool DaoxDebugger::EditContinue ( DaoProcess *process, int newEntryLine, QList<int> & lineMap, QStringList & newCodes, QStringList & routCodes )
{
	DaoRoutine *oldrout = process->activeRoutine;
	int i, j, k, dest = 0;
	//printf( "=======%s\n", routCodes.join("\n").toLocal8Bit().data() );
	//printf( "=======%s\n", newCodes.join("\n").toLocal8Bit().data() );
	if( routCodes.size() == newCodes.size() ){
		DaoLexer *lexer = DaoLexer_New();
		bool eq = true;
		for(i=0; i<routCodes.size(); i++){
			QString s1 = NormalizeCodes( routCodes[i], lexer );
			QString s2 = NormalizeCodes( newCodes[i], lexer );
			if( s1 != s2 ){
				eq = false;
				break;
			}
		}
		DaoLexer_Delete( lexer );
		if( eq ) return true;
	}
	QString codes = newCodes.join( "\n" );
	DaoParser *parser = DaoParser_New();
	DaoRoutine *routine = DaoRoutine_New( oldrout->nameSpace, oldrout->routHost, 1 );
	routine->routType = oldrout->routType;
	routine->parCount = oldrout->parCount;
	routine->attribs = oldrout->attribs;
	routine->defLine = oldrout->defLine;
	parser->routine = routine;
	parser->nameSpace = routine->nameSpace = oldrout->nameSpace;
	parser->vmSpace = oldrout->nameSpace->vmSpace;
	DString_Assign( parser->fileName, oldrout->nameSpace->name );
	routine->body->codeStart = oldrout->body->codeStart;
	routine->body->codeEnd = oldrout->body->codeStart + newCodes.size() + 1;
	parser->regCount = routine->parCount;
	parser->levelBase = oldrout->defLine != 0;
	bool res = DaoParser_LexCode( parser, codes.toLocal8Bit().data(), 1 );
	for(i=0; i<(int)parser->tokens->size; i++){
		parser->tokens->items.pToken[i]->line += routine->body->codeStart;
	}
	for(i=0; i<(int)oldrout->body->defLocals->size; i++){
		DaoToken *tok = oldrout->body->defLocals->items.pToken[i];
		if( tok->index >= oldrout->parCount || tok->type ==0 ) break;
		MAP_Insert( DList_Top( parser->lookupTables ), & tok->string, i );
		DList_Append( routine->body->defLocals, tok );
	}
	res = res && DaoParser_ParseRoutine( parser );
	DaoParser_Delete( parser );
	if( res == false ){
		DaoRoutine_Delete( routine );
		return false;
	}
	if( (process->stackSize - process->stackTop) < (routine->body->regCount + DAO_MAX_PARAM) ){
		DaoProcess_PushFrame( process, routine->body->regCount );
		DaoProcess_PopFrame( process );
	}
	DaoType **regTypes = routine->body->regType->items.pType;
	DaoValue **newValues = process->activeValues;
	DaoValue **oldValues = (DaoValue**)calloc( oldrout->body->regCount, sizeof(DaoValue*) );

	memcpy( oldValues, newValues, oldrout->body->regCount * sizeof(DaoValue*) );
	memset( newValues, 0, oldrout->body->regCount * sizeof(DaoValue*) );
	DaoProcess_InitTopFrame( process, routine, process->activeObject );

#if 0
	DaoStream *stream = DaoStream_New();
	DaoRoutine_PrintCode( oldrout, stream );
	DaoRoutine_PrintCode( routine, stream );
#endif

	regmap.clear();
	for(i=0; i<oldrout->parCount; i++) regmap[i] = i;

	DaoVmCode   *oldVMC = oldrout->body->vmCodes->data.codes;
	DaoVmCode   *newVMC = routine->body->vmCodes->data.codes;
	DaoVmCodeX **oldAnnot = oldrout->body->annotCodes->items.pVmc;
	DaoVmCodeX **newAnnot = routine->body->annotCodes->items.pVmc;
	int M = oldrout->body->vmCodes->size;
	int N = routine->body->vmCodes->size;
	j = k = 0;
	for(i=0; i<lineMap.size(); i++){
		QList<DaoVmCode> oldLineCodes;
		QList<DaoVmCode> newLineCodes;
		if( lineMap[i] <0 ) continue;
		int old = lineMap[i] + oldrout->body->codeStart + 1;
		int niu = i + routine->body->codeStart + 1;
		//printf( "%3i  %3i: %3i  %3i;  %3i  %3i\n", j, k, i, niu, lineMap[i], old );
		while( j<M && oldAnnot[j]->line < old ) ++j;
		while( k<N && newAnnot[k]->line < niu ) ++k;
		while( j<M && oldAnnot[j]->line == old ){
			oldLineCodes.append( oldVMC[j] );
			++j;
		}
		while( k<N && newAnnot[k]->line == niu ){
			newLineCodes.append( newVMC[k] );
			++k;
		}
		Matching( oldLineCodes, newLineCodes );
	}
	QMap<int,int>::iterator it, end = regmap.end();
	for(it=regmap.begin(); it != end; ++it){
		j = it.key();
		i = it.value();
		DaoValue_Move( oldValues[j], & newValues[i], regTypes[i] );
	}

	int offset = 0;
	if( newEntryLine <0 ){
		DaoVmCodeX **annotCodes = oldrout->body->annotCodes->items.pVmc;
		int entry = (process->activeCode - process->topFrame->codes) + 1;
		int entryline = oldrout->body->annotCodes->items.pVmc[entry]->line;
		/* if the entry line is NOT modified, use it */
		entryline -= oldrout->body->codeStart + 1;
		for(i=0; i<lineMap.size(); i++) if( lineMap[i] == entryline ) break;
		int newEntryLine = i < lineMap.size() ? i : -1;
		if( newEntryLine >=0 ){
			entryline += oldrout->body->codeStart + 1;
			while( (--entry) >=0 && annotCodes[entry]->line == entryline ) offset ++;
		}
		/* if the entry line IS modified, set the entry line to the first modified line */
		if( newEntryLine <0 ){
			for(i=0; i<lineMap.size(); i++) if( lineMap[i] <0 ) break;
			newEntryLine = i;
		}
		/* if the entry line is manually set: */
		newEntryLine += routine->body->codeStart + 1;
	}

	//XXX GC_ShiftRC( routine, oldrout );
	GC_IncRC( routine );
	oldrout->body->revised = routine;
	process->activeRoutine = routine;
	process->activeTypes = regTypes;
	process->topFrame->codes = routine->body->vmCodes->data.codes;

	ResetExecution( process, newEntryLine, offset );

	i = newCodes.size() - routCodes.size();
	DaoNS_UpdateLineInfo( routine->nameSpace, routine->body->codeStart, i );
	return true;
}
示例#17
0
void DaoxEdge_SetValue( DaoxEdge *self, DaoValue *value )
{
	DaoValue_Move( value, & self->value, self->ctype->args->items.pType[1] );
}
示例#18
0
static void DaoSTD_ProcData( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoProcess_PutValue( proc, proc->stackValues[1] );
	if( n == 0 ) return;
	DaoValue_Move( p[0], & proc->stackValues[1], NULL );
}