EmitLongJump() public method

Emits code to branch between statements, even if code generation is within a finally block (where unconditional branches are not allowed).
public EmitLongJump ( ILGenerator generator, ILLabel targetLabel ) : void
generator ILGenerator The generator to output the CIL to.
targetLabel ILLabel The label to jump to.
return void
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)
        {
            // Generate code for the start of the statement.
            var statementLocals = new StatementLocals();

            GenerateStartOfStatement(generator, optimizationInfo, statementLocals);

            // Emit the return value.
            if (this.Value == null)
            {
                EmitHelpers.EmitUndefined(generator);
            }
            else
            {
                this.Value.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToAny(generator, this.Value.ResultType);
            }

            // Determine if this is the last statement in the function.
            bool lastStatement = optimizationInfo.AbstractSyntaxTree is BlockStatement &&
                                 ((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count > 0 &&
                                 ((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements[((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count - 1] == this;

            // The first return statement initializes the variable that holds the return value.
            if (optimizationInfo.ReturnVariable == null)
            {
                optimizationInfo.ReturnVariable = generator.DeclareVariable(typeof(object), "returnValue");
            }

            // Store the return value in a variable.
            generator.StoreVariable(optimizationInfo.ReturnVariable);

            // There is no need to jump to the end of the function if this is the last statement.
            if (lastStatement == false)
            {
                // 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);
            }

            // Generate code for the end of the statement.
            GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
        }
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)
        {
            // Generate code for the start of the statement.
            var statementLocals = new StatementLocals();
            GenerateStartOfStatement(generator, optimizationInfo, statementLocals);

            // 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));

            // Generate code for the end of the statement.
            GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
        }
Exemplo n.º 3
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)
        {
            // Generate code for the start of the statement.
            var statementLocals = new StatementLocals();

            GenerateStartOfStatement(generator, optimizationInfo, statementLocals);

            // 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));

            // Generate code for the end of the statement.
            GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
        }
        /// <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)
        {
            // Generate code for the start of the statement.
            var statementLocals = new StatementLocals();
            GenerateStartOfStatement(generator, optimizationInfo, statementLocals);

            // Emit the return value.
            if (this.Value == null)
                EmitHelpers.EmitUndefined(generator);
            else
            {
                this.Value.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToAny(generator, this.Value.ResultType);
            }

            // Determine if this is the last statement in the function.
            bool lastStatement = optimizationInfo.AbstractSyntaxTree is BlockStatement &&
                ((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count > 0 &&
                ((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements[((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count - 1] == this;

            // The first return statement initializes the variable that holds the return value.
            if (optimizationInfo.ReturnVariable == null)
                optimizationInfo.ReturnVariable = generator.DeclareVariable(typeof(object), "returnValue");

            // Store the return value in a variable.
            generator.StoreVariable(optimizationInfo.ReturnVariable);

            // There is no need to jump to the end of the function if this is the last statement.
            if (lastStatement == false)
            {
                
                // 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);

            }

            // Generate code for the end of the statement.
            GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
        }