示例#1
0
        private void EmitInlinedInvoke(InvocationExpression invoke, CompilationFlags flags)
        {
            var lambda = invoke.LambdaOperand;

            // This is tricky: we need to emit the arguments outside of the
            // scope, but set them inside the scope. Fortunately, using the IL
            // stack it is entirely doable.

            // 1. Emit invoke arguments
            var wb = EmitArguments(lambda.Type.GetMethod("Invoke"), invoke);

            // 2. Create the nested LambdaCompiler
            var inner = new LambdaCompiler(this, lambda);

            // 3. Emit the body
            // if the inlined lambda is the last expression of the whole lambda,
            // tail call can be applied.
            if (wb.Count != 0)
            {
                flags = UpdateEmitAsTailCallFlag(flags, CompilationFlags.EmitAsNoTail);
            }
            inner.EmitLambdaBody(_scope, true, flags);

            // 4. Emit writebacks if needed
            EmitWriteBack(wb);
        }
        /// <summary>
        /// Compiler entry point
        /// </summary>
        /// <param name="lambda">LambdaExpression to compile.</param>
        /// <returns>The compiled delegate.</returns>
        internal static Delegate Compile(LambdaExpression lambda)
        {
            // 1. Bind lambda
            var tree = AnalyzeLambda(ref lambda);

            // 2. Create lambda compiler
            var c = new LambdaCompiler(tree, lambda);

            // 3. Emit
            c.EmitLambdaBody();

            // 4. Return the delegate.
            return(c.CreateDelegate());
        }