internal override Expression AsExpression(Expression target) { if (target.Type.IsValueType && MemberBinding.Member is global::System.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; }
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 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 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() )); }
// InvocationExpression private Result RewriteInvocationExpression(Expression expr, Stack stack) { var node = (InvocationExpression)expr; ChildRewriter cr; // See if the lambda will be inlined var 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 = new InvocationExpression(lambda, cr[0, -1], node.Type); } var 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 ? new InvocationExpression(cr[0], cr[1, -1], node.Type) : expr)); }
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 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)); } throw Error.UnhandledBinding(); }
internal ChildRewriter(StackSpiller self, Stack stack, int count) { _self = self; _stack = stack; _expressions = new Expression[count]; }
internal override LambdaExpression Accept(Compiler.StackSpiller spiller) { return(spiller.Rewrite(this)); }
internal abstract LambdaExpression Accept(Compiler.StackSpiller spiller);
protected BindingRewriter(MemberBinding memberBinding, StackSpiller stackSpiller) { MemberBinding = memberBinding; StackSpiller = stackSpiller; }