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)); }
public virtual void AddInstructions(LightCompiler compiler) { Instruction instr = DynamicInstructionN.CreateUntypedInstruction(_binder, ArgumentCount); if (instr == null) { var lightBinder = _binder as ILightCallSiteBinder; if (lightBinder == null || !lightBinder.AcceptsArgumentArray) { compiler.Compile(Reduce()); return; } Debug.Assert(Type == typeof(object)); instr = new DynamicSplatInstruction(ArgumentCount, CallSite <Func <CallSite, ArgumentArray, object> > .Create(_binder)); } for (int i = 0; i < ArgumentCount; i++) { compiler.Compile(GetArgument(i)); } compiler.Instructions.Emit(instr); }