Browse Source

Helpers ILCode.IsConditionalControlFlow() and ILCode.IsUnconditionalControlFlow()

pull/100/head
David Srbecký 16 years ago
parent
commit
10a96a8d3f
  1. 5
      ICSharpCode.Decompiler/ILAst/GotoRemoval.cs
  2. 2
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  3. 24
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  4. 40
      ICSharpCode.Decompiler/ILAst/ILCodes.cs

5
ICSharpCode.Decompiler/ILAst/GotoRemoval.cs

@ -65,8 +65,9 @@ namespace ICSharpCode.Decompiler.ILAst
int count = ilCase.Body.Count; int count = ilCase.Body.Count;
if (count >= 2) { if (count >= 2) {
if (!ilCase.Body[count - 2].CanFallThough() && if (ilCase.Body[count - 2].IsUnconditionalControlFlow() &&
ilCase.Body[count - 1].Match(ILCode.LoopOrSwitchBreak)) { ilCase.Body[count - 1].Match(ILCode.LoopOrSwitchBreak))
{
ilCase.Body.RemoveAt(count - 1); ilCase.Body.RemoveAt(count - 1);
} }
} }

2
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -309,7 +309,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Find all successors // Find all successors
List<ByteCode> branchTargets = new List<ByteCode>(); List<ByteCode> branchTargets = new List<ByteCode>();
if (byteCode.Code.CanFallThough()) { if (!byteCode.Code.IsUnconditionalControlFlow()) {
branchTargets.Add(byteCode.Next); branchTargets.Add(byteCode.Next);
} }
if (byteCode.Operand is Instruction[]) { if (byteCode.Operand is Instruction[]) {

24
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -309,15 +309,16 @@ namespace ICSharpCode.Decompiler.ILAst
// Start a new basic block if necessary // Start a new basic block if necessary
if (currNode is ILLabel || if (currNode is ILLabel ||
lastNode is ILTryCatchBlock ||
currNode is ILTryCatchBlock || currNode is ILTryCatchBlock ||
(lastNode is ILExpression && ((ILExpression)lastNode).IsBranch())) lastNode is ILTryCatchBlock ||
lastNode.IsConditionalControlFlow() ||
lastNode.IsUnconditionalControlFlow())
{ {
// Try to reuse the label // Try to reuse the label
ILLabel label = currNode is ILLabel ? ((ILLabel)currNode) : new ILLabel() { Name = "Block_" + (nextLabelIndex++) }; ILLabel label = currNode is ILLabel ? ((ILLabel)currNode) : new ILLabel() { Name = "Block_" + (nextLabelIndex++) };
// Terminate the last block // Terminate the last block
if (lastNode.CanFallThough()) { if (!lastNode.IsUnconditionalControlFlow()) {
// Explicit branch from one block to other // Explicit branch from one block to other
basicBlock.FallthoughGoto = new ILExpression(ILCode.Br, label); basicBlock.FallthoughGoto = new ILExpression(ILCode.Br, label);
} else if (lastNode.Match(ILCode.Br)) { } else if (lastNode.Match(ILCode.Br)) {
@ -432,8 +433,8 @@ namespace ICSharpCode.Decompiler.ILAst
for (int i = 0; i < block.Body.Count; i++) { for (int i = 0; i < block.Body.Count; i++) {
ILCondition cond = block.Body[i] as ILCondition; ILCondition cond = block.Body[i] as ILCondition;
if (cond != null) { if (cond != null) {
bool trueExits = cond.TrueBlock.Body.Count > 0 && !cond.TrueBlock.Body.Last().CanFallThough(); bool trueExits = cond.TrueBlock.Body.LastOrDefault().IsUnconditionalControlFlow();
bool falseExits = cond.FalseBlock.Body.Count > 0 && !cond.FalseBlock.Body.Last().CanFallThough(); bool falseExits = cond.FalseBlock.Body.LastOrDefault().IsUnconditionalControlFlow();
if (trueExits) { if (trueExits) {
// Move the false block after the condition // Move the false block after the condition
@ -504,13 +505,16 @@ namespace ICSharpCode.Decompiler.ILAst
return modified; return modified;
} }
public static bool CanFallThough(this ILNode node) public static bool IsConditionalControlFlow(this ILNode node)
{ {
ILExpression expr = node as ILExpression; ILExpression expr = node as ILExpression;
if (expr != null) { return expr != null && expr.Code.IsConditionalControlFlow();
return expr.Code.CanFallThough(); }
}
return true; public static bool IsUnconditionalControlFlow(this ILNode node)
{
ILExpression expr = node as ILExpression;
return expr != null && expr.Code.IsUnconditionalControlFlow();
} }
/// <summary> /// <summary>

40
ICSharpCode.Decompiler/ILAst/ILCodes.cs

@ -280,7 +280,41 @@ namespace ICSharpCode.Decompiler.ILAst
return code.ToString().ToLowerInvariant().TrimStart('_').Replace('_','.'); return code.ToString().ToLowerInvariant().TrimStart('_').Replace('_','.');
} }
public static bool CanFallThough(this ILCode code) public static bool IsConditionalControlFlow(this ILCode code)
{
switch(code) {
case ILCode.__Brfalse_S:
case ILCode.__Brtrue_S:
case ILCode.__Beq_S:
case ILCode.__Bge_S:
case ILCode.__Bgt_S:
case ILCode.__Ble_S:
case ILCode.__Blt_S:
case ILCode.__Bne_Un_S:
case ILCode.__Bge_Un_S:
case ILCode.__Bgt_Un_S:
case ILCode.__Ble_Un_S:
case ILCode.__Blt_Un_S:
case ILCode.__Brfalse:
case ILCode.Brtrue:
case ILCode.__Beq:
case ILCode.__Bge:
case ILCode.__Bgt:
case ILCode.__Ble:
case ILCode.__Blt:
case ILCode.__Bne_Un:
case ILCode.__Bge_Un:
case ILCode.__Bgt_Un:
case ILCode.__Ble_Un:
case ILCode.__Blt_Un:
case ILCode.Switch:
return true;
default:
return false;
}
}
public static bool IsUnconditionalControlFlow(this ILCode code)
{ {
switch(code) { switch(code) {
case ILCode.Br: case ILCode.Br:
@ -295,9 +329,9 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.LoopContinue: case ILCode.LoopContinue:
case ILCode.LoopOrSwitchBreak: case ILCode.LoopOrSwitchBreak:
case ILCode.YieldBreak: case ILCode.YieldBreak:
return false;
default:
return true; return true;
default:
return false;
} }
} }

Loading…
Cancel
Save