Skip to content

Commit

Permalink
[LibraryImportGenerator] Reduce unnecessary casting/locals in pinning…
Browse files Browse the repository at this point in the history
… path (dotnet#69804)
  • Loading branch information
elinor-fung authored May 26, 2022
1 parent 74aa24c commit 5ba2911
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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).
/// </summary>
ManagedTypeAndAttributes,

/// <summary>
/// The native signature should be the type returned by <see cref="IMarshallingGenerator.AsNativeType(TypePositionInfo)"/> passed by value.
/// </summary>
NativeType,

/// <summary>
/// The native signature should be a pointer to the type returned by <see cref="IMarshallingGenerator.AsNativeType(TypePositionInfo)"/> passed by value.
/// </summary>
Expand All @@ -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.
/// </summary>
ManagedIdentifier,

/// <summary>
/// The native identifier provided by <see cref="StubCodeContext.GetIdentifiers(TypePositionInfo)"/> should be passed by value.
/// </summary>
NativeIdentifier,

/// <summary>
/// The address of the native identifier provided by <see cref="StubCodeContext.GetIdentifiers(TypePositionInfo)"/> should be passed by value.
/// </summary>
AddressOfNativeIdentifier
AddressOfNativeIdentifier,

/// <summary>
/// The native identifier provided by <see cref="StubCodeContext.GetIdentifiers(TypePositionInfo)"/> should be cast to the native type.
/// </summary>
CastNativeIdentifier
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ private static ParameterSyntax GenerateForwardingParameter(TypePositionInfo info
return param;
}


private static bool TryRehydrateMarshalAsAttribute(TypePositionInfo info, out AttributeSyntax marshalAsAttribute)
{
marshalAsAttribute = null!;
Expand Down Expand Up @@ -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()
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

Expand All @@ -46,6 +56,7 @@ public IEnumerable<StatementSyntax> Generate(TypePositionInfo info, StubCodeCont
{
return GeneratePinningPath(info, context);
}

return _innerMarshallingGenerator.Generate(info, context);
}

Expand All @@ -60,39 +71,32 @@ public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context)
{
return false;
}

return _innerMarshallingGenerator.UsesNativeIdentifier(info, context);
}
private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContext context)
{
return context.SingleFrameSpansNativeContext && !info.IsByRef && !info.IsManagedReturnPosition;
}

private IEnumerable<StatementSyntax> GeneratePinningPath(TypePositionInfo info, StubCodeContext context)
private static IEnumerable<StatementSyntax> 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* <nativeIdentifier> = <managedIdentifier>)
yield return FixedStatement(
VariableDeclaration(
PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))),
SingletonSeparatedList(
VariableDeclarator(Identifier(pinnedIdentifier))
VariableDeclarator(Identifier(nativeIdentifier))
.WithInitializer(EqualsValueClause(
IdentifierName(managedIdentifier)
))
)
),
// <nativeType> <native> = (<nativeType>)<pinned>;
LocalDeclarationStatement(
VariableDeclaration(AsNativeType(info),
SingletonSeparatedList(
VariableDeclarator(nativeIdentifier)
.WithInitializer(EqualsValueClause(
CastExpression(
AsNativeType(info),
IdentifierName(pinnedIdentifier)))))))
);
EmptyStatement());
}
}
}
Expand Down

0 comments on commit 5ba2911

Please sign in to comment.