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(); }
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; } }