Exemplo n.º 1
0
 /// <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));
 }
Exemplo n.º 2
0
        /// <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);
            }
        }