// 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)); }
// InvocationExpression private Result RewriteInvocationExpression(Expression expr, Stack stack) { InvocationExpression node = (InvocationExpression)expr; ChildRewriter cr; // 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(Expression.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)); } 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) { RequireNoRefArgs(Expression.GetInvokeMethod(node.Expression)); } return(cr.Finish(cr.Rewrite ? node.Rewrite(cr[0], cr[1, -1]) : expr)); }
/// <summary> /// Visits the children of the <see cref="InvocationExpression" />. /// </summary> /// <param name="node">The expression to visit.</param> /// <returns>The modified expression, if it or any subexpression was modified; /// otherwise, returns the original expression.</returns> protected internal virtual Expression VisitInvocation(InvocationExpression node) { Expression e = Visit(node.Expression); Expression[] a = VisitArguments(node); if (e == node.Expression && a == null) { return(node); } return(node.Rewrite(e, a)); }