/* // Note: reference count is not handled for "self"! // But it is cached in the DaoProcess object, so no need to handle it by user! */ int DaoValue_Deserialize( DaoValue **self, DString *serial, DaoNamespace *ns, DaoProcess *proc ) { DaoParser *parser = DaoParser_New(); DArray *types = DArray_New(0); DMap *omap = DMap_New(0,0); int rc; *self = NULL; parser->nameSpace = ns; parser->vmSpace = ns->vmSpace; DaoParser_LexCode( parser, DString_GetMBS( serial ), 0 ); if( parser->tokens->size == 0 ) goto Failed; DArray_PushFront( types, NULL ); rc = DaoParser_Deserialize( parser, 0, parser->tokens->size-1, self, types, ns, proc, omap ); if( *self ) DaoProcess_CacheValue( proc, *self ); DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return rc; Failed: DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return 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; }
void DaoNamespace_Restore( DaoNamespace *self, DaoProcess *proc, FILE *fin ) { DaoParser *parser = DaoParser_New(); DString *line = DString_New(1); DArray *types = DArray_New(0); DArray *tokens = parser->tokens; DMap *omap = DMap_New(0,0); DString *name; DNode *node; parser->nameSpace = self; parser->vmSpace = self->vmSpace; while( DaoFile_ReadLine( fin, line ) ){ DaoValue *value = NULL; int st = DAO_GLOBAL_VARIABLE; int pm = DAO_DATA_PRIVATE; int i, n, start = 0; char *mbs; DaoParser_LexCode( parser, line->mbs, 0 ); if( tokens->size == 0 ) continue; name = & tokens->items.pToken[start]->string; if( name->size == 6 && strcmp( name->mbs, "inputs" ) == 0 ){ if( tokens->size < 3 ) continue; DString_Clear( line ); n = tokens->items.pToken[start+2]->string.size; mbs = tokens->items.pToken[start+2]->string.mbs; for(i=0; i<n; i++){ char c1 = mbs[i]; char c2 = mbs[i+1]; if( c1 < 'A' || c1 > 'P' ) continue; DString_AppendChar( line, (char)((c1-'A')*16 + (c2-'A')) ); i += 1; } /* printf( "%s\n", line->mbs ); */ DaoProcess_Eval( proc, self, line->mbs ); continue; } switch( tokens->items.pToken[start]->name ){ case DKEY_PRIVATE : pm = DAO_DATA_PRIVATE; start += 1; break; case DKEY_PROTECTED : pm = DAO_DATA_PROTECTED; start += 1; break; case DKEY_PUBLIC : pm = DAO_DATA_PUBLIC; start += 1; break; } if( start >= tokens->size ) continue; switch( tokens->items.pToken[start]->name ){ case DKEY_CONST : st = DAO_GLOBAL_CONSTANT; start += 1; break; case DKEY_VAR : st = DAO_GLOBAL_VARIABLE; start += 1; break; } if( tokens->items.pToken[start]->name != DTOK_IDENTIFIER ) continue; name = & tokens->items.pToken[start]->string; start += 1; if( start + 3 >= tokens->size ) continue; if( tokens->items.pToken[start]->name != DTOK_ASSN ) continue; start += 1; DArray_Clear( parser->errors ); DArray_Clear( types ); DArray_PushFront( types, NULL ); DaoParser_Deserialize( parser, start, tokens->size-1, &value, types, self, proc, omap ); if( value == NULL ) continue; node = DMap_Find( self->lookupTable, name ); if( node ) continue; if( st == DAO_GLOBAL_CONSTANT ){ DaoNamespace_AddConst( self, name, value, pm ); }else{ DaoNamespace_AddVariable( self, name, value, NULL, pm ); } } DMap_Delete( omap ); DString_Delete( line ); DArray_Delete( types ); DaoParser_Delete( parser ); }