IronRuby.Compiler.Ast.ReturnStatement.Propagate C# (CSharp) Method

Propagate() static private method

static private Propagate ( AstGenerator gen, System.Linq.Expressions resultVariable ) : Expression
gen AstGenerator
resultVariable System.Linq.Expressions
return System.Linq.Expressions.Expression
        internal static MSA.Expression/*!*/ Propagate(AstGenerator/*!*/ gen, MSA.Expression/*!*/ resultVariable) {
            // eval:
            if (gen.CompilerOptions.IsEval) {
                return Methods.EvalPropagateReturn.OpCall(resultVariable);
            }

            // block:
            if (gen.CurrentBlock != null) {
                return Methods.BlockPropagateReturn.OpCall(
                    gen.CurrentBlock.BfcVariable,
                    resultVariable
                );
            }

            // method:
            return Methods.MethodPropagateReturn.OpCall(
                gen.CurrentScopeVariable,
                gen.MakeMethodBlockParameterRead(),
                Ast.Convert(resultVariable, typeof(BlockReturnResult))
            );
        }
    }

Usage Example

        internal static MSA.Expression /*!*/ MakeCallWithBlockRetryable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ invoke,
                                                                        MSA.Expression blockArgVariable, MSA.Expression transformedBlock, bool isBlockDefinition)
        {
            Assert.NotNull(invoke);
            Debug.Assert((blockArgVariable == null) == (transformedBlock == null));

            // see Ruby Language.doc/Control Flow Implementation/Method Call With a Block
            MSA.Expression          resultVariable = gen.CurrentScope.DefineHiddenVariable("#method-result", typeof(object));
            MSA.ParameterExpression evalUnwinder;

            MSA.LabelTarget retryLabel = Ast.Label("retry");

            var result = new AstBlock {
                Ast.Assign(blockArgVariable, Ast.Convert(transformedBlock, blockArgVariable.Type)),

                Ast.Label(retryLabel),

                (isBlockDefinition) ? Methods.InitializeBlock.OpCall(blockArgVariable) : null,

                AstUtils.Try(
                    Ast.Assign(resultVariable, invoke)
                    ).Catch(evalUnwinder = Ast.Parameter(typeof(EvalUnwinder), "#u"),
                            Ast.Assign(
                                resultVariable,
                                Ast.Field(evalUnwinder, EvalUnwinder.ReturnValueField)
                                )
                            ),

                Ast.IfThen(Ast.TypeEqual(resultVariable, typeof(BlockReturnResult)),
                           Ast.IfThenElse(Methods.IsRetrySingleton.OpCall(resultVariable),
                                          // retry:
                                          AstUtils.IfThenElse(Ast.Equal(gen.MakeMethodBlockParameterRead(), blockArgVariable),
                                                              RetryStatement.TransformRetry(gen),
                                                              Ast.Goto(retryLabel)
                                                              ),
                                          // return:
                                          gen.Return(ReturnStatement.Propagate(gen, resultVariable))
                                          )
                           ),

                resultVariable
            };

            return(result);
        }