private static void SaveLambda(LambdaExpression lambda) { var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test"),AssemblyBuilderAccess.Save); var type = asm.DefineDynamicModule("myModule", "test.dll").DefineType("myType"); var builder = type.DefineMethod("Foo", MethodAttributes.Public | MethodAttributes.Static); lambda.CompileToMethod(builder); type.CreateType(); asm.Save("test.dll"); }
protected string CompileMethod(LambdaExpression expr) { var returnType = expr.Type; var parameters = expr.Parameters.Select(p => p.Type).ToArray(); lock (locker) { var name = "Binding_" + (methodCounter++); var method = bindingsClass.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Static, returnType, parameters); expr.CompileToMethod(method); return bindingsClass.FullName + "." + name; } }
private Delegate CompileExpression(Type t, LambdaExpression expression) { var typeBuilder = DefineMappingType(string.Format("Deserialize{0}_{1}", t.Name, Guid.NewGuid().ToString("N"))); var methodBuilder = typeBuilder.DefineMethod( "Deserialize", MethodAttributes.Public | MethodAttributes.Static, t, expression.Parameters.Select(p => p.Type).ToArray()); expression.CompileToMethod(methodBuilder); var resultingType = typeBuilder.CreateType(); var function = Delegate.CreateDelegate(expression.Type, resultingType.GetMethod("Deserialize")); return function; }
/// <summary> /// Emits the code needed to properly push an object on the stack, /// serializing the value if necessary. /// </summary> /// <param name="typeBuilder">The TypeBuilder for the method being built.</param> /// <param name="methodBuilder">The method currently being built.</param> /// <param name="invocationContext">The invocation context for this call.</param> /// <param name="invocationContexts">A list of invocation contexts that will be appended to.</param> /// <param name="invocationContextsField">The static field containing the array of invocation contexts at runtime.</param> /// <param name="i">The index of the current parameter being pushed.</param> /// <param name="sourceType">The type that the parameter is being converted from.</param> /// <param name="targetType">The type that the parameter is being converted to.</param> /// <param name="converter">An optional converter to apply to the source type.</param> /// <param name="serializationProvider">The serialization provider for the current interface.</param> /// <param name="serializationProviderField"> /// The field on the current object that contains the serialization provider at runtime. /// This method assume the current object is stored in arg.0. /// </param> internal static void EmitSerializeValue( TypeBuilder typeBuilder, MethodBuilder methodBuilder, InvocationContext invocationContext, List<InvocationContext> invocationContexts, FieldBuilder invocationContextsField, int i, Type sourceType, Type targetType, LambdaExpression converter, TraceSerializationProvider serializationProvider, FieldBuilder serializationProviderField) { ILGenerator mIL = methodBuilder.GetILGenerator(); // if the source is a parameter, then load the parameter onto the stack if (i >= 0) mIL.Emit(OpCodes.Ldarg, i + 1); // if a converter is passed in, then define a static method and use it to convert if (converter != null) { MethodBuilder mb = typeBuilder.DefineMethod(Guid.NewGuid().ToString(), MethodAttributes.Static | MethodAttributes.Public, converter.ReturnType, converter.Parameters.Select(p => p.Type).ToArray()); converter.CompileToMethod(mb); mIL.Emit(OpCodes.Call, mb); // the object on the stack is now the return type. we may need to convert it further sourceType = converter.ReturnType; } // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef && sourceType.GetElementType() == targetType) { sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); return; } // if the types match, just put the argument on the stack if (sourceType == targetType) return; // this is not a match, so convert using the serializer. // verify that the target type is a string if (targetType != typeof(string)) throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot convert type {0} to a type compatible with EventSource", targetType.FullName)); // for fundamental types, just convert them with ToString and be done with it var underlyingType = Nullable.GetUnderlyingType(sourceType) ?? sourceType; if (!sourceType.IsGenericParameter && (underlyingType.IsEnum || (underlyingType.IsValueType && underlyingType.Assembly == typeof(string).Assembly))) { // convert the argument to a string with ToString LocalBuilder lb = mIL.DeclareLocal(sourceType); mIL.Emit(OpCodes.Stloc, lb.LocalIndex); mIL.Emit(OpCodes.Ldloca, lb.LocalIndex); mIL.Emit(OpCodes.Call, sourceType.GetMethod("ToString", Type.EmptyTypes)); return; } // non-fundamental types use the object serializer var context = new TraceSerializationContext(invocationContext, i); context.EventLevel = serializationProvider.GetEventLevelForContext(context); if (context.EventLevel != null) { LocalBuilder lb = mIL.DeclareLocal(sourceType); mIL.Emit(OpCodes.Stloc, lb.LocalIndex); // get the object serializer from the this pointer mIL.Emit(OpCodes.Ldsfld, serializationProviderField); mIL.Emit(OpCodes.Ldloc, lb.LocalIndex); // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef) { sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); } // if it's a value type, we have to box it to log it if (sourceType.IsGenericParameter || sourceType.IsValueType) mIL.Emit(OpCodes.Box, sourceType); // get the invocation context from the array on the provider mIL.Emit(OpCodes.Ldsfld, invocationContextsField); mIL.Emit(OpCodes.Ldc_I4, invocationContexts.Count); mIL.Emit(OpCodes.Ldelem, typeof(TraceSerializationContext)); invocationContexts.Add(context); mIL.Emit(OpCodes.Callvirt, typeof(TraceSerializationProvider).GetMethod("ProvideSerialization", BindingFlags.Instance | BindingFlags.Public)); } else { mIL.Emit(OpCodes.Pop); mIL.Emit(OpCodes.Ldnull); } }
public static void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, List<ParameterExpression> paramExprs, Type[] paramTypes, CljILGen ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda) { Expression call = dyn; GenContext context = Compiler.CompilerContextVar.deref() as GenContext; if (context != null && context.DynInitHelper != null) call = context.DynInitHelper.ReduceDyn(dyn); if (returnType == typeof(void)) { call = Expression.Block(call, Expression.Default(typeof(object))); returnType = typeof(object); } else if (returnType != call.Type) { call = Expression.Convert(call, returnType); } call = GenContext.AddDebugInfo(call, spanMap); delType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, paramTypes); lambda = Expression.Lambda(delType, call, paramExprs); mbLambda = null; if (context == null) { // light compile Delegate d = lambda.Compile(); int key = RT.nextID(); CacheDelegate(key, d); ilg.EmitInt(key); ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate); ilg.Emit(OpCodes.Castclass, delType); } else { mbLambda = context.TB.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes); lambda.CompileToMethod(mbLambda); } }
public void CompileToMethod(LambdaExpression expression, MethodBuilder method) { expression.CompileToMethod(method); }
public MethodBuilder DeclareMethod(TypeBuilder module, string name, LambdaExpression expression) { var methodBuilder = module.DefineMethod(name, MethodAttributes.Static | MethodAttributes.Public); expression.CompileToMethod(methodBuilder); return methodBuilder; }
/// <summary> /// Saves the given lambda expression to disk as an executable assembly /// under the given filename. /// </summary> /// <param name="exprLambdaProgram">Lambda to save.</param> /// <param name="fileSpec">Output file specification.</param> /// <remarks> /// Code from: http://stackoverflow.com/questions/15168150/how-to-save-an-expression-tree-as-the-main-entry-point-to-a-new-executable-disk /// </remarks> /// static void SaveToDisk(LambdaExpression exprLambdaProgram, string fileSpec) { string outputFilename = Path.GetFileName(fileSpec); string assemblyName = outputFilename.Substring(0, outputFilename.Length - Path.GetExtension(outputFilename).Length); // Attach the expression as a method to a dynamic assembly var asmName = new AssemblyName(assemblyName); var asmBuilder = AssemblyBuilder.DefineDynamicAssembly (asmName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = asmBuilder.DefineDynamicModule(assemblyName, outputFilename); var typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public); var methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), new[] { typeof(string) }); exprLambdaProgram.CompileToMethod(methodBuilder); // Save the dynamic assembly to disk as an executable. typeBuilder.CreateType(); asmBuilder.SetEntryPoint(methodBuilder); asmBuilder.Save(outputFilename); }
public override void DefineFunc(object ID, System.Linq.Expressions.LambdaExpression Corpse) { Corpse.CompileToMethod(((AssemblyFunction)ScopeFunctions[(int)ID].Information).Method); }
private Delegate CompileExpression(Type sourceType, Type destinationType, LambdaExpression expression) { if (this.options.Debug.DebugInformationEnabled) { this.DebugInformation = new DebugInformation { MappingExpression = expression }; } if (this.options.Compilation.CompileToDynamicAssembly && !mapProcessor.NonPublicMembersAccessed) { var typeBuilder = DefineMappingType(string.Format("From_{0}_to_{1}_{2}", sourceType.Name, destinationType.Name, Guid.NewGuid().ToString("N"))); var methodBuilder = typeBuilder.DefineMethod("Map", MethodAttributes.Public | MethodAttributes.Static); expression.CompileToMethod(methodBuilder); var resultingType = typeBuilder.CreateType(); var function = Delegate.CreateDelegate(expression.Type, resultingType.GetMethod("Map")); return function; } else { // Much simpler, but the resulting delegate incurs an invocation overhead from experience return expression.Compile(); } }
private static Delegate CompileExpression(Type sourceType, Type destinationType, LambdaExpression expression) { if (IsPublicClass(sourceType) && IsPublicClass(destinationType)) { if (moduleBuilder == null) { var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("ThisMemberFunctionsAssembly_" + Guid.NewGuid().ToString("N")), AssemblyBuilderAccess.Run); moduleBuilder = assemblyBuilder.DefineDynamicModule("Module"); } var typeBuilder = moduleBuilder.DefineType(string.Format("From_{0}_to_{1}_{2}", sourceType.Name, destinationType.Name, Guid.NewGuid().ToString("N"), TypeAttributes.Public)); var methodBuilder = typeBuilder.DefineMethod("Map", MethodAttributes.Public | MethodAttributes.Static); expression.CompileToMethod(methodBuilder); var resultingType = typeBuilder.CreateType(); var function = Delegate.CreateDelegate(expression.Type, resultingType.GetMethod("Map")); return function; } else { return expression.Compile(); } }