public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { int stackchange = 0; if (methodInfo == null) throw new ArgumentNullException("methodInfo"); int tk = GetMethodToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); InternalEmit(opcode); // The opcode must be one of call, callvirt, or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode passed to EmitCall."); // Push the return value if there is one. if (methodInfo.GetReturnType() != typeof(void)) stackchange++; // Pop the parameters. if (methodInfo.GetParameterTypes() != null) stackchange -= methodInfo.GetParameterTypes().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; // Pop the optional parameters off the stack. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tk, m_length, m_ILStream); }