Browse Source

Stack analysis for methods that include exception handlers

pull/1/head^2
David Srbecký 18 years ago
parent
commit
edc9e53590
  1. 2
      src/AstMetodBodyBuilder.cs
  2. 1
      src/ByteCode.Type.cs
  3. 11
      src/ByteCodeCollection.cs
  4. 3
      src/ControlFlow/Nodes.cs

2
src/AstMetodBodyBuilder.cs

@ -32,6 +32,7 @@ namespace Decompiler
methodDef.Body.Simplify(); methodDef.Body.Simplify();
ByteCodeCollection body = new ByteCodeCollection(methodDef); ByteCodeCollection body = new ByteCodeCollection(methodDef);
ByteCodeExpressionCollection exprCollection = new ByteCodeExpressionCollection(body); ByteCodeExpressionCollection exprCollection = new ByteCodeExpressionCollection(body);
try { try {
exprCollection.Optimize(); exprCollection.Optimize();
@ -235,6 +236,7 @@ namespace Decompiler
case Code.Blt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); case Code.Blt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
case Code.Blt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); case Code.Blt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
case Code.Bne_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2); case Code.Bne_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
case Code.Leave: return new Ast.PrimitiveExpression(true, true.ToString());
default: throw new Exception("Bad opcode"); default: throw new Exception("Bad opcode");
} }
} else if (branch is ShortCircuitBranch) { } else if (branch is ShortCircuitBranch) {

1
src/ByteCode.Type.cs

@ -14,6 +14,7 @@ namespace Decompiler
{ {
static public Cecil.TypeReference TypeVoid = GetCecilType(typeof(void)); static public Cecil.TypeReference TypeVoid = GetCecilType(typeof(void));
static public Cecil.TypeReference TypeObject = GetCecilType(typeof(Object)); static public Cecil.TypeReference TypeObject = GetCecilType(typeof(Object));
static public Cecil.TypeReference TypeException = GetCecilType(typeof(Exception));
static public Cecil.TypeReference TypeBool = GetCecilType(typeof(bool)); static public Cecil.TypeReference TypeBool = GetCecilType(typeof(bool));
static public Cecil.TypeReference TypeInt32 = GetCecilType(typeof(Int32)); static public Cecil.TypeReference TypeInt32 = GetCecilType(typeof(Int32));
static public Cecil.TypeReference TypeString = GetCecilType(typeof(string)); static public Cecil.TypeReference TypeString = GetCecilType(typeof(string));

11
src/ByteCodeCollection.cs

@ -65,7 +65,7 @@ namespace Decompiler
} }
} }
UpdateNextPrevious(); UpdateNextPrevious();
UpdateStackAnalysis(); UpdateStackAnalysis(methodDef);
} }
void UpdateNextPrevious() void UpdateNextPrevious()
@ -76,11 +76,18 @@ namespace Decompiler
} }
} }
void UpdateStackAnalysis() void UpdateStackAnalysis(MethodDefinition methodDef)
{ {
if (this.Count > 0) { if (this.Count > 0) {
this[0].MergeStackBeforeWith(CilStack.Empty); this[0].MergeStackBeforeWith(CilStack.Empty);
} }
foreach(ExceptionHandler handler in methodDef.Body.ExceptionHandlers) {
ByteCode byteCode = this.GetByOffset(handler.HandlerStart.Offset);
CilStack expetionStack = new CilStack();
// TODO: Allocated by what?
expetionStack.Add(new CilStackSlot(byteCode, ByteCode.TypeException));
byteCode.MergeStackBeforeWith(expetionStack);
}
} }
} }
} }

3
src/ControlFlow/Nodes.cs

@ -149,7 +149,8 @@ namespace Decompiler.ControlFlow
if (node == target) continue; if (node == target) continue;
// Non-conditional branch does not fall-through // Non-conditional branch does not fall-through
if (exprs[i].OpCode.Code == Code.Br) continue; if (exprs[i].OpCode.Code == Code.Br ||
exprs[i].OpCode.Code == Code.Leave) continue;
node.FallThroughBasicBlock = target; node.FallThroughBasicBlock = target;
target.BasicBlockPredecessors.Add(node); target.BasicBlockPredecessors.Add(node);

Loading…
Cancel
Save