public MethodDesc this[DelegateThunkKind kind] { get { switch (kind) { case DelegateThunkKind.OpenStaticThunk: return(_openStaticThunk); case DelegateThunkKind.MulticastThunk: return(_multicastThunk); case DelegateThunkKind.ClosedStaticThunk: return(_closedStaticThunk); case DelegateThunkKind.ClosedInstanceThunkOverGenericMethod: return(_closedInstanceOverGeneric); case DelegateThunkKind.ObjectArrayThunk: return(_invokeObjectArrayThunk); case DelegateThunkKind.OpenInstanceThunk: return(_openInstanceThunk); default: return(null); } } }
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); ILCodeLabel returnNullLabel = emitter.NewCodeLabel(); ILCodeLabel[] labels = new ILCodeLabel[(int)DelegateThunkCollection.MaxThunkKind]; for (DelegateThunkKind i = 0; i < DelegateThunkCollection.MaxThunkKind; i++) { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk != null) { labels[(int)i] = emitter.NewCodeLabel(); } else { labels[(int)i] = returnNullLabel; } } codeStream.EmitLdArg(1); codeStream.EmitSwitch(labels); codeStream.Emit(ILOpcode.br, returnNullLabel); for (DelegateThunkKind i = 0; i < DelegateThunkCollection.MaxThunkKind; i++) { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk == null) { continue; } MethodDesc targetMethod = thunk.InstantiateAsOpen(); codeStream.EmitLabel(labels[(int)i]); codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(targetMethod)); codeStream.Emit(ILOpcode.ret); } codeStream.EmitLabel(returnNullLabel); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.conv_i); codeStream.Emit(ILOpcode.ret); return(emitter.Link(this)); }
public override MethodIL EmitIL() { const DelegateThunkKind maxThunkKind = DelegateThunkKind.ObjectArrayThunk; ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); ILCodeLabel returnNullLabel = emitter.NewCodeLabel(); ILCodeLabel[] labels = new ILCodeLabel[(int)maxThunkKind]; for (DelegateThunkKind i = 0; i < maxThunkKind; i++) { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk != null) { labels[(int)i] = emitter.NewCodeLabel(); } else { labels[(int)i] = returnNullLabel; } } codeStream.EmitLdArg(1); codeStream.EmitSwitch(labels); codeStream.Emit(ILOpcode.br, returnNullLabel); for (DelegateThunkKind i = 0; i < maxThunkKind; i++) { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk != null) { codeStream.EmitLabel(labels[(int)i]); codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(thunk.InstantiateAsOpen())); codeStream.Emit(ILOpcode.ret); } } codeStream.EmitLabel(returnNullLabel); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.conv_i); codeStream.Emit(ILOpcode.ret); return(emitter.Link()); }
public MethodDesc this[DelegateThunkKind kind] { get { switch (kind) { case DelegateThunkKind.OpenStaticThunk: return(_openStaticThunk); case DelegateThunkKind.MulticastThunk: return(_multicastThunk); case DelegateThunkKind.ClosedStaticThunk: return(_closedStaticThunk); default: return(null); } } }
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); ILCodeLabel returnNullLabel = emitter.NewCodeLabel(); bool hasDynamicInvokeThunk = (_delegateInfo.SupportedFeatures & DelegateFeature.DynamicInvoke) != 0 && DynamicInvokeMethodThunk.SupportsSignature(_delegateInfo.Signature); ILCodeLabel[] labels = new ILCodeLabel[(int)DelegateThunkCollection.MaxThunkKind]; for (DelegateThunkKind i = 0; i < DelegateThunkCollection.MaxThunkKind; i++) { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk != null || (i == DelegateThunkKind.DelegateInvokeThunk && hasDynamicInvokeThunk)) { labels[(int)i] = emitter.NewCodeLabel(); } else { labels[(int)i] = returnNullLabel; } } codeStream.EmitLdArg(1); codeStream.EmitSwitch(labels); codeStream.Emit(ILOpcode.br, returnNullLabel); for (DelegateThunkKind i = 0; i < DelegateThunkCollection.MaxThunkKind; i++) { MethodDesc targetMethod = null; // Dynamic invoke thunk is special since we're calling into a shared helper if (i == DelegateThunkKind.DelegateInvokeThunk && hasDynamicInvokeThunk) { Debug.Assert(_delegateInfo.Thunks[i] == null); var sig = new DynamicInvokeMethodSignature(_delegateInfo.Signature); MethodDesc thunk = Context.GetDynamicInvokeThunk(sig); if (thunk.HasInstantiation) { TypeDesc[] inst = DynamicInvokeMethodThunk.GetThunkInstantiationForMethod(_delegateInfo.Type.InstantiateAsOpen().GetMethod("Invoke", null)); targetMethod = Context.GetInstantiatedMethod(thunk, new Instantiation(inst)); } else { targetMethod = thunk; } } else { MethodDesc thunk = _delegateInfo.Thunks[i]; if (thunk != null) { targetMethod = thunk.InstantiateAsOpen(); } } if (targetMethod != null) { codeStream.EmitLabel(labels[(int)i]); codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(targetMethod)); codeStream.Emit(ILOpcode.ret); } } codeStream.EmitLabel(returnNullLabel); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.conv_i); codeStream.Emit(ILOpcode.ret); return(emitter.Link(this)); }
public MethodDesc this[DelegateThunkKind kind] { get { switch (kind) { case DelegateThunkKind.OpenStaticThunk: return _openStaticThunk; case DelegateThunkKind.MulticastThunk: return _multicastThunk; case DelegateThunkKind.ClosedStaticThunk: return _closedStaticThunk; default: return null; } } }
public MethodDesc this[DelegateThunkKind kind] { get { switch (kind) { case DelegateThunkKind.OpenStaticThunk: return _openStaticThunk; case DelegateThunkKind.MulticastThunk: return _multicastThunk; case DelegateThunkKind.ClosedStaticThunk: return _closedStaticThunk; case DelegateThunkKind.DelegateInvokeThunk: return _invokeThunk; case DelegateThunkKind.ClosedInstanceThunkOverGenericMethod: return _closedInstanceOverGeneric; default: return null; } } }