Beispiel #1
0
        private void Compile(string expression, ExpressionOptions options)
        {
            // Add the services that will be used by elements during the compile
            IServiceContainer services = new ServiceContainer();

            this.AddServices(services);

            // Parse and get the root element of the parse tree
            ExpressionElement topElement = _myContext.Parse(expression, services);

            if (options.ResultType == null)
            {
                options.ResultType = topElement.ResultType;
            }

            RootExpressionElement rootElement = new RootExpressionElement(topElement, options.ResultType);

            DynamicMethod dm = this.CreateDynamicMethod();

            FleeILGenerator ilg = new FleeILGenerator(dm.GetILGenerator());

            // Emit the IL
            rootElement.Emit(ilg, services);
            if (ilg.NeedsSecondPass())
            {
                // second pass required due to long branches.
                dm = this.CreateDynamicMethod();
                ilg.PrepareSecondPass(dm.GetILGenerator());
                rootElement.Emit(ilg, services);
            }

            ilg.ValidateLength();

            // Emit to an assembly if required
            if (options.EmitToAssembly == true)
            {
                EmitToAssembly(ilg, rootElement, services);
            }

            Type delegateType = typeof(ExpressionEvaluator <>).MakeGenericType(typeof(T));

            _myEvaluator = (ExpressionEvaluator <T>)dm.CreateDelegate(delegateType);
        }
Beispiel #2
0
        /// <summary>
        /// Emit to an assembly. We've already computed long branches at this point,
        /// so we emit as a second pass
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="rootElement"></param>
        /// <param name="services"></param>
        private static void EmitToAssembly(FleeILGenerator ilg, ExpressionElement rootElement, IServiceContainer services)
        {
            AssemblyName assemblyName = new AssemblyName(EmitAssemblyName);

            string assemblyFileName = string.Format("{0}.dll", EmitAssemblyName);

            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(assemblyFileName);

            MethodBuilder mb = moduleBuilder.DefineGlobalMethod("Evaluate", MethodAttributes.Public | MethodAttributes.Static, typeof(T), new Type[] {
                typeof(object), typeof(ExpressionContext), typeof(VariableCollection)
            });

            // already emitted once for local use,
            ilg.PrepareSecondPass(mb.GetILGenerator());

            rootElement.Emit(ilg, services);

            moduleBuilder.CreateGlobalFunctions();
            //assemblyBuilder.Save(assemblyFileName);
            assemblyBuilder.CreateInstance(assemblyFileName);
        }