private static object TryCompile(ref ClosureInfo closureInfo, Type delegateType, Type[] paramTypes, Type returnType, Expression bodyExpr, IList <ParameterExpression> paramExprs) { if (!TryCollectBoundConstants(ref closureInfo, bodyExpr, paramExprs)) { return(null); } if (closureInfo != null) { closureInfo.ConstructClosure(); } var method = GetDynamicMethod(paramTypes, returnType, closureInfo); var il = method.GetILGenerator(); if (!EmittingVisitor.TryEmit(bodyExpr, paramExprs, il, closureInfo)) { return(null); } il.Emit(OpCodes.Ret); // emits return from generated method // create open delegate with closure object if (closureInfo == null) { return(method.CreateDelegate(delegateType)); } return(method.CreateDelegate(delegateType, closureInfo.ClosureObject)); }
private static Func <object[], object> EmitDelegateFromExpression(Expression expr) { var method = new DynamicMethod("CreateA", typeof(object), new[] { typeof(object[]) }); var il = method.GetILGenerator(); var ok = EmittingVisitor.TryVisit(expr, il); il.Emit(OpCodes.Ret); return((Func <object[], object>)method.CreateDelegate(typeof(Func <object[], object>))); }
private static Instruction[] LexParseAndEmit(string source) { var reader = source.CharwiseWithTrimmedLines(); using var lexer = new Lexer(reader); var tokens = lexer.Lex().ToList(); var parser = new Parser(tokens); var ast = (ProgramSyntax)parser.Parse(); var functions = new SymbolWaddler().WaddleProgram(ast); var emitter = new EmittingVisitor(functions[Naming.EntryPointFunctionName].Variables .ToDictionary(kvp => kvp.Key, kvp => kvp.Value as Symbol)); ast.Accept(emitter); return(emitter.BuildProgram()); }
static partial void CompileToDelegate(Expression expression, ref FactoryDelegate result) { var method = new DynamicMethod(string.Empty, typeof(object), _factoryDelegateArgTypes, typeof(Container).Module, skipVisibility: true); var il = method.GetILGenerator(); var emitted = EmittingVisitor.TryVisit(expression, il); if (emitted) { il.Emit(OpCodes.Ret); result = (FactoryDelegate)method.CreateDelegate(typeof(FactoryDelegate)); } }
/// <summary>Compiles expression to delegate by emitting the IL. /// If sub-expressions are not supported by emitter, then the method returns null. /// The usage should be calling the method, if result is null then calling the Expression.Compile.</summary> /// <param name="bodyExpr">Lambda body.</param> /// <param name="paramExprs">Lambda parameter expressions.</param> /// <param name="paramTypes">The types of parameters.</param> /// <param name="returnType">The return type.</param> /// <returns>Result delegate or null, if unable to compile.</returns> public static TDelegate TryCompile <TDelegate>( Expression bodyExpr, ParameterExpression[] paramExprs, Type[] paramTypes, Type returnType) where TDelegate : class { var constantExprs = new List <ConstantExpression>(); if (!TryCollectBoundConstants(bodyExpr, constantExprs)) { return(null); } object closure = null; ClosureInfo closureInfo = null; DynamicMethod method; if (constantExprs.Count == 0) { method = new DynamicMethod(string.Empty, returnType, paramTypes, typeof(FastExpressionCompiler).Module, skipVisibility: true); } else { var constants = new object[constantExprs.Count]; var constantCount = constants.Length; for (var i = constantCount - 1; i >= 0; i--) { constants[i] = constantExprs[i].Value; } if (constantCount <= Closure.CreateMethods.Length) { var createClosureMethod = Closure.CreateMethods[constantCount - 1]; var constantTypes = new Type[constantCount]; for (var i = 0; i < constantCount; i++) { constantTypes[i] = constantExprs[i].Type; } var createClosure = createClosureMethod.MakeGenericMethod(constantTypes); closure = createClosure.Invoke(null, constants); var fields = closure.GetType().GetTypeInfo().DeclaredFields; var fieldsArray = fields as FieldInfo[] ?? fields.ToArray(); closureInfo = new ClosureInfo(constantExprs, fieldsArray); } else { var arrayClosure = new ArrayClosure(constants); closure = arrayClosure; closureInfo = new ClosureInfo(constantExprs); } var closureType = closure.GetType(); var closureAndParamTypes = GetClosureAndParamTypes(paramTypes, closureType); method = new DynamicMethod(string.Empty, returnType, closureAndParamTypes, closureType, skipVisibility: true); } var il = method.GetILGenerator(); var emitted = EmittingVisitor.TryEmit(bodyExpr, paramExprs, il, closureInfo); if (emitted) { il.Emit(OpCodes.Ret); return((TDelegate)(object)method.CreateDelegate(typeof(TDelegate), closure)); } return(null); }