Ejemplo n.º 1
0
        public VariadicArrayParametersDelegate CachedCompileLambda(LambdaExpression lambda)
        {
            IReadOnlyList <object> constants;

            ParameterListDelegate compiled;

            if (delegates.TryGetValue(lambda, out compiled))
            {
                constants = ConstantExtractor.ExtractConstantsOnly(lambda.Body);
            }
            else
            {
                var extractionResult = ConstantExtractor.ExtractConstants(lambda.Body);

                compiled = ParameterListRewriter.RewriteLambda(
                    Expression.Lambda(
                        extractionResult.ConstantfreeExpression.Body,
                        extractionResult.ConstantfreeExpression.Parameters.Concat(lambda.Parameters)))
                           .Compile();

                var key = getClosureFreeKeyForCaching(extractionResult, lambda.Parameters);

                delegates.TryAdd(key, compiled);
                constants = extractionResult.ExtractedConstants;
            }

            return(args => compiled(constants.Concat(args).ToArray()));
        }
Ejemplo n.º 2
0
            public static LambdaExpression Extract(Expression exp, out IList <object> values)
            {
                var extractor = new ConstantExtractor();
                var body      = extractor.Visit(exp);

                values = extractor.constantValues.ToArray();
                if (values.Count >= 5)
                {
                    // Can't create a lambda with more than 4 parameters.  Go figure.
                    values = new object[] { values };
                    return(ParamArrayRewriter.Rewrite(body, extractor.newParameters.ToArray()));
                }
                return(Expression.Lambda(body, extractor.newParameters.ToArray()));
            }
        public void SimpleTest()
        {
            var ex = new ConstantExtractor(CreateAdd(1));
            var ey = new ConstantExtractor(CreateAdd(2));

            var tx = ex.Process().ToExpressionTree();
            var ty = ey.Process().ToExpressionTree();

            var cx = (int)ex.GetConstants()[0];
            var cy = (int)ey.GetConstants()[0];

            Assert.AreEqual(cx, 1);
            Assert.AreEqual(cy, 2);
            Assert.AreEqual(tx, ty);
        }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        public override object Execute(Expression expression)
        {
            if (expression.NodeType != ExpressionType.Call)
            {
                throw new Exception("Unsupported node type: " + expression.NodeType);
            }

            var m = (MethodCallExpression)expression;

            if (m.Method.Name != "Select")
            {
                throw new Exception("Unsupported method: " + m.Method.Name);
            }

            // Pull out the constants from the new expression
            IList <object> values;
            var            extractedLambda = ConstantExtractor.Extract(m, out values);

            // Now get compiled version from cache, or create as appropriate
            var cacheKey    = new CacheEntry(m);
            var cachedEntry = GetCachedEntry(cacheKey);

            if (cachedEntry == null)
            {
                Type dataType = m.Method.GetGenericArguments()[0];                  // Queryable.Select<TSource,TResult>(...)

                // Perform the translation to using FudgeMsgs rather than the data type
                var translator = new FudgeExpressionTranslator(dataType, source);
                var newSelect  = (LambdaExpression)translator.Translate(extractedLambda);

                // We can now create a fully-fledged cache entry
                cachedEntry = new CacheEntry(cacheKey, newSelect.Compile());
                AddCacheEntry(cachedEntry);
            }
            return(cachedEntry.Invoke(values.ToArray()));
        }