- Remove `PinnableManagedValueMarshaller` and `NativeMarshallingAttributeInfo.IsPinnableManagedType`
- Rename `CustomNativeTypeMarshallingGenerator` -> `CustomTypeMarshallingGenerator`
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
-using System.Linq.Expressions;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
namespace Microsoft.Interop
return (attr, entryType);
}
- public static IMethodSymbol? FindGetPinnableReference(ITypeSymbol type)
- {
- // Lookup a GetPinnableReference method based on the spec for the pattern-based
- // fixed statement. We aren't supporting a GetPinnableReference extension method
- // (which is apparently supported in the compiler).
- // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.3/pattern-based-fixed
- return type.GetMembers(ShapeMemberNames.GetPinnableReference)
- .OfType<IMethodSymbol>()
- .FirstOrDefault(m => m is { Parameters.Length: 0 } and
- ({ ReturnsByRef: true } or { ReturnsByRefReadonly: true }));
- }
-
private static CustomTypeMarshallerData? GetMarshallerDataForType(
ITypeSymbol marshallerType,
MarshalMode mode,
using System;
using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics;
using System.Linq;
-using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
namespace Microsoft.Interop
internal static IMethodSymbol? GetManagedValuesSource(ITypeSymbol type, ITypeSymbol readOnlySpanOfT)
{
// static ReadOnlySpan<TManagedElement> GetManagedValuesSource()
- return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.GetManagedValuesSource)
+ return type.GetMembers(ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesSource)
.OfType<IMethodSymbol>()
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: false, ReturnType: INamedTypeSymbol returnType }
&& SymbolEqualityComparer.Default.Equals(readOnlySpanOfT, returnType.ConstructedFrom));
internal static IMethodSymbol? GetUnmanagedValuesDestination(ITypeSymbol type, ITypeSymbol spanOfT)
{
// static Span<TUnmanagedElement> GetUnmanagedValuesDestination()
- return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.GetUnmanagedValuesDestination)
+ return type.GetMembers(ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesDestination)
.OfType<IMethodSymbol>()
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: false, ReturnType: INamedTypeSymbol returnType }
&& SymbolEqualityComparer.Default.Equals(spanOfT, returnType.ConstructedFrom));
internal static IMethodSymbol? GetManagedValuesDestination(ITypeSymbol type, ITypeSymbol managedType, ITypeSymbol spanOfT)
{
// static Span<TManagedElement> GetManagedValuesDestination(int numElements)
- return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.GetManagedValuesDestination)
+ return type.GetMembers(ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesDestination)
.OfType<IMethodSymbol>()
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 1, ReturnsVoid: false, ReturnType: INamedTypeSymbol returnType }
&& m.Parameters[0].Type.SpecialType == SpecialType.System_Int32
internal static IMethodSymbol? GetUnmanagedValuesSource(ITypeSymbol type, ITypeSymbol readOnlySpanOfT)
{
// static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements)
- return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.GetUnmanagedValuesSource)
+ return type.GetMembers(ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesSource)
.OfType<IMethodSymbol>()
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 1, ReturnsVoid: false, ReturnType: INamedTypeSymbol returnType }
&& m.Parameters[0].Type.SpecialType == SpecialType.System_Int32
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
-using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
marshallingStrategy = new StatelessFreeMarshalling(marshallingStrategy, marshallerData.MarshallerType.Syntax);
}
- IMarshallingGenerator marshallingGenerator = new CustomNativeTypeMarshallingGenerator(marshallingStrategy, enableByValueContentsMarshalling: false);
+ IMarshallingGenerator marshallingGenerator = new CustomTypeMarshallingGenerator(marshallingStrategy, enableByValueContentsMarshalling: false);
if (marshallerData.Shape.HasFlag(MarshallerShape.StatelessPinnableReference))
{
marshallingStrategy = new StatelessFreeMarshalling(marshallingStrategy, marshallerTypeSyntax);
}
- IMarshallingGenerator marshallingGenerator = new CustomNativeTypeMarshallingGenerator(
+ IMarshallingGenerator marshallingGenerator = new CustomTypeMarshallingGenerator(
marshallingStrategy,
enableByValueContentsMarshalling: info.ManagedType is SzArrayType && (!elementIsBlittable || ElementTypeIsSometimesNonBlittable(elementInfo)));
NativeLinearCollectionMarshallingInfo marshalInfo,
TypeSyntax unmanagedElementType)
=> originalTypeSyntax.ReplaceNodes(
- originalTypeSyntax.DescendantNodesAndSelf().OfType<TypeSyntax>().Where(t => t.IsEquivalentTo(marshalInfo.PlaceholderTypeParameter.Syntax)),
- (_, _) => unmanagedElementType);
+ originalTypeSyntax.DescendantNodesAndSelf().OfType<TypeSyntax>().Where(t => t.IsEquivalentTo(marshalInfo.PlaceholderTypeParameter.Syntax)),
+ (_, _) => unmanagedElementType);
private void ValidateCustomNativeTypeMarshallingSupported(TypePositionInfo info, StubCodeContext context, NativeMarshallingAttributeInfo marshalInfo)
{
if (!info.IsByRef
&& !info.IsManagedReturnPosition
&& context.SingleFrameSpansNativeContext
- && !(marshalInfo.IsPinnableManagedType || marshalInfo.Marshallers.IsDefinedOrDefault(Options.InMode)))
+ && !marshalInfo.Marshallers.IsDefinedOrDefault(Options.InMode))
{
throw new MarshallingNotSupportedException(info, context)
{
namespace Microsoft.Interop
{
/// <summary>
- /// Implements generating code for an <see cref="ICustomNativeTypeMarshallingStrategy"/> instance.
+ /// Implements generating code for an <see cref="ICustomTypeMarshallingStrategy"/> instance.
/// </summary>
- internal sealed class CustomNativeTypeMarshallingGenerator : IMarshallingGenerator
+ internal sealed class CustomTypeMarshallingGenerator : IMarshallingGenerator
{
private readonly ICustomTypeMarshallingStrategy _nativeTypeMarshaller;
private readonly bool _enableByValueContentsMarshalling;
- public CustomNativeTypeMarshallingGenerator(ICustomTypeMarshallingStrategy nativeTypeMarshaller, bool enableByValueContentsMarshalling)
+ public CustomTypeMarshallingGenerator(ICustomTypeMarshallingStrategy nativeTypeMarshaller, bool enableByValueContentsMarshalling)
{
_nativeTypeMarshaller = nativeTypeMarshaller;
_enableByValueContentsMarshalling = enableByValueContentsMarshalling;
case StubCodeContext.Stage.NotifyForSuccessfulInvoke:
if (!info.IsManagedReturnPosition && info.RefKind != RefKind.Out)
{
- if (_nativeTypeMarshaller is ICustomTypeMarshallingStrategy strategyWithGuaranteedUnmarshal)
- {
- return strategyWithGuaranteedUnmarshal.GenerateNotifyForSuccessfulInvokeStatements(info, context);
- }
+ return _nativeTypeMarshaller.GenerateNotifyForSuccessfulInvokeStatements(info, context);
}
break;
case StubCodeContext.Stage.UnmarshalCapture:
|| (info.IsByRef && info.RefKind != RefKind.In)
|| (_enableByValueContentsMarshalling && !info.IsByRef && info.ByValueContentsMarshalKind.HasFlag(ByValueContentsMarshalKind.Out)))
{
- if (_nativeTypeMarshaller is ICustomTypeMarshallingStrategy strategyWithGuaranteedUnmarshal)
- {
- return strategyWithGuaranteedUnmarshal.GenerateGuaranteedUnmarshalStatements(info, context);
- }
+ return _nativeTypeMarshaller.GenerateGuaranteedUnmarshalStatements(info, context);
}
break;
case StubCodeContext.Stage.Cleanup:
// 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 Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Microsoft.Interop
{
{
TypeSyntax AsNativeType(TypePositionInfo info);
- IEnumerable<StatementSyntax> GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context);
+ IEnumerable<StatementSyntax> GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context);
- IEnumerable<StatementSyntax> GenerateSetupStatements(TypePositionInfo info, StubCodeContext context);
+ IEnumerable<StatementSyntax> GenerateGuaranteedUnmarshalStatements(TypePositionInfo info, StubCodeContext context);
- IEnumerable<StatementSyntax> GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context);
+ IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context);
+
+ IEnumerable<StatementSyntax> GenerateNotifyForSuccessfulInvokeStatements(TypePositionInfo info, StubCodeContext context);
+
+ IEnumerable<StatementSyntax> GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context);
IEnumerable<StatementSyntax> GeneratePinStatements(TypePositionInfo info, StubCodeContext context);
+ IEnumerable<StatementSyntax> GenerateSetupStatements(TypePositionInfo info, StubCodeContext context);
+
IEnumerable<StatementSyntax> GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context);
IEnumerable<StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context);
bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context);
-
- IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context);
- IEnumerable<StatementSyntax> GenerateGuaranteedUnmarshalStatements(TypePositionInfo info, StubCodeContext context);
- IEnumerable<StatementSyntax> GenerateNotifyForSuccessfulInvokeStatements(TypePositionInfo info, StubCodeContext context);
}
}
+++ /dev/null
-// 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 Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
-
-namespace Microsoft.Interop
-{
- public sealed class PinnableManagedValueMarshaller : IMarshallingGenerator
- {
- private readonly IMarshallingGenerator _innerMarshallingGenerator;
-
- public PinnableManagedValueMarshaller(IMarshallingGenerator innerMarshallingGenerator)
- {
- _innerMarshallingGenerator = innerMarshallingGenerator;
- }
-
- public bool IsSupported(TargetFramework target, Version version)
- => _innerMarshallingGenerator.IsSupported(target, version);
-
- public ValueBoundaryBehavior GetValueBoundaryBehavior(TypePositionInfo info, StubCodeContext context)
- {
- if (IsPinningPathSupported(info, context))
- {
- if (AsNativeType(info) is PointerTypeSyntax pointerType
- && pointerType.ElementType is PredefinedTypeSyntax predefinedType
- && predefinedType.Keyword.IsKind(SyntaxKind.VoidKeyword))
- {
- return ValueBoundaryBehavior.NativeIdentifier;
- }
-
- // Cast to native type if it is not void*
- return ValueBoundaryBehavior.CastNativeIdentifier;
- }
-
- return _innerMarshallingGenerator.GetValueBoundaryBehavior(info, context);
- }
-
- public TypeSyntax AsNativeType(TypePositionInfo info)
- {
- return _innerMarshallingGenerator.AsNativeType(info);
- }
-
- public SignatureBehavior GetNativeSignatureBehavior(TypePositionInfo info)
- {
- return _innerMarshallingGenerator.GetNativeSignatureBehavior(info);
- }
-
- public IEnumerable<StatementSyntax> Generate(TypePositionInfo info, StubCodeContext context)
- {
- if (IsPinningPathSupported(info, context))
- {
- return GeneratePinningPath(info, context);
- }
-
- return _innerMarshallingGenerator.Generate(info, context);
- }
-
- public bool SupportsByValueMarshalKind(ByValueContentsMarshalKind marshalKind, StubCodeContext context)
- {
- return _innerMarshallingGenerator.SupportsByValueMarshalKind(marshalKind, context);
- }
-
- public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context)
- {
- if (IsPinningPathSupported(info, context))
- {
- return false;
- }
-
- return _innerMarshallingGenerator.UsesNativeIdentifier(info, context);
- }
- private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContext context)
- {
- return context.SingleFrameSpansNativeContext && !info.IsByRef && !info.IsManagedReturnPosition;
- }
-
- private static IEnumerable<StatementSyntax> GeneratePinningPath(TypePositionInfo info, StubCodeContext context)
- {
- if (context.CurrentStage == StubCodeContext.Stage.Pin)
- {
- (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
-
- // fixed (void* <nativeIdentifier> = <managedIdentifier>)
- yield return FixedStatement(
- VariableDeclaration(
- PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))),
- SingletonSeparatedList(
- VariableDeclarator(Identifier(nativeIdentifier))
- .WithInitializer(EqualsValueClause(
- IdentifierName(managedIdentifier)
- ))
- )
- ),
- EmptyStatement());
- }
- }
- }
-}
/// </summary>
public record NativeMarshallingAttributeInfo(
ManagedTypeInfo EntryPointType,
- CustomTypeMarshallers Marshallers,
- bool IsPinnableManagedType) : MarshallingInfo;
+ CustomTypeMarshallers Marshallers) : MarshallingInfo;
/// <summary>
/// Custom type marshalling via MarshalUsingAttribute or NativeMarshallingAttribute for a linear collection
public sealed record NativeLinearCollectionMarshallingInfo(
ManagedTypeInfo EntryPointType,
CustomTypeMarshallers Marshallers,
- bool IsPinnableManagedType,
CountInfo ElementCountInfo,
ManagedTypeInfo PlaceholderTypeParameter) : NativeMarshallingAttributeInfo(
EntryPointType,
- Marshallers,
- IsPinnableManagedType);
+ Marshallers);
/// <summary>
/// The type of the element is a SafeHandle-derived type with no marshalling attributes.
}
ManagedTypeInfo entryPointTypeInfo = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(entryPointType);
- bool isPinnableManagedType = !isMarshalUsingAttribute && ManualTypeMarshallingHelper.FindGetPinnableReference(type) is not null;
bool isLinearCollectionMarshalling = ManualTypeMarshallingHelper.IsLinearCollectionEntryPoint(entryPointType);
if (isLinearCollectionMarshalling)
return new NativeLinearCollectionMarshallingInfo(
entryPointTypeInfo,
marshallers.Value,
- isPinnableManagedType,
parsedCountInfo,
ManagedTypeInfo.CreateTypeInfoForTypeSymbol(entryPointType.TypeParameters.Last()));
}
}
else if (ManualTypeMarshallingHelper.TryGetValueMarshallersFromEntryType(entryPointType, type, _compilation, out CustomTypeMarshallers? marshallers))
{
- return new NativeMarshallingAttributeInfo(entryPointTypeInfo, marshallers.Value, isPinnableManagedType);
+ return new NativeMarshallingAttributeInfo(entryPointTypeInfo, marshallers.Value);
}
return NoMarshallingInfo.Instance;
}
return new NativeLinearCollectionMarshallingInfo(
ManagedTypeInfo.CreateTypeInfoForTypeSymbol(arrayMarshaller),
marshallers.Value,
- IsPinnableManagedType: false,
countInfo,
ManagedTypeInfo.CreateTypeInfoForTypeSymbol(arrayMarshaller.TypeParameters.Last()));
}
{
return new NativeMarshallingAttributeInfo(
EntryPointType: ManagedTypeInfo.CreateTypeInfoForTypeSymbol(stringMarshaller),
- Marshallers: marshallers.Value,
- IsPinnableManagedType: false);
+ Marshallers: marshallers.Value);
}
}