public IEnumerable <StatementSyntax> GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context) { if (MarshallerHelpers.CanUseCallerAllocatedBuffer(info, context)) { return(GenerateCallerAllocatedBufferMarshalStatements()); } return(_innerMarshaller.GenerateMarshalStatements(info, context)); IEnumerable <StatementSyntax> GenerateCallerAllocatedBufferMarshalStatements() { // TODO: Update once we can consume the scoped keword. We should be able to simplify this once we get that API. string stackPtrIdentifier = context.GetAdditionalIdentifier(info, "stackptr"); // <bufferElementType>* <managedIdentifier>__stackptr = stackalloc <bufferElementType>[<_bufferSize>]; yield return(LocalDeclarationStatement( VariableDeclaration( PointerType(_bufferElementType), SingletonSeparatedList( VariableDeclarator(stackPtrIdentifier) .WithInitializer(EqualsValueClause( StackAllocArrayCreationExpression( ArrayType( _bufferElementType, SingletonList(ArrayRankSpecifier(SingletonSeparatedList <ExpressionSyntax>( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerType, IdentifierName(ShapeMemberNames.BufferSize)) ))))))))))); (string managedIdentifier, _) = context.GetIdentifiers(info); // <marshaller>.FromManaged(<managedIdentifier>, new Span<bufferElementType>(<stackPtrIdentifier>, <marshallerType>.BufferSize)); yield return(ExpressionStatement( InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(context.GetAdditionalIdentifier(info, StatefulValueMarshalling.MarshallerIdentifier)), IdentifierName(ShapeMemberNames.Value.Stateful.FromManaged)), ArgumentList(SeparatedList( new[] { Argument(IdentifierName(managedIdentifier)), Argument( ObjectCreationExpression( GenericName(Identifier(TypeNames.System_Span), TypeArgumentList(SingletonSeparatedList( _bufferElementType)))) .WithArgumentList( ArgumentList(SeparatedList(new ArgumentSyntax[] { Argument(IdentifierName(stackPtrIdentifier)), Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, _marshallerType, IdentifierName(ShapeMemberNames.BufferSize))) })))) }))))); } }
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)); } }
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)) })))))); } } }