internal static Instruction CreateDynamicInstruction(Type delegateType, CallSiteBinder binder)
        {
            Func <CallSiteBinder, Instruction> factory;

            lock (s_factories)
            {
                if (!s_factories.TryGetValue(delegateType, out factory))
                {
                    if (delegateType.GetMethod("Invoke").ReturnType == typeof(void))
                    {
                        // TODO: We should generally support void returning binders but the only
                        // ones that exist are delete index/member who's perf isn't that critical.
                        return(new DynamicInstructionN(delegateType, CallSite.Create(delegateType, binder), true));
                    }

                    Type instructionType = DynamicInstructionN.GetDynamicInstructionType(delegateType);
                    if (instructionType == null)
                    {
                        return(new DynamicInstructionN(delegateType, CallSite.Create(delegateType, binder)));
                    }

                    factory =
                        (Func <CallSiteBinder, Instruction>)
                        instructionType.GetMethod("Factory").CreateDelegate(typeof(Func <CallSiteBinder, Instruction>));

                    s_factories[delegateType] = factory;
                }
            }
            return(factory(binder));
        }
Example #2
0
        internal static Instruction CreateDynamicInstruction(Type delegateType, CallSiteBinder binder)
        {
            Func <CallSiteBinder, Instruction> func = null;
            Instruction dynamicInstructionN;

            lock (InstructionList._factories)
            {
                if (!InstructionList._factories.TryGetValue(delegateType, out func))
                {
                    if (delegateType.GetMethod("Invoke").ReturnType != typeof(void))
                    {
                        Type dynamicInstructionType = DynamicInstructionN.GetDynamicInstructionType(delegateType);
                        if (dynamicInstructionType != null)
                        {
                            func = (Func <CallSiteBinder, Instruction>)Delegate.CreateDelegate(typeof(Func <CallSiteBinder, Instruction>), dynamicInstructionType.GetMethod("Factory"));
                            InstructionList._factories[delegateType] = func;
                        }
                        else
                        {
                            dynamicInstructionN = new DynamicInstructionN(delegateType, CallSite.Create(delegateType, binder));
                            return(dynamicInstructionN);
                        }
                    }
                    else
                    {
                        dynamicInstructionN = new DynamicInstructionN(delegateType, CallSite.Create(delegateType, binder), true);
                        return(dynamicInstructionN);
                    }
                }
                return(func(binder));
            }
            return(dynamicInstructionN);
        }