Exemplo n.º 1
0
        // InvocationExpression
        private Result RewriteInvocationExpression(Expression expr, Stack stack)
        {
            InvocationExpression node = (InvocationExpression)expr;

            ChildRewriter cr;

#if LINQ // NB: Our compiler doesn't inline; this could still happen at a later stage in the LINQ compiler after lowering async lambdas to sync ones.
            // See if the lambda will be inlined
            LambdaExpression lambda = node.LambdaOperand();
            if (lambda != null)
            {
                // Arguments execute on current stack
                cr = new ChildRewriter(this, stack, node.Arguments.Count);
                cr.Add(node.Arguments);

                if (cr.Action == RewriteAction.SpillStack)
                {
                    RequireNoRefArgs(ExpressionStubs.GetInvokeMethod(node.Expression));
                }

                // Lambda body also executes on current stack
                var spiller = new StackSpiller(stack);
                lambda = lambda.Accept(spiller);

                if (cr.Rewrite || spiller._lambdaRewrite != RewriteAction.None)
                {
                    node = node.Rewrite(lambda, cr[0, -1]);
                }

                Result result = cr.Finish(node);
                return(new Result(result.Action | spiller._lambdaRewrite, result.Node));
            }
#endif

            cr = new ChildRewriter(this, stack, node.Arguments.Count + 1);

            // first argument starts on stack as provided
            cr.Add(node.Expression);

            // rest of arguments have non-empty stack (delegate instance on the stack)
            cr.Add(node.Arguments);

            if (cr.Action == RewriteAction.SpillStack)
            {
#if LINQ
                RequireNoRefArgs(ExpressionStubs.GetInvokeMethod(node.Expression));
#else
                MarkRefArgs(cr, ExpressionStubs.GetInvokeMethod(node.Expression), 1);
#endif
            }

            return(cr.Finish(cr.Rewrite ? node.Rewrite(cr[0], cr[1, -1]) : expr));
        }