private static string GetOverloadedOperatorFunctionName(BinaryArithmeticOperation op) { switch (op) { case BinaryArithmeticOperation.Add: return("Addition"); case BinaryArithmeticOperation.Subtract: return("Subtraction"); case BinaryArithmeticOperation.Multiply: return("Multiply"); case BinaryArithmeticOperation.Divide: return("Division"); case BinaryArithmeticOperation.Mod: return("Modulus"); case BinaryArithmeticOperation.Power: return("Exponent"); default: Debug.Assert(false, "unknown operator type"); return(null); } }
/// <summary> /// Returns the correct name used to generate IL operations /// </summary> /// <param name="operation"></param> /// <returns></returns> private static string GetOverloadedOperatorFunctionName(BinaryArithmeticOperation operation) { return(operation switch { BinaryArithmeticOperation.Add => "Addition", BinaryArithmeticOperation.Subtract => "Subtraction", BinaryArithmeticOperation.Multiply => "Multiply", BinaryArithmeticOperation.Divide => "Division", BinaryArithmeticOperation.Mod => "Modulus", BinaryArithmeticOperation.Power => "Exponent", _ => throw new InvalidOperationException($"Operation {operation} is not a valid arithmetic operation"), });
private static string GetOverloadedOperatorFunctionName(BinaryArithmeticOperation op) { string getOverloadedOperatorFunctionName = null; switch (op) { case BinaryArithmeticOperation.Add: getOverloadedOperatorFunctionName = "Addition"; break; case BinaryArithmeticOperation.Subtract: getOverloadedOperatorFunctionName = "Subtraction"; break; case BinaryArithmeticOperation.Multiply: getOverloadedOperatorFunctionName = "Multiply"; break; case BinaryArithmeticOperation.Divide: getOverloadedOperatorFunctionName = "Division"; break; case BinaryArithmeticOperation.Mod: getOverloadedOperatorFunctionName = "Modulus"; break; case BinaryArithmeticOperation.Power: getOverloadedOperatorFunctionName = "Exponent"; break; default: Debug.Assert(false, "unknown operator type"); break; } return(getOverloadedOperatorFunctionName); }
protected override void GetOperation(object operation) { this.operation = (BinaryArithmeticOperation)operation; }
/// <summary> /// Emit an arithmetic operation with handling for unsigned and checked contexts /// </summary> /// <param name="op"></param> /// <param name="ilg"></param> /// <param name="services"></param> private void EmitArithmeticOperation(BinaryArithmeticOperation op, FleeILGenerator ilg, IServiceProvider services) { ExpressionOptions options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); bool unsigned = IsUnsignedForArithmetic(MyLeftChild.ResultType) & IsUnsignedForArithmetic(MyRightChild.ResultType); bool integral = Utility.IsIntegralType(MyLeftChild.ResultType) & Utility.IsIntegralType(MyRightChild.ResultType); bool emitOverflow = integral & options.Checked; EmitChildWithConvert(MyLeftChild, this.ResultType, ilg, services); if (this.IsOptimizablePower == false) { EmitChildWithConvert(MyRightChild, this.ResultType, ilg, services); } switch (op) { case BinaryArithmeticOperation.Add: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Add_Ovf_Un); } else { ilg.Emit(OpCodes.Add_Ovf); } } else { ilg.Emit(OpCodes.Add); } break; case BinaryArithmeticOperation.Subtract: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Sub_Ovf_Un); } else { ilg.Emit(OpCodes.Sub_Ovf); } } else { ilg.Emit(OpCodes.Sub); } break; case BinaryArithmeticOperation.Multiply: this.EmitMultiply(ilg, emitOverflow, unsigned); break; case BinaryArithmeticOperation.Divide: if (unsigned == true) { ilg.Emit(OpCodes.Div_Un); } else { ilg.Emit(OpCodes.Div); } break; case BinaryArithmeticOperation.Mod: if (unsigned == true) { ilg.Emit(OpCodes.Rem_Un); } else { ilg.Emit(OpCodes.Rem); } break; case BinaryArithmeticOperation.Power: this.EmitPower(ilg, emitOverflow, unsigned); break; default: Debug.Fail("Unknown op type"); break; } }
// Emit an arithmetic operation with handling for unsigned and checked contexts private void EmitArithmeticOperation(BinaryArithmeticOperation op, FleeILGenerator ilg, IServiceProvider services) { ExpressionOptions options = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions; bool unsigned = IsUnsignedForArithmetic(MyLeftChild.ResultType) & IsUnsignedForArithmetic(MyRightChild.ResultType); bool integral = Utility.IsIntegralType(MyLeftChild.ResultType) & Utility.IsIntegralType(MyRightChild.ResultType); bool emitOverflow = integral & options.Checked; switch (op) { case BinaryArithmeticOperation.Add: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Add_Ovf_Un); } else { ilg.Emit(OpCodes.Add_Ovf); } } else { ilg.Emit(OpCodes.Add); } break; case BinaryArithmeticOperation.Subtract: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Sub_Ovf_Un); } else { ilg.Emit(OpCodes.Sub_Ovf); } } else { ilg.Emit(OpCodes.Sub); } break; case BinaryArithmeticOperation.Multiply: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Mul_Ovf_Un); } else { ilg.Emit(OpCodes.Mul_Ovf); } } else { ilg.Emit(OpCodes.Mul); } break; case BinaryArithmeticOperation.Divide: if (unsigned == true) { ilg.Emit(OpCodes.Div_Un); } else { ilg.Emit(OpCodes.Div); } break; case BinaryArithmeticOperation.Mod: if (unsigned == true) { ilg.Emit(OpCodes.Rem_Un); } else { ilg.Emit(OpCodes.Rem); } break; case BinaryArithmeticOperation.Power: ilg.Emit(OpCodes.Call, OurPowerMethodInfo); break; default: Debug.Fail("Unknown op type"); break; } }
private void EmitArithmeticOperation(BinaryArithmeticOperation op, FleeIlGenerator ilg, IServiceProvider services) { var options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); var unsigned = IsUnsignedForArithmetic(this.myLeftChild.ResultType) & IsUnsignedForArithmetic(this.myRightChild.ResultType); var integral = Utility.IsIntegralType(this.myLeftChild.ResultType) & Utility.IsIntegralType(this.myRightChild.ResultType); var emitOverflow = integral & options.Checked; EmitChildWithConvert(this.myLeftChild, this.ResultType, ilg, services); var flag = !this.IsOptimizablePower; if (flag) { EmitChildWithConvert(this.myRightChild, this.ResultType, ilg, services); } switch (op) { case BinaryArithmeticOperation.Add: { var flag2 = emitOverflow; if (flag2) { var flag3 = unsigned; ilg.Emit(flag3 ? OpCodes.Add_Ovf_Un : OpCodes.Add_Ovf); } else { ilg.Emit(OpCodes.Add); } break; } case BinaryArithmeticOperation.Subtract: { var flag4 = emitOverflow; if (flag4) { var flag5 = unsigned; ilg.Emit(flag5 ? OpCodes.Sub_Ovf_Un : OpCodes.Sub_Ovf); } else { ilg.Emit(OpCodes.Sub); } break; } case BinaryArithmeticOperation.Multiply: this.EmitMultiply(ilg, emitOverflow, unsigned); break; case BinaryArithmeticOperation.Divide: { var flag6 = unsigned; ilg.Emit(flag6 ? OpCodes.Div_Un : OpCodes.Div); break; } case BinaryArithmeticOperation.Mod: { var flag7 = unsigned; ilg.Emit(flag7 ? OpCodes.Rem_Un : OpCodes.Rem); break; } case BinaryArithmeticOperation.Power: this.EmitPower(ilg, emitOverflow, unsigned); break; default: Debug.Fail("Unknown op type"); break; } }
protected override void GetOperation(object operation) { MyOperation = (BinaryArithmeticOperation)operation; }
// Emit an arithmetic operation with handling for unsigned and checked contexts private void EmitArithmeticOperation(BinaryArithmeticOperation op, FleeILGenerator ilg, IServiceProvider services) { var options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); var unsigned = IsUnsignedForArithmetic(MyLeftChild.ResultType) & IsUnsignedForArithmetic(MyRightChild.ResultType); var integral = Utility.IsIntegralType(MyLeftChild.ResultType) & Utility.IsIntegralType(MyRightChild.ResultType); var emitOverflow = integral & options.Checked; EmitChildWithConvert(MyLeftChild, this.ResultType, ilg, services); if (this.IsOptimizablePower == false) { EmitChildWithConvert(MyRightChild, this.ResultType, ilg, services); } switch (op) { case BinaryArithmeticOperation.Add: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Add_Ovf_Un); } else { ilg.Emit(OpCodes.Add_Ovf); } } else { ilg.Emit(OpCodes.Add); } break; case BinaryArithmeticOperation.Subtract: if (emitOverflow == true) { if (unsigned == true) { ilg.Emit(OpCodes.Sub_Ovf_Un); } else { ilg.Emit(OpCodes.Sub_Ovf); } } else { ilg.Emit(OpCodes.Sub); } break; case BinaryArithmeticOperation.Multiply: this.EmitMultiply(ilg, emitOverflow, unsigned); break; case BinaryArithmeticOperation.Divide: if (unsigned == true) { ilg.Emit(OpCodes.Div_Un); } else { ilg.Emit(OpCodes.Div); } break; case BinaryArithmeticOperation.Mod: if (unsigned == true ) { ilg.Emit(OpCodes.Rem_Un); } else { ilg.Emit(OpCodes.Rem); } break; case BinaryArithmeticOperation.Power: this.EmitPower(ilg, emitOverflow, unsigned); break; default: Debug.Fail("Unknown op type"); break; } }
private static string GetOverloadedOperatorFunctionName(BinaryArithmeticOperation op) { switch (op) { case BinaryArithmeticOperation.Add: return "Addition"; case BinaryArithmeticOperation.Subtract: return "Subtraction"; case BinaryArithmeticOperation.Multiply: return "Multiply"; case BinaryArithmeticOperation.Divide: return "Division"; case BinaryArithmeticOperation.Mod: return "Modulus"; case BinaryArithmeticOperation.Power: return "Exponent"; default: Debug.Assert(false, "unknown operator type"); return null; } }