Ejemplo n.º 1
0
        /// <summary>
        /// Generates CIL for a compound assignment 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>
        /// <param name="target"> The target to modify. </param>
        private void GenerateCompoundAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target)
        {
            // Evaluate the left hand side only once.
            target.GenerateReference(generator, optimizationInfo);
            target.DuplicateReference(generator, optimizationInfo); // For the GenerateSet, later on.

            // Load the value to assign.
            var compoundOperator = new BinaryExpression(GetCompoundBaseOperator(this.OperatorType), new ReferenceGetExpression(target), this.GetOperand(1));

            compoundOperator.GenerateCode(generator, optimizationInfo);

            ILLocalVariable result = null;

            if (optimizationInfo.IgnoreReturnValue != this)
            {
                // Store the resulting value so we can return it as the result of the expression.
                result = generator.CreateTemporaryVariable(compoundOperator.ResultType);
                generator.Duplicate();
                generator.StoreVariable(result);
            }

            // Store the value.
            target.GenerateSet(generator, optimizationInfo, compoundOperator.ResultType);

            if (optimizationInfo.IgnoreReturnValue != this)
            {
                // Restore the expression result.
                generator.LoadVariable(result);
                generator.ReleaseTemporaryVariable(result);
            }
            else
            {
                optimizationInfo.ReturnValueWasNotGenerated = true;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates CIL for an increment or decrement 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>
        /// <param name="target"> The target to modify. </param>
        /// <param name="postfix"> <c>true</c> if this is the postfix version of the operator;
        /// <c>false</c> otherwise. </param>
        /// <param name="increment"> <c>true</c> if this is the increment operator; <c>false</c> if
        /// this is the decrement operator. </param>
        private void GenerateIncrementOrDecrement(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target, bool postfix, bool increment)
        {
            // Note: increment and decrement can produce a number that is out of range if the
            // target is of type Int32.  The only time this should happen is for a loop variable
            // where the range has been carefully checked to make sure an out of range condition
            // cannot happen.

            // Evaluate the left hand side only once.
            target.GenerateReference(generator, optimizationInfo);
            target.DuplicateReference(generator, optimizationInfo); // For the GenerateSet, later on.

            // Get the target value.
            target.GenerateGet(generator, optimizationInfo, true);

            // Convert it to a number.
            if (target.Type != PrimitiveType.Int32)
            {
                EmitConversion.ToNumber(generator, target.Type);
            }

            // If this is PostIncrement or PostDecrement, store the value so it can be returned later.
            var result = generator.CreateTemporaryVariable(target.Type == PrimitiveType.Int32 ? PrimitiveType.Int32 : PrimitiveType.Number);

            if (postfix == true)
            {
                generator.Duplicate();
                generator.StoreVariable(result);
            }

            // Load the increment constant.
            if (target.Type == PrimitiveType.Int32)
            {
                generator.LoadInt32(1);
            }
            else
            {
                generator.LoadDouble(1.0);
            }

            // Add or subtract the constant to the target value.
            if (increment == true)
            {
                generator.Add();
            }
            else
            {
                generator.Subtract();
            }

            // If this is PreIncrement or PreDecrement, store the value so it can be returned later.
            if (postfix == false)
            {
                generator.Duplicate();
                generator.StoreVariable(result);
            }

            // Store the value.
            target.GenerateSet(generator, optimizationInfo, target.Type == PrimitiveType.Int32 ? PrimitiveType.Int32 : PrimitiveType.Number, optimizationInfo.StrictMode);

            // Restore the expression result.
            generator.LoadVariable(result);
            generator.ReleaseTemporaryVariable(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Generates CIL for an increment or decrement 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>
        /// <param name="target"> The target to modify. </param>
        /// <param name="postfix"> <c>true</c> if this is the postfix version of the operator;
        /// <c>false</c> otherwise. </param>
        /// <param name="increment"> <c>true</c> if this is the increment operator; <c>false</c> if
        /// this is the decrement operator. </param>
        private void GenerateIncrementOrDecrement(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target, bool postfix, bool increment)
        {
            // Note: increment and decrement can produce a number that is out of range if the
            // target is of type Int32.  The only time this should happen is for a loop variable
            // where the range has been carefully checked to make sure an out of range condition
            // cannot happen.

            // Evaluate the left hand side only once.
            target.GenerateReference(generator, optimizationInfo);
            target.DuplicateReference(generator, optimizationInfo); // For the GenerateSet, later on.

            // Get the target value.
            target.GenerateGet(generator, optimizationInfo, true);

            // Convert it to a number.
            if (target.Type != PrimitiveType.Int32)
                EmitConversion.ToNumber(generator, target.Type);

            // If this is PostIncrement or PostDecrement, store the value so it can be returned later.
            var result = generator.CreateTemporaryVariable(target.Type == PrimitiveType.Int32 ? PrimitiveType.Int32 : PrimitiveType.Number);
            if (postfix == true)
            {
                generator.Duplicate();
                generator.StoreVariable(result);
            }

            // Load the increment constant.
            if (target.Type == PrimitiveType.Int32)
                generator.LoadInt32(1);
            else
                generator.LoadDouble(1.0);

            // Add or subtract the constant to the target value.
            if (increment == true)
                generator.Add();
            else
                generator.Subtract();

            // If this is PreIncrement or PreDecrement, store the value so it can be returned later.
            if (postfix == false)
            {
                generator.Duplicate();
                generator.StoreVariable(result);
            }

            // Store the value.
            target.GenerateSet(generator, optimizationInfo, target.Type == PrimitiveType.Int32 ? PrimitiveType.Int32 : PrimitiveType.Number, optimizationInfo.StrictMode);

            // Restore the expression result.
            generator.LoadVariable(result);
            generator.ReleaseTemporaryVariable(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Generates CIL for a compound assignment 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>
        /// <param name="target"> The target to modify. </param>
        private void GenerateCompoundAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target)
        {
            // Evaluate the left hand side only once.
            target.GenerateReference(generator, optimizationInfo);
            target.DuplicateReference(generator, optimizationInfo); // For the GenerateSet, later on.

            // Load the value to assign.
            var compoundOperator = new BinaryExpression(GetCompoundBaseOperator(this.OperatorType), new ReferenceGetExpression(target), this.GetOperand(1));
            compoundOperator.GenerateCode(generator, optimizationInfo);

            // Store the resulting value so we can return it as the result of the expression.
            var result = generator.CreateTemporaryVariable(compoundOperator.ResultType);
            generator.Duplicate();
            generator.StoreVariable(result);

            // Store the value.
            target.GenerateSet(generator, optimizationInfo, compoundOperator.ResultType, optimizationInfo.StrictMode);

            // Restore the expression result.
            generator.LoadVariable(result);
            generator.ReleaseTemporaryVariable(result);
        }