Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
    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>)));
    }
Exemplo n.º 3
0
        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));
            }
        }
Exemplo n.º 5
0
        /// <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);
        }