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