/// <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>CompiledCode<R, C> - a delegate that calls the compiled expression</returns> public CompiledCode <R, C> GetDelegate <R, C>(DynamicMethodState methodState) { ExecuteExpression <R, C> methodDelegate = null; //get delegate factory IExpressionDelegateFactory delegateFactory = new ExpressionDelegateFactory(m_language); 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 CompiledCode <R, C>(methodDelegate)); }
public ExecuteExpression <T> CreateExpressionDelegate <T>(DynamicMethodState methodState, object functionClass) { ExecuteExpression <T> expressionDelegate; Stopwatch stopWatch = new Stopwatch(); Trace.WriteLine("Dynamic dll creation - " + stopWatch.ElapsedMilliseconds.ToString()); stopWatch = new Stopwatch(); stopWatch.Start(); //create DynamicMethod dynamicMethod = new DynamicMethod("", typeof(T), new Type[] { functionClass.GetType() }, functionClass.GetType()); DynamicILInfo dynamicInfo = dynamicMethod.GetDynamicILInfo(); dynamicMethod.InitLocals = methodState.InitLocals; SignatureHelper locals = SignatureHelper.GetLocalVarSigHelper(); foreach (int localIndex in methodState.LocalVariables.Keys) { LocalVariable localVar = methodState.LocalVariables[localIndex]; locals.AddArgument(localVar.LocalType, localVar.IsPinned); } dynamicInfo.SetLocalSignature(locals.GetSignature()); IlTokenResolver tokenResolver = new IlTokenResolver(methodState.TokenOffset.Fields, methodState.TokenOffset.Methods, methodState.TokenOffset.Members, methodState.TokenOffset.Types, methodState.TokenOffset.LiteralStrings); methodState.CodeBytes = tokenResolver.ResolveCodeTokens(methodState.CodeBytes, dynamicInfo); dynamicInfo.SetCode(methodState.CodeBytes, methodState.MaxStackSize); expressionDelegate = (ExecuteExpression <T>)dynamicMethod.CreateDelegate(typeof(ExecuteExpression <T>), functionClass); stopWatch.Stop(); Trace.WriteLine("Dynamic Method Creation - " + stopWatch.ElapsedMilliseconds.ToString()); return(expressionDelegate); }
/// <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<R, C> - a delegate that calls the compiled expression</returns> public ExecuteExpression <R, C> CreateExpressionDelegate <R, C>(DynamicMethodState methodState) { ExecuteExpression <R, C> expressionDelegate; //create a dynamic method DynamicMethod dynamicMethod = new DynamicMethod("_" + Guid.NewGuid().ToString("N"), typeof(R), new Type[] { 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 IlTokenResolver 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 expressionDelegate = (ExecuteExpression <R, C>)dynamicMethod.CreateDelegate(typeof(ExecuteExpression <R, C>)); return(expressionDelegate); }
/// <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) { DynamicMethodState methodState = new DynamicMethodState(); //IL info from method MethodBody 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 (LocalVariableInfo localInfo in methodIlCode.LocalVariables) { locals.Add(localInfo.LocalIndex, new LocalVariable(localInfo.IsPinned, localInfo.LocalType.TypeHandle)); } methodState.localVariables = locals; TokenOffset tokenOffset = new TokenOffset(); //get metadata token offsets IlReader 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); }