private int CompareTo(DynamicInvokeMethodThunk otherMethod)
        {
            int result = _targetSignature.Length - otherMethod._targetSignature.Length;

            if (result != 0)
            {
                return(result);
            }

            result = (_targetSignature.HasReturnValue ? 1 : 0) - (otherMethod._targetSignature.HasReturnValue ? 1 : 0);
            if (result != 0)
            {
                return(result);
            }

            for (int i = 0; i < _targetSignature.Length; i++)
            {
                result = (int)_targetSignature[i] - (int)otherMethod._targetSignature[i];
                if (result != 0)
                {
                    return(result);
                }
            }

            Debug.Assert(this == otherMethod);
            return(0);
        }
Beispiel #2
0
        private int CompareTo(DynamicInvokeMethodThunk otherMethod)
        {
            int result = _targetSignature.Length - otherMethod._targetSignature.Length;

            if (result != 0)
            {
                return(result);
            }

            DynamicInvokeMethodParameterKind thisReturnType = _targetSignature.ReturnType;

            result = (int)thisReturnType - (int)otherMethod._targetSignature.ReturnType;
            if (result != 0)
            {
                return(result);
            }

            if (thisReturnType == DynamicInvokeMethodParameterKind.Pointer)
            {
                result = _targetSignature.GetNumerOfReturnTypePointerIndirections() - otherMethod._targetSignature.GetNumerOfReturnTypePointerIndirections();
                if (result != 0)
                {
                    return(result);
                }
            }

            for (int i = 0; i < _targetSignature.Length; i++)
            {
                DynamicInvokeMethodParameterKind thisParamType = _targetSignature[i];
                result = (int)thisParamType - (int)otherMethod._targetSignature[i];
                if (result != 0)
                {
                    return(result);
                }

                if (thisParamType == DynamicInvokeMethodParameterKind.Pointer)
                {
                    result = _targetSignature.GetNumberOfParameterPointerIndirections(i) - otherMethod._targetSignature.GetNumberOfParameterPointerIndirections(i);
                    if (result != 0)
                    {
                        return(result);
                    }
                }
            }

            Debug.Assert(this == otherMethod);
            return(0);
        }
 public DynamicInvokeMethodSignature(MethodSignature concreteSignature)
 {
     Debug.Assert(DynamicInvokeMethodThunk.SupportsSignature(concreteSignature));
     _signature = concreteSignature;
 }
 public DynamicInvokeThunkGenericParameter(DynamicInvokeMethodThunk owningMethod, int index)
 {
     _owningMethod = owningMethod;
     Index         = index;
 }
Beispiel #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));
        }