public override void VisitCall(CallExpression call)
{
MethodInfo method = call.Method;
ParameterInfo[] parameters = typeManager.GetParameters(method);
int i = call.IsBuiltin ? 1 : 0;
if (call.Flip) {
ModalExpression arg = (ModalExpression) call.Arguments.First;
arg.Accept(this);
BoxIfNecessary(arg.RawType, parameters[i].ParameterType);
LocalBuilder tmp =
ilGenerator.DeclareLocal(parameters[i].ParameterType);
ilGenerator.Emit(OpCodes.Stloc, tmp);
call.Receiver.Accept(this);
ilGenerator.Emit(OpCodes.Ldloc, tmp);
}
else {
if (call.Receiver != null) {
if (!call.IsBuiltin &&
call.Receiver.RawType.IsValueType) {
if (call.Receiver is LocalExpression) {
LocalExpression localExpr =
(LocalExpression) call.Receiver;
Argument arg =
currentRoutine.GetArgument(localExpr.Name);
if (arg != null) {
ilGenerator.Emit(OpCodes.Ldarga, arg.Index);
}
else {
LocalVariable local =
localVariableStack.GetLocal(localExpr.Name);
local.EmitLoadAddress(ilGenerator);
}
}
else {
LocalBuilder tmp2 =
ilGenerator.DeclareLocal(call.Receiver.RawType);
call.Receiver.Accept(this);
ilGenerator.Emit(OpCodes.Stloc, tmp2);
ilGenerator.Emit(OpCodes.Ldloca, tmp2);
}
}
else {
call.Receiver.Accept(this);
}
}
foreach (ModalExpression arg in call.Arguments) {
arg.Accept(this);
BoxIfNecessary(arg.RawType, parameters[i].ParameterType);
i++;
}
}
if (call.Receiver != null &&
call.Receiver.RawType.IsInterface)
ilGenerator.EmitCall(OpCodes.Callvirt, method, null);
else
ilGenerator.EmitCall(OpCodes.Call, method, null);
}