protected virtual void ApplyPushBehaviour(InspectionPass pass, Instruction instruction) { InspectedStack stack = pass.Stack; switch (instruction.OpCode.StackBehaviourPush) { case StackBehaviour.Push0: break; case StackBehaviour.Push1: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Push1_push1: // stack.Push(null); // stack.Push(null); // break; throw new ArgumentException(); case StackBehaviour.Pushi: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Pushi8: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Pushr4: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Pushr8: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Pushref: stack.Push(GetStackEntryForInstruction(pass, instruction)); break; case StackBehaviour.Varpush: MethodReference operand = instruction.Operand as MethodReference; if (operand != null) { if (!IsVoid(operand.DeclaringType.Module, operand.ReturnType.ReturnType)) { stack.Push(GetStackEntryForInstruction(pass, instruction)); } } break; default: throw new ArgumentException(); } }
protected virtual void ApplyPopBehaviour(InspectionPass pass, Instruction instruction) { InspectedStack stack = pass.Stack; switch (instruction.OpCode.StackBehaviourPop) { case StackBehaviour.Pop0: break; case StackBehaviour.Pop1: stack.Pop(); break; case StackBehaviour.Pop1_pop1: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi: stack.Pop(); break; case StackBehaviour.Popi_pop1: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi_popi: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi_popi8: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi_popi_popi: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi_popr4: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popi_popr8: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref: stack.Pop(); break; case StackBehaviour.Popref_pop1: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi: stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi_popi: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi_popi8: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi_popr4: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi_popr8: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.Popref_popi_popref: stack.Pop(); stack.Pop(); stack.Pop(); break; case StackBehaviour.PopAll: pass.Stack.Clear(); break; case StackBehaviour.Varpop: MethodReference operand = instruction.Operand as MethodReference; if (operand != null) { for (int i = 0; i < operand.Parameters.Count; ++i) { stack.Pop(); } if (instruction.OpCode != OpCodes.Newobj && operand.HasThis) { stack.Pop(); } } if (OpCodes.Ret == instruction.OpCode) { if (!IsVoid(pass.Method.DeclaringType.Module, pass.Method.ReturnType.ReturnType)) { stack.Pop(); } } break; default: throw new ArgumentException(); } }