private void EmitBinaryOperator(EmitContext ec) { ILGenerator ig = ec.ig; bool flag = Expression.IsUnsigned(this.left.Type); ExpressionType nodeType = base.NodeType; switch (nodeType) { case ExpressionType.Divide: ig.Emit((!flag) ? OpCodes.Div : OpCodes.Div_Un); break; case ExpressionType.Equal: ig.Emit(OpCodes.Ceq); break; case ExpressionType.ExclusiveOr: ig.Emit(OpCodes.Xor); break; case ExpressionType.GreaterThan: ig.Emit((!flag) ? OpCodes.Cgt : OpCodes.Cgt_Un); break; case ExpressionType.GreaterThanOrEqual: if (flag || BinaryExpression.IsSingleOrDouble(this.left.Type)) { ig.Emit(OpCodes.Clt_Un); } else { ig.Emit(OpCodes.Clt); } ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Ceq); break; default: switch (nodeType) { case ExpressionType.Add: ig.Emit(OpCodes.Add); break; case ExpressionType.AddChecked: if (BinaryExpression.IsInt32OrInt64(this.left.Type)) { ig.Emit(OpCodes.Add_Ovf); } else { ig.Emit((!flag) ? OpCodes.Add : OpCodes.Add_Ovf_Un); } break; case ExpressionType.And: ig.Emit(OpCodes.And); break; default: throw new InvalidOperationException(string.Format("Internal error: BinaryExpression contains non-Binary nodetype {0}", base.NodeType)); } break; case ExpressionType.LeftShift: case ExpressionType.RightShift: ig.Emit(OpCodes.Ldc_I4, (this.left.Type != typeof(int)) ? 63 : 31); ig.Emit(OpCodes.And); if (base.NodeType == ExpressionType.RightShift) { ig.Emit((!flag) ? OpCodes.Shr : OpCodes.Shr_Un); } else { ig.Emit(OpCodes.Shl); } break; case ExpressionType.LessThan: ig.Emit((!flag) ? OpCodes.Clt : OpCodes.Clt_Un); break; case ExpressionType.LessThanOrEqual: if (flag || BinaryExpression.IsSingleOrDouble(this.left.Type)) { ig.Emit(OpCodes.Cgt_Un); } else { ig.Emit(OpCodes.Cgt); } ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Ceq); break; case ExpressionType.Modulo: ig.Emit((!flag) ? OpCodes.Rem : OpCodes.Rem_Un); break; case ExpressionType.Multiply: ig.Emit(OpCodes.Mul); break; case ExpressionType.MultiplyChecked: if (BinaryExpression.IsInt32OrInt64(this.left.Type)) { ig.Emit(OpCodes.Mul_Ovf); } else { ig.Emit((!flag) ? OpCodes.Mul : OpCodes.Mul_Ovf_Un); } break; case ExpressionType.NotEqual: ig.Emit(OpCodes.Ceq); ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Ceq); break; case ExpressionType.Or: ig.Emit(OpCodes.Or); break; case ExpressionType.Power: ig.Emit(OpCodes.Call, typeof(Math).GetMethod("Pow")); break; case ExpressionType.Subtract: ig.Emit(OpCodes.Sub); break; case ExpressionType.SubtractChecked: if (BinaryExpression.IsInt32OrInt64(this.left.Type)) { ig.Emit(OpCodes.Sub_Ovf); } else { ig.Emit((!flag) ? OpCodes.Sub : OpCodes.Sub_Ovf_Un); } break; } }