private Result RewriteIndexAssignment(BinaryExpression node, Stack stack) { var index = (IndexExpression)node.Left; var cr = new NullAwareChildRewriter(this, stack, 2 + index.ArgumentCount); cr.Add(index.Object); cr.AddArguments(index); cr.Add(node.Right); if (cr.Action == RewriteAction.SpillStack) { cr.MarkRefInstance(index.Object); } if (cr.Rewrite) { node = new AssignBinaryExpression ( new IndexExpression ( cr[0], // Object index.Indexer, cr[1, -2] ! // arguments ), cr[-1] ! // value ); } return(cr.Finish(node)); }
private Result RewriteMemberAssignment(BinaryExpression node, Stack stack) { var lvalue = (MemberExpression)node.Left; var cr = new NullAwareChildRewriter(this, stack, 2); // If there's an instance, it executes on the stack in current state // and rest is executed on non-empty stack. // Otherwise the stack is left unchanged. cr.Add(lvalue.Expression); cr.Add(node.Right); if (cr.Action == RewriteAction.SpillStack) { cr.MarkRefInstance(lvalue.Expression); } if (cr.Rewrite) { return(cr.Finish ( new AssignBinaryExpression ( MemberExpression.Make(cr[0] !, lvalue.Member), cr[1] ! ) )); } return(new Result(RewriteAction.None, node)); }
private Result RewriteBinaryExpression(Expression expr, Stack stack) { var node = (BinaryExpression)expr; var cr = new NullAwareChildRewriter(this, stack, 3); // Left expression executes on the stack as left by parent cr.Add(node.Left); // Right expression always has non-empty stack (left is on it) cr.Add(node.Right); // conversion is a lambda, stack state will be ignored cr.Add(node.Conversion !); if (cr.Action == RewriteAction.SpillStack) { RequireNoRefArgs(node.Method); } return(cr.Finish ( cr.Rewrite ? BinaryExpression.Create ( node.NodeType, cr[0] !, cr[1] !, node.Type, node.Method, (LambdaExpression)cr[2] ! ) : expr )); }
private Result RewriteMethodCallExpression(Expression expr, Stack stack) { var node = (MethodCallExpression)expr; var cr = new NullAwareChildRewriter(this, stack, node.ArgumentCount + 1); // For instance methods, the instance executes on the // stack as is, but stays on the stack, making it non-empty. cr.Add(node.Object); cr.AddArguments(node); if (cr.Action == RewriteAction.SpillStack) { cr.MarkRefInstance(node.Object); cr.MarkRefArgs(node.Method, 1); } if (cr.Rewrite) { expr = node.Object != null ? (Expression) new InstanceMethodCallExpressionN(node.Method, cr[0], cr[1, -1] !) : new MethodCallExpressionN(node.Method, cr[1, -1] !); } return(cr.Finish(expr)); }