예제 #1
0
파일: DelegateInfo.cs 프로젝트: tmds/corert
        internal DelegateThunkCollection(DelegateInfo owningDelegate)
        {
            _openStaticThunk           = new DelegateInvokeOpenStaticThunk(owningDelegate);
            _multicastThunk            = new DelegateInvokeMulticastThunk(owningDelegate);
            _closedStaticThunk         = new DelegateInvokeClosedStaticThunk(owningDelegate);
            _invokeThunk               = new DelegateDynamicInvokeThunk(owningDelegate);
            _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate);

            // Methods that have a byref-like type in the signature cannot be invoked with the object array thunk.
            // We would need to box the parameter and these can't be boxed.
            MethodSignature delegateSignature        = owningDelegate.Signature;
            bool            generateObjectArrayThunk = true;

            for (int i = 0; i < delegateSignature.Length; i++)
            {
                TypeDesc paramType = delegateSignature[i];
                if (paramType.IsByRef)
                {
                    paramType = ((ByRefType)paramType).ParameterType;
                }
                if (!paramType.IsSignatureVariable && paramType.IsByRefLike)
                {
                    generateObjectArrayThunk = false;
                    break;
                }
            }
            TypeDesc normalizedReturnType = delegateSignature.ReturnType;

            if (normalizedReturnType.IsByRef)
            {
                normalizedReturnType = ((ByRefType)normalizedReturnType).ParameterType;
            }
            if (!normalizedReturnType.IsSignatureVariable && normalizedReturnType.IsByRefLike)
            {
                generateObjectArrayThunk = false;
            }

            if (generateObjectArrayThunk)
            {
                _invokeObjectArrayThunk = new DelegateInvokeObjectArrayThunk(owningDelegate);
            }

            if (!owningDelegate.Type.HasInstantiation && IsNativeCallingConventionCompatible(delegateSignature))
            {
                _reversePInvokeThunk = new DelegateReversePInvokeThunk(owningDelegate);
            }

            if (delegateSignature.Length > 0)
            {
                TypeDesc firstParam = delegateSignature[0];

                bool generateOpenInstanceMethod;

                switch (firstParam.Category)
                {
                case TypeFlags.Pointer:
                case TypeFlags.FunctionPointer:
                    generateOpenInstanceMethod = false;
                    break;

                case TypeFlags.ByRef:
                    firstParam = ((ByRefType)firstParam).ParameterType;
                    generateOpenInstanceMethod = firstParam.IsSignatureVariable || firstParam.IsValueType;
                    break;

                case TypeFlags.Array:
                case TypeFlags.SzArray:
                case TypeFlags.SignatureTypeVariable:
                    generateOpenInstanceMethod = true;
                    break;

                default:
                    Debug.Assert(firstParam.IsDefType);
                    generateOpenInstanceMethod = !firstParam.IsValueType;
                    break;
                }

                if (generateOpenInstanceMethod)
                {
                    _openInstanceThunk = new DelegateInvokeOpenInstanceThunk(owningDelegate);
                }
            }
        }
예제 #2
0
 internal DelegateThunkCollection(DelegateInfo owningDelegate)
 {
     _openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate);
     _multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate);
     _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate);
 }
예제 #3
0
 internal DelegateThunkCollection(DelegateInfo owningDelegate)
 {
     _openStaticThunk   = new DelegateInvokeOpenStaticThunk(owningDelegate);
     _multicastThunk    = new DelegateInvokeMulticastThunk(owningDelegate);
     _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate);
 }
예제 #4
0
        internal DelegateThunkCollection(DelegateInfo owningDelegate)
        {
            _openStaticThunk           = new DelegateInvokeOpenStaticThunk(owningDelegate);
            _multicastThunk            = new DelegateInvokeMulticastThunk(owningDelegate);
            _closedStaticThunk         = new DelegateInvokeClosedStaticThunk(owningDelegate);
            _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate);

            // Methods that have a byref-like type in the signature cannot be invoked with the object array thunk.
            // We would need to box the parameter and these can't be boxed.
            // Neither can be methods that have pointers in the signature.
            MethodSignature delegateSignature        = owningDelegate.Signature;
            bool            generateObjectArrayThunk = true;

            for (int i = 0; i < delegateSignature.Length; i++)
            {
                TypeDesc paramType = delegateSignature[i];
                if (paramType.IsByRef)
                {
                    paramType = ((ByRefType)paramType).ParameterType;
                }
                if (!paramType.IsSignatureVariable && paramType.IsByRefLike)
                {
                    generateObjectArrayThunk = false;
                    break;
                }
                if (paramType.IsPointer || paramType.IsFunctionPointer)
                {
                    generateObjectArrayThunk = false;
                    break;
                }
            }
            TypeDesc returnType = delegateSignature.ReturnType;

            if (returnType.IsByRef)
            {
                generateObjectArrayThunk = false;
            }
            if (!returnType.IsSignatureVariable && returnType.IsByRefLike)
            {
                generateObjectArrayThunk = false;
            }
            if (returnType.IsPointer || returnType.IsFunctionPointer)
            {
                generateObjectArrayThunk = false;
            }

            if ((owningDelegate.SupportedFeatures & DelegateFeature.ObjectArrayThunk) != 0 && generateObjectArrayThunk)
            {
                _invokeObjectArrayThunk = new DelegateInvokeObjectArrayThunk(owningDelegate);
            }

            //
            // Check whether we have an open instance thunk
            //

            if ((owningDelegate.SupportedFeatures & DelegateFeature.OpenInstanceThunk) != 0 && delegateSignature.Length > 0)
            {
                TypeDesc firstParam = delegateSignature[0];

                bool generateOpenInstanceMethod;

                switch (firstParam.Category)
                {
                case TypeFlags.Pointer:
                case TypeFlags.FunctionPointer:
                    generateOpenInstanceMethod = false;
                    break;

                case TypeFlags.ByRef:
                    firstParam = ((ByRefType)firstParam).ParameterType;
                    generateOpenInstanceMethod = firstParam.IsSignatureVariable || firstParam.IsValueType;
                    break;

                case TypeFlags.Array:
                case TypeFlags.SzArray:
                case TypeFlags.SignatureTypeVariable:
                    generateOpenInstanceMethod = true;
                    break;

                default:
                    Debug.Assert(firstParam.IsDefType);
                    generateOpenInstanceMethod = !firstParam.IsValueType;
                    break;
                }

                if (generateOpenInstanceMethod)
                {
                    _openInstanceThunk = new DelegateInvokeOpenInstanceThunk(owningDelegate);
                }
            }
        }
예제 #5
0
 internal DelegateThunkCollection(DelegateInfo owningDelegate)
 {
     _openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate);
     _multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate);
     _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate);
     _invokeThunk = new DelegateDynamicInvokeThunk(owningDelegate);
     _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate);
 }