From 0fe95f6b0bcc3ec82cb32dc20b9e8b54ac479436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Sun, 11 Nov 2007 20:21:59 +0000 Subject: [PATCH] Use custom data structure to store bytecode sequence --- Decompiler.csproj | 2 + src/AstMetodBodyBuilder.cs | 69 ++++++++++++++++---------------- src/ByteCode.cs | 65 +++++++++++++++++++++++++++++++ src/ByteCodeCollection.cs | 62 +++++++++++++++++++++++++++++ src/StackAnalysis.Types.cs | 14 +++---- src/StackAnalysis.cs | 80 +++++++++++++++++++------------------- src/Util.cs | 20 +++++----- 7 files changed, 220 insertions(+), 92 deletions(-) create mode 100644 src/ByteCode.cs create mode 100644 src/ByteCodeCollection.cs diff --git a/Decompiler.csproj b/Decompiler.csproj index 164276c50..d07b24d12 100644 --- a/Decompiler.csproj +++ b/Decompiler.csproj @@ -39,6 +39,8 @@ + + diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index 13f66c4d5..ac13c9f77 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -18,7 +18,8 @@ namespace Decompiler methodDef.Body.Simplify(); - StackAnalysis stackAnalysis = new StackAnalysis(methodDef); + ByteCodeCollection body = new ByteCodeCollection(methodDef.Body.Instructions); + StackAnalysis stackAnalysis = new StackAnalysis(methodDef, body); foreach(VariableDefinition varDef in methodDef.Body.Variables) { Ast.VariableDeclaration astVar = new Ast.VariableDeclaration(varDef.Name); @@ -27,12 +28,12 @@ namespace Decompiler astBlock.Children.Add(astLocalVar); } - foreach(Instruction instr in methodDef.Body.Instructions) { - OpCode opCode = instr.OpCode; + foreach(ByteCode byteCode in body) { + OpCode opCode = byteCode.OpCode; string description = string.Format(" {1, -22} # {2}->{3} {4} {5}", - instr.Offset, - opCode + " " + FormatInstructionOperand(instr.Operand), + byteCode.Offset, + opCode + " " + FormatByteCodeOperand(byteCode.Operand), opCode.StackBehaviourPop, opCode.StackBehaviourPush, opCode.FlowControl == FlowControl.Next ? string.Empty : "Flow=" + opCode.FlowControl, @@ -40,21 +41,21 @@ namespace Decompiler Ast.Statement astStatement = null; try { - int argCount = Util.GetNumberOfInputs(methodDef, instr); + int argCount = Util.GetNumberOfInputs(methodDef, byteCode); Ast.Expression[] args = new Ast.Expression[argCount]; for(int i = 0; i < argCount; i++) { - Instruction allocBy = stackAnalysis.StackBefore[instr].Peek(argCount - i).AllocadedBy; + ByteCode allocBy = stackAnalysis.StackBefore[byteCode].Peek(argCount - i).AllocadedBy; string name = string.Format("expr{0:X2}", allocBy.Offset); args[i] = new Ast.IdentifierExpression(name); } object codeExpr = MakeCodeDomExpression( methodDef, - instr, + byteCode, args); if (codeExpr is Ast.Expression) { - if (Util.GetNumberOfOutputs(methodDef, instr) == 1) { - string type = stackAnalysis.GetTypeOf(instr).FullName; - string name = string.Format("expr{0:X2}", instr.Offset); + if (Util.GetNumberOfOutputs(methodDef, byteCode) == 1) { + string type = stackAnalysis.GetTypeOf(byteCode).FullName; + string name = string.Format("expr{0:X2}", byteCode.Offset); Ast.LocalVariableDeclaration astLocal = new Ast.LocalVariableDeclaration(new Ast.TypeReference(type.ToString())); astLocal.Variables.Add(new Ast.VariableDeclaration(name, (Ast.Expression)codeExpr)); astStatement = astLocal; @@ -68,8 +69,8 @@ namespace Decompiler astStatement = MakeComment(description); } //astBlock.Children.Add(MakeComment(description)); - if (stackAnalysis.BranchTargetOf[instr].Count > 0) { - astBlock.Children.Add(new Ast.LabelStatement(string.Format("IL_{0:X2}", instr.Offset))); + if (stackAnalysis.BranchTargetOf[byteCode].Count > 0) { + astBlock.Children.Add(new Ast.LabelStatement(string.Format("IL_{0:X2}", byteCode.Offset))); } astBlock.Children.Add(astStatement); //astBlock.Children.Add(MakeComment(" " + stackAnalysis.StackAfter[instr].ToString())); @@ -84,12 +85,12 @@ namespace Decompiler return new Ast.ExpressionStatement(new PrimitiveExpression(text, text)); } - static object FormatInstructionOperand(object operand) + static object FormatByteCodeOperand(object operand) { if (operand == null) { return string.Empty; - } else if (operand is Instruction) { - return string.Format("IL_{0:X2}", ((Instruction)operand).Offset); + } else if (operand is ByteCode) { + return string.Format("IL_{0:X2}", ((ByteCode)operand).Offset); } else if (operand is MethodReference) { return ((MethodReference)operand).Name + "()"; } else if (operand is Cecil.TypeReference) { @@ -107,13 +108,13 @@ namespace Decompiler } } - static object MakeCodeDomExpression(MethodDefinition methodDef, Instruction inst, params Ast.Expression[] args) + static object MakeCodeDomExpression(MethodDefinition methodDef, ByteCode byteCode, params Ast.Expression[] args) { - OpCode opCode = inst.OpCode; - object operand = inst.Operand; + OpCode opCode = byteCode.OpCode; + object operand = byteCode.Operand; Ast.TypeReference operandAsTypeRef = operand is Cecil.TypeReference ? new Ast.TypeReference(((Cecil.TypeReference)operand).FullName) : null; - Instruction operandAsInstruction = operand is Instruction ? (Instruction)operand : null; - string operandAsInstructionLabel = operand is Instruction ? String.Format("IL_{0:X2}", ((Instruction)operand).Offset) : null; + ByteCode operandAsByteCode = operand as ByteCode; + string operandAsByteCodeLabel = operand is ByteCode ? String.Format("IL_{0:X2}", ((ByteCode)operand).Offset) : null; Ast.Expression arg1 = args.Length >= 1 ? args[0] : null; Ast.Expression arg2 = args.Length >= 2 ? args[1] : null; Ast.Expression arg3 = args.Length >= 3 ? args[2] : null; @@ -174,19 +175,19 @@ namespace Decompiler case Code.Stelem_Any: throw new NotImplementedException(); #endregion #region Branching - case Code.Br: return new Ast.GotoStatement(operandAsInstructionLabel); - case Code.Brfalse: return new Ast.IfElseStatement(new Ast.UnaryOperatorExpression(arg1, UnaryOperatorType.Not), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Brtrue: return new Ast.IfElseStatement(arg1, new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Beq: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Bge: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Bge_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Bgt: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Bgt_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Ble: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Ble_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Blt: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Blt_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); - case Code.Bne_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2), new Ast.GotoStatement(operandAsInstructionLabel)); + case Code.Br: return new Ast.GotoStatement(operandAsByteCodeLabel); + case Code.Brfalse: return new Ast.IfElseStatement(new Ast.UnaryOperatorExpression(arg1, UnaryOperatorType.Not), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Brtrue: return new Ast.IfElseStatement(arg1, new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Beq: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Bge: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Bge_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Bgt: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Bgt_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Ble: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Ble_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Blt: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Blt_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); + case Code.Bne_Un: return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2), new Ast.GotoStatement(operandAsByteCodeLabel)); #endregion #region Comparison case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, ConvertIntToBool(arg2)); diff --git a/src/ByteCode.cs b/src/ByteCode.cs new file mode 100644 index 000000000..6b0d181b2 --- /dev/null +++ b/src/ByteCode.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +using Cecil = Mono.Cecil; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace Decompiler +{ + public class ByteCode + { + ByteCode next; + + int offset; + OpCode opCode; + object operand; + + public ByteCode Next { + get { return next; } + set { next = value; } + } + + public int Offset { + get { return offset; } + set { offset = value; } + } + + public OpCode OpCode { + get { return opCode; } + set { opCode = value; } + } + + public object Operand { + get { return operand; } + set { operand = value; } + } + + public ByteCode BranchTarget { + get { + return (ByteCode)operand; + } + } + + public bool CanBranch { + get { + return OpCode.FlowControl == FlowControl.Branch || + OpCode.FlowControl == FlowControl.Cond_Branch; + } + } + + public ByteCode(int offset, OpCode opCode, object operand) + { + this.offset = offset; + this.opCode = opCode; + this.operand = operand; + } + + public ByteCode(Instruction inst) + { + this.offset = inst.Offset; + this.opCode = inst.OpCode; + this.operand = inst.Operand; + } + } +} diff --git a/src/ByteCodeCollection.cs b/src/ByteCodeCollection.cs new file mode 100644 index 000000000..37289eec9 --- /dev/null +++ b/src/ByteCodeCollection.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using Cecil = Mono.Cecil; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace Decompiler +{ + public class ByteCodeCollection: IEnumerable + { + List byteCodes = new List(); + + public IEnumerator GetEnumerator() + { + return byteCodes.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return byteCodes.GetEnumerator(); + } + + public int Count { + get { + return byteCodes.Count; + } + } + + public ByteCode this[int index] { + get { + return byteCodes[index]; + } + } + + public ByteCode GetByOffset(int offset) + { + foreach(ByteCode byteCode in this) { + if (byteCode.Offset == offset) { + return byteCode; + } + } + throw new Exception("Not found"); + } + + public ByteCodeCollection(InstructionCollection instCol) + { + foreach(Instruction inst in instCol) { + byteCodes.Add(new ByteCode(inst)); + } + foreach(ByteCode byteCode in this) { + if (byteCode.CanBranch) { + byteCode.Operand = GetByOffset(((Instruction)byteCode.Operand).Offset); + } + } + for(int i = 0; i < byteCodes.Count - 1; i++) { + this[i].Next = this[i + 1]; + } + } + } +} diff --git a/src/StackAnalysis.Types.cs b/src/StackAnalysis.Types.cs index b2f62823d..b91aba662 100644 --- a/src/StackAnalysis.Types.cs +++ b/src/StackAnalysis.Types.cs @@ -23,22 +23,22 @@ namespace Decompiler return new Cecil.TypeReference(type.Name, type.Namespace, null, type.IsValueType); } - static Cecil.TypeReference GetType(MethodDefinition methodDef, Instruction inst, params Cecil.TypeReference[] args) + static Cecil.TypeReference GetType(MethodDefinition methodDef, ByteCode byteCode, params Cecil.TypeReference[] args) { try { - return(GetTypeInternal(methodDef, inst, args)); + return(GetTypeInternal(methodDef, byteCode, args)); } catch (NotImplementedException) { return TypeObject; } } - static Cecil.TypeReference GetTypeInternal(MethodDefinition methodDef, Instruction inst, params Cecil.TypeReference[] args) + static Cecil.TypeReference GetTypeInternal(MethodDefinition methodDef, ByteCode byteCode, params Cecil.TypeReference[] args) { - OpCode opCode = inst.OpCode; - object operand = inst.Operand; + OpCode opCode = byteCode.OpCode; + object operand = byteCode.Operand; Cecil.TypeReference operandAsTypeRef = operand as Cecil.TypeReference; - Instruction operandAsInstruction = operand is Instruction ? (Instruction)operand : null; - string operandAsInstructionLabel = operand is Instruction ? String.Format("IL_{0:X2}", ((Instruction)operand).Offset) : null; + ByteCode operandAsByteCode = operand as ByteCode; + string operandAsByteCodeLabel = operand is ByteCode ? String.Format("IL_{0:X2}", ((ByteCode)operand).Offset) : null; Cecil.TypeReference arg1 = args.Length >= 1 ? args[0] : null; Cecil.TypeReference arg2 = args.Length >= 2 ? args[1] : null; Cecil.TypeReference arg3 = args.Length >= 3 ? args[2] : null; diff --git a/src/StackAnalysis.cs b/src/StackAnalysis.cs index 6ad2bf313..7539702e3 100644 --- a/src/StackAnalysis.cs +++ b/src/StackAnalysis.cs @@ -12,10 +12,10 @@ namespace Decompiler { // Imutable public struct CilStackSlot { - Instruction allocadedBy; + ByteCode allocadedBy; Cecil.TypeReference type; - public Instruction AllocadedBy { + public ByteCode AllocadedBy { get { return allocadedBy; } } @@ -23,7 +23,7 @@ namespace Decompiler get { return type; } } - public CilStackSlot(Instruction allocadedBy, Cecil.TypeReference type) + public CilStackSlot(ByteCode allocadedBy, Cecil.TypeReference type) { this.allocadedBy = allocadedBy; this.type = type; @@ -106,98 +106,96 @@ namespace Decompiler public partial class StackAnalysis { MethodDefinition methodDef; - Dictionary stackBefore = new Dictionary(); - Dictionary stackAfter = new Dictionary(); - Dictionary> branchTargetOf = new Dictionary>(); + Dictionary stackBefore = new Dictionary(); + Dictionary stackAfter = new Dictionary(); + Dictionary> branchTargetOf = new Dictionary>(); - public Dictionary StackBefore { + public Dictionary StackBefore { get { return stackBefore; } } - public Dictionary StackAfter { + public Dictionary StackAfter { get { return stackAfter; } } - public Dictionary> BranchTargetOf { + public Dictionary> BranchTargetOf { get { return branchTargetOf; } } - public Cecil.TypeReference GetTypeOf(Instruction inst) + public Cecil.TypeReference GetTypeOf(ByteCode byteCode) { - if (Util.GetNumberOfOutputs(methodDef, inst) == 0) { + if (Util.GetNumberOfOutputs(methodDef, byteCode) == 0) { return TypeVoid; } else { - return StackAfter[inst].Peek(1).Type; + return StackAfter[byteCode].Peek(1).Type; } } - public StackAnalysis(MethodDefinition methodDef) { + public StackAnalysis(MethodDefinition methodDef, ByteCodeCollection byteCodeCol) { this.methodDef = methodDef; - foreach(Instruction inst in methodDef.Body.Instructions) { - stackBefore[inst] = null; - stackAfter[inst] = null; - branchTargetOf[inst] = new List(); + foreach(ByteCode byteCode in byteCodeCol) { + stackBefore[byteCode] = null; + stackAfter[byteCode] = null; + branchTargetOf[byteCode] = new List(); } - foreach(Instruction inst in methodDef.Body.Instructions) { - if (inst.OpCode.FlowControl == FlowControl.Branch || - inst.OpCode.FlowControl == FlowControl.Cond_Branch) - { - branchTargetOf[(Instruction)inst.Operand].Add(inst); + foreach(ByteCode byteCode in byteCodeCol) { + if (byteCode.CanBranch) { + branchTargetOf[byteCode.BranchTarget].Add(byteCode); } } - if (methodDef.Body.Instructions.Count > 0) { - Instruction firstInst = methodDef.Body.Instructions[0]; + if (byteCodeCol.Count > 0) { + ByteCode firstInst = byteCodeCol[0]; stackBefore[firstInst] = CilStack.Empty; - ProcessInstructionRec(firstInst); + ProcessByteCodeRec(firstInst); } } - void ProcessInstructionRec(Instruction inst) + void ProcessByteCodeRec(ByteCode byteCode) { - stackAfter[inst] = ChangeStack(stackBefore[inst], inst); + stackAfter[byteCode] = ChangeStack(stackBefore[byteCode], byteCode); - switch(inst.OpCode.FlowControl) { + switch(byteCode.OpCode.FlowControl) { case FlowControl.Branch: - CopyStack(inst, ((Instruction)inst.Operand)); + CopyStack(byteCode, byteCode.BranchTarget); break; case FlowControl.Cond_Branch: - CopyStack(inst, inst.Next); - CopyStack(inst, ((Instruction)inst.Operand)); + CopyStack(byteCode, byteCode.Next); + CopyStack(byteCode, byteCode.BranchTarget); break; case FlowControl.Next: case FlowControl.Call: - CopyStack(inst, inst.Next); + CopyStack(byteCode, byteCode.Next); break; case FlowControl.Return: - if (stackAfter[inst].Count > 0) throw new Exception("Non-empty stack at the end"); + if (stackAfter[byteCode].Count > 0) throw new Exception("Non-empty stack at the end"); break; default: throw new NotImplementedException(); } } - CilStack ChangeStack(CilStack oldStack, Instruction inst) + CilStack ChangeStack(CilStack oldStack, ByteCode byteCode) { CilStack newStack = oldStack.Clone(); - CilStackSlot[] popedSlots = newStack.PopCount(Util.GetNumberOfInputs(methodDef, inst)); + CilStackSlot[] popedSlots = newStack.PopCount(Util.GetNumberOfInputs(methodDef, byteCode)); List typeArgs = new List(); foreach(CilStackSlot slot in popedSlots) { typeArgs.Add(slot.Type); } - for (int i = 0; i < Util.GetNumberOfOutputs(methodDef, inst); i++) { - newStack.Push(new CilStackSlot(inst, GetType(methodDef, inst, typeArgs.ToArray()))); + for (int i = 0; i < Util.GetNumberOfOutputs(methodDef, byteCode); i++) { + newStack.Push(new CilStackSlot(byteCode, GetType(methodDef, byteCode, typeArgs.ToArray()))); } return newStack; } - void CopyStack(Instruction instFrom, Instruction instTo) + void CopyStack(ByteCode byteCodeFrom, ByteCode byteCodeTo) { CilStack mergedStack; - if (!Merge(stackAfter[instFrom], stackBefore[instTo], out mergedStack)) { - stackBefore[instTo] = mergedStack; - ProcessInstructionRec(instTo); + if (!Merge(stackAfter[byteCodeFrom], stackBefore[byteCodeTo], out mergedStack)) { + stackBefore[byteCodeTo] = mergedStack; + ProcessByteCodeRec(byteCodeTo); } } diff --git a/src/Util.cs b/src/Util.cs index 5e1cbfa1b..a8e11d557 100644 --- a/src/Util.cs +++ b/src/Util.cs @@ -11,9 +11,9 @@ namespace Decompiler { public static class Util { - public static int GetNumberOfInputs(MethodDefinition methodDef, Instruction inst) + public static int GetNumberOfInputs(MethodDefinition methodDef, ByteCode byteCode) { - switch(inst.OpCode.StackBehaviourPop) { + switch(byteCode.OpCode.StackBehaviourPop) { case StackBehaviour.Pop0: return 0; case StackBehaviour.Pop1: return 1; case StackBehaviour.Popi: return 1; @@ -34,9 +34,9 @@ namespace Decompiler case StackBehaviour.Popref_popi_popref: return 3; case StackBehaviour.PopAll: throw new Exception("PopAll"); case StackBehaviour.Varpop: - switch(inst.OpCode.Code) { + switch(byteCode.OpCode.Code) { case Code.Call: - Cecil.MethodReference cecilMethod = ((MethodReference)inst.Operand); + Cecil.MethodReference cecilMethod = ((MethodReference)byteCode.Operand); if (cecilMethod.HasThis) { return cecilMethod.Parameters.Count + 1 /* this */; } else { @@ -53,13 +53,13 @@ namespace Decompiler case Code.Newobj: throw new NotImplementedException(); default: throw new Exception("Unknown Varpop opcode"); } - default: throw new Exception("Unknown pop behaviour: " + inst.OpCode.StackBehaviourPop); + default: throw new Exception("Unknown pop behaviour: " + byteCode.OpCode.StackBehaviourPop); } } - public static int GetNumberOfOutputs(MethodDefinition methodDef, Instruction inst) + public static int GetNumberOfOutputs(MethodDefinition methodDef, ByteCode byteCode) { - switch(inst.OpCode.StackBehaviourPush) { + switch(byteCode.OpCode.StackBehaviourPush) { case StackBehaviour.Push0: return 0; case StackBehaviour.Push1: return 1; case StackBehaviour.Push1_push1: return 2; @@ -69,9 +69,9 @@ namespace Decompiler case StackBehaviour.Pushr8: return 1; case StackBehaviour.Pushref: return 1; case StackBehaviour.Varpush: // Happens only for calls - switch(inst.OpCode.Code) { + switch(byteCode.OpCode.Code) { case Code.Call: - Cecil.MethodReference cecilMethod = ((MethodReference)inst.Operand); + Cecil.MethodReference cecilMethod = ((MethodReference)byteCode.Operand); if (cecilMethod.ReturnType.ReturnType.FullName == Constants.Void) { return 0; } else { @@ -81,7 +81,7 @@ namespace Decompiler case Code.Callvirt: throw new NotImplementedException(); default: throw new Exception("Unknown Varpush opcode"); } - default: throw new Exception("Unknown push behaviour: " + inst.OpCode.StackBehaviourPush); + default: throw new Exception("Unknown push behaviour: " + byteCode.OpCode.StackBehaviourPush); } } }