@@ -15,9 +15,9 @@ internal class AD7DisassemblyStream : IDebugDisassemblyStream2
15
15
private ulong _addr ;
16
16
private enum_DISASSEMBLY_STREAM_SCOPE _scope ;
17
17
private string _pLastDocument ;
18
- private int m_dwLastSourceLine ;
19
- private bool m_lastSourceInfoStale ;
20
- private bool m_skipNextInstruction ;
18
+ private uint _dwLastSourceLine ;
19
+ private bool _lastSourceInfoStale ;
20
+ private bool _skipNextInstruction ;
21
21
22
22
internal AD7DisassemblyStream ( AD7Engine engine , enum_DISASSEMBLY_STREAM_SCOPE scope , IDebugCodeContext2 pCodeContext )
23
23
{
@@ -26,8 +26,8 @@ internal AD7DisassemblyStream(AD7Engine engine, enum_DISASSEMBLY_STREAM_SCOPE sc
26
26
AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress ;
27
27
_addr = addr . Address ;
28
28
_pLastDocument = null ;
29
- m_dwLastSourceLine = - 1 ;
30
- m_lastSourceInfoStale = true ;
29
+ _dwLastSourceLine = 0 ;
30
+ _lastSourceInfoStale = true ;
31
31
}
32
32
33
33
#region IDebugDisassemblyStream2 Members
@@ -102,12 +102,12 @@ private DisassemblyData FetchBadInstruction(enum_DISASSEMBLY_STREAM_FIELDS dwFie
102
102
103
103
public int Read ( uint dwInstructions , enum_DISASSEMBLY_STREAM_FIELDS dwFields , out uint pdwInstructionsRead , DisassemblyData [ ] prgDisassembly )
104
104
{
105
- if ( m_lastSourceInfoStale && ! m_skipNextInstruction )
105
+ if ( _lastSourceInfoStale && ! _skipNextInstruction )
106
106
{
107
107
SeekBack ( 1 ) ;
108
108
}
109
109
110
- if ( m_skipNextInstruction )
110
+ if ( _skipNextInstruction )
111
111
{
112
112
dwInstructions += 1 ;
113
113
}
@@ -124,8 +124,17 @@ public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, ou
124
124
// bad address range, return '??'
125
125
for ( iOp = 0 ; iOp < dwInstructions ; _addr ++ , ++ iOp )
126
126
{
127
+ if ( _skipNextInstruction )
128
+ {
129
+ _addr ++ ;
130
+ dwInstructions -- ;
131
+ _skipNextInstruction = false ;
132
+ }
127
133
prgDisassembly [ iOp ] = FetchBadInstruction ( dwFields ) ;
128
134
}
135
+ _lastSourceInfoStale = false ;
136
+ _dwLastSourceLine = 0 ;
137
+ _pLastDocument = null ;
129
138
pdwInstructionsRead = iOp ;
130
139
return Constants . S_OK ;
131
140
}
@@ -139,26 +148,25 @@ public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, ou
139
148
using ( IEnumerator < DisasmInstruction > instructionEnumerator = instructions . GetEnumerator ( ) )
140
149
{
141
150
int idx = 0 ;
142
- if ( m_skipNextInstruction )
151
+ if ( _skipNextInstruction )
143
152
{
153
+ _skipNextInstruction = false ;
154
+
144
155
instructionEnumerator . MoveNext ( ) ;
145
156
DisasmInstruction instruction = instructionEnumerator . Current ;
146
157
147
- m_dwLastSourceLine = ( int ) instruction . Line - 1 ;
148
- _pLastDocument = string . Concat ( "file://" , instruction . File ) ;
158
+ _dwLastSourceLine = instruction . Line != 0 ? instruction . Line - 1 : 0 ;
159
+ _pLastDocument = instruction . File ;
149
160
161
+ dwInstructions -- ;
150
162
idx ++ ;
151
163
}
152
164
153
- for ( ; idx < dwInstructions ; idx ++ )
165
+ for ( ; idx < dwInstructions + 1 && iOp < dwInstructions ; idx ++ )
154
166
{
155
167
instructionEnumerator . MoveNext ( ) ;
156
168
DisasmInstruction instruction = instructionEnumerator . Current ;
157
169
158
- if ( iOp >= dwInstructions )
159
- {
160
- break ;
161
- }
162
170
_addr = instruction . Addr ;
163
171
164
172
if ( ( dwFields & enum_DISASSEMBLY_STREAM_FIELDS . DSF_ADDRESS ) != 0 )
@@ -197,45 +205,59 @@ public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, ou
197
205
}
198
206
}
199
207
200
- if ( ( dwFields & enum_DISASSEMBLY_STREAM_FIELDS . DSF_POSITION ) != 0 && instruction . Line != 0 )
208
+
209
+ string currentFile = instruction . File ;
210
+ uint currentLine = instruction . Line - 1 ;
211
+ bool isNewDocument = string . IsNullOrEmpty ( _pLastDocument ) || ! _pLastDocument . Equals ( currentFile , StringComparison . Ordinal ) ;
212
+ bool isNewLine = currentLine != _dwLastSourceLine ;
213
+
214
+ if ( ( dwFields & enum_DISASSEMBLY_STREAM_FIELDS . DSF_POSITION ) != 0 && currentLine != 0 )
201
215
{
202
- uint startLine = instruction . Line - 1 ;
203
216
217
+ prgDisassembly [ iOp ] . dwFields |= enum_DISASSEMBLY_STREAM_FIELDS . DSF_POSITION ;
204
218
prgDisassembly [ iOp ] . posBeg = new TEXT_POSITION ( )
205
219
{
206
- dwLine = startLine ,
220
+ dwLine = currentLine ,
207
221
dwColumn = 0
208
222
} ;
209
223
prgDisassembly [ iOp ] . posEnd = new TEXT_POSITION ( )
210
224
{
211
- dwLine = instruction . Line ,
225
+ dwLine = currentLine ,
212
226
dwColumn = 0
213
227
} ;
214
228
215
- prgDisassembly [ iOp ] . dwFields |= enum_DISASSEMBLY_STREAM_FIELDS . DSF_POSITION ;
216
-
217
- if ( m_dwLastSourceLine != instruction . Line && instruction . Line != 0 )
218
- {
219
- prgDisassembly [ iOp ] . dwFlags |= enum_DISASSEMBLY_FLAGS . DF_HASSOURCE ;
220
- }
229
+ // Update last seen source line.
230
+ _dwLastSourceLine = currentLine ;
221
231
}
222
232
223
- bool newDocument = string . IsNullOrEmpty ( _pLastDocument ) || ! _pLastDocument . Equals ( instruction . File , StringComparison . Ordinal ) ;
233
+ // Show source if we have line and file information and if there is a new line.
234
+ if ( currentLine != 0 && currentFile != null && isNewLine )
235
+ {
236
+ prgDisassembly [ iOp ] . dwFlags |= enum_DISASSEMBLY_FLAGS . DF_HASSOURCE ;
237
+ }
224
238
225
- if ( ! string . IsNullOrWhiteSpace ( instruction . File ) )
239
+ if ( ! string . IsNullOrWhiteSpace ( currentFile ) )
226
240
{
227
241
if ( ( dwFields & enum_DISASSEMBLY_STREAM_FIELDS . DSF_DOCUMENTURL ) != 0 )
228
242
{
229
- if ( newDocument || idx == 0 )
243
+ // idx 0 is the previous instruction. The first requested instruction
244
+ // is at idx 1.
245
+ if ( isNewDocument || idx == 1 )
230
246
{
231
247
prgDisassembly [ iOp ] . dwFields |= enum_DISASSEMBLY_STREAM_FIELDS . DSF_DOCUMENTURL ;
232
- prgDisassembly [ iOp ] . bstrDocumentUrl = string . Concat ( "file://" , instruction . File ) ;
248
+ prgDisassembly [ iOp ] . bstrDocumentUrl = string . Concat ( "file://" , currentFile ) ;
233
249
}
234
250
}
235
251
}
236
252
237
- m_dwLastSourceLine = ( int ) instruction . Line ;
238
- if ( newDocument )
253
+ if ( ( dwFields & enum_DISASSEMBLY_STREAM_FIELDS . DSF_BYTEOFFSET ) != 0 )
254
+ {
255
+ prgDisassembly [ iOp ] . dwFields |= enum_DISASSEMBLY_STREAM_FIELDS . DSF_BYTEOFFSET ;
256
+ // For the disassembly window, offset should be set to 0 to show source and non-zero to hide it.
257
+ prgDisassembly [ iOp ] . dwByteOffset = isNewLine ? 0 : uint . MaxValue ;
258
+ }
259
+
260
+ if ( isNewDocument )
239
261
{
240
262
prgDisassembly [ iOp ] . dwFlags |= enum_DISASSEMBLY_FLAGS . DF_DOCUMENTCHANGE ;
241
263
_pLastDocument = instruction . File ;
@@ -288,10 +310,10 @@ private int SeekForward(long iInstructions)
288
310
289
311
private int SeekBack ( long iInstructions )
290
312
{
291
- if ( m_lastSourceInfoStale )
313
+ if ( _lastSourceInfoStale )
292
314
{
293
315
iInstructions += 1 ;
294
- m_skipNextInstruction = true ;
316
+ _skipNextInstruction = true ;
295
317
}
296
318
_engine . DebuggedProcess . WorkerThread . RunOperation ( async ( ) =>
297
319
{
@@ -303,8 +325,8 @@ private int SeekBack(long iInstructions)
303
325
public int Seek ( enum_SEEK_START dwSeekStart , IDebugCodeContext2 pCodeContext , ulong uCodeLocationId , long iInstructions )
304
326
{
305
327
_pLastDocument = null ;
306
- m_lastSourceInfoStale = true ;
307
- m_dwLastSourceLine = - 1 ;
328
+ _lastSourceInfoStale = true ;
329
+ _dwLastSourceLine = 0 ;
308
330
309
331
if ( dwSeekStart == enum_SEEK_START . SEEK_START_CODECONTEXT )
310
332
{
0 commit comments