/// <summary>
        /// Compiles a DynamicMethodState and returns a delegate.
        /// </summary>
        /// <typeparam name="R">The return type of the expression</typeparam>
        /// <typeparam name="C">The type of the function class</typeparam>
        /// <param name="methodState">The serialized version of a method on the functionClass</param>
        /// <returns>ExecuteExpression&lt;R, C&gt; - a delegate that calls the compiled expression</returns>
        public ExecuteExpression <R, C> CreateExpressionDelegate <R, C>(DynamicMethodState methodState)
        {
            //create a dynamic method
            var dynamicMethod = new DynamicMethod("_" + Guid.NewGuid().ToString("N"), typeof(R), new[] { typeof(C) }, typeof(C));

            //get the IL writer for it
            DynamicILInfo dynamicInfo = dynamicMethod.GetDynamicILInfo();

            //set the properties gathered from the compiled expression
            dynamicMethod.InitLocals = methodState.InitLocals;

            //set local variables
            SignatureHelper locals = SignatureHelper.GetLocalVarSigHelper();

            foreach (int localIndex in methodState.LocalVariables.Keys)
            {
                LocalVariable localVar = methodState.LocalVariables[localIndex];
                locals.AddArgument(Type.GetTypeFromHandle(localVar.LocalType), localVar.IsPinned);
            }

            dynamicInfo.SetLocalSignature(locals.GetSignature());

            //resolve any metadata tokens
            var tokenResolver = new IlTokenResolver(methodState.TokenOffset.Fields, methodState.TokenOffset.Methods, methodState.TokenOffset.Types, methodState.TokenOffset.LiteralStrings);

            methodState.CodeBytes = tokenResolver.ResolveCodeTokens(methodState.CodeBytes, dynamicInfo);

            //set the IL code for the dynamic method
            dynamicInfo.SetCode(methodState.CodeBytes, methodState.MaxStackSize);

            //create a delegate for fast execution
            var expressionDelegate = (ExecuteExpression <R, C>)dynamicMethod.CreateDelegate(typeof(ExecuteExpression <R, C>));

            return(expressionDelegate);
        }
Example #2
0
        /// <summary>
        /// Compiles a DynamicMethodState and returns a delegate.
        /// </summary>
        /// <typeparam name="R">The return type of the expression</typeparam>
        /// <typeparam name="C">The type of the function class</typeparam>
        /// <param name="methodState">The serialized version of a method on the functionClass</param>
        /// <returns>EvalExpression&lt;R, C&gt; - a delegate that calls the compiled expression</returns>
        internal EvalExpression <R, C> GetDelegate <R, C>(DynamicMethodState methodState)
        {
            ExecuteExpression <R, C> methodDelegate = null;

            //get delegate factory
            var delegateFactory = new ExpressionDelegateFactory();

            if (methodState != null && methodState.CodeBytes != null)
            {
                //get delegate from factory
                methodDelegate = delegateFactory.CreateExpressionDelegate <R, C>(methodState);
            }

            //return an eval delegate based on the delegate from the factory
            return(new EvalExpression <R, C>(methodDelegate));
        }
        /// <summary>
        /// Converts a MethodInfo into a serialized version of it.
        /// </summary>
        /// <param name="dynamicMethod">The method for which to create a DynamicMethod for</param>
        /// <returns>DynamicMethodState - serialized version of a method.</returns>
        protected DynamicMethodState GetMethodState(MethodInfo dynamicMethod)
        {
            var methodState = new DynamicMethodState();

            //IL info from method
            var methodIlCode = dynamicMethod.GetMethodBody();

            //get code bytes and other method properties
            methodState.CodeBytes    = methodIlCode.GetILAsByteArray();
            methodState.InitLocals   = methodIlCode.InitLocals;
            methodState.MaxStackSize = methodIlCode.MaxStackSize;

            //get any local variable information
            IDictionary <int, LocalVariable> locals = new SortedList <int, LocalVariable>();

            foreach (var localInfo in methodIlCode.LocalVariables)
            {
                locals.Add(localInfo.LocalIndex, new LocalVariable(localInfo.IsPinned, localInfo.LocalType.TypeHandle));
            }

            methodState.LocalVariables = locals;

            var tokenOffset = new TokenOffset();

            //get metadata token offsets
            var reader = new IlReader(methodState.CodeBytes, dynamicMethod.Module);

            tokenOffset.Fields         = reader.Fields;
            tokenOffset.Methods        = reader.Methods;
            tokenOffset.Types          = reader.Types;
            tokenOffset.LiteralStrings = reader.LiteralStrings;

            methodState.TokenOffset = tokenOffset;

            return(methodState);
        }