From 50ffc95cf3f839428a158dca9ead2a3e7250d27f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Sep 2023 13:42:59 +0200 Subject: [PATCH] Add UnsafeAccessorAttribute polyfill --- ...ompilerServices.UnsafeAccessorAttribute.cs | 80 +++++++++++++++++++ ...ime.CompilerServices.UnsafeAccessorKind.cs | 40 ++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs new file mode 100644 index 0000000..0a2591c --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs @@ -0,0 +1,80 @@ +// +#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.CompilerServices +{ + /// + /// Provides access to an inaccessible member of a specific type. + /// + /// + /// This attribute may be applied to an extern static method. + /// The implementation of the extern static method annotated with + /// this attribute will be provided by the runtime based on the information in + /// the attribute and the signature of the method that the attribute is applied to. + /// The runtime will try to find the matching method or field and forward the call + /// to it. If the matching method or field is not found, the body of the extern + /// method will throw or . + /// Only the specific type defined will be examined for inaccessible members. The type hierarchy + /// is not walked looking for a match. + /// + /// For , + /// , + /// , + /// and , the type of + /// the first argument of the annotated extern method identifies the owning type. + /// The value of the first argument is treated as this pointer for instance fields and methods. + /// The first argument must be passed as ref for instance fields and methods on structs. + /// The value of the first argument is not used by the implementation for static fields and methods. + /// + /// Return type is considered for the signature match. modreqs and modopts are initially not considered for + /// the signature match. However, if an ambiguity exists ignoring modreqs and modopts, a precise match + /// is attempted. If an ambiguity still exists is thrown. + /// + /// By default, the attributed method's name dictates the name of the method/field. This can cause confusion + /// in some cases since language abstractions, like C# local functions, generate mangled IL names. The + /// solution to this is to use the nameof mechanism and define the property. + /// + /// + /// public void Method(Class c) + /// { + /// PrivateMethod(c); + /// + /// [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(PrivateMethod))] + /// extern static void PrivateMethod(Class c); + /// } + /// + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class UnsafeAccessorAttribute : global::System.Attribute + { + /// + /// Instantiates an + /// providing access to a member of kind . + /// + /// The kind of the target to which access is provided. + public UnsafeAccessorAttribute(global::System.Runtime.CompilerServices.UnsafeAccessorKind kind) + { + Kind = kind; + } + + /// + /// Gets the kind of member to which access is provided. + /// + public global::System.Runtime.CompilerServices.UnsafeAccessorKind Kind { get; } + + /// + /// Gets or sets the name of the member to which access is provided. + /// + /// + /// The name defaults to the annotated method name if not specified. + /// The name must be unset/null for . + /// + public string? Name { get; set; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs new file mode 100644 index 0000000..7cb4fc3 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs @@ -0,0 +1,40 @@ +// +#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.CompilerServices +{ + /// + /// Specifies the kind of target to which an is providing access. + /// + internal enum UnsafeAccessorKind + { + /// + /// Provide access to a constructor. + /// + Constructor, + + /// + /// Provide access to a method. + /// + Method, + + /// + /// Provide access to a static method. + /// + StaticMethod, + + /// + /// Provide access to a field. + /// + Field, + + /// + /// Provide access to a static field. + /// + StaticField + } +} \ No newline at end of file