예제 #1
0
            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));
            }
예제 #2
0
            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));
        }
예제 #4
0
 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;
     }
 }
예제 #5
0
            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));
        }
예제 #7
0
            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;
                }
            }
예제 #8
0
            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);
예제 #12
0
 protected BindingRewriter(MemberBinding memberBinding, StackSpiller stackSpiller)
 {
     MemberBinding = memberBinding;
     StackSpiller  = stackSpiller;
 }