Skip to content

Commit

Permalink
Add the CustomTypeMarshallerAttribute type to make it easier to ident…
Browse files Browse the repository at this point in the history
…ify marshaller types (dotnet#65591)
  • Loading branch information
jkoritzinsky authored and radekdoulik committed Mar 30, 2022
1 parent ce47347 commit 969b939
Show file tree
Hide file tree
Showing 65 changed files with 5,337 additions and 3,147 deletions.
187 changes: 116 additions & 71 deletions docs/design/libraries/LibraryImportGenerator/SpanMarshallers.md

Large diffs are not rendered by default.

170 changes: 116 additions & 54 deletions docs/design/libraries/LibraryImportGenerator/StructMarshalling.md

Large diffs are not rendered by default.

27 changes: 12 additions & 15 deletions docs/project/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,15 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
| __`SYSLIB1052`__ | Specified configuration is not supported by source-generated P/Invokes |
| __`SYSLIB1053`__ | Current target framework is not supported by source-generated P/Invokes |
| __`SYSLIB1054`__ | Specified LibraryImportAttribute arguments cannot be forwarded to DllImportAttribute |
| __`SYSLIB1055`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1056`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1057`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1058`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1059`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1060`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1061`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1062`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1063`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1064`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1065`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1066`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1067`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1068`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1069`__ | *_`SYSLIB1055`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1055`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1056`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1057`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1058`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1059`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1060`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1061`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1062`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1063`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1064`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1065`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
| __`SYSLIB1066`__ | *_`SYSLIB1055`-`SYSLIB1066` reserved for Microsoft.Interop.LibraryImportGenerator._* |
9 changes: 8 additions & 1 deletion eng/generators.targets
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@
Include="$(CoreLibSharedDir)System\Runtime\InteropServices\StringMarshalling.cs" />

<!-- Only add the following files if we are on the latest TFM (that is, net7). -->
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'" Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedMarshallingAttribute.cs" />
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'"
Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedMarshallingAttribute.cs" />
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'"
Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\CustomTypeMarshallerKind.cs" />
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'"
Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\CustomTypeMarshallerDirection.cs" />
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'"
Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\CustomTypeMarshallerFeatures.cs" />

<!-- Only add the following files if we are on the latest TFM (that is, net7) and the project is SPCL or has references to System.Runtime.CompilerServices.Unsafe and System.Memory -->
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal enum ClassLibFunctionId
IDynamicCastableGetInterfaceImplementation = 9,
}

internal static partial class InternalCalls
internal static class InternalCalls
{
//
// internalcalls for System.GC.
Expand All @@ -59,24 +59,24 @@ internal static void RhCollect(int generation, InternalGCCollectionMode mode)
RhpCollect(generation, mode);
}

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
private static partial void RhpCollect(int generation, InternalGCCollectionMode mode);
private static extern void RhpCollect(int generation, InternalGCCollectionMode mode);

[RuntimeExport("RhGetGcTotalMemory")]
internal static long RhGetGcTotalMemory()
{
return RhpGetGcTotalMemory();
}

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
private static partial long RhpGetGcTotalMemory();
private static extern long RhpGetGcTotalMemory();

[RuntimeExport("RhStartNoGCRegion")]
internal static int RhStartNoGCRegion(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC)
{
return RhpStartNoGCRegion(totalSize, hasLohSize, lohSize, disallowFullBlockingGC);
return RhpStartNoGCRegion(totalSize, hasLohSize ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, lohSize, disallowFullBlockingGC ? Interop.BOOL.TRUE : Interop.BOOL.FALSE);
}

[RuntimeExport("RhEndNoGCRegion")]
Expand Down Expand Up @@ -282,53 +282,55 @@ internal static extern unsafe bool RhpCallFilterFunclet(
// These either do not need to be called in cooperative mode or, in some cases, MUST be called in preemptive
// mode. Note that they must use the Cdecl calling convention due to a limitation in our .obj file linking
// support.
// We use DllImport here instead of DllImport as we don't want to add a dependency on source-generated
// interop support to Test.CoreLib.
//------------------------------------------------------------------------------------------------------------

// Block the current thread until at least one object needs to be finalized (returns true) or
// memory is low (returns false and the finalizer thread should initiate a garbage collection).
[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial uint RhpWaitForFinalizerRequest();
internal static extern uint RhpWaitForFinalizerRequest();

// Indicate that the current round of finalizations is complete.
[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhpSignalFinalizationComplete();
internal static extern void RhpSignalFinalizationComplete();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhpAcquireCastCacheLock();
internal static extern void RhpAcquireCastCacheLock();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhpReleaseCastCacheLock();
internal static extern void RhpReleaseCastCacheLock();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial ulong RhpGetTickCount64();
internal static extern ulong RhpGetTickCount64();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhpAcquireThunkPoolLock();
internal static extern void RhpAcquireThunkPoolLock();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhpReleaseThunkPoolLock();
internal static extern void RhpReleaseThunkPoolLock();

[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial IntPtr RhAllocateThunksMapping();
internal static extern IntPtr RhAllocateThunksMapping();

// Enters a no GC region, possibly doing a blocking GC if there is not enough
// memory available to satisfy the caller's request.
[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial int RhpStartNoGCRegion(long totalSize, [MarshalAs(UnmanagedType.Bool)] bool hasLohSize, long lohSize, [MarshalAs(UnmanagedType.Bool)] bool disallowFullBlockingGC);
internal static extern int RhpStartNoGCRegion(long totalSize, Interop.BOOL hasLohSize, long lohSize, Interop.BOOL disallowFullBlockingGC);

// Exits a no GC region, possibly doing a GC to clean up the garbage that
// the caller allocated.
[LibraryImport(Redhawk.BaseName)]
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial int RhpEndNoGCRegion();
internal static extern int RhpEndNoGCRegion();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

namespace System.Runtime.InteropServices
{
// Included because the C# compiler requires it for the unmanaged constraint
public enum UnmanagedType
{
Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,10 @@ public static unsafe int RhGetCurrentThreadStackTrace(IntPtr[] outputBuffer)
return RhpGetCurrentThreadStackTrace(pOutputBuffer, (uint)((outputBuffer != null) ? outputBuffer.Length : 0), new UIntPtr(&pOutputBuffer));
}

[LibraryImport(Redhawk.BaseName)]
// Use DllImport here instead of LibraryImport because this file is used by Test.CoreLib.
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
private static unsafe partial int RhpGetCurrentThreadStackTrace(IntPtr* pOutputBuffer, uint outputBufferLength, UIntPtr addressInCurrentFrame);
private static unsafe extern int RhpGetCurrentThreadStackTrace(IntPtr* pOutputBuffer, uint outputBufferLength, UIntPtr addressInCurrentFrame);

// Worker for RhGetCurrentThreadStackTrace. RhGetCurrentThreadStackTrace just allocates a transition
// frame that will be used to seed the stack trace and this method does all the real work.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ internal static unsafe object RhNewObject(EETypePtr pEEType)
internal static unsafe Array RhNewArray(EETypePtr pEEType, int length)
=> RhNewArray(pEEType.ToPointer(), length);

[LibraryImport(RuntimeLibrary)]
internal static unsafe partial void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult);
[DllImport(RuntimeLibrary)]
internal static unsafe extern void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult);

[MethodImpl(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhpFallbackFailFast")]
Expand Down
14 changes: 6 additions & 8 deletions src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<TargetFramework>netstandard2.0</TargetFramework>
<EnableLibraryImportGenerator>true</EnableLibraryImportGenerator>
<!--
SYSLIB1053: LibraryImportGenerator Target Framework Not Supported.
-->
<NoWarn>$(NoWarn);SYSLIB1053</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DefineConstants>FEATURE_GC_STRESS;$(DefineConstants)</DefineConstants>
Expand All @@ -33,6 +28,9 @@
<IntermediatesDir>$(ArtifactsObjDir)\coreclr\$(TargetOS).$(TargetArchitecture).$(CoreCLRConfiguration)</IntermediatesDir>
<IntermediatesDir Condition="'$(Ninja)' == 'false' and $([MSBuild]::IsOsPlatform('Windows'))">$(IntermediatesDir)\ide</IntermediatesDir>
</PropertyGroup>
<PropertyGroup>
<CommonPath>$([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'Common', 'src'))</CommonPath>
</PropertyGroup>
<ItemGroup Condition="'$(InPlaceRuntime)' == 'true'">
<Compile Include="..\..\Runtime.Base\src\System\Runtime\CachedInterfaceDispatch.cs">
<Link>Runtime.Base\src\System\Runtime\CachedInterfaceDispatch.cs</Link>
Expand Down Expand Up @@ -67,9 +65,6 @@
<Compile Include="..\..\Runtime.Base\src\System\Runtime\TypeCast.cs">
<Link>Runtime.Base\src\System\Runtime\TypeCast.cs</Link>
</Compile>
<Compile Include="..\..\Runtime.Base\src\System\Runtime\InteropServices\MarshalAsAttribute.cs">
<Link>Runtime.Base\src\System\Runtime\InteropServices\MarshalAsAttribute.cs</Link>
</Compile>
<Compile Include="..\..\Runtime.Base\src\System\Runtime\InteropServices\UnsafeGCHandle.cs">
<Link>Runtime.Base\src\System\Runtime\InteropServices\UnsafeGCHandle.cs</Link>
</Compile>
Expand All @@ -82,6 +77,9 @@
<Compile Include="$(AotCommonPath)\Internal\Runtime\TransitionBlock.cs">
<Link>Common\TransitionBlock.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\Interop.BOOL.cs">
<Link>Common\Interop\Windows\Interop.BOOL.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(InPlaceRuntime)' == 'true'">
<Compile Include="$(IntermediatesDir)\nativeaot\Runtime\Full\AsmOffsets.cs" />
Expand Down
15 changes: 9 additions & 6 deletions src/libraries/Common/src/Interop/Interop.Ldap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ internal struct SEC_WINNT_AUTH_IDENTITY_EX
public string packageList;
public int packageListLength;

#if NET7_0_OR_GREATER
[CustomTypeMarshaller(typeof(SEC_WINNT_AUTH_IDENTITY_EX), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
#endif
[StructLayout(LayoutKind.Sequential)]
internal struct Native
{
Expand Down Expand Up @@ -173,6 +176,7 @@ internal sealed class BerVal
public IntPtr bv_val = IntPtr.Zero;

#if NET7_0_OR_GREATER
[CustomTypeMarshaller(typeof(BerVal), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.TwoStageMarshalling)]
internal unsafe struct PinningMarshaller
{
private readonly BerVal _managed;
Expand All @@ -183,7 +187,7 @@ public PinningMarshaller(BerVal managed)

public ref int GetPinnableReference() => ref (_managed is null ? ref Unsafe.NullRef<int>() : ref _managed.bv_len);

public void* Value => Unsafe.AsPointer(ref GetPinnableReference());
public void* ToNativeValue() => Unsafe.AsPointer(ref GetPinnableReference());
}
#endif
}
Expand Down Expand Up @@ -211,6 +215,7 @@ internal struct LdapReferralCallback
#if NET7_0_OR_GREATER
public static readonly unsafe int Size = sizeof(Marshaller.Native);

[CustomTypeMarshaller(typeof(LdapReferralCallback), Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling)]
public unsafe struct Marshaller
{
public unsafe struct Native
Expand All @@ -234,11 +239,9 @@ public Marshaller(LdapReferralCallback managed)
_native.dereference = managed.dereference is not null ? Marshal.GetFunctionPointerForDelegate(managed.dereference) : IntPtr.Zero;
}

public Native Value
{
get => _native;
set => _native = value;
}
public Native ToNativeValue() => _native;

public void FromNativeValue(Native value) => _native = value;

public LdapReferralCallback ToManaged()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal struct MARSHALLED_UNICODE_STRING
internal ushort MaximumLength;
internal string Buffer;

[CustomTypeMarshaller(typeof(MARSHALLED_UNICODE_STRING), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
public struct Native
{
internal ushort Length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal struct CRYPTUI_VIEWCERTIFICATE_STRUCTW
internal uint nStartPage;

#if NET7_0_OR_GREATER
[CustomTypeMarshaller(typeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW), Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
internal unsafe struct Native
{
private uint dwSize;
Expand Down Expand Up @@ -139,6 +140,7 @@ internal struct CRYPTUI_SELECTCERTIFICATE_STRUCTW
internal IntPtr hSelectedCertStore;

#if NET7_0_OR_GREATER
[CustomTypeMarshaller(typeof(CRYPTUI_SELECTCERTIFICATE_STRUCTW), Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
internal unsafe struct Native
{
private uint dwSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ internal struct HttpHeader
internal string Value;
internal uint ValueLength;

[CustomTypeMarshaller(typeof(HttpHeader), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
internal struct Native
{
private IntPtr Name;
Expand Down
Loading

0 comments on commit 969b939

Please sign in to comment.