/// <summary> /// Emit a string concatenation /// </summary> /// <param name="ilg"></param> /// <param name="services"></param> private void EmitStringConcat(FleeILGenerator ilg, IServiceProvider services) { Type argType = default(Type); System.Reflection.MethodInfo concatMethodInfo = default(System.Reflection.MethodInfo); // Pick the most specific concat method if (this.AreBothChildrenOfType(typeof(string)) == true) { concatMethodInfo = _ourStringConcatMethodInfo; argType = typeof(string); } else { Debug.Assert(this.IsEitherChildOfType(typeof(string)), "one child must be a string"); concatMethodInfo = _ourObjectConcatMethodInfo; argType = typeof(object); } // Emit the operands and call the function MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, argType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, argType, ilg); ilg.Emit(OpCodes.Call, concatMethodInfo); }
// If the shift count is greater than the number of bits in the number, the result is undefined. // So we play it safe and force the shift count to 32/64 bits by ANDing it with the appropriate mask. private void EmitShiftCount(FleeILGenerator ilg, IServiceProvider services) { MyRightChild.Emit(ilg, services); TypeCode tc = Type.GetTypeCode(MyLeftChild.ResultType); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: ilg.Emit(OpCodes.Ldc_I4_S, Convert.ToSByte(0x1f)); break; case TypeCode.Int64: case TypeCode.UInt64: ilg.Emit(OpCodes.Ldc_I4_S, Convert.ToSByte(0x3f)); break; default: Debug.Assert(false, "unknown left shift operand"); break; } ilg.Emit(OpCodes.And); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { MethodInfo overloadedMethod = this.GetOverloadedAndOrOperator(); if ((overloadedMethod != null)) { // Emit a call to an overloaded operator this.EmitOverloadedOperatorCall(overloadedMethod, ilg, services); } else { Type resultType = this.ResultType; if (object.ReferenceEquals(resultType, typeof(bool))) { this.DoEmitLogical(ilg, services); } else { MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); EmitBitwiseOperation(ilg, _myOperation); } } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); ilg.Emit(OpCodes.Xor); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; if (object.ReferenceEquals(resultType, typeof(bool))) { this.DoEmitLogical(ilg, services); } else { MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); EmitBitwiseOperation(ilg, _myOperation); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type binaryResultType = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType); MethodInfo overloadedOperator = this.GetOverloadedCompareOperator(); if (this.AreBothChildrenOfType(typeof(string))) { // String equality MyLeftChild.Emit(ilg, services); MyRightChild.Emit(ilg, services); EmitStringEquality(ilg, _myOperation, services); } else if ((overloadedOperator != null)) { base.EmitOverloadedOperatorCall(overloadedOperator, ilg, services); } else if ((binaryResultType != null)) { // Emit a compare of numeric operands EmitChildWithConvert(MyLeftChild, binaryResultType, ilg, services); EmitChildWithConvert(MyRightChild, binaryResultType, ilg, services); EmitCompareOperation(ilg, _myOperation); } else if (this.AreBothChildrenOfType(typeof(bool))) { // Boolean equality this.EmitRegular(ilg, services); } else if (this.AreBothChildrenReferenceTypes() == true) { // Reference equality this.EmitRegular(ilg, services); } else if (MyLeftChild.ResultType.IsEnum == true & MyRightChild.ResultType.IsEnum == true) { this.EmitRegular(ilg, services); } else { Debug.Fail("unknown operand types"); } }
private void EmitRegular(FleeILGenerator ilg, IServiceProvider services) { MyLeftChild.Emit(ilg, services); MyRightChild.Emit(ilg, services); this.EmitCompareOperation(ilg, _myOperation); }