private void BinaryShiftExpression(BinaryExpression binaryExpression) { binaryExpression.Left.Accept(this); binaryExpression.Right.Accept(this); int bits = Marshal.SizeOf(binaryExpression.Left.Type) * 8; ILUtil.EmitConstant(_il, bits - 1); _il.Emit(OpCodes.And); switch (binaryExpression.ExpressionType) { case ExpressionType.ShiftLeft: _il.Emit(OpCodes.Shl); break; case ExpressionType.ShiftRight: if (TypeUtil.IsUnsigned(binaryExpression.Left.Type)) { _il.Emit(OpCodes.Shr_Un); } else { _il.Emit(OpCodes.Shr); } break; default: throw new InvalidOperationException(); } }
private static void EmitNumericConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked) { if ( !(typeFrom.IsEnum || TypeUtil.IsNumeric(typeFrom)) || !(typeTo.IsEnum || TypeUtil.IsNumeric(typeTo)) ) { throw new InvalidOperationException("Unhandled convert"); } bool isFromUnsigned = TypeUtil.IsUnsigned(typeFrom); bool isFromFloatingPoint = TypeUtil.IsFloatingPoint(typeFrom); if (typeTo == typeof(Single)) { if (isFromUnsigned) { il.Emit(OpCodes.Conv_R_Un); } il.Emit(OpCodes.Conv_R4); } else if (typeTo == typeof(Double)) { if (isFromUnsigned) { il.Emit(OpCodes.Conv_R_Un); } il.Emit(OpCodes.Conv_R8); } else { TypeCode tc = Type.GetTypeCode(typeTo); if (isChecked) { // Overflow checking needs to know if the source value on the IL stack is unsigned or not. if (isFromUnsigned) { switch (tc) { case TypeCode.SByte: il.Emit(OpCodes.Conv_Ovf_I1_Un); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_Ovf_I2_Un); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_Ovf_I4_Un); break; case TypeCode.Int64: il.Emit(OpCodes.Conv_Ovf_I8_Un); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_Ovf_U1_Un); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_Ovf_U2_Un); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_Ovf_U4_Un); break; case TypeCode.UInt64: il.Emit(OpCodes.Conv_Ovf_U8_Un); break; default: throw new InvalidOperationException("Unhandled convert"); } } else { switch (tc) { case TypeCode.SByte: il.Emit(OpCodes.Conv_Ovf_I1); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_Ovf_I2); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_Ovf_I4); break; case TypeCode.Int64: il.Emit(OpCodes.Conv_Ovf_I8); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_Ovf_U1); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_Ovf_U2); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_Ovf_U4); break; case TypeCode.UInt64: il.Emit(OpCodes.Conv_Ovf_U8); break; default: throw new InvalidOperationException("Unhandled convert"); } } } else { switch (tc) { case TypeCode.SByte: il.Emit(OpCodes.Conv_I1); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_U1); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_I2); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_U2); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_I4); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_U4); break; case TypeCode.Int64: if (isFromUnsigned) { il.Emit(OpCodes.Conv_U8); } else { il.Emit(OpCodes.Conv_I8); } break; case TypeCode.UInt64: if (isFromUnsigned || isFromFloatingPoint) { il.Emit(OpCodes.Conv_U8); } else { il.Emit(OpCodes.Conv_I8); } break; default: throw new InvalidOperationException("Unhandled convert"); } } } }
private void BinaryArithicExpression(BinaryExpression binaryExpression) { // Reference compares. if ( !binaryExpression.Left.Type.IsValueType && !binaryExpression.Right.Type.IsValueType && ( binaryExpression.ExpressionType == ExpressionType.Equals || binaryExpression.ExpressionType == ExpressionType.NotEquals ) ) { binaryExpression.Left.Accept(this); binaryExpression.Right.Accept(this); _il.Emit(OpCodes.Ceq); if (binaryExpression.ExpressionType == ExpressionType.NotEquals) { _il.Emit(OpCodes.Ldc_I4_0); _il.Emit(OpCodes.Ceq); } return; } Emit(binaryExpression.Left, binaryExpression.CommonType); Emit(binaryExpression.Right, binaryExpression.CommonType); switch (binaryExpression.ExpressionType) { case ExpressionType.Equals: case ExpressionType.NotEquals: _il.Emit(OpCodes.Ceq); if (binaryExpression.ExpressionType == ExpressionType.NotEquals) { _il.Emit(OpCodes.Ldc_I4_0); _il.Emit(OpCodes.Ceq); } break; case ExpressionType.Greater: case ExpressionType.LessOrEquals: if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Cgt_Un); } else { _il.Emit(OpCodes.Cgt); } if (binaryExpression.ExpressionType == ExpressionType.LessOrEquals) { _il.Emit(OpCodes.Ldc_I4_0); _il.Emit(OpCodes.Ceq); } break; case ExpressionType.Less: case ExpressionType.GreaterOrEquals: if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Clt_Un); } else { _il.Emit(OpCodes.Clt); } if (binaryExpression.ExpressionType == ExpressionType.GreaterOrEquals) { _il.Emit(OpCodes.Ldc_I4_0); _il.Emit(OpCodes.Ceq); } break; case ExpressionType.Add: if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType)) { if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Add_Ovf_Un); } else { _il.Emit(OpCodes.Add_Ovf); } } else { _il.Emit(OpCodes.Add); } break; case ExpressionType.Divide: if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Div_Un); } else { _il.Emit(OpCodes.Div); } break; case ExpressionType.Multiply: if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType)) { if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Mul_Ovf_Un); } else { _il.Emit(OpCodes.Mul_Ovf); } } else { _il.Emit(OpCodes.Mul); } break; case ExpressionType.Subtract: if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType)) { if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Sub_Ovf_Un); } else { _il.Emit(OpCodes.Sub_Ovf); } } else { _il.Emit(OpCodes.Sub); } break; case ExpressionType.Modulo: if (TypeUtil.IsUnsigned(binaryExpression.CommonType)) { _il.Emit(OpCodes.Rem_Un); } else { _il.Emit(OpCodes.Rem); } break; default: throw new InvalidOperationException(); } }