Beispiel #1
0
        /// <summary>
        /// Creates a lambda compiler that will compile into the provided Methodbuilder
        /// </summary>
        private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, IMethodBuilderForLambdaCompiler 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.AsMethodBase();

            _ilg = method.GetILGenerator();

            // These are populated by AnalyzeTree/VariableBinder
            _scope          = tree.Scopes[lambda];
            _boundConstants = tree.Constants[lambda];

            InitializeMethod();
        }
Beispiel #2
0
        /// <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, IMethodBuilderForLambdaCompiler 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();
        }