示例#1
0
        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
            });
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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));
        }
示例#4
0
        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
            });
        }