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 ); }
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 ); }
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; }
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; }
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; }
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; }
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" ); } }
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 ); }
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; }
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 ); } } }
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; } }
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; } } } }
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 ); }
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; }
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 }
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; }
void DaoxEdge_SetValue( DaoxEdge *self, DaoValue *value ) { DaoValue_Move( value, & self->value, self->ctype->args->items.pType[1] ); }
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 ); }