Example #1
0
        private MSAst.LambdaExpression TransformGenerator(MSAst.LambdaExpression lambda)
        {
            GeneratorExpression generator = (GeneratorExpression)lambda.Body;

            MSAst.Expression body = generator.Body;

            _generatorLabelTarget = generator.Target;

            // $TODO: Detect if the label's type is not typeof(object), and create a new label
            Debug.Assert(_generatorLabelTarget.Type == typeof(object));

            _generatorParams.Add(_frame);

            Dictionary <MSAst.ParameterExpression, object> parameters = new Dictionary <MSAst.ParameterExpression, object>();

            foreach (MSAst.ParameterExpression parameter in lambda.Parameters)
            {
                parameters.Add(parameter, null);
            }

            // Add parameters to the pending list
            _pendingLocals.AddRange(lambda.Parameters);

            // Run 1st tree walk to identify all locals
            LambdaWalker lambdaWalker = new LambdaWalker();

            lambdaWalker.Visit(body);

            // Add all locals to pending list
            _pendingLocals.AddRange(lambdaWalker.Locals);

            // Prepare variables
            LayoutVariablesForGenerator(parameters);

            // Rewrite for generator
            MSAst.Expression generatorBody = TransformToGeneratorBody(body);

            // Get the generator factory lambda
            MSAst.LambdaExpression generatorFactoryLambda = CreateGeneratorFactoryLambda(generatorBody);

            // Create FunctionInfo object
            CreateFunctionInfo(generatorFactoryLambda);

            // Create our own outer generator lambda
            return(CreateOuterGeneratorFactory(lambda.Type));
        }
        private MSAst.LambdaExpression TransformLambda(MSAst.LambdaExpression lambda)
        {
            MSAst.Expression body = lambda.Body;

            _lambdaVars.AddRange(new[] { _thread, _framePushed, _funcInfo, _traceLocations, _debugMarker, _frameExitException });

            _generatorParams.Add(_frame);

            Type returnType = lambda.Type.GetMethod("Invoke").ReturnType;

            // Create $retVal variable only if the return type isn't void
            if (returnType == typeof(object))
            {
                _retVal = _retValAsObject;
            }
            else if (returnType != typeof(void))
            {
                _retVal = Ast.Variable(returnType, "$retVal");
            }

            if (_retVal != null)
            {
                _lambdaVars.Add(_retVal);
                _generatorVars.Add(_retVal);
            }

            _lambdaVars.Add(_retValFromGeneratorLoop);

            Dictionary <MSAst.ParameterExpression, object> parameters = new Dictionary <MSAst.ParameterExpression, object>();

            foreach (MSAst.ParameterExpression parameter in lambda.Parameters)
            {
                parameters.Add(parameter, null);
            }

            // Add parameters to the pending list
            _pendingLocals.AddRange(lambda.Parameters);

            // Run 1st tree walk to identify all locals
            LambdaWalker lambdaWalker = new LambdaWalker();

            body = lambdaWalker.Visit(body);

            // Add all locals to pending list
            _pendingLocals.AddRange(lambdaWalker.Locals);

            // Process the variables
            LayOutVariables(lambdaWalker.StrongBoxedLocals, parameters);

            // Rewrite for generator
            MSAst.Expression generatorBody = TransformToGeneratorBody(body);

            // Add source file variables
            _lambdaVars.AddRange(_sourceFilesMap.Values);

            // Create the expression for pushing the frame
            CreatePushFrameExpression();

            // Rewrite for debuggable body
            MSAst.Expression debuggableBody = TransformToDebuggableBody(body);

            // Get the generator factory lambda
            MSAst.LambdaExpression generatorFactoryLambda = CreateGeneratorFactoryLambda(generatorBody);

            // Create FunctionInfo object
            CreateFunctionInfo(generatorFactoryLambda);


            // Create the outer lambda
            return(CreateOuterLambda(lambda.Type, debuggableBody));
        }