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); } } }
internal DelegateThunkCollection(DelegateInfo owningDelegate) { _openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate); _multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate); _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate); }
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); } } }
internal DelegateThunkCollection(DelegateInfo owningDelegate) { _openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate); _multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate); _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate); _invokeThunk = new DelegateDynamicInvokeThunk(owningDelegate); _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate); }