Пример #1
0
        //TODO enable sharing of these custom delegates
        private Delegate CreateCustomDelegate(Type delegateType)
        {
            //PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "Synchronously compiling a custom delegate");

            var  method             = delegateType.GetMethod("Invoke");
            var  paramInfos         = method.GetParameters();
            var  parameters         = new ParameterExpression[paramInfos.Length];
            var  parametersAsObject = new Expression[paramInfos.Length];
            bool hasByRef           = false;

            for (int i = 0; i < paramInfos.Length; i++)
            {
                ParameterExpression parameter = Expression.Parameter(paramInfos[i].ParameterType, paramInfos[i].Name);
                hasByRef              = hasByRef || paramInfos[i].ParameterType.IsByRef;
                parameters[i]         = parameter;
                parametersAsObject[i] = Expression.Convert(parameter, typeof(object));
            }

            var data = Expression.NewArrayInit(typeof(object), parametersAsObject);
            var dlg  = new Func <object[], object>(Run);

            var dlgExpr = AstUtils.Constant(dlg);


            var argsParam = Expression.Parameter(typeof(object[]), "$args");

            Expression body;

            if (method.ReturnType == typeof(void))
            {
                body = Expression.Block(typeof(void), Expression.Invoke(dlgExpr, argsParam));
            }
            else
            {
                body = Expression.Convert(Expression.Invoke(dlgExpr, argsParam), method.ReturnType);
            }

            if (hasByRef)
            {
                List <Expression> updates = new List <Expression>();
                for (int i = 0; i < paramInfos.Length; i++)
                {
                    if (paramInfos[i].ParameterType.IsByRef)
                    {
                        updates.Add(
                            Expression.Assign(
                                parameters[i],
                                Expression.Convert(
                                    Expression.ArrayAccess(argsParam, Expression.Constant(i)),
                                    paramInfos[i].ParameterType.GetElementType()
                                    )
                                )
                            );
                    }
                }

                body = Expression.TryFinally(body, Expression.Block(typeof(void), updates));
            }

            body = Expression.Block(
                method.ReturnType,
                new[] { argsParam },
                Expression.Assign(argsParam, data),
                body
                );

            var lambda = Expression.Lambda(delegateType, body, parameters);

            //return System.Linq.Expressions.Compiler.LambdaCompiler.Compile(lambda, null);
            throw new NotImplementedException("byref delegate");
        }
 internal virtual Expression GetFalse()
 {
     // Using a singleton here to ensure a stable object identity for IfFalse, which Update relies on.
     return(AstUtils.Empty());
 }