/// <summary> /// Creates a lambda compiler for an inlined lambda /// </summary> private LambdaCompiler(LambdaCompiler parent, LambdaExpression lambda) { _tree = parent._tree; _lambda = lambda; _method = parent._method; _ilg = parent._ilg; _hasClosureArgument = parent._hasClosureArgument; _typeBuilder = parent._typeBuilder; _scope = _tree.Scopes[lambda]; _boundConstants = parent._boundConstants; }
/// <summary> /// Mutates the MethodBuilder parameter, filling in IL, parameters, /// and return type. /// /// (probably shouldn't be modifying parameters/return type...) /// </summary> internal static void Compile(LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { // 1. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); tree.DebugInfoGenerator = debugInfoGenerator; // 2. Create lambda compiler LambdaCompiler c = new LambdaCompiler(tree, lambda, method); // 3. Emit c.EmitLambdaBody(); }
/// <summary> /// Compiler entry point /// </summary> /// <param name="lambda">LambdaExpression to compile.</param> /// <param name="debugInfoGenerator">Debug info generator.</param> /// <returns>The compiled delegate.</returns> internal static Delegate Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator) { // 1. Bind lambda AnalyzedTree tree = AnalyzeLambda(ref lambda); tree.DebugInfoGenerator = debugInfoGenerator; // 2. Create lambda compiler LambdaCompiler c = new LambdaCompiler(tree, lambda); // 3. Emit c.EmitLambdaBody(); // 4. Return the delegate. return(c.CreateDelegate()); }
/// <summary> /// Creates a lambda compiler that will compile into the provided Methodbuilder /// </summary> private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method) { _hasClosureArgument = tree.Scopes[lambda].NeedsClosure; Type[] paramTypes = GetParameterTypes(lambda); if (_hasClosureArgument) { paramTypes = paramTypes.AddFirst(typeof(Closure)); } method.SetReturnType(lambda.ReturnType); method.SetParameters(paramTypes); var paramNames = lambda.Parameters.Map(p => p.Name); // parameters are index from 1, with closure argument we need to skip the first arg int startIndex = _hasClosureArgument ? 2 : 1; for (int i = 0; i < paramNames.Length; i++) { method.DefineParameter(i + startIndex, ParameterAttributes.None, paramNames[i]); } _tree = tree; _lambda = lambda; _typeBuilder = (TypeBuilder)method.DeclaringType; _method = method; #if MICROSOFT_SCRIPTING_CORE || SILVERLIGHT _ilg = new OffsetTrackingILGenerator(method.GetILGenerator()); #else _ilg = method.GetILGenerator(); #endif // These are populated by AnalyzeTree/VariableBinder _scope = tree.Scopes[lambda]; _boundConstants = tree.Constants[lambda]; InitializeMethod(); }