Example #1
0
        public static void ParameterInitMiddleware(ref IMarshalContext ctx, Action next)
        {
            for (int index = 0; index < ctx.MethodSymbol.Parameters.Length; index++)
            {
                var symbol = ctx.MethodSymbol.Parameters[index];
                var id     = ctx.DeclareVariable(symbol.Type);
                ctx.SetVariable(id, _ => IdentifierName(FormatName(symbol.Name)));
                ctx.SetParameterToVariable(index, id);
            }

            next();
        }
        public static void GenericPointerMarshaller(ref IMarshalContext ctx, Action next)
        {
            for (int i = 0; i < ctx.LoadTypes.Length - 1; i++)
            {
                var lt = ctx.LoadTypes[i];
                if (lt is IPointerTypeSymbol pts)
                {
                    if (pts.PointedAtType is ITypeParameterSymbol tps)
                    {
                        var id = ctx.DeclareVariable
                                 (
                            ctx.Compilation.CreatePointerTypeSymbol
                                (ctx.Compilation.GetSpecialType(SpecialType.System_Void))
                                 );
                        var baseId = ctx.ParameterVariables[i];
                        ctx.SetVariable(id, ctx => CastExpression(IdentifierName("void*"), ctx.ResolveVariable(baseId).Value));
                        ctx.SetParameterToVariable(i, id);
                    }
                }
            }

            next();
        }
Example #3
0
        public static void DelegateMarshaller(ref IMarshalContext ctx, Action next)
        {
            for (var index = 0; index < ctx.ParameterVariables.Length; index++)
            {
                var options = ctx.ParameterMarshalOptions[index];

                if (ctx.LoadTypes[index].TypeKind != TypeKind.Delegate)
                {
                    continue;
                }

                ctx.LoadTypes[index] = ctx.Compilation.GetSpecialType(SpecialType.System_IntPtr);
                var id = ctx.DeclareVariable(ctx.LoadTypes[index]);
                var parameterVariable = ctx.ResolveVariable(ctx.ParameterVariables[index]);
                ctx.SetVariable
                (
                    id, ctx => ConditionalExpression
                    (
                        BinaryExpression
                        (
                            SyntaxKind.EqualsExpression, parameterVariable.Value,
                            LiteralExpression(SyntaxKind.NullLiteralExpression)
                        ),
                        MemberAccessExpression
                        (
                            SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(IntPtr)),
                            IdentifierName(nameof(IntPtr.Zero))
                        ), InvocationExpression
                            ( // System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer<T>(ResultName)
                            MemberAccessExpression
                            (
                                SyntaxKind.SimpleMemberAccessExpression,
                                MemberAccessExpression
                                (
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    MemberAccessExpression
                                    (
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        MemberAccessExpression
                                        (
                                            SyntaxKind.SimpleMemberAccessExpression, IdentifierName("System"),
                                            IdentifierName("Runtime")
                                        ), IdentifierName("InteropServices")
                                    ), IdentifierName("Marshal")
                                ), IdentifierName("GetFunctionPointerForDelegate")
                            ), ArgumentList(SingletonSeparatedList(Argument(parameterVariable.Value)))
                            )
                    )
                );
                ctx.SetParameterToVariable(index, id);
            }

            int resultLocalId     = default;
            var processReturn     = ctx.ReturnLoadType.TypeKind == TypeKind.Delegate;
            var oldReturnLoadType = ctx.ReturnLoadType;

            if (processReturn)
            {
                resultLocalId      = ctx.DeclareVariable(ctx.ReturnLoadType);
                ctx.ReturnLoadType = ctx.Compilation.GetSpecialType(SpecialType.System_IntPtr);
            }

            next();

            if (processReturn)
            {
                var resultVariable = ctx.ResolveVariable(ctx.ResultVariable.Value);
                ctx.SetVariable
                (
                    resultLocalId, ctx => ConditionalExpression
                    (
                        BinaryExpression
                        (
                            SyntaxKind.EqualsExpression, resultVariable.Value,
                            MemberAccessExpression
                            (
                                SyntaxKind.SimpleMemberAccessExpression, IdentifierName("IntPtr"),
                                IdentifierName("Zero")
                            )
                        ), LiteralExpression(SyntaxKind.NullLiteralExpression), InvocationExpression
                            ( // System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer<T>(ResultName)
                            MemberAccessExpression
                            (
                                SyntaxKind.SimpleMemberAccessExpression,
                                MemberAccessExpression
                                (
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    MemberAccessExpression
                                    (
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        MemberAccessExpression
                                        (
                                            SyntaxKind.SimpleMemberAccessExpression, IdentifierName("System"),
                                            IdentifierName("Runtime")
                                        ), IdentifierName("InteropServices")
                                    ), IdentifierName("Marshal")
                                ),
                                GenericName
                                (
                                    Identifier("GetDelegateForFunctionPointer"),
                                    TypeArgumentList
                                    (
                                        SingletonSeparatedList
                                        (
                                            (TypeSyntax)IdentifierName
                                            (
                                                oldReturnLoadType.ToDisplayString
                                                    (SymbolDisplayFormat.FullyQualifiedFormat)
                                            )
                                        )
                                    )
                                )
                            ),
                            ArgumentList
                                (SingletonSeparatedList(Argument(resultVariable.Value)))
                            )
                    )
                );
                ctx.ResultVariable = resultLocalId;
            }
        }