Browse Source

Moved typing code to ByteCode.GetType()

pull/1/head^2
David Srbecký 18 years ago
parent
commit
53eed43bf5
  1. 2
      Decompiler.csproj
  2. 12
      src/ByteCode.Type.cs
  3. 34
      src/ByteCode.cs
  4. 4
      src/StackAnalysis.cs

2
Decompiler.csproj

@ -40,12 +40,12 @@
<Compile Include="src\AstBuilder.cs" /> <Compile Include="src\AstBuilder.cs" />
<Compile Include="src\AstMetodBodyBuilder.cs" /> <Compile Include="src\AstMetodBodyBuilder.cs" />
<Compile Include="src\ByteCode.cs" /> <Compile Include="src\ByteCode.cs" />
<Compile Include="src\ByteCode.Type.cs" />
<Compile Include="src\ByteCodeCollection.cs" /> <Compile Include="src\ByteCodeCollection.cs" />
<Compile Include="src\MainForm.cs" /> <Compile Include="src\MainForm.cs" />
<Compile Include="src\MainForm.Designer.cs" /> <Compile Include="src\MainForm.Designer.cs" />
<Compile Include="src\Program.cs" /> <Compile Include="src\Program.cs" />
<Compile Include="src\StackAnalysis.cs" /> <Compile Include="src\StackAnalysis.cs" />
<Compile Include="src\StackAnalysis.Types.cs" />
<Compile Include="src\Util.cs" /> <Compile Include="src\Util.cs" />
<EmbeddedResource Include="src\MainForm.resx"> <EmbeddedResource Include="src\MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>

12
src/StackAnalysis.Types.cs → src/ByteCode.Type.cs

@ -10,7 +10,7 @@ using Mono.Cecil.Cil;
namespace Decompiler namespace Decompiler
{ {
public partial class StackAnalysis public partial class ByteCode
{ {
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));
@ -23,19 +23,19 @@ namespace Decompiler
return new Cecil.TypeReference(type.Name, type.Namespace, null, type.IsValueType); 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 { try {
return(GetTypeInternal(methodDef, byteCode, args)); return(GetTypeInternal(args));
} catch (NotImplementedException) { } catch (NotImplementedException) {
return TypeObject; 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; OpCode opCode = this.OpCode;
object operand = byteCode.Operand; object operand = this.Operand;
Cecil.TypeReference operandAsTypeRef = operand as Cecil.TypeReference; Cecil.TypeReference operandAsTypeRef = operand as Cecil.TypeReference;
ByteCode operandAsByteCode = operand as ByteCode; ByteCode operandAsByteCode = operand as ByteCode;
string operandAsByteCodeLabel = operand is ByteCode ? String.Format("IL_{0:X2}", ((ByteCode)operand).Offset) : null; string operandAsByteCodeLabel = operand is ByteCode ? String.Format("IL_{0:X2}", ((ByteCode)operand).Offset) : null;

34
src/ByteCode.cs

@ -7,7 +7,7 @@ using Mono.Cecil.Cil;
namespace Decompiler namespace Decompiler
{ {
public class ByteCode public partial class ByteCode
{ {
ByteCode previous; ByteCode previous;
ByteCode next; ByteCode next;
@ -31,16 +31,40 @@ namespace Decompiler
public int PopCount { public int PopCount {
get { get {
return GetNumberOfInputs(methodDef, this); int popCount;
int pushCount;
SimulateStackSize(out popCount, out pushCount);
return popCount;
} }
} }
public int PushCount { public int PushCount {
get { 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<ByteCode> NestedByteCodes { public List<ByteCode> NestedByteCodes {
get { return nestedByteCodes; } get { return nestedByteCodes; }
} }
@ -81,7 +105,7 @@ namespace Decompiler
this.operand = inst.Operand; this.operand = inst.Operand;
} }
static int GetNumberOfInputs(MethodDefinition methodDef, ByteCode byteCode) static int GetPopCount(MethodDefinition methodDef, ByteCode byteCode)
{ {
switch(byteCode.OpCode.StackBehaviourPop) { switch(byteCode.OpCode.StackBehaviourPop) {
case StackBehaviour.Pop0: return 0; 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) { switch(byteCode.OpCode.StackBehaviourPush) {
case StackBehaviour.Push0: return 0; case StackBehaviour.Push0: return 0;

4
src/StackAnalysis.cs

@ -125,7 +125,7 @@ namespace Decompiler
public Cecil.TypeReference GetTypeOf(ByteCode byteCode) public Cecil.TypeReference GetTypeOf(ByteCode byteCode)
{ {
if (byteCode.PushCount == 0) { if (byteCode.PushCount == 0) {
return TypeVoid; return ByteCode.TypeVoid;
} else { } else {
return StackAfter[byteCode].Peek(1).Type; return StackAfter[byteCode].Peek(1).Type;
} }
@ -185,7 +185,7 @@ namespace Decompiler
typeArgs.Add(slot.Type); typeArgs.Add(slot.Type);
} }
for (int i = 0; i < byteCode.PushCount; i++) { 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; return newStack;
} }

Loading…
Cancel
Save