private static CompiledLambda CompileToDynamicMethod( LambdaExpression lambda, ParsedLambda parsedLambda, CompilerOptions options, bool internalCall, List <CompiledLambda> compiledLambdas) { var parameters = lambda.Parameters.ToArray(); var parameterTypes = parameters.Select(parameter => parameter.Type).ToArray(); var returnType = lambda.ReturnType; var method = new DynamicMethod(lambda.Name ?? Guid.NewGuid().ToString(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, parameterTypes, Module, true); using (var il = new GroboIL(method, AnalyzeILStack)) { var context = new EmittingContext { Options = options, Lambda = lambda, Method = method, SkipVisibility = true, Parameters = parameters, ParsedLambda = parsedLambda, CompiledLambdas = compiledLambdas, Il = il }; CompileInternal(lambda, context); } return(new CompiledLambda { Delegate = Extensions.IsMono && internalCall?method.CreateDelegate(Extensions.GetDelegateType(parameterTypes, returnType)) : method.CreateDelegate(Extensions.GetDelegateType(parsedLambda.ConstantsParameter == null ? parameterTypes : parameterTypes.Skip(1).ToArray(), lambda.ReturnType), parsedLambda.Constants), Method = method }); }
internal static void CompileToMethodInternal( LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator, ParsedLambda parsedLambda, CompilerOptions options, List <CompiledLambda> compiledLambdas, MethodBuilder method) { var typeBuilder = method.ReflectedType as TypeBuilder; if (typeBuilder == null) { throw new ArgumentException("Unable to obtain type builder of the method", "method"); } using (var il = new GroboIL(method, AnalyzeILStack)) { var context = new EmittingContext { Options = options, DebugInfoGenerator = debugInfoGenerator, TypeBuilder = typeBuilder, Lambda = lambda, Method = method, SkipVisibility = false, Parameters = lambda.Parameters.ToArray(), ParsedLambda = parsedLambda, CompiledLambdas = compiledLambdas, Il = il }; CompileInternal(lambda, context); } }
private static Action <object, Delegate[]> BuildDelegatesFoister(ParsedLambda parsedLambda) { var constants = Expression.Parameter(typeof(object)); var delegates = Expression.Parameter(typeof(Delegate[])); var castedConstants = Expression.Parameter(parsedLambda.ConstantsType); var body = Expression.Block(new[] { castedConstants }, Expression.Assign(castedConstants, Expression.Convert(constants, parsedLambda.ConstantsType)), parsedLambda.ConstantsBuilder.Assign(castedConstants, parsedLambda.DelegatesFieldId, delegates)); var lambda = Expression.Lambda <Action <object, Delegate[]> >(body, constants, delegates); return(Compile(lambda, CompilerOptions.None)); }
internal static CompiledLambda CompileInternal( LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator, ParsedLambda parsedLambda, CompilerOptions options, bool internalCall, List <CompiledLambda> compiledLambdas) { if (debugInfoGenerator == null) { return(CompileToDynamicMethod(lambda, parsedLambda, options, internalCall, compiledLambdas)); } var parameters = lambda.Parameters.ToArray(); var parameterTypes = parameters.Select(parameter => parameter.Type).ToArray(); var returnType = lambda.ReturnType; var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Public | TypeAttributes.Class); var method = typeBuilder.DefineMethod(lambda.Name ?? Guid.NewGuid().ToString(), MethodAttributes.Static | MethodAttributes.Public, returnType, parameterTypes); for (var i = 0; i < parameters.Length; ++i) { method.DefineParameter(i + 1, ParameterAttributes.None, parameters[i].Name); } CompileToMethodInternal(lambda, debugInfoGenerator, parsedLambda, options, compiledLambdas, method); var type = typeBuilder.CreateType(); var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), returnType, parameterTypes, Module, true); using (var il = new GroboIL(dynamicMethod)) { for (var i = 0; i < parameterTypes.Length; ++i) { il.Ldarg(i); } il.Call(type.GetMethod(method.Name)); il.Ret(); } return(new CompiledLambda { Delegate = Extensions.IsMono && internalCall?dynamicMethod.CreateDelegate(Extensions.GetDelegateType(parameterTypes, returnType)) : dynamicMethod.CreateDelegate(Extensions.GetDelegateType(parsedLambda.ConstantsParameter == null ? parameterTypes : parameterTypes.Skip(1).ToArray(), lambda.ReturnType), parsedLambda.Constants), Method = method }); }