2011-09-09 7 views

risposta

9

Fusioni il IdwsProgramExecution-TdwsProgramExecution, potrai accedere ad una "CurrentProg", proprietà, un TdwsProgram ovvero un TdwsMainProgram (se siete nella principale) o a TdwsProcedure (se si utilizza un metodo proc/func /). Quelli avranno una proprietà Table, che elenca i simboli locali, quello è l'ambito più diretto. Che La tabella avrà uno o più genitori, che fa riferimento agli ambiti parent (gerarchicamente, in termini di ambito del codice sorgente).

Se in un TdwsProcedure, si può anche voler guardare la sua proprietà FuncSymbol, che avrà una tabella di parametri (utile se si desidera isolare direttamente i parametri dal resto del campo di applicazione locale)

+0

Grazie Eric, ha lavorato la prima volta. –

2

Per gli altri che stanno leggendo questa domanda, mostrerò alcune informazioni supplementari relative all'ottenimento del valore di un simbolo. Il simbolo è trovato come descritto sopra da Eric, ma è difficile capire come ottenere il valore reale del simbolo. Il codice seguente è una procedura che popola un TMemo (memLocalVariables) con variabili locali ogni volta che viene chiamato. Ci sono alcune funzionalità mancanti come la formattazione ordinata del valore della variabile e l'accesso ai parametri di chiamata. Lo chiamo dallo stato del debugger 'dsDebugSuspended'. Il bit meno intuitivo è l'accesso ai dati dei simboli sullo stack e l'uso del puntatore di base dello stack. Un ottimo modo per imparare come funziona il compilatore! Ma forse c'è una funzione di utilità da qualche parte che non ho trovato ...? Eric?

procedure DrawLocalVariables; 
    var 
    ProgramExecution : TdwsProgramExecution; 
    I : integer; 
    Sym : TSymbol; 
    V : variant; 
    Adr : integer; 
    SymbolTable : TSymbolTable; 
    begin 
    memLocalVariables.Lines.Clear; 

    ProgramExecution := TdwsProgramExecution(dwsDebugger1.Execution); 
    SymbolTable := ProgramExecution.CurrentProg.Table; 
    For I := 0 to SymbolTable.Count-1 do 
     begin 
     Sym := SymbolTable[I]; 
     if Sym is TDataSymbol then 
     begin 
     Adr := TDataSymbol(Sym).StackAddr + ProgramExecution.Stack.BasePointer; 
     ProgramExecution.Stack.ReadValue(Adr, V); 
     memLocalVariables.Lines.Add(Format('%s = %s', [ Sym.Name, VarToStr(V) ])); 
     end; 
     end; 
    end; 
+1

È possibile utilizzare TdwsCompiler.Evaluate per valutare la variabile o un'espressione utilizzando le variabili locali (il watcher del debugger la usa). L'accesso diretto allo stack è tuttavia il modo più efficiente, se si desidera solo il valore della variabile, ma Evaluate consente di ottenere più facilmente ClassName di una variabile di classe f.i. –

+0

Buon punto Eric, grazie, non ci avevo pensato –