public IEnumerable <StatementSyntax> GenerateGuaranteedUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { if (!_shape.HasFlag(MarshallerShape.GuaranteedUnmarshal)) { yield break; } (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info); string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(numElementsIdentifier), _numElementsExpression))); // <managedIdentifier> = <marshallerType>.AllocateContainerForManagedElementsFinally(<nativeIdentifier>, <numElements>); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(managedIdentifier), InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerTypeSyntax, IdentifierName(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForManagedElementsFinally)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(nativeIdentifier)), Argument(IdentifierName(numElementsIdentifier)) })))))); }
public IEnumerable <StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { if (!_shape.HasFlag(MarshallerShape.ToManaged)) { yield break; } if (!info.IsByRef && info.ByValueContentsMarshalKind.HasFlag(ByValueContentsMarshalKind.Out)) { yield return(GenerateByValueOutUnmarshalStatement(info, context)); } else { // int <numElements> = <numElementExpression> string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); yield return(LocalDeclarationStatement( VariableDeclaration( PredefinedType(Token(SyntaxKind.IntKeyword)), SingletonSeparatedList( VariableDeclarator(numElementsIdentifier) .WithInitializer(EqualsValueClause(_numElementsExpression)))))); yield return(GenerateUnmarshalStatement(info, context)); } foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, context)) { yield return(statement); } }
public StatementSyntax GenerateUnmarshalStatement(TypePositionInfo info, StubCodeContext context) { string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(info, context); string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(info, context); string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); // ReadOnlySpan<TUnmanagedElement> <nativeSpan> = <GetUnmanagedValuesSource> // Span<T> <managedSpan> = <GetManagedValuesDestination> // << unmarshal contents >> return(Block( LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_ReadOnlySpan), TypeArgumentList(SingletonSeparatedList(_unmanagedElementType))), SingletonSeparatedList( VariableDeclarator( Identifier(nativeSpanIdentifier)) .WithInitializer(EqualsValueClause( GetUnmanagedValuesSource(info, context)))))), LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList(SingletonSeparatedList(_elementInfo.ManagedType.Syntax))), SingletonSeparatedList( VariableDeclarator( Identifier(managedSpanIdentifier)) .WithInitializer(EqualsValueClause( GetManagedValuesDestination(info, context)))))), GenerateContentsMarshallingStatement( info, context, IdentifierName(numElementsIdentifier), StubCodeContext.Stage.UnmarshalCapture, StubCodeContext.Stage.Unmarshal))); }
public IEnumerable <StatementSyntax> GenerateSetupStatements(TypePositionInfo info, StubCodeContext context) { yield return(LocalDeclarationStatement( VariableDeclaration( PredefinedType(Token(SyntaxKind.IntKeyword)), SingletonSeparatedList( VariableDeclarator(MarshallerHelpers.GetNumElementsIdentifier(info, context)))))); }
public IEnumerable <StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info); string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); if (!info.IsByRef && info.ByValueContentsMarshalKind.HasFlag(ByValueContentsMarshalKind.Out)) { // <numElements> = <GetManagedValuesSource.Length; yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(numElementsIdentifier), MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GetManagedValuesSource(info, context), IdentifierName("Length"))))); yield return(GenerateByValueOutUnmarshalStatement(info, context)); } if (!_shape.HasFlag(MarshallerShape.ToManaged)) { yield break; } else { // <numElements> = <numElementsExpression>; yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(numElementsIdentifier), _numElementsExpression))); // <managedIdentifier> = <marshallerType>.AllocateContainerForManagedElements(<nativeIdentifier>, <numElements>); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(managedIdentifier), InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerTypeSyntax, IdentifierName(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForManagedElements)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(nativeIdentifier)), Argument(IdentifierName(numElementsIdentifier)) })))))); // ReadOnlySpan<TUnmanagedElement> <nativeSpan> = <marshallerType>.GetUnmanagedValuesSource(<nativeIdentifier>, <numElements>) // Span<T> <managedSpan> = <marshallerType>.GetManagedValuesDestination(<managedIdentifier>) // << unmarshal contents >> yield return(GenerateUnmarshalStatement(info, context)); } }
protected override InvocationExpressionSyntax GetManagedValuesDestination(TypePositionInfo info, StubCodeContext context) { string marshaller = StatefulValueMarshalling.GetMarshallerIdentifier(info, context); string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); // <marshaller>.GetManagedValuesDestination(<numElements>) return(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(marshaller), IdentifierName(ShapeMemberNames.LinearCollection.Stateless.GetManagedValuesDestination)), ArgumentList(SingletonSeparatedList( Argument(IdentifierName(numElementsIdentifier)))))); }
public IEnumerable <StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); if (!info.IsByRef && info.ByValueContentsMarshalKind.HasFlag(ByValueContentsMarshalKind.Out)) { // int <numElements> = <GetManagedValuesSource>.Length; yield return(LocalDeclarationStatement( VariableDeclaration( PredefinedType(Token(SyntaxKind.IntKeyword)), SingletonSeparatedList( VariableDeclarator(numElementsIdentifier) .WithInitializer(EqualsValueClause( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GetManagedValuesSource(info, context), IdentifierName("Length")))))))); yield return(GenerateByValueOutUnmarshalStatement(info, context)); } if (!_shape.HasFlag(MarshallerShape.ToManaged)) { yield break; } else { // int <numElements> = <numElementsExpression>; yield return(LocalDeclarationStatement( VariableDeclaration( PredefinedType(Token(SyntaxKind.IntKeyword)), SingletonSeparatedList( VariableDeclarator(numElementsIdentifier) .WithInitializer(EqualsValueClause(_numElementsExpression)))))); // ReadOnlySpan<TUnmanagedElement> <nativeSpan> = <marshaller>.GetUnmanagedValuesSource(<nativeIdentifier>, <numElements>) // Span<T> <managedSpan> = <marshaller>.GetManagedValuesDestination(<managedIdentifier>) // << unmarshal contents >> yield return(GenerateUnmarshalStatement(info, context)); } foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, context)) { yield return(statement); } }
protected override InvocationExpressionSyntax GetUnmanagedValuesSource(TypePositionInfo info, StubCodeContext context) { string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); string nativeIdentifier = context.GetIdentifiers(info).native; // <marshallerType>.GetUnmanagedValuesSource(<nativeIdentifier>, <numElements>) return(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, _marshallerTypeSyntax, IdentifierName(ShapeMemberNames.LinearCollection.Stateless.GetUnmanagedValuesSource)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(nativeIdentifier)), Argument(IdentifierName(numElementsIdentifier)) })))); }
public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context) { if (!_shape.HasFlag(MarshallerShape.ToUnmanaged) && !_shape.HasFlag(MarshallerShape.CallerAllocatedBuffer)) { yield break; } if (_shape.HasFlag(MarshallerShape.ToUnmanaged) && !(_shape.HasFlag(MarshallerShape.CallerAllocatedBuffer) && MarshallerHelpers.CanUseCallerAllocatedBuffer(info, context))) { (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info); string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); // <nativeIdentifier> = <marshallerType>.AllocateContainerForUnmanagedElements(<managedIdentifier>, out <numElements>); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerTypeSyntax, IdentifierName(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForUnmanagedElements)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(managedIdentifier)), Argument(IdentifierName(numElementsIdentifier)) .WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword)) })))))); } if (!info.IsByRef && info.ByValueContentsMarshalKind == ByValueContentsMarshalKind.Out) { yield return(GenerateByValueOutMarshalStatement(info, context)); } else { yield return(GenerateMarshalStatement(info, context)); } }
protected StatementSyntax GenerateByValueOutUnmarshalStatement(TypePositionInfo info, StubCodeContext context) { // Use ManagedSource and NativeDestination spans for by-value marshalling since we're just marshalling back the contents, // not the array itself. // This code is ugly since we're now enforcing readonly safety with ReadOnlySpan for all other scenarios, // but this is an uncommon case so we don't want to design the API around enabling just it. string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(info, context); // Span<TElement> <managedSpan> = MemoryMarshal.CreateSpan(ref Unsafe.AsRef(in <GetManagedValuesSource>.GetPinnableReference(), <numElements>)); LocalDeclarationStatementSyntax managedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList( SingletonSeparatedList(_elementInfo.ManagedType.Syntax)) ), SingletonSeparatedList(VariableDeclarator(managedSpanIdentifier).WithInitializer(EqualsValueClause( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, ParseName(TypeNames.System_Runtime_InteropServices_MemoryMarshal), IdentifierName("CreateSpan"))) .WithArgumentList( ArgumentList( SeparatedList( new[] { Argument( InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ParseName(TypeNames.System_Runtime_CompilerServices_Unsafe), IdentifierName("AsRef")), ArgumentList(SingletonSeparatedList( Argument( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GetManagedValuesSource(info, context), IdentifierName("GetPinnableReference")), ArgumentList())) .WithRefKindKeyword( Token(SyntaxKind.InKeyword)))))) .WithRefKindKeyword( Token(SyntaxKind.RefKeyword)), Argument( IdentifierName(numElementsIdentifier)) })))))))); // Span<TUnmanagedElement> <nativeSpan> = <GetUnmanagedValuesDestination> string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(info, context); LocalDeclarationStatementSyntax unmanagedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList(SingletonSeparatedList(_unmanagedElementType))), SingletonSeparatedList( VariableDeclarator( Identifier(nativeSpanIdentifier)) .WithInitializer(EqualsValueClause( GetUnmanagedValuesDestination(info, context)))))); return(Block( managedValuesDeclaration, unmanagedValuesDeclaration, GenerateContentsMarshallingStatement( info, context, IdentifierName(numElementsIdentifier), StubCodeContext.Stage.UnmarshalCapture, StubCodeContext.Stage.Unmarshal))); }
public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context) { if (MarshallerHelpers.CanUseCallerAllocatedBuffer(info, context)) { return(GenerateCallerAllocatedBufferMarshalStatements()); } return(_innerMarshaller.GenerateMarshalStatements(info, context)); IEnumerable <StatementSyntax> GenerateCallerAllocatedBufferMarshalStatements() { string bufferIdentifier = context.GetAdditionalIdentifier(info, "buffer"); // Span<bufferElementType> <bufferIdentifier> = stackalloc <bufferElementType>[<marshallerType>.BufferSize]; yield return(LocalDeclarationStatement( VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList( SingletonSeparatedList(_bufferElementType))), SingletonSeparatedList( VariableDeclarator(bufferIdentifier) .WithInitializer(EqualsValueClause( StackAllocArrayCreationExpression( ArrayType( _bufferElementType, SingletonList(ArrayRankSpecifier(SingletonSeparatedList <ExpressionSyntax>( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerType, IdentifierName(ShapeMemberNames.BufferSize)) ))))))))))); (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info); if (_isLinearCollectionMarshalling) { string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); // <nativeIdentifier> = <marshallerType>.AllocateContainerForUnmanagedElements(<managedIdentifier>, <bufferIdentifier>, out <numElements>); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerType, IdentifierName(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForUnmanagedElements)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(managedIdentifier)), Argument(IdentifierName(bufferIdentifier)), Argument(IdentifierName(numElementsIdentifier)) .WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword)) })))))); // Linear collections have additional marshalling required using the inner marshaller foreach (StatementSyntax statement in _innerMarshaller.GenerateMarshalStatements(info, context)) { yield return(statement); } } else { // <nativeIdentifier> = <marshallerType>.ConvertToUnmanaged(<managedIdentifier>, <nativeIdentifier>__buffer); yield return(ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerType, IdentifierName(ShapeMemberNames.Value.Stateless.ConvertToUnmanaged)), ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(managedIdentifier)), Argument(IdentifierName(bufferIdentifier)) })))))); } } }