From e4c1716c2ce87a37d463ce89d647cea04fa04b6e Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 23 Sep 2021 13:34:13 -0400 Subject: [PATCH] Convert Unsafe.As to unsafe code in BOOL to unblock net35 tests --- src/Microsoft.Windows.CsWin32/Generator.cs | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.Windows.CsWin32/Generator.cs b/src/Microsoft.Windows.CsWin32/Generator.cs index 707c5d54..5667e120 100644 --- a/src/Microsoft.Windows.CsWin32/Generator.cs +++ b/src/Microsoft.Windows.CsWin32/Generator.cs @@ -3729,21 +3729,17 @@ private StructDeclarationSyntax DeclareTypeDefBOOLStruct(TypeDefinition typeDef) .WithExpressionBody(ArrowExpressionClause(fieldAccessExpression)).WithSemicolonToken(SemicolonWithLineFeed) .AddModifiers(TokenWithSpace(this.Visibility))); - static InvocationExpressionSyntax UnsafeAs(SyntaxKind fromType, SyntaxKind toType, IdentifierNameSyntax localSource) => - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(nameof(Unsafe)), - GenericName(nameof(Unsafe.As), TypeArgumentList().AddArguments(PredefinedType(Token(fromType)), PredefinedType(Token(toType))))), - ArgumentList().AddArguments(Argument(localSource).WithRefKindKeyword(Token(SyntaxKind.RefKeyword)))); - - // BOOL(bool value) => this.value = Unsafe.As(ref value); + // unsafe BOOL(bool value) => this.value = *(sbyte*)&value; IdentifierNameSyntax valueParameter = IdentifierName("value"); - ExpressionSyntax boolToInt = UnsafeAs(SyntaxKind.BoolKeyword, SyntaxKind.SByteKeyword, valueParameter); + ExpressionSyntax boolToSByte = PrefixUnaryExpression( + SyntaxKind.PointerIndirectionExpression, + CastExpression( + PointerType(PredefinedType(TokenWithNoSpace(SyntaxKind.SByteKeyword))), + PrefixUnaryExpression(SyntaxKind.AddressOfExpression, valueParameter))); members = members.Add(ConstructorDeclaration(name.Identifier) - .AddModifiers(TokenWithSpace(this.Visibility)) + .AddModifiers(TokenWithSpace(this.Visibility), TokenWithSpace(SyntaxKind.UnsafeKeyword)) .AddParameterListParameters(Parameter(valueParameter.Identifier).WithType(PredefinedType(TokenWithSpace(SyntaxKind.BoolKeyword)))) - .WithExpressionBody(ArrowExpressionClause(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, fieldAccessExpression, boolToInt).WithOperatorToken(TokenWithSpaces(SyntaxKind.EqualsToken)))) + .WithExpressionBody(ArrowExpressionClause(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, fieldAccessExpression, boolToSByte).WithOperatorToken(TokenWithSpaces(SyntaxKind.EqualsToken)))) .WithSemicolonToken(SemicolonWithLineFeed)); // BOOL(int value) => this.value = value; @@ -3753,20 +3749,25 @@ static InvocationExpressionSyntax UnsafeAs(SyntaxKind fromType, SyntaxKind toTyp .WithExpressionBody(ArrowExpressionClause(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, fieldAccessExpression, valueParameter).WithOperatorToken(TokenWithSpaces(SyntaxKind.EqualsToken)))) .WithSemicolonToken(SemicolonWithLineFeed)); - // public static implicit operator bool(BOOL value) + // public unsafe static implicit operator bool(BOOL value) // { // sbyte v = checked((sbyte)value.value); - // return Unsafe.As(ref v); + // return *(bool*)&v; // } IdentifierNameSyntax localVarName = IdentifierName("v"); + ExpressionSyntax sbyteToBool = PrefixUnaryExpression( + SyntaxKind.PointerIndirectionExpression, + CastExpression( + PointerType(PredefinedType(TokenWithNoSpace(SyntaxKind.BoolKeyword))), + PrefixUnaryExpression(SyntaxKind.AddressOfExpression, localVarName))); var implicitBOOLtoBoolBody = Block().AddStatements( LocalDeclarationStatement(VariableDeclaration(PredefinedType(Token(SyntaxKind.SByteKeyword)))).AddDeclarationVariables( VariableDeclarator(localVarName.Identifier).WithInitializer(EqualsValueClause(CheckedExpression(SyntaxKind.CheckedExpression, CastExpression(PredefinedType(Token(SyntaxKind.SByteKeyword)), MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, valueParameter, fieldName)))))), - ReturnStatement(UnsafeAs(SyntaxKind.SByteKeyword, SyntaxKind.BoolKeyword, localVarName))); + ReturnStatement(sbyteToBool)); members = members.Add(ConversionOperatorDeclaration(Token(SyntaxKind.ImplicitKeyword), PredefinedType(Token(SyntaxKind.BoolKeyword))) .AddParameterListParameters(Parameter(valueParameter.Identifier).WithType(name.WithTrailingTrivia(TriviaList(Space)))) .WithBody(implicitBOOLtoBoolBody) - .AddModifiers(TokenWithSpace(SyntaxKind.PublicKeyword), TokenWithSpace(SyntaxKind.StaticKeyword))); // operators MUST be public + .AddModifiers(TokenWithSpace(SyntaxKind.PublicKeyword), TokenWithSpace(SyntaxKind.StaticKeyword), TokenWithSpace(SyntaxKind.UnsafeKeyword))); // operators MUST be public // public static implicit operator BOOL(bool value) => new BOOL(value); members = members.Add(ConversionOperatorDeclaration(Token(SyntaxKind.ImplicitKeyword), name)