internal override Expression AsExpression(Expression target) { if (target.Type.IsValueType && MemberBinding.Member is Reflection.PropertyInfo) { throw Error.CannotAutoInitializeValueTypeMemberThroughProperty(MemberBinding.Member); } RequireNotRefInstance(target); var member = Expression.MakeMemberAccess(target, MemberBinding.Member); var memberTemp = StackSpiller.MakeTemp(member.Type); var block = new Expression[_bindings.Count + 2]; block[0] = Expression.Assign(memberTemp, member); for (var i = 0; i < _bindings.Count; i++) { var br = _bindingRewriters[i]; block[i + 1] = br.AsExpression(memberTemp); } // We need to copy back value types if (memberTemp.Type.IsValueType) { block[_bindings.Count + 1] = Expression.Block( typeof(void), Expression.Assign(Expression.MakeMemberAccess(target, MemberBinding.Member), memberTemp) ); } else { block[_bindings.Count + 1] = Expression.Empty(); } return(MakeBlock(block)); }
internal MemberAssignmentRewriter(MemberAssignment memberBinding, StackSpiller stackSpiller, Stack stack) : base(memberBinding, stackSpiller) { var result = stackSpiller.RewriteExpression(memberBinding.Expression, stack); RewriteAction = result.Action; _rhs = result.Node; }
internal MemberAssignmentRewriter(MemberAssignment binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { Result result = spiller.RewriteExpression(binding.Expression, stack); _action = result.Action; _rhs = result.Node; }
private static AnalyzedTree AnalyzeLambda(ref LambdaExpression lambda) { // Spill the stack for any exception handling blocks or other // constructs which require entering with an empty stack lambda = StackSpiller.AnalyzeLambda(lambda); // Bind any variable references in this lambda return(VariableBinder.Bind(lambda)); }
internal MemberMemberBindingRewriter(MemberMemberBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _bindings = binding.Bindings; _bindingRewriters = new BindingRewriter[_bindings.Count]; for (int i = 0; i < _bindings.Count; i++) { BindingRewriter br = BindingRewriter.Create(_bindings[i], spiller, stack); _action |= br.Action; _bindingRewriters[i] = br; } }
internal MemberMemberBindingRewriter(MemberMemberBinding memberBinding, StackSpiller stackSpiller, Stack stack) : base(memberBinding, stackSpiller) { _bindings = memberBinding.Bindings; _bindingRewriters = new BindingRewriter[_bindings.Count]; for (var i = 0; i < _bindings.Count; i++) { var br = Create(_bindings[i], stackSpiller, stack); RewriteAction |= br.Action; _bindingRewriters[i] = br; } }
internal MemberMemberBindingRewriter(MemberMemberBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _bindings = binding.Bindings; _bindingRewriters = new BindingRewriter[_bindings.Count]; for (int i = 0; i < _bindings.Count; i++) { BindingRewriter br = BindingRewriter.Create(_bindings[i], spiller, stack); _action |= br.Action; _bindingRewriters[i] = br; } }
// 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)); }
internal override Expression AsExpression(Expression target) { RequireNotRefInstance(target); var member = Expression.MakeMemberAccess(target, MemberBinding.Member); var memberTemp = StackSpiller.MakeTemp(member.Type); return(MakeBlock( Expression.Assign(memberTemp, _rhs), Expression.Assign(member, memberTemp), Expression.Empty() )); }
internal static BindingRewriter Create(MemberBinding binding, StackSpiller spiller, Stack stack) { switch (binding.BindingType) { case MemberBindingType.Assignment: MemberAssignment assign = (MemberAssignment)binding; return new MemberAssignmentRewriter(assign, spiller, stack); case MemberBindingType.ListBinding: MemberListBinding list = (MemberListBinding)binding; return new ListBindingRewriter(list, spiller, stack); case MemberBindingType.MemberBinding: MemberMemberBinding member = (MemberMemberBinding)binding; return new MemberMemberBindingRewriter(member, spiller, stack); } throw Error.UnhandledBinding(); }
private Result RewriteInvocationExpression(Expression expr, Stack stack) { var 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.ArgumentCount); cr.AddArguments(node); if (cr.Action == RewriteAction.SpillStack) { cr.MarkRefArgs(Expression.GetInvokeMethod(node.Expression), startIndex: 0); } // Lambda body also executes on current stack. var spiller = new StackSpiller(stack); lambda = lambda.Accept(spiller); if (cr.Rewrite || spiller._lambdaRewrite != RewriteAction.None) { node = new InvocationExpressionN(lambda, cr[0, -1], node.Type); } Result result = cr.Finish(node); return(new Result(result.Action | spiller._lambdaRewrite, result.Node)); } cr = new ChildRewriter(this, stack, node.ArgumentCount + 1); // First argument starts on stack as provided. cr.Add(node.Expression); // Rest of arguments have non-empty stack (the delegate instance is on the stack). cr.AddArguments(node); if (cr.Action == RewriteAction.SpillStack) { cr.MarkRefArgs(Expression.GetInvokeMethod(node.Expression), startIndex: 1); } return(cr.Finish(cr.Rewrite ? new InvocationExpressionN(cr[0], cr[1, -1], node.Type) : 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)); }
internal MemberMemberBindingRewriter(MemberMemberBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _bindings = binding.Bindings; var count = _bindings.Count; _bindingRewriters = new BindingRewriter[count]; for (var i = 0; i < count; i++) { var br = Create(_bindings[i], spiller, stack); Action |= br.Action; _bindingRewriters[i] = br; } }
internal ListBindingRewriter(MemberListBinding memberBinding, StackSpiller stackSpiller, Stack stack) : base(memberBinding, stackSpiller) { _inits = memberBinding.Initializers; _childRewriters = new ChildRewriter[_inits.Count]; for (var i = 0; i < _inits.Count; i++) { var init = _inits[i]; var cr = new ChildRewriter(stackSpiller, stack, init.Arguments.Count); cr.Add(init.Arguments); RewriteAction |= cr.Action; _childRewriters[i] = cr; } }
internal ListBindingRewriter(MemberListBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _inits = binding.Initializers; _childRewriters = new ChildRewriter[_inits.Count]; for (int i = 0; i < _inits.Count; i++) { ElementInit init = _inits[i]; ChildRewriter cr = new ChildRewriter(spiller, stack, init.Arguments.Count); cr.Add(init.Arguments); _action |= cr.Action; _childRewriters[i] = cr; } }
internal static BindingRewriter Create(MemberBinding binding, StackSpiller spiller, Stack stack) { switch (binding.BindingType) { case MemberBindingType.Assignment: MemberAssignment assign = (MemberAssignment)binding; return(new MemberAssignmentRewriter(assign, spiller, stack)); case MemberBindingType.ListBinding: MemberListBinding list = (MemberListBinding)binding; return(new ListBindingRewriter(list, spiller, stack)); case MemberBindingType.MemberBinding: MemberMemberBinding member = (MemberMemberBinding)binding; return(new MemberMemberBindingRewriter(member, spiller, stack)); } throw Error.UnhandledBinding(); }
internal ListBindingRewriter(MemberListBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _initializers = binding.Initializers; var count = _initializers.Count; _childRewriters = new ChildRewriter[count]; for (var i = 0; i < count; i++) { var init = _initializers[i]; var cr = new ChildRewriter(spiller, stack, init.Arguments.Count); cr.Add(init.Arguments); Action |= cr.Action; _childRewriters[i] = cr; } }
internal static BindingRewriter Create(MemberBinding binding, StackSpiller spiller, Stack stack) { switch (binding.BindingType) { case MemberBindingType.Assignment: var assign = (MemberAssignment)binding; return(new MemberAssignmentRewriter(assign, spiller, stack)); case MemberBindingType.ListBinding: var list = (MemberListBinding)binding; return(new ListBindingRewriter(list, spiller, stack)); case MemberBindingType.MemberBinding: var member = (MemberMemberBinding)binding; return(new MemberMemberBindingRewriter(member, spiller, stack)); default: break; } throw new ArgumentException("Unhandled binding "); }
internal override Expression AsExpression(Expression target) { if (target.Type.IsValueType && MemberBinding.Member is Reflection.PropertyInfo) { throw Error.CannotAutoInitializeValueTypeElementThroughProperty(MemberBinding.Member); } RequireNotRefInstance(target); var member = Expression.MakeMemberAccess(target, MemberBinding.Member); var memberTemp = StackSpiller.MakeTemp(member.Type); var block = new Expression[_inits.Count + 2]; block[0] = Expression.Assign(memberTemp, member); for (var i = 0; i < _inits.Count; i++) { var cr = _childRewriters[i]; var add = cr.Finish(Expression.Call(memberTemp, _inits[i].AddMethod, cr[0, -1])); block[i + 1] = add.Node; } // We need to copy back value types if (memberTemp.Type.IsValueType) { block[_inits.Count + 1] = Expression.Block( typeof(void), Expression.Assign(Expression.MakeMemberAccess(target, MemberBinding.Member), memberTemp) ); } else { block[_inits.Count + 1] = Expression.Empty(); } return(MakeBlock(block)); }
internal BindingRewriter(MemberBinding binding, StackSpiller spiller) { _binding = binding; _spiller = spiller; }
/// <summary> /// Creates a new child rewriter instance using the specified initial /// evaluation <see cref="stack"/> state and the number of child /// expressions specified in <see cref="count"/>. /// </summary> /// <param name="self">The parent stack spiller.</param> /// <param name="stack">The initial evaluation stack state.</param> /// <param name="count">The number of child expressions that will be added.</param> internal ChildRewriter(StackSpiller self, Stack stack, int count) { _self = self; _stack = stack; _expressions = new Expression[count]; }
internal ChildRewriter(StackSpiller self, Stack stack, int count) { _self = self; _stack = stack; _expressions = new Expression[count]; }
internal BindingRewriter(MemberBinding binding, StackSpiller spiller) { _binding = binding; _spiller = spiller; }
internal ListBindingRewriter(MemberListBinding binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { _inits = binding.Initializers; _childRewriters = new ChildRewriter[_inits.Count]; for (int i = 0; i < _inits.Count; i++) { ElementInit init = _inits[i]; ChildRewriter cr = new ChildRewriter(spiller, stack, init.Arguments.Count); cr.Add(init.Arguments); _action |= cr.Action; _childRewriters[i] = cr; } }
internal abstract LambdaExpression Accept(StackSpiller spiller);
internal abstract LambdaExpression Accept(Compiler.StackSpiller spiller);
internal MemberAssignmentRewriter(MemberAssignment binding, StackSpiller spiller, Stack stack) : base(binding, spiller) { Result result = spiller.RewriteExpression(binding.Expression, stack); _action = result.Action; _rhs = result.Node; }
protected BindingRewriter(MemberBinding memberBinding, StackSpiller stackSpiller) { MemberBinding = memberBinding; StackSpiller = stackSpiller; }
internal override LambdaExpression Accept(Compiler.StackSpiller spiller) { return(spiller.Rewrite(this)); }
protected BindingRewriter(MemberBinding binding, StackSpiller spiller) { Binding = binding; Spiller = spiller; }