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);
}