Ejemplo n.º 1
0
        public IEnumerable <StatementSyntax> GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context)
        {
            if (!_shape.HasFlag(MarshallerShape.Free))
            {
                yield break;
            }

            // <marshaller>.Free();
            yield return(ExpressionStatement(
                             InvocationExpression(
                                 MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                        IdentifierName(context.GetAdditionalIdentifier(info, MarshallerIdentifier)),
                                                        IdentifierName(ShapeMemberNames.Free)),
                                 ArgumentList())));
        }
Ejemplo n.º 2
0
        public IEnumerable <StatementSyntax> GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context)
        {
            if (!_shape.HasFlag(MarshallerShape.Free))
            {
                yield break;
            }

            // <marshallerType>.Free(<nativeIdentifier>);
            yield return(ExpressionStatement(
                             InvocationExpression(
                                 MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                        _marshallerTypeSyntax,
                                                        IdentifierName(ShapeMemberNames.Free)),
                                 ArgumentList(SingletonSeparatedList(
                                                  Argument(IdentifierName(context.GetIdentifiers(info).native)))))));
        }
Ejemplo n.º 3
0
        public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context)
        {
            if (!_shape.HasFlag(MarshallerShape.ToUnmanaged) && !_shape.HasFlag(MarshallerShape.CallerAllocatedBuffer))
            {
                yield break;
            }

            foreach (StatementSyntax statement in _innerMarshaller.GenerateMarshalStatements(info, context))
            {
                yield return(statement);
            }

            if (!info.IsByRef && info.ByValueContentsMarshalKind == ByValueContentsMarshalKind.Out)
            {
                yield return(GenerateByValueOutMarshalStatement(info, context));

                yield break;
            }

            yield return(GenerateMarshalStatement(info, context));
        }
Ejemplo n.º 4
0
        public IEnumerable <StatementSyntax> GenerateGuaranteedUnmarshalStatements(TypePositionInfo info, StubCodeContext context)
        {
            if (!_shape.HasFlag(MarshallerShape.GuaranteedUnmarshal))
            {
                yield break;
            }

            (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);

            // <managedIdentifier> = <marshallerType>.ConvertToManagedFinally(<nativeIdentifier>);
            yield return(ExpressionStatement(
                             AssignmentExpression(
                                 SyntaxKind.SimpleAssignmentExpression,
                                 IdentifierName(managedIdentifier),
                                 InvocationExpression(
                                     MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                            _marshallerTypeSyntax,
                                                            IdentifierName(ShapeMemberNames.Value.Stateless.ConvertToManagedFinally)),
                                     ArgumentList(SingletonSeparatedList(
                                                      Argument(IdentifierName(nativeIdentifier))))))));
        }
Ejemplo n.º 5
0
        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))
            }))))));
        }
Ejemplo n.º 6
0
        public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context)
        {
            if (!_shape.HasFlag(MarshallerShape.ToUnmanaged) && !_shape.HasFlag(MarshallerShape.CallerAllocatedBuffer))
            {
                yield break;
            }

            foreach (StatementSyntax statement in _innerMarshaller.GenerateMarshalStatements(info, context))
            {
                yield return(statement);
            }

            if (!info.IsByRef && info.ByValueContentsMarshalKind == ByValueContentsMarshalKind.Out)
            {
                yield return(GenerateByValueOutMarshalStatement(info, context));

                yield break;
            }

            // ReadOnlySpan<T> <managedSpan> = <marshaller>.GetManagedValuesSource()
            // Span<TUnmanagedElement> <nativeSpan> = <marshaller>.GetUnmanagedValuesDestination()
            // << marshal contents >>
            yield return(GenerateMarshalStatement(info, context));
        }
Ejemplo n.º 7
0
        public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context, IEnumerable <ArgumentSyntax> nativeTypeConstructorArguments)
        {
            if (!_shape.HasFlag(MarshallerShape.ToUnmanaged))
            {
                yield break;
            }

            (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
            string numElementsIdentifier = 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))
            }))))));

            // <marshallerType>.GetUnmanagedValuesDestination(<nativeIdentifier>, <numElements>)
            ExpressionSyntax destination =
                InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        _marshallerTypeSyntax,
                        IdentifierName(ShapeMemberNames.LinearCollection.Stateless.GetUnmanagedValuesDestination)),
                    ArgumentList(SeparatedList(new ArgumentSyntax[]
            {
                Argument(IdentifierName(nativeIdentifier)),
                Argument(IdentifierName(numElementsIdentifier)),
            })));

            if (!info.IsByRef && info.ByValueContentsMarshalKind == ByValueContentsMarshalKind.Out)
            {
                // If the parameter is marshalled by-value [Out], then we don't marshal the contents of the collection.
                // We do clear the span, so that if the invoke target doesn't fill it, we aren't left with undefined content.
                // <marshallerType>.GetUnmanagedValuesDestination(<nativeIdentifier>, <numElements>).Clear();
                yield return(ExpressionStatement(
                                 InvocationExpression(
                                     MemberAccessExpression(
                                         SyntaxKind.SimpleMemberAccessExpression,
                                         destination,
                                         IdentifierName("Clear")))));

                yield break;
            }

            // Skip the cast if the managed and unmanaged element types are the same
            if (!_unmanagedElementType.IsEquivalentTo(_managedElementType))
            {
                // MemoryMarshal.Cast<<unmanagedElementType>, <managedElementType>>(<destination>)
                destination = InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        ParseTypeName(TypeNames.System_Runtime_InteropServices_MemoryMarshal),
                        GenericName(
                            Identifier("Cast"))
                        .WithTypeArgumentList(
                            TypeArgumentList(
                                SeparatedList(
                                    new[]
                {
                    _unmanagedElementType,
                    _managedElementType
                })))),
                    ArgumentList(SingletonSeparatedList(
                                     Argument(destination))));
            }

            // <marshallerType>.GetManagedValuesSource(<managedIdentifer>).CopyTo(<destination>);
            yield return(ExpressionStatement(
                             InvocationExpression(
                                 MemberAccessExpression(
                                     SyntaxKind.SimpleMemberAccessExpression,
                                     InvocationExpression(
                                         MemberAccessExpression(
                                             SyntaxKind.SimpleMemberAccessExpression,
                                             _marshallerTypeSyntax,
                                             IdentifierName(ShapeMemberNames.LinearCollection.Stateless.GetManagedValuesSource)),
                                         ArgumentList(SingletonSeparatedList(
                                                          Argument(IdentifierName(managedIdentifier))))),
                                     IdentifierName("CopyTo")))
                             .AddArgumentListArguments(
                                 Argument(destination))));
        }