Browse Source

Make ILRange field private - introduce public API for IL range manipulation.

pull/1440/head
Siegfried Pammer 6 years ago
parent
commit
c1fca21e8a
  1. 8
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 4
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  3. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 66
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  5. 11
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  6. 6
      ICSharpCode.Decompiler/IL/ControlFlow/AwaitInCatchTransform.cs
  7. 27
      ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs
  8. 18
      ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs
  9. 19
      ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs
  10. 4
      ICSharpCode.Decompiler/IL/ControlFlow/ExitPoints.cs
  11. 16
      ICSharpCode.Decompiler/IL/ControlFlow/LoopDetection.cs
  12. 4
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs
  13. 38
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  14. 22
      ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs
  15. 23
      ICSharpCode.Decompiler/IL/ILReader.cs
  16. 82
      ICSharpCode.Decompiler/IL/Instructions.cs
  17. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  18. 2
      ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
  19. 6
      ICSharpCode.Decompiler/IL/Instructions/Block.cs
  20. 6
      ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs
  21. 6
      ICSharpCode.Decompiler/IL/Instructions/Branch.cs
  22. 6
      ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs
  23. 2
      ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs
  24. 7
      ICSharpCode.Decompiler/IL/Instructions/Comp.cs
  25. 8
      ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
  26. 2
      ICSharpCode.Decompiler/IL/Instructions/Conv.cs
  27. 24
      ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs
  28. 2
      ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs
  29. 4
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  30. 42
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs
  31. 2
      ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs
  32. 2
      ICSharpCode.Decompiler/IL/Instructions/LdLen.cs
  33. 2
      ICSharpCode.Decompiler/IL/Instructions/Leave.cs
  34. 2
      ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs
  35. 8
      ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs
  36. 2
      ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs
  37. 8
      ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs
  38. 2
      ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs
  39. 6
      ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs
  40. 18
      ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs
  41. 2
      ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs
  42. 2
      ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs
  43. 4
      ICSharpCode.Decompiler/IL/PointerArithmeticOffset.cs
  44. 8
      ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs
  45. 4
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  46. 24
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  47. 6
      ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs
  48. 34
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  49. 6
      ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs
  50. 12
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  51. 8
      ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs
  52. 29
      ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs
  53. 81
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs
  54. 6
      ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs
  55. 4
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs
  56. 22
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs
  57. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  58. 4
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs
  59. 15
      ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs
  60. 2
      ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

8
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2917,8 +2917,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2917,8 +2917,8 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitInvalidBranch(InvalidBranch inst, TranslationContext context)
{
string message = "Error";
if (inst.ILRange.Start != 0) {
message += $" near IL_{inst.ILRange.Start:x4}";
if (inst.StartILOffset != 0) {
message += $" near IL_{inst.StartILOffset:x4}";
}
if (!string.IsNullOrEmpty(inst.Message)) {
message += ": " + inst.Message;
@ -2929,8 +2929,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2929,8 +2929,8 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitInvalidExpression(InvalidExpression inst, TranslationContext context)
{
string message = "Error";
if (inst.ILRange.Start != 0) {
message += $" near IL_{inst.ILRange.Start:x4}";
if (inst.StartILOffset != 0) {
message += $" near IL_{inst.StartILOffset:x4}";
}
if (!string.IsNullOrEmpty(inst.Message)) {
message += ": " + inst.Message;

4
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -256,7 +256,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -256,7 +256,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
// Add the IL range associated with this instruction to the current sequence point.
if (HasUsableILRange(inst) && current.Intervals != null) {
current.Intervals.Add(inst.ILRange);
current.Intervals.AddRange(inst.ILRanges);
var function = inst.Parent.Ancestors.OfType<ILFunction>().FirstOrDefault();
Debug.Assert(current.Function == null || current.Function == function);
current.Function = function;
@ -275,7 +275,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -275,7 +275,7 @@ namespace ICSharpCode.Decompiler.CSharp
internal static bool HasUsableILRange(ILInstruction inst)
{
if (inst.ILRange.IsEmpty)
if (inst.HasILRange)
return false;
return !(inst is BlockContainer || inst is Block);
}

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -267,6 +267,7 @@ @@ -267,6 +267,7 @@
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="DecompileRun.cs" />
<Compile Include="Disassembler\ILParser.cs" />
<Compile Include="IL\ILInstructionExtensions.cs" />
<Compile Include="IL\Transforms\CombineExitsTransform.cs" />
<Compile Include="IL\Transforms\ReduceNestingTransform.cs" />
<Compile Include="IL\Transforms\LocalFunctionDecompiler.cs" />

66
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -56,26 +56,26 @@ namespace ICSharpCode.Decompiler.IL @@ -56,26 +56,26 @@ namespace ICSharpCode.Decompiler.IL
foreach (var eh in body.ExceptionRegions) {
var tryRange = new Interval(eh.TryOffset, eh.TryOffset + eh.TryLength);
var handlerBlock = new BlockContainer();
handlerBlock.ILRange = new Interval(eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength);
handlerBlock.AddILRange(new Interval(eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength));
handlerBlock.Blocks.Add(new Block());
handlerContainers.Add(handlerBlock.ILRange.Start, handlerBlock);
handlerContainers.Add(handlerBlock.StartILOffset, handlerBlock);
if (eh.Kind == ExceptionRegionKind.Fault || eh.Kind == ExceptionRegionKind.Finally) {
var tryBlock = new BlockContainer();
tryBlock.ILRange = tryRange;
tryBlock.AddILRange(tryRange);
if (eh.Kind == ExceptionRegionKind.Finally)
tryInstructionList.Add(new TryFinally(tryBlock, handlerBlock) { ILRange = tryRange });
tryInstructionList.Add(new TryFinally(tryBlock, handlerBlock).WithILRange(tryRange));
else
tryInstructionList.Add(new TryFault(tryBlock, handlerBlock) { ILRange = tryRange });
tryInstructionList.Add(new TryFault(tryBlock, handlerBlock).WithILRange(tryRange));
continue;
}
//
var tryCatch = tryCatchList.FirstOrDefault(tc => tc.TryBlock.ILRange == tryRange);
var tryCatch = tryCatchList.FirstOrDefault(tc => tc.TryBlock.ILRanges.SingleOrDefault() == tryRange);
if (tryCatch == null) {
var tryBlock = new BlockContainer();
tryBlock.ILRange = tryRange;
tryBlock.AddILRange(tryRange);
tryCatch = new TryCatch(tryBlock);
tryCatch.ILRange = tryRange;
tryCatch.AddILRange(tryRange);
tryCatchList.Add(tryCatch);
tryInstructionList.Add(tryCatch);
}
@ -83,22 +83,22 @@ namespace ICSharpCode.Decompiler.IL @@ -83,22 +83,22 @@ namespace ICSharpCode.Decompiler.IL
ILInstruction filter;
if (eh.Kind == System.Reflection.Metadata.ExceptionRegionKind.Filter) {
var filterBlock = new BlockContainer(expectedResultType: StackType.I4);
filterBlock.ILRange = new Interval(eh.FilterOffset, eh.HandlerOffset);
filterBlock.AddILRange(new Interval(eh.FilterOffset, eh.HandlerOffset));
filterBlock.Blocks.Add(new Block());
handlerContainers.Add(filterBlock.ILRange.Start, filterBlock);
handlerContainers.Add(filterBlock.StartILOffset, filterBlock);
filter = filterBlock;
} else {
filter = new LdcI4(1);
}
var handler = new TryCatchHandler(filter, handlerBlock, variableByExceptionHandler[eh]);
handler.AddILRange(filter.ILRange);
handler.AddILRange(handlerBlock.ILRange);
handler.AddILRange(filter);
handler.AddILRange(handlerBlock);
tryCatch.Handlers.Add(handler);
tryCatch.AddILRange(handler.ILRange);
tryCatch.AddILRange(handler);
}
if (tryInstructionList.Count > 0) {
tryInstructionList = tryInstructionList.OrderBy(tc => tc.TryBlock.ILRange.Start).ThenByDescending(tc => tc.TryBlock.ILRange.End).ToList();
tryInstructionList = tryInstructionList.OrderBy(tc => tc.TryBlock.StartILOffset).ThenByDescending(tc => tc.TryBlock.EndILOffset).ToList();
nextTry = tryInstructionList[0];
}
}
@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.IL @@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.IL
public void CreateBlocks(BlockContainer mainContainer, List<ILInstruction> instructions, BitArray incomingBranches, CancellationToken cancellationToken)
{
CreateContainerStructure();
mainContainer.ILRange = new Interval(0, body.GetCodeSize());
mainContainer.SetILRange(new Interval(0, body.GetCodeSize()));
currentContainer = mainContainer;
if (instructions.Count == 0) {
currentContainer.Blocks.Add(new Block {
@ -126,19 +126,19 @@ namespace ICSharpCode.Decompiler.IL @@ -126,19 +126,19 @@ namespace ICSharpCode.Decompiler.IL
foreach (var inst in instructions) {
cancellationToken.ThrowIfCancellationRequested();
int start = inst.ILRange.Start;
int start = inst.StartILOffset;
if (currentBlock == null || (incomingBranches[start] && !IsStackAdjustment(inst))) {
// Finish up the previous block
FinalizeCurrentBlock(start, fallthrough: true);
// Leave nested containers if necessary
while (start >= currentContainer.ILRange.End) {
while (start >= currentContainer.EndILOffset) {
currentContainer = containerStack.Pop();
currentBlock = currentContainer.Blocks.Last();
// this container is skipped (i.e. the loop will execute again)
// set ILRange to the last instruction offset inside the block.
if (start >= currentContainer.ILRange.End) {
Debug.Assert(currentBlock.ILRange.IsEmpty);
currentBlock.ILRange = new Interval(currentBlock.ILRange.Start, start);
if (start >= currentContainer.EndILOffset) {
Debug.Assert(currentBlock.HasILRange);
currentBlock.AddILRange(new Interval(currentBlock.StartILOffset, start));
}
}
// Enter a handler if necessary
@ -153,30 +153,30 @@ namespace ICSharpCode.Decompiler.IL @@ -153,30 +153,30 @@ namespace ICSharpCode.Decompiler.IL
currentBlock = new Block();
currentContainer.Blocks.Add(currentBlock);
}
currentBlock.ILRange = new Interval(start, start);
currentBlock.SetILRange(new Interval(start, start));
}
while (nextTry != null && start == nextTry.TryBlock.ILRange.Start) {
while (nextTry != null && start == nextTry.TryBlock.StartILOffset) {
currentBlock.Instructions.Add(nextTry);
containerStack.Push(currentContainer);
currentContainer = (BlockContainer)nextTry.TryBlock;
currentBlock = new Block();
currentContainer.Blocks.Add(currentBlock);
currentBlock.ILRange = new Interval(start, start);
currentBlock.SetILRange(new Interval(start, start));
nextTry = tryInstructionList.ElementAtOrDefault(++currentTryIndex);
}
currentBlock.Instructions.Add(inst);
if (inst.HasFlag(InstructionFlags.EndPointUnreachable))
FinalizeCurrentBlock(inst.ILRange.End, fallthrough: false);
FinalizeCurrentBlock(inst.EndILOffset, fallthrough: false);
else if (!CreateExtendedBlocks && inst.HasFlag(InstructionFlags.MayBranch))
FinalizeCurrentBlock(inst.ILRange.End, fallthrough: true);
FinalizeCurrentBlock(inst.EndILOffset, fallthrough: true);
}
FinalizeCurrentBlock(mainContainer.ILRange.End, fallthrough: false);
FinalizeCurrentBlock(mainContainer.EndILOffset, fallthrough: false);
// Finish up all containers
while (containerStack.Count > 0) {
currentContainer = containerStack.Pop();
currentBlock = currentContainer.Blocks.Last();
FinalizeCurrentBlock(mainContainer.ILRange.End, fallthrough: false);
FinalizeCurrentBlock(mainContainer.EndILOffset, fallthrough: false);
}
ConnectBranches(mainContainer, cancellationToken);
}
@ -190,8 +190,8 @@ namespace ICSharpCode.Decompiler.IL @@ -190,8 +190,8 @@ namespace ICSharpCode.Decompiler.IL
{
if (currentBlock == null)
return;
Debug.Assert(currentBlock.ILRange.IsEmpty);
currentBlock.ILRange = new Interval(currentBlock.ILRange.Start, currentILOffset);
Debug.Assert(currentBlock.HasILRange);
currentBlock.SetILRange(new Interval(currentBlock.StartILOffset, currentILOffset));
if (fallthrough) {
if (currentBlock.Instructions.LastOrDefault() is SwitchInstruction switchInst && switchInst.Sections.Last().Body.MatchNop()) {
// Instead of putting the default branch after the switch instruction
@ -213,9 +213,7 @@ namespace ICSharpCode.Decompiler.IL @@ -213,9 +213,7 @@ namespace ICSharpCode.Decompiler.IL
branch.TargetBlock = FindBranchTarget(branch.TargetILOffset);
if (branch.TargetBlock == null) {
branch.ReplaceWith(new InvalidBranch("Could not find block for branch target "
+ Disassembler.DisassemblerHelpers.OffsetToString(branch.TargetILOffset)) {
ILRange = branch.ILRange
});
+ Disassembler.DisassemblerHelpers.OffsetToString(branch.TargetILOffset)).WithILRange(branch));
}
break;
case Leave leave:
@ -224,7 +222,7 @@ namespace ICSharpCode.Decompiler.IL @@ -224,7 +222,7 @@ namespace ICSharpCode.Decompiler.IL
if (leave.TargetContainer == null) {
// assign the finally/filter container
leave.TargetContainer = containerStack.Peek();
leave.Value = ILReader.Cast(leave.Value, leave.TargetContainer.ExpectedResultType, null, leave.ILRange.Start);
leave.Value = ILReader.Cast(leave.Value, leave.TargetContainer.ExpectedResultType, null, leave.StartILOffset);
}
break;
case BlockContainer container:
@ -249,7 +247,7 @@ namespace ICSharpCode.Decompiler.IL @@ -249,7 +247,7 @@ namespace ICSharpCode.Decompiler.IL
{
foreach (var container in containerStack) {
foreach (var block in container.Blocks) {
if (block.ILRange.Start == targetILOffset)
if (block.StartILOffset == targetILOffset)
return block;
}
}

11
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -504,9 +504,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -504,9 +504,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
moveNextFunction.ReleaseRef();
foreach (var branch in function.Descendants.OfType<Branch>()) {
if (branch.TargetBlock == setResultAndExitBlock) {
branch.ReplaceWith(new Leave((BlockContainer)function.Body, resultVar == null ? null : new LdLoc(resultVar)) {
ILRange = branch.ILRange
});
branch.ReplaceWith(new Leave((BlockContainer)function.Body, resultVar == null ? null : new LdLoc(resultVar)).WithILRange(branch));
}
}
foreach (var leave in function.Descendants.OfType<Leave>()) {
@ -526,9 +524,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -526,9 +524,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
foreach (var leave in function.Descendants.OfType<Leave>()) {
if (moveNextLeaves.Contains(leave)) {
leave.ReplaceWith(new InvalidBranch {
Message = "leave MoveNext - await not detected correctly",
ILRange = leave.ILRange
});
Message = "leave MoveNext - await not detected correctly"
}.WithILRange(leave));
}
}
// Delete dead loads of the state cache variable:
@ -951,7 +948,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -951,7 +948,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
// if there's any remaining loads (there shouldn't be), replace them with the constant 1
foreach (LdLoc load in doFinallyBodies.LoadInstructions.ToArray()) {
load.ReplaceWith(new LdcI4(1) { ILRange = load.ILRange });
load.ReplaceWith(new LdcI4(1).WithILRange(load));
}
context.StepEndGroup(keepIfEmpty: true);
}

6
ICSharpCode.Decompiler/IL/ControlFlow/AwaitInCatchTransform.cs

@ -268,7 +268,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -268,7 +268,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
var outer = BlockContainer.FindClosestContainer(container.Parent);
if (outer != null) changedContainers.Add(outer);
finallyContainer.Blocks.Add(entryPointOfFinally);
finallyContainer.ILRange = entryPointOfFinally.ILRange;
finallyContainer.AddILRange(entryPointOfFinally);
exitOfFinally.Instructions.RemoveRange(tempStore.ChildIndex, 3);
exitOfFinally.Instructions.Add(new Leave(finallyContainer));
foreach (var branchToFinally in container.Descendants.OfType<Branch>()) {
@ -278,9 +278,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -278,9 +278,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
foreach (var newBlock in additionalBlocksInFinally) {
newBlock.Remove();
finallyContainer.Blocks.Add(newBlock);
finallyContainer.AddILRange(newBlock.ILRange);
finallyContainer.AddILRange(newBlock);
}
tryCatch.ReplaceWith(new TryFinally(tryCatch.TryBlock, finallyContainer) {ILRange = tryCatch.TryBlock.ILRange});
tryCatch.ReplaceWith(new TryFinally(tryCatch.TryBlock, finallyContainer).WithILRange(tryCatch.TryBlock));
}
// clean up all modified containers

27
ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs

@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (DetectExitPoints.CompatibleExitInstruction(ifInst.TrueInst, exitInst)) {
// if (...) exitInst; exitInst;
context.Step("Use empty block as then-branch", ifInst.TrueInst);
ifInst.TrueInst = new Nop() { ILRange = ifInst.TrueInst.ILRange };
ifInst.TrueInst = new Nop().WithILRange(ifInst.TrueInst);
// false, because we didn't inline a real block
// this will cause HandleIfInstruction() to attempt to inline the exitInst.
return false;
@ -231,7 +231,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -231,7 +231,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// -> if (...) { ... } else { ... } blockExit;
context.Step("Remove redundant 'goto blockExit;' in then-branch", ifInst);
if (!(ifInst.TrueInst is Block trueBlock) || trueBlock.Instructions.Count == 1)
ifInst.TrueInst = new Nop { ILRange = ifInst.TrueInst.ILRange };
ifInst.TrueInst = new Nop().WithILRange(ifInst.TrueInst);
else
trueBlock.Instructions.RemoveAt(trueBlock.Instructions.Count - 1);
@ -396,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -396,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
context.Step("Swap empty then-branch with else-branch", ifInst);
var oldTrue = ifInst.TrueInst;
ifInst.TrueInst = ifInst.FalseInst;
ifInst.FalseInst = new Nop { ILRange = oldTrue.ILRange };
ifInst.FalseInst = new Nop().WithILRange(oldTrue);
ifInst.Condition = Comp.LogicNot(ifInst.Condition);
}
@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// </summary>
private void OrderIfBlocks(IfInstruction ifInst)
{
if (IsEmpty(ifInst.FalseInst) || GetILRange(ifInst.TrueInst).Start <= GetILRange(ifInst.FalseInst).Start)
if (IsEmpty(ifInst.FalseInst) || GetStartILOffset(ifInst.TrueInst, out _) <= GetStartILOffset(ifInst.FalseInst, out _))
return;
context.Step("Swap then-branch with else-branch to match IL order", ifInst);
@ -437,14 +437,17 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -437,14 +437,17 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
ifInst.Condition = Comp.LogicNot(ifInst.Condition);
}
public static Interval GetILRange(ILInstruction inst)
public static int GetStartILOffset(ILInstruction inst, out bool isEmpty)
{
// some compilers merge the leave instructions for different arguments using stack variables
// these get split and inlined, but the ILRange of the value remains a better indicator of the actual location
if (inst is Leave leave && !leave.Value.MatchNop())
return leave.Value.ILRange;
if (inst is Leave leave && !leave.Value.MatchNop()) {
isEmpty = leave.Value.HasILRange;
return leave.Value.StartILOffset;
}
return inst.ILRange;
isEmpty = inst.HasILRange;
return inst.StartILOffset;
}
/// <summary>
@ -524,13 +527,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -524,13 +527,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// prefer arranging stuff in IL order
if (exit1.MatchBranch(out var block1) && exit2.MatchBranch(out var block2))
return block1.ILRange.Start.CompareTo(block2.ILRange.Start);
return block1.StartILOffset.CompareTo(block2.StartILOffset);
// use the IL offsets of the arguments of leave instructions instead of the leaves themselves if possible
if (exit1.MatchLeave(out var _, out var arg1) && exit2.MatchLeave(out var _, out var arg2))
return arg1.ILRange.Start.CompareTo(arg2.ILRange.Start);
return arg1.StartILOffset.CompareTo(arg2.StartILOffset);
return exit1.ILRange.Start.CompareTo(exit2.ILRange.Start);
return exit1.StartILOffset.CompareTo(exit2.StartILOffset);
}
/// <summary>
@ -630,7 +633,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -630,7 +633,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
for (int i = startIndex; i < endIndex; i++) {
var inst = block.Instructions[i];
extractedBlock.Instructions.Add(inst);
extractedBlock.AddILRange(inst.ILRange);
extractedBlock.AddILRange(inst);
}
block.Instructions.RemoveRange(startIndex, endIndex - startIndex);

18
ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// Move ILRanges of special nop instructions to the previous non-nop instruction.
for (int i = block.Instructions.Count - 1; i > 0; i--) {
if (block.Instructions[i] is Nop nop && nop.Kind == NopKind.Pop) {
block.Instructions[i - 1].AddILRange(nop.ILRange);
block.Instructions[i - 1].AddILRange(nop);
}
}
@ -82,8 +82,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -82,8 +82,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (value.MatchLdLoc(out ILVariable v)
&& v.IsSingleDefinition && v.LoadCount == 1 && block.Instructions[0].MatchStLoc(v, out ILInstruction inst)) {
context.Step("Inline variable in return block", block);
inst.AddILRange(ret.Value.ILRange);
inst.AddILRange(block.Instructions[0].ILRange);
inst.AddILRange(ret.Value);
inst.AddILRange(block.Instructions[0]);
ret.Value = inst;
block.Instructions.RemoveAt(0);
}
@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
context.Step("Simplify branch to branch", branch);
var nextBranch = (Branch)targetBlock.Instructions[0];
branch.TargetBlock = nextBranch.TargetBlock;
branch.AddILRange(nextBranch.ILRange);
branch.AddILRange(nextBranch);
if (targetBlock.IncomingEdgeCount == 0)
targetBlock.Instructions.Clear(); // mark the block for deletion
targetBlock = branch.TargetBlock;
@ -133,8 +133,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -133,8 +133,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
context.Step("Replace branch to leave with leave", branch);
// Replace branches to 'leave' instruction with the leave instruction
var leave2 = leave.Clone();
if (!branch.ILRange.IsEmpty) // use the ILRange of the branch if possible
leave2.ILRange = branch.ILRange;
if (!branch.HasILRange) // use the ILRange of the branch if possible
leave2.AddILRange(branch);
branch.ReplaceWith(leave2);
}
if (targetBlock.IncomingEdgeCount == 0)
@ -186,13 +186,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -186,13 +186,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false; // don't inline block into itself
context.Step("CombineBlockWithNextBlock", br);
var targetBlock = br.TargetBlock;
if (targetBlock.ILRange.Start < block.ILRange.Start && IsDeadTrueStore(block)) {
if (targetBlock.StartILOffset < block.StartILOffset && IsDeadTrueStore(block)) {
// The C# compiler generates a dead store for the condition of while (true) loops.
block.Instructions.RemoveRange(block.Instructions.Count - 3, 2);
}
if (block.ILRange.IsEmpty)
block.ILRange = targetBlock.ILRange;
if (block.HasILRange)
block.AddILRange(targetBlock);
block.Instructions.Remove(br);
block.Instructions.AddRange(targetBlock.Instructions);

19
ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
for (int k = j + 1; k < block.Instructions.Count; k++) {
newBlock.Instructions.Add(block.Instructions[k]);
}
newBlock.ILRange = newBlock.Instructions[0].ILRange;
newBlock.AddILRange(newBlock.Instructions[0]);
block.Instructions.RemoveRange(j + 1, newBlock.Instructions.Count);
block.Instructions.Add(new Branch(newBlock));
container.Blocks.Insert(i + 1, newBlock);
@ -147,9 +147,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -147,9 +147,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (p.StackType != StackType.Ref) {
arrayToPointer = new Conv(arrayToPointer, p.StackType.ToPrimitiveType(), false, Sign.None);
}
block.Instructions[block.Instructions.Count - 2] = new StLoc(p, arrayToPointer) {
ILRange = block.Instructions[block.Instructions.Count - 2].ILRange
};
block.Instructions[block.Instructions.Count - 2] = new StLoc(p, arrayToPointer)
.WithILRange(block.Instructions[block.Instructions.Count - 2]);
((Branch)block.Instructions.Last()).TargetBlock = targetBlock;
modified = true;
}
@ -356,7 +355,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -356,7 +355,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
var pinnedRegion = new PinnedRegion(stLoc.Variable, stLoc.Value, body) { ILRange = stLoc.ILRange };
var pinnedRegion = new PinnedRegion(stLoc.Variable, stLoc.Value, body).WithILRange(stLoc);
stLoc.ReplaceWith(pinnedRegion);
block.Instructions.RemoveAt(block.Instructions.Count - 1); // remove branch into body
ProcessPinnedRegion(pinnedRegion);
@ -414,7 +413,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -414,7 +413,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
foreach (var block in body.Blocks)
DetectPinnedRegion(block);
body.Blocks.RemoveAll(b => b.Instructions.Count == 0); // remove dummy blocks
body.ILRange = body.EntryPoint.ILRange;
body.SetILRange(body.EntryPoint);
}
private void MoveArrayToPointerToPinnedRegionInit(PinnedRegion pinnedRegion)
@ -447,8 +446,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -447,8 +446,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
newVar.HasGeneratedName = oldVar.HasGeneratedName;
oldVar.Function.Variables.Add(newVar);
pinnedRegion.Variable = newVar;
pinnedRegion.Init = new ArrayToPointer(pinnedRegion.Init) { ILRange = arrayToPointer.ILRange };
conv.ReplaceWith(new LdLoc(newVar) { ILRange = conv.ILRange });
pinnedRegion.Init = new ArrayToPointer(pinnedRegion.Init).WithILRange(arrayToPointer);
conv.ReplaceWith(new LdLoc(newVar).WithILRange(conv));
}
void ReplacePinnedVar(ILVariable oldVar, ILVariable newVar, ILInstruction inst)
@ -457,8 +456,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -457,8 +456,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (inst is Conv conv && conv.Kind == ConversionKind.StopGCTracking && conv.Argument.MatchLdLoc(oldVar) && conv.ResultType == newVar.StackType) {
// conv ref->i (ldloc oldVar)
// => ldloc newVar
conv.AddILRange(conv.Argument.ILRange);
conv.ReplaceWith(new LdLoc(newVar) { ILRange = conv.ILRange });
conv.AddILRange(conv.Argument);
conv.ReplaceWith(new LdLoc(newVar).WithILRange(conv));
return;
}
if (inst is IInstructionWithVariableOperand iwvo && iwvo.Variable == oldVar) {

4
ICSharpCode.Decompiler/IL/ControlFlow/ExitPoints.cs

@ -166,7 +166,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -166,7 +166,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
currentExit = ChooseExit(potentialExits);
foreach (var exit in potentialExits) {
if (CompatibleExitInstruction(currentExit, exit)) {
exit.ReplaceWith(new Leave(currentContainer) { ILRange = exit.ILRange });
exit.ReplaceWith(new Leave(currentContainer).WithILRange(exit));
}
}
Debug.Assert(!currentExit.MatchLeave(currentContainer));
@ -222,7 +222,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -222,7 +222,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (currentExit == ExitNotYetDetermined && CanIntroduceAsExit(inst)) {
potentialExits.Add(inst);
} else if (CompatibleExitInstruction(inst, currentExit)) {
inst.ReplaceWith(new Leave(currentContainer) { ILRange = inst.ILRange });
inst.ReplaceWith(new Leave(currentContainer).WithILRange(inst));
}
}

16
ICSharpCode.Decompiler/IL/ControlFlow/LoopDetection.cs

@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return;
Block block = (Block)node.UserData;
if (block.ILRange.Start > exitPointILOffset
if (block.StartILOffset > exitPointILOffset
&& !HasReachableExit(node)
&& ((Block)node.UserData).Parent == currentBlockContainer)
{
@ -440,7 +440,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -440,7 +440,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// that prevents us from finding a nice exit for the inner loops, causing
// unnecessary gotos.
exitPoint = node;
exitPointILOffset = block.ILRange.Start;
exitPointILOffset = block.StartILOffset;
return; // don't visit children, they are likely to have even later IL offsets and we'd end up
// moving almost all of the code into the loop.
}
@ -641,12 +641,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -641,12 +641,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// Move contents of oldEntryPoint to newEntryPoint
// (we can't move the block itself because it might be the target of branch instructions outside the loop)
newEntryPoint.Instructions.ReplaceList(oldEntryPoint.Instructions);
newEntryPoint.ILRange = oldEntryPoint.ILRange;
newEntryPoint.AddILRange(oldEntryPoint);
oldEntryPoint.Instructions.ReplaceList(new[] { loopContainer });
if (exitTargetBlock != null)
oldEntryPoint.Instructions.Add(new Branch(exitTargetBlock));
loopContainer.ILRange = newEntryPoint.ILRange;
loopContainer.AddILRange(newEntryPoint);
MoveBlocksIntoContainer(loop, loopContainer);
// Rewrite branches within the loop from oldEntryPoint to newEntryPoint:
@ -654,7 +654,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -654,7 +654,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (branch.TargetBlock == oldEntryPoint) {
branch.TargetBlock = newEntryPoint;
} else if (branch.TargetBlock == exitTargetBlock) {
branch.ReplaceWith(new Leave(loopContainer) { ILRange = branch.ILRange });
branch.ReplaceWith(new Leave(loopContainer).WithILRange(branch));
}
}
}
@ -723,7 +723,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -723,7 +723,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
BlockContainer switchContainer = new BlockContainer(ContainerKind.Switch);
Block newEntryPoint = new Block();
newEntryPoint.ILRange = switchInst.ILRange;
newEntryPoint.AddILRange(switchInst);
switchContainer.Blocks.Add(newEntryPoint);
newEntryPoint.Instructions.Add(switchInst);
block.Instructions[block.Instructions.Count - 1] = switchContainer;
@ -733,13 +733,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -733,13 +733,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
block.Instructions.Add(new Branch(exitTargetBlock));
}
switchContainer.ILRange = newEntryPoint.ILRange;
switchContainer.AddILRange(newEntryPoint);
MoveBlocksIntoContainer(nodesInSwitch, switchContainer);
// Rewrite branches within the loop from oldEntryPoint to newEntryPoint:
foreach (var branch in switchContainer.Descendants.OfType<Branch>()) {
if (branch.TargetBlock == exitTargetBlock) {
branch.ReplaceWith(new Leave(switchContainer) { ILRange = branch.ILRange });
branch.ReplaceWith(new Leave(switchContainer).WithILRange(branch));
}
}

4
ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs

@ -180,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -180,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// Remove branch/leave after if; it's getting moved into a section.
block.Instructions.RemoveAt(block.Instructions.Count - 1);
}
sw.ILRange = block.Instructions[block.Instructions.Count - 1].ILRange;
sw.AddILRange(block.Instructions[block.Instructions.Count - 1]);
block.Instructions[block.Instructions.Count - 1] = sw;
// mark all inner blocks that were converted to the switch statement for deletion
@ -317,7 +317,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -317,7 +317,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// The switch has a single break target and there is one more hint
// The break target cannot be inlined, and should have the highest IL offset of everything targetted by the switch
return breakBlock.ILRange.Start >= analysis.Sections.Select(s => s.Value.MatchBranch(out var b) ? b.ILRange.Start : -1).Max();
return breakBlock.StartILOffset >= analysis.Sections.Select(s => s.Value.MatchBranch(out var b) ? b.StartILOffset : -1).Max();
}
/// <summary>

38
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -649,10 +649,10 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -649,10 +649,10 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
private BlockContainer ConvertBody(BlockContainer oldBody, StateRangeAnalysis rangeAnalysis)
{
var blockStateMap = rangeAnalysis.GetBlockStateSetMapping(oldBody);
BlockContainer newBody = new BlockContainer() { ILRange = oldBody.ILRange };
BlockContainer newBody = new BlockContainer().WithILRange(oldBody);
// create all new blocks so that they can be referenced by gotos
for (int blockIndex = 0; blockIndex < oldBody.Blocks.Count; blockIndex++) {
newBody.Blocks.Add(new Block { ILRange = oldBody.Blocks[blockIndex].ILRange });
newBody.Blocks.Add(new Block().WithILRange(oldBody.Blocks[blockIndex]));
}
// convert contents of blocks
@ -670,14 +670,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -670,14 +670,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// We keep the state-changing instruction around (as first instruction of the new block)
// for reconstructing the try-finallys.
} else {
newBlock.Instructions.Add(new InvalidExpression("Assigned non-constant to iterator.state field") {
ILRange = oldInst.ILRange
});
newBlock.Instructions.Add(new InvalidExpression("Assigned non-constant to iterator.state field").WithILRange(oldInst));
continue; // don't copy over this instruction, but continue with the basic block
}
} else if (field.MemberDefinition.Equals(currentField)) {
// create yield return
newBlock.Instructions.Add(new YieldReturn(value) { ILRange = oldInst.ILRange });
newBlock.Instructions.Add(new YieldReturn(value).WithILRange(oldInst));
ConvertBranchAfterYieldReturn(newBlock, oldBlock, oldInst.ChildIndex + 1);
break; // we're done with this basic block
}
@ -696,7 +694,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -696,7 +694,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
// copy over the instruction to the new block
newBlock.Instructions.Add(oldInst);
newBlock.AddILRange(oldInst.ILRange);
newBlock.AddILRange(oldInst);
UpdateBranchTargets(oldInst);
}
}
@ -781,7 +779,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -781,7 +779,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
{
if (newBlock.Instructions.Count > 0) {
var newBlock2 = new Block();
newBlock2.ILRange = new Interval(oldInst.ILRange.Start, oldInst.ILRange.Start);
newBlock2.AddILRange(new Interval(oldInst.StartILOffset, oldInst.StartILOffset));
newBody.Blocks.Add(newBlock2);
newBlock.Instructions.Add(new Branch(newBlock2));
newBlock = newBlock2;
@ -821,9 +819,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -821,9 +819,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
if (value.MatchLdcI4(0)) {
// yield break
leave.ReplaceWith(new Leave(newBody) { ILRange = leave.ILRange });
leave.ReplaceWith(new Leave(newBody).WithILRange(leave));
} else {
leave.ReplaceWith(new InvalidBranch("Unexpected return in MoveNext()") { ILRange = leave.ILRange });
leave.ReplaceWith(new InvalidBranch("Unexpected return in MoveNext()").WithILRange(leave));
}
} else {
if (leave.TargetContainer == oldBody) {
@ -861,25 +859,25 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -861,25 +859,25 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
if (v.StackType == StackType.Ref) {
Debug.Assert(v.Kind == VariableKind.Parameter && v.Index < 0); // this pointer
inst.ReplaceWith(new LdLoc(v) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoc(v).WithILRange(inst));
} else {
inst.ReplaceWith(new LdLoca(v) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoca(v).WithILRange(inst));
}
} else if (!isCompiledWithMono && inst.MatchLdThis()) {
inst.ReplaceWith(new InvalidExpression("stateMachine") { ExpectedResultType = inst.ResultType, ILRange = inst.ILRange });
inst.ReplaceWith(new InvalidExpression("stateMachine") { ExpectedResultType = inst.ResultType }.WithILRange(inst));
} else {
foreach (var child in inst.Children) {
TranslateFieldsToLocalAccess(function, child, fieldToVariableMap, isCompiledWithMono);
}
if (inst is LdObj ldobj && ldobj.Target is LdLoca ldloca && ldloca.Variable.StateMachineField != null) {
LdLoc ldloc = new LdLoc(ldloca.Variable);
ldloc.AddILRange(ldobj.ILRange);
ldloc.AddILRange(ldloca.ILRange);
ldloc.AddILRange(ldobj);
ldloc.AddILRange(ldloca);
inst.ReplaceWith(ldloc);
} else if (inst is StObj stobj && stobj.Target is LdLoca ldloca2 && ldloca2.Variable.StateMachineField != null) {
StLoc stloc = new StLoc(ldloca2.Variable, stobj.Value);
stloc.AddILRange(stobj.ILRange);
stloc.AddILRange(ldloca2.ILRange);
stloc.AddILRange(stobj);
stloc.AddILRange(ldloca2);
inst.ReplaceWith(stloc);
}
}
@ -988,11 +986,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -988,11 +986,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
finallyMethodToStateRange.Remove(finallyMethod);
var tryBlock = new Block();
tryBlock.ILRange = block.ILRange;
tryBlock.AddILRange(block);
tryBlock.Instructions.AddRange(block.Instructions);
var tryBlockContainer = new BlockContainer();
tryBlockContainer.Blocks.Add(tryBlock);
tryBlockContainer.ILRange = tryBlock.ILRange;
tryBlockContainer.AddILRange(tryBlock);
stateToContainer.Add(state, tryBlockContainer);
ILInstruction finallyBlock;
@ -1006,7 +1004,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -1006,7 +1004,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
block.Instructions.Clear();
block.Instructions.Add(new TryFinally(tryBlockContainer, finallyBlock) { ILRange = tryBlockContainer.ILRange});
block.Instructions.Add(new TryFinally(tryBlockContainer, finallyBlock).WithILRange(tryBlockContainer));
}
IMethod FindFinallyMethod(int state)

22
ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
{
internal static class ILInstructionExtensions
{
public static T WithILRange<T>(this T target, ILInstruction sourceInstruction) where T : ILInstruction
{
target.AddILRange(sourceInstruction);
return target;
}
public static T WithILRange<T>(this T target, Interval range) where T : ILInstruction
{
target.AddILRange(range);
return target;
}
}
}

23
ICSharpCode.Decompiler/IL/ILReader.cs

@ -389,8 +389,8 @@ namespace ICSharpCode.Decompiler.IL @@ -389,8 +389,8 @@ namespace ICSharpCode.Decompiler.IL
Warn("Unknown result type (might be due to invalid IL or missing references)");
decodedInstruction.CheckInvariant(ILPhase.InILReader);
int end = reader.Offset;
decodedInstruction.ILRange = new Interval(start, end);
UnpackPush(decodedInstruction).ILRange = decodedInstruction.ILRange;
decodedInstruction.AddILRange(new Interval(start, end));
UnpackPush(decodedInstruction).AddILRange(decodedInstruction);
instructionBuilder.Add(decodedInstruction);
if (decodedInstruction.HasDirectFlag(InstructionFlags.EndPointUnreachable)) {
if (!stackByOffset.TryGetValue(end, out currentStack)) {
@ -429,8 +429,7 @@ namespace ICSharpCode.Decompiler.IL @@ -429,8 +429,7 @@ namespace ICSharpCode.Decompiler.IL
value = new Conv(value, additionalVar.StackType.ToPrimitiveType(), false, Sign.Signed);
newInstructions.Add(new StLoc(additionalVar, value) {
IsStackAdjustment = true,
ILRange = inst.ILRange
});
}.WithILRange(inst));
}
}
}
@ -454,7 +453,7 @@ namespace ICSharpCode.Decompiler.IL @@ -454,7 +453,7 @@ namespace ICSharpCode.Decompiler.IL
}
output.Write(" [");
bool isFirstElement = true;
foreach (var element in stackByOffset[inst.ILRange.Start]) {
foreach (var element in stackByOffset[inst.StartILOffset]) {
if (isFirstElement)
isFirstElement = false;
else
@ -465,11 +464,11 @@ namespace ICSharpCode.Decompiler.IL @@ -465,11 +464,11 @@ namespace ICSharpCode.Decompiler.IL
}
output.Write(']');
output.WriteLine();
if (isBranchTarget[inst.ILRange.Start])
if (isBranchTarget[inst.StartILOffset])
output.Write('*');
else
output.Write(' ');
output.WriteLocalReference("IL_" + inst.ILRange.Start.ToString("x4"), inst.ILRange.Start, isDefinition: true);
output.WriteLocalReference("IL_" + inst.StartILOffset.ToString("x4"), inst.StartILOffset, isDefinition: true);
output.Write(": ");
inst.WriteTo(output, new ILAstWritingOptions());
output.WriteLine();
@ -1033,7 +1032,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1033,7 +1032,7 @@ namespace ICSharpCode.Decompiler.IL
var variable = unionFind.Find(inst.Variable);
if (variables.Add(variable))
variable.Name = "S_" + (variables.Count - 1);
return new LdLoc(variable) { ILRange = inst.ILRange };
return new LdLoc(variable).WithILRange(inst);
}
return inst;
}
@ -1045,7 +1044,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1045,7 +1044,7 @@ namespace ICSharpCode.Decompiler.IL
var variable = unionFind.Find(inst.Variable);
if (variables.Add(variable))
variable.Name = "S_" + (variables.Count - 1);
return new StLoc(variable, inst.Value) { ILRange = inst.ILRange };
return new StLoc(variable, inst.Value).WithILRange(inst);
}
return inst;
}
@ -1064,7 +1063,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1064,7 +1063,7 @@ namespace ICSharpCode.Decompiler.IL
ILInstruction Peek()
{
if (currentStack.IsEmpty) {
return new InvalidExpression("Stack underflow") { ILRange = new Interval(reader.Offset, reader.Offset) };
return new InvalidExpression("Stack underflow").WithILRange(new Interval(reader.Offset, reader.Offset));
}
return new LdLoc(currentStack.Peek());
}
@ -1072,7 +1071,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1072,7 +1071,7 @@ namespace ICSharpCode.Decompiler.IL
ILInstruction Pop()
{
if (currentStack.IsEmpty) {
return new InvalidExpression("Stack underflow") { ILRange = new Interval(reader.Offset, reader.Offset) };
return new InvalidExpression("Stack underflow").WithILRange(new Interval(reader.Offset, reader.Offset));
}
ILVariable v;
currentStack = currentStack.Pop(out v);
@ -1490,7 +1489,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1490,7 +1489,7 @@ namespace ICSharpCode.Decompiler.IL
int start = reader.Offset - 1; // opCode is always one byte in this case
int target = ILParser.DecodeBranchTarget(ref reader, opCode);
var condition = Comparison(kind, un);
condition.ILRange = new Interval(start, reader.Offset);
condition.AddILRange(new Interval(start, reader.Offset));
if (!IsInvalidBranch(target)) {
MarkBranchTarget(target);
return new IfInstruction(condition, new Branch(target));

82
ICSharpCode.Decompiler/IL/Instructions.cs

@ -346,7 +346,7 @@ namespace ICSharpCode.Decompiler.IL @@ -346,7 +346,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.argument.WriteTo(output, options);
@ -439,7 +439,7 @@ namespace ICSharpCode.Decompiler.IL @@ -439,7 +439,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.left.WriteTo(output, options);
@ -596,7 +596,7 @@ namespace ICSharpCode.Decompiler.IL @@ -596,7 +596,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.target.WriteTo(output, options);
@ -971,7 +971,7 @@ namespace ICSharpCode.Decompiler.IL @@ -971,7 +971,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
variable.WriteTo(output);
@ -2282,7 +2282,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2282,7 +2282,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
variable.WriteTo(output);
@ -2357,7 +2357,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2357,7 +2357,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
variable.WriteTo(output);
@ -2490,7 +2490,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2490,7 +2490,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
variable.WriteTo(output);
@ -2585,7 +2585,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2585,7 +2585,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.value.WriteTo(output, options);
@ -2748,7 +2748,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2748,7 +2748,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -2785,7 +2785,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2785,7 +2785,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.I4; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -2822,7 +2822,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2822,7 +2822,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.I8; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -2859,7 +2859,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2859,7 +2859,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.F4; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -2896,7 +2896,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2896,7 +2896,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.F8; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -2933,7 +2933,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2933,7 +2933,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, Value);
@ -3000,7 +3000,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3000,7 +3000,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.I; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
method.WriteTo(output);
@ -3048,7 +3048,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3048,7 +3048,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
method.WriteTo(output);
@ -3093,7 +3093,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3093,7 +3093,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -3132,7 +3132,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3132,7 +3132,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
member.WriteTo(output);
@ -3220,7 +3220,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3220,7 +3220,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -3355,7 +3355,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3355,7 +3355,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (IsVolatile)
output.Write("volatile.");
if (UnalignedPrefix > 0)
@ -3503,7 +3503,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3503,7 +3503,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (IsVolatile)
output.Write("volatile.");
if (UnalignedPrefix > 0)
@ -3616,7 +3616,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3616,7 +3616,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (DelayExceptions)
output.Write("delayex.");
output.Write(OpCode);
@ -3660,7 +3660,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3660,7 +3660,7 @@ namespace ICSharpCode.Decompiler.IL
public IField Field { get { return field; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
field.WriteTo(output);
@ -3711,7 +3711,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3711,7 +3711,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -3756,7 +3756,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3756,7 +3756,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -3862,7 +3862,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3862,7 +3862,7 @@ namespace ICSharpCode.Decompiler.IL
}
void OriginalWriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (IsVolatile)
output.Write("volatile.");
if (UnalignedPrefix > 0)
@ -3996,7 +3996,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3996,7 +3996,7 @@ namespace ICSharpCode.Decompiler.IL
}
void OriginalWriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (IsVolatile)
output.Write("volatile.");
if (UnalignedPrefix > 0)
@ -4062,7 +4062,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4062,7 +4062,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4116,7 +4116,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4116,7 +4116,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4170,7 +4170,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4170,7 +4170,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4284,7 +4284,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4284,7 +4284,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4333,7 +4333,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4333,7 +4333,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return type.GetStackType(); } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4449,7 +4449,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4449,7 +4449,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.I4; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -4643,7 +4643,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4643,7 +4643,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (DelayExceptions)
output.Write("delayex.");
if (IsReadOnly)
@ -4747,7 +4747,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4747,7 +4747,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.array.WriteTo(output, options);
@ -4984,7 +4984,7 @@ namespace ICSharpCode.Decompiler.IL @@ -4984,7 +4984,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
method.WriteTo(output);
@ -5999,7 +5999,7 @@ namespace ICSharpCode.Decompiler.IL @@ -5999,7 +5999,7 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -6081,7 +6081,7 @@ namespace ICSharpCode.Decompiler.IL @@ -6081,7 +6081,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
type.WriteTo(output);
@ -6176,7 +6176,7 @@ namespace ICSharpCode.Decompiler.IL @@ -6176,7 +6176,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.value.WriteTo(output, options);
@ -6269,7 +6269,7 @@ namespace ICSharpCode.Decompiler.IL @@ -6269,7 +6269,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.value.WriteTo(output, options);
@ -6331,7 +6331,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns @@ -6331,7 +6331,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
output.Write(')');

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -595,7 +595,7 @@ namespace ICSharpCode.Decompiler.IL @@ -595,7 +595,7 @@ namespace ICSharpCode.Decompiler.IL
public IEnumerable<string> WriteToBody {
get {
yield return "ILRange.WriteTo(output, options);";
yield return "WriteILRange(output, options);";
foreach (string line in WriteOpCodePrefix)
yield return line;
yield return "output.Write(OpCode);";

2
ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs

@ -177,7 +177,7 @@ namespace ICSharpCode.Decompiler.IL @@ -177,7 +177,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write("." + GetOperatorName(Operator));
if (CheckForOverflow) {

6
ICSharpCode.Decompiler/IL/Instructions/Block.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.Decompiler.IL @@ -95,7 +95,7 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
Block clone = new Block(Kind);
clone.ILRange = this.ILRange;
clone.AddILRange(this);
clone.Instructions.AddRange(this.Instructions.Select(inst => inst.Clone()));
clone.FinalInstruction = this.FinalInstruction.Clone();
return clone;
@ -145,12 +145,12 @@ namespace ICSharpCode.Decompiler.IL @@ -145,12 +145,12 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public string Label
{
get { return Disassembler.DisassemblerHelpers.OffsetToString(this.ILRange.Start); }
get { return Disassembler.DisassemblerHelpers.OffsetToString(this.StartILOffset); }
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("Block ");
output.WriteLocalReference(Label, this, isDefinition: true);
if (Kind != BlockKind.ControlFlow)

6
ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs

@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.IL @@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
BlockContainer clone = new BlockContainer();
clone.ILRange = this.ILRange;
clone.AddILRange(this);
clone.Blocks.AddRange(this.Blocks.Select(block => (Block)block.Clone()));
// Adjust branch instructions to point to the new container
foreach (var branch in clone.Descendants.OfType<Branch>()) {
@ -117,7 +117,7 @@ namespace ICSharpCode.Decompiler.IL @@ -117,7 +117,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.WriteLocalReference("BlockContainer", this, isDefinition: true);
output.Write(' ');
switch (Kind) {
@ -181,7 +181,7 @@ namespace ICSharpCode.Decompiler.IL @@ -181,7 +181,7 @@ namespace ICSharpCode.Decompiler.IL
base.CheckInvariant(phase);
Debug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]);
Debug.Assert(!IsConnected || EntryPoint?.IncomingEdgeCount >= 1);
Debug.Assert(EntryPoint == null || Parent is ILFunction || !ILRange.IsEmpty);
Debug.Assert(EntryPoint == null || Parent is ILFunction || !HasILRange);
Debug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable)));
Debug.Assert(Blocks.All(b => b.Kind == BlockKind.ControlFlow)); // this also implies that the blocks don't use FinalInstruction
Block bodyStartBlock;

6
ICSharpCode.Decompiler/IL/Instructions/Branch.cs

@ -40,11 +40,11 @@ namespace ICSharpCode.Decompiler.IL @@ -40,11 +40,11 @@ namespace ICSharpCode.Decompiler.IL
public Branch(Block targetBlock) : base(OpCode.Branch)
{
this.targetBlock = targetBlock ?? throw new ArgumentNullException(nameof(targetBlock));
this.targetILOffset = targetBlock.ILRange.Start;
this.targetILOffset = targetBlock.StartILOffset;
}
public int TargetILOffset {
get { return targetBlock != null ? targetBlock.ILRange.Start : targetILOffset; }
get { return targetBlock != null ? targetBlock.StartILOffset : targetILOffset; }
}
public Block TargetBlock {
@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.IL @@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
output.WriteLocalReference(TargetLabel, (object)targetBlock ?? TargetILOffset);

6
ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs

@ -76,9 +76,7 @@ namespace ICSharpCode.Decompiler.IL @@ -76,9 +76,7 @@ namespace ICSharpCode.Decompiler.IL
{
return new CallIndirect(CallingConvention, ReturnType, ParameterTypes,
this.Arguments.Select(inst => inst.Clone()), functionPointer.Clone()
) {
ILRange = this.ILRange
};
).WithILRange(this);
}
public override StackType ResultType => ReturnType.GetStackType();
@ -91,7 +89,7 @@ namespace ICSharpCode.Decompiler.IL @@ -91,7 +89,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("call.indirect ");
ReturnType.WriteTo(output);
output.Write('(');

2
ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs

@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.IL @@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (ConstrainedTo != null) {
output.Write("constrained[");
ConstrainedTo.WriteTo(output, ILNameSyntax.ShortTypeName);

7
ICSharpCode.Decompiler/IL/Instructions/Comp.cs

@ -175,7 +175,7 @@ namespace ICSharpCode.Decompiler.IL @@ -175,7 +175,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (options.UseLogicOperationSugar && MatchLogicNot(out var arg)) {
output.Write("logic.not(");
arg.WriteTo(output, options);
@ -214,11 +214,6 @@ namespace ICSharpCode.Decompiler.IL @@ -214,11 +214,6 @@ namespace ICSharpCode.Decompiler.IL
{
return new Comp(ComparisonKind.Equality, Sign.None, arg, new LdcI4(0));
}
public static Comp LogicNot(ILInstruction arg, Interval ilrange)
{
return new Comp(ComparisonKind.Equality, Sign.None, arg, new LdcI4(0)) { ILRange = ilrange };
}
}
}

8
ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.Decompiler.IL @@ -94,7 +94,7 @@ namespace ICSharpCode.Decompiler.IL
this.Operator = binary.Operator;
this.IsLifted = binary.IsLifted;
this.type = type;
this.ILRange = binary.ILRange;
this.AddILRange(binary);
Debug.Assert(compoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue || (Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub));
Debug.Assert(IsValidCompoundAssignmentTarget(Target));
}
@ -172,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL @@ -172,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write("." + BinaryNumericInstruction.GetOperatorName(Operator));
if (CompoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue)
@ -216,7 +216,7 @@ namespace ICSharpCode.Decompiler.IL @@ -216,7 +216,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (CompoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue)
@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.IL @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write("." + Operation.ToString().ToLower());
DynamicInstruction.WriteBinderFlags(BinderFlags, output, options);

2
ICSharpCode.Decompiler/IL/Instructions/Conv.cs

@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.IL @@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (CheckForOverflow) {
output.Write(".ovf");

24
ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.IL @@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.IL
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -180,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL @@ -180,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.IL @@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.IL @@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -297,7 +297,7 @@ namespace ICSharpCode.Decompiler.IL @@ -297,7 +297,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -329,7 +329,7 @@ namespace ICSharpCode.Decompiler.IL @@ -329,7 +329,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -361,7 +361,7 @@ namespace ICSharpCode.Decompiler.IL @@ -361,7 +361,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -397,7 +397,7 @@ namespace ICSharpCode.Decompiler.IL @@ -397,7 +397,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -438,7 +438,7 @@ namespace ICSharpCode.Decompiler.IL @@ -438,7 +438,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -484,7 +484,7 @@ namespace ICSharpCode.Decompiler.IL @@ -484,7 +484,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -529,7 +529,7 @@ namespace ICSharpCode.Decompiler.IL @@ -529,7 +529,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
@ -559,7 +559,7 @@ namespace ICSharpCode.Decompiler.IL @@ -559,7 +559,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');

2
ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.Decompiler.IL @@ -18,7 +18,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (IsChecked) output.Write(".checked");
output.Write(' ');

4
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -121,7 +121,7 @@ namespace ICSharpCode.Decompiler.IL @@ -121,7 +121,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (Method != null) {
output.Write(' ');
@ -183,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL @@ -183,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL
void MarkUsedILRanges(ILInstruction inst)
{
if (CSharp.SequencePointBuilder.HasUsableILRange(inst)) {
usedILRanges.Add(new LongInterval(inst.ILRange.Start, inst.ILRange.End));
usedILRanges.Add(new LongInterval(inst.StartILOffset, inst.EndILOffset));
}
if (!(inst is ILFunction)) {
foreach (var child in inst.Children) {

42
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -206,19 +206,19 @@ namespace ICSharpCode.Decompiler.IL @@ -206,19 +206,19 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// Gets the ILRange for this instruction alone, ignoring the operands.
/// </summary>
public Interval ILRange;
private Interval ILRange;
public void AddILRange(Interval newRange)
{
if (newRange.IsEmpty) {
return;
}
if (this.ILRange.IsEmpty) {
this.ILRange = newRange;
return;
}
if (newRange.Start <= this.ILRange.Start) {
if (newRange.End < this.ILRange.Start) {
if (newRange.IsEmpty) {
return;
}
if (newRange.Start <= this.StartILOffset) {
if (newRange.End < this.StartILOffset) {
this.ILRange = newRange; // use the earlier range
} else {
// join overlapping ranges
@ -226,10 +226,38 @@ namespace ICSharpCode.Decompiler.IL @@ -226,10 +226,38 @@ namespace ICSharpCode.Decompiler.IL
}
} else if (newRange.Start <= this.ILRange.End) {
// join overlapping ranges
this.ILRange = new Interval(this.ILRange.Start, Math.Max(newRange.End, this.ILRange.End));
this.ILRange = new Interval(this.StartILOffset, Math.Max(newRange.End, this.ILRange.End));
}
}
public void AddILRange(ILInstruction sourceInstruction)
{
AddILRange(sourceInstruction.ILRange);
}
public void SetILRange(ILInstruction sourceInstruction)
{
ILRange = sourceInstruction.ILRange;
}
public void SetILRange(Interval range)
{
ILRange = range;
}
public int StartILOffset => ILRange.Start;
public int EndILOffset => ILRange.End;
public bool HasILRange => ILRange.IsEmpty;
public IEnumerable<Interval> ILRanges => new[] { ILRange };
public void WriteILRange(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
}
/// <summary>
/// Writes the ILAst to the text output.
/// </summary>

2
ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.IL @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
if (options.UseLogicOperationSugar) {
if (MatchLogicAnd(out var lhs, out var rhs)) {
output.Write("logic.and(");

2
ICSharpCode.Decompiler/IL/Instructions/LdLen.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.IL @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write('.');
output.Write(resultType);

2
ICSharpCode.Decompiler/IL/Instructions/Leave.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL @@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (targetContainer != null) {
output.Write(' ');

2
ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.Decompiler.IL @@ -28,7 +28,7 @@ namespace ICSharpCode.Decompiler.IL
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("lock (");
OnExpression.WriteTo(output, options);
output.WriteLine(") {");

8
ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL
{
if (options.UseFieldSugar) {
if (this.MatchLdFld(out var target, out var field)) {
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("ldfld ");
field.WriteTo(output);
output.Write('(');
@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.IL @@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')');
return;
} else if (this.MatchLdsFld(out field)) {
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("ldsfld ");
field.WriteTo(output);
return;
@ -65,7 +65,7 @@ namespace ICSharpCode.Decompiler.IL @@ -65,7 +65,7 @@ namespace ICSharpCode.Decompiler.IL
{
if (options.UseFieldSugar) {
if (this.MatchStFld(out var target, out var field, out var value)) {
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("stfld ");
field.WriteTo(output);
output.Write('(');
@ -75,7 +75,7 @@ namespace ICSharpCode.Decompiler.IL @@ -75,7 +75,7 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')');
return;
} else if (this.MatchStsFld(out field, out value)) {
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("stsfld ");
field.WriteTo(output);
output.Write('(');

2
ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs

@ -91,7 +91,7 @@ namespace ICSharpCode.Decompiler.IL @@ -91,7 +91,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
output.Write("(");
valueInst.WriteTo(output, options);

8
ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.IL @@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.IL
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
// the non-custom WriteTo would add useless parentheses
}
@ -46,7 +46,7 @@ namespace ICSharpCode.Decompiler.IL @@ -46,7 +46,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (Kind != NopKind.Normal) {
output.Write("." + Kind.ToString().ToLowerInvariant());
@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.IL @@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (!string.IsNullOrEmpty(Message)) {
output.Write("(\"");
@ -100,7 +100,7 @@ namespace ICSharpCode.Decompiler.IL @@ -100,7 +100,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (!string.IsNullOrEmpty(Message)) {
output.Write("(\"");

2
ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs

@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL @@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("string.to.int (");
Argument.WriteTo(output, options);
output.Write(", { ");

6
ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.IL @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("switch");
if (IsLifted)
output.Write(".lifted");
@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.IL @@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
var clone = new SwitchInstruction(value.Clone());
clone.ILRange = this.ILRange;
clone.AddILRange(this);
clone.Value = value.Clone();
clone.Sections.AddRange(this.Sections.Select(h => (SwitchSection)h.Clone()));
return clone;
@ -182,7 +182,7 @@ namespace ICSharpCode.Decompiler.IL @@ -182,7 +182,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.WriteLocalReference("case", this, isDefinition: true);
output.Write(' ');
if (HasNullLabel) {

18
ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs

@ -60,14 +60,14 @@ namespace ICSharpCode.Decompiler.IL @@ -60,14 +60,14 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
var clone = new TryCatch(TryBlock.Clone());
clone.ILRange = this.ILRange;
clone.AddILRange(this);
clone.Handlers.AddRange(this.Handlers.Select(h => (TryCatchHandler)h.Clone()));
return clone;
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(".try ");
TryBlock.WriteTo(output, options);
foreach (var handler in Handlers) {
@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.IL @@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("catch ");
if (variable != null) {
output.WriteLocalReference(variable.Name, variable, isDefinition: true);
@ -197,14 +197,12 @@ namespace ICSharpCode.Decompiler.IL @@ -197,14 +197,12 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
return new TryFinally(TryBlock.Clone(), finallyBlock.Clone()) {
ILRange = this.ILRange
};
return new TryFinally(TryBlock.Clone(), finallyBlock.Clone()).WithILRange(this);
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(".try ");
TryBlock.WriteTo(output, options);
output.Write(" finally ");
@ -293,14 +291,12 @@ namespace ICSharpCode.Decompiler.IL @@ -293,14 +291,12 @@ namespace ICSharpCode.Decompiler.IL
public override ILInstruction Clone()
{
return new TryFault(TryBlock.Clone(), faultBlock.Clone()) {
ILRange = this.ILRange
};
return new TryFault(TryBlock.Clone(), faultBlock.Clone()).WithILRange(this);
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(".try ");
TryBlock.WriteTo(output, options);
output.Write(" fault ");

2
ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs

@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.IL @@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.IL
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write(OpCode);
if (IsLifted) {
output.Write(".lifted");

2
ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.Decompiler.IL @@ -38,7 +38,7 @@ namespace ICSharpCode.Decompiler.IL
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
WriteILRange(output, options);
output.Write("using (");
Variable.WriteTo(output);
output.Write(" = ");

4
ICSharpCode.Decompiler/IL/PointerArithmeticOffset.cs

@ -44,14 +44,14 @@ namespace ICSharpCode.Decompiler.IL @@ -44,14 +44,14 @@ namespace ICSharpCode.Decompiler.IL
return countOffsetInst;
}
} else if (byteOffsetInst.UnwrapConv(ConversionKind.SignExtend) is SizeOf sizeOf && sizeOf.Type.Equals(pointerType.ElementType)) {
return new LdcI4(1) { ILRange = byteOffsetInst.ILRange };
return new LdcI4(1).WithILRange(byteOffsetInst);
} else if (byteOffsetInst.MatchLdcI(out long val)) {
// If the offset is a constant, it's possible that the compiler
// constant-folded the multiplication.
if (elementSize > 0 && (val % elementSize == 0) && val > 0) {
val /= elementSize.Value;
if (val <= int.MaxValue) {
return new LdcI4((int)val) { ILRange = byteOffsetInst.ILRange };
return new LdcI4((int)val).WithILRange(byteOffsetInst);
}
}
}

8
ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs

@ -41,9 +41,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -41,9 +41,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// leave (elseValue)
// =>
// leave (if (cond) value else elseValue)
IfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value) { ILRange = ifInst.ILRange };
Leave combinedLeave = new Leave(leave.TargetContainer, value) { ILRange = leaveElse.ILRange };
combinedLeave.AddILRange(leave.ILRange);
IfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value);
value.AddILRange(ifInst);
Leave combinedLeave = new Leave(leave.TargetContainer, value);
combinedLeave.AddILRange(leaveElse);
combinedLeave.AddILRange(leave);
ifInst.ReplaceWith(combinedLeave);
block.Instructions.RemoveAt(combinedLeave.ChildIndex + 1);
}

4
ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else {
// evaluate the value for its side-effects
context.Step("remove dead store to stack: evaluate the value for its side-effects", block.Instructions[i]);
copiedExpr.AddILRange(block.Instructions[i].ILRange);
copiedExpr.AddILRange(block.Instructions[i]);
block.Instructions[i] = copiedExpr;
}
} else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) {
@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var arg = copiedExpr.Children[j];
var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode());
uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType) {
Name = "C_" + arg.ILRange.Start,
Name = "C_" + arg.StartILOffset,
HasGeneratedName = true,
};
block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg));

24
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -44,7 +44,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
foreach (var inst in function.Descendants) {
cancellationToken.ThrowIfCancellationRequested();
if (inst is NewObj call) {
context.StepStartGroup($"TransformDelegateConstruction {call.ILRange}", call);
context.StepStartGroup($"TransformDelegateConstruction {call.StartILOffset}", call);
ILFunction f = TransformDelegateConstruction(call, out ILInstruction target);
if (f != null && target is IInstructionWithVariableOperand instWithVar) {
if (instWithVar.Variable.Kind == VariableKind.Local) {
@ -65,7 +65,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -65,7 +65,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
}
foreach (var target in targetsToReplace.OrderByDescending(t => ((ILInstruction)t).ILRange.Start)) {
foreach (var target in targetsToReplace.OrderByDescending(t => ((ILInstruction)t).StartILOffset)) {
context.Step($"TransformDisplayClassUsages {target.Variable}", (ILInstruction)target);
function.AcceptVisitor(new TransformDisplayClassUsages(function, target, target.Variable.CaptureScope, orphanedVariableInits, translatedDisplayClasses));
}
@ -204,9 +204,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -204,9 +204,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
nestedContext.StepStartGroup("DelegateConstruction (nested lambdas)", function);
((IILTransform)new DelegateConstruction()).Run(function, nestedContext);
nestedContext.StepEndGroup();
function.AddILRange(target.ILRange);
function.AddILRange(value.ILRange);
function.AddILRange(value.Arguments[1].ILRange);
function.AddILRange(target);
function.AddILRange(value);
function.AddILRange(value.Arguments[1]);
return function;
}
@ -322,7 +322,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -322,7 +322,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
field = (IField)field.MemberDefinition;
ILInstruction value;
if (initValues.TryGetValue(field, out DisplayClassVariable info)) {
inst.ReplaceWith(new StLoc(info.variable, inst.Value) { ILRange = inst.ILRange });
inst.ReplaceWith(new StLoc(info.variable, inst.Value).WithILRange(inst));
} else {
if (inst.Value.MatchLdLoc(out var v) && v.Kind == VariableKind.Parameter && currentFunction == v.Function) {
// special case for parameters: remove copies of parameter values.
@ -333,7 +333,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -333,7 +333,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return;
v = currentFunction.RegisterVariable(VariableKind.Local, field.Type, field.Name);
v.CaptureScope = captureScope;
inst.ReplaceWith(new StLoc(v, inst.Value) { ILRange = inst.ILRange });
inst.ReplaceWith(new StLoc(v, inst.Value).WithILRange(inst));
value = new LdLoc(v);
}
initValues.Add(field, new DisplayClassVariable { value = value, variable = v });
@ -348,7 +348,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -348,7 +348,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!initValues.TryGetValue((IField)field.MemberDefinition, out DisplayClassVariable info))
return;
var replacement = info.value.Clone();
replacement.ILRange = inst.ILRange;
replacement.SetILRange(inst);
inst.ReplaceWith(replacement);
}
@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (inst.Target.MatchLdThis() && inst.Field.Name == "$this"
&& inst.Field.MemberDefinition.ReflectionName.Contains("c__Iterator")) {
var variable = currentFunction.Variables.First((f) => f.Index == -1);
inst.ReplaceWith(new LdLoca(variable) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoca(variable).WithILRange(inst));
}
if (inst.Parent is LdObj || inst.Parent is StObj)
return;
@ -370,11 +370,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -370,11 +370,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return;
var v = currentFunction.RegisterVariable(VariableKind.Local, field.Type, field.Name);
v.CaptureScope = captureScope;
inst.ReplaceWith(new LdLoca(v) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoca(v).WithILRange(inst));
var value = new LdLoc(v);
initValues.Add(field, new DisplayClassVariable { value = value, variable = v });
} else if (info.value is LdLoc l) {
inst.ReplaceWith(new LdLoca(l.Variable) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoca(l.Variable).WithILRange(inst));
} else {
Debug.Fail("LdFlda pattern not supported!");
}
@ -384,7 +384,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -384,7 +384,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
base.VisitNumericCompoundAssign(inst);
if (inst.Target.MatchLdLoc(out var v)) {
inst.ReplaceWith(new StLoc(v, new BinaryNumericInstruction(inst.Operator, inst.Target, inst.Value, inst.CheckForOverflow, inst.Sign) { ILRange = inst.ILRange }));
inst.ReplaceWith(new StLoc(v, new BinaryNumericInstruction(inst.Operator, inst.Target, inst.Value, inst.CheckForOverflow, inst.Sign).WithILRange(inst)));
}
}
}

6
ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs

@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
&& !inst.IsVolatile)
{
context.Step($"stobj(ldloca {v.Name}, ...) => stloc {v.Name}(...)", inst);
inst.ReplaceWith(new StLoc(v, inst.Value) { ILRange = inst.ILRange });
inst.ReplaceWith(new StLoc(v, inst.Value).WithILRange(inst));
return true;
}
return false;
@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
&& !inst.IsVolatile)
{
context.Step($"ldobj(ldloca {v.Name}) => ldloc {v.Name}", inst);
inst.ReplaceWith(new LdLoc(v) { ILRange = inst.ILRange });
inst.ReplaceWith(new LdLoc(v).WithILRange(inst));
return true;
}
return false;
@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// call(ref, ...)
// => stobj(ref, newobj(...))
var newObj = new NewObj(inst.Method);
newObj.ILRange = inst.ILRange;
newObj.AddILRange(inst);
newObj.Arguments.AddRange(inst.Arguments.Skip(1));
newObj.ILStackWasEmpty = inst.ILStackWasEmpty;
var expr = new StObj(inst.Arguments[0], newObj, inst.Method.DeclaringType);

34
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// if (comp(x != 0)) ==> if (x)
// comp(comp(...) != 0) => comp(...)
context.Step("Remove redundant comp(... != 0)", inst);
inst.Left.AddILRange(inst.ILRange);
inst.Left.AddILRange(inst);
inst.ReplaceWith(inst.Left);
inst.Left.AcceptVisitor(this);
return;
@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// This is a special case where the C# compiler doesn't generate conv.i4 after ldlen.
context.Step("comp(ldlen.i4 array == ldc.i4 0)", inst);
inst.InputType = StackType.I4;
inst.Left.ReplaceWith(new LdLen(StackType.I4, array) { ILRange = inst.Left.ILRange });
inst.Left.ReplaceWith(new LdLen(StackType.I4, array).WithILRange(inst.Left));
inst.Right = rightWithoutConv;
} else if (inst.Left is Conv conv && conv.TargetType == PrimitiveType.I && conv.Argument.ResultType == StackType.O) {
// C++/CLI sometimes uses this weird comparison with null:
@ -137,8 +137,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -137,8 +137,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// -> comp(ldloc obj == ldnull)
inst.InputType = StackType.O;
inst.Left = conv.Argument;
inst.Right = new LdNull { ILRange = inst.Right.ILRange };
inst.Right.AddILRange(rightWithoutConv.ILRange);
inst.Right = new LdNull().WithILRange(inst.Right);
inst.Right.AddILRange(rightWithoutConv);
}
}
@ -161,8 +161,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -161,8 +161,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
&& (!inst.CheckForOverflow || context.Settings.AssumeArrayLengthFitsIntoInt32))
{
context.Step("conv.i4(ldlen array) => ldlen.i4(array)", inst);
inst.AddILRange(inst.Argument.ILRange);
inst.ReplaceWith(new LdLen(inst.TargetType.GetStackType(), array) { ILRange = inst.ILRange });
inst.AddILRange(inst.Argument);
inst.ReplaceWith(new LdLen(inst.TargetType.GetStackType(), array).WithILRange(inst));
}
}
@ -172,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -172,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (inst.Type.IsReferenceType == true && inst.Argument.ResultType == inst.ResultType) {
// For reference types, box is a no-op.
context.Step("box ref-type(arg) => arg", inst);
inst.Argument.AddILRange(inst.ILRange);
inst.Argument.AddILRange(inst);
inst.ReplaceWith(inst.Argument);
}
}
@ -209,7 +209,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -209,7 +209,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if ((!comp.InputType.IsFloatType() && !comp.IsLifted) || comp.Kind.IsEqualityOrInequality()) {
context.Step("push negation into comparison", inst);
comp.Kind = comp.Kind.Negate();
comp.AddILRange(inst.ILRange);
comp.AddILRange(inst);
inst.ReplaceWith(comp);
}
comp.AcceptVisitor(this);
@ -220,9 +220,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -220,9 +220,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IfInstruction ifInst = (IfInstruction)arg;
var ldc0 = ifInst.FalseInst;
Debug.Assert(ldc0.MatchLdcI4(0));
ifInst.Condition = Comp.LogicNot(lhs, inst.ILRange);
ifInst.TrueInst = new LdcI4(1) { ILRange = ldc0.ILRange };
ifInst.FalseInst = Comp.LogicNot(rhs, inst.ILRange);
ifInst.Condition = Comp.LogicNot(lhs).WithILRange(inst);
ifInst.TrueInst = new LdcI4(1).WithILRange(ldc0);
ifInst.FalseInst = Comp.LogicNot(rhs).WithILRange(inst);
inst.ReplaceWith(ifInst);
ifInst.AcceptVisitor(this);
} else if (arg.MatchLogicOr(out lhs, out rhs)) {
@ -232,9 +232,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -232,9 +232,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IfInstruction ifInst = (IfInstruction)arg;
var ldc1 = ifInst.TrueInst;
Debug.Assert(ldc1.MatchLdcI4(1));
ifInst.Condition = Comp.LogicNot(lhs, inst.ILRange);
ifInst.TrueInst = Comp.LogicNot(rhs, inst.ILRange);
ifInst.FalseInst = new LdcI4(0) { ILRange = ldc1.ILRange };
ifInst.Condition = Comp.LogicNot(lhs).WithILRange(inst);
ifInst.TrueInst = Comp.LogicNot(rhs).WithILRange(inst);
ifInst.FalseInst = new LdcI4(0).WithILRange(ldc1);
inst.ReplaceWith(ifInst);
ifInst.AcceptVisitor(this);
} else {
@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var newVariable = initializerVariable.Function.RegisterVariable(VariableKind.InitializerTarget, type);
foreach (var load in initializerVariable.LoadInstructions.ToArray()) {
ILInstruction newInst = new LdLoc(newVariable);
newInst.AddILRange(load.ILRange);
newInst.AddILRange(load);
if (load.Parent != initializer)
newInst = new Conv(newInst, PrimitiveType.I, false, Sign.None);
load.ReplaceWith(newInst);
@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -425,7 +425,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
if (transformed != null) {
context.Step("User-defined short-circuiting logic operator (roslyn pattern)", condition);
transformed.AddILRange(inst.ILRange);
transformed.AddILRange(inst);
inst.ReplaceWith(transformed);
return;
}
@ -552,7 +552,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -552,7 +552,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (trueInst.Instructions[0].MatchStLoc(out v, out value1) && falseInst.Instructions[0].MatchStLoc(v, out value2)) {
context.Step("conditional operator", inst);
var newIf = new IfInstruction(Comp.LogicNot(inst.Condition), value2, value1);
newIf.ILRange = inst.ILRange;
newIf.AddILRange(inst);
inst.ReplaceWith(new StLoc(v, newIf));
context.RequestRerun(); // trigger potential inlining of the newly created StLoc
return newIf;

6
ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs

@ -186,9 +186,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -186,9 +186,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
// combine all conditions and the exit instruction into one IfInstruction:
IfInstruction condition = null;
conditionBlock.AddILRange(exit.ILRange);
conditionBlock.AddILRange(exit);
foreach (var inst in conditions) {
conditionBlock.AddILRange(inst.ILRange);
conditionBlock.AddILRange(inst);
if (condition == null) {
condition = inst;
if (swap) {
@ -414,7 +414,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -414,7 +414,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// move the increment instruction:
newIncremenBlock.Instructions.Add(secondToLast);
newIncremenBlock.Instructions.Add(last);
newIncremenBlock.AddILRange(secondToLast.ILRange);
newIncremenBlock.AddILRange(secondToLast);
whileLoopBody.Instructions.RemoveRange(secondToLastIndex, 2);
whileLoopBody.Instructions.Add(new Branch(newIncremenBlock));
// complete transform.

12
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -106,14 +106,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -106,14 +106,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ctorCallStart = function.Descendants.FirstOrDefault(d => d is CallInstruction call && !(call is NewObj)
&& call.Method.IsConstructor
&& call.Method.DeclaringType.IsReferenceType == true
&& call.Parent is Block)?.ILRange.Start ?? -1;
&& call.Parent is Block)?.StartILOffset ?? -1;
}
if (inst.ILRange.InclusiveEnd >= ctorCallStart.GetValueOrDefault())
if (inst.EndILOffset > ctorCallStart.GetValueOrDefault())
return false;
var topLevelInst = inst.Ancestors.LastOrDefault(instr => instr.Parent is Block);
if (topLevelInst == null)
return false;
return topLevelInst.ILRange.InclusiveEnd < ctorCallStart.GetValueOrDefault();
return topLevelInst.EndILOffset <= ctorCallStart.GetValueOrDefault();
}
internal static bool IsCatchWhenBlock(Block block)
@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
int pos = stloc.ChildIndex;
if (DoInline(v, stloc.Value, block.Instructions.ElementAtOrDefault(pos + 1), options, context)) {
// Assign the ranges of the stloc instruction:
stloc.Value.AddILRange(stloc.ILRange);
stloc.Value.AddILRange(stloc);
// Remove the stloc instruction:
Debug.Assert(block.Instructions[pos] == stloc);
block.Instructions.RemoveAt(pos);
@ -200,7 +200,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -200,7 +200,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else if (v.Kind == VariableKind.StackSlot) {
context.Step("Remove dead store, but keep expression", stloc);
// Assign the ranges of the stloc instruction:
stloc.Value.AddILRange(stloc.ILRange);
stloc.Value.AddILRange(stloc);
// Remove the stloc, but keep the inner expression
stloc.ReplaceWith(stloc.Value);
return true;
@ -233,7 +233,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -233,7 +233,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step($"Inline variable '{v.Name}'", inlinedExpression);
// Assign the ranges of the ldloc instruction:
inlinedExpression.AddILRange(loadInst.ILRange);
inlinedExpression.AddILRange(loadInst);
if (loadInst.OpCode == OpCode.LdLoca) {
// it was an ldloca instruction, so we need to use the pseudo-opcode 'addressof'

8
ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -86,7 +86,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step("LockTransformMCS", block);
block.Instructions.RemoveAt(i - 1);
block.Instructions.RemoveAt(i - 2);
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange });
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));
return true;
}
@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step("LockTransformV2", block);
block.Instructions.RemoveAt(i - 1);
block.Instructions.RemoveAt(i - 2);
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange });
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));
return true;
}
@ -173,7 +173,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -173,7 +173,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step("LockTransformV4", block);
block.Instructions.RemoveAt(i - 1);
tryContainer.EntryPoint.Instructions.RemoveAt(0);
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange });
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));
return true;
}
@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
block.Instructions.RemoveAt(i - 1);
block.Instructions.RemoveAt(i - 2);
tryContainer.EntryPoint.Instructions.RemoveAt(0);
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange });
body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));
return true;
}

29
ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// Check if "condition ? trueInst : falseInst" can be simplified using the null-conditional operator.
/// Returns the replacement instruction, or null if no replacement is possible.
/// </summary>
internal ILInstruction Run(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst, Interval ilRange)
internal ILInstruction Run(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst)
{
Debug.Assert(context.Settings.NullPropagation);
Debug.Assert(!condition.MatchLogicNot(out _), "Caller should pass in positive condition");
@ -80,16 +80,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -80,16 +80,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return null;
if (comp.Kind == ComparisonKind.Equality) {
// testedVar == null ? trueInst : falseInst
return TryNullPropagation(testedVar, falseInst, trueInst, Mode.ReferenceType, ilRange);
return TryNullPropagation(testedVar, falseInst, trueInst, Mode.ReferenceType);
} else if (comp.Kind == ComparisonKind.Inequality) {
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.ReferenceType, ilRange);
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.ReferenceType);
}
} else if (NullableLiftingTransform.MatchHasValueCall(condition, out ILInstruction loadInst)) {
// loadInst.HasValue ? trueInst : falseInst
if (loadInst.MatchLdLoca(out testedVar)) {
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByValue, ilRange);
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByValue);
} else if (loadInst.MatchLdLoc(out testedVar)) {
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByReference, ilRange);
return TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByReference);
}
}
return null;
@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// testedVar != null ? nonNullInst : nullInst
/// </summary>
ILInstruction TryNullPropagation(ILVariable testedVar, ILInstruction nonNullInst, ILInstruction nullInst,
Mode mode, Interval ilRange)
Mode mode)
{
bool removedRewrapOrNullableCtor = false;
if (NullableLiftingTransform.MatchNullableCtor(nonNullInst, out _, out var arg)) {
@ -118,13 +118,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -118,13 +118,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// testedVar != null ? testedVar.AccessChain : null
// => testedVar?.AccessChain
IntroduceUnwrap(testedVar, varLoad, mode);
return new NullableRewrap(nonNullInst) { ILRange = ilRange };
return new NullableRewrap(nonNullInst);
} else if (nullInst.MatchDefaultValue(out var type) && type.IsKnownType(KnownTypeCode.NullableOfT)) {
context.Step($"Null propagation (mode={mode}, output=value type)", nonNullInst);
// testedVar != null ? testedVar.AccessChain : default(T?)
// => testedVar?.AccessChain
IntroduceUnwrap(testedVar, varLoad, mode);
return new NullableRewrap(nonNullInst) { ILRange = ilRange };
return new NullableRewrap(nonNullInst);
} else if (!removedRewrapOrNullableCtor && NullableType.IsNonNullableValueType(returnType)) {
context.Step($"Null propagation (mode={mode}, output=null coalescing)", nonNullInst);
// testedVar != null ? testedVar.AccessChain : nullInst
@ -136,8 +136,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -136,8 +136,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
new NullableRewrap(nonNullInst),
nullInst
) {
UnderlyingResultType = nullInst.ResultType,
ILRange = ilRange
UnderlyingResultType = nullInst.ResultType
};
}
return null;
@ -180,7 +179,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -180,7 +179,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IntroduceUnwrap(testedVar, varLoad, mode);
ifInst.ReplaceWith(new NullableRewrap(
bodyInst
) { ILRange = ifInst.ILRange });
).WithILRange(ifInst));
}
bool IsValidAccessChain(ILVariable testedVar, Mode mode, ILInstruction inst, out ILInstruction finalLoad)
@ -286,15 +285,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -286,15 +285,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
Debug.Assert(NullableLiftingTransform.MatchGetValueOrDefault(varLoad, testedVar));
replacement = new NullableUnwrap(
varLoad.ResultType,
new LdLoc(testedVar) { ILRange = varLoad.Children[0].ILRange }
) { ILRange = varLoad.ILRange };
new LdLoc(testedVar).WithILRange(varLoad.Children[0])
).WithILRange(varLoad);
break;
case Mode.NullableByReference:
replacement = new NullableUnwrap(
varLoad.ResultType,
new LdLoc(testedVar) { ILRange = varLoad.Children[0].ILRange },
new LdLoc(testedVar).WithILRange(varLoad.Children[0]),
refInput: true
) { ILRange = varLoad.ILRange };
).WithILRange(varLoad);
break;
default:
throw new ArgumentOutOfRangeException("mode");

81
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
if (context.Settings.NullPropagation && !NullPropagationTransform.IsProtectedIfInst(ifInst as IfInstruction)) {
var nullPropagated = new NullPropagationTransform(context)
.Run(condition, trueInst, falseInst, ifInst.ILRange);
.Run(condition, trueInst, falseInst)?.WithILRange(ifInst);
if (nullPropagated != null)
return nullPropagated;
}
@ -156,7 +156,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -156,7 +156,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (AnalyzeCondition(condition)) {
// (v1 != null && ... && vn != null) ? trueInst : falseInst
// => normal lifting
return LiftNormal(trueInst, falseInst, ilrange: ifInst.ILRange);
return LiftNormal(trueInst, falseInst)?.WithILRange(ifInst);
}
if (MatchCompOrDecimal(condition, out var comp)) {
// This might be a C#-style lifted comparison
@ -206,36 +206,36 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -206,36 +206,36 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step("NullableLiftingTransform: v == true", ifInst);
return new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = trueInst.ILRange },
new LdcI4(1) { ILRange = falseInst.ILRange }
) { ILRange = ifInst.ILRange };
new LdLoc(v).WithILRange(trueInst),
new LdcI4(1).WithILRange(falseInst)
).WithILRange(ifInst);
} else if (trueInst.MatchLdcI4(0) && MatchHasValueCall(falseInst, v)) {
// v.GetValueOrDefault() ? false : v.HasValue
// ==> v == false
context.Step("NullableLiftingTransform: v == false", ifInst);
return new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = falseInst.ILRange },
new LdLoc(v).WithILRange(falseInst),
trueInst // LdcI4(0)
) { ILRange = ifInst.ILRange };
).WithILRange(ifInst);
} else if (MatchNegatedHasValueCall(trueInst, v) && falseInst.MatchLdcI4(1)) {
// v.GetValueOrDefault() ? !v.HasValue : true
// ==> v != true
context.Step("NullableLiftingTransform: v != true", ifInst);
return new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = trueInst.ILRange },
new LdLoc(v).WithILRange(trueInst),
falseInst // LdcI4(1)
) { ILRange = ifInst.ILRange };
).WithILRange(ifInst);
} else if (trueInst.MatchLdcI4(1) && MatchNegatedHasValueCall(falseInst, v)) {
// v.GetValueOrDefault() ? true : !v.HasValue
// ==> v != false
context.Step("NullableLiftingTransform: v != false", ifInst);
return new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = falseInst.ILRange },
new LdcI4(0) { ILRange = trueInst.ILRange }
) { ILRange = ifInst.ILRange };
new LdLoc(v).WithILRange(falseInst),
new LdcI4(0).WithILRange(trueInst)
).WithILRange(ifInst);
}
}
// Handle & and | on bool?:
@ -246,7 +246,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -246,7 +246,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// condition ? v : (bool?)false
// => condition & v
context.Step("NullableLiftingTransform: 3vl.bool.and(bool, bool?)", ifInst);
return new ThreeValuedBoolAnd(condition, trueInst) { ILRange = ifInst.ILRange };
return new ThreeValuedBoolAnd(condition, trueInst).WithILRange(ifInst);
}
if (falseInst.MatchLdLoc(out var v2)) {
// condition ? v : v2
@ -254,10 +254,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -254,10 +254,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// (nullable1.GetValueOrDefault() || (!nullable2.GetValueOrDefault() && !nullable1.HasValue)) ? v : v2
if (v == nullable1 && v2 == nullable2) {
context.Step("NullableLiftingTransform: 3vl.bool.or(bool?, bool?)", ifInst);
return new ThreeValuedBoolOr(trueInst, falseInst) { ILRange = ifInst.ILRange };
return new ThreeValuedBoolOr(trueInst, falseInst).WithILRange(ifInst);
} else if (v == nullable2 && v2 == nullable1) {
context.Step("NullableLiftingTransform: 3vl.bool.and(bool?, bool?)", ifInst);
return new ThreeValuedBoolAnd(falseInst, trueInst) { ILRange = ifInst.ILRange };
return new ThreeValuedBoolAnd(falseInst, trueInst).WithILRange(ifInst);
}
}
}
@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// condition ? (bool?)true : v
// => condition | v
context.Step("NullableLiftingTransform: 3vl.logic.or(bool, bool?)", ifInst);
return new ThreeValuedBoolOr(condition, falseInst) { ILRange = ifInst.ILRange };
return new ThreeValuedBoolOr(condition, falseInst).WithILRange(ifInst);
}
}
return null;
@ -382,9 +382,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -382,9 +382,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal ILInstruction MakeLifted(ComparisonKind newComparisonKind, ILInstruction left, ILInstruction right)
{
if (Instruction is Comp comp) {
return new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, comp.InputType, comp.Sign, left, right) {
ILRange = Instruction.ILRange
};
return new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, comp.InputType, comp.Sign, left, right).WithILRange(Instruction);
} else if (Instruction is Call call) {
IMethod method;
if (newComparisonKind == Kind) {
@ -400,10 +398,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -400,10 +398,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return new Call(CSharp.Resolver.CSharpOperators.LiftUserDefinedOperator(method)) {
Arguments = { left, right },
ConstrainedTo = call.ConstrainedTo,
ILRange = call.ILRange,
ILStackWasEmpty = call.ILStackWasEmpty,
IsTail = call.IsTail
};
}.WithILRange(call);
} else {
return null;
}
@ -531,10 +528,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -531,10 +528,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return new Call(liftedOperator) {
Arguments = { left, right },
ConstrainedTo = call.ConstrainedTo,
ILRange = call.ILRange,
ILStackWasEmpty = call.ILStackWasEmpty,
IsTail = call.IsTail,
};
}.WithILRange(call);
}
return null;
}
@ -549,7 +545,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -549,7 +545,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// where the v1,...,vn are the <c>this.nullableVars</c>.
/// If lifting fails, returns <c>null</c>.
/// </summary>
ILInstruction LiftNormal(ILInstruction trueInst, ILInstruction falseInst, Interval ilrange)
ILInstruction LiftNormal(ILInstruction trueInst, ILInstruction falseInst)
{
if (trueInst.MatchIfInstructionPositiveCondition(out var nestedCondition, out var nestedTrue, out var nestedFalse)) {
// Sometimes Roslyn generates pointless conditions like:
@ -569,8 +565,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -569,8 +565,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// => v ?? fallback
context.Step("v.HasValue ? v : fallback => v ?? fallback", trueInst);
return new NullCoalescingInstruction(NullCoalescingKind.Nullable, trueInst, falseInst) {
UnderlyingResultType = NullableType.GetUnderlyingType(nullableVars[0].Type).GetStackType(),
ILRange = ilrange
UnderlyingResultType = NullableType.GetUnderlyingType(nullableVars[0].Type).GetStackType()
};
} else if (trueInst is Call call && !call.IsLifted
&& CSharp.Resolver.CSharpOperators.IsComparisonOperator(call.Method)
@ -592,10 +587,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -592,10 +587,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return new Call(liftedOperator) {
Arguments = { left, right },
ConstrainedTo = call.ConstrainedTo,
ILRange = call.ILRange,
ILStackWasEmpty = call.ILStackWasEmpty,
IsTail = call.IsTail
};
}.WithILRange(call);
}
}
}
@ -619,9 +613,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -619,9 +613,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
inputUType.GetStackType(), inputUType.GetSign(), utype.ToPrimitiveType(),
checkForOverflow: false,
isLifted: true
) {
ILRange = ilrange
};
);
}
} else {
context.Step("NullableLiftingTransform.DoLift", trueInst);
@ -639,15 +631,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -639,15 +631,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
if (isNullCoalescingWithNonNullableFallback) {
lifted = new NullCoalescingInstruction(NullCoalescingKind.NullableWithValueFallback, lifted, falseInst) {
UnderlyingResultType = exprToLift.ResultType,
ILRange = ilrange
UnderlyingResultType = exprToLift.ResultType
};
} else if (!MatchNull(falseInst, utype)) {
// Normal lifting, but the falseInst isn't `default(utype?)`
// => use the `??` operator to provide the fallback value.
lifted = new NullCoalescingInstruction(NullCoalescingKind.Nullable, lifted, falseInst) {
UnderlyingResultType = exprToLift.ResultType,
ILRange = ilrange
UnderlyingResultType = exprToLift.ResultType
};
}
return lifted;
@ -681,7 +671,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -681,7 +671,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
if (foundIndices.Any())
return (new LdLoc(inputVar) { ILRange = inst.ILRange }, foundIndices);
return (new LdLoc(inputVar).WithILRange(inst), foundIndices);
else
return (null, null);
} else if (inst is Conv conv) {
@ -693,17 +683,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -693,17 +683,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// (thus causing it not to throw when any of them is null).
return (null, null);
}
var newInst = new Conv(arg, conv.InputType, conv.InputSign, conv.TargetType, conv.CheckForOverflow, isLifted: true) {
ILRange = conv.ILRange
};
var newInst = new Conv(arg, conv.InputType, conv.InputSign, conv.TargetType, conv.CheckForOverflow, isLifted: true).WithILRange(conv);
return (newInst, bits);
}
} else if (inst is BitNot bitnot) {
var (arg, bits) = DoLift(bitnot.Argument);
if (arg != null) {
var newInst = new BitNot(arg, isLifted: true, stackType: bitnot.ResultType) {
ILRange = bitnot.ILRange
};
var newInst = new BitNot(arg, isLifted: true, stackType: bitnot.ResultType).WithILRange(bitnot);
return (newInst, bits);
}
} else if (inst is BinaryNumericInstruction binary) {
@ -720,9 +706,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -720,9 +706,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
binary.LeftInputType, binary.RightInputType,
binary.CheckForOverflow, binary.Sign,
isLifted: true
) {
ILRange = binary.ILRange
};
).WithILRange(binary);
return (newInst, bits);
}
} else if (inst is Comp comp && !comp.IsLifted && comp.Kind == ComparisonKind.Equality
@ -734,9 +718,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -734,9 +718,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// except for operator! on bool?.
var (arg, bits) = DoLift(comp.Left);
Debug.Assert(arg != null);
var newInst = new Comp(comp.Kind, ComparisonLiftingKind.ThreeValuedLogic, comp.InputType, comp.Sign, arg, comp.Right.Clone()) {
ILRange = comp.ILRange
};
var newInst = new Comp(comp.Kind, ComparisonLiftingKind.ThreeValuedLogic, comp.InputType, comp.Sign, arg, comp.Right.Clone()).WithILRange(comp);
return (newInst, bits);
} else if (inst is Call call && call.Method.IsOperator) {
// Lifted user-defined operators, except for comparison operators (as those return bool, not bool?)
@ -765,8 +747,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -765,8 +747,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ConstrainedTo = call.ConstrainedTo,
IsTail = call.IsTail,
ILStackWasEmpty = call.ILStackWasEmpty,
ILRange = call.ILRange
};
}.WithILRange(call);
newInst.Arguments.AddRange(newArgs);
return (newInst, newBits);
}

6
ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs

@ -136,9 +136,9 @@ namespace ICSharpCode.Decompiler.IL @@ -136,9 +136,9 @@ namespace ICSharpCode.Decompiler.IL
Debug.Assert(ifInst != block.Instructions.Last());
var trueRange = ConditionDetection.GetILRange(ifInst.TrueInst);
var falseRange = ConditionDetection.GetILRange(block.Instructions[block.Instructions.IndexOf(ifInst)+1]);
if (!trueRange.IsEmpty && !falseRange.IsEmpty && falseRange.Start < trueRange.Start)
var trueRangeStart = ConditionDetection.GetStartILOffset(ifInst.TrueInst, out bool trueRangeIsEmpty);
var falseRangeStart = ConditionDetection.GetStartILOffset(block.Instructions[block.Instructions.IndexOf(ifInst)+1], out bool falseRangeIsEmpty);
if (!trueRangeIsEmpty && !falseRangeIsEmpty && falseRangeStart < trueRangeStart)
ConditionDetection.InvertIf(block, ifInst, context);
}

4
ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
for (int i = block.Instructions.Count - 1; i >= 0; i--) {
SwitchInstruction newSwitch;
if (MatchSwitchOnNullable(block.Instructions, i, out newSwitch)) {
newSwitch.ILRange = block.Instructions[i - 2].ILRange;
newSwitch.AddILRange(block.Instructions[i - 2]);
block.Instructions[i + 1].ReplaceWith(newSwitch);
block.Instructions.RemoveRange(i - 2, 3);
i -= 2;
@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
continue;
}
if (MatchRoslynSwitchOnNullable(block.Instructions, i, out newSwitch)) {
newSwitch.ILRange = block.Instructions[i - 1].ILRange;
newSwitch.AddILRange(block.Instructions[i - 1]);
block.Instructions[i - 1].ReplaceWith(newSwitch);
block.Instructions.RemoveRange(i, 2);
i--;

22
ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

@ -219,17 +219,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -219,17 +219,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var inst = new SwitchInstruction(stringToInt);
inst.Sections.AddRange(sections);
if (extraLoad) {
inst.ILRange = instructions[i - 2].ILRange;
inst.AddILRange(instructions[i - 2]);
instructions[i - 2].ReplaceWith(inst);
instructions.RemoveRange(i - 1, 3);
i -= 2;
} else {
if (keepAssignmentBefore) {
inst.ILRange = instructions[i].ILRange;
inst.AddILRange(instructions[i]);
instructions[i].ReplaceWith(inst);
instructions.RemoveAt(i + 1);
} else {
inst.ILRange = instructions[i - 1].ILRange;
inst.AddILRange(instructions[i - 1]);
instructions[i - 1].ReplaceWith(inst);
instructions.RemoveRange(i, 2);
i--;
@ -308,7 +308,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -308,7 +308,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var inst = new SwitchInstruction(stringToInt);
inst.Sections.AddRange(sections);
inst.ILRange = instructions[i - 1].ILRange;
inst.AddILRange(instructions[i - 1]);
instructions[i].ReplaceWith(inst);
instructions.RemoveAt(i + 1);
instructions.RemoveAt(i - 1);
@ -477,8 +477,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -477,8 +477,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
if (!right.MatchLdcI4(0))
return false;
sections.Add(new SwitchSection() { Body = ifInst.TrueInst, Labels = new LongSet(0), ILRange = ifInst.ILRange });
sections.Add(new SwitchSection() { Body = switchBlock.Instructions[1], Labels = new LongSet(0).Invert(), ILRange = switchBlock.Instructions[1].ILRange });
sections.Add(new SwitchSection() { Body = ifInst.TrueInst, Labels = new LongSet(0) }.WithILRange(ifInst));
sections.Add(new SwitchSection() { Body = switchBlock.Instructions[1], Labels = new LongSet(0).Invert() }.WithILRange(switchBlock.Instructions[1]));
break;
}
// mcs: map sections without a value to the default section, if possible
@ -501,12 +501,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -501,12 +501,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
instructions[i + 1].ReplaceWith(inst);
if (keepAssignmentBefore) {
// delete if (comp(ldloc switchValueVar == ldnull))
inst.ILRange = instructions[i].ILRange;
inst.AddILRange(instructions[i]);
instructions.RemoveAt(i);
i--;
} else {
// delete both the if and the assignment before
inst.ILRange = instructions[i - 1].ILRange;
inst.AddILRange(instructions[i - 1]);
instructions.RemoveRange(i - 1, 2);
i -= 2;
}
@ -721,7 +721,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -721,7 +721,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var stringToInt = new StringToInt(switchValue, stringValues);
var inst = new SwitchInstruction(stringToInt);
inst.Sections.AddRange(sections);
inst.ILRange = block.Instructions[i].ILRange;
inst.AddILRange(block.Instructions[i]);
block.Instructions[i].ReplaceWith(inst);
block.Instructions.RemoveRange(i + 1, 3);
info.Transformed = true;
@ -819,11 +819,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -819,11 +819,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
newSwitch.Sections.Add(new SwitchSection { Labels = defaultLabel, Body = defaultSection.Body });
instructions[i].ReplaceWith(newSwitch);
if (keepAssignmentBefore) {
newSwitch.ILRange = instructions[i - 1].ILRange;
newSwitch.AddILRange(instructions[i - 1]);
instructions.RemoveAt(i - 1);
i--;
} else {
newSwitch.ILRange = instructions[i - 2].ILRange;
newSwitch.AddILRange(instructions[i - 2]);
instructions.RemoveRange(i - 2, 2);
i -= 2;
}

2
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -321,7 +321,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -321,7 +321,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else {
return false;
}
newInst.AddILRange(setterValue.ILRange);
newInst.AddILRange(setterValue);
if (storeInSetter != null) {
storeInSetter.Value = newInst;
newInst = storeInSetter;

4
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -152,13 +152,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -152,13 +152,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!ReadParameters(instruction.Arguments[1], parameterList, parameterVariablesList, new SimpleTypeResolveContext(context.Function.Method)))
return (null, SpecialType.UnknownType);
var container = new BlockContainer();
container.ILRange = instruction.ILRange;
container.AddILRange(instruction);
var functionType = instruction.Method.ReturnType.TypeArguments[0];
var returnType = functionType.GetDelegateInvokeMethod()?.ReturnType;
var function = new ILFunction(returnType, parameterList, context.Function.GenericContext, container);
function.DelegateType = functionType;
function.Variables.AddRange(parameterVariablesList);
function.ILRange = instruction.ILRange;
function.AddILRange(instruction);
lambdaStack.Push(function);
var (bodyInstruction, type) = ConvertInstruction(instruction.Arguments[0]);
lambdaStack.Pop();

15
ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs

@ -97,9 +97,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -97,9 +97,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (s.IsUsedWithin(call.Arguments[1]))
return false;
context.Step("User-defined short-circuiting logic operator (legacy pattern)", condition);
((StLoc)block.Instructions[pos]).Value = new UserDefinedLogicOperator(call.Method, lhsInst, call.Arguments[1]) {
ILRange = call.ILRange
};
((StLoc)block.Instructions[pos]).Value = new UserDefinedLogicOperator(call.Method, lhsInst, call.Arguments[1])
.WithILRange(call);
block.Instructions.RemoveAt(pos + 1);
context.RequestRerun(); // the 'stloc s' may now be eligible for inlining
return true;
@ -148,9 +147,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -148,9 +147,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return null;
var result = new UserDefinedLogicOperator(call.Method, call.Arguments[0], call.Arguments[1]);
result.AddILRange(condition.ILRange);
result.AddILRange(trueInst.ILRange);
result.AddILRange(call.ILRange);
result.AddILRange(condition);
result.AddILRange(trueInst);
result.AddILRange(call);
return result;
}
@ -242,9 +241,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -242,9 +241,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return null;
var logicInst = new DynamicLogicOperatorInstruction(binary.BinderFlags, logicOp, binary.CallingContext,
binary.LeftArgumentInfo, binary.Left, binary.RightArgumentInfo, binary.Right)
{
ILRange = binary.ILRange
};
.WithILRange(binary);
if (rhsUnary != null) {
rhsUnary.Operand = logicInst;
return rhsUnary;

2
ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

@ -87,7 +87,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -87,7 +87,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.Step("UsingTransform", tryFinally);
storeInst.Variable.Kind = VariableKind.UsingLocal;
block.Instructions.RemoveAt(i);
block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock) { ILRange = storeInst.ILRange };
block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock).WithILRange(storeInst);
return true;
}

Loading…
Cancel
Save