@@ -451,7 +451,7 @@ private static bool SkipGeneratedBranchesForAwaitForeach(List<Instruction> instr
451
451
// if GetResult() returned true.
452
452
453
453
454
- bool CheckForAsyncEnumerator ( List < Instruction > instructions , Instruction instruction , int currentIndex )
454
+ static bool CheckForAsyncEnumerator ( List < Instruction > instructions , Instruction instruction , int currentIndex )
455
455
{
456
456
// We're looking for the following pattern, which checks whether a
457
457
// compiler-generated field of type IAsyncEnumerator<> is null.
@@ -467,7 +467,8 @@ bool CheckForAsyncEnumerator(List<Instruction> instructions, Instruction instruc
467
467
}
468
468
469
469
if ( currentIndex >= 2 &&
470
- instructions [ currentIndex - 2 ] . IsLdarg ( 0 ) &&
470
+ ( instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg ||
471
+ instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg_0 ) &&
471
472
instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
472
473
instructions [ currentIndex - 1 ] . Operand is FieldDefinition field &&
473
474
IsCompilerGenerated ( field ) && field . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" ) )
@@ -479,7 +480,7 @@ bool CheckForAsyncEnumerator(List<Instruction> instructions, Instruction instruc
479
480
}
480
481
481
482
482
- bool CheckIfExceptionThrown ( List < Instruction > instructions , Instruction instruction , int currentIndex )
483
+ static bool CheckIfExceptionThrown ( List < Instruction > instructions , Instruction instruction , int currentIndex )
483
484
{
484
485
// Here, we want to find a pattern where we're checking whether a
485
486
// compiler-generated field of type Object is null. To narrow our
@@ -537,7 +538,7 @@ instructions[j].Operand is MethodReference callRef &&
537
538
}
538
539
539
540
540
- bool CheckThrownExceptionType ( List < Instruction > instructions , Instruction instruction , int currentIndex )
541
+ static bool CheckThrownExceptionType ( List < Instruction > instructions , Instruction instruction , int currentIndex )
541
542
{
542
543
// In this case, we're looking for a branch generated by the compiler to
543
544
// check whether a previously-thrown exception has (at least) the type
@@ -567,7 +568,12 @@ bool CheckThrownExceptionType(List<Instruction> instructions, Instruction instru
567
568
if ( instructions [ i ] . OpCode == OpCodes . Isinst &&
568
569
instructions [ i ] . Operand is TypeReference typeRef &&
569
570
typeRef . FullName == "System.Exception" &&
570
- instructions [ i - 1 ] . IsLdloc ( ) )
571
+ ( instructions [ i - 1 ] . OpCode == OpCodes . Ldloc ||
572
+ instructions [ i - 1 ] . OpCode == OpCodes . Ldloc_S ||
573
+ instructions [ i - 1 ] . OpCode == OpCodes . Ldloc_0 ||
574
+ instructions [ i - 1 ] . OpCode == OpCodes . Ldloc_1 ||
575
+ instructions [ i - 1 ] . OpCode == OpCodes . Ldloc_2 ||
576
+ instructions [ i - 1 ] . OpCode == OpCodes . Ldloc_3 ) )
571
577
{
572
578
return true ;
573
579
}
@@ -585,7 +591,7 @@ private static bool SkipGeneratedBranchesForAwaitUsing(List<Instruction> instruc
585
591
CheckForCleanup ( instructions , instruction , currentIndex ) ;
586
592
587
593
588
- bool CheckForSkipDisposal ( List < Instruction > instructions , Instruction instruction , int currentIndex )
594
+ static bool CheckForSkipDisposal ( List < Instruction > instructions , Instruction instruction , int currentIndex )
589
595
{
590
596
// The async state machine generated for an "await using" contains a branch
591
597
// that checks whether the call to DisposeAsync() needs to be skipped.
@@ -654,9 +660,18 @@ instructions[i].Operand is FieldDefinition reloadedField &&
654
660
}
655
661
}
656
662
}
657
- else if ( instructions [ currentIndex - 1 ] . IsLdloc ( out int localVariableIndex ) &&
658
- instructions [ currentIndex + 1 ] . IsLdloc ( out int reloadedLocalVariableIndex ) &&
659
- localVariableIndex == reloadedLocalVariableIndex &&
663
+ else if ( ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc ||
664
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_S ||
665
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_0 ||
666
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_1 ||
667
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_2 ||
668
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_3 ) &&
669
+ ( instructions [ currentIndex + 1 ] . OpCode == OpCodes . Ldloc ||
670
+ instructions [ currentIndex + 1 ] . OpCode == OpCodes . Ldloc_S ||
671
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_0 ||
672
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_1 ||
673
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_2 ||
674
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldloc_3 ) &&
660
675
instructions [ currentIndex + 2 ] . OpCode == OpCodes . Callvirt &&
661
676
instructions [ currentIndex + 2 ] . Operand is MethodReference method &&
662
677
method . DeclaringType . FullName == "System.IAsyncDisposable" &&
@@ -686,7 +701,7 @@ instructions[i].Operand is FieldDefinition reloadedField &&
686
701
}
687
702
688
703
689
- bool CheckForCleanup ( List < Instruction > instructions , Instruction instruction , int currentIndex )
704
+ static bool CheckForCleanup ( List < Instruction > instructions , Instruction instruction , int currentIndex )
690
705
{
691
706
// The pattern we're looking for here is this:
692
707
//
@@ -721,7 +736,8 @@ bool CheckForCleanup(List<Instruction> instructions, Instruction instruction, in
721
736
}
722
737
723
738
if ( currentIndex >= 1 &&
724
- instructions [ currentIndex - 1 ] . IsLdc_I4 ( 1 ) )
739
+ ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldc_I4 ||
740
+ instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldc_I4_1 ) )
725
741
{
726
742
int minLoadFieldIndex = Math . Max ( 1 , currentIndex - 5 ) ;
727
743
@@ -770,7 +786,7 @@ private static bool SkipGeneratedBranchesForAsyncIterator(List<Instruction> inst
770
786
DisposeCheck ( instructions , instruction , currentIndex ) ;
771
787
772
788
773
- bool CheckForStateSwitch ( List < Instruction > instructions , Instruction instruction , int currentIndex )
789
+ static bool CheckForStateSwitch ( List < Instruction > instructions , Instruction instruction , int currentIndex )
774
790
{
775
791
// The pattern we're looking for here is this one:
776
792
//
@@ -813,7 +829,7 @@ instructions[i].Operand is FieldDefinition field &&
813
829
}
814
830
815
831
816
- bool DisposeCheck ( List < Instruction > instructions , Instruction instruction , int currentIndex )
832
+ static bool DisposeCheck ( List < Instruction > instructions , Instruction instruction , int currentIndex )
817
833
{
818
834
// Within the compiler-generated async iterator, there are at least a
819
835
// couple of places where we find this pattern, in which the async
0 commit comments