Example #1
0
        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);
                }
            }
        }
Example #2
0
        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));
        }
Example #3
0
        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());
        }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        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));
        }
Example #6
0
 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;
         }
     }
 }
Example #7
0
 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;
         }
     }
 }