public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) {
int tk;
int stackchange = 0;
if (methodInfo == null)
throw new ArgumentNullException("methodInfo");
if (methodInfo.ContainsGenericParameters)
throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters)
throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
tk = GetMemberRefToken(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.ReturnType != typeof(void))
stackchange++;
// Pop the parameters.
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);
m_length = PutInteger4(tk, m_length, m_ILStream);
}