private 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");
         yield return(FixedStatement(
                          VariableDeclaration(
                              PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))),
                              SingletonSeparatedList(
                                  VariableDeclarator(Identifier(pinnedIdentifier))
                                  .WithInitializer(EqualsValueClause(
                                                       IdentifierName(managedIdentifier)
                                                       ))
                                  )
                              ),
                          // <nativeType> <native> = (<nativeType>)<pinned>;
                          LocalDeclarationStatement(
                              VariableDeclaration(AsNativeType(info),
                                                  SingletonSeparatedList(
                                                      VariableDeclarator(nativeIdentifier)
                                                      .WithInitializer(EqualsValueClause(
                                                                           CastExpression(
                                                                               AsNativeType(info),
                                                                               IdentifierName(pinnedIdentifier)))))))
                          ));
     }
 }
예제 #2
0
        private IEnumerable <StatementSyntax> GeneratePinningPath(TypePositionInfo info, StubCodeContext context)
        {
            if (context.CurrentStage == StubCodeContext.Stage.Pin)
            {
                (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);

                // fixed (void* <nativeIdentifier> = &<getPinnableReferenceType>.GetPinnableReference(<managedIdentifier>))
                yield return(FixedStatement(
                                 VariableDeclaration(
                                     PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))),
                                     SingletonSeparatedList(
                                         VariableDeclarator(Identifier(nativeIdentifier))
                                         .WithInitializer(EqualsValueClause(
                                                              PrefixUnaryExpression(SyntaxKind.AddressOfExpression,
                                                                                    InvocationExpression(
                                                                                        MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                                               _getPinnableReferenceType,
                                                                                                               IdentifierName(ShapeMemberNames.GetPinnableReference)),
                                                                                        ArgumentList(SingletonSeparatedList(
                                                                                                         Argument(IdentifierName(managedIdentifier))))))
                                                              ))
                                         )
                                     ),
                                 EmptyStatement()));
            }
        }
예제 #3
0
        public ArgumentSyntax AsArgument(TypePositionInfo info, StubCodeContext context)
        {
            (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
            if (!info.IsByRef)
            {
                // (ushort)<managedIdentifier>
                return(Argument(
                           CastExpression(
                               AsNativeType(info),
                               IdentifierName(managedIdentifier))));
            }
            else if (IsPinningPathSupported(info, context))
            {
                // (ushort*)<pinned>
                return(Argument(
                           CastExpression(
                               PointerType(AsNativeType(info)),
                               IdentifierName(PinnedIdentifier(info.InstanceIdentifier)))));
            }

            // &<nativeIdentifier>
            return(Argument(
                       PrefixUnaryExpression(
                           SyntaxKind.AddressOfExpression,
                           IdentifierName(nativeIdentifier))));
        }
예제 #4
0
 protected override ExpressionSyntax GenerateByteLengthCalculationExpression(TypePositionInfo info, StubCodeContext context)
 {
     // + 1 for number of characters in case left over high surrogate is ?
     // * <MaxByteCountPerChar> (3 for UTF-8)
     // +1 for null terminator
     // int <byteLen> = (<managed>.Length + 1) * 3 + 1;
     return(BinaryExpression(
                SyntaxKind.AddExpression,
                BinaryExpression(
                    SyntaxKind.MultiplyExpression,
                    ParenthesizedExpression(
                        BinaryExpression(
                            SyntaxKind.AddExpression,
                            MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                IdentifierName(context.GetIdentifiers(info).managed),
                                IdentifierName("Length")),
                            LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(1)))),
                    LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(MaxByteCountPerChar))),
                LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(1))));
 }