private static void AttemptImplicitCast <TFrom, TTo>()
            {
                // based on the IL produced by:
                // dynamic list = new List<TTo>();
                // list.Add(Get<TFrom>());
                // We can't use the above code because it will mimic a cast in a generic method
                // which doesn't have the same semantics as a cast in a non-generic method

                var list   = new List <TTo>(capacity: 0);
                var binder = CSharpBinder.InvokeMember(
                    flags: CSharpBinderFlags.ResultDiscarded,
                    name: "Add",
                    typeArguments: null,
                    context: typeof(ConversionHelper),
                    argumentInfo: new[]
                {
                    CSharpArgumentInfo.Create(flags: CSharpArgumentInfoFlags.None, name: null),
                    CSharpArgumentInfo.Create(
                        flags: CSharpArgumentInfoFlags.UseCompileTimeType,
                        name: null
                        ),
                }
                    );
                var callSite = CallSite <Action <CallSite, object, TFrom> > .Create(binder);

                callSite.Target.Invoke(callSite, list, default(TFrom));
            }
Пример #2
0
        internal static Delegate WrapFunc(Type returnType, object invokable, int length)
        {
            CallSite <DynamicInvokeWrapFunc> tSite;

            if (!_dynamicInvokeWrapFunc.TryGetValue(returnType, out tSite))
            {
                var tMethod = "WrapFuncHelperMono";

#if !__MonoCS__
                //Mono Compiler can't compile or run WrapFuncHelper
                if (!Util.IsMono)
                {
                    tMethod = "WrapFuncHelper";
                }
#endif
                tSite = CallSite <DynamicInvokeWrapFunc> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        tMethod,
                        new[] { returnType },
                        typeof(InvokeHelper),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                }
                        ));

                _dynamicInvokeWrapFunc[returnType] = tSite;
            }
            return((Delegate)tSite.Target(tSite, typeof(InvokeHelper), invokable, length));
        }
Пример #3
0
        internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label)
        {
            CallSiteBinder binder      = Binder.InvokeMember(CSharpBinderFlags.None, MethodName, Types, dynamicContext ?? typeof(object), new object[Arguments.Arguments.Length + 1].Select(val => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)));
            Expression     dynamicCall = Expression.Dynamic(binder, typeof(object), new[] { Target.GetExpression(parameters, locals, dataContainers, dynamicContext, label) }.Concat(Arguments.Arguments.Select(token => token.GetExpression(parameters, locals, dataContainers, dynamicContext, label))));

            var targetVar = Expression.Variable(typeof(object));
            var argsVar   = Expression.Variable(typeof(object[]));
            var methodVar = Expression.Variable(typeof(Tuple <MethodInfo, object[]>));
            var resultVar = Expression.Variable(typeof(object));

            Expression test      = Expression.Equal(methodVar, Expression.Constant(null, typeof(Tuple <MethodInfo, object[]>)));
            Expression ifNotNull = Expression.Assign(resultVar, Expression.Call(Expression.Property(methodVar, Item1Prop), InvokeMethod, Expression.Constant(null), Expression.Property(methodVar, Item2Prop)));
            Expression ifNull    = Expression.Assign(resultVar, dynamicCall);

            Expression branch = Expression.IfThenElse(test, ifNull, ifNotNull);

            Expression block = Expression.Block(new[] { targetVar, argsVar, methodVar }, new[]
            {
                Expression.Assign(targetVar, Target.GetExpression(parameters, locals, dataContainers, dynamicContext, label)),
                Expression.Assign(argsVar, Expression.NewArrayInit(typeof(object), new[] { targetVar }.Concat(Arguments.Arguments.Select(token => token.GetExpression(parameters, locals, dataContainers, dynamicContext, label))))),
                Expression.Assign(methodVar, Expression.Call(GetMethod, Expression.Constant(MethodName, typeof(string)), Expression.Constant(Types, typeof(Type[])), argsVar)),
                branch,
                resultVar
            });

            Expression ret = Expression.Block(new[] { resultVar }, new Expression[] { Expression.IfThenElse(Expression.Property(null, SupportsExtensions), block, ifNull), resultVar });

            return(ret);
        }
Пример #4
0
        internal static Delegate WrapFunc(Type returnType, object invokable, int length)
        {
            if (!_dynamicInvokeWrapFunc.TryGetValue(returnType, out var tSite))
            {
                var tMethod = "WrapFuncHelper";

                tSite = CallSite <DynamicInvokeWrapFunc> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        tMethod,
                        new[] { returnType },
                        typeof(InvokeHelper),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                }
                        ));

                _dynamicInvokeWrapFunc[returnType] = tSite;
            }
            return((Delegate)tSite.Target(tSite, typeof(InvokeHelper), invokable, length));
        }
        internal static Delegate WrapFunc(Type returnType, object functor, int length)
        {
            CallSite <DynamicInvokeWrapFunc> theCallSite;

            if (!_dynamicInvokeWrapFunc.TryGetValue(returnType, out theCallSite))
            {
                var methodName = "WrapFunctionToDelegateMono";

#if !__MonoCS__
                if (!TypeFactorization.IsMonoRuntimeEnvironment)
                {
                    methodName = "WrapFunctionToDelegate";
                }
#endif
                theCallSite = CallSite <DynamicInvokeWrapFunc> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        methodName,
                        new[] { returnType },
                        typeof(InvocationMapping),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                }));

                _dynamicInvokeWrapFunc[returnType] = theCallSite;
            }
            return((Delegate)theCallSite.Target(theCallSite, typeof(InvocationMapping), functor, length));
        }
        internal static void InvokeMemberActionCallSite(object target, MemberInvocationMoniker name, object[] arguments,
                                                        string[] argumentNames, Type context, bool staticContext,
                                                        ref CallSite callSite)
        {
            LazyBinder binder     = null;
            Type       binderType = null;

            if (callSite == null)
            {
                binder = () =>
                {
                    var argumentBindingList = GetBindingArgumentList(arguments, argumentNames,
                                                                     staticContext);

                    var flag = CSharpBinderFlags.ResultDiscarded;
                    if (name.IsNameSpecial)
                    {
                        flag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    return(Binder.InvokeMember(flag, name.Name, name.GenericArguments,
                                               context, argumentBindingList));
                };
                binderType = typeof(InvokeMemberBinder);
            }

            MemberActionInvoke(ref callSite, binderType, binder, name, staticContext, context, argumentNames, target,
                               arguments);
        }
Пример #7
0
        internal static void InvokeMemberActionCallSite(object target, InvokeMemberName name, object[] args, string[] tArgNames, Type tContext, bool tStaticContext, ref CallSite callSite)
        {
            LazyBinder tBinder     = null;
            Type       tBinderType = null;

            if (callSite == null)
            {
                tBinder = () =>
                {
                    IEnumerable <CSharpArgumentInfo> tList;
                    tList = GetBindingArgumentList(args, tArgNames, tStaticContext);

                    var tFlag = CSharpBinderFlags.ResultDiscarded;
                    if (name.IsSpecialName)
                    {
                        tFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    return(Binder.InvokeMember(tFlag, name.Name, name.GenericArgs,
                                               tContext, tList));
                };
                tBinderType = typeof(InvokeMemberBinder);
            }


            InvokeMemberAction(ref callSite, tBinderType, KnownMember, tBinder, name, tStaticContext, tContext, tArgNames, target, args);
        }
Пример #8
0
 private static CallSiteBinder get_binder()
 {
     return(Binder.InvokeMember(CSharpBinderFlags.None, "Power", null, MethodBase.GetCurrentMethod().DeclaringType, new[]
     {
         CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
         CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)
     }));
 }
Пример #9
0
        internal static CallSite CreateCallSite(
            Type delegateType,
            Type specificBinderType,
            int knownType,
            LazyBinder binder,
            InvokeMemberName name,
            Type context,
            string[] argNames  = null,
            bool staticContext = false,
            bool isEvent       = false

            )
        {
            CallSite <DynamicCreateCallSite> tSite;

            bool foundInCache;

            lock (_callSiteCacheLock)
            {
                foundInCache = DynamicInvokeCreateCallSite.TryGetValue(delegateType, out tSite);
            }

            if (!foundInCache)
            {
                tSite = CallSite <DynamicCreateCallSite> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "CreateCallSite",
                        new[] { delegateType },
                        typeof(InvokeHelper),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),                                                                   // InvokeHelper
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //binderType
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //knownType
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //binder
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //name
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //context
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //argnames
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //staticcontext
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //isevent
                }
                        ));

                lock (_callSiteCacheLock)
                {
                    // another thread might have been faster; add to dictionary only if we are the first
                    if (!DynamicInvokeCreateCallSite.ContainsKey(delegateType))
                    {
                        DynamicInvokeCreateCallSite[delegateType] = tSite;
                    }
                }
            }
            return((CallSite)tSite.Target(tSite, typeof(InvokeHelper), specificBinderType, knownType, binder, name, context, argNames, staticContext, isEvent));
        }
Пример #10
0
 internal static CallSiteBinder GetFunctionCallBinder(string name, int argsCount = 0, bool isStatic = true)
 {
     return(Binder.InvokeMember(CSharpBinderFlags.None,
                                name,
                                null,
                                typeof(object),
                                new[] {
         isStatic
                                         ? CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType, null)
                                         : CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
     }
                                .Concat(GetArgInfo(argsCount))));
 }
Пример #11
0
        private static TDelegate CallInternal <TDelegate>(string memberName, bool isStaticContext, object context, Type[] genericArgs)
        {
            MethodInfo method = GetDelegateMethod <TDelegate>();

            ParameterInfo[] methodParams = method.GetParameters();
            CallSite        callSite     = CallSite.Create(
                CreateDelegateType(method, methodParams),
                Binder.InvokeMember(
                    method.IsVoid() ? CSharpBinderFlags.ResultDiscarded : CSharpBinderFlags.None,
                    memberName, genericArgs ?? Type.EmptyTypes, Context(context), Args(methodParams.Length, isStaticContext)));

            return(CreateDelegateInvokeCallSite <TDelegate>(method, methodParams, callSite));
        }
Пример #12
0
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext, ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        tTargetFlag = CSharpArgumentInfoFlags.None;
                LazyBinder tBinder;
                Type       tBinderType;
                int        tKnownType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var tStaticFlag = CSharpBinderFlags.None;
                    if (Util.IsMono) //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                    {
                        tStaticFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    tBinder = () => Binder.InvokeMember(tStaticFlag, "get_" + name,
                                                        null,
                                                        context,
                                                        new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.IsStaticType |
                            CSharpArgumentInfoFlags.UseCompileTimeType,
                            null)
                    });

                    tBinderType = typeof(InvokeMemberBinder);
                    tKnownType  = KnownMember;
                }
                else
                {
                    tBinder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            tTargetFlag, null)
                    });
                    tBinderType = typeof(GetMemberBinder);
                    tKnownType  = KnownGet;
                }


                callsite = CreateCallSite <Func <CallSite, object, object> >(tBinderType, tKnownType, tBinder, name, context,
                                                                             staticContext: staticContext);
            }
            var tCallSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(tCallSite.Target(tCallSite, target));
        }
Пример #13
0
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext,
                                                 ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        targeflag = CSharpArgumentInfoFlags.None;
                LazyBinder binder;
                Type       binderType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var staticFlag = CSharpBinderFlags.None;
                    if (TypeFactorization.IsMonoRuntimeEnvironment)
                    {
                        //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        staticFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    binder = () => Binder.InvokeMember(staticFlag, "get_" + name,
                                                       null,
                                                       context,
                                                       new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.IsStaticType |
                            CSharpArgumentInfoFlags.UseCompileTimeType,
                            null)
                    });

                    binderType = typeof(InvokeMemberBinder);
                }
                else
                {
                    binder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                    context,
                                                    new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            targeflag, null)
                    });
                    binderType = typeof(GetMemberBinder);
                }

                callsite = CreateCallSite <Func <CallSite, object, object> >(binderType, binder, name, context);
            }
            var callSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(callSite.Target(callSite, target));
        }
Пример #14
0
        private static TDelegate CallInternal <TDelegate>([NotNull] string memberName,
                                                          bool isStaticContext, [CanBeNull] object context, [CanBeNull] Type[] genericArgs)
        {
            if (memberName == null)
            {
                throw new ArgumentNullException(nameof(memberName));
            }
            MethodInfo method = GetDelegateMethod <TDelegate>();

            ParameterInfo[] methodParams = method.GetParameters();
            CallSite        callSite     = CallSite.Create(
                CreateDelegateType(method, methodParams),
                Binder.InvokeMember(
                    method.IsVoid() ? CSharpBinderFlags.ResultDiscarded : CSharpBinderFlags.None,
                    memberName, genericArgs ?? Type.EmptyTypes, Context(context), Args(methodParams.Length, isStaticContext)));

            return(CreateDelegateInvokeCallSite <TDelegate>(method, methodParams, callSite));
        }
Пример #15
0
        internal static dynamic DynamicInvokeStaticMember(
            Type returnType,
            ref CallSite callSite,
            Type binderType,
            LazyBinder binder,
            string name,
            bool staticContext,
            Type context,
            string[] argumentNames,
            Type target, params object[] arguments)
        {
            CallSite <DynamicInvokeMemberConstructorValueType> site;

            if (!_dynamicInvokeMemberSite.TryGetValue(returnType, out site))
            {
                site = CallSite <DynamicInvokeMemberConstructorValueType> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "InvokeMemberTargetType",
                        new[] { typeof(Type), returnType },
                        typeof(InvocationMapping),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType |
                        CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsRef, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                }));

                _dynamicInvokeMemberSite[returnType] = site;
            }

            return(site.Target(site, typeof(InvocationMapping), ref callSite, binderType, binder, name, staticContext,
                               context, argumentNames, target, arguments));
        }
Пример #16
0
        internal static CallSite CreateCallSite(
            Type delegateType,
            Type specificBinderType,
            int knownType,
            LazyBinder binder,
            InvokeMemberName name,
            Type context,
            string[] argNames  = null,
            bool staticContext = false,
            bool isEvent       = false

            )
        {
            CallSite <DynamicCreateCallSite> tSite;

            if (!_dynamicInvokeCreateCallSite.TryGetValue(delegateType, out tSite))
            {
                tSite = CallSite <DynamicCreateCallSite> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "CreateCallSite",
                        new[] { delegateType },
                        typeof(InvokeHelper),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),                                                                   // InvokeHelper
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //binderType
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //knownType
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //binder
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //name
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //context
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //argnames
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //staticcontext
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), //isevent
                }
                        ));

                _dynamicInvokeCreateCallSite[delegateType] = tSite;
            }
            return((CallSite)tSite.Target(tSite, typeof(InvokeHelper), specificBinderType, knownType, binder, name, context, argNames, staticContext, isEvent));
        }
Пример #17
0
        private MethodBindResult BindMethodInternal(string name, Type[] typeArgs, object[] args, object[] bindArgs)
        {
            // create C# member invocation binder
            const CSharpBinderFlags binderFlags = CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded;
            var binder = Binder.InvokeMember(binderFlags, name, typeArgs, accessContext ?? engine.AccessContext, CreateArgInfoEnum(bindArgs));

            // perform default binding
            var binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, target, bindArgs);
            var rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

            var result = MethodBindResult.Create(name, rawResult, target, args);

            if (!(result is MethodBindSuccess) && !(target is HostType) && target.Type.IsInterface)
            {
                // binding through interface failed; try base interfaces
                foreach (var interfaceType in target.Type.GetInterfaces())
                {
                    var tempTarget = HostObject.Wrap(target.InvokeTarget, interfaceType);
                    binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, tempTarget, bindArgs);
                    rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

                    var tempResult = MethodBindResult.Create(name, rawResult, target, args);
                    if (tempResult is MethodBindSuccess)
                    {
                        return(tempResult);
                    }
                }

                // binding through base interfaces failed; try System.Object
                var objectTarget = HostObject.Wrap(target.InvokeTarget, typeof(object));
                binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, objectTarget, bindArgs);
                rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

                var objectResult = MethodBindResult.Create(name, rawResult, target, args);
                if (objectResult is MethodBindSuccess)
                {
                    return(objectResult);
                }
            }

            return(result);
        }
Пример #18
0
        internal static dynamic DynamicInvokeStaticMember(Type tReturn, ref CallSite callsite, Type binderType, int knownType, LazyBinder binder,
                                                          InvokeMemberName name,
                                                          bool staticContext,
                                                          Type context,
                                                          string[] argNames,
                                                          Type target, params object[] args)
        {
            CallSite <DynamicInvokeMemberConstructorValueType> tSite;

            if (!_dynamicInvokeMemberSite.TryGetValue(tReturn, out tSite))
            {
                tSite = CallSite <DynamicInvokeMemberConstructorValueType> .Create(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "InvokeMemberTargetType",
                        new[] { typeof(Type), tReturn },
                        typeof(InvokeHelper),
                        new[]
                {
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType |
                        CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsRef, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
                }
                        )
                    );

                _dynamicInvokeMemberSite[tReturn] = tSite;
            }

            return(tSite.Target(tSite, typeof(InvokeHelper), ref callsite, binderType, knownType, binder, name, staticContext, context, argNames, target, args));
        }
Пример #19
0
        private static MethodBindResult BindMethodCore(Type bindContext, BindingFlags bindFlags, HostTarget target, string name, Type[] typeArgs, object[] args, object[] bindArgs)
        {
            Interlocked.Increment(ref coreBindCount);

            // create C# member invocation binder
            const CSharpBinderFlags binderFlags = CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded;
            var binder = (InvokeMemberBinder)Binder.InvokeMember(binderFlags, name, typeArgs, bindContext, CreateArgInfoEnum(target, bindArgs));

            // perform default binding
            var rawResult = BindMethodRaw(bindFlags, binder, target, bindArgs);

            var result = MethodBindResult.Create(name, rawResult, target, args);

            if ((result is MethodBindFailure) && !(target is HostType) && target.Type.IsInterface)
            {
                // binding through interface failed; try base interfaces
                foreach (var interfaceType in target.Type.GetInterfaces())
                {
                    var baseInterfaceTarget = HostObject.Wrap(target.InvokeTarget, interfaceType);
                    rawResult = BindMethodRaw(bindFlags, binder, baseInterfaceTarget, bindArgs);

                    var baseInterfaceResult = MethodBindResult.Create(name, rawResult, target, args);
                    if (baseInterfaceResult is MethodBindSuccess)
                    {
                        return(baseInterfaceResult);
                    }
                }

                // binding through base interfaces failed; try System.Object
                var objectTarget = HostObject.Wrap(target.InvokeTarget, typeof(object));
                rawResult = BindMethodRaw(bindFlags, binder, objectTarget, bindArgs);

                var objectResult = MethodBindResult.Create(name, rawResult, target, args);
                if (objectResult is MethodBindSuccess)
                {
                    return(objectResult);
                }
            }

            return(result);
        }
Пример #20
0
        internal static object InvokeMemberCallSite(object target, String_OR_InvokeMemberName name, object[] args, string[] tArgNames, Type tContext, bool tStaticContext, ref CallSite callSite)
        {
            LazyBinder tBinder     = null;
            Type       tBinderType = null;

            if (callSite == null)
            {
                tBinder = () => {
                    var tList = GetBindingArgumentList(args, tArgNames, tStaticContext);
                    var tFlag = CSharpBinderFlags.None;
                    if (name.IsSpecialName)
                    {
                        tFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }
                    return(Binder.InvokeMember(tFlag, name.Name, name.GenericArgs,
                                               tContext, tList));
                };
                tBinderType = typeof(InvokeMemberBinder);
            }

            return(InvokeMember <object>(ref callSite, tBinderType, tBinder, name, tStaticContext, tContext, tArgNames, target, args));
        }
Пример #21
0
        private static dynamic BuildCallSite(string methodName, bool wantReturnValue, object[] parameters, IEnumerable <CSharpArgumentInfo> binderArgs)
        {
            // ResultDiscarded is an optimization that the compiler can make at compile time that we
            // cannot determine at runtime. That is to say, I have no idea if the caller will save the
            // result of the invocation (if there is any). This flag has nothing to do with the return
            // type of the target method in this case. If the target bound method's return type actually
            // is void then this is neccessary or we get "Cannot implicitly convert type 'void' to 'object'"
            CallSiteBinder binder = Binder.InvokeMember(
                wantReturnValue ? CSharpBinderFlags.None : CSharpBinderFlags.ResultDiscarded,
                methodName,
                null,
                typeof(DynamicMethodBinder),  // The purpose of this ref is unclear to me.
                binderArgs);

            var typeArgs = new List <Type>
            {
                typeof(CallSite),
                typeof(object)
            };

            if (parameters.Length > 0)
            {
                typeArgs.AddRange(GetTypeArray(parameters));
            }

            if (wantReturnValue)
            {
                typeArgs.Add(typeof(object));
            }

            // returns open generic type Func`n/Action`n
            Type callSiteParameterType = GetFuncOrActionTypeByArity(wantReturnValue, typeArgs.ToArray());
            Type callSiteType          = typeof(CallSite <>).MakeGenericType(callSiteParameterType);

            MethodInfo create   = callSiteType.GetMethod("Create", new[] { typeof(CallSiteBinder) });
            dynamic    callSite = create.Invoke(callSiteType, new object[] { binder });

            return(callSite);
        }
Пример #22
0
        internal static object InvokeSetCallSite(object target, string name, object value, Type context,
                                                 bool staticContext, ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder binder;
                Type       binderType;
                if (staticContext)
                {
                    binder = () =>
                    {
                        var staticFlage = CSharpBinderFlags.ResultDiscarded;

                        //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        if (TypeFactorization.IsMonoRuntimeEnvironment)
                        {
                            staticFlage |= CSharpBinderFlags.InvokeSpecialName;
                        }

                        return(Binder.InvokeMember(staticFlage, "set_" + name,
                                                   null,
                                                   context,
                                                   new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType,
                                null),
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.None,
                                null)
                        }));
                    };

                    binderType = typeof(InvokeMemberBinder);
                    callSite   = CreateCallSite <Action <CallSite, object, object> >(binderType, binder, name, context);
                }
                else
                {
                    binder = () => Binder.SetMember(CSharpBinderFlags.None, name,
                                                    context,
                                                    new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None, null),
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None,
                            null)
                    });

                    binderType = typeof(SetMemberBinder);
                    callSite   = CreateCallSite <Func <CallSite, object, object, object> >(binderType, binder, name, context);
                }
            }

            if (staticContext)
            {
                var staticContextheCallSite = (CallSite <Action <CallSite, object, object> >)callSite;
                staticContextheCallSite.Target(callSite, target, value);
                return(value);
            }
            else
            {
                var cs      = (CallSite <Func <CallSite, object, object, object> >)callSite;
                var tResult = cs.Target(callSite, target, value);
                return(tResult);
            }
        }
Пример #23
0
        internal static object InvokeSetCallSite(object target, string name, object value, Type context, bool staticContext, ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder tBinder;
                Type       tBinderType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    tBinder = () => {
                        var tStaticFlag = CSharpBinderFlags.ResultDiscarded;
                        if (Util.IsMono)             //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        {
                            tStaticFlag |= CSharpBinderFlags.InvokeSpecialName;
                        }

                        return(Binder.InvokeMember(tStaticFlag, "set_" + name,
                                                   null,
                                                   context,
                                                   new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType, null),
                            CSharpArgumentInfo.Create(

                                CSharpArgumentInfoFlags.None

                                , null)
                        }));
                    };

                    tBinderType = typeof(InvokeMemberBinder);
                    callSite    = CreateCallSite <Action <CallSite, object, object> >(tBinderType, KnownMember, tBinder, name, context, staticContext: true);
                }
                else
                {
                    tBinder = () => Binder.SetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None, null),
                        CSharpArgumentInfo.Create(

                            CSharpArgumentInfoFlags.None

                            , null)
                    });


                    tBinderType = typeof(SetMemberBinder);
                    callSite    = CreateCallSite <Func <CallSite, object, object, object> >(tBinderType, KnownSet, tBinder, name, context, staticContext: false);
                }
            }

            if (staticContext)
            {
                var tCallSite = (CallSite <Action <CallSite, object, object> >)callSite;
                tCallSite.Target(callSite, target, value);
                return(value);
            }
            else
            {
                var tCallSite = (CallSite <Func <CallSite, object, object, object> >)callSite;
                var tResult   = tCallSite.Target(callSite, target, value);
                return(tResult);
            }
        }
        private static Func <object, object[], object> CreateNewFuncInvokeDelegate([NotNull] string method, int argCount)
        {
            if (string.IsNullOrEmpty(method))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(method));
            }

            Debug.Assert(argCount >= 0 && argCount <= MaximumArgumentCount);

            var reqTypeList = new Type[argCount + DynamicReservedArgumentCount + 1];
            var argInfoList = new CSharpArgumentInfo[argCount + 1];

            reqTypeList[0] = typeof(CallSite);
            reqTypeList[1] = typeof(object);
            reqTypeList[2] = typeof(object);

            argInfoList[0] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);

            for (var i = 0; i < argCount; i++)
            {
                reqTypeList[i + 3] = typeof(object);
                argInfoList[i + 1] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
            }

            var synthFuncType = Expression.GetFuncType(reqTypeList);
            var callSite      = CallSite.Create(
                synthFuncType,
                Binder.InvokeMember(
                    CSharpBinderFlags.None,
                    method,
                    null,
                    typeof(SimpleDynamicInvoker),
                    argInfoList));

            var field = callSite
                        .GetType()
                        .GetField(nameof(CallSite <object> .Target));

            Debug.Assert(field != null);
            var @delegate = (Delegate)field.GetValue(callSite);

            Debug.Assert(@delegate != null);

            if (argCount == 0)
            {
                return((@object, args) =>
                {
                    Debug.Assert(args == null || args.Length == 0);
                    return @delegate.DynamicInvoke(callSite, @object);
                });
            }

            return((@object, args) =>
            {
                Debug.Assert(args != null && args.Length == argCount);
                var actualArgs = new object[argCount + 2];
                actualArgs[0] = callSite;
                actualArgs[1] = @object;
                Array.Copy(args, 0, actualArgs, actualArgs.Length - argCount, argCount);

                var ret = @delegate.DynamicInvoke(actualArgs);
                return ret;
            });
        }
Пример #25
0
        /// <summary>
        /// Returns an Expression that accesses a member on an Expression
        /// </summary>
        /// <param name="isFunction">Determines whether the member being accessed is a function or a property</param>
        /// <param name="isCall">Determines whether the member returns void</param>
        /// <param name="le">The expression that contains the member to be accessed</param>
        /// <param name="membername">The name of the member to access</param>
        /// <param name="args">Optional list of arguments to be passed if the member is a method</param>
        /// <returns></returns>
        public static Expression MemberAccess(bool isFunction, bool isCall, Expression le, string membername, List <Expression> args)
        {
            var argTypes = args.Select(x => x.Type);

            Expression instance = null;
            Type       type     = null;

            var isDynamic     = false;
            var isRuntimeType = false;

            if (le.Type.Name == "RuntimeType")
            {
                isRuntimeType = true;
                type          = ((Type)((ConstantExpression)le).Value);
            }
            else
            {
                type      = le.Type;
                instance  = le;
                isDynamic = type.IsDynamic();
            }

            if (isFunction)
            {
                if (isDynamic)
                {
                    var expArgs = new List <Expression> {
                        instance
                    };

                    expArgs.AddRange(args);

                    if (isCall)
                    {
                        var binderMC = Binder.InvokeMember(
                            CSharpBinderFlags.ResultDiscarded,
                            membername,
                            null,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        return(Expression.Dynamic(binderMC, typeof(void), expArgs));
                    }

                    var binderM = Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        membername,
                        null,
                        type,
                        expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                        );

                    return(Expression.Dynamic(binderM, typeof(object), expArgs));
                }
                else
                {
                    var mis        = MethodResolution.GetApplicableMembers(type, membername, args);
                    var methodInfo = (MethodInfo)mis[0];

                    if (methodInfo != null)
                    {
                        var parameterInfos = methodInfo.GetParameters();

                        foreach (var parameterInfo in parameterInfos)
                        {
                            var index = parameterInfo.Position;

                            args[index] = TypeConversion.Convert(args[index], parameterInfo.ParameterType);
                        }

                        return(Expression.Call(instance, methodInfo, args.ToArray()));
                    }

                    var match = MethodResolution.GetExactMatch(type, instance, membername, args) ??
                                MethodResolution.GetParamsMatch(type, instance, membername, args);

                    if (match != null)
                    {
                        return(match);
                    }
                }
            }
            else
            {
                if (isDynamic)
                {
                    var binder = Binder.GetMember(
                        CSharpBinderFlags.None,
                        membername,
                        type,
                        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                        );

                    var result = Expression.Dynamic(binder, typeof(object), instance);


                    if (args.Count > 0)
                    {
                        var expArgs = new List <Expression>()
                        {
                            result
                        };

                        expArgs.AddRange(args);

                        var indexedBinder = Binder.GetIndex(
                            CSharpBinderFlags.None,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        result =
                            Expression.Dynamic(indexedBinder, typeof(object), expArgs);
                    }

                    return(result);
                }
                else
                {
                    Expression exp = null;

                    var propertyInfo = type.GetProperty(membername);
                    if (propertyInfo != null)
                    {
                        exp = Expression.Property(instance, propertyInfo);
                    }
                    else
                    {
                        var fieldInfo = type.GetField(membername);
                        if (fieldInfo != null)
                        {
                            exp = Expression.Field(instance, fieldInfo);
                        }
                    }

                    if (exp != null)
                    {
                        if (args.Count > 0)
                        {
                            return(Expression.ArrayAccess(exp, args));
                        }
                        else
                        {
                            return(exp);
                        }
                    }
                }
            }

            throw new Exception(string.Format("Member not found: {0}.{1}", le.Type.Name, membername));
        }
Пример #26
0
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext, ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        tTargetFlag = CSharpArgumentInfoFlags.None;
                LazyBinder tBinder;
                Type       tBinderType;
                int        tKnownType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var tStaticFlag = CSharpBinderFlags.None;
                    if ((target is Type && ((Type)target).GetTypeInfo().IsPublic))
                    {
                        tBinder = () => Binder.InvokeMember(tStaticFlag, "get_" + name,
                                                            null,
                                                            context,
                                                            new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType,
                                null)
                        });

                        tBinderType = typeof(InvokeMemberBinder);
                        tKnownType  = KnownMember;
                    }
                    else
                    {
                        tBinder = () => Binder.GetMember(tStaticFlag, name,
                                                         context,
                                                         new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType, null)
                        });

                        tBinderType = typeof(InvokeMemberBinder);
                        tKnownType  = KnownMember;
                    }
                }
                else
                {
                    tBinder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            tTargetFlag, null)
                    });
                    tBinderType = typeof(GetMemberBinder);
                    tKnownType  = KnownGet;
                }


                callsite = CreateCallSite <Func <CallSite, object, object> >(tBinderType, tKnownType, tBinder, name, context,
                                                                             staticContext: staticContext);
            }
            var tCallSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(tCallSite.Target(tCallSite, target));
        }
Пример #27
0
            private static Action <IInvocation> CompileInvoker(MethodInfo method)
            {
                var methodParameters    = method.GetParameters();
                var invocationParameter = Expression.Parameter(typeof(IInvocation), "invocation");

                var targetAndArgumentInfos = Pack(
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    methodParameters.Select(
                        mp => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name))).ToArray();

                var targetAndArguments = Pack <Expression>(
                    Expression.Property(invocationParameter, invocationParameter.Type, "InvocationTarget"),
                    methodParameters.Select(
                        (mp, index) =>
                        Expression.Convert(
                            Expression.ArrayIndex(
                                Expression.Property(invocationParameter, invocationParameter.Type,
                                                    "Arguments"),
                                Expression.Constant(index)), mp.ParameterType))).ToArray();

                Expression body = null;

                if (method.IsSpecialName)
                {
                    if (method.Name.Equals("get_Item"))
                    {
                        body = Expression.Dynamic(
                            Binder.GetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.Equals("set_Item"))
                    {
                        var targetAndArgumentInfosWithoutTheNameValue = Pack(
                            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                            methodParameters.Select(
                                mp => mp.Name == "value" ? CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) : CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name)));

                        body = Expression.Dynamic(
                            Binder.SetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfosWithoutTheNameValue),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("get_"))
                    {
                        //  Build lambda containing the following call site:
                        //  (IInvocation invocation) => {
                        //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name};
                        //  }
                        body = Expression.Dynamic(
                            Binder.GetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("get_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("set_"))
                    {
                        body = Expression.Dynamic(
                            Binder.SetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("set_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }
                }
                if (body == null)
                {
                    //  Build lambda containing the following call site:
                    //  (IInvocation invocation) => {
                    //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name}(
                    //          {methodParameters[*].Name}: ({methodParameters[*].Type})invocation.Arguments[*],
                    //          ...);
                    //  }


                    body = Expression.Dynamic(
                        Binder.InvokeMember(
                            CSharpBinderFlags.None,
                            method.Name,
                            null,
                            typeof(object),
                            targetAndArgumentInfos),
                        typeof(object),
                        targetAndArguments);
                }

                if (method.ReturnType != typeof(void))
                {
                    body = Expression.Assign(
                        Expression.Property(invocationParameter, invocationParameter.Type, "ReturnValue"),
                        Expression.Convert(body, typeof(object)));
                }

                var lambda = Expression.Lambda <Action <IInvocation> >(body, invocationParameter);

                return(lambda.Compile());
            }