internal override void TranslateToIL(ILGenerator il, Type rtype){
if (this.metaData == null){
TranslateToILForNoOverloadCase(il, rtype);
return;
}
if (this.metaData is MethodInfo){
Object result = null;
MethodInfo oper = (MethodInfo)this.metaData;
Type type = Convert.ToType(this.operand1.InferType(null));
ParameterInfo[] pars = oper.GetParameters();
this.operand1.TranslateToILPreSetPlusGet(il);
Convert.Emit(this, il, type, pars[0].ParameterType);
this.operand2.TranslateToIL(il, pars[1].ParameterType);
il.Emit(OpCodes.Call, oper);
if (rtype != Typeob.Void){
result = il.DeclareLocal(rtype);
il.Emit(OpCodes.Dup);
Convert.Emit(this, il, type, rtype);
il.Emit(OpCodes.Stloc, (LocalBuilder)result);
}
Convert.Emit(this, il, oper.ReturnType, type);
this.operand1.TranslateToILSet(il);
if (rtype != Typeob.Void)
il.Emit(OpCodes.Ldloc, (LocalBuilder)result);
}else{
//Getting here is just too bad. We do not know until the code runs whether or not to call an overloaded operator method.
//Compile operands to objects and devolve the decision making to run time thunks
Type type = Convert.ToType(this.operand1.InferType(null));
LocalBuilder result = il.DeclareLocal(Typeob.Object);
this.operand1.TranslateToILPreSetPlusGet(il);
Convert.Emit(this, il, type, Typeob.Object);
il.Emit(OpCodes.Stloc, result);
il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData);
il.Emit(OpCodes.Ldloc, result);
this.operand2.TranslateToIL(il, Typeob.Object);
il.Emit(OpCodes.Call, CompilerGlobals.evaluateNumericBinaryMethod);
if (rtype != Typeob.Void){
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Stloc, result);
}
Convert.Emit(this, il, Typeob.Object, type);
this.operand1.TranslateToILSet(il);
if (rtype != Typeob.Void){
il.Emit(OpCodes.Ldloc, result);
Convert.Emit(this, il, Typeob.Object, rtype);
}
}
}