/// <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) { // The left hand side needs to be a variable reference or member access. var target = this.GetOperand(0) as IReferenceExpression; if (target == null) { // Emit an error message. switch (this.OperatorType) { case OperatorType.PostIncrement: case OperatorType.PostDecrement: EmitHelpers.EmitThrow(generator, "ReferenceError", "Invalid left-hand side in postfix operation", optimizationInfo); break; case OperatorType.PreIncrement: case OperatorType.PreDecrement: EmitHelpers.EmitThrow(generator, "ReferenceError", "Invalid left-hand side in prefix operation", optimizationInfo); break; default: EmitHelpers.EmitThrow(generator, "ReferenceError", "Invalid left-hand side in assignment", optimizationInfo); break; } //if (optimizationInfo.SuppressReturnValue == false) EmitHelpers.EmitDefaultValue(generator, this.ResultType); return; } // The left hand side cannot be "arguments" or "eval" in strict mode. if (optimizationInfo.StrictMode && target is NameExpression) { if (((NameExpression)target).Name == "eval") { throw new JavaScriptException(optimizationInfo.Engine, "SyntaxError", "The variable 'eval' cannot be modified in strict mode.", optimizationInfo.SourceSpan.StartLine, optimizationInfo.Source.Path, optimizationInfo.FunctionName); } if (((NameExpression)target).Name == "arguments") { throw new JavaScriptException(optimizationInfo.Engine, "SyntaxError", "The variable 'arguments' cannot be modified in strict mode.", optimizationInfo.SourceSpan.StartLine, optimizationInfo.Source.Path, optimizationInfo.FunctionName); } } switch (this.OperatorType) { case OperatorType.Assignment: // Standard assignment operator. GenerateAssignment(generator, optimizationInfo, target); break; case OperatorType.PostIncrement: GenerateIncrementOrDecrement(generator, optimizationInfo, target, true, true); break; case OperatorType.PostDecrement: GenerateIncrementOrDecrement(generator, optimizationInfo, target, true, false); break; case OperatorType.PreIncrement: GenerateIncrementOrDecrement(generator, optimizationInfo, target, false, true); break; case OperatorType.PreDecrement: GenerateIncrementOrDecrement(generator, optimizationInfo, target, false, false); break; case OperatorType.CompoundAdd: // Special case += GenerateCompoundAddAssignment(generator, optimizationInfo, target); break; default: // All other compound operators. GenerateCompoundAssignment(generator, optimizationInfo, target); break; } }