Browse Source

Return instruction pops zero or one item instead of all.

Exception of catch block does not have to be consumed.
Related to #185
pull/252/merge
David Srbecký 14 years ago
parent
commit
aeeda32d10
  1. 4
      ICSharpCode.Decompiler/CecilExtensions.cs
  2. 2
      ICSharpCode.Decompiler/FlowAnalysis/SsaFormBuilder.cs
  3. 7
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

4
ICSharpCode.Decompiler/CecilExtensions.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler @@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler
throw new NotSupportedException ();
}
public static int? GetPopDelta(this Instruction instruction)
public static int? GetPopDelta(this Instruction instruction, MethodDefinition methodDef)
{
OpCode code = instruction.OpCode;
switch (code.StackBehaviourPop) {
@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler @@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler
case StackBehaviour.Varpop:
if (code == OpCodes.Ret)
return null;
return methodDef.ReturnType.IsVoid() ? 0 : 1;
if (code.FlowControl != FlowControl.Call)
break;

2
ICSharpCode.Decompiler/FlowAnalysis/SsaFormBuilder.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis @@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
continue;
}
int popCount = inst.GetPopDelta() ?? stackSize;
int popCount = inst.GetPopDelta(method) ?? stackSize;
stackSize -= popCount;
if (stackSize < 0)
throw new InvalidProgramException("IL stack underflow");

7
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.ILAst
EndOffset = inst.Next != null ? inst.Next.Offset : methodDef.Body.CodeSize,
Code = code,
Operand = operand,
PopCount = inst.GetPopDelta(),
PopCount = inst.GetPopDelta(methodDef),
PushCount = inst.GetPushDelta()
};
if (prefixes != null) {
@ -701,8 +701,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -701,8 +701,9 @@ namespace ICSharpCode.Decompiler.ILAst
};
// Handle the automatically pushed exception on the stack
ByteCode ldexception = ldexceptions[eh];
if (ldexception.StoreTo.Count == 0) {
throw new Exception("Exception should be consumed by something");
if (ldexception.StoreTo == null || ldexception.StoreTo.Count == 0) {
// Exception is not used
catchBlock.ExceptionVariable = null;
} else if (ldexception.StoreTo.Count == 1) {
ILExpression first = catchBlock.Body[0] as ILExpression;
if (first != null &&

Loading…
Cancel
Save