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
switch (inst.OpCode) { switch (inst.OpCode) {
case OpCode.Branch: case OpCode.Branch:
var branch = (Branch)inst; var branch = (Branch)inst;
Debug.Assert(branch.TargetBlock == null);
branch.TargetBlock = FindBranchTarget(branch.TargetILOffset); branch.TargetBlock = FindBranchTarget(branch.TargetILOffset);
break; break;
case OpCode.Leave:
var leave = (Leave)inst;
Debug.Assert(leave.TargetContainer == null);
leave.TargetContainer = containerStack.Peek();
break;
case OpCode.BlockContainer: case OpCode.BlockContainer:
var container = (BlockContainer)inst; var container = (BlockContainer)inst;
containerStack.Push(container); containerStack.Push(container);

2
ICSharpCode.Decompiler/IL/ILReader.cs

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

4
ICSharpCode.Decompiler/IL/InstructionFlags.cs

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

32
ICSharpCode.Decompiler/IL/Instructions.cs

@ -68,8 +68,6 @@ namespace ICSharpCode.Decompiler.IL
Branch, Branch,
/// <summary>Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c></summary> /// <summary>Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c></summary>
Leave, 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> /// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>
IfInstruction, IfInstruction,
/// <summary>Try-catch statement.</summary> /// <summary>Try-catch statement.</summary>
@ -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> /// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>
public sealed partial class IfInstruction : ILInstruction public sealed partial class IfInstruction : ILInstruction
{ {
@ -2737,10 +2714,6 @@ namespace ICSharpCode.Decompiler.IL
{ {
Default(inst); Default(inst);
} }
protected internal virtual void VisitEndFinally(EndFinally inst)
{
Default(inst);
}
protected internal virtual void VisitIfInstruction(IfInstruction inst) protected internal virtual void VisitIfInstruction(IfInstruction inst)
{ {
Default(inst); Default(inst);
@ -3039,10 +3012,6 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst); return Default(inst);
} }
protected internal virtual T VisitEndFinally(EndFinally inst)
{
return Default(inst);
}
protected internal virtual T VisitIfInstruction(IfInstruction inst) protected internal virtual T VisitIfInstruction(IfInstruction inst)
{ {
return Default(inst); return Default(inst);
@ -3328,7 +3297,6 @@ namespace ICSharpCode.Decompiler.IL
"arglist", "arglist",
"br", "br",
"leave", "leave",
"endfinally",
"if", "if",
"try.catch", "try.catch",
"try.catch.handler", "try.catch.handler",

3
ICSharpCode.Decompiler/IL/Instructions.tt

@ -63,9 +63,6 @@
CustomClassName("Branch"), NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags), 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>", new OpCode("leave", "Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c>",
NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags), 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>", new OpCode("if", "If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c>",
CustomClassName("IfInstruction"), CustomClassName("IfInstruction"),
CustomChildren(new []{ CustomChildren(new []{

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

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

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

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// * LoopDetection should run before other control flow structures are detected. /// * LoopDetection should run before other control flow structures are detected.
/// * Blocks should be basic blocks (not extended basic blocks) so that the natural loops /// * Blocks should be basic blocks (not extended basic blocks) so that the natural loops
/// don't include more instructions than strictly necessary. /// 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> /// </remarks>
public class LoopDetection : IILTransform public class LoopDetection : IILTransform
{ {

Loading…
Cancel
Save