ConvertToInteger() public abstract method

Pops a value from the stack, converts it to a signed integer, then pushes it back onto the stack.
public abstract ConvertToInteger ( ) : void
return void
Ejemplo n.º 1
0
        /// <summary>
        /// Pops the value on the stack, converts it to an integer, then pushes the integer result
        /// onto the stack.
        /// </summary>
        /// <param name="generator"> The IL generator. </param>
        /// <param name="fromType"> The type to convert from. </param>
        public static void ToInteger(ILGenerator generator, PrimitiveType fromType)
        {
            // Check that a conversion is actually necessary.
            if (fromType == PrimitiveType.Int32 || fromType == PrimitiveType.UInt32 || fromType == PrimitiveType.Bool)
            {
                return;
            }

            switch (fromType)
            {
            case PrimitiveType.Undefined:
            case PrimitiveType.Null:
                // Converting from undefined or null produces 0.
                generator.Pop();
                generator.LoadInt32(0);
                break;

            case PrimitiveType.Number:
                // Converting from a number produces the following:
                // Any number between -2147483648 and +2147483647 -> itself
                // Any number smaller than -2147483648 -> -2147483648
                // Any number larger than +2147483647 -> +2147483647
                // NaN -> 0

                // bool isPositiveInfinity = input > 2147483647.0
                var isPositiveInfinity = generator.CreateTemporaryVariable(typeof(bool));
                generator.Duplicate();
                generator.LoadDouble(2147483647.0);
                generator.CompareGreaterThan();
                generator.StoreVariable(isPositiveInfinity);

                // bool notNaN = input == input
                var notNaN = generator.CreateTemporaryVariable(typeof(bool));
                generator.Duplicate();
                generator.Duplicate();
                generator.CompareEqual();
                generator.StoreVariable(notNaN);

                // input = (int)input
                // Infinity -> -2147483648
                // -Infinity -> -2147483648
                // NaN -> -2147483648
                generator.ConvertToInteger();

                // input = input & -((int)notNaN)
                generator.LoadVariable(notNaN);
                generator.Negate();
                generator.BitwiseAnd();

                // input = input - (int)isPositiveInfinity
                generator.LoadVariable(isPositiveInfinity);
                generator.Subtract();

                // The temporary variables are no longer needed.
                generator.ReleaseTemporaryVariable(notNaN);
                generator.ReleaseTemporaryVariable(isPositiveInfinity);
                break;

            case PrimitiveType.String:
            case PrimitiveType.ConcatenatedString:
            case PrimitiveType.Any:
            case PrimitiveType.Object:
                // Otherwise, fall back to calling TypeConverter.ToInteger()
                generator.Call(ReflectionHelpers.TypeConverter_ToInteger);
                break;

            default:
                throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Pops the value on the stack, converts it to an integer, then pushes the integer result
        /// onto the stack.
        /// </summary>
        /// <param name="generator"> The IL generator. </param>
        /// <param name="fromType"> The type to convert from. </param>
        public static void ToInteger(ILGenerator generator, PrimitiveType fromType)
        {
            // Check that a conversion is actually necessary.
            if (fromType == PrimitiveType.Int32 || fromType == PrimitiveType.UInt32 || fromType == PrimitiveType.Bool)
                return;

            switch (fromType)
            {
                case PrimitiveType.Undefined:
                case PrimitiveType.Null:
                    // Converting from undefined or null produces 0.
                    generator.Pop();
                    generator.LoadInt32(0);
                    break;

                case PrimitiveType.Number:
                    // Converting from a number produces the following:
                    // Any number between -2147483648 and +2147483647 -> itself
                    // Any number smaller than -2147483648 -> -2147483648
                    // Any number larger than +2147483647 -> +2147483647
                    // NaN -> 0

                    // bool isPositiveInfinity = input > 2147483647.0
                    var isPositiveInfinity = generator.CreateTemporaryVariable(typeof(bool));
                    generator.Duplicate();
                    generator.LoadDouble(2147483647.0);
                    generator.CompareGreaterThan();
                    generator.StoreVariable(isPositiveInfinity);

                    // bool notNaN = input == input
                    var notNaN = generator.CreateTemporaryVariable(typeof(bool));
                    generator.Duplicate();
                    generator.Duplicate();
                    generator.CompareEqual();
                    generator.StoreVariable(notNaN);

                    // input = (int)input
                    // Infinity -> -2147483648
                    // -Infinity -> -2147483648
                    // NaN -> -2147483648
                    generator.ConvertToInteger();

                    // input = input & -((int)notNaN)
                    generator.LoadVariable(notNaN);
                    generator.Negate();
                    generator.BitwiseAnd();

                    // input = input - (int)isPositiveInfinity
                    generator.LoadVariable(isPositiveInfinity);
                    generator.Subtract();

                    // The temporary variables are no longer needed.
                    generator.ReleaseTemporaryVariable(notNaN);
                    generator.ReleaseTemporaryVariable(isPositiveInfinity);
                    break;

                case PrimitiveType.String:
                case PrimitiveType.ConcatenatedString:
                case PrimitiveType.Any:
                case PrimitiveType.Object:
                    // Otherwise, fall back to calling TypeConverter.ToInteger()
                    generator.Call(ReflectionHelpers.TypeConverter_ToInteger);
                    break;

                default:
                    throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
            }
        }