@@ -106,9 +106,7 @@ public static (NefFile, ContractManifest, JToken) RemoveUncoveredInstructions(Ne
106
106
nef . Compiler = AppDomain . CurrentDomain . FriendlyName ;
107
107
nef . CheckSum = NefFile . ComputeChecksum ( nef ) ;
108
108
109
- Dictionary < int , ( int docId , int startLine , int startCol , int endLine , int endCol ) > newAddrToSequencePoint = new ( ) ;
110
- Dictionary < int , string > newMethodStart = new ( ) ;
111
- Dictionary < int , string > newMethodEnd = new ( ) ;
109
+ //Dictionary<int, (int docId, int startLine, int startCol, int endLine, int endCol)> newAddrToSequencePoint = new();
112
110
HashSet < JToken > methodsToRemove = new ( ) ;
113
111
foreach ( JToken ? method in ( JArray ) debugInfo [ "methods" ] ! )
114
112
{
@@ -121,8 +119,6 @@ public static (NefFile, ContractManifest, JToken) RemoveUncoveredInstructions(Ne
121
119
}
122
120
int methodStart = ( int ) simplifiedInstructionsToAddress [ oldAddressToInstruction [ oldMethodStart ] ] ! ;
123
121
int methodEnd = ( int ) simplifiedInstructionsToAddress [ oldAddressToInstruction [ oldMethodEnd ] ] ! ;
124
- newMethodStart . Add ( methodStart , method [ "id" ] ! . AsString ( ) ) ; // TODO: same format of method name as dumpnef
125
- newMethodEnd . Add ( methodEnd , method [ "id" ] ! . AsString ( ) ) ;
126
122
method [ "range" ] = $ "{ methodStart } -{ methodEnd } ";
127
123
128
124
int previousSequencePoint = methodStart ;
@@ -140,14 +136,6 @@ public static (NefFile, ContractManifest, JToken) RemoveUncoveredInstructions(Ne
140
136
}
141
137
else
142
138
newSequencePoints . Add ( new JString ( $ "{ previousSequencePoint } { sequencePointGroups [ 2 ] } ") ) ;
143
- GroupCollection documentGroups = DocumentRegex . Match ( sequencePointGroups [ 2 ] . ToString ( ) ) . Groups ;
144
- newAddrToSequencePoint . Add ( previousSequencePoint , (
145
- int . Parse ( documentGroups [ 1 ] . ToString ( ) ) ,
146
- int . Parse ( documentGroups [ 2 ] . ToString ( ) ) ,
147
- int . Parse ( documentGroups [ 3 ] . ToString ( ) ) ,
148
- int . Parse ( documentGroups [ 4 ] . ToString ( ) ) ,
149
- int . Parse ( documentGroups [ 5 ] . ToString ( ) )
150
- ) ) ;
151
139
}
152
140
method [ "sequence-points" ] = newSequencePoints ;
153
141
}
@@ -173,6 +161,8 @@ public static Dictionary<int, bool>
173
161
Parallel . ForEach ( manifest . Abi . Methods , method =>
174
162
CoverInstruction ( method . Offset , script , coveredMap )
175
163
) ;
164
+ //foreach (ContractMethodDescriptor method in manifest.Abi.Methods)
165
+ // CoverInstruction(method.Offset, script, coveredMap);
176
166
// start from _deploy method
177
167
foreach ( JToken ? method in ( JArray ) debugInfo [ "methods" ] ! )
178
168
{
@@ -249,7 +239,17 @@ public static BranchType CoverInstruction(int addr, Script script, Dictionary<in
249
239
250
240
// TODO: ABORTMSG may THROW instead of ABORT. Just throw new NotImplementedException for ABORTMSG?
251
241
if ( instruction . OpCode == OpCode . ABORT || instruction . OpCode == OpCode . ABORTMSG )
242
+ {
243
+ // See if we are in a try. There may still be runtime exceptions
244
+ ( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
245
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
246
+ // Visit catchAddr because there may still be exceptions at runtime
247
+ return CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
248
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
249
+ // Visit finallyAddr because there may still be exceptions at runtime
250
+ return CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
252
251
return BranchType . ABORT ;
252
+ }
253
253
if ( callWithJump . Contains ( instruction . OpCode ) )
254
254
{
255
255
int callTarget = ComputeJumpTarget ( addr , instruction ) ;
@@ -260,12 +260,32 @@ public static BranchType CoverInstruction(int addr, Script script, Dictionary<in
260
260
continue ;
261
261
}
262
262
if ( returnedType == BranchType . ABORT )
263
+ {
264
+ // See if we are in a try. There may still be runtime exceptions
265
+ ( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
266
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
267
+ // Visit catchAddr because there may still be exceptions at runtime
268
+ return CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
269
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
270
+ // Visit finallyAddr because there may still be exceptions at runtime
271
+ return CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
263
272
return BranchType . ABORT ;
273
+ }
264
274
if ( returnedType == BranchType . THROW )
265
275
goto HANDLE_THROW ;
266
276
}
267
277
if ( instruction . OpCode == OpCode . RET )
278
+ {
279
+ // See if we are in a try. There may still be runtime exceptions
280
+ ( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
281
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
282
+ // Visit catchAddr because there may still be exceptions at runtime
283
+ CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
284
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
285
+ // Visit finallyAddr because there may still be exceptions at runtime
286
+ CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
268
287
return BranchType . OK ;
288
+ }
269
289
if ( tryThrowFinally . Contains ( instruction . OpCode ) )
270
290
{
271
291
if ( instruction . OpCode == OpCode . TRY || instruction . OpCode == OpCode . TRY_L )
@@ -275,14 +295,15 @@ public static BranchType CoverInstruction(int addr, Script script, Dictionary<in
275
295
if ( instruction . OpCode == OpCode . ENDTRY )
276
296
{
277
297
( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
278
- if ( stackType != TryStack . TRY && stackType != TryStack . CATCH ) throw new BadScriptException ( "No try stack on ENDTRY" ) ;
298
+ if ( stackType != TryStack . TRY && stackType != TryStack . CATCH )
299
+ throw new BadScriptException ( "No try stack on ENDTRY" ) ;
279
300
280
- if ( stackType == TryStack . TRY )
281
- {
301
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
282
302
// Visit catchAddr because there may still be exceptions at runtime
283
- Stack < ( ( int returnAddr , int finallyAddr ) , TryStack stackType ) > newStack = new ( stack ) ;
284
- CoverInstruction ( catchAddr , script , coveredMap , stack : newStack , throwed : true ) ;
285
- }
303
+ CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
304
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
305
+ // Visit finallyAddr because there may still be exceptions at runtime
306
+ CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
286
307
287
308
stack . Pop ( ) ;
288
309
int endPointer = addr + instruction . TokenI8 ;
@@ -325,12 +346,32 @@ public static BranchType CoverInstruction(int addr, Script script, Dictionary<in
325
346
if ( conditionalJump . Contains ( instruction . OpCode ) || conditionalJump_L . Contains ( instruction . OpCode ) )
326
347
{
327
348
int targetAddress = ComputeJumpTarget ( addr , instruction ) ;
328
- BranchType noJump = CoverInstruction ( addr + instruction . Size , script , coveredMap ) ;
329
- BranchType jump = CoverInstruction ( targetAddress , script , coveredMap ) ;
349
+ BranchType noJump = CoverInstruction ( addr + instruction . Size , script , coveredMap , stack : new ( stack . Reverse ( ) ) ) ;
350
+ BranchType jump = CoverInstruction ( targetAddress , script , coveredMap , stack : new ( stack . Reverse ( ) ) ) ;
330
351
if ( noJump == BranchType . OK || jump == BranchType . OK )
352
+ {
353
+ // See if we are in a try. There may still be runtime exceptions
354
+ ( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
355
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
356
+ // Visit catchAddr because there may still be exceptions at runtime
357
+ CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
358
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
359
+ // Visit finallyAddr because there may still be exceptions at runtime
360
+ CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
331
361
return BranchType . OK ;
362
+ }
332
363
if ( noJump == BranchType . ABORT && jump == BranchType . ABORT )
364
+ {
365
+ // See if we are in a try. There may still be runtime exceptions
366
+ ( ( catchAddr , finallyAddr ) , stackType ) = stack . Peek ( ) ;
367
+ if ( stackType == TryStack . TRY && catchAddr != - 1 )
368
+ // Visit catchAddr because there may still be exceptions at runtime
369
+ return CoverInstruction ( catchAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
370
+ if ( stackType == TryStack . CATCH && finallyAddr != - 1 )
371
+ // Visit finallyAddr because there may still be exceptions at runtime
372
+ return CoverInstruction ( finallyAddr , script , coveredMap , stack : new ( stack . Reverse ( ) ) , throwed : true ) ;
333
373
return BranchType . ABORT ;
374
+ }
334
375
if ( noJump == BranchType . THROW || jump == BranchType . THROW ) // THROW, ABORT => THROW
335
376
goto HANDLE_THROW ;
336
377
throw new Exception ( $ "Unknown { nameof ( BranchType ) } { noJump } { jump } ") ;
0 commit comments