/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Load the value to assign. var rhs = GetOperand(1); // Potentially transferring a constant here. // Note that all of the others affect the source value in some way // so this is the only one which can potentially transfer a constant like this. object constValue = target.GetConstantValue(); // Store the value. target.GenerateSet(generator, optimizationInfo, optimizationInfo.RootExpression != this, rhs.GetResultType(optimizationInfo), delegate(bool two) { // Generate the code: if (constValue != null) { // Straight emit the constant value (Note that it could be a function - it handles that for us): EmitHelpers.EmitValue(generator, constValue); } else { rhs.GenerateCode(generator, optimizationInfo); } if (two) { // Duplicate the value so it remains on the stack afterwards. generator.Duplicate(); } }, optimizationInfo.StrictMode); }
/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Evaluate the left hand side first! target.GenerateReference(generator, optimizationInfo); // Load the value to assign. var rhs = this.GetOperand(1); rhs.GenerateCode(generator, optimizationInfo); // Support the inferred function displayName property. if (rhs is FunctionExpression) { ((FunctionExpression)rhs).GenerateDisplayName(generator, optimizationInfo, target.ToString(), false); } // Store the RHS value so we can return it as the result of the expression. var result = generator.CreateTemporaryVariable(rhs.ResultType); generator.Duplicate(); generator.StoreVariable(result); // Store the value. target.GenerateSet(generator, optimizationInfo, rhs.ResultType, optimizationInfo.StrictMode); // Restore the RHS value. generator.LoadVariable(result); generator.ReleaseTemporaryVariable(result); }
/// <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; } }
/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Evaluate the left hand side first! target.GenerateReference(generator, optimizationInfo); // Load the value to assign. var rhs = this.GetOperand(1); rhs.GenerateCode(generator, optimizationInfo); ILLocalVariable result = null; if (optimizationInfo.IgnoreReturnValue != this) { // Store the RHS value so we can return it as the result of the expression. result = generator.CreateTemporaryVariable(rhs.ResultType); generator.Duplicate(); generator.StoreVariable(result); } // Store the value. target.GenerateSet(generator, optimizationInfo, rhs.ResultType); if (optimizationInfo.IgnoreReturnValue != this) { // Restore the RHS value. generator.LoadVariable(result); generator.ReleaseTemporaryVariable(result); } else { optimizationInfo.ReturnValueWasNotGenerated = true; } }
/// <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. // Store the value. target.GenerateSet(generator, optimizationInfo, optimizationInfo.RootExpression != this, target.GetResultType(optimizationInfo) == typeof(int) ? typeof(int) : typeof(double), delegate(bool two) { // Get the target value. target.GenerateGet(generator, optimizationInfo, true); // Convert it to a number. if (target.GetResultType(optimizationInfo) != typeof(int)) { EmitConversion.ToNumber(generator, target.GetResultType(optimizationInfo)); } // If this is PostIncrement or PostDecrement, duplicate the value so it can be produced as the return value. if (postfix && two) { generator.Duplicate(); } // Load the increment constant. if (target.GetResultType(optimizationInfo) == typeof(int)) { 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, duplicate the value so it can be produced as the return value. if (!postfix && two) { generator.Duplicate(); } }, optimizationInfo.StrictMode); }
/// <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) { // Load the value to assign. var compoundOperator = new BinaryExpression(GetCompoundBaseOperator(this.OperatorType), this.GetOperand(0), this.GetOperand(1)); compoundOperator.GenerateCode(generator, optimizationInfo); // Duplicate the value so it remains on the stack afterwards. //if (optimizationInfo.SuppressReturnValue == false) generator.Duplicate(); // Store the value. target.GenerateSet(generator, optimizationInfo, compoundOperator.ResultType, optimizationInfo.StrictMode); }
/// <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) { // Load the value to assign. var compoundOperator = new BinaryExpression(GetCompoundBaseOperator(this.OperatorType), this.GetOperand(0), this.GetOperand(1)); // Store the value. target.GenerateSet(generator, optimizationInfo, optimizationInfo.RootExpression != this, compoundOperator.GetResultType(optimizationInfo), delegate(bool two) { // Generate the code: compoundOperator.GenerateCode(generator, optimizationInfo); if (two) { // Duplicate the value so it remains on the stack afterwards. generator.Duplicate(); } }, optimizationInfo.StrictMode); }
/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Load the value to assign. var rhs = this.GetOperand(1); rhs.GenerateCode(generator, optimizationInfo); // Support the inferred function displayName property. if (rhs is FunctionExpression) { ((FunctionExpression)rhs).GenerateDisplayName(generator, optimizationInfo, target.ToString(), false); } // Duplicate the value so it remains on the stack afterwards. //if (optimizationInfo.SuppressReturnValue == false) generator.Duplicate(); // Store the value. target.GenerateSet(generator, optimizationInfo, rhs.ResultType, optimizationInfo.StrictMode); }
/// <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); }
/// <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); }
/// <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); }
/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Evaluate the left hand side first! target.GenerateReference(generator, optimizationInfo); // Load the value to assign. var rhs = this.GetOperand(1); rhs.GenerateCode(generator, optimizationInfo); // Support the inferred function displayName property. if (rhs is FunctionExpression) ((FunctionExpression)rhs).GenerateDisplayName(generator, optimizationInfo, target.ToString(), false); // Store the RHS value so we can return it as the result of the expression. var result = generator.CreateTemporaryVariable(rhs.ResultType); generator.Duplicate(); generator.StoreVariable(result); // Store the value. target.GenerateSet(generator, optimizationInfo, rhs.ResultType, optimizationInfo.StrictMode); // Restore the RHS value. generator.LoadVariable(result); generator.ReleaseTemporaryVariable(result); }
/// <summary> /// Generates CIL for an 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 GenerateAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target) { // Load the value to assign. var rhs = this.GetOperand(1); rhs.GenerateCode(generator, optimizationInfo); // Support the inferred function displayName property. if (rhs is FunctionExpression) ((FunctionExpression)rhs).GenerateDisplayName(generator, optimizationInfo, target.ToString(), false); // Duplicate the value so it remains on the stack afterwards. //if (optimizationInfo.SuppressReturnValue == false) generator.Duplicate(); // Store the value. target.GenerateSet(generator, optimizationInfo, rhs.ResultType, optimizationInfo.StrictMode); }