|
|
|
|
@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
@@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
context.Step("CreatePinnedRegion", block); |
|
|
|
|
context.StepStartGroup($"CreatePinnedRegion {stLoc.Variable.Name}", block); |
|
|
|
|
BlockContainer body = new BlockContainer(); |
|
|
|
|
for (int i = 0; i < sourceContainer.Blocks.Count; i++) { |
|
|
|
|
if (reachedEdgesPerBlock[i] > 0) { |
|
|
|
|
@ -344,10 +344,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
@@ -344,10 +344,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
|
|
|
|
|
// we'll delete the dummy block later
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stLoc.ReplaceWith(new PinnedRegion(stLoc.Variable, stLoc.Value, body) { ILRange = stLoc.ILRange }); |
|
|
|
|
|
|
|
|
|
var pinnedRegion = new PinnedRegion(stLoc.Variable, stLoc.Value, body) { ILRange = stLoc.ILRange }; |
|
|
|
|
stLoc.ReplaceWith(pinnedRegion); |
|
|
|
|
block.Instructions.RemoveAt(block.Instructions.Count - 1); // remove branch into body
|
|
|
|
|
ProcessPinnedRegion((PinnedRegion)block.Instructions.Last()); |
|
|
|
|
CleanUpTryFinallyAroundPinnedRegion(pinnedRegion); |
|
|
|
|
ProcessPinnedRegion(pinnedRegion); |
|
|
|
|
context.StepEndGroup(keepIfEmpty: true); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -614,5 +617,46 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
@@ -614,5 +617,46 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
|
|
|
|
|
body.EntryPoint.Instructions.RemoveAt(0); |
|
|
|
|
} |
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region CleanUpTryFinallyAroundPinnedRegion
|
|
|
|
|
private void CleanUpTryFinallyAroundPinnedRegion(PinnedRegion pinnedRegion) |
|
|
|
|
{ |
|
|
|
|
if (!(pinnedRegion.Parent is Block tryBlock)) |
|
|
|
|
return; |
|
|
|
|
if (!(tryBlock.Parent is BlockContainer tryContainer)) |
|
|
|
|
return; |
|
|
|
|
if (!(tryContainer.Parent is TryFinally tryFinally)) |
|
|
|
|
return; |
|
|
|
|
// .try BlockContainer {
|
|
|
|
|
// Block IL_001b (incoming: 1) {
|
|
|
|
|
// stloc S_11(call GetArray())
|
|
|
|
|
// PinnedRegion V_3(ldloc S_11, BlockContainer {
|
|
|
|
|
// Block IL_0022 (incoming: 1) {
|
|
|
|
|
// stloc V_2(conv ref->i (array.to.pointer(ldloc V_3)))
|
|
|
|
|
// ...
|
|
|
|
|
// }
|
|
|
|
|
// ...
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
// ...
|
|
|
|
|
// } finally BlockContainer {
|
|
|
|
|
// Block IL_0043 (incoming: 1) {
|
|
|
|
|
// stloc V_3(ldnull)
|
|
|
|
|
// leave IL_0043 (nop)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
if (!(tryFinally.FinallyBlock is BlockContainer finallyContainer)) |
|
|
|
|
return; |
|
|
|
|
if (finallyContainer.Blocks.Count != 1) |
|
|
|
|
return; |
|
|
|
|
var finallyBlock = finallyContainer.Blocks[0]; |
|
|
|
|
if (finallyBlock.Instructions[0].MatchStLoc(pinnedRegion.Variable, out var value) |
|
|
|
|
&& value.MatchLdNull()) { |
|
|
|
|
context.Step("Remove store in finally block", finallyBlock); |
|
|
|
|
finallyBlock.Instructions.RemoveAt(0); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
#endregion
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|