Browse Source

Fix catch with object

pull/910/head
mohe2015 8 years ago
parent
commit
98b99eddb8
  1. 62
      ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs

62
ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs

@ -41,10 +41,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// br whenConditionBlock // br whenConditionBlock
// } // }
var instructions = container.EntryPoint.Instructions; var instructions = container.EntryPoint.Instructions;
((StLoc)instructions[0]).Value = exceptionSlot; if (instructions.Count == 3) {
instructions[1].ReplaceWith(new Branch(whenConditionBlock)); ((StLoc)instructions[0]).Value = exceptionSlot;
instructions.RemoveAt(2); instructions[1].ReplaceWith(new Branch(whenConditionBlock));
container.SortBlocks(deleteUnreachableBlocks: true); instructions.RemoveAt(2);
container.SortBlocks(deleteUnreachableBlocks: true);
} else if (instructions.Count == 2) {
// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock
// br falseBlock
instructions[0].ReplaceWith(new Branch(whenConditionBlock));
instructions.RemoveAt(1);
container.SortBlocks(deleteUnreachableBlocks: true);
}
} }
} }
} }
@ -61,21 +69,39 @@ namespace ICSharpCode.Decompiler.IL.Transforms
exceptionType = null; exceptionType = null;
exceptionSlot = null; exceptionSlot = null;
whenConditionBlock = null; whenConditionBlock = null;
if (entryPoint == null || entryPoint.IncomingEdgeCount != 1 || entryPoint.Instructions.Count != 3) if (entryPoint == null || entryPoint.IncomingEdgeCount != 1)
return false; return false;
if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) || if (entryPoint.Instructions.Count == 3) {
temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType)) if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) ||
return false; temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType))
if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception) return false;
return false; if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch)) return false;
return false; if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch))
if (!condition.MatchCompNotEquals(out var left, out var right)) return false;
return false; if (!condition.MatchCompNotEquals(out var left, out var right))
if (!entryPoint.Instructions[2].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock)) return false;
return false; if (!entryPoint.Instructions[2].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))
if ((left.MatchLdNull() && right.MatchLdLoc(temp)) || (right.MatchLdNull() && left.MatchLdLoc(temp))) { return false;
return branch.MatchBranch(out whenConditionBlock); if ((left.MatchLdNull() && right.MatchLdLoc(temp)) || (right.MatchLdNull() && left.MatchLdLoc(temp))) {
return branch.MatchBranch(out whenConditionBlock);
}
} else if (entryPoint.Instructions.Count == 2) {
// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock
// br falseBlock
if (!entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var branch))
return false;
if (!condition.MatchCompNotEquals(out var left, out var right))
return false;
if (!entryPoint.Instructions[1].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))
return false;
if (!left.MatchIsInst(out exceptionSlot, out exceptionType))
return false;
if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
return false;
if (right.MatchLdNull()) {
return branch.MatchBranch(out whenConditionBlock);
}
} }
return false; return false;
} }

Loading…
Cancel
Save