CompileToMethod() public method

public CompileToMethod ( MethodBuilder method, DebugInfoGenerator debugInfoGenerator ) : void
method System.Reflection.Emit.MethodBuilder
debugInfoGenerator System.Runtime.CompilerServices.DebugInfoGenerator
return void
 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;
        }
Example #4
0
        /// <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);
            }
        }
Example #5
0
        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);
 }
Example #7
0
 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);
        }
Example #9
0
 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();
              }
        }