diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs index 2f622da69344d5..3c8e6c09aa3581 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs @@ -30,10 +30,12 @@ public enum SignatureBehavior /// The native type should match the managed type, including rehydrating marshalling attributes and by-ref syntax (pure forwarding). /// ManagedTypeAndAttributes, + /// /// The native signature should be the type returned by passed by value. /// NativeType, + /// /// The native signature should be a pointer to the type returned by passed by value. /// @@ -49,14 +51,21 @@ public enum ValueBoundaryBehavior /// The managed value should be passed as-is, including any managed by-ref syntax used in the managed declaration. /// ManagedIdentifier, + /// /// The native identifier provided by should be passed by value. /// NativeIdentifier, + /// /// The address of the native identifier provided by should be passed by value. /// - AddressOfNativeIdentifier + AddressOfNativeIdentifier, + + /// + /// The native identifier provided by should be cast to the native type. + /// + CastNativeIdentifier } /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs index 8de5682ac01580..e07e8baaf616b0 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs @@ -96,7 +96,6 @@ private static ParameterSyntax GenerateForwardingParameter(TypePositionInfo info return param; } - private static bool TryRehydrateMarshalAsAttribute(TypePositionInfo info, out AttributeSyntax marshalAsAttribute) { marshalAsAttribute = null!; @@ -203,6 +202,7 @@ public static ArgumentSyntax AsArgument(this IMarshallingGenerator generator, Ty ValueBoundaryBehavior.ManagedIdentifier when info.IsByRef => Argument(IdentifierName(managedIdentifier)).WithRefKindKeyword(Token(info.RefKindSyntax)), ValueBoundaryBehavior.NativeIdentifier => Argument(IdentifierName(nativeIdentifier)), ValueBoundaryBehavior.AddressOfNativeIdentifier => Argument(PrefixUnaryExpression(SyntaxKind.AddressOfExpression, IdentifierName(nativeIdentifier))), + ValueBoundaryBehavior.CastNativeIdentifier => Argument(CastExpression(generator.AsParameter(info).Type, IdentifierName(nativeIdentifier))), _ => throw new InvalidOperationException() }; } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs index 191713bbf019f4..3531a8cc8d0e6c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; @@ -25,8 +26,17 @@ public ValueBoundaryBehavior GetValueBoundaryBehavior(TypePositionInfo info, Stu { if (IsPinningPathSupported(info, context)) { - return ValueBoundaryBehavior.NativeIdentifier; + 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); } @@ -46,6 +56,7 @@ public IEnumerable Generate(TypePositionInfo info, StubCodeCont { return GeneratePinningPath(info, context); } + return _innerMarshallingGenerator.Generate(info, context); } @@ -60,6 +71,7 @@ public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context) { return false; } + return _innerMarshallingGenerator.UsesNativeIdentifier(info, context); } private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContext context) @@ -67,32 +79,24 @@ private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContex return context.SingleFrameSpansNativeContext && !info.IsByRef && !info.IsManagedReturnPosition; } - private IEnumerable GeneratePinningPath(TypePositionInfo info, StubCodeContext context) + private static IEnumerable GeneratePinningPath(TypePositionInfo info, StubCodeContext context) { if (context.CurrentStage == StubCodeContext.Stage.Pin) { (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info); - string pinnedIdentifier = context.GetAdditionalIdentifier(info, "pinned"); + + // fixed (void* = ) yield return FixedStatement( VariableDeclaration( PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))), SingletonSeparatedList( - VariableDeclarator(Identifier(pinnedIdentifier)) + VariableDeclarator(Identifier(nativeIdentifier)) .WithInitializer(EqualsValueClause( IdentifierName(managedIdentifier) )) ) ), - // = (); - LocalDeclarationStatement( - VariableDeclaration(AsNativeType(info), - SingletonSeparatedList( - VariableDeclarator(nativeIdentifier) - .WithInitializer(EqualsValueClause( - CastExpression( - AsNativeType(info), - IdentifierName(pinnedIdentifier))))))) - ); + EmptyStatement()); } } }