From ef357af10c4f7f0b491b5dc0dff5a36a9b97d07b Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 4 Jan 2022 09:22:35 -0500 Subject: [DllImportGenerator] Update buffer size field for custom marshalling (#63316) --- .../Runtime/InteropServices/ArrayMarshaller.cs | 6 +- .../Analyzers/AnalyzerDiagnostics.cs | 4 +- .../Analyzers/ManualTypeMarshallingAnalyzer.cs | 44 ++++++------- .../gen/DllImportGenerator/Resources.Designer.cs | 72 +++++++++++----------- .../gen/DllImportGenerator/Resources.resx | 24 ++++---- .../ManualTypeMarshallingHelper.cs | 5 +- .../ICustomNativeTypeMarshallingStrategy.cs | 6 +- .../MarshallingAttributeInfo.cs | 2 +- .../tests/Ancillary.Interop/SpanMarshallers.cs | 13 ++-- .../DllImportGenerator.UnitTests/CodeSnippets.cs | 12 ++-- .../ManualTypeMarshallingAnalyzerTests.cs | 16 ++--- .../tests/TestAssets/SharedTypes/NonBlittable.cs | 6 +- 12 files changed, 110 insertions(+), 100 deletions(-) (limited to 'src/libraries') diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs b/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs index dc11f7efd42..a1b99ab9223 100644 --- a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs +++ b/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs @@ -67,7 +67,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of array parameters doesn't /// blow the stack since this is a new optimization in the code-generated interop. /// - public const int StackBufferSize = 0x200; + public const int BufferSize = 0x200; + public const bool RequiresStackBuffer = true; public Span ManagedValues => _managedArray; @@ -160,7 +161,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of array parameters doesn't /// blow the stack since this is a new optimization in the code-generated interop. /// - public const int StackBufferSize = 0x200; + public const int BufferSize = 0x200; + public const bool RequiresStackBuffer = true; public Span ManagedValues => Unsafe.As(_managedArray); diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs index 37740545ed1..3153a25954d 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs @@ -25,8 +25,8 @@ namespace Microsoft.Interop.Analyzers public const string ValuePropertyMustHaveSetter = Prefix + "008"; public const string ValuePropertyMustHaveGetter = Prefix + "009"; public const string GetPinnableReferenceShouldSupportAllocatingMarshallingFallback = Prefix + "010"; - public const string StackallocMarshallingShouldSupportAllocatingMarshallingFallback = Prefix + "011"; - public const string StackallocConstructorMustHaveStackBufferSizeConstant = Prefix + "012"; + public const string CallerAllocMarshallingShouldSupportAllocatingMarshallingFallback = Prefix + "011"; + public const string CallerAllocConstructorMustHaveStackBufferSizeConstant = Prefix + "012"; public const string RefValuePropertyUnsupported = Prefix + "014"; public const string NativeGenericTypeMustBeClosedOrMatchArity = Prefix + "016"; public const string MarshallerGetPinnableReferenceRequiresValueProperty = Prefix + "018"; diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs index 5446b843aea..9a3c33326d4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs @@ -126,25 +126,25 @@ namespace Microsoft.Interop.Analyzers isEnabledByDefault: true, description: GetResourceString(nameof(Resources.GetPinnableReferenceShouldSupportAllocatingMarshallingFallbackDescription))); - public static readonly DiagnosticDescriptor StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule = + public static readonly DiagnosticDescriptor CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule = new DiagnosticDescriptor( - Ids.StackallocMarshallingShouldSupportAllocatingMarshallingFallback, - "StackallocMarshallingShouldSupportAllocatingMarshallingFallback", - GetResourceString(nameof(Resources.StackallocMarshallingShouldSupportAllocatingMarshallingFallbackMessage)), + Ids.CallerAllocMarshallingShouldSupportAllocatingMarshallingFallback, + "CallerAllocMarshallingShouldSupportAllocatingMarshallingFallback", + GetResourceString(nameof(Resources.CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackMessage)), Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, - description: GetResourceString(nameof(Resources.StackallocMarshallingShouldSupportAllocatingMarshallingFallbackDescription))); + description: GetResourceString(nameof(Resources.CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackDescription))); - public static readonly DiagnosticDescriptor StackallocConstructorMustHaveStackBufferSizeConstantRule = + public static readonly DiagnosticDescriptor CallerAllocConstructorMustHaveBufferSizeConstantRule = new DiagnosticDescriptor( - Ids.StackallocConstructorMustHaveStackBufferSizeConstant, - "StackallocConstructorMustHaveStackBufferSizeConstant", - GetResourceString(nameof(Resources.StackallocConstructorMustHaveStackBufferSizeConstantMessage)), + Ids.CallerAllocConstructorMustHaveStackBufferSizeConstant, + "CallerAllocConstructorMustHaveBufferSizeConstant", + GetResourceString(nameof(Resources.CallerAllocConstructorMustHaveBufferSizeConstantMessage)), Category, DiagnosticSeverity.Error, isEnabledByDefault: true, - description: GetResourceString(nameof(Resources.StackallocConstructorMustHaveStackBufferSizeConstantDescription))); + description: GetResourceString(nameof(Resources.CallerAllocConstructorMustHaveBufferSizeConstantDescription))); public static readonly DiagnosticDescriptor RefValuePropertyUnsupportedRule = new DiagnosticDescriptor( @@ -189,8 +189,8 @@ namespace Microsoft.Interop.Analyzers ValuePropertyMustHaveSetterRule, ValuePropertyMustHaveGetterRule, GetPinnableReferenceShouldSupportAllocatingMarshallingFallbackRule, - StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule, - StackallocConstructorMustHaveStackBufferSizeConstantRule, + CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule, + CallerAllocConstructorMustHaveBufferSizeConstantRule, RefValuePropertyUnsupportedRule, NativeGenericTypeMustBeClosedOrMatchArityRule, MarshallerGetPinnableReferenceRequiresValuePropertyRule); @@ -425,7 +425,7 @@ namespace Microsoft.Interop.Analyzers } bool hasConstructor = false; - bool hasStackallocConstructor = false; + bool hasCallerAllocSpanConstructor = false; foreach (IMethodSymbol ctor in marshalerType.Constructors) { if (ctor.IsStatic) @@ -435,15 +435,15 @@ namespace Microsoft.Interop.Analyzers hasConstructor = hasConstructor || ManualTypeMarshallingHelper.IsManagedToNativeConstructor(ctor, type, variant); - if (!hasStackallocConstructor && ManualTypeMarshallingHelper.IsStackallocConstructor(ctor, type, _spanOfByte, variant)) + if (!hasCallerAllocSpanConstructor && ManualTypeMarshallingHelper.IsCallerAllocatedSpanConstructor(ctor, type, _spanOfByte, variant)) { - hasStackallocConstructor = true; - IFieldSymbol stackAllocSizeField = nativeType.GetMembers("StackBufferSize").OfType().FirstOrDefault(); - if (stackAllocSizeField is null or { DeclaredAccessibility: not Accessibility.Public } or { IsConst: false } or { Type: not { SpecialType: SpecialType.System_Int32 } }) + hasCallerAllocSpanConstructor = true; + IFieldSymbol bufferSizeField = nativeType.GetMembers(ManualTypeMarshallingHelper.BufferSizeFieldName).OfType().FirstOrDefault(); + if (bufferSizeField is null or { DeclaredAccessibility: not Accessibility.Public } or { IsConst: false } or { Type: not { SpecialType: SpecialType.System_Int32 } }) { context.ReportDiagnostic( GetDiagnosticLocations(context, ctor, nativeMarshalerAttributeData).CreateDiagnostic( - StackallocConstructorMustHaveStackBufferSizeConstantRule, + CallerAllocConstructorMustHaveBufferSizeConstantRule, nativeType.ToDisplayString())); } } @@ -452,7 +452,7 @@ namespace Microsoft.Interop.Analyzers bool hasToManaged = ManualTypeMarshallingHelper.HasToManagedMethod(marshalerType, type); // Validate that the native type has at least one marshalling method (either managed to native or native to managed) - if (!hasConstructor && !hasStackallocConstructor && !hasToManaged) + if (!hasConstructor && !hasCallerAllocSpanConstructor && !hasToManaged) { context.ReportDiagnostic( GetDiagnosticLocations(context, marshalerType, nativeMarshalerAttributeData).CreateDiagnostic( @@ -462,11 +462,11 @@ namespace Microsoft.Interop.Analyzers } // Validate that this type can support marshalling when stackalloc is not usable. - if (isNativeMarshallingAttribute && hasStackallocConstructor && !hasConstructor) + if (isNativeMarshallingAttribute && hasCallerAllocSpanConstructor && !hasConstructor) { context.ReportDiagnostic( GetDiagnosticLocations(context, marshalerType, nativeMarshalerAttributeData).CreateDiagnostic( - StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule, + CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule, marshalerType.ToDisplayString())); } @@ -490,7 +490,7 @@ namespace Microsoft.Interop.Analyzers // We error if either of the conditions below are partially met but not fully met: // - a constructor and a Value property getter // - a ToManaged method and a Value property setter - if ((hasConstructor || hasStackallocConstructor) && valueProperty.GetMethod is null) + if ((hasConstructor || hasCallerAllocSpanConstructor) && valueProperty.GetMethod is null) { context.ReportDiagnostic( GetDiagnosticLocations(context, valueProperty, nativeMarshalerAttributeData).CreateDiagnostic( diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs index f44085e2257..28352565c85 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs @@ -78,6 +78,42 @@ namespace Microsoft.Interop { } } + /// + /// Looks up a localized string similar to When constructor taking a Span<byte> is specified on the native type, the type must also have a public integer constant named BufferSize to provide the size of the caller-allocated buffer.. + /// + internal static string CallerAllocConstructorMustHaveBufferSizeConstantDescription { + get { + return ResourceManager.GetString("CallerAllocConstructorMustHaveBufferSizeConstantDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The native type '{0}' must have a 'public const int BufferSize' field that specifies the size of the stack buffer because it has a constructor that takes a caller-allocated Span<byte>. + /// + internal static string CallerAllocConstructorMustHaveBufferSizeConstantMessage { + get { + return ResourceManager.GetString("CallerAllocConstructorMustHaveBufferSizeConstantMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A type that supports marshalling from managed to native using a caller-allocated buffer should also support marshalling from managed to native where using a caller-allocated buffer is impossible.. + /// + internal static string CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackDescription { + get { + return ResourceManager.GetString("CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Native type '{0}' has a constructor taking a caller-allocated buffer, but does not support marshalling in scenarios where using a caller-allocated buffer is impossible. + /// + internal static string CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackMessage { + get { + return ResourceManager.GetString("CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to The 'BlittableTypeAttribute' and 'NativeMarshallingAttribute' attributes are mutually exclusive.. /// @@ -492,42 +528,6 @@ namespace Microsoft.Interop { } } - /// - /// Looks up a localized string similar to When constructor taking a Span<byte> is specified on the native type, the type must also have a public integer constant named StackBufferSize to provide the size of the stack-allocated buffer.. - /// - internal static string StackallocConstructorMustHaveStackBufferSizeConstantDescription { - get { - return ResourceManager.GetString("StackallocConstructorMustHaveStackBufferSizeConstantDescription", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The native type '{0}' must have a 'public const int StackBufferSize' field that specifies the size of the stack buffer because it has a constructor that takes a stack-allocated Span<byte>. - /// - internal static string StackallocConstructorMustHaveStackBufferSizeConstantMessage { - get { - return ResourceManager.GetString("StackallocConstructorMustHaveStackBufferSizeConstantMessage", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A type that supports marshalling from managed to native by stack allocation should also support marshalling from managed to native where stack allocation is impossible.. - /// - internal static string StackallocMarshallingShouldSupportAllocatingMarshallingFallbackDescription { - get { - return ResourceManager.GetString("StackallocMarshallingShouldSupportAllocatingMarshallingFallbackDescription", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Native type '{0}' has a stack-allocating constructor does not support marshalling in scenarios where stack allocation is impossible. - /// - internal static string StackallocMarshallingShouldSupportAllocatingMarshallingFallbackMessage { - get { - return ResourceManager.GetString("StackallocMarshallingShouldSupportAllocatingMarshallingFallbackMessage", resourceCulture); - } - } - /// /// Looks up a localized string similar to P/Invoke source generation is not supported on unknown target framework v{0}. The generated source will not be compatible with other frameworks.. /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx index f2acaa98ed1..a05f66fac1e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx +++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx @@ -123,6 +123,18 @@ Type '{0}' is marked with 'BlittableTypeAttribute' but is not blittable + + When a constructor taking a Span<byte> is specified on the native type, the type must also have a public integer constant named BufferSize to provide the size of the caller-allocated buffer. + + + The native type '{0}' must have a 'public const int BufferSize' field that specifies the size of the stack buffer because it has a constructor that takes a caller-allocated Span<byte> + + + A type that supports marshalling from managed to native using a caller-allocated buffer should also support marshalling from managed to native where using a caller-allocated buffer is impossible. + + + Native type '{0}' has a constructor taking a caller-allocated buffer, but does not support marshalling in scenarios where using a caller-allocated buffer is impossible + The 'BlittableTypeAttribute' and 'NativeMarshallingAttribute' attributes are mutually exclusive. @@ -262,18 +274,6 @@ An abstract type derived from 'SafeHandle' cannot be marshalled by reference. The provided type must be concrete. - - When constructor taking a Span<byte> is specified on the native type, the type must also have a public integer constant named StackBufferSize to provide the size of the stack-allocated buffer. - - - The native type '{0}' must have a 'public const int StackBufferSize' field that specifies the size of the stack buffer because it has a constructor that takes a stack-allocated Span<byte> - - - A type that supports marshalling from managed to native by stack allocation should also support marshalling from managed to native where stack allocation is impossible. - - - Native type '{0}' has a stack-allocating constructor does not support marshalling in scenarios where stack allocation is impossible - P/Invoke source generation is not supported on unknown target framework v{0}. The generated source will not be compatible with other frameworks. {0} is a version number diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs index 503cae185ec..b6343bb5d23 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs @@ -11,7 +11,8 @@ namespace Microsoft.Interop { public const string ValuePropertyName = "Value"; public const string GetPinnableReferenceName = "GetPinnableReference"; - public const string StackBufferSizeFieldName = "StackBufferSize"; + public const string BufferSizeFieldName = "BufferSize"; + public const string RequiresStackBufferFieldName = "RequiresStackBuffer"; public const string ToManagedMethodName = "ToManaged"; public const string FreeNativeMethodName = "FreeNative"; public const string ManagedValuesPropertyName = "ManagedValues"; @@ -57,7 +58,7 @@ namespace Microsoft.Interop && SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type); } - public static bool IsStackallocConstructor( + public static bool IsCallerAllocatedSpanConstructor( IMethodSymbol ctor, ITypeSymbol managedType, ITypeSymbol spanOfByte, diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs index b653006db9c..f1b4cc171aa 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs @@ -306,7 +306,7 @@ namespace Microsoft.Interop { if (StackAllocOptimizationValid(info, context)) { - // byte* __stackptr = stackalloc byte[<_nativeLocalType>.StackBufferSize]; + // byte* __stackptr = stackalloc byte[<_nativeLocalType>.BufferSize]; yield return LocalDeclarationStatement( VariableDeclaration( PointerType(PredefinedType(Token(SyntaxKind.ByteKeyword))), @@ -319,7 +319,7 @@ namespace Microsoft.Interop SingletonList(ArrayRankSpecifier(SingletonSeparatedList( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, AsNativeType(info), - IdentifierName(ManualTypeMarshallingHelper.StackBufferSizeFieldName)) + IdentifierName(ManualTypeMarshallingHelper.BufferSizeFieldName)) )))))))))); } @@ -373,7 +373,7 @@ namespace Microsoft.Interop Argument(IdentifierName(GetStackAllocPointerIdentifier(info, context))), Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, AsNativeType(info), - IdentifierName(ManualTypeMarshallingHelper.StackBufferSizeFieldName))) + IdentifierName(ManualTypeMarshallingHelper.BufferSizeFieldName))) })))); } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs index f5376fda0a8..d1f659d125b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs @@ -641,7 +641,7 @@ namespace Microsoft.Interop { features |= CustomMarshallingFeatures.ManagedToNative; } - else if (ManualTypeMarshallingHelper.IsStackallocConstructor(ctor, type, spanOfByte, marshallingVariant) + else if (ManualTypeMarshallingHelper.IsCallerAllocatedSpanConstructor(ctor, type, spanOfByte, marshallingVariant) && (valueProperty is null or { GetMethod: not null })) { features |= CustomMarshallingFeatures.ManagedToNativeStackalloc; diff --git a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs index d5543df3c88..46cd7302fbf 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs @@ -52,7 +52,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of array parameters doesn't /// blow the stack since this is a new optimization in the code-generated interop. /// - public const int StackBufferSize = 0x200; + public const int BufferSize = 0x200; + public const bool RequiresStackBuffer = true; public Span ManagedValues => MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(_managedSpan), _managedSpan.Length); @@ -120,7 +121,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of array parameters doesn't /// blow the stack since this is a new optimization in the code-generated interop. /// - public const int StackBufferSize = ReadOnlySpanMarshaller.StackBufferSize; + public const int BufferSize = ReadOnlySpanMarshaller.BufferSize; + public const bool RequiresStackBuffer = ReadOnlySpanMarshaller.RequiresStackBuffer; public Span ManagedValues => _inner.ManagedValues; @@ -180,7 +182,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of span parameters doesn't /// blow the stack. /// - public const int StackBufferSize = SpanMarshaller.StackBufferSize; + public const int BufferSize = SpanMarshaller.BufferSize; public Span ManagedValues => _inner.ManagedValues; @@ -251,7 +253,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// Number kept small to ensure that P/Invokes with a lot of span parameters doesn't /// blow the stack. /// - public const int StackBufferSize = SpanMarshaller.StackBufferSize; + public const int BufferSize = SpanMarshaller.BufferSize; + public const bool RequiresStackBuffer = SpanMarshaller.RequiresStackBuffer; public Span ManagedValues => _inner.ManagedValues; @@ -337,7 +340,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling /// /// Stack-alloc threshold set to 0 so that the generator can use the constructor that takes a stackSpace to let the marshaller know that the original data span can be used and safely pinned. /// - public const int StackBufferSize = 0; + public const int BufferSize = 0; public Span ManagedValues => _data; diff --git a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/CodeSnippets.cs b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/CodeSnippets.cs index 42d3d9c49c8..79fb731628f 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/CodeSnippets.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/CodeSnippets.cs @@ -664,7 +664,7 @@ struct Native public S ToManaged() => new S { b = i != 0 }; - public const int StackBufferSize = 1; + public const int BufferSize = 1; } "; public static string CustomStructMarshallingStackallocOnlyRefParameter = BasicParameterWithByRefModifier("ref", "S") + @" @@ -684,7 +684,8 @@ struct Native public S ToManaged() => new S { b = i != 0 }; - public const int StackBufferSize = 1; + public const int BufferSize = 1; + public const bool RequiresStackBuffer = false; } "; public static string CustomStructMarshallingOptionalStackallocParametersAndModifiers = BasicParametersAndModifiers("S") + @" @@ -708,7 +709,8 @@ struct Native public S ToManaged() => new S { b = i != 0 }; - public const int StackBufferSize = 1; + public const int BufferSize = 1; + public const bool RequiresStackBuffer = true; } "; @@ -730,7 +732,7 @@ struct Native public int Value { get; set; } - public const int StackBufferSize = 1; + public const int BufferSize = 1; } "; public static string CustomStructMarshallingValuePropertyParametersAndModifiers = BasicParametersAndModifiers("S") + @" @@ -828,7 +830,7 @@ unsafe ref struct Native } } - public const int StackBufferSize = 1; + public const int BufferSize = 1; } partial class Test diff --git a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs index 2a7d42b2d63..240805071a1 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs @@ -838,7 +838,7 @@ ref struct {|#0:Native|} { public Native(S s, Span stackSpace) : this() {} - public const int StackBufferSize = 1; + public const int BufferSize = 1; public Span ManagedValues { get; set; } public Span NativeValueStorage { get; set; } @@ -868,7 +868,7 @@ ref struct {|#0:Native|} { public Native(S s, Span stackSpace, int nativeElementSize) : this() {} - public const int StackBufferSize = 1; + public const int BufferSize = 1; public Span ManagedValues { get; set; } public Span NativeValueStorage { get; set; } @@ -877,7 +877,7 @@ ref struct {|#0:Native|} }"; await VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(0).WithArguments("Native", "S")); + VerifyCS.Diagnostic(CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(0).WithArguments("Native", "S")); } [ConditionalFact] @@ -996,11 +996,11 @@ struct {|#0:Native|} { public Native(S s, Span buffer) {} - public const int StackBufferSize = 0x100; + public const int BufferSize = 0x100; }"; await VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(0).WithArguments("Native")); + VerifyCS.Diagnostic(CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(0).WithArguments("Native")); } [ConditionalFact] @@ -1023,11 +1023,11 @@ struct {|#1:Native|} public IntPtr Value => IntPtr.Zero; - public const int StackBufferSize = 0x100; + public const int BufferSize = 0x100; }"; await VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(1).WithArguments("Native"), + VerifyCS.Diagnostic(CallerAllocMarshallingShouldSupportAllocatingMarshallingFallbackRule).WithLocation(1).WithArguments("Native"), VerifyCS.Diagnostic(GetPinnableReferenceShouldSupportAllocatingMarshallingFallbackRule).WithLocation(0).WithArguments("S", "Native")); } @@ -1620,7 +1620,7 @@ struct Native }"; await VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(StackallocConstructorMustHaveStackBufferSizeConstantRule).WithLocation(0).WithArguments("Native")); + VerifyCS.Diagnostic(CallerAllocConstructorMustHaveBufferSizeConstantRule).WithLocation(0).WithArguments("Native")); } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs index 4969c546594..94d35ace34a 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs @@ -192,7 +192,8 @@ namespace SharedTypes Marshal.FreeCoTaskMem((IntPtr)allocated); } - public const int StackBufferSize = 0x100; + public const int BufferSize = 0x100; + public const bool RequiresStackBuffer = true; } @@ -260,7 +261,8 @@ namespace SharedTypes /// Number kept small to ensure that P/Invokes with a lot of array parameters doesn't /// blow the stack since this is a new optimization in the code-generated interop. /// - public const int StackBufferSize = 0x200; + public const int BufferSize = 0x200; + public const bool RequiresStackBuffer = true; public Span ManagedValues => CollectionsMarshal.AsSpan(managedList); -- cgit v1.2.3