diff --git a/Decompiler.csproj b/Decompiler.csproj
index d07b24d12..7e3bfbdb2 100644
--- a/Decompiler.csproj
+++ b/Decompiler.csproj
@@ -40,12 +40,12 @@
+
-
MainForm.cs
diff --git a/src/StackAnalysis.Types.cs b/src/ByteCode.Type.cs
similarity index 93%
rename from src/StackAnalysis.Types.cs
rename to src/ByteCode.Type.cs
index b91aba662..94c83f2bf 100644
--- a/src/StackAnalysis.Types.cs
+++ b/src/ByteCode.Type.cs
@@ -10,7 +10,7 @@ using Mono.Cecil.Cil;
namespace Decompiler
{
- public partial class StackAnalysis
+ public partial class ByteCode
{
static public Cecil.TypeReference TypeVoid = GetCecilType(typeof(void));
static public Cecil.TypeReference TypeObject = GetCecilType(typeof(Object));
@@ -23,19 +23,19 @@ namespace Decompiler
return new Cecil.TypeReference(type.Name, type.Namespace, null, type.IsValueType);
}
- static Cecil.TypeReference GetType(MethodDefinition methodDef, ByteCode byteCode, params Cecil.TypeReference[] args)
+ public Cecil.TypeReference GetType(params Cecil.TypeReference[] args)
{
try {
- return(GetTypeInternal(methodDef, byteCode, args));
+ return(GetTypeInternal(args));
} catch (NotImplementedException) {
return TypeObject;
}
}
- static Cecil.TypeReference GetTypeInternal(MethodDefinition methodDef, ByteCode byteCode, params Cecil.TypeReference[] args)
+ public Cecil.TypeReference GetTypeInternal(params Cecil.TypeReference[] args)
{
- OpCode opCode = byteCode.OpCode;
- object operand = byteCode.Operand;
+ OpCode opCode = this.OpCode;
+ object operand = this.Operand;
Cecil.TypeReference operandAsTypeRef = operand as Cecil.TypeReference;
ByteCode operandAsByteCode = operand as ByteCode;
string operandAsByteCodeLabel = operand is ByteCode ? String.Format("IL_{0:X2}", ((ByteCode)operand).Offset) : null;
diff --git a/src/ByteCode.cs b/src/ByteCode.cs
index e01912217..713a3077d 100644
--- a/src/ByteCode.cs
+++ b/src/ByteCode.cs
@@ -7,7 +7,7 @@ using Mono.Cecil.Cil;
namespace Decompiler
{
- public class ByteCode
+ public partial class ByteCode
{
ByteCode previous;
ByteCode next;
@@ -31,16 +31,40 @@ namespace Decompiler
public int PopCount {
get {
- return GetNumberOfInputs(methodDef, this);
+ int popCount;
+ int pushCount;
+ SimulateStackSize(out popCount, out pushCount);
+ return popCount;
}
}
public int PushCount {
get {
- return GetNumberOfOutputs(methodDef, this);
+ int popCount;
+ int pushCount;
+ SimulateStackSize(out popCount, out pushCount);
+ return pushCount;
}
}
+ void SimulateStackSize(out int popCount, out int pushCount)
+ {
+ int stackSize = 0;
+ int minStackSize = 0;
+ foreach(ByteCode bc in nestedByteCodes) {
+ stackSize -= bc.PopCount;
+ minStackSize = Math.Min(minStackSize, stackSize);
+ stackSize += bc.PushCount;
+ }
+ {
+ stackSize -= GetPopCount(methodDef, this);
+ minStackSize = Math.Min(minStackSize, stackSize);
+ stackSize += GetPushCount(methodDef, this);
+ }
+ popCount = -minStackSize;
+ pushCount = stackSize - minStackSize;
+ }
+
public List NestedByteCodes {
get { return nestedByteCodes; }
}
@@ -81,7 +105,7 @@ namespace Decompiler
this.operand = inst.Operand;
}
- static int GetNumberOfInputs(MethodDefinition methodDef, ByteCode byteCode)
+ static int GetPopCount(MethodDefinition methodDef, ByteCode byteCode)
{
switch(byteCode.OpCode.StackBehaviourPop) {
case StackBehaviour.Pop0: return 0;
@@ -127,7 +151,7 @@ namespace Decompiler
}
}
- static int GetNumberOfOutputs(MethodDefinition methodDef, ByteCode byteCode)
+ static int GetPushCount(MethodDefinition methodDef, ByteCode byteCode)
{
switch(byteCode.OpCode.StackBehaviourPush) {
case StackBehaviour.Push0: return 0;
diff --git a/src/StackAnalysis.cs b/src/StackAnalysis.cs
index 985a65503..bc87bd6af 100644
--- a/src/StackAnalysis.cs
+++ b/src/StackAnalysis.cs
@@ -125,7 +125,7 @@ namespace Decompiler
public Cecil.TypeReference GetTypeOf(ByteCode byteCode)
{
if (byteCode.PushCount == 0) {
- return TypeVoid;
+ return ByteCode.TypeVoid;
} else {
return StackAfter[byteCode].Peek(1).Type;
}
@@ -185,7 +185,7 @@ namespace Decompiler
typeArgs.Add(slot.Type);
}
for (int i = 0; i < byteCode.PushCount; i++) {
- newStack.Push(new CilStackSlot(byteCode, GetType(methodDef, byteCode, typeArgs.ToArray())));
+ newStack.Push(new CilStackSlot(byteCode, byteCode.GetType(typeArgs.ToArray())));
}
return newStack;
}