Browse Source

Replace 'endfinally' with 'leave'

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
4dec7abb63
  1. 6
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  2. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  3. 4
      ICSharpCode.Decompiler/IL/InstructionFlags.cs
  4. 32
      ICSharpCode.Decompiler/IL/Instructions.cs
  5. 3
      ICSharpCode.Decompiler/IL/Instructions.tt
  6. 14
      ICSharpCode.Decompiler/IL/Instructions/Leave.cs
  7. 2
      ICSharpCode.Decompiler/IL/Transforms/LoopDetection.cs

6
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -175,8 +175,14 @@ namespace ICSharpCode.Decompiler.IL @@ -175,8 +175,14 @@ namespace ICSharpCode.Decompiler.IL
switch (inst.OpCode) {
case OpCode.Branch:
var branch = (Branch)inst;
Debug.Assert(branch.TargetBlock == null);
branch.TargetBlock = FindBranchTarget(branch.TargetILOffset);
break;
case OpCode.Leave:
var leave = (Leave)inst;
Debug.Assert(leave.TargetContainer == null);
leave.TargetContainer = containerStack.Peek();
break;
case OpCode.BlockContainer:
var container = (BlockContainer)inst;
containerStack.Push(container);

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -431,7 +431,7 @@ namespace ICSharpCode.Decompiler.IL @@ -431,7 +431,7 @@ namespace ICSharpCode.Decompiler.IL
return new Peek(stack.Count > 0 ? stack.Peek() : StackType.Unknown);
case ILOpCode.Endfilter:
case ILOpCode.Endfinally:
return new EndFinally();
return new Leave(null);
case ILOpCode.Initblk:
throw new NotImplementedException();
case ILOpCode.Jmp:

4
ICSharpCode.Decompiler/IL/InstructionFlags.cs

@ -81,6 +81,10 @@ namespace ICSharpCode.Decompiler.IL @@ -81,6 +81,10 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// The instruction performs unconditional control flow, so that its endpoint is unreachable.
/// </summary>
/// <remarks>
/// If EndPointUnreachable is set, either MayThrow or MayBranch should also be set
/// (unless the instruction represents an infinite loop).
/// </remarks>
EndPointUnreachable = 0x400,
}
}

32
ICSharpCode.Decompiler/IL/Instructions.cs

@ -68,8 +68,6 @@ namespace ICSharpCode.Decompiler.IL @@ -68,8 +68,6 @@ namespace ICSharpCode.Decompiler.IL
Branch,
/// <summary>Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c></summary>
Leave,
/// <summary>Marks the end of an finally, fault or exception filter block.</summary>
EndFinally,
/// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>
IfInstruction,
/// <summary>Try-catch statement.</summary>
@ -701,27 +699,6 @@ namespace ICSharpCode.Decompiler.IL @@ -701,27 +699,6 @@ namespace ICSharpCode.Decompiler.IL
}
}
/// <summary>Marks the end of an finally, fault or exception filter block.</summary>
public sealed partial class EndFinally : SimpleInstruction
{
public EndFinally() : base(OpCode.EndFinally)
{
}
public override StackType ResultType { get { return StackType.Void; } }
protected override InstructionFlags ComputeFlags()
{
return InstructionFlags.EndPointUnreachable | InstructionFlags.MayBranch;
}
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitEndFinally(this);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitEndFinally(this);
}
}
/// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>
public sealed partial class IfInstruction : ILInstruction
{
@ -2737,10 +2714,6 @@ namespace ICSharpCode.Decompiler.IL @@ -2737,10 +2714,6 @@ namespace ICSharpCode.Decompiler.IL
{
Default(inst);
}
protected internal virtual void VisitEndFinally(EndFinally inst)
{
Default(inst);
}
protected internal virtual void VisitIfInstruction(IfInstruction inst)
{
Default(inst);
@ -3039,10 +3012,6 @@ namespace ICSharpCode.Decompiler.IL @@ -3039,10 +3012,6 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
protected internal virtual T VisitEndFinally(EndFinally inst)
{
return Default(inst);
}
protected internal virtual T VisitIfInstruction(IfInstruction inst)
{
return Default(inst);
@ -3328,7 +3297,6 @@ namespace ICSharpCode.Decompiler.IL @@ -3328,7 +3297,6 @@ namespace ICSharpCode.Decompiler.IL
"arglist",
"br",
"leave",
"endfinally",
"if",
"try.catch",
"try.catch.handler",

3
ICSharpCode.Decompiler/IL/Instructions.tt

@ -63,9 +63,6 @@ @@ -63,9 +63,6 @@
CustomClassName("Branch"), NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags),
new OpCode("leave", "Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c>",
NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags),
// TODO: get rid of endfinally, we can represent those with 'leave blockcontainer' instead
new OpCode("endfinally", "Marks the end of an finally, fault or exception filter block.",
CustomClassName("EndFinally"), NoArguments, UnconditionalBranch, MayBranch),
new OpCode("if", "If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c>",
CustomClassName("IfInstruction"),
CustomChildren(new []{

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

@ -47,8 +47,8 @@ namespace ICSharpCode.Decompiler.IL @@ -47,8 +47,8 @@ namespace ICSharpCode.Decompiler.IL
public Leave(BlockContainer targetContainer) : base(OpCode.Leave)
{
if (targetContainer == null)
throw new ArgumentNullException("targetContainer");
// Note: ILReader will create Leave instructions with targetContainer==null to represent 'endfinally',
// the targetContainer will then be filled in by BlockBuilder
this.targetContainer = targetContainer;
}
@ -88,20 +88,22 @@ namespace ICSharpCode.Decompiler.IL @@ -88,20 +88,22 @@ namespace ICSharpCode.Decompiler.IL
}
public string TargetLabel {
get { return targetContainer.EntryPoint.Label; }
get { return targetContainer != null ? targetContainer.EntryPoint.Label : string.Empty; }
}
internal override void CheckInvariant()
{
base.CheckInvariant();
Debug.Assert(this.IsDescendantOf(targetContainer));
Debug.Assert(targetContainer == null || this.IsDescendantOf(targetContainer));
}
public override void WriteTo(ITextOutput output)
{
output.Write(OpCode);
output.Write(' ');
output.WriteReference(TargetLabel, targetContainer, isLocal: true);
if (targetContainer != null) {
output.Write(' ');
output.WriteReference(TargetLabel, targetContainer, isLocal: true);
}
if (PopCount != 0) {
output.Write(" (pops ");
output.Write(PopCount.ToString());

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

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// * LoopDetection should run before other control flow structures are detected.
/// * Blocks should be basic blocks (not extended basic blocks) so that the natural loops
/// don't include more instructions than strictly necessary.
/// * (depending on future loop detection improvements:) Loop detection should run after the 'return block' is duplicated.
/// * (depending on future loop detection improvements:) Loop detection should run after the 'return block' is duplicated (OptimizingTransform).
/// </remarks>
public class LoopDetection : IILTransform
{

Loading…
Cancel
Save