internal Expression <T> BuildExpression <T>(string expressionName, string expression) { var owner = DefaultExpressionOwner.Instance; var ownerType = DefaultExpressionOwner.Type; Imports.ImportOwner(ownerType); var context = new ExpressionContext(Options, expressionName, owner) { Variables = Variables, Imports = Imports, ComputeInstance = ComputeInstance, }; var topElement = Parse(expression, context); var rootElement = new RootExpressionElement(topElement, typeof(T)); var dynamicMethod = CreateDynamicMethod <T>(ownerType); var ilGenerator = new YaleIlGenerator(dynamicMethod.GetILGenerator()); rootElement.Emit(ilGenerator, context); #if DEBUG ilGenerator.ValidateLength(); #endif var delegateType = typeof(ExpressionEvaluator <>).MakeGenericType(typeof(T)); var evaluator = (ExpressionEvaluator <T>)dynamicMethod.CreateDelegate(delegateType); return(new Expression <T>(expression, evaluator, context)); }
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); }