Negate() public abstract method

Pops a value from the stack, negates it, then pushes it back onto the stack.
public abstract Negate ( ) : void
return void
コード例 #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));
            }
        }
コード例 #2
0
        /// <summary>
        /// Generates CIL for the expression.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
        {
            // Special-case the delete operator.
            if (this.OperatorType == OperatorType.Delete)
            {
                GenerateDelete(generator, optimizationInfo);
                return;
            }

            // If a return value is not expected, generate only the side-effects.

            /*if (optimizationInfo.SuppressReturnValue == true)
             * {
             *  this.GenerateSideEffects(generator, optimizationInfo);
             *  return;
             * }*/

            // Special-case the typeof operator.
            if (this.OperatorType == OperatorType.Typeof)
            {
                GenerateTypeof(generator, optimizationInfo);
                return;
            }

            // Load the operand onto the stack.
            this.Operand.GenerateCode(generator, optimizationInfo);

            // Convert the operand to the correct type.
            switch (this.OperatorType)
            {
            case OperatorType.Plus:
            case OperatorType.Minus:
                EmitConversion.ToNumber(generator, this.Operand.ResultType);
                break;

            case OperatorType.BitwiseNot:
                EmitConversion.ToInt32(generator, this.Operand.ResultType);
                break;

            case OperatorType.LogicalNot:
                EmitConversion.ToBool(generator, this.Operand.ResultType);
                break;
            }

            // Apply the operator.
            switch (this.OperatorType)
            {
            case OperatorType.Plus:
                break;

            case OperatorType.Minus:
                generator.Negate();
                break;

            case OperatorType.BitwiseNot:
                generator.BitwiseNot();
                break;

            case OperatorType.LogicalNot:
                generator.LoadBoolean(false);
                generator.CompareEqual();
                break;

            case OperatorType.Void:
                generator.Pop();
                EmitHelpers.EmitUndefined(generator);
                break;

            default:
                throw new NotImplementedException(string.Format("Unsupported operator {0}", this.OperatorType));
            }
        }
コード例 #3
0
        /// <summary>
        /// Generates CIL for the expression.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
        {
            // Special-case the delete operator.
            if (this.OperatorType == OperatorType.Delete)
            {
                GenerateDelete(generator, optimizationInfo);
                return;
            }

            // If a return value is not expected, generate only the side-effects.
            /*if (optimizationInfo.SuppressReturnValue == true)
            {
                this.GenerateSideEffects(generator, optimizationInfo);
                return;
            }*/

            // Special-case the typeof operator.
            if (this.OperatorType == OperatorType.Typeof)
            {
                GenerateTypeof(generator, optimizationInfo);
                return;
            }

            // Load the operand onto the stack.
            this.Operand.GenerateCode(generator, optimizationInfo);

            // Convert the operand to the correct type.
            switch (this.OperatorType)
            {
                case OperatorType.Plus:
                case OperatorType.Minus:
                    EmitConversion.ToNumber(generator, this.Operand.ResultType);
                    break;

                case OperatorType.BitwiseNot:
                    EmitConversion.ToInt32(generator, this.Operand.ResultType);
                    break;

                case OperatorType.LogicalNot:
                    EmitConversion.ToBool(generator, this.Operand.ResultType);
                    break;
            }

            // Apply the operator.
            switch (this.OperatorType)
            {
                case OperatorType.Plus:
                    break;

                case OperatorType.Minus:
                    generator.Negate();
                    break;

                case OperatorType.BitwiseNot:
                    generator.BitwiseNot();
                    break;

                case OperatorType.LogicalNot:
                    generator.LoadBoolean(false);
                    generator.CompareEqual();
                    break;

                case OperatorType.Void:
                    generator.Pop();
                    EmitHelpers.EmitUndefined(generator);
                    break;

                default:
                    throw new NotImplementedException(string.Format("Unsupported operator {0}", this.OperatorType));
            }
        }
コード例 #4
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));
            }
        }