Skip to content

Commit 8162487

Browse files
Drop the per-call predicate from FindFlagInitStore.
After the cluster-1/3/4 fixes converged every caller on the same matching shape (match the slot/kind/type of a reference ILVariable, then check the init value), the `Predicate<StLoc>` parameter was just a hole through which each caller restated that logic verbatim. Fold the slot/kind/type check into the helper and have callers pass just the reference variable and a value matcher.
1 parent 17c60ef commit 8162487

1 file changed

Lines changed: 22 additions & 33 deletions

File tree

ICSharpCode.Decompiler/IL/ControlFlow/RuntimeAsyncExceptionRewriteTransform.cs

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,8 @@ static bool TryRewriteTryFinally(TryCatch tryCatch, TryCatchHandler handler, Blo
279279
return false;
280280

281281
// Pre-try: somewhere among the instructions preceding the TryCatch we expect
282-
// an `stloc obj(ldnull)`. Other (unrelated) stores may be interleaved. After
283-
// SplitVariables, when the try body always throws the pre-init's local is a separate
284-
// ILVariable from the in-handler store, so match by slot/kind/type rather than identity.
285-
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch,
286-
s => s.Variable.Index == objectVariable.Index
287-
&& s.Variable.Kind == objectVariable.Kind
288-
&& s.Variable.Type.IsKnownType(KnownTypeCode.Object)
289-
&& s.Value.MatchLdNull());
282+
// an `stloc obj(ldnull)`. Other (unrelated) stores may be interleaved.
283+
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch, objectVariable, v => v.MatchLdNull());
290284
if (flagInitStore == null)
291285
return false;
292286

@@ -383,18 +377,26 @@ static bool TryRewriteTryFinally(TryCatch tryCatch, TryCatchHandler handler, Blo
383377
return true;
384378
}
385379

386-
// Scan instructions before `tryCatch` for the runtime-async flag-init store that matches
387-
// `predicate`. The lowering inserts an `stloc obj(ldnull)` (try-finally) or
388-
// `stloc num(ldc.i4 0)` (try-catch) before the try region; the catch handler overwrites it,
389-
// the continuation reads it to decide whether an exception occurred (and which case).
390-
// Returns null when no matching store is found.
391-
static StLoc FindFlagInitStore(Block parentBlock, TryCatch tryCatch, Predicate<StLoc> predicate)
380+
// Scan instructions before `tryCatch` for the runtime-async flag-init store. The lowering
381+
// inserts an `stloc obj(ldnull)` (try-finally) or `stloc num(ldc.i4 0)` (try-catch) before
382+
// the try region; the catch handler overwrites it, and the continuation reads it to decide
383+
// whether an exception occurred (and which case). Match by `referenceVar`'s slot/kind/type
384+
// rather than identity — after SplitVariables, the pre-init's ILVariable may differ from
385+
// the in-handler one. Returns null when no matching store is found.
386+
static StLoc FindFlagInitStore(Block parentBlock, TryCatch tryCatch, ILVariable referenceVar, Predicate<ILInstruction> matchInitValue)
392387
{
393388
int tryIndex = tryCatch.ChildIndex;
394389
for (int i = 0; i < tryIndex; i++)
395390
{
396-
if (parentBlock.Instructions[i] is StLoc s && predicate(s))
397-
return s;
391+
if (parentBlock.Instructions[i] is not StLoc s)
392+
continue;
393+
if (s.Variable.Index != referenceVar.Index || s.Variable.Kind != referenceVar.Kind)
394+
continue;
395+
if (!s.Variable.Type.Equals(referenceVar.Type))
396+
continue;
397+
if (!matchInitValue(s.Value))
398+
continue;
399+
return s;
398400
}
399401
return null;
400402
}
@@ -640,15 +642,8 @@ static bool TryRewriteTryCatch(TryCatch tryCatch, TryCatchHandler handler, Block
640642
if (prefixCount != 0)
641643
return false;
642644

643-
// Pre-try: somewhere before the TryCatch we expect `stloc num(ldc.i4 0)`. After
644-
// SplitVariables the pre-init's local may be a separate ILVariable, so match the slot
645-
// and type rather than the ILVariable identity (same workaround as the multi-handler
646-
// matcher).
647-
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch,
648-
s => s.Variable.Index == numVariable.Index
649-
&& s.Variable.Kind == numVariable.Kind
650-
&& s.Variable.Type.IsKnownType(KnownTypeCode.Int32)
651-
&& s.Value.MatchLdcI4(0));
645+
// Pre-try: somewhere before the TryCatch we expect `stloc num(ldc.i4 0)`.
646+
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch, numVariable, v => v.MatchLdcI4(0));
652647
if (flagInitStore == null)
653648
return false;
654649

@@ -789,14 +784,8 @@ static bool TryRewriteMultiHandlerTryCatch(TryCatch tryCatch, Block parentBlock,
789784
handlerInfos.Add((handler, k, bodyObj, bodyTmp));
790785
}
791786

792-
// Pre-try: stloc num(ldc.i4 0). After SplitVariables the pre-init's local may be a
793-
// separate ILVariable (the in-handler stores form a disjoint use that gets split off),
794-
// so match the slot and type rather than the ILVariable identity.
795-
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch,
796-
s => s.Variable.Index == numVariable.Index
797-
&& s.Variable.Kind == numVariable.Kind
798-
&& s.Variable.Type.IsKnownType(KnownTypeCode.Int32)
799-
&& s.Value.MatchLdcI4(0));
787+
// Pre-try: stloc num(ldc.i4 0).
788+
var flagInitStore = FindFlagInitStore(parentBlock, tryCatch, numVariable, v => v.MatchLdcI4(0));
800789
if (flagInitStore == null)
801790
return false;
802791
// Block continuation { switch (ldloc num) { case K: br case_K ... ; default: leave outer } }

0 commit comments

Comments
 (0)