// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using Internal.IL; using Internal.IL.Stubs; using Debug = System.Diagnostics.Debug; using System.Threading; namespace Internal.TypeSystem.Interop { /// /// This generates a class which inherits from System.Runtime.InteropServices.NativeFunctionPointerWrapper. It has a constructror and /// a second instance method which marshalls arguments in the forward direction in order to call the native function pointer. /// public partial class PInvokeDelegateWrapper : MetadataType { // The type of delegate that will be created from the native function pointer public MetadataType DelegateType { get; } public override ModuleDesc Module { get; } public override string Name { get { return "PInvokeDelegateWrapper__" + DelegateType.Name; } } public override string DiagnosticName { get { return "PInvokeDelegateWrapper__" + DelegateType.DiagnosticName; } } public override string Namespace { get { return "Internal.CompilerGenerated"; } } public override string DiagnosticNamespace { get { return "Internal.CompilerGenerated"; } } public override bool IsExplicitLayout { get { return false; } } public override PInvokeStringFormat PInvokeStringFormat { get { return PInvokeStringFormat.AnsiClass; } } public override bool IsSequentialLayout { get { return false; } } public override bool IsBeforeFieldInit { get { return false; } } public override MetadataType MetadataBaseType { get { return InteropTypes.GetNativeFunctionPointerWrapper(Context); } } public override DefType BaseType { get { return InteropTypes.GetNativeFunctionPointerWrapper(Context); } } public override bool IsSealed { get { return true; } } public override bool IsAbstract { get { return false; } } public override DefType ContainingType { get { return null; } } public override DefType[] ExplicitlyImplementedInterfaces { get { return Array.Empty(); } } public override TypeSystemContext Context { get { return DelegateType.Context; } } private InteropStateManager _interopStateManager; public PInvokeDelegateWrapper(ModuleDesc owningModule, MetadataType delegateType, InteropStateManager interopStateManager) { Debug.Assert(delegateType.IsDelegate); Module = owningModule; DelegateType = delegateType; _interopStateManager = interopStateManager; } public override ClassLayoutMetadata GetClassLayout() { return default(ClassLayoutMetadata); } public override bool HasCustomAttribute(string attributeNamespace, string attributeName) { return false; } public override IEnumerable GetNestedTypes() { return Array.Empty(); } public override MetadataType GetNestedType(string name) { return null; } protected override MethodImplRecord[] ComputeVirtualMethodImplsForType() { return Array.Empty(); } public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string name) { return Array.Empty(); } private int _hashCode; private void InitializeHashCode() { var hashCodeBuilder = new Internal.NativeFormat.TypeHashingAlgorithms.HashCodeBuilder(Namespace); if (Namespace.Length > 0) { hashCodeBuilder.Append("."); } hashCodeBuilder.Append(Name); _hashCode = hashCodeBuilder.ToHashCode(); } public override int GetHashCode() { if (_hashCode == 0) { InitializeHashCode(); } return _hashCode; } protected override TypeFlags ComputeTypeFlags(TypeFlags mask) { TypeFlags flags = 0; if ((mask & TypeFlags.HasGenericVarianceComputed) != 0) { flags |= TypeFlags.HasGenericVarianceComputed; } if ((mask & TypeFlags.CategoryMask) != 0) { flags |= TypeFlags.Class; } flags |= TypeFlags.HasFinalizerComputed; flags |= TypeFlags.AttributeCacheComputed; return flags; } private MethodDesc[] _methods; private void InitializeMethods() { MethodDesc[] methods = new MethodDesc[] { new PInvokeDelegateWrapperConstructor(this), // Constructor new DelegateMarshallingMethodThunk(DelegateType, this, _interopStateManager, DelegateMarshallingMethodThunkKind.ForwardNativeFunctionWrapper) // a forward marshalling instance method }; Interlocked.CompareExchange(ref _methods, methods, null); } public override IEnumerable GetMethods() { if (_methods == null) { InitializeMethods(); } return _methods; } public MethodDesc GetPInvokeDelegateWrapperMethod(PInvokeDelegateWrapperMethodKind kind) { if (_methods == null) { InitializeMethods(); } Debug.Assert((int)kind < _methods.Length); return _methods[(int)kind]; } } public enum PInvokeDelegateWrapperMethodKind : byte { Constructor = 0, Invoke = 1 } }