Beispiel #1
0
        /// <summary>
        /// Walks the lambda and produces a higher order function, which can be
        /// used to bind the lambda to a closure array from the interpreter.
        /// </summary>
        /// <param name="lambda">The lambda to bind.</param>
        /// <param name="closureVariables">Variables which are being accessed defined in the outer scope.</param>
        /// <returns>A delegate that can be called to produce a delegate bound to the passed in closure array.</returns>
        internal static Func <StrongBox <object>[], Delegate> BindLambda(LambdaExpression lambda, Dictionary <ParameterExpression, LocalVariable> closureVariables)
        {
            // 1. Create rewriter
            var closure = Expression.Parameter(typeof(StrongBox <object>[]), "closure");
            var visitor = new LightLambdaClosureVisitor(closureVariables, closure);

            // 2. Visit the lambda
            lambda = (LambdaExpression)visitor.Visit(lambda);

            // 3. Create a higher-order function which fills in the parameters
            var result = Expression.Lambda <Func <StrongBox <object>[], Delegate> >(lambda, closure);

            // 4. Compile it
            return(result.Compile());
        }
Beispiel #2
0
        /// <summary>
        /// Create a compiled delegate for the LightLambda, and saves it so
        /// future calls to Run will execute the compiled code instead of
        /// interpreting.
        /// </summary>
        internal void Compile(object state)
        {
            if (_compiled != null)
            {
                return;
            }

            // Compilation is expensive, we only want to do it once.
            lock (_compileLock) {
                if (_compiled != null)
                {
                    return;
                }

                PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Interpreted lambda compiled");

                // Interpreter needs a standard delegate type.
                // So change the lambda's delegate type to Func<...> or
                // Action<...> so it can be called from the LightLambda.Run
                // methods.
                LambdaExpression lambda = (_lambda as LambdaExpression) ?? (LambdaExpression)((LightLambdaExpression)_lambda).Reduce();
                if (_interpreter != null)
                {
                    _compiledDelegateType = GetFuncOrAction(lambda);
                    lambda = Expression.Lambda(_compiledDelegateType, lambda.Body, lambda.Name, lambda.Parameters);
                }

                if (HasClosure)
                {
                    _compiled = LightLambdaClosureVisitor.BindLambda(lambda, _interpreter.ClosureVariables);
                }
                else
                {
                    _compiled = lambda.Compile();
                }
            }
        }