Skip to content

Commit

Permalink
Add InlineArrayAttribute polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Nov 22, 2023
1 parent 4ce7799 commit f8c5c70
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ It also includes the following optional runtime-supported polyfills:
- `[SuppressGCTransition]` (see [here](https://devblogs.microsoft.com/dotnet/improvements-in-native-code-interop-in-net-5-0/))
- `[DisableRuntimeMarshalling]` (see [here](https://learn.microsoft.com/dotnet/standard/native-interop/disabled-marshalling))
- `[UnsafeAccessor]` (see [here](https://github.com/dotnet/runtime/issues/81741))
- `[InlineArray]` (see [here](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-12.0/inline-arrays))

# Options ⚙️

Expand Down
1 change: 1 addition & 0 deletions src/PolySharp.Package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ It also includes the following optional runtime-supported polyfills:
- `[SuppressGCTransition]` (see [here](https://devblogs.microsoft.com/dotnet/improvements-in-native-code-interop-in-net-5-0/))
- `[DisableRuntimeMarshalling]` (see [here](https://learn.microsoft.com/dotnet/standard/native-interop/disabled-marshalling))
- `[UnsafeAccessor]` (see [here](https://github.com/dotnet/runtime/issues/81741))
- `[InlineArray]` (see [here](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-12.0/inline-arrays))

# Options ⚙️

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <auto-generated/>
#pragma warning disable
#nullable enable annotations

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Runtime.CompilerServices2
{
/// <summary>
/// Indicates that the instance's storage is sequentially replicated "length" times.
/// </summary>
/// <remarks>
/// <para>
/// This attribute can be used to annotate a <see langword="struct"/> type with a single field.
/// The runtime will replicate that field in the actual type layout as many times as is specified.
/// </para>
/// <para>
/// Here's an example of how an inline array type with 8 <see cref="float"/> values can be declared:
/// <code lang="csharp">
/// [InlineArray(8)]
/// struct Float8InlineArray
/// {
/// private float _value;
/// }
/// </code>
/// </para>
/// </remarks>
[global::System.AttributeUsage(global::System.AttributeTargets.Struct, AllowMultiple = false)]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
public sealed class InlineArrayAttribute : global::System.Attribute
{
/// <summary>Creates a new <see cref="global::System.Runtime.CompilerServices2.InlineArrayAttribute"/> instance with the specified length.</summary>
/// <param name="length">The number of sequential fields to replicate in the inline array type.</param>
public InlineArrayAttribute(int length)
{
Length = length;
}

/// <summary>Gets the number of sequential fields to replicate in the inline array type.</summary>
public int Length { get; }
}
}
8 changes: 7 additions & 1 deletion src/PolySharp.SourceGenerators/Models/SyntaxFixupType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,11 @@ internal enum SyntaxFixupType
/// Generates the <c>[UnmanagedCallersOnly]</c> type in the <c>InteropServices2</c> dummy namespace.
/// </summary>
/// <remarks>This is needed when methods annotated with the attribute have to be assigned to delegates, which Roslyn will otherwise block.</remarks>
UseInteropServices2ForUnmanagedCallersOnlyAttribute = 1 << 2
UseInteropServices2ForUnmanagedCallersOnlyAttribute = 1 << 2,

/// <summary>
/// Generates a global using for the <c>[InlineArray]</c> type in the dummy namespace.
/// </summary>
/// <remarks>This is always needed when the type is used, as the usage is entirely blocked in the normal namespace.</remarks>
EmitGlobalUsingForInlineArrayAttribute = 1 << 3
}
19 changes: 19 additions & 0 deletions src/PolySharp.SourceGenerators/PolyfillsGenerator.Polyfills.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ static SyntaxFixupType GetSyntaxFixupType(Compilation compilation, string name)
fixupType |= SyntaxFixupType.RemoveMethodImplAttributes;
}

// Emit the global using for the dummy [InlineArray] type, if allowed
if (name is "System.Runtime.CompilerServices.InlineArrayAttribute" &&
compilation.HasLanguageVersionAtLeastEqualTo(LanguageVersion.CSharp10))
{
fixupType |= SyntaxFixupType.EmitGlobalUsingForInlineArrayAttribute;
}

return fixupType;
}

Expand Down Expand Up @@ -287,6 +294,18 @@ private void EmitGeneratedType(SourceProductionContext context, GeneratedType ty
"System.Runtime.InteropServices2");
}

if ((type.FixupType & SyntaxFixupType.EmitGlobalUsingForInlineArrayAttribute) != 0)
{
// Generate a global using for [InlineArray]
adjustedSource = adjustedSource.Replace(
"namespace System.Runtime.CompilerServices2",
"""
global using InlineArrayAttribute = global::System.Runtime.CompilerServices2.InlineArrayAttribute;

namespace System.Runtime.CompilerServices2
""");
}

sourceText = SourceText.From(adjustedSource, Encoding.UTF8);
}
else
Expand Down
12 changes: 10 additions & 2 deletions tests/PolySharp.Tests/RuntimeSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ public void ReferenceSomeAssemblyFile()

internal class AccessorApis
{
#pragma warning disable IDE0044
#pragma warning disable CS0169, IDE0044
private int field;
#pragma warning restore IDE0044
#pragma warning restore CS0169, IDE0044

[StackTraceHidden]
public void HideMe()
Expand All @@ -99,4 +99,12 @@ public void HideMe()

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = nameof(field))]
public static extern ref int GetField(RandomApis obj);
}

[InlineArray(16)]
internal struct Int8
{
#pragma warning disable CS0169, IDE0044, IDE0051
private int value0;
#pragma warning restore CS0169, IDE0044, IDE0051
}

0 comments on commit f8c5c70

Please sign in to comment.