/// <summary> /// Generates CIL for the statement. /// </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) { // Emit an unconditional branch. // Note: the continue statement might be branching from inside a try { } or finally { } // block to outside. EmitLongJump() handles this. optimizationInfo.EmitLongJump(generator, optimizationInfo.GetContinueTarget(this.Label)); }
/// <summary> /// Generates CIL for the statement. /// </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) { if (optimizationInfo.IsConstructor) { return; } // Emit the return value. Type returnType = ReturnType; // Determine if this is the last statement in the function. BlockStatement hostBlock = optimizationInfo.AbstractSyntaxTree as BlockStatement; bool lastStatement; if (hostBlock != null && hostBlock.Statements.Count > 0 && hostBlock.Statements[hostBlock.Statements.Count - 1] == this) { lastStatement = true; } else { lastStatement = false; } // Current return var: var returnVar = optimizationInfo.ReturnVariable; if (Value != null) { // Emit the returned value: Value.GenerateCode(generator, optimizationInfo); // The first return statement initializes the variable that holds the return value. if (returnVar == null) { if (!lastStatement) { returnVar = generator.DeclareVariable(returnType, "returnValue"); optimizationInfo.ReturnVariable = returnVar; } } } else if (returnVar != null) { // We need to return undefined here, which will require changing the return type to object. // No value being set: EmitHelpers.EmitUndefined(generator); } if (returnVar != null) { // the return type here must be a child type of the return type. // If it isn't then this function returns different things. // Store the return value in a variable. generator.StoreVariable(returnVar); } // There is no need to jump to the end of the function if this is the last statement. if (!lastStatement) { // The first return statement that needs to branch creates the return label. This is // defined in FunctionmethodGenerator.GenerateCode at the end of the function. if (optimizationInfo.ReturnTarget == null) { optimizationInfo.ReturnTarget = generator.CreateLabel(); } // Branch to the end of the function. Note: the return statement might be branching // from inside a try { } or finally { } block to outside. EmitLongJump() handles this. optimizationInfo.EmitLongJump(generator, optimizationInfo.ReturnTarget); } }