private MSAst.LambdaExpression CreateGeneratorFactoryLambda(MSAst.Expression generatorBody)
        {
            MSAst.Expression body = Ast.Block(
                Ast.Call(
                    typeof(RuntimeOps).GetMethod("ReplaceLiftedLocals"),
                    _frame,
                    Ast.RuntimeVariables(_pendingLocals)
                    ),
                generatorBody
                );

            if (_retVal != null)
            {
                body = Ast.Block(
                    Ast.Assign(_retVal, body),
                    AstUtils.YieldReturn(
                        _generatorLabelTarget, Ast.Convert(_retVal, typeof(object))
                        )
                    );
            }

            List <Type> argTypes = new List <Type>();

            for (int i = 0; i < _variableInfos.Count; i++)
            {
                VariableInfo varInfo = _variableInfos[i];
                if (varInfo.IsParameter)
                {
                    argTypes.Add(varInfo.VariableType);
                }
            }

            if (body.Type != typeof(void))
            {
                body = AstUtils.Void(body);
            }

            return(AstUtils.GeneratorLambda(
                       InvokeTargets.GetGeneratorFactoryTarget(argTypes.ToArray()),
                       _generatorLabelTarget,
                       Ast.Block(
                           _generatorVars,
                           body
                           ),
                       _alias,
                       _generatorParams));
        }
示例#2
0
        /// <summary>
        /// Creates the generator LambdaExpression from the builder.
        /// After this operation, the builder can no longer be used to create other instances.
        /// </summary>
        /// <returns>New LambdaExpression instance.</returns>
        public LambdaExpression MakeGenerator(LabelTarget label, Type lambdaType)
        {
            Validate();
            EnsureSignature(lambdaType);

            LambdaExpression lambda = Utils.GeneratorLambda(
                lambdaType,
                label,
                MakeBody(),
                _name + "$" + Interlocked.Increment(ref _lambdaId),
                _params
                );

            // The builder is now completed
            _completed = true;

            return(lambda);
        }