/// <summary> /// Compute delta of pushing according to given instruction /// <remarks>Modified method taken from http://cecil.googlecode.com/svn/trunk/decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/ControlFlowGraphBuilder.cs </remarks>. /// </summary> /// <param name="instruction">Instruction which delta is computed.</param> /// <returns>Push delta.</returns> int getPushDelta(CILInstruction instruction) { var stackBehaviour = instruction.OpCode.StackBehaviourPush; switch (stackBehaviour) { case StackBehaviour.Push0: return(0); case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: return(1); case StackBehaviour.Push1_push1: return(2); case StackBehaviour.Varpush: if (instruction.MethodOperand == null) { //cannot be determined return(0); } return(instruction.MethodOperand.ReturnType.TypeName == typeof(void).FullName ? 0 : 1); default: //unknown behaviour return(0); } }
/// <summary> /// Transcript given instructions in context of given method. /// Transcription is processed by given emitter. /// </summary> /// <param name="method">Context method of transcription</param> /// <param name="instructions">Transcripted instructions</param> /// <param name="emitter">Emitter where transcription is emitted</param> internal static void Transcript(TypeMethodInfo method, IEnumerable <CILInstruction> instructions, EmitterBase emitter) { E = emitter; Method = method; LocalTmpVar = E.GetTemporaryVariable("local"); //prepare labels table Labels.Clear(); foreach (var instruction in instructions) { var labelName = string.Format("L_0x{0:x4}", instruction.Address); Labels.Add(instruction.Address, E.CreateLabel(labelName)); } foreach (var instruction in instructions) { Instruction = instruction; E.SetLabel(Labels[instruction.Address]); var block = E.StartNewInfoBlock(); block.Comment = "\n---" + Instruction.ToString(); Action transcriptor; if (_transcriptors.TryGetValue(Name, out transcriptor)) { transcriptor(); } else { unknownInstruction(); } } }
/// <summary> /// Compute delta of popping according to given instruction /// <remarks>Modified method taken from http://cecil.googlecode.com/svn/trunk/decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/ControlFlowGraphBuilder.cs </remarks>. /// </summary> /// <param name="instruction">Instruction which delta is computed.</param> /// <param name="stackHeight">Current height of stack that should be popped.</param> /// <returns>Pop delta.</returns> int getPopDelta(CILInstruction instruction, int stackHeight) { var stackBehaviour = instruction.OpCode.StackBehaviourPop; switch (stackBehaviour) { case StackBehaviour.Pop0: return(0); case StackBehaviour.Popi: case StackBehaviour.Popref: case StackBehaviour.Pop1: return(1); case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: return(2); case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: return(3); case StackBehaviour.PopAll: return(stackHeight); case StackBehaviour.Varpop: if (instruction.MethodOperand != null) { var method = instruction.MethodOperand; int count = method.Parameters.Length; if (method.HasThis && OpCodes.Newobj.Value != instruction.OpCode.Value) { ++count; } return(count); } //if (instruction.OpCode.Code == Code.Ret) //return IsVoidMethod() ? 0 : 1; return(0); //we dont now if we are in void method } return(0); }