Ejemplo n.º 1
0
        public void UpdateDoesntRepeatEnumeration(int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(0);
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray();

            BlockExpression block = Expression.Block(expressions);

            Assert.Same(block, block.Update(null, new RunOnceEnumerable <Expression>(expressions)));
            Assert.NotSame(
                block,
                block.Update(null, new RunOnceEnumerable <Expression>(PadBlock(blockSize - 1, Expression.Constant(1)))));
        }
Ejemplo n.º 2
0
        public void UpdateDoesntRepeatEnumeration(int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(0);
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray();

            ParameterExpression[] vars = { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) };

            BlockExpression block = Expression.Block(vars, expressions);

            Assert.Same(block, block.Update(new RunOnceEnumerable <ParameterExpression>(vars), block.Expressions));
            vars = new[] { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) };
            Assert.NotSame(block, block.Update(new RunOnceEnumerable <ParameterExpression>(vars), block.Expressions));
        }
Ejemplo n.º 3
0
            private BlockExpression AddIncludes(BlockExpression shaperBlock)
            {
                if (_pendingIncludes.Count == 0)
                {
                    return(shaperBlock);
                }

                var shaperExpressions = new List <Expression>(shaperBlock.Expressions);
                var instanceVariable  = shaperExpressions[shaperExpressions.Count - 1];

                shaperExpressions.RemoveAt(shaperExpressions.Count - 1);

                var includesToProcess = _pendingIncludes;

                _pendingIncludes = new List <IncludeExpression>();

                foreach (var include in includesToProcess)
                {
                    AddInclude(shaperExpressions, include, shaperBlock, instanceVariable);
                }

                shaperExpressions.Add(instanceVariable);
                shaperBlock = shaperBlock.Update(shaperBlock.Variables, shaperExpressions);
                return(shaperBlock);
            }
Ejemplo n.º 4
0
        protected override Expression VisitBlock(BlockExpression node)
        {
            var variables   = VisitAndConvert(node.Variables, nameof(VisitBlock));
            var expressions = Visit(node.Expressions);

            return(node.Update(variables, expressions));
        }
Ejemplo n.º 5
0
            /// <summary>
            /// Visit block expressions for scope tracking and closure emitting purposes.
            /// </summary>
            /// <param name="node">The block expression to rewrite.</param>
            /// <returns>The rewritten expression.</returns>
            protected override Expression VisitBlock(BlockExpression node)
            {
                //
                // Introduce a new scope and keep track of the original scope in order to restore
                // it after visiting child expressions.
                //
                var currentScope = _scope;

                try
                {
                    var scope = _analysis[node];
                    _scope = new CompilerScope(currentScope, scope);

                    if (!scope.HasHoistedLocals)
                    {
                        //
                        // In case there are no hoisted locals, we don't need to use a builder to
                        // instantiate a closure. Simply visit the child expressions and update.
                        //
                        var expressions = Visit(node.Expressions);

                        return(node.Update(node.Variables, expressions));
                    }
                    else
                    {
                        //
                        // In case there are hoisted locals, enter the scope to obtain a builder,
                        // append the visited child expressions, and return a new block. This will
                        // add the statements needed to instantiate the closure and link it to its
                        // parent (if any).
                        //
                        var expressions = node.Expressions;
                        var n           = expressions.Count;

                        //
                        // Note we don't copy hoisted locals during Enter because the storage
                        // location of these is superseded by the storage field in the closure.
                        //
                        var builder = _scope.Enter(count: n, copyLocals: false);

                        for (var i = 0; i < n; i++)
                        {
                            builder.Append(Visit(expressions[i]));
                        }

                        //
                        // Note that we don't update the original block here;  the builder will
                        // create a new block anyway, and we can simply use that as our substitute,
                        // provided the original (non-hoisted) locals are declared.
                        //
                        return(builder.Finish(declareLocals: true));
                    }
                }
                finally
                {
                    _scope = currentScope;
                }
            }
Ejemplo n.º 6
0
        public void UpdateWithExpressionsReturnsSame(object value, int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(value, value.GetType());
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant);

            BlockExpression block = Expression.Block(SingleParameter, expressions);

            Assert.Same(block, block.Update(block.Variables, block.Expressions));
        }
        public void UpdateToNullArguments(int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(0);
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant);

            BlockExpression block = Expression.Block(expressions);

            AssertExtensions.Throws <ArgumentNullException>("expressions", () => block.Update(null, null));
        }
        public void UpdateDifferentSizeReturnsDifferent(int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(0);
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray();

            BlockExpression block = Expression.Block(expressions);

            Assert.NotSame(block, block.Update(null, block.Expressions.Prepend(Expression.Empty())));
        }
Ejemplo n.º 9
0
        private static BlockExpression Update(BlockExpression node)
        {
            // Tests the call of Update to Expression.Block factories.

            BlockExpression res = node.Update(node.Variables, node.Expressions.ToArray());

            Assert.Same(node, res);

            return(res);
        }
Ejemplo n.º 10
0
        BlockExpression VisitBlockExpression(BlockExpression node)
        {
            return(VisitBlock(() => {
                VisitBlockVariables(node);

                var expressions = VisitBlockExpressions(node);

                return node.Update(node.Variables, expressions);
            }));
        }
Ejemplo n.º 11
0
        public void UpdateDifferentSizeReturnsDifferent(int blockSize)
        {
            ConstantExpression       constant    = Expression.Constant(0);
            IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray();

            ParameterExpression[] vars = { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) };

            BlockExpression block = Expression.Block(vars, expressions);

            Assert.NotSame(block, block.Update(vars, block.Expressions.Prepend(Expression.Empty())));
        }
Ejemplo n.º 12
0
            protected override Expression VisitBlock(BlockExpression node)
            {
                var variables = node.Variables;

                if (variables.Count > 0)
                {
                    var newVariables = Push(variables);

                    var expressions = Visit(node.Expressions);

                    Pop();

                    return(node.Update(newVariables, expressions));
                }
                else
                {
                    var expressions = Visit(node.Expressions);

                    return(node.Update(variables, expressions));
                }
            }
        protected override Expression VisitBlock(BlockExpression node)
        {
            if (CanOptimize(node))
            {
                return(FlattenBlocks(node));
            }

            var variables   = VisitAndConvert(node.Variables, nameof(VisitBlock));
            var expressions = VisitSequence(node.Expressions);

            return(node.Update(variables, expressions));
        }
        /// <summary>
        /// Visits a block expression. During the call, the block's variables are mapped in the tracked scope symbol table.
        /// </summary>
        /// <param name="node">Block expression to visit.</param>
        /// <returns>Result of visiting the block expression.</returns>
        protected virtual Expression VisitBlockCore(BlockExpression node)
        {
            if (node == null)
            {
                return(null);
            }

            var variables   = VisitAndConvert(node.Variables, nameof(VisitBlockCore));
            var expressions = Visit(node.Expressions);

            return(node.Update(variables, expressions));
        }
 /// <inheritdoc />
 protected override Expression VisitBlock(BlockExpression node)
 {
     if (TryFindAddToCollectionExpression(node.Expressions, out MethodCallExpression methodCallExpression))
     {
         Expression callReplaceDenormalizedInstances = Expression.Call(
             null,
             RemoveDenormalizedInstancesMethodInfo,
             methodCallExpression.Arguments);
         IList <Expression> newBlockExpressions = new List <Expression>(node.Expressions);
         newBlockExpressions.Add(callReplaceDenormalizedInstances);
         node = node.Update(node.Variables, newBlockExpressions);
     }
     return(base.VisitBlock(node));
 }
Ejemplo n.º 16
0
 // async method cannot have block expression with type not equal to void
 protected override Expression VisitBlock(BlockExpression node)
 {
     if (node.Type == typeof(void))
     {
         Statement.Rewrite(ref node);
         node.Variables.ForEach(variable => Variables.Add(variable, null));
         node = node.Update(Empty <ParameterExpression>(), node.Expressions);
         return(context.Rewrite(node, base.VisitBlock));
     }
     else
     {
         return(VisitBlock(Expression.Block(typeof(void), node.Variables, node.Expressions)));
     }
 }
        public void UpdateAnyExpressionDifferentReturnsDifferent(int blockSize)
        {
            ConstantExpression constant = Expression.Constant(0);

            Expression[] expressions = PadBlock(blockSize - 1, constant).ToArray();

            BlockExpression block = Expression.Block(expressions);

            for (int i = 0; i != expressions.Length; ++i)
            {
                Expression[] newExps = new Expression[expressions.Length];
                expressions.CopyTo(newExps, 0);
                newExps[i] = Expression.Constant(1);
                Assert.NotSame(block, block.Update(null, newExps));
            }
        }
Ejemplo n.º 18
0
        protected override Expression VisitBlock(BlockExpression node)
        {
            var peek      = localParameters.Peek();
            var variables = node.Variables.Where(variable => !parsedLambda.ParsedParameters.ContainsKey(variable) && !peek.Contains(variable)).ToArray();

            foreach (var variable in variables)
            {
                peek.Add(variable);
            }
            var expressions = node.Expressions.Select(Visit);

            foreach (var variable in variables)
            {
                peek.Remove(variable);
            }
            return(node.Update(variables, expressions));
        }
            protected override Expression VisitBlock(BlockExpression node)
            {
                var replacements = default(Dictionary <ParameterExpression, ReplacementInfo>);

                foreach (var variable in node.Variables)
                {
                    var type = variable.Type;

                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(RefHolder <>))
                    {
                        replacements ??= new Dictionary <ParameterExpression, ReplacementInfo>();
                        replacements.Add(variable, new ReplacementInfo());
                    }
                }

                if (replacements != null)
                {
                    _refLocalHolders.Push(replacements);

                    var expressions = Visit(node.Expressions);

                    var updatedReplacements = _refLocalHolders.Pop();

                    Debug.Assert(updatedReplacements == replacements);

                    var variables = new List <ParameterExpression>();

                    foreach (var variable in node.Variables)
                    {
                        if (updatedReplacements.TryGetValue(variable, out var replacement))
                        {
                            variables.AddRange(replacement.Temps);
                        }
                        else
                        {
                            variables.Add(variable);
                        }
                    }

                    return(node.Update(variables, expressions));
                }

                return(base.VisitBlock(node));
            }
        public T?Simplify <T>(T?expression) where T : Expression
        {
            if (expression is null)
            {
                return(null);
            }
            Expression expr = expression.Reduce() switch
            {
                UnaryExpression unaryExpr => unaryExpr.Update(Simplify(unaryExpr.Operand)),
                BinaryExpression binaryExpr => binaryExpr.Update(Simplify(binaryExpr.Left), binaryExpr.Conversion, Simplify(binaryExpr.Right)),
                LambdaExpression lambdaExpr => Expression.Lambda(Simplify(lambdaExpr.Body), lambdaExpr.Name, lambdaExpr.TailCall, Simplify(lambdaExpr.Parameters)),
                TryExpression tryExpr => tryExpr.Update(Simplify(tryExpr.Body), Simplify(tryExpr.Handlers), Simplify(tryExpr.Finally), Simplify(tryExpr.Fault)),
                NewExpression newExpr => newExpr.Update(Simplify(newExpr.Arguments)),
                GotoExpression gotoExpr => gotoExpr.Update(gotoExpr.Target, Simplify(gotoExpr.Value)),
                LoopExpression loopExpr => loopExpr.Update(loopExpr.BreakLabel, loopExpr.ContinueLabel, Simplify(loopExpr.Body)),
                BlockExpression blockExpr => blockExpr.Update(Simplify(blockExpr.Variables), Simplify(blockExpr.Expressions)),
                IndexExpression indexExpr => indexExpr.Update(Simplify(indexExpr.Object) !, Simplify(indexExpr.Arguments)),
                LabelExpression labelExpr => labelExpr.Update(labelExpr.Target, Simplify(labelExpr.DefaultValue)),
                MemberExpression memberExpr => memberExpr.Update(Simplify(memberExpr.Expression)),
                SwitchExpression switchExpr => switchExpr.Update(Simplify(switchExpr.SwitchValue), Simplify(switchExpr.Cases), Simplify(switchExpr.DefaultBody)),
                DynamicExpression dynamicExpr => dynamicExpr.Update(Simplify(dynamicExpr.Arguments)),
                ListInitExpression listInitExpr => listInitExpr.Update(Simplify(listInitExpr.NewExpression), Simplify(listInitExpr.Initializers)),
                NewArrayExpression newArrayExpr => newArrayExpr.Update(Simplify(newArrayExpr.Expressions)),
                InvocationExpression invokeExpr => invokeExpr.Update(Simplify(invokeExpr.Expression), Simplify(invokeExpr.Arguments)),
                MemberInitExpression memberInitExpr => memberInitExpr.Update(Simplify(memberInitExpr.NewExpression), memberInitExpr.Bindings),
                MethodCallExpression methodCallExpr => methodCallExpr.Update(Simplify(methodCallExpr.Object), Simplify(methodCallExpr.Arguments)),
                TypeBinaryExpression typeBinaryExpr => typeBinaryExpr.Update(Simplify(typeBinaryExpr.Expression)),
                ConditionalExpression condExpr => condExpr.Update(Simplify(condExpr.Test), Simplify(condExpr.IfTrue), Simplify(condExpr.IfFalse)),
                RuntimeVariablesExpression runtimeVarExpr => runtimeVarExpr.Update(Simplify(runtimeVarExpr.Variables)),
                _ => expression
            };

            foreach (var transform in transformers)
            {
                expr = transform.Transform(expr, this);
            }

            return((T)expr);
        }
Ejemplo n.º 21
0
 BlockExpression Convert(BlockExpression expr)
 {
     return(expr.Update(Process(expr.Variables), Process(expr.Expressions)));
 }
 protected override Expression VisitBlock(BlockExpression node)
 {
     var variables = VisitAndConvert(node.Variables, nameof(VisitBlock));
     var expressions = Visit(node.Expressions);
     return node.Update(variables, expressions);
 }
Ejemplo n.º 23
0
            protected override Expression VisitBlock(BlockExpression node)
            {
                var exprs = node.Expressions.SelectMany(e => new Expression[] { _log(Expression.Constant("S" + _n++)), Visit(e) }).ToList();

                return(node.Update(node.Variables, exprs));
            }
Ejemplo n.º 24
0
 protected override Expression VisitBlock(BlockExpression node)
 {
     var exprs = node.Expressions.SelectMany(e => new Expression[] { _log(Expression.Constant("S" + _n++)), Visit(e) }).ToList();
     return node.Update(node.Variables, exprs);
 }
Ejemplo n.º 25
0
 protected override Expression VisitBlock(BlockExpression node)
 {
     return(node.Update(node.Variables, Visit(node.Expressions)));
 }
Ejemplo n.º 26
0
        private static BlockExpression Update(BlockExpression node)
        {
            // Tests the call of Update to Expression.Block factories.

            var res = node.Update(node.Variables, node.Expressions.ToArray());

            Assert.NotSame(node, res);

            return res;
        }
Ejemplo n.º 27
0
 private static BlockExpression SetChildren(ReadOnlySpan <Expression> newChildren, BlockExpression b)
 => b.Update(b.Variables, newChildren.ToArray());