From 0d11977733f8f2cc6bafd5430e21413c4a754277 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Thu, 28 Nov 2024 00:28:37 +0100 Subject: [PATCH 1/7] Added SwiftSelf to function signatures --- .../StringCSharpEmitter/Handler/MethodHandler.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index 74747ef0aa11..a30b96872388 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -59,7 +59,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto { var methodEnv = (MethodEnvironment)env; var methodDecl = (MethodDecl)methodEnv.MethodDecl; - + // Emit PInvoke method EmitPInvoke(writer, methodEnv, typeDatabase); @@ -146,7 +146,7 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) if (methodDecl.MethodType == MethodType.Instance) { - writer.WriteLine($"{parentDecl.Name} self = this;"); + writer.WriteLine($"var self = new System.Runtime.InteropServices.Swift.SwiftSelf<{parentDecl.Name}>(this);"); } string returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; string methodArgs = string.Join(", ", methodDecl.CSSignature.Skip(1).Select(p => p.Name)); @@ -171,9 +171,10 @@ private List GetMethodParams(MethodDecl methodDecl) if (!methodDecl.IsConstructor && methodDecl.MethodType != MethodType.Static) { // Add self as the first parameter (after the return type) - tempDecl.Insert(1, new ArgumentDecl { - SwiftTypeSpec = new NamedTypeSpec (parentDecl.Name), - CSTypeIdentifier = new TypeDecl { Name = parentDecl.Name, MangledName = string.Empty, Fields = new List(), Declarations = new List(), ParentDecl = parentDecl, ModuleDecl = parentDecl.ModuleDecl}, + tempDecl.Insert(1, new ArgumentDecl + { + SwiftTypeSpec = new NamedTypeSpec(parentDecl.Name), + CSTypeIdentifier = new TypeDecl { Name = $"System.Runtime.InteropServices.Swift.SwiftSelf<{parentDecl.Name}>", MangledName = string.Empty, Fields = new List(), Declarations = new List(), ParentDecl = parentDecl, ModuleDecl = parentDecl.ModuleDecl }, Name = "self", PrivateName = string.Empty, IsInOut = false, From b54ced75aa682d51752788c669babcadf281df5a Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Wed, 11 Dec 2024 18:26:05 +0100 Subject: [PATCH 2/7] Added projections of non-frozen functions --- .gitignore | 1 + .../Handler/MethodHandler.cs | 379 ++++-- .../Handler/ModuleHandler.cs | 10 +- .../Handler/TypeHandler.cs | 166 ++- .../src/Marshaler/MarshallingExtensions.cs | 46 + src/Swift.Bindings/src/Model/StructDecl.cs | 3 + .../src/Parser/SwiftABIParser.cs | 34 +- .../NonFrozenStructsTests.Source.cs | 141 +++ .../NonFrozenStructs/NonFrozenStructsTests.cs | 169 +++ .../NonFrozenStructsTests.swift | 1070 +++++++++++++++++ src/Swift.Runtime/src/TypeDatabase.cs | 8 +- src/Swift.Runtime/src/TypeDatabase.xml | 44 +- src/Swift.Runtime/src/TypeRegistrar.cs | 12 +- 13 files changed, 1915 insertions(+), 168 deletions(-) create mode 100644 src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs create mode 100644 src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs create mode 100644 src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs create mode 100644 src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift diff --git a/.gitignore b/.gitignore index e973ccc28494..88dd960af910 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ msbuild.wrn .libs/ *.lo *.o +build/ # Cross directory eng/common/cross diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index a30b96872388..e124d66135d8 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -6,6 +6,98 @@ namespace BindingsGeneration { + /// + /// Factory class for creating instances of ConstructorHandler. + /// + public class ConstructorHandlerFactory : IFactory + { + /// + /// Determines if the factory handles the specified declaration. + /// + /// The base declaration. + public bool Handles(BaseDecl decl) + { + return decl is MethodDecl methodDecl && methodDecl.IsConstructor; + } + + /// + /// Constructs a new instance of ConstructorHandler. + /// + public IMethodHandler Construct() + { + return new ConstructorHandler(); + } + } + + /// + /// Handler class for constructor declarations. + /// + public class ConstructorHandler : BaseHandler, IMethodHandler + { + public ConstructorHandler() + { + } + + /// + /// Marshals the specified constructor. + /// + /// + public IEnvironment Marshal(BaseDecl decl) + { + return new MethodEnvironment(decl); + } + + /// + /// Emits the code for the specified environment. + /// + /// The IndentedTextWriter instance. + /// The environment. + /// The conductor instance. + /// The type database instance. + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + { + var methodEnv = (MethodEnvironment)env; + EmitWrapper(writer, methodEnv, typeDatabase); + PInvokeEmitter.EmitPInvoke(writer, methodEnv, typeDatabase); + writer.WriteLine(); + } + + /// + /// Emits the wrapper method declaration. + /// + /// The IndentedTextWriter instance. + /// The method environment. + /// The type database instance. + private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment methodEnv, TypeDatabase typeDatabase) + { + var methodDecl = (MethodDecl)methodEnv.MethodDecl; + var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); + writer.WriteLine($"public {parentDecl.Name}({SignatureHandler.GetCSWrapperSignature(methodDecl)})"); + + writer.WriteLine("{"); + writer.Indent++; + + string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; + + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + string invokeArguments = pInvokeSignature.ParametersNames(); + + if (methodDecl.RequiresIndirectResult(parentDecl, typeDatabase)) + { + writer.WriteLine($"_payload = (SwiftHandle)NativeMemory.Alloc(_payloadSize);"); + writer.WriteLine("var swiftIndirectResult = new SwiftIndirectResult((void*)_payload);"); + writer.WriteLine($"{PInvokeName}({invokeArguments});"); + } + else + { + writer.WriteLine($"this = {PInvokeName}({invokeArguments});"); + } + + writer.Indent--; + writer.WriteLine("}"); + } + } + /// /// Represents a method handler factory. /// @@ -18,13 +110,13 @@ public class MethodHandlerFactory : IFactory /// public bool Handles(BaseDecl decl) { - return decl is MethodDecl; + return decl is MethodDecl methodDecl && !methodDecl.IsConstructor; } /// /// Constructs a handler. /// - public IMethodHandler Construct () + public IMethodHandler Construct() { return new MethodHandler(); } @@ -35,7 +127,7 @@ public IMethodHandler Construct () /// public class MethodHandler : BaseHandler, IMethodHandler { - public MethodHandler () + public MethodHandler() { } @@ -58,168 +150,243 @@ public IEnvironment Marshal(BaseDecl methodDecl) public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) { var methodEnv = (MethodEnvironment)env; - var methodDecl = (MethodDecl)methodEnv.MethodDecl; - - // Emit PInvoke method - EmitPInvoke(writer, methodEnv, typeDatabase); - - // Emit wrapper method if marshalling is required - if (methodDecl.ParentDecl is StructDecl || methodDecl.ParentDecl is ClassDecl) - { - if (methodDecl.IsConstructor) - { - // Emit constructor - EmitConstructor(writer, methodEnv); - } - else - { - // Emit method - EmitWrapperMethod(writer, methodEnv); - } - } + EmitWrapperMethod(writer, methodEnv, typeDatabase); + PInvokeEmitter.EmitPInvoke(writer, methodEnv, typeDatabase); writer.WriteLine(); } /// - /// Emits the PInvoke method declaration. + /// Emits the wrapper method declaration. /// /// The IndentedTextWriter instance. /// The environment. /// The type database. - private void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment env, TypeDatabase typeDatabase) + private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env, TypeDatabase typeDatabase) { var methodDecl = (MethodDecl)env.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - - string accessModifier = parentDecl == moduleDecl ? "public" : "internal"; - string methodType = methodDecl.IsConstructor ? parentDecl.Name : methodDecl.CSSignature.First().CSTypeIdentifier.Name; - string methodName = parentDecl == moduleDecl ? methodDecl.Name : $"{env.PInvokePrefix}{methodDecl.Name}"; - string libPath = typeDatabase.GetLibraryName(moduleDecl.Name); - - writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); - writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{methodDecl.MangledName}\")]"); - writer.WriteLine($"{accessModifier} static extern {methodType} {methodName}({GetInternalMethodSignature(methodDecl)});"); - } - - /// - /// Emits the constructor declaration. - /// - /// The IndentedTextWriter instance. - /// The environment declaration. - private void EmitConstructor(IndentedTextWriter writer, MethodEnvironment env) - { - var methodDecl = (MethodDecl)env.MethodDecl; - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); string methodName = $"{env.PInvokePrefix}{methodDecl.Name}"; - writer.WriteLine($"public {parentDecl.Name}({GetPublicMethodSignature(methodDecl)})"); + writer.WriteLine($"public {((methodDecl.MethodType == MethodType.Static || parentDecl is ModuleDecl) ? "static " : "")}{methodDecl.CSSignature.First().CSTypeIdentifier.Name} {methodDecl.Name}({SignatureHandler.GetCSWrapperSignature(methodDecl)})"); writer.WriteLine("{"); writer.Indent++; - string methodArgs = string.Join(", ", methodDecl.CSSignature.Skip(1).Select(p => p.Name)); - writer.WriteLine($"this = {methodName}({GetMethodArgs(methodDecl)});"); + if (methodDecl.RequiresSwiftSelf(parentDecl)) + { + if (parentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct()) + writer.WriteLine($"var self = new SwiftSelf<{parentDecl.Name}>(this);"); + else + writer.WriteLine($"var self = new SwiftSelf((void*)_payload);"); + } + + // TODO: Add Indirect result marshalling to methods other than constructors + + string returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; + + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + string invokeArguments = pInvokeSignature.ParametersNames(); + + // Call the PInvoke method + writer.WriteLine($"{returnPrefix}{methodName}({invokeArguments});"); writer.Indent--; writer.WriteLine("}"); } + } + + /// + /// Represents a PInvoke argument. + /// + /// + /// + internal record PInvokeArgument(string Type, string Name) + { + public override string ToString() => $"{Type} {Name}"; + } + + /// + /// Represents a PInvoke signature. + /// + /// + /// + internal record PInvokeSignature(string ReturnType, IReadOnlyList Parameters) + { + public string ParametersString() => string.Join(", ", Parameters.Select(p => p.ToString())); + + public string ParametersNames() => string.Join(", ", Parameters.Select(p => + p.Type == "SwiftHandle" ? $"{p.Name}.Payload" : p.Name)); // TODO: Find a better way to do this + } + + /// + /// Represents a PInvoke signature builder. + /// + internal class PInvokeSignatureBuilder + { + private string _returnType = "invalid"; + private readonly List _parameters = new(); + + MethodDecl MethodDecl { get; } + BaseDecl ParentDecl { get; } + TypeDatabase TypeDatabase { get; } + /// - /// Emits the wrapper method declaration. + /// Initializes a new instance of the class. /// - /// The IndentedTextWriter instance. - /// The environment. - private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) + /// The method declaration. + /// The parent declaration. + /// The type database. + public PInvokeSignatureBuilder(MethodDecl methodDecl, BaseDecl parentDecl, TypeDatabase typeDatabase) { - var methodDecl = (MethodDecl)env.MethodDecl; - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - - string methodName = $"{env.PInvokePrefix}{methodDecl.Name}"; - - writer.WriteLine($"public {(methodDecl.MethodType == MethodType.Static ? "static " : "")}{methodDecl.CSSignature.First().CSTypeIdentifier.Name} {methodDecl.Name}({GetPublicMethodSignature(methodDecl)})"); - writer.WriteLine("{"); - writer.Indent++; + MethodDecl = methodDecl; + ParentDecl = parentDecl; + TypeDatabase = typeDatabase; + } - if (methodDecl.MethodType == MethodType.Instance) + /// + /// Handles the return type of the method. + /// + public void HandleReturnType() + { + if (!MethodDecl.RequiresIndirectResult(ParentDecl, TypeDatabase)) { - writer.WriteLine($"var self = new System.Runtime.InteropServices.Swift.SwiftSelf<{parentDecl.Name}>(this);"); + var returnType = MethodDecl.CSSignature.First().CSTypeIdentifier.Name; + SetReturnType(returnType); + } + else + { + AddParameter("SwiftIndirectResult", "swiftIndirectResult"); + SetReturnType("void"); } - string returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; - string methodArgs = string.Join(", ", methodDecl.CSSignature.Skip(1).Select(p => p.Name)); - writer.WriteLine($"{returnPrefix}{methodName}({GetMethodArgs(methodDecl)});"); - writer.Indent--; - writer.WriteLine("}"); } /// - /// Gets the method parameters. + /// Handles the arguments of the method. /// - /// The method declaration. - /// The list of method parameters. - private List GetMethodParams(MethodDecl methodDecl) + public void HandleArguments() { - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - List tempDecl = new(methodDecl.CSSignature); + foreach (var argument in MethodDecl.CSSignature.Skip(1)) + { + var typeRecord = TypeDatabase.Registrar.GetType(argument); + if (typeRecord.IsFrozen && typeRecord.IsBlittable) + { + AddParameter(argument.CSTypeIdentifier.Name, argument.Name); + } + else + { + AddParameter($"SwiftHandle", argument.Name); + } + } + } - // If this is a type method, add the marshalling for the self parameter - if (parentDecl is StructDecl || parentDecl is ClassDecl) + /// + /// Handles the Swift self parameter of the method. + /// + public void HandleSwiftSelf() + { + if (MethodDecl.RequiresSwiftSelf(ParentDecl)) { - if (!methodDecl.IsConstructor && methodDecl.MethodType != MethodType.Static) + if (ParentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct()) + { + AddParameter($"SwiftSelf<{ParentDecl.Name}>", "self"); + } + else { - // Add self as the first parameter (after the return type) - tempDecl.Insert(1, new ArgumentDecl - { - SwiftTypeSpec = new NamedTypeSpec(parentDecl.Name), - CSTypeIdentifier = new TypeDecl { Name = $"System.Runtime.InteropServices.Swift.SwiftSelf<{parentDecl.Name}>", MangledName = string.Empty, Fields = new List(), Declarations = new List(), ParentDecl = parentDecl, ModuleDecl = parentDecl.ModuleDecl }, - Name = "self", - PrivateName = string.Empty, - IsInOut = false, - ParentDecl = methodDecl, - ModuleDecl = methodDecl.ModuleDecl - }); + AddParameter("SwiftSelf", "self"); } } + } - return tempDecl.Skip(1).ToList(); + /// + /// Builds the PInvoke signature. + /// + /// The PInvoke signature. + public PInvokeSignature Build() + { + return new PInvokeSignature(_returnType, _parameters.ToArray()); } /// - /// Gets the internal method signature. + /// Sets the return type of the method. /// - /// The module declaration. - /// The internal method signature. - private string GetInternalMethodSignature(MethodDecl methodDecl) + /// The return type. + private void SetReturnType(string returnType) { - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); + _returnType = returnType; + } - List parameters = GetMethodParams(methodDecl); - return string.Join(", ", parameters.Select(p => $"{p.CSTypeIdentifier.Name} {p.Name}").ToList()); + /// + /// Adds a parameter to the PInvoke signature. + /// + /// The parameter type. + /// The parameter name.s + private void AddParameter(string type, string name) + { + _parameters.Add(new PInvokeArgument(type, name)); } + } + /// + /// Provides methods for handling method signatures. + /// + static class SignatureHandler + { /// - /// Gets the public method signature. + /// Gets the method parameters. + /// + /// The method declaration. + /// The type database. + /// The method parameters. + public static PInvokeSignature GetPinvokeSignature(MethodDecl methodDecl, TypeDatabase typeDatabase) + { + var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); + var pInvokeSignature = new PInvokeSignatureBuilder(methodDecl, parentDecl, typeDatabase); + pInvokeSignature.HandleReturnType(); + pInvokeSignature.HandleArguments(); + pInvokeSignature.HandleSwiftSelf(); + return pInvokeSignature.Build(); + } + + /// + /// Gets the wrapper method signature. /// /// The module declaration. - /// The public method signature. - private string GetPublicMethodSignature(MethodDecl methodDecl) + /// The wrapper method signature. + public static string GetCSWrapperSignature(MethodDecl methodDecl) { List parameters = methodDecl.CSSignature.Skip(1).ToList(); return string.Join(", ", parameters.Select(p => $"{p.CSTypeIdentifier.Name} {p.Name}").ToList()); } + } + /// + /// Provides methods for emitting PInvoke signatures. + /// + public static class PInvokeEmitter + { /// - /// Gets the method arguments. + /// Emits the PInvoke signature. /// - /// The module declaration. - /// The public method arguments. - private string GetMethodArgs(MethodDecl methodDecl) + /// The IndentedTextWriter instance. + /// The method environment. + /// The type database. + public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment methodEnv, TypeDatabase typeDatabase) { - List parameters = GetMethodParams(methodDecl); - return string.Join(", ", parameters.Select(p => p.Name).ToList()); + var methodDecl = (MethodDecl)methodEnv.MethodDecl; + var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); + var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ModuleDecl)); + + string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; + string libPath = typeDatabase.GetLibraryName(moduleDecl.Name); + + writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); + writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{methodDecl.MangledName}\")]"); + + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + + writer.WriteLine($"private static extern {pInvokeSignature.ReturnType} {PInvokeName}({pInvokeSignature.ParametersString()});"); } } } diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs index 43205c92b2df..29e38434775f 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs @@ -23,7 +23,7 @@ public bool Handles(BaseDecl decl) /// /// Constructs a new instance of ModuleHandler. /// - public IModuleHandler Construct () + public IModuleHandler Construct() { return new ModuleHandler(); } @@ -34,7 +34,7 @@ public IModuleHandler Construct () /// public class ModuleHandler : BaseHandler, IModuleHandler { - public ModuleHandler () + public ModuleHandler() { } @@ -58,7 +58,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto { var moduleEnv = (ModuleEnvironment)env; var moduleDecl = (ModuleDecl)moduleEnv.ModuleDecl; - + var generatedNamespace = $"Swift.{moduleDecl.Name}"; writer.WriteLine($"using System;"); @@ -82,13 +82,13 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto writer.WriteLine($"public class {moduleDecl.Name}"); writer.WriteLine("{"); writer.Indent++; - foreach(FieldDecl fieldDecl in moduleDecl.Fields) + foreach (FieldDecl fieldDecl in moduleDecl.Fields) { string accessModifier = fieldDecl.Visibility == Visibility.Public ? "public" : "private"; writer.WriteLine($"{accessModifier} {fieldDecl.CSTypeIdentifier.Name} {fieldDecl.Name};"); } writer.WriteLine(); - foreach(MethodDecl methodDecl in moduleDecl.Methods) + foreach (MethodDecl methodDecl in moduleDecl.Methods) { if (conductor.TryGetMethodHandler(methodDecl, out var methodHandler)) { diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs index b5a596f4de13..527455f77208 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs @@ -7,34 +7,34 @@ namespace BindingsGeneration { /// - /// Factory class for creating instances of StructHandler. + /// Factory class for creating instances of FrozenStructHandler. /// - public class StructHandlerFactory : IFactory + public class FrozenStructHandlerFactory : IFactory { - /// + /// /// Determines if the factory handles the specified declaration. /// /// The base declaration. public bool Handles(BaseDecl decl) { - return decl is StructDecl; + return decl is StructDecl structDecl && structDecl.IsMarshalledAsStruct(); } /// /// Constructs a new instance of StructHandler. /// - public ITypeHandler Construct () + public ITypeHandler Construct() { - return new StructHandler(); + return new FrozenStructHandler(); } } /// - /// Handler class for struct declarations. + /// Handler class for frozen struct declarations. /// - public class StructHandler : BaseHandler, ITypeHandler + public class FrozenStructHandler : BaseHandler, ITypeHandler { - public StructHandler () + public FrozenStructHandler() { } @@ -126,6 +126,146 @@ private unsafe bool VerifyFieldRecord(SwiftTypeInfo swiftTypeInfo, int fieldInde } } + /// + /// Factory class for creating instances of NonFrozenStructHandler. + /// + public class NonFrozenStructHandlerFactory : IFactory + { + /// + /// Determines if the factory handles the specified declaration. + /// + /// The base declaration. + public bool Handles(BaseDecl decl) + { + return decl is StructDecl structDecl && !structDecl.IsMarshalledAsStruct(); + } + + /// + /// Constructs a new instance of StructHandler. + /// + public ITypeHandler Construct() + { + return new NonFrozenStructHandler(); + } + } + + /// + /// Handler class for non-frozen struct declarations. + /// + public class NonFrozenStructHandler : BaseHandler, ITypeHandler + { + public NonFrozenStructHandler() + { + } + + /// + /// Marshals the specified struct declaration. + /// + /// The struct declaration. + public IEnvironment Marshal(BaseDecl structDecl) + { + return new TypeEnvironment(structDecl); + } + + /// + /// Emits the code for the specified environment. + /// + /// The IndentedTextWriter instance. + /// The environment. + /// The conductor instance. + /// The type database instance. + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + { + var structEnv = (TypeEnvironment)env; + var structDecl = (StructDecl)structEnv.TypeDecl; + var parentDecl = structDecl.ParentDecl ?? throw new ArgumentNullException(nameof(structDecl.ParentDecl)); + var moduleDecl = structDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(structDecl.ModuleDecl)); + var typeRecord = typeDatabase.Registrar.GetType(moduleDecl.Name, structDecl.Name); + SwiftTypeInfo? swiftTypeInfo = typeRecord?.SwiftTypeInfo; + + writer.WriteLine($"public unsafe class {structDecl.Name} : IDisposable"); + writer.WriteLine("{"); + writer.Indent++; + + WritePrivateFields(writer); + WriteDisposeMethod(writer, structDecl.Name); + WriteFinalizer(writer, structDecl.Name); + WritePayload(writer); + WriteMetadata(writer, moduleDecl.Name, structDecl.MangledName, typeDatabase); + + writer.WriteLine(); + base.HandleBaseDecl(writer, structDecl.Declarations, conductor, typeDatabase); + + writer.Indent--; + writer.WriteLine("}"); + } + + /// + /// Writes the private fields for the class. + /// + private static void WritePrivateFields(IndentedTextWriter writer) + { + writer.WriteLine(); + writer.WriteLine("private static nuint _payloadSize = Metadata.Size;"); + writer.WriteLine("private SwiftHandle _payload;"); + writer.WriteLine("private bool _disposed = false;"); + } + + /// + /// Writes the Dispose method for the class. + /// + private static void WriteDisposeMethod(IndentedTextWriter writer, string className) + { + writer.WriteLine("public void Dispose()"); + writer.WriteLine("{"); + writer.Indent++; + writer.WriteLine("if (!_disposed)"); + writer.WriteLine("{"); + writer.Indent++; + writer.WriteLine("NativeMemory.Free((void*)_payload);"); + writer.WriteLine("_disposed = true;"); + writer.WriteLine("GC.SuppressFinalize(this);"); + writer.Indent--; + writer.WriteLine("}"); + writer.Indent--; + writer.WriteLine("}"); + } + + /// + /// Writes the finalizer for the class. + /// + private static void WriteFinalizer(IndentedTextWriter writer, string className) + { + writer.WriteLine($"~{className}()"); + writer.WriteLine("{"); + writer.Indent++; + writer.WriteLine("NativeMemory.Free((void*)_payload);"); + writer.Indent--; + writer.WriteLine("}"); + } + + /// + /// Writes the metadata for the class. + /// + private static void WriteMetadata(IndentedTextWriter writer, string moduleName, string mangledName, TypeDatabase typeDatabase) + { + writer.WriteLine("public static TypeMetadata Metadata => PInvoke_getMetadata();"); + + writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); + string libPath = typeDatabase.GetLibraryName(moduleName); + writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{mangledName}Ma\")]"); + writer.WriteLine("internal static extern TypeMetadata PInvoke_getMetadata();"); + } + + /// + /// Writes the payload accessor for the class. + /// + private static void WritePayload(IndentedTextWriter writer) + { + writer.WriteLine("public SwiftHandle Payload => _payload;"); + } + } + /// /// Factory class for creating instances of ClassHandler. /// @@ -143,7 +283,7 @@ public bool Handles(BaseDecl decl) /// /// Constructs a new instance of ClassHandler. /// - public ITypeHandler Construct () + public ITypeHandler Construct() { return new ClassHandler(); } @@ -154,11 +294,11 @@ public ITypeHandler Construct () /// public class ClassHandler : BaseHandler, ITypeHandler { - public ClassHandler () + public ClassHandler() { } - /// + /// /// Marshals the specified class declaration. /// /// The class declaration. @@ -178,7 +318,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto { var classEnv = (TypeEnvironment)env; var classDecl = (ClassDecl)classEnv.TypeDecl; - + writer.WriteLine($"public unsafe class {classDecl.Name} {{"); writer.Indent++; diff --git a/src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs b/src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs new file mode 100644 index 000000000000..56335e823a73 --- /dev/null +++ b/src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs @@ -0,0 +1,46 @@ + + +using Swift.Runtime; + +namespace BindingsGeneration +{ + public static class MarshallingExtensions // TODO: Find better place for those + { + public static bool RequiresIndirectResult(this MethodDecl methodDecl, BaseDecl parentDecl, TypeDatabase typeDatabase) + { + if (methodDecl.IsConstructor && !(parentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct())) return true; + var returnType = methodDecl.CSSignature.First(); + + if (returnType.Name == "") return false; // TODO: Void should be handled differently + + var returnTypeRecord = typeDatabase.Registrar.GetType(returnType); + if (!(returnTypeRecord.IsFrozen && returnTypeRecord.IsBlittable)) return true; + return false; + } + + public static bool RequiresSwiftSelf(this MethodDecl methodDecl, BaseDecl parentDecl) + { + if (parentDecl is ModuleDecl) return false; // global funcs + if (methodDecl.MethodType == MethodType.Static) return false; + if (methodDecl.IsConstructor) return false; + + return true; + } + + public static bool IsMarshalledAsStruct(this StructDecl decl) + { + return decl is StructDecl structDecl && structDecl.IsFrozen && structDecl.IsBlittable; + } + + public static TypeRecord GetType(this TypeRegistrar typeRegistrar, ArgumentDecl argumentDecl) + { + if (argumentDecl.SwiftTypeSpec is not NamedTypeSpec swiftTypeSpec) + { + throw new NotImplementedException($"{argumentDecl} is not a NamedTypeSpec"); + } + + var typeRecord = typeRegistrar.GetType(swiftTypeSpec.Module, swiftTypeSpec.NameWithoutModule) ?? throw new NotImplementedException($"Type {swiftTypeSpec.Name} not found in type database"); + return typeRecord; + } + } +} diff --git a/src/Swift.Bindings/src/Model/StructDecl.cs b/src/Swift.Bindings/src/Model/StructDecl.cs index e2199aea4aa3..c09060c5da87 100644 --- a/src/Swift.Bindings/src/Model/StructDecl.cs +++ b/src/Swift.Bindings/src/Model/StructDecl.cs @@ -8,5 +8,8 @@ namespace BindingsGeneration /// public sealed record StructDecl : TypeDecl { + public required bool IsBlittable { get; set; } + + public required bool IsFrozen { get; set; } } } diff --git a/src/Swift.Bindings/src/Parser/SwiftABIParser.cs b/src/Swift.Bindings/src/Parser/SwiftABIParser.cs index 8ae1fc1d4339..afdec7bbe196 100644 --- a/src/Swift.Bindings/src/Parser/SwiftABIParser.cs +++ b/src/Swift.Bindings/src/Parser/SwiftABIParser.cs @@ -38,7 +38,7 @@ public record Node public required string MangledName { get; set; } public required string PrintedName { get; set; } public required string ModuleName { get; set; } - public required string [] DeclAttributes { get; set; } + public required string[] DeclAttributes { get; set; } public required bool? @static { get; set; } public required bool? IsInternal { get; set; } public required string? GenericSig { get; set; } @@ -244,9 +244,9 @@ private List CollectDeclarations(IEnumerable nodes, BaseDecl par catch (NotImplementedException e) { if (_verbose > 1) - Console.WriteLine($"Not implemented '{node.Name}': {e.Message}"); + Console.WriteLine($"Not implemented '{node.Name}': {e.Message}"); } - catch (Exception e) + catch (Exception e) { if (_verbose > 0) Console.WriteLine($"Error while processing node '{node.Name}': {e.Message}"); @@ -284,15 +284,11 @@ private List CollectDeclarations(IEnumerable nodes, BaseDecl par metadataPtr = DynamicLibraryLoader.invoke(_dylibPath, GetMetadataAccessor(node)); var swiftTypeInfo = new SwiftTypeInfo { MetadataPtr = metadataPtr }; - if (node.DeclAttributes != null && Array.IndexOf(node.DeclAttributes, "Frozen") != -1 && - (!swiftTypeInfo.ValueWitnessTable->IsNonPOD || !swiftTypeInfo.ValueWitnessTable->IsNonBitwiseTakable)) - { - decl = CreateStructDecl(node, parentDecl, moduleDecl); - } - else - { - decl = CreateClassDecl(node, parentDecl, moduleDecl); - } + // TODO: Find better place for this + typeRecord.IsBlittable = !swiftTypeInfo.ValueWitnessTable->IsNonPOD || !swiftTypeInfo.ValueWitnessTable->IsNonBitwiseTakable; //TODO: This is not the full picture. + typeRecord.IsFrozen = node.DeclAttributes != null && Array.IndexOf(node.DeclAttributes, "Frozen") != -1; + + decl = CreateStructDecl(node, parentDecl, moduleDecl, typeRecord.IsFrozen, typeRecord.IsBlittable); typeRecord.SwiftTypeInfo = swiftTypeInfo; break; @@ -325,7 +321,7 @@ private List CollectDeclarations(IEnumerable nodes, BaseDecl par /// The parent declaration. /// The module declaration. /// The struct declaration. - private StructDecl CreateStructDecl(Node node, BaseDecl parentDecl, BaseDecl moduleDecl) + private StructDecl CreateStructDecl(Node node, BaseDecl parentDecl, BaseDecl moduleDecl, bool IsFrozen, bool IsBlittable) { return new StructDecl { @@ -334,7 +330,9 @@ private StructDecl CreateStructDecl(Node node, BaseDecl parentDecl, BaseDecl mod Fields = new List(), Declarations = new List(), ParentDecl = parentDecl, - ModuleDecl = moduleDecl + ModuleDecl = moduleDecl, + IsFrozen = IsFrozen, + IsBlittable = IsBlittable }; } @@ -434,12 +432,14 @@ private FieldDecl CreateFieldDecl(Node node, BaseDecl parentDecl, BaseDecl modul /// TypeSpec CreateTypeSpec(Node node) { - switch (node.Kind) { + switch (node.Kind) + { case kNominal: case kFunc: var spec = TypeSpecParser.Parse(node.PrintedName); - if (spec is null) { - throw new Exception($"Error parsing type from \"{node.PrintedName}\""); + if (spec is null) + { + throw new Exception($"Error parsing type from \"{node.PrintedName}\""); } return spec; default: diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs new file mode 100644 index 000000000000..6e45bf23a4be --- /dev/null +++ b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using Swift.NonFrozenStructsTests; + +namespace Test +{ + public class MainClass + { + public static int Main(string[] args) + { + return 0; + } + public static long[] SwiftNonFrozenStruct0() + { + Console.Write("Running SwiftStruct0: "); + F0_S0 f0_s0 = new F0_S0(1.0, 2, 3); + Console.WriteLine($"F0_S0: {f0_s0.hashValue()}"); + F0_S1 f0_s1 = new F0_S1(4); + Console.WriteLine($"F0_S1: {f0_s1.hashValue()}"); + F0_S2 f0_s2 = new F0_S2(5.0f); + Console.WriteLine($"F0_S2: {f0_s2.hashValue()}"); + long result = NonFrozenStructsTests.swiftFunc0(-23758, 148652722, 3833542748216839160, 21987, new F0_S0(3425626963407448, 989224444, 55562), new F0_S1(1751696348434043356), 14, new F0_S2(1047842)); + return new long[] { f0_s0.hashValue(), f0_s1.hashValue(), f0_s2.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct1() + { + Console.Write("Running SwiftStruct1: "); + F1_S0 f1_s0 = new F1_S0(6, 7.0, 8, 9, 10); + F1_S1 f1_s1 = new F1_S1(101); + F1_S2 f1_s2 = new F1_S2(102); + long result = NonFrozenStructsTests.swiftFunc1(new F1_S0(6106136698885217102, 6195715435808, 121, 676336729, 51621), 121, new F1_S1(101), new F1_S2(-11974)); + return new long[] { f1_s0.hashValue(), f1_s1.hashValue(), f1_s2.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct2() + { + Console.Write("Running SwiftStruct2: "); + F2_S0 f2_s0 = new F2_S0(11, 12); + F2_S1 f2_s1 = new F2_S1(13, 14, 15, 16, 17); + F2_S2_S0_S0 f2_s2_s0_s0 = new F2_S2_S0_S0(18); + F2_S3 f2_s3 = new F2_S3(103); + F2_S4 f2_s4 = new F2_S4(16, 17); + F2_S5 f2_s5 = new F2_S5(18.0f); + long result = NonFrozenStructsTests.swiftFunc2(1467471118999515177, -1109, 1443466834, new F2_S0(unchecked((nint)8641951469425609828), unchecked((nuint)3263825339460718643)), 6, 42857709, new F2_S1(6855376760105631967, 2087467091, 25810, 2495195821026007124, 62146), new F2_S2(new F2_S2_S0(new F2_S2_S0_S0(unchecked((nint)561009218247569242)))), 46110, 7547287, new F2_S3(34), new F2_S4(203178131, unchecked((nuint)8676866947888134131)), new F2_S5(7890213), 5623254678629817168); + return new long[] { f2_s0.hashValue(), f2_s1.hashValue(), f2_s2_s0_s0.hashValue(), f2_s3.hashValue(), f2_s4.hashValue(), f2_s5.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct3() + { + Console.Write("Running SwiftStruct3: "); + F3_S0_S0 f3_s0_s0 = new F3_S0_S0(19, 20); + F3_S0 f3_s0 = new F3_S0(21, f3_s0_s0, 22); + F3_S1 f3_s1 = new F3_S1(23, 24.0f); + F3_S2 f3_s2 = new F3_S2(25.0f); + F3_S3 f3_s3 = new F3_S3(104, 26); + F3_S4 f3_s4 = new F3_S4(27, 28.0f, 29); + F3_S5 f3_s5 = new F3_S5(30, 31); + F3_S6_S0 f3_s6_s0 = new F3_S6_S0(32, 105); + F3_S6 f3_s6 = new F3_S6(f3_s6_s0, 33, 34); + F3_S7 f3_s7 = new F3_S7(35); + long result = NonFrozenStructsTests.swiftFunc3(unchecked((nint)3764414362291906102), new F3_S0(23, new F3_S0_S0(unchecked((nint)3007367655161186204), 549733154), 38928730), new F3_S1(338326426991485790, 7517271), 4025506815523052, unchecked((nint)431338169919855088), new F3_S2(7888763), new F3_S3(57, unchecked((nint)8933588466514096604)), new F3_S4(unchecked((nuint)7769316271655125502), 1663231, 27333), new F3_S5(887161443, 4368322322535461551), 32477, 948591564, new F3_S6(new F3_S6_S0(7033, 124), 67, 221), unchecked((nint)6195032215974632640), new F3_S7(4076570630190469380)); + return new long[] { f3_s0_s0.hashValue(), f3_s0.hashValue(), f3_s1.hashValue(), f3_s2.hashValue(), f3_s3.hashValue(), f3_s4.hashValue(), f3_s5.hashValue(), f3_s6_s0.hashValue(), f3_s6.hashValue(), f3_s7.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct4() + { + Console.Write("Running SwiftStruct4: "); + F4_S0 f4_s0 = new F4_S0(36, 37, 38); + F4_S1_S0 f4_s1_s0 = new F4_S1_S0(39); + F4_S1 f4_s1 = new F4_S1(f4_s1_s0, 40.0f); + F4_S2_S0 f4_s2_s0 = new F4_S2_S0(41); + F4_S2 f4_s2 = new F4_S2(f4_s2_s0, 42); + F4_S3 f4_s3 = new F4_S3(43, 44, 45); + long result = NonFrozenStructsTests.swiftFunc4(unchecked((nint)7962207922494873063), new F4_S0(16887, 11193, 20997), unchecked((nuint)938043702598629976), 8692646626431098135, -16, 1244033228990732, new F4_S1(new F4_S1_S0(274421021), 7037264), 154, 1187166500, 1096514224, 7283010216047805604, new F4_S2(new F4_S2_S0(unchecked((nint)3285810526807361976)), unchecked((nint)2934841899954168407)), 3384, unchecked((nint)4857017836321530071), new F4_S3(9030480386017125399, 5466901523025762626, 3430278619936831574), 234522698); + return new long[] { f4_s0.hashValue(), f4_s1_s0.hashValue(), f4_s1.hashValue(), f4_s2_s0.hashValue(), f4_s2.hashValue(), f4_s3.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct5() + { + Console.Write("Running SwiftStruct5: "); + F5_S0 f5_s0 = new F5_S0(46); + long result = NonFrozenStructsTests.swiftFunc5(unchecked((nuint)425569624776371773), 8077063517132296390, 126, new F5_S0(unchecked((nuint)8032431538406335990))); + return new long[] { f5_s0.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct6() + { + Console.Write("Running SwiftStruct6: "); + F6_S0 f6_s0 = new F6_S0(47, 48, 49); + F6_S1 f6_s1 = new F6_S1(50, 51.0f); + F6_S2_S0 f6_s2_s0 = new F6_S2_S0(52.0); + F6_S2 f6_s2 = new F6_S2(f6_s2_s0, 53); + F6_S3 f6_s3 = new F6_S3(54.0, 55.0, 56); + F6_S4 f6_s4 = new F6_S4(57); + F6_S5 f6_s5 = new F6_S5(58); + long result = NonFrozenStructsTests.swiftFunc6(7742402881449217499, new F6_S0(158138445, unchecked((nint)4280990415451108676), 220), new F6_S1(unchecked((nint)7698928046973811162), 478730), unchecked((nuint)7348396082620937303), 76, 638113630, new F6_S2(new F6_S2_S0(55341051405503), 61378), 8235930, -20241, new F6_S3(318363825012010, 3586735152618866, 6630554942616673404), 46432, 744827194985602, 1973021571, new F6_S4(103), new F6_S5(-5345)); + return new long[] { f6_s0.hashValue(), f6_s1.hashValue(), f6_s2_s0.hashValue(), f6_s2.hashValue(), f6_s3.hashValue(), f6_s4.hashValue(), f6_s5.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct7() + { + Console.Write("Running SwiftStruct7: "); + F7_S0 f7_s0 = new F7_S0(59, 60); + F7_S1 f7_s1 = new F7_S1(61); + long result = NonFrozenStructsTests.swiftFunc7(6953928391541094904, unchecked((nint)2531714261502554653), 224, new F7_S0(14482, unchecked((nint)4704842847707480837)), new F7_S1(148), 659764805); + return new long[] { f7_s0.hashValue(), f7_s1.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct8() + { + Console.Write("Running SwiftStruct8: "); + F8_S0 f8_s0 = new F8_S0(62); + long result = NonFrozenStructsTests.swiftFunc8(48505, unchecked((nuint)8758330817072549915), 7130, 4163773298933598697, new F8_S0(1934119180), 2843311260726166700); + return new long[] { f8_s0.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct9() + { + Console.Write("Running SwiftStruct9: "); + F9_S0 f9_s0 = new F9_S0(63.0); + F9_S1 f9_s1 = new F9_S1(64); + long result = NonFrozenStructsTests.swiftFunc9(3214937834123081267, 6846768, new F9_S0(1713527158921541), 25670, new F9_S1(1650872599), 39910); + return new long[] { f9_s0.hashValue(), f9_s1.hashValue(), result }; + } + + public static long[] SwiftNonFrozenStruct10() + { + Console.Write("Running SwiftStruct10: "); + F10_S0 f10_s0 = new F10_S0(65, 66); + F10_S1 f10_s1 = new F10_S1(67.0f, 68, 69); + F10_S2 f10_s2 = new F10_S2(70, 71); + F10_S3 f10_s3 = new F10_S3(72.0f); + F10_S4 f10_s4 = new F10_S4(73); + long result = NonFrozenStructsTests.swiftFunc10(57914, 11968, new F10_S0(155502634291755209, 2096010440), 1373054541331378384, 2401784, -16, 9038689080810964859, 521869082023571496, 8919173990791765137, 4890513, 1113752036, 1477591037, 1463349953238439103, 7521124889381630793, new F10_S1(620783, 33, unchecked((nuint)1209731409858919135)), 1560688600815438014, new F10_S2(unchecked((nuint)2244178273746563479), 4252696983313269084), new F10_S3(6539550), new F10_S4(1264398289929487498)); + return new long[] { f10_s0.hashValue(), f10_s1.hashValue(), f10_s2.hashValue(), f10_s3.hashValue(), f10_s4.hashValue(), result }; + } + } +} diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs new file mode 100644 index 000000000000..c8f9736c953a --- /dev/null +++ b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs @@ -0,0 +1,169 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Xunit; + +namespace BindingsGeneration.Tests +{ + public class NonFrozenStructsTests : IClassFixture + { + private readonly TestFixture _fixture; + private static string _assemblyPath; + + public NonFrozenStructsTests(TestFixture fixture) + { + _fixture = fixture; + } + + public class TestFixture + { + static TestFixture() + { + InitializeResources(); + } + + private static void InitializeResources() + { + BindingsGenerator.GenerateBindings("NonFrozenStructs/NonFrozenStructsTests.abi.json", "NonFrozenStructs/"); + _assemblyPath = TestsHelper.Compile( + new string[] { "NonFrozenStructs/*.cs" }, + new string[] { }, + new string[] { }); + } + } + + [Fact] + public static void TestSwiftStruct0() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct0", new object[] { }); + Assert.Equal(-3555910212621330623, result[0]); + Assert.Equal(3232700585171816769, result[1]); + Assert.Equal(5405857218178297237, result[2]); + Assert.Equal(-5199645484972017144, result[3]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct1() + { + + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct1", new object[] { }); + Assert.Equal(-8001373452266497130, result[0]); + Assert.Equal(-5808561271200422464, result[1]); + Assert.Equal(619381321311063739, result[2]); + Assert.Equal(-5789188411070459345, result[3]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct2() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct2", new object[] { }); + Assert.Equal(-2644299808654375646, result[0]); + Assert.Equal(-5946857472632060272, result[1]); + Assert.Equal(-2996592682669871081, result[2]); + Assert.Equal(-5808559072177166042, result[3]); + Assert.Equal(8741931523650439060, result[4]); + Assert.Equal(5451771724251677586, result[5]); + Assert.Equal(-1831688667491861211, result[6]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct3() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct3", new object[] { }); + Assert.Equal(2183680504548519170, result[0]); + Assert.Equal(6464181192521079681, result[1]); + Assert.Equal(-3914014010231380795, result[2]); + Assert.Equal(5367593114012495226, result[3]); + Assert.Equal(-5127890789322606739, result[4]); + Assert.Equal(-1801544295733561908, result[5]); + Assert.Equal(9153003238137716468, result[6]); + Assert.Equal(-4315142132599941972, result[7]); + Assert.Equal(-1490133437166812017, result[8]); + Assert.Equal(-1699583181824442426, result[9]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct4() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct4", new object[] { }); + Assert.Equal(-5555791715238606502, result[0]); + Assert.Equal(7917312046649396258, result[1]); + Assert.Equal(7787216292523950588, result[2]); + Assert.Equal(-6752434813728457588, result[3]); + Assert.Equal(-664221457051710106, result[4]); + Assert.Equal(-1729670953176434449, result[5]); + Assert.Equal(5366279618472372586, result[6]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct5() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct5", new object[] { }); + Assert.Equal(-8984750220696046997, result[0]); + Assert.Equal(5832440388901373477, result[1]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct6() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct6", new object[] { }); + Assert.Equal(1692306587549742161, result[0]); + Assert.Equal(-1484226257450236447, result[1]); + Assert.Equal(-6229230135174619697, result[2]); + Assert.Equal(-3202371936141214966, result[3]); + Assert.Equal(631817796766569309, result[4]); + Assert.Equal(-5808600853619038060, result[5]); + Assert.Equal(584944617122307319, result[6]); + Assert.Equal(-8871753131984133391, result[7]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct7() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct7", new object[] { }); + Assert.Equal(1770792034096671794, result[0]); + Assert.Equal(-5808605251665550904, result[1]); + Assert.Equal(5963731324167739917, result[2]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct8() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct8", new object[] { }); + Assert.Equal(962290567653668427, result[0]); + Assert.Equal(1919194302322813426, result[1]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct9() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct9", new object[] { }); + Assert.Equal(-127835592947727486, result[0]); + Assert.Equal(5462998930071304245, result[1]); + Assert.Equal(-5878079645235476214, result[2]); + Console.WriteLine("OK"); + } + + [Fact] + public static void TestSwiftStruct10() + { + long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct10", new object[] { }); + Assert.Equal(-1058509415045616378, result[0]); + Assert.Equal(6725059428863802130, result[1]); + Assert.Equal(716752888238966276, result[2]); + Assert.Equal(5451770624740049375, result[3]); + Assert.Equal(4635659444355057900, result[4]); + Assert.Equal(-5714135075575530569, result[5]); + Console.WriteLine("OK"); + } + } +} diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift new file mode 100644 index 000000000000..8842498ca8ed --- /dev/null +++ b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift @@ -0,0 +1,1070 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import Foundation + +struct HasherFNV1a { + + private var hash: UInt = 14_695_981_039_346_656_037 + private let prime: UInt = 1_099_511_628_211 + + mutating func combine(_ val: T) { + for byte in withUnsafeBytes(of: val, Array.init) { + hash ^= UInt(byte) + hash = hash &* prime + } + } + + func finalize() -> Int { + Int(truncatingIfNeeded: hash) + } +} + +public struct F0_S0 +{ + public let f0 : Double; + public let f1 : UInt32; + public let f2 : UInt16; + + public init(f0 : Double, f1 : UInt32, f2 : UInt16) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public func swiftFunc0(a0: Int16, a1: Int32, a2: UInt64, a3: UInt16, a4: F0_S0, a5: F0_S1, a6: UInt8, a7: F0_S2) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2); + hasher.combine(a3); + hasher.combine(a4.f0); + hasher.combine(a4.f1); + hasher.combine(a4.f2); + hasher.combine(a5.f0); + hasher.combine(a6); + hasher.combine(a7.f0); + return hasher.finalize() +} + +public struct F0_S1 +{ + public let f0 : UInt64; + + public init(f0 : UInt64) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F0_S2 +{ + public let f0 : Float; + + public init(f0 : Float) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F1_S0 +{ + public let f0 : Int64; + public let f1 : Double; + public let f2 : Int8; + public let f3 : Int32; + public let f4 : UInt16; + + public init(f0 : Int64, f1 : Double, f2 : Int8, f3 : Int32, f4 : UInt16) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + self.f3 = f3 + self.f4 = f4 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + hasher.combine(f3) + hasher.combine(f4) + return hasher.finalize() + } +} + +public struct F1_S1 +{ + public let f0 : UInt8; + + public init(f0: UInt8) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F1_S2 +{ + public let f0 : Int16; + + public init(f0: Int16) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public func swiftFunc1(a0: F1_S0, a1: UInt8, a2: F1_S1, a3: F1_S2) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0.f0); + hasher.combine(a0.f1); + hasher.combine(a0.f2); + hasher.combine(a0.f3); + hasher.combine(a0.f4); + hasher.combine(a1); + hasher.combine(a2.f0); + hasher.combine(a3.f0); + return hasher.finalize() +} + +public struct F2_S0 +{ + public let f0 : Int; + public let f1 : UInt; + + public init(f0: Int, f1: UInt) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F2_S1 +{ + public let f0 : Int64; + public let f1 : Int32; + public let f2 : Int16; + public let f3 : Int64; + public let f4 : UInt16; + + public init(f0: Int64, f1: Int32, f2: Int16, f3: Int64, f4: UInt16) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + self.f3 = f3 + self.f4 = f4 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + hasher.combine(f3) + hasher.combine(f4) + return hasher.finalize() + } +} + +public struct F2_S2_S0_S0 +{ + public let f0 : Int; + + public init(f0: Int) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F2_S2_S0 +{ + public let f0 : F2_S2_S0_S0; + + public init(f0: F2_S2_S0_S0) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0) + return hasher.finalize() + } +} + +public struct F2_S2 +{ + public let f0 : F2_S2_S0; + + public init(f0: F2_S2_S0) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0) + return hasher.finalize() + } +} + +public struct F2_S3 +{ + public let f0 : UInt8; + + public init(f0: UInt8) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F2_S4 +{ + public let f0 : Int32; + public let f1 : UInt; + + public init(f0: Int32, f1: UInt) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F2_S5 +{ + public let f0 : Float; + + public init(f0: Float) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public func swiftFunc2(a0: Int64, a1: Int16, a2: Int32, a3: F2_S0, a4: UInt8, a5: Int32, a6: F2_S1, a7: F2_S2, a8: UInt16, a9: Float, a10: F2_S3, a11: F2_S4, a12: F2_S5, a13: Int64) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2); + hasher.combine(a3.f0); + hasher.combine(a3.f1); + hasher.combine(a4); + hasher.combine(a5); + hasher.combine(a6.f0); + hasher.combine(a6.f1); + hasher.combine(a6.f2); + hasher.combine(a6.f3); + hasher.combine(a6.f4); + hasher.combine(a7.f0.f0.f0); + hasher.combine(a8); + hasher.combine(a9); + hasher.combine(a10.f0); + hasher.combine(a11.f0); + hasher.combine(a11.f1); + hasher.combine(a12.f0); + hasher.combine(a13); + return hasher.finalize() +} + +public struct F3_S0_S0 +{ + public let f0 : Int; + public let f1 : UInt32; + + public init(f0: Int, f1: UInt32) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F3_S0 +{ + public let f0 : Int8; + public let f1 : F3_S0_S0; + public let f2 : UInt32; + + public init(f0: Int8, f1: F3_S0_S0, f2: UInt32) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1.f0) + hasher.combine(f1.f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public struct F3_S1 +{ + public let f0 : Int64; + public let f1 : Float; + + public init(f0: Int64, f1: Float) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F3_S2 +{ + public let f0 : Float; + + public init(f0: Float) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F3_S3 +{ + public let f0 : UInt8; + public let f1 : Int; + + public init(f0: UInt8, f1: Int) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F3_S4 +{ + public let f0 : UInt; + public let f1 : Float; + public let f2 : UInt16; + + public init(f0: UInt, f1: Float, f2: UInt16) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public struct F3_S5 +{ + public let f0 : UInt32; + public let f1 : Int64; + + public init(f0: UInt32, f1: Int64) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F3_S6_S0 +{ + public let f0 : Int16; + public let f1 : UInt8; + + public init(f0: Int16, f1: UInt8) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F3_S6 +{ + public let f0 : F3_S6_S0; + public let f1 : Int8; + public let f2 : UInt8; + + public init(f0: F3_S6_S0, f1: Int8, f2: UInt8) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0) + hasher.combine(f0.f1) + hasher.combine(f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public struct F3_S7 +{ + public let f0 : UInt64; + + public init(f0: UInt64) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public func swiftFunc3(a0: Int, a1: F3_S0, a2: F3_S1, a3: Double, a4: Int, a5: F3_S2, a6: F3_S3, a7: F3_S4, a8: F3_S5, a9: UInt16, a10: Int32, a11: F3_S6, a12: Int, a13: F3_S7) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1.f0); + hasher.combine(a1.f1.f0); + hasher.combine(a1.f1.f1); + hasher.combine(a1.f2); + hasher.combine(a2.f0); + hasher.combine(a2.f1); + hasher.combine(a3); + hasher.combine(a4); + hasher.combine(a5.f0); + hasher.combine(a6.f0); + hasher.combine(a6.f1); + hasher.combine(a7.f0); + hasher.combine(a7.f1); + hasher.combine(a7.f2); + hasher.combine(a8.f0); + hasher.combine(a8.f1); + hasher.combine(a9); + hasher.combine(a10); + hasher.combine(a11.f0.f0); + hasher.combine(a11.f0.f1); + hasher.combine(a11.f1); + hasher.combine(a11.f2); + hasher.combine(a12); + hasher.combine(a13.f0); + return hasher.finalize() +} + +public struct F4_S0 +{ + public let f0 : UInt16; + public let f1 : Int16; + public let f2 : Int16; + + public init(f0: UInt16, f1: Int16, f2: Int16) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public struct F4_S1_S0 +{ + public let f0 : UInt32; + + public init(f0: UInt32) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F4_S1 +{ + public let f0 : F4_S1_S0; + public let f1 : Float; + + public init(f0: F4_S1_S0, f1: Float) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F4_S2_S0 +{ + public let f0 : Int; + + public init(f0: Int) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public struct F4_S2 +{ + public let f0 : F4_S2_S0; + public let f1 : Int; + + public init(f0: F4_S2_S0, f1: Int) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0) + hasher.combine(f1) + return hasher.finalize() + } +} + +public struct F4_S3 +{ + public let f0 : UInt64; + public let f1 : UInt64; + public let f2 : Int64; + + public init(f0: UInt64, f1: UInt64, f2: Int64) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + hasher.combine(f1) + hasher.combine(f2) + return hasher.finalize() + } +} + +public func swiftFunc4(a0: Int, a1: F4_S0, a2: UInt, a3: UInt64, a4: Int8, a5: Double, a6: F4_S1, a7: UInt8, a8: Int32, a9: UInt32, a10: UInt64, a11: F4_S2, a12: Int16, a13: Int, a14: F4_S3, a15: UInt32) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1.f0); + hasher.combine(a1.f1); + hasher.combine(a1.f2); + hasher.combine(a2); + hasher.combine(a3); + hasher.combine(a4); + hasher.combine(a5); + hasher.combine(a6.f0.f0); + hasher.combine(a6.f1); + hasher.combine(a7); + hasher.combine(a8); + hasher.combine(a9); + hasher.combine(a10); + hasher.combine(a11.f0.f0); + hasher.combine(a11.f1); + hasher.combine(a12); + hasher.combine(a13); + hasher.combine(a14.f0); + hasher.combine(a14.f1); + hasher.combine(a14.f2); + hasher.combine(a15); + return hasher.finalize() +} + +public struct F5_S0 +{ + public let f0 : UInt; + + public init(f0: UInt) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0) + return hasher.finalize() + } +} + +public func swiftFunc5(a0: UInt, a1: UInt64, a2: UInt8, a3: F5_S0) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2); + hasher.combine(a3.f0); + return hasher.finalize() +} + +public struct F6_S0 +{ + public let f0 : Int32; + public let f1 : Int; + public let f2 : UInt8; + + public init(f0: Int32, f1: Int, f2: UInt8) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + hasher.combine(f2); + return hasher.finalize() + } +} + +public struct F6_S1 +{ + public let f0 : Int; + public let f1 : Float; + + public init(f0: Int, f1: Float) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + return hasher.finalize() + } +} + +public struct F6_S2_S0 +{ + public let f0 : Double; + + public init(f0: Double) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public struct F6_S2 +{ + public let f0 : F6_S2_S0; + public let f1 : UInt16; + + public init(f0: F6_S2_S0, f1: UInt16) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0.f0); + hasher.combine(f1); + return hasher.finalize() + } +} + +public struct F6_S3 +{ + public let f0 : Double; + public let f1 : Double; + public let f2 : UInt64; + + public init(f0: Double, f1: Double, f2: UInt64) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + hasher.combine(f2); + return hasher.finalize() + } +} + +public struct F6_S4 +{ + public let f0 : Int8; + + public init(f0: Int8) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public struct F6_S5 +{ + public let f0 : Int16; + + public init(f0: Int16) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public func swiftFunc6(a0: Int64, a1: F6_S0, a2: F6_S1, a3: UInt, a4: UInt8, a5: Int32, a6: F6_S2, a7: Float, a8: Int16, a9: F6_S3, a10: UInt16, a11: Double, a12: UInt32, a13: F6_S4, a14: F6_S5) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1.f0); + hasher.combine(a1.f1); + hasher.combine(a1.f2); + hasher.combine(a2.f0); + hasher.combine(a2.f1); + hasher.combine(a3); + hasher.combine(a4); + hasher.combine(a5); + hasher.combine(a6.f0.f0); + hasher.combine(a6.f1); + hasher.combine(a7); + hasher.combine(a8); + hasher.combine(a9.f0); + hasher.combine(a9.f1); + hasher.combine(a9.f2); + hasher.combine(a10); + hasher.combine(a11); + hasher.combine(a12); + hasher.combine(a13.f0); + hasher.combine(a14.f0); + return hasher.finalize() +} + +public struct F7_S0 +{ + public let f0 : Int16; + public let f1 : Int; + + public init(f0: Int16, f1: Int) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + return hasher.finalize() + } +} + +public struct F7_S1 +{ + public let f0 : UInt8; + + public init(f0: UInt8) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public func swiftFunc7(a0: Int64, a1: Int, a2: UInt8, a3: F7_S0, a4: F7_S1, a5: UInt32) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2); + hasher.combine(a3.f0); + hasher.combine(a3.f1); + hasher.combine(a4.f0); + hasher.combine(a5); + return hasher.finalize() +} + +public struct F8_S0 +{ + public let f0 : Int32; + + public init(f0: Int32) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public func swiftFunc8(a0: UInt16, a1: UInt, a2: UInt16, a3: UInt64, a4: F8_S0, a5: UInt64) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2); + hasher.combine(a3); + hasher.combine(a4.f0); + hasher.combine(a5); + return hasher.finalize() +} + +public struct F9_S0 +{ + public let f0 : Double; + + public init(f0: Double) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public struct F9_S1 +{ + public let f0 : Int32; + + public init(f0: Int32) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public func swiftFunc9(a0: Int64, a1: Float, a2: F9_S0, a3: UInt16, a4: F9_S1, a5: UInt16) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2.f0); + hasher.combine(a3); + hasher.combine(a4.f0); + hasher.combine(a5); + return hasher.finalize() +} + +public struct F10_S0 +{ + public let f0 : Int64; + public let f1 : UInt32; + + public init(f0: Int64, f1: UInt32) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + return hasher.finalize() + } +} + +public struct F10_S1 +{ + public let f0 : Float; + public let f1 : UInt8; + public let f2 : UInt; + + public init(f0: Float, f1: UInt8, f2: UInt) { + self.f0 = f0 + self.f1 = f1 + self.f2 = f2 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + hasher.combine(f2); + return hasher.finalize() + } +} + +public struct F10_S2 +{ + public let f0 : UInt; + public let f1 : UInt64; + + public init(f0: UInt, f1: UInt64) { + self.f0 = f0 + self.f1 = f1 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + hasher.combine(f1); + return hasher.finalize() + } +} + +public struct F10_S3 +{ + public let f0 : Float; + + public init(f0: Float) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public struct F10_S4 +{ + public let f0 : Int64; + + public init(f0: Int64) { + self.f0 = f0 + } + + public func hashValue() -> Int { + var hasher = HasherFNV1a() + hasher.combine(f0); + return hasher.finalize() + } +} + +public func swiftFunc10(a0: UInt16, a1: UInt16, a2: F10_S0, a3: UInt64, a4: Float, a5: Int8, a6: Int64, a7: UInt64, a8: Int64, a9: Float, a10: Int32, a11: Int32, a12: Int64, a13: UInt64, a14: F10_S1, a15: Int64, a16: F10_S2, a17: F10_S3, a18: F10_S4) -> Int { + var hasher = HasherFNV1a() + hasher.combine(a0); + hasher.combine(a1); + hasher.combine(a2.f0); + hasher.combine(a2.f1); + hasher.combine(a3); + hasher.combine(a4); + hasher.combine(a5); + hasher.combine(a6); + hasher.combine(a7); + hasher.combine(a8); + hasher.combine(a9); + hasher.combine(a10); + hasher.combine(a11); + hasher.combine(a12); + hasher.combine(a13); + hasher.combine(a14.f0); + hasher.combine(a14.f1); + hasher.combine(a14.f2); + hasher.combine(a15); + hasher.combine(a16.f0); + hasher.combine(a16.f1); + hasher.combine(a17.f0); + hasher.combine(a18.f0); + return hasher.finalize() +} diff --git a/src/Swift.Runtime/src/TypeDatabase.cs b/src/Swift.Runtime/src/TypeDatabase.cs index 446a41b8d4f5..f1db3ce2248a 100644 --- a/src/Swift.Runtime/src/TypeDatabase.cs +++ b/src/Swift.Runtime/src/TypeDatabase.cs @@ -82,7 +82,7 @@ private void ReadVersion1_0(XmlDocument xmlDoc) XmlNode? entitiesNode = xmlDoc.SelectSingleNode("//swifttypedatabase/entities"); if (entitiesNode == null) - throw new Exception("Invalid XML structure: 'entities' node not found."); + throw new Exception("Invalid XML structure: 'entities' node not found."); foreach (XmlNode? entityNode in entitiesNode.ChildNodes) { @@ -95,6 +95,8 @@ private void ReadVersion1_0(XmlDocument xmlDoc) string swiftMetadataAccessor = typeDeclarationNode?.Attributes?["metadataaccessor"]?.Value ?? string.Empty; string csharpTypeIdentifier = entityNode?.Attributes?["managedTypeName"]?.Value ?? throw new Exception("Invalid XML structure: Missing 'managedTypeName' attribute."); string @namespace = entityNode?.Attributes?["managedNameSpace"]?.Value ?? throw new Exception("Invalid XML structure: Missing 'managedNameSpace' attribute."); + string frozen = typeDeclarationNode?.Attributes?["frozen"]?.Value ?? throw new Exception("Invalid XML structure: Missing 'frozen' attribute."); + string blittable = typeDeclarationNode?.Attributes?["blittable"]?.Value ?? throw new Exception("Invalid XML structure: Missing 'blittable' attribute."); if (swiftTypeIdentifier == null || csharpTypeIdentifier == null) throw new Exception("Invalid XML structure: Missing attributes."); @@ -105,6 +107,8 @@ private void ReadVersion1_0(XmlDocument xmlDoc) typeRecord.TypeIdentifier = csharpTypeIdentifier; typeRecord.MetadataAccessor = $"{swiftMetadataAccessor}Ma"; typeRecord.IsProcessed = true; + typeRecord.IsBlittable = blittable.ToLower() == "true"; + typeRecord.IsFrozen = frozen.ToLower() == "true"; } } @@ -154,7 +158,7 @@ public bool IsTypeProcessed(string moduleName, string typeIdentifier) var typeRecord = Registrar.GetType(moduleName, typeIdentifier); if (typeRecord != null) return typeRecord.IsProcessed; - + return false; } diff --git a/src/Swift.Runtime/src/TypeDatabase.xml b/src/Swift.Runtime/src/TypeDatabase.xml index f3b268c83524..1b57fde409ad 100644 --- a/src/Swift.Runtime/src/TypeDatabase.xml +++ b/src/Swift.Runtime/src/TypeDatabase.xml @@ -2,70 +2,70 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/Swift.Runtime/src/TypeRegistrar.cs b/src/Swift.Runtime/src/TypeRegistrar.cs index 4011a856bab1..5da10ae79341 100644 --- a/src/Swift.Runtime/src/TypeRegistrar.cs +++ b/src/Swift.Runtime/src/TypeRegistrar.cs @@ -53,7 +53,7 @@ public record TypeRecord /// The C# type identifier. /// public required string TypeIdentifier { get; set; } - + /// /// The Swift metadata accessor. /// @@ -68,6 +68,10 @@ public record TypeRecord /// The value indicating whether the type has been processed. /// public required bool IsProcessed { get; set; } + + public required bool IsBlittable { get; set; } + + public required bool IsFrozen { get; set; } } public class TypeRegistrar @@ -102,14 +106,16 @@ public ModuleRecord RegisterModule(string moduleName) /// The type record. public TypeRecord RegisterType(string moduleName, string typeIdentifier) { - var moduleRecord = RegisterModule(moduleName); + var moduleRecord = RegisterModule(moduleName); return moduleRecord.TypeRecords.GetOrAdd(typeIdentifier, _ => new TypeRecord { Namespace = moduleName, TypeIdentifier = typeIdentifier, SwiftTypeInfo = null, IsProcessed = false, - MetadataAccessor = string.Empty + MetadataAccessor = string.Empty, + IsBlittable = false, + IsFrozen = false }); } From 1b8a52f6498638388eed091791ce5f71127de28b Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Fri, 13 Dec 2024 13:16:22 +0100 Subject: [PATCH 3/7] TypeDatabase on env --- .../Handler/MethodHandler.cs | 36 +++++++++---------- .../Handler/ModuleHandler.cs | 12 +++---- .../Handler/TypeHandler.cs | 30 ++++++++-------- .../StringCSharpEmitter/ModuleEmitter.cs | 4 +-- .../src/Marshaler/IEnvironment.cs | 13 +++++-- src/Swift.Bindings/src/Marshaler/IHandler.cs | 17 +++++---- .../src/Marshaler/MarshallingExtensions.cs | 3 +- 7 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index e124d66135d8..314a5d8194f6 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -42,9 +42,9 @@ public ConstructorHandler() /// Marshals the specified constructor. /// /// - public IEnvironment Marshal(BaseDecl decl) + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { - return new MethodEnvironment(decl); + return new MethodEnvironment(decl, typeDatabase); } /// @@ -54,11 +54,11 @@ public IEnvironment Marshal(BaseDecl decl) /// The environment. /// The conductor instance. /// The type database instance. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var methodEnv = (MethodEnvironment)env; - EmitWrapper(writer, methodEnv, typeDatabase); - PInvokeEmitter.EmitPInvoke(writer, methodEnv, typeDatabase); + EmitWrapper(writer, methodEnv); + PInvokeEmitter.EmitPInvoke(writer, methodEnv); writer.WriteLine(); } @@ -68,7 +68,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto /// The IndentedTextWriter instance. /// The method environment. /// The type database instance. - private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment methodEnv, TypeDatabase typeDatabase) + private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment methodEnv) { var methodDecl = (MethodDecl)methodEnv.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); @@ -79,10 +79,10 @@ private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment met string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, methodEnv.TypeDatabase); string invokeArguments = pInvokeSignature.ParametersNames(); - if (methodDecl.RequiresIndirectResult(parentDecl, typeDatabase)) + if (methodDecl.RequiresIndirectResult(parentDecl, methodEnv.TypeDatabase)) { writer.WriteLine($"_payload = (SwiftHandle)NativeMemory.Alloc(_payloadSize);"); writer.WriteLine("var swiftIndirectResult = new SwiftIndirectResult((void*)_payload);"); @@ -135,9 +135,9 @@ public MethodHandler() /// Marshals the method declaration. /// /// The method declaration. - public IEnvironment Marshal(BaseDecl methodDecl) + public IEnvironment Marshal(BaseDecl methodDecl, TypeDatabase typeDatabase) { - return new MethodEnvironment(methodDecl); + return new MethodEnvironment(methodDecl, typeDatabase); } /// @@ -147,12 +147,12 @@ public IEnvironment Marshal(BaseDecl methodDecl) /// The environment. /// The conductor instance. /// The type database. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var methodEnv = (MethodEnvironment)env; - EmitWrapperMethod(writer, methodEnv, typeDatabase); - PInvokeEmitter.EmitPInvoke(writer, methodEnv, typeDatabase); + EmitWrapperMethod(writer, methodEnv); + PInvokeEmitter.EmitPInvoke(writer, methodEnv); writer.WriteLine(); } @@ -162,7 +162,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto /// The IndentedTextWriter instance. /// The environment. /// The type database. - private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env, TypeDatabase typeDatabase) + private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) { var methodDecl = (MethodDecl)env.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); @@ -185,7 +185,7 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env, string returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, env.TypeDatabase); string invokeArguments = pInvokeSignature.ParametersNames(); // Call the PInvoke method @@ -372,19 +372,19 @@ public static class PInvokeEmitter /// The IndentedTextWriter instance. /// The method environment. /// The type database. - public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment methodEnv, TypeDatabase typeDatabase) + public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment methodEnv) { var methodDecl = (MethodDecl)methodEnv.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ModuleDecl)); string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; - string libPath = typeDatabase.GetLibraryName(moduleDecl.Name); + string libPath = methodEnv.TypeDatabase.GetLibraryName(moduleDecl.Name); writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{methodDecl.MangledName}\")]"); - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, typeDatabase); + var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, methodEnv.TypeDatabase); writer.WriteLine($"private static extern {pInvokeSignature.ReturnType} {PInvokeName}({pInvokeSignature.ParametersString()});"); } diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs index 29e38434775f..fa76100e2a5d 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs @@ -42,9 +42,9 @@ public ModuleHandler() /// Marshals the module declaration. /// /// The module declaration. - public IEnvironment Marshal(BaseDecl moduleDecl) + public IEnvironment Marshal(BaseDecl moduleDecl, TypeDatabase typeDatabase) { - return new ModuleEnvironment(moduleDecl); + return new ModuleEnvironment(moduleDecl, typeDatabase); } /// @@ -54,7 +54,7 @@ public IEnvironment Marshal(BaseDecl moduleDecl) /// The environment. /// The conductor instance. /// The type database instance. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var moduleEnv = (ModuleEnvironment)env; var moduleDecl = (ModuleDecl)moduleEnv.ModuleDecl; @@ -92,8 +92,8 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto { if (conductor.TryGetMethodHandler(methodDecl, out var methodHandler)) { - var methodEnv = methodHandler.Marshal(methodDecl); - methodHandler.Emit(writer, methodEnv, conductor, typeDatabase); + var methodEnv = methodHandler.Marshal(methodDecl, env.TypeDatabase); + methodHandler.Emit(writer, methodEnv, conductor); } else { @@ -108,7 +108,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto } // Emit top-level types - base.HandleBaseDecl(writer, moduleDecl.Declarations, conductor, typeDatabase); + base.HandleBaseDecl(writer, moduleDecl.Declarations, conductor, env.TypeDatabase); writer.Indent--; writer.WriteLine("}"); diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs index 527455f77208..cbb040f6f7f7 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs @@ -42,9 +42,9 @@ public FrozenStructHandler() /// Marshals the specified struct declaration. /// /// The struct declaration. - public IEnvironment Marshal(BaseDecl structDecl) + public IEnvironment Marshal(BaseDecl structDecl, TypeDatabase typeDatabase) { - return new TypeEnvironment(structDecl); + return new TypeEnvironment(structDecl, typeDatabase); } /// @@ -54,14 +54,14 @@ public IEnvironment Marshal(BaseDecl structDecl) /// The environment. /// The conductor instance. /// The type database instance. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var structEnv = (TypeEnvironment)env; var structDecl = (StructDecl)structEnv.TypeDecl; var parentDecl = structDecl.ParentDecl ?? throw new ArgumentNullException(nameof(structDecl.ParentDecl)); var moduleDecl = structDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(structDecl.ParentDecl)); // Retrieve type info from the type database - var typeRecord = typeDatabase.Registrar.GetType(moduleDecl.Name, structDecl.Name); + var typeRecord = env.TypeDatabase.Registrar.GetType(moduleDecl.Name, structDecl.Name); SwiftTypeInfo? swiftTypeInfo = typeRecord?.SwiftTypeInfo; if (swiftTypeInfo.HasValue) @@ -91,7 +91,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto } writer.WriteLine(); - base.HandleBaseDecl(writer, structDecl.Declarations, conductor, typeDatabase); + base.HandleBaseDecl(writer, structDecl.Declarations, conductor, env.TypeDatabase); writer.Indent--; writer.WriteLine("}"); @@ -162,9 +162,9 @@ public NonFrozenStructHandler() /// Marshals the specified struct declaration. /// /// The struct declaration. - public IEnvironment Marshal(BaseDecl structDecl) + public IEnvironment Marshal(BaseDecl structDecl, TypeDatabase typeDatabase) { - return new TypeEnvironment(structDecl); + return new TypeEnvironment(structDecl, typeDatabase); } /// @@ -174,13 +174,13 @@ public IEnvironment Marshal(BaseDecl structDecl) /// The environment. /// The conductor instance. /// The type database instance. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var structEnv = (TypeEnvironment)env; var structDecl = (StructDecl)structEnv.TypeDecl; var parentDecl = structDecl.ParentDecl ?? throw new ArgumentNullException(nameof(structDecl.ParentDecl)); var moduleDecl = structDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(structDecl.ModuleDecl)); - var typeRecord = typeDatabase.Registrar.GetType(moduleDecl.Name, structDecl.Name); + var typeRecord = env.TypeDatabase.Registrar.GetType(moduleDecl.Name, structDecl.Name); SwiftTypeInfo? swiftTypeInfo = typeRecord?.SwiftTypeInfo; writer.WriteLine($"public unsafe class {structDecl.Name} : IDisposable"); @@ -191,10 +191,10 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto WriteDisposeMethod(writer, structDecl.Name); WriteFinalizer(writer, structDecl.Name); WritePayload(writer); - WriteMetadata(writer, moduleDecl.Name, structDecl.MangledName, typeDatabase); + WriteMetadata(writer, moduleDecl.Name, structDecl.MangledName, env.TypeDatabase); writer.WriteLine(); - base.HandleBaseDecl(writer, structDecl.Declarations, conductor, typeDatabase); + base.HandleBaseDecl(writer, structDecl.Declarations, conductor, env.TypeDatabase); writer.Indent--; writer.WriteLine("}"); @@ -302,9 +302,9 @@ public ClassHandler() /// Marshals the specified class declaration. /// /// The class declaration. - public IEnvironment Marshal(BaseDecl classDecl) + public IEnvironment Marshal(BaseDecl classDecl, TypeDatabase typeDatabase) { - return new TypeEnvironment(classDecl); + return new TypeEnvironment(classDecl, typeDatabase); } /// @@ -314,7 +314,7 @@ public IEnvironment Marshal(BaseDecl classDecl) /// The environment. /// The conductor instance. /// The type database instance. - public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase) + public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var classEnv = (TypeEnvironment)env; var classDecl = (ClassDecl)classEnv.TypeDecl; @@ -322,7 +322,7 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto writer.WriteLine($"public unsafe class {classDecl.Name} {{"); writer.Indent++; - base.HandleBaseDecl(writer, classDecl.Declarations, conductor, typeDatabase); + base.HandleBaseDecl(writer, classDecl.Declarations, conductor, env.TypeDatabase); writer.Indent--; writer.WriteLine("}"); diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/ModuleEmitter.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/ModuleEmitter.cs index 852a30cee3f5..f40e2323e9f1 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/ModuleEmitter.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/ModuleEmitter.cs @@ -40,8 +40,8 @@ public void EmitModule(ModuleDecl moduleDecl) IndentedTextWriter writer = new(sw); var @namespace = $"Swift.{moduleDecl.Name}"; - var env = moduleHandler.Marshal(moduleDecl); - moduleHandler.Emit(writer, env, _conductor, _typeDatabase); + var env = moduleHandler.Marshal(moduleDecl, _typeDatabase); + moduleHandler.Emit(writer, env, _conductor); string csOutputPath = Path.Combine(_outputDirectory, $"{@namespace}.cs"); using (StreamWriter outputFile = new(csOutputPath)) diff --git a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs index c86540b6b1a9..120c14f3e2f6 100644 --- a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs +++ b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using Swift.Runtime; + namespace BindingsGeneration { /// @@ -8,6 +10,7 @@ namespace BindingsGeneration /// public interface IEnvironment { + public TypeDatabase TypeDatabase { get; } // TODO: Replace with proper interface. Consider base class. } /// @@ -17,12 +20,13 @@ public interface IEnvironment /// Initializes a new instance of the ModuleEnvironment class. /// /// The module declaration. - public class ModuleEnvironment(BaseDecl moduleDecl) : IEnvironment + public class ModuleEnvironment(BaseDecl moduleDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the module declaration. /// public BaseDecl ModuleDecl { get; private set; } = moduleDecl; + public TypeDatabase TypeDatabase { get; } = typeDatabase; } /// @@ -32,12 +36,13 @@ public class ModuleEnvironment(BaseDecl moduleDecl) : IEnvironment /// Initializes a new instance of the TypeEnvironment class. /// /// The type declaration. - public class TypeEnvironment(BaseDecl typeDecl) : IEnvironment + public class TypeEnvironment(BaseDecl typeDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the type declaration. /// public BaseDecl TypeDecl { get; private set; } = typeDecl; + public TypeDatabase TypeDatabase { get; } = typeDatabase; } /// @@ -47,7 +52,7 @@ public class TypeEnvironment(BaseDecl typeDecl) : IEnvironment /// Initializes a new instance of the MethodEnvironment class. /// /// The method declaration. - public class MethodEnvironment(BaseDecl methodDecl) : IEnvironment + public class MethodEnvironment(BaseDecl methodDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the method declaration. @@ -58,5 +63,7 @@ public class MethodEnvironment(BaseDecl methodDecl) : IEnvironment /// Gets the PInvoke prefix. /// public string PInvokePrefix { get; private set; } = "PInvoke_"; + + public TypeDatabase TypeDatabase { get; } = typeDatabase; } } diff --git a/src/Swift.Bindings/src/Marshaler/IHandler.cs b/src/Swift.Bindings/src/Marshaler/IHandler.cs index 5f37baf53c69..d693e07c53a0 100644 --- a/src/Swift.Bindings/src/Marshaler/IHandler.cs +++ b/src/Swift.Bindings/src/Marshaler/IHandler.cs @@ -16,7 +16,7 @@ public interface IHandler /// /// The base declaration. /// The environment corresponding to the base declaration. - IEnvironment Marshal(BaseDecl baseDecl); + IEnvironment Marshal(BaseDecl baseDecl, TypeDatabase typeDatabase); /// /// Emits the necessary code for the specified environment. @@ -24,8 +24,7 @@ public interface IHandler /// The IndentedTextWriter instance. /// The environment. /// The conductor instance. - /// The type database instance. - void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor, TypeDatabase typeDatabase); + void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor); } /// @@ -83,8 +82,8 @@ protected virtual void HandleBaseDecl(IndentedTextWriter writer, IEnumerable Date: Mon, 16 Dec 2024 22:30:16 +0100 Subject: [PATCH 4/7] Rework signature handling --- .../Handler/MethodHandler.cs | 181 +++++++++++++----- .../Handler/ModuleHandler.cs | 9 +- .../Handler/TypeHandler.cs | 22 ++- .../src/Marshaler/IEnvironment.cs | 34 +++- 4 files changed, 189 insertions(+), 57 deletions(-) diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index 314a5d8194f6..f4175711a38f 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -41,10 +41,15 @@ public ConstructorHandler() /// /// Marshals the specified constructor. /// - /// + /// The method declaration. + /// The type database instance. public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { - return new MethodEnvironment(decl, typeDatabase); + if (decl is not MethodDecl methodDecl) + { + throw new ArgumentException("The provided decl must be a MethodDecl.", nameof(decl)); + } + return new MethodEnvironment(methodDecl, typeDatabase); } /// @@ -70,17 +75,17 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto /// The type database instance. private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment methodEnv) { - var methodDecl = (MethodDecl)methodEnv.MethodDecl; + var methodDecl = methodEnv.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - writer.WriteLine($"public {parentDecl.Name}({SignatureHandler.GetCSWrapperSignature(methodDecl)})"); + writer.WriteLine($"public {parentDecl.Name}({methodEnv.SignatureHandler.GetWrapperSignature().ParametersString()})"); writer.WriteLine("{"); writer.Indent++; string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, methodEnv.TypeDatabase); - string invokeArguments = pInvokeSignature.ParametersNames(); + var pInvokeSignature = methodEnv.SignatureHandler.GetPInvokeSignature(); + string invokeArguments = pInvokeSignature.CallArgumentsString(); if (methodDecl.RequiresIndirectResult(parentDecl, methodEnv.TypeDatabase)) { @@ -135,8 +140,13 @@ public MethodHandler() /// Marshals the method declaration. /// /// The method declaration. - public IEnvironment Marshal(BaseDecl methodDecl, TypeDatabase typeDatabase) + /// The type database instance. + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { + if (decl is not MethodDecl methodDecl) + { + throw new ArgumentException("The provided decl must be a MethodDecl.", nameof(decl)); + } return new MethodEnvironment(methodDecl, typeDatabase); } @@ -146,7 +156,6 @@ public IEnvironment Marshal(BaseDecl methodDecl, TypeDatabase typeDatabase) /// The IndentedTextWriter instance. /// The environment. /// The conductor instance. - /// The type database. public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var methodEnv = (MethodEnvironment)env; @@ -161,15 +170,15 @@ public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conducto /// /// The IndentedTextWriter instance. /// The environment. - /// The type database. private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) { var methodDecl = (MethodDecl)env.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - string methodName = $"{env.PInvokePrefix}{methodDecl.Name}"; + var methodName = $"{env.PInvokePrefix}{methodDecl.Name}"; + var staticKeyword = methodDecl.MethodType == MethodType.Static || parentDecl is ModuleDecl ? "static " : ""; - writer.WriteLine($"public {((methodDecl.MethodType == MethodType.Static || parentDecl is ModuleDecl) ? "static " : "")}{methodDecl.CSSignature.First().CSTypeIdentifier.Name} {methodDecl.Name}({SignatureHandler.GetCSWrapperSignature(methodDecl)})"); + writer.WriteLine($"public {staticKeyword}{methodDecl.CSSignature.First().CSTypeIdentifier.Name} {methodDecl.Name}({env.SignatureHandler.GetWrapperSignature().ParametersString()})"); writer.WriteLine("{"); writer.Indent++; @@ -183,10 +192,8 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) // TODO: Add Indirect result marshalling to methods other than constructors - string returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; - - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, env.TypeDatabase); - string invokeArguments = pInvokeSignature.ParametersNames(); + var returnPrefix = methodDecl.CSSignature.First().CSTypeIdentifier.Name == "void" ? "" : "return "; + var invokeArguments = env.SignatureHandler.GetPInvokeSignature().CallArgumentsString(); // Call the PInvoke method writer.WriteLine($"{returnPrefix}{methodName}({invokeArguments});"); @@ -197,35 +204,101 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) } /// - /// Represents a PInvoke argument. + /// Represents a parameter. /// /// /// - internal record PInvokeArgument(string Type, string Name) + public record Parameter(string Type, string Name) { public override string ToString() => $"{Type} {Name}"; } /// - /// Represents a PInvoke signature. + /// Represents a signature. /// /// /// - internal record PInvokeSignature(string ReturnType, IReadOnlyList Parameters) + public record Signature(string ReturnType, IReadOnlyList Parameters) { public string ParametersString() => string.Join(", ", Parameters.Select(p => p.ToString())); - public string ParametersNames() => string.Join(", ", Parameters.Select(p => + public string CallArgumentsString() => string.Join(", ", Parameters.Select(p => p.Type == "SwiftHandle" ? $"{p.Name}.Payload" : p.Name)); // TODO: Find a better way to do this } + public class WrapperSignatureBuilder + { + private string _returnType = "invalid"; + private readonly List _parameters = new(); + + MethodDecl MethodDecl { get; } + BaseDecl ParentDecl { get; } + TypeDatabase TypeDatabase { get; } + + public WrapperSignatureBuilder(MethodDecl methodDecl, TypeDatabase typeDatabase) + { + MethodDecl = methodDecl; + ParentDecl = methodDecl.ParentDecl!; + TypeDatabase = typeDatabase; + } + + /// + /// Handles the return type of the method. + /// + public void HandleReturnType() + { + var returnType = MethodDecl.CSSignature.First().CSTypeIdentifier.Name; + SetReturnType(returnType); + } + + /// + /// Handles the arguments of the method. + /// + public void HandleArguments() + { + foreach (var argument in MethodDecl.CSSignature.Skip(1)) + { + AddParameter(argument.CSTypeIdentifier.Name, argument.Name); + } + } + + /// + /// Builds the PInvoke signature. + /// + /// The PInvoke signature. + public Signature Build() + { + return new Signature(_returnType, _parameters.ToArray()); + } + + + /// + /// Sets the return type of the method. + /// + /// The return type. + private void SetReturnType(string returnType) + { + _returnType = returnType; + } + + /// + /// Adds a parameter to the PInvoke signature. + /// + /// The parameter type. + /// The parameter name.s + private void AddParameter(string type, string name) + { + _parameters.Add(new Parameter(type, name)); + } + } + /// /// Represents a PInvoke signature builder. /// - internal class PInvokeSignatureBuilder + public class PInvokeSignatureBuilder { private string _returnType = "invalid"; - private readonly List _parameters = new(); + private readonly List _parameters = new(); MethodDecl MethodDecl { get; } BaseDecl ParentDecl { get; } @@ -238,10 +311,10 @@ internal class PInvokeSignatureBuilder /// The method declaration. /// The parent declaration. /// The type database. - public PInvokeSignatureBuilder(MethodDecl methodDecl, BaseDecl parentDecl, TypeDatabase typeDatabase) + public PInvokeSignatureBuilder(MethodDecl methodDecl, TypeDatabase typeDatabase) { MethodDecl = methodDecl; - ParentDecl = parentDecl; + ParentDecl = methodDecl.ParentDecl!; TypeDatabase = typeDatabase; } @@ -303,9 +376,9 @@ public void HandleSwiftSelf() /// Builds the PInvoke signature. /// /// The PInvoke signature. - public PInvokeSignature Build() + public Signature Build() { - return new PInvokeSignature(_returnType, _parameters.ToArray()); + return new Signature(_returnType, _parameters.ToArray()); } /// @@ -324,40 +397,58 @@ private void SetReturnType(string returnType) /// The parameter name.s private void AddParameter(string type, string name) { - _parameters.Add(new PInvokeArgument(type, name)); + _parameters.Add(new Parameter(type, name)); } } /// /// Provides methods for handling method signatures. /// - static class SignatureHandler + public class SignatureHandler { + private Signature? _pInvokeSignature; + private Signature? _wrapperSignature; + + MethodDecl MethodDecl { get; } + TypeDatabase TypeDatabase { get; } + + public SignatureHandler(MethodDecl methodDecl, TypeDatabase typeDatabase) + { + MethodDecl = methodDecl; + TypeDatabase = typeDatabase; + } + /// - /// Gets the method parameters. + /// Gets the PInvoke signature. /// - /// The method declaration. - /// The type database. - /// The method parameters. - public static PInvokeSignature GetPinvokeSignature(MethodDecl methodDecl, TypeDatabase typeDatabase) + /// The PInvoke signature. + public Signature GetPInvokeSignature() { - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - var pInvokeSignature = new PInvokeSignatureBuilder(methodDecl, parentDecl, typeDatabase); - pInvokeSignature.HandleReturnType(); - pInvokeSignature.HandleArguments(); - pInvokeSignature.HandleSwiftSelf(); - return pInvokeSignature.Build(); + if (_pInvokeSignature == null) + { + var pInvokeSignature = new PInvokeSignatureBuilder(MethodDecl, TypeDatabase); + pInvokeSignature.HandleReturnType(); + pInvokeSignature.HandleArguments(); + pInvokeSignature.HandleSwiftSelf(); + _pInvokeSignature = pInvokeSignature.Build(); + } + return _pInvokeSignature; } /// /// Gets the wrapper method signature. /// - /// The module declaration. /// The wrapper method signature. - public static string GetCSWrapperSignature(MethodDecl methodDecl) + public Signature GetWrapperSignature() { - List parameters = methodDecl.CSSignature.Skip(1).ToList(); - return string.Join(", ", parameters.Select(p => $"{p.CSTypeIdentifier.Name} {p.Name}").ToList()); + if (_wrapperSignature == null) + { + var wrapperSignature = new WrapperSignatureBuilder(MethodDecl, TypeDatabase); + wrapperSignature.HandleReturnType(); + wrapperSignature.HandleArguments(); + _wrapperSignature = wrapperSignature.Build(); + } + return _wrapperSignature; } } @@ -371,11 +462,9 @@ public static class PInvokeEmitter /// /// The IndentedTextWriter instance. /// The method environment. - /// The type database. public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment methodEnv) { var methodDecl = (MethodDecl)methodEnv.MethodDecl; - var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ModuleDecl)); string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; @@ -384,7 +473,7 @@ public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment meth writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{methodDecl.MangledName}\")]"); - var pInvokeSignature = SignatureHandler.GetPinvokeSignature(methodDecl, methodEnv.TypeDatabase); + var pInvokeSignature = methodEnv.SignatureHandler.GetPInvokeSignature(); writer.WriteLine($"private static extern {pInvokeSignature.ReturnType} {PInvokeName}({pInvokeSignature.ParametersString()});"); } diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs index fa76100e2a5d..76f66fe0072b 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/ModuleHandler.cs @@ -42,8 +42,13 @@ public ModuleHandler() /// Marshals the module declaration. /// /// The module declaration. - public IEnvironment Marshal(BaseDecl moduleDecl, TypeDatabase typeDatabase) + /// The type database instance. + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { + if (decl is not ModuleDecl moduleDecl) + { + throw new ArgumentException("The provided decl must be a ModuleDecl.", nameof(decl)); + } return new ModuleEnvironment(moduleDecl, typeDatabase); } @@ -57,7 +62,7 @@ public IEnvironment Marshal(BaseDecl moduleDecl, TypeDatabase typeDatabase) public void Emit(IndentedTextWriter writer, IEnvironment env, Conductor conductor) { var moduleEnv = (ModuleEnvironment)env; - var moduleDecl = (ModuleDecl)moduleEnv.ModuleDecl; + var moduleDecl = moduleEnv.ModuleDecl; var generatedNamespace = $"Swift.{moduleDecl.Name}"; diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs index cbb040f6f7f7..3457593e3327 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs @@ -42,8 +42,13 @@ public FrozenStructHandler() /// Marshals the specified struct declaration. /// /// The struct declaration. - public IEnvironment Marshal(BaseDecl structDecl, TypeDatabase typeDatabase) + /// The type database instance. + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { + if (decl is not StructDecl structDecl) + { + throw new ArgumentException("The provided decl must be a StructDecl.", nameof(decl)); + } return new TypeEnvironment(structDecl, typeDatabase); } @@ -162,8 +167,14 @@ public NonFrozenStructHandler() /// Marshals the specified struct declaration. /// /// The struct declaration. - public IEnvironment Marshal(BaseDecl structDecl, TypeDatabase typeDatabase) + /// The type database instance. + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { + if (decl is not StructDecl structDecl) + { + throw new ArgumentException("The provided decl must be a StructDecl.", nameof(decl)); + + } return new TypeEnvironment(structDecl, typeDatabase); } @@ -302,8 +313,13 @@ public ClassHandler() /// Marshals the specified class declaration. /// /// The class declaration. - public IEnvironment Marshal(BaseDecl classDecl, TypeDatabase typeDatabase) + /// The type database instance. + public IEnvironment Marshal(BaseDecl decl, TypeDatabase typeDatabase) { + if (decl is not ClassDecl classDecl) + { + throw new ArgumentException("The provided decl must be a ClassDecl.", nameof(decl)); + } return new TypeEnvironment(classDecl, typeDatabase); } diff --git a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs index 120c14f3e2f6..3a2b932e427f 100644 --- a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs +++ b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs @@ -10,6 +10,9 @@ namespace BindingsGeneration /// public interface IEnvironment { + /// + /// Gets the TypeDatabase + /// public TypeDatabase TypeDatabase { get; } // TODO: Replace with proper interface. Consider base class. } @@ -20,12 +23,17 @@ public interface IEnvironment /// Initializes a new instance of the ModuleEnvironment class. /// /// The module declaration. - public class ModuleEnvironment(BaseDecl moduleDecl, TypeDatabase typeDatabase) : IEnvironment + /// The type database instance. + public class ModuleEnvironment(ModuleDecl moduleDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the module declaration. /// - public BaseDecl ModuleDecl { get; private set; } = moduleDecl; + public ModuleDecl ModuleDecl { get; private set; } = moduleDecl; + + /// + /// Gets the TypeDatabase + /// public TypeDatabase TypeDatabase { get; } = typeDatabase; } @@ -36,12 +44,17 @@ public class ModuleEnvironment(BaseDecl moduleDecl, TypeDatabase typeDatabase) : /// Initializes a new instance of the TypeEnvironment class. /// /// The type declaration. - public class TypeEnvironment(BaseDecl typeDecl, TypeDatabase typeDatabase) : IEnvironment + /// The type database instance. + public class TypeEnvironment(TypeDecl typeDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the type declaration. /// - public BaseDecl TypeDecl { get; private set; } = typeDecl; + public TypeDecl TypeDecl { get; private set; } = typeDecl; + + /// + /// Gets the TypeDatabase + /// public TypeDatabase TypeDatabase { get; } = typeDatabase; } @@ -52,18 +65,27 @@ public class TypeEnvironment(BaseDecl typeDecl, TypeDatabase typeDatabase) : IEn /// Initializes a new instance of the MethodEnvironment class. /// /// The method declaration. - public class MethodEnvironment(BaseDecl methodDecl, TypeDatabase typeDatabase) : IEnvironment + /// The type database instance. + public class MethodEnvironment(MethodDecl methodDecl, TypeDatabase typeDatabase) : IEnvironment { /// /// Gets the method declaration. /// - public BaseDecl MethodDecl { get; private set; } = methodDecl; + public MethodDecl MethodDecl { get; private set; } = methodDecl; /// /// Gets the PInvoke prefix. /// public string PInvokePrefix { get; private set; } = "PInvoke_"; + /// + /// Gets the TypeDatabase + /// public TypeDatabase TypeDatabase { get; } = typeDatabase; + + /// + /// Gets the SignatureHandler + /// + public SignatureHandler SignatureHandler { get; } = new SignatureHandler(methodDecl, typeDatabase); } } From 974893cf702a97d06e6aa485416a36e3f1a4e0f5 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Tue, 17 Dec 2024 00:56:59 +0100 Subject: [PATCH 5/7] Add centralized naming --- .../Handler/MethodHandler.cs | 26 ++++++++++++------- .../src/Marshaler/IEnvironment.cs | 4 --- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index f4175711a38f..a773b534199d 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -82,20 +82,20 @@ private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment met writer.WriteLine("{"); writer.Indent++; - string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; + var pInvokeName = NameProvider.GetPInvokeName(methodDecl); var pInvokeSignature = methodEnv.SignatureHandler.GetPInvokeSignature(); - string invokeArguments = pInvokeSignature.CallArgumentsString(); + var invokeArguments = pInvokeSignature.CallArgumentsString(); if (methodDecl.RequiresIndirectResult(parentDecl, methodEnv.TypeDatabase)) { writer.WriteLine($"_payload = (SwiftHandle)NativeMemory.Alloc(_payloadSize);"); writer.WriteLine("var swiftIndirectResult = new SwiftIndirectResult((void*)_payload);"); - writer.WriteLine($"{PInvokeName}({invokeArguments});"); + writer.WriteLine($"{pInvokeName}({invokeArguments});"); } else { - writer.WriteLine($"this = {PInvokeName}({invokeArguments});"); + writer.WriteLine($"this = {pInvokeName}({invokeArguments});"); } writer.Indent--; @@ -175,7 +175,7 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) var methodDecl = (MethodDecl)env.MethodDecl; var parentDecl = methodDecl.ParentDecl ?? throw new ArgumentNullException(nameof(methodDecl.ParentDecl)); - var methodName = $"{env.PInvokePrefix}{methodDecl.Name}"; + var pInvokeName = NameProvider.GetPInvokeName(methodDecl); var staticKeyword = methodDecl.MethodType == MethodType.Static || parentDecl is ModuleDecl ? "static " : ""; writer.WriteLine($"public {staticKeyword}{methodDecl.CSSignature.First().CSTypeIdentifier.Name} {methodDecl.Name}({env.SignatureHandler.GetWrapperSignature().ParametersString()})"); @@ -196,7 +196,7 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) var invokeArguments = env.SignatureHandler.GetPInvokeSignature().CallArgumentsString(); // Call the PInvoke method - writer.WriteLine($"{returnPrefix}{methodName}({invokeArguments});"); + writer.WriteLine($"{returnPrefix}{pInvokeName}({invokeArguments});"); writer.Indent--; writer.WriteLine("}"); @@ -467,15 +467,23 @@ public static void EmitPInvoke(IndentedTextWriter writer, MethodEnvironment meth var methodDecl = (MethodDecl)methodEnv.MethodDecl; var moduleDecl = methodDecl.ModuleDecl ?? throw new ArgumentNullException(nameof(methodDecl.ModuleDecl)); - string PInvokeName = $"{methodEnv.PInvokePrefix}{methodDecl.Name}"; - string libPath = methodEnv.TypeDatabase.GetLibraryName(moduleDecl.Name); + var pInvokeName = NameProvider.GetPInvokeName(methodDecl); + var libPath = methodEnv.TypeDatabase.GetLibraryName(moduleDecl.Name); writer.WriteLine("[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })]"); writer.WriteLine($"[DllImport(\"{libPath}\", EntryPoint = \"{methodDecl.MangledName}\")]"); var pInvokeSignature = methodEnv.SignatureHandler.GetPInvokeSignature(); - writer.WriteLine($"private static extern {pInvokeSignature.ReturnType} {PInvokeName}({pInvokeSignature.ParametersString()});"); + writer.WriteLine($"private static extern {pInvokeSignature.ReturnType} {pInvokeName}({pInvokeSignature.ParametersString()});"); + } + } + + public static class NameProvider + { + public static string GetPInvokeName(MethodDecl methodDecl) + { + return $"PInvoke_{methodDecl.Name}"; } } } diff --git a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs index 3a2b932e427f..707cb84cb91d 100644 --- a/src/Swift.Bindings/src/Marshaler/IEnvironment.cs +++ b/src/Swift.Bindings/src/Marshaler/IEnvironment.cs @@ -73,10 +73,6 @@ public class MethodEnvironment(MethodDecl methodDecl, TypeDatabase typeDatabase) /// public MethodDecl MethodDecl { get; private set; } = methodDecl; - /// - /// Gets the PInvoke prefix. - /// - public string PInvokePrefix { get; private set; } = "PInvoke_"; /// /// Gets the TypeDatabase From 17e2109bcb06713cccce11171d9a372cc8bf7098 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Tue, 17 Dec 2024 01:26:06 +0100 Subject: [PATCH 6/7] Reverted extension methods --- .../Handler/MethodHandler.cs | 15 +++++++------ .../Handler/TypeHandler.cs | 4 ++-- ...ingExtensions.cs => MarshallingHelpers.cs} | 21 ++++++++++++------- 3 files changed, 22 insertions(+), 18 deletions(-) rename src/Swift.Bindings/src/Marshaler/{MarshallingExtensions.cs => MarshallingHelpers.cs} (55%) diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs index a773b534199d..d803caff78ae 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/MethodHandler.cs @@ -87,7 +87,7 @@ private static void EmitWrapper(IndentedTextWriter writer, MethodEnvironment met var pInvokeSignature = methodEnv.SignatureHandler.GetPInvokeSignature(); var invokeArguments = pInvokeSignature.CallArgumentsString(); - if (methodDecl.RequiresIndirectResult(parentDecl, methodEnv.TypeDatabase)) + if (MarshallingHelpers.MethodRequiresIndirectResult(methodDecl, parentDecl, methodEnv.TypeDatabase)) { writer.WriteLine($"_payload = (SwiftHandle)NativeMemory.Alloc(_payloadSize);"); writer.WriteLine("var swiftIndirectResult = new SwiftIndirectResult((void*)_payload);"); @@ -182,9 +182,9 @@ private void EmitWrapperMethod(IndentedTextWriter writer, MethodEnvironment env) writer.WriteLine("{"); writer.Indent++; - if (methodDecl.RequiresSwiftSelf(parentDecl)) + if (MarshallingHelpers.MethodRequiresSwiftSelf(methodDecl, parentDecl)) { - if (parentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct()) + if (parentDecl is StructDecl structDecl && MarshallingHelpers.StructIsMarshalledAsCSStruct(structDecl)) writer.WriteLine($"var self = new SwiftSelf<{parentDecl.Name}>(this);"); else writer.WriteLine($"var self = new SwiftSelf((void*)_payload);"); @@ -323,7 +323,7 @@ public PInvokeSignatureBuilder(MethodDecl methodDecl, TypeDatabase typeDatabase) /// public void HandleReturnType() { - if (!MethodDecl.RequiresIndirectResult(ParentDecl, TypeDatabase)) + if (!MarshallingHelpers.MethodRequiresIndirectResult(MethodDecl, ParentDecl, TypeDatabase)) { var returnType = MethodDecl.CSSignature.First().CSTypeIdentifier.Name; SetReturnType(returnType); @@ -342,8 +342,7 @@ public void HandleArguments() { foreach (var argument in MethodDecl.CSSignature.Skip(1)) { - var typeRecord = TypeDatabase.Registrar.GetType(argument); - if (typeRecord.IsFrozen && typeRecord.IsBlittable) + if (MarshallingHelpers.ArgumentIsMarshalledAsCSStruct(argument, TypeDatabase)) { AddParameter(argument.CSTypeIdentifier.Name, argument.Name); } @@ -359,9 +358,9 @@ public void HandleArguments() /// public void HandleSwiftSelf() { - if (MethodDecl.RequiresSwiftSelf(ParentDecl)) + if (MarshallingHelpers.MethodRequiresSwiftSelf(MethodDecl, ParentDecl)) { - if (ParentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct()) + if (ParentDecl is StructDecl structDecl && MarshallingHelpers.StructIsMarshalledAsCSStruct(structDecl)) { AddParameter($"SwiftSelf<{ParentDecl.Name}>", "self"); } diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs index 3457593e3327..97aefdf33e97 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs @@ -17,7 +17,7 @@ public class FrozenStructHandlerFactory : IFactory /// The base declaration. public bool Handles(BaseDecl decl) { - return decl is StructDecl structDecl && structDecl.IsMarshalledAsStruct(); + return decl is StructDecl structDecl && MarshallingHelpers.StructIsMarshalledAsCSStruct(structDecl); } /// @@ -142,7 +142,7 @@ public class NonFrozenStructHandlerFactory : IFactory /// The base declaration. public bool Handles(BaseDecl decl) { - return decl is StructDecl structDecl && !structDecl.IsMarshalledAsStruct(); + return decl is StructDecl structDecl && !MarshallingHelpers.StructIsMarshalledAsCSStruct(structDecl); } /// diff --git a/src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs b/src/Swift.Bindings/src/Marshaler/MarshallingHelpers.cs similarity index 55% rename from src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs rename to src/Swift.Bindings/src/Marshaler/MarshallingHelpers.cs index 67248f231696..7d54e294ec2d 100644 --- a/src/Swift.Bindings/src/Marshaler/MarshallingExtensions.cs +++ b/src/Swift.Bindings/src/Marshaler/MarshallingHelpers.cs @@ -5,21 +5,20 @@ namespace BindingsGeneration { - public static class MarshallingExtensions // TODO: Find better place for those + public static class MarshallingHelpers // TODO: Find better place for those { - public static bool RequiresIndirectResult(this MethodDecl methodDecl, BaseDecl parentDecl, TypeDatabase typeDatabase) + public static bool MethodRequiresIndirectResult(MethodDecl methodDecl, BaseDecl parentDecl, TypeDatabase typeDatabase) { - if (methodDecl.IsConstructor && !(parentDecl is StructDecl structDecl && structDecl.IsMarshalledAsStruct())) return true; + if (methodDecl.IsConstructor && !(parentDecl is StructDecl structDecl && StructIsMarshalledAsCSStruct(structDecl))) return true; var returnType = methodDecl.CSSignature.First(); if (returnType.Name == "") return false; // TODO: Void should be handled differently - var returnTypeRecord = typeDatabase.Registrar.GetType(returnType); - if (!(returnTypeRecord.IsFrozen && returnTypeRecord.IsBlittable)) return true; + if (!ArgumentIsMarshalledAsCSStruct(returnType, typeDatabase)) return true; return false; } - public static bool RequiresSwiftSelf(this MethodDecl methodDecl, BaseDecl parentDecl) + public static bool MethodRequiresSwiftSelf(MethodDecl methodDecl, BaseDecl parentDecl) { if (parentDecl is ModuleDecl) return false; // global funcs if (methodDecl.MethodType == MethodType.Static) return false; @@ -28,12 +27,18 @@ public static bool RequiresSwiftSelf(this MethodDecl methodDecl, BaseDecl parent return true; } - public static bool IsMarshalledAsStruct(this StructDecl decl) + public static bool StructIsMarshalledAsCSStruct(StructDecl decl) { return decl is StructDecl structDecl && structDecl.IsFrozen && structDecl.IsBlittable; } - public static TypeRecord GetType(this TypeRegistrar typeRegistrar, ArgumentDecl argumentDecl) + public static bool ArgumentIsMarshalledAsCSStruct(ArgumentDecl argumentDecl, TypeDatabase typeDatabase) + { + var typeRecord = GetType(argumentDecl, typeDatabase.Registrar); //TODO: Add information to typeRecord if thing is a struct + return typeRecord.IsFrozen && typeRecord.IsBlittable; + } + + private static TypeRecord GetType(ArgumentDecl argumentDecl, TypeRegistrar typeRegistrar) { if (argumentDecl.SwiftTypeSpec is not NamedTypeSpec swiftTypeSpec) { From 5fd8181b82ca2f44ef10ba21c86debae934afa07 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Wed, 18 Dec 2024 00:48:26 +0100 Subject: [PATCH 7/7] Fix tests after rebase --- .../Handler/TypeHandler.cs | 2 +- src/Swift.Bindings/src/Marshaler/Conductor.cs | 11 +- .../NonFrozenStructs/NonFrozenStructsTests.cs | 211 ++++++++++++++++++ .../NonFrozenStructsTests.swift | 0 .../NonFrozenStructsTests.Source.cs | 141 ------------ .../NonFrozenStructs/NonFrozenStructsTests.cs | 169 -------------- 6 files changed, 219 insertions(+), 315 deletions(-) create mode 100644 src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.cs rename src/Swift.Bindings/tests/{ => IntegrationTests/StressTests}/NonFrozenStructs/NonFrozenStructsTests.swift (100%) delete mode 100644 src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs delete mode 100644 src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs diff --git a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs index 97aefdf33e97..eced3ada4d18 100644 --- a/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs +++ b/src/Swift.Bindings/src/Emitter/StringCSharpEmitter/Handler/TypeHandler.cs @@ -218,7 +218,7 @@ private static void WritePrivateFields(IndentedTextWriter writer) { writer.WriteLine(); writer.WriteLine("private static nuint _payloadSize = Metadata.Size;"); - writer.WriteLine("private SwiftHandle _payload;"); + writer.WriteLine("private SwiftHandle _payload = SwiftHandle.Zero;"); writer.WriteLine("private bool _disposed = false;"); } diff --git a/src/Swift.Bindings/src/Marshaler/Conductor.cs b/src/Swift.Bindings/src/Marshaler/Conductor.cs index 73b0060a8fa6..c1cf37c5e25a 100644 --- a/src/Swift.Bindings/src/Marshaler/Conductor.cs +++ b/src/Swift.Bindings/src/Marshaler/Conductor.cs @@ -16,20 +16,23 @@ namespace BindingsGeneration /// The Conductor class is responsible for managing handler factories and retrieving specific handlers for declarations. /// It initializes the handler factories and provides methods to fetch handlers for given declarations. /// - public class Conductor { + public class Conductor + { private readonly List _moduleHandlerFactories = [ new ModuleHandlerFactory() ]; private readonly List _typeHandlerFactories = [ - new StructHandlerFactory(), + new NonFrozenStructHandlerFactory(), + new FrozenStructHandlerFactory(), new ClassHandlerFactory(), ]; private readonly List _fieldHandlerFactories = []; private readonly List _methodHandlerFactories = [ - new MethodHandlerFactory() + new MethodHandlerFactory(), + new ConstructorHandlerFactory(), ]; private readonly List _argumentHandlerFactories = []; - + /// /// Initializes a new instance of the Conductor class and loads all handler factories. /// diff --git a/src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.cs b/src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.cs new file mode 100644 index 000000000000..1befd7416b4b --- /dev/null +++ b/src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.cs @@ -0,0 +1,211 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Xunit; +using Swift.NonFrozenStructsTests; + +namespace BindingsGeneration.Tests +{ + public class NonFrozenStructsTests : IClassFixture + { + private readonly TestFixture _fixture; + + public NonFrozenStructsTests(TestFixture fixture) + { + _fixture = fixture; + } + + public class TestFixture + { + static TestFixture() + { + InitializeResources(); + } + + private static void InitializeResources() + { + // Initialize + } + } + + [Fact] + public static void TestSwiftStruct0() + { + F0_S0 f0_s0 = new F0_S0(1.0, 2, 3); + F0_S1 f0_s1 = new F0_S1(4); + F0_S2 f0_s2 = new F0_S2(5.0f); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc0(-23758, 148652722, 3833542748216839160, 21987, new F0_S0(3425626963407448, 989224444, 55562), new F0_S1(1751696348434043356), 14, new F0_S2(1047842)); + Assert.Equal(-3555910212621330623, f0_s0.hashValue()); + Assert.Equal(3232700585171816769, f0_s1.hashValue()); + Assert.Equal(5405857218178297237, f0_s2.hashValue()); + Assert.Equal(-5199645484972017144, result); + } + + [Fact] + public static void TestSwiftStruct1() + { + + F1_S0 f1_s0 = new F1_S0(6, 7.0, 8, 9, 10); + F1_S1 f1_s1 = new F1_S1(101); + F1_S2 f1_s2 = new F1_S2(102); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc1(new F1_S0(6106136698885217102, 6195715435808, 121, 676336729, 51621), 121, new F1_S1(101), new F1_S2(-11974)); + + Assert.Equal(-8001373452266497130, f1_s0.hashValue()); + Assert.Equal(-5808561271200422464, f1_s1.hashValue()); + Assert.Equal(619381321311063739, f1_s2.hashValue()); + Assert.Equal(-5789188411070459345, result); + } + + [Fact] + public static void TestSwiftStruct2() + { + F2_S0 f2_s0 = new F2_S0(11, 12); + F2_S1 f2_s1 = new F2_S1(13, 14, 15, 16, 17); + F2_S2_S0_S0 f2_s2_s0_s0 = new F2_S2_S0_S0(18); + F2_S3 f2_s3 = new F2_S3(103); + F2_S4 f2_s4 = new F2_S4(16, 17); + F2_S5 f2_s5 = new F2_S5(18.0f); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc2(1467471118999515177, -1109, 1443466834, new F2_S0(unchecked((nint)8641951469425609828), unchecked((nuint)3263825339460718643)), 6, 42857709, new F2_S1(6855376760105631967, 2087467091, 25810, 2495195821026007124, 62146), new F2_S2(new F2_S2_S0(new F2_S2_S0_S0(unchecked((nint)561009218247569242)))), 46110, 7547287, new F2_S3(34), new F2_S4(203178131, unchecked((nuint)8676866947888134131)), new F2_S5(7890213), 5623254678629817168); + + Assert.Equal(-2644299808654375646, f2_s0.hashValue()); + Assert.Equal(-5946857472632060272, f2_s1.hashValue()); + Assert.Equal(-2996592682669871081, f2_s2_s0_s0.hashValue()); + Assert.Equal(-5808559072177166042, f2_s3.hashValue()); + Assert.Equal(8741931523650439060, f2_s4.hashValue()); + Assert.Equal(5451771724251677586, f2_s5.hashValue()); + Assert.Equal(-1831688667491861211, result); + } + + [Fact] + public static void TestSwiftStruct3() + { + F3_S0_S0 f3_s0_s0 = new F3_S0_S0(19, 20); + F3_S0 f3_s0 = new F3_S0(21, f3_s0_s0, 22); + F3_S1 f3_s1 = new F3_S1(23, 24.0f); + F3_S2 f3_s2 = new F3_S2(25.0f); + F3_S3 f3_s3 = new F3_S3(104, 26); + F3_S4 f3_s4 = new F3_S4(27, 28.0f, 29); + F3_S5 f3_s5 = new F3_S5(30, 31); + F3_S6_S0 f3_s6_s0 = new F3_S6_S0(32, 105); + F3_S6 f3_s6 = new F3_S6(f3_s6_s0, 33, 34); + F3_S7 f3_s7 = new F3_S7(35); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc3(unchecked((nint)3764414362291906102), new F3_S0(23, new F3_S0_S0(unchecked((nint)3007367655161186204), 549733154), 38928730), new F3_S1(338326426991485790, 7517271), 4025506815523052, unchecked((nint)431338169919855088), new F3_S2(7888763), new F3_S3(57, unchecked((nint)8933588466514096604)), new F3_S4(unchecked((nuint)7769316271655125502), 1663231, 27333), new F3_S5(887161443, 4368322322535461551), 32477, 948591564, new F3_S6(new F3_S6_S0(7033, 124), 67, 221), unchecked((nint)6195032215974632640), new F3_S7(4076570630190469380)); + + Assert.Equal(2183680504548519170, f3_s0_s0.hashValue()); + Assert.Equal(6464181192521079681, f3_s0.hashValue()); + Assert.Equal(-3914014010231380795, f3_s1.hashValue()); + Assert.Equal(5367593114012495226, f3_s2.hashValue()); + Assert.Equal(-5127890789322606739, f3_s3.hashValue()); + Assert.Equal(-1801544295733561908, f3_s4.hashValue()); + Assert.Equal(9153003238137716468, f3_s5.hashValue()); + Assert.Equal(-4315142132599941972, f3_s6_s0.hashValue()); + Assert.Equal(-1490133437166812017, f3_s6.hashValue()); + Assert.Equal(-1699583181824442426, f3_s7.hashValue()); + Assert.Equal(-8840537967093155898, result); + } + + [Fact] + public static void TestSwiftStruct4() + { + F4_S0 f4_s0 = new F4_S0(36, 37, 38); + F4_S1_S0 f4_s1_s0 = new F4_S1_S0(39); + F4_S1 f4_s1 = new F4_S1(f4_s1_s0, 40.0f); + F4_S2_S0 f4_s2_s0 = new F4_S2_S0(41); + F4_S2 f4_s2 = new F4_S2(f4_s2_s0, 42); + F4_S3 f4_s3 = new F4_S3(43, 44, 45); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc4(unchecked((nint)7962207922494873063), new F4_S0(16887, 11193, 20997), unchecked((nuint)938043702598629976), 8692646626431098135, -16, 1244033228990732, new F4_S1(new F4_S1_S0(274421021), 7037264), 154, 1187166500, 1096514224, 7283010216047805604, new F4_S2(new F4_S2_S0(unchecked((nint)3285810526807361976)), unchecked((nint)2934841899954168407)), 3384, unchecked((nint)4857017836321530071), new F4_S3(9030480386017125399, 5466901523025762626, 3430278619936831574), 234522698); + + Assert.Equal(-5555791715238606502, f4_s0.hashValue()); + Assert.Equal(7917312046649396258, f4_s1_s0.hashValue()); + Assert.Equal(7787216292523950588, f4_s1.hashValue()); + Assert.Equal(-6752434813728457588, f4_s2_s0.hashValue()); + Assert.Equal(-664221457051710106, f4_s2.hashValue()); + Assert.Equal(-1729670953176434449, f4_s3.hashValue()); + Assert.Equal(5366279618472372586, result); + } + + [Fact] + public static void TestSwiftStruct5() + { + F5_S0 f5_s0 = new F5_S0(46); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc5(unchecked((nuint)425569624776371773), 8077063517132296390, 126, new F5_S0(unchecked((nuint)8032431538406335990))); + + Assert.Equal(-8984750220696046997, f5_s0.hashValue()); + Assert.Equal(5832440388901373477, result); + } + + [Fact] + public static void TestSwiftStruct6() + { + F6_S0 f6_s0 = new F6_S0(47, 48, 49); + F6_S1 f6_s1 = new F6_S1(50, 51.0f); + F6_S2_S0 f6_s2_s0 = new F6_S2_S0(52.0); + F6_S2 f6_s2 = new F6_S2(f6_s2_s0, 53); + F6_S3 f6_s3 = new F6_S3(54.0, 55.0, 56); + F6_S4 f6_s4 = new F6_S4(57); + F6_S5 f6_s5 = new F6_S5(58); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc6(7742402881449217499, new F6_S0(158138445, unchecked((nint)4280990415451108676), 220), new F6_S1(unchecked((nint)7698928046973811162), 478730), unchecked((nuint)7348396082620937303), 76, 638113630, new F6_S2(new F6_S2_S0(55341051405503), 61378), 8235930, -20241, new F6_S3(318363825012010, 3586735152618866, 6630554942616673404), 46432, 744827194985602, 1973021571, new F6_S4(103), new F6_S5(-5345)); + + Assert.Equal(1692306587549742161, f6_s0.hashValue()); + Assert.Equal(-1484226257450236447, f6_s1.hashValue()); + Assert.Equal(-6229230135174619697, f6_s2_s0.hashValue()); + Assert.Equal(-3202371936141214966, f6_s2.hashValue()); + Assert.Equal(631817796766569309, f6_s3.hashValue()); + Assert.Equal(-5808600853619038060, f6_s4.hashValue()); + Assert.Equal(584944617122307319, f6_s5.hashValue()); + Assert.Equal(-8871753131984133391, result); + } + + [Fact] + public static void TestSwiftStruct7() + { + F7_S0 f7_s0 = new F7_S0(59, 60); + F7_S1 f7_s1 = new F7_S1(61); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc7(6953928391541094904, unchecked((nint)2531714261502554653), 224, new F7_S0(14482, unchecked((nint)4704842847707480837)), new F7_S1(148), 659764805); + + Assert.Equal(1770792034096671794, f7_s0.hashValue()); + Assert.Equal(-5808605251665550904, f7_s1.hashValue()); + Assert.Equal(5963731324167739917, result); + } + + [Fact] + public static void TestSwiftStruct8() + { + F8_S0 f8_s0 = new F8_S0(62); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc8(48505, unchecked((nuint)8758330817072549915), 7130, 4163773298933598697, new F8_S0(1934119180), 2843311260726166700); + + Assert.Equal(962290567653668427, f8_s0.hashValue()); + Assert.Equal(1919194302322813426, result); + } + + [Fact] + public static void TestSwiftStruct9() + { + F9_S0 f9_s0 = new F9_S0(63.0); + F9_S1 f9_s1 = new F9_S1(64); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc9(3214937834123081267, 6846768, new F9_S0(1713527158921541), 25670, new F9_S1(1650872599), 39910); + + Assert.Equal(-127835592947727486, f9_s0.hashValue()); + Assert.Equal(5462998930071304245, f9_s1.hashValue()); + Assert.Equal(-5878079645235476214, result); + } + + [Fact] + public static void TestSwiftStruct10() + { + F10_S0 f10_s0 = new F10_S0(65, 66); + F10_S1 f10_s1 = new F10_S1(67.0f, 68, 69); + F10_S2 f10_s2 = new F10_S2(70, 71); + F10_S3 f10_s3 = new F10_S3(72.0f); + F10_S4 f10_s4 = new F10_S4(73); + long result = Swift.NonFrozenStructsTests.NonFrozenStructsTests.swiftFunc10(57914, 11968, new F10_S0(155502634291755209, 2096010440), 1373054541331378384, 2401784, -16, 9038689080810964859, 521869082023571496, 8919173990791765137, 4890513, 1113752036, 1477591037, 1463349953238439103, 7521124889381630793, new F10_S1(620783, 33, unchecked((nuint)1209731409858919135)), 1560688600815438014, new F10_S2(unchecked((nuint)2244178273746563479), 4252696983313269084), new F10_S3(6539550), new F10_S4(1264398289929487498)); + + Assert.Equal(-1058509415045616378, f10_s0.hashValue()); + Assert.Equal(6725059428863802130, f10_s1.hashValue()); + Assert.Equal(716752888238966276, f10_s2.hashValue()); + Assert.Equal(5451770624740049375, f10_s3.hashValue()); + Assert.Equal(4635659444355057900, f10_s4.hashValue()); + Assert.Equal(-5714135075575530569, result); + } + } +} diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift b/src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.swift similarity index 100% rename from src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.swift rename to src/Swift.Bindings/tests/IntegrationTests/StressTests/NonFrozenStructs/NonFrozenStructsTests.swift diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs deleted file mode 100644 index 6e45bf23a4be..000000000000 --- a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.Source.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using Swift.NonFrozenStructsTests; - -namespace Test -{ - public class MainClass - { - public static int Main(string[] args) - { - return 0; - } - public static long[] SwiftNonFrozenStruct0() - { - Console.Write("Running SwiftStruct0: "); - F0_S0 f0_s0 = new F0_S0(1.0, 2, 3); - Console.WriteLine($"F0_S0: {f0_s0.hashValue()}"); - F0_S1 f0_s1 = new F0_S1(4); - Console.WriteLine($"F0_S1: {f0_s1.hashValue()}"); - F0_S2 f0_s2 = new F0_S2(5.0f); - Console.WriteLine($"F0_S2: {f0_s2.hashValue()}"); - long result = NonFrozenStructsTests.swiftFunc0(-23758, 148652722, 3833542748216839160, 21987, new F0_S0(3425626963407448, 989224444, 55562), new F0_S1(1751696348434043356), 14, new F0_S2(1047842)); - return new long[] { f0_s0.hashValue(), f0_s1.hashValue(), f0_s2.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct1() - { - Console.Write("Running SwiftStruct1: "); - F1_S0 f1_s0 = new F1_S0(6, 7.0, 8, 9, 10); - F1_S1 f1_s1 = new F1_S1(101); - F1_S2 f1_s2 = new F1_S2(102); - long result = NonFrozenStructsTests.swiftFunc1(new F1_S0(6106136698885217102, 6195715435808, 121, 676336729, 51621), 121, new F1_S1(101), new F1_S2(-11974)); - return new long[] { f1_s0.hashValue(), f1_s1.hashValue(), f1_s2.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct2() - { - Console.Write("Running SwiftStruct2: "); - F2_S0 f2_s0 = new F2_S0(11, 12); - F2_S1 f2_s1 = new F2_S1(13, 14, 15, 16, 17); - F2_S2_S0_S0 f2_s2_s0_s0 = new F2_S2_S0_S0(18); - F2_S3 f2_s3 = new F2_S3(103); - F2_S4 f2_s4 = new F2_S4(16, 17); - F2_S5 f2_s5 = new F2_S5(18.0f); - long result = NonFrozenStructsTests.swiftFunc2(1467471118999515177, -1109, 1443466834, new F2_S0(unchecked((nint)8641951469425609828), unchecked((nuint)3263825339460718643)), 6, 42857709, new F2_S1(6855376760105631967, 2087467091, 25810, 2495195821026007124, 62146), new F2_S2(new F2_S2_S0(new F2_S2_S0_S0(unchecked((nint)561009218247569242)))), 46110, 7547287, new F2_S3(34), new F2_S4(203178131, unchecked((nuint)8676866947888134131)), new F2_S5(7890213), 5623254678629817168); - return new long[] { f2_s0.hashValue(), f2_s1.hashValue(), f2_s2_s0_s0.hashValue(), f2_s3.hashValue(), f2_s4.hashValue(), f2_s5.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct3() - { - Console.Write("Running SwiftStruct3: "); - F3_S0_S0 f3_s0_s0 = new F3_S0_S0(19, 20); - F3_S0 f3_s0 = new F3_S0(21, f3_s0_s0, 22); - F3_S1 f3_s1 = new F3_S1(23, 24.0f); - F3_S2 f3_s2 = new F3_S2(25.0f); - F3_S3 f3_s3 = new F3_S3(104, 26); - F3_S4 f3_s4 = new F3_S4(27, 28.0f, 29); - F3_S5 f3_s5 = new F3_S5(30, 31); - F3_S6_S0 f3_s6_s0 = new F3_S6_S0(32, 105); - F3_S6 f3_s6 = new F3_S6(f3_s6_s0, 33, 34); - F3_S7 f3_s7 = new F3_S7(35); - long result = NonFrozenStructsTests.swiftFunc3(unchecked((nint)3764414362291906102), new F3_S0(23, new F3_S0_S0(unchecked((nint)3007367655161186204), 549733154), 38928730), new F3_S1(338326426991485790, 7517271), 4025506815523052, unchecked((nint)431338169919855088), new F3_S2(7888763), new F3_S3(57, unchecked((nint)8933588466514096604)), new F3_S4(unchecked((nuint)7769316271655125502), 1663231, 27333), new F3_S5(887161443, 4368322322535461551), 32477, 948591564, new F3_S6(new F3_S6_S0(7033, 124), 67, 221), unchecked((nint)6195032215974632640), new F3_S7(4076570630190469380)); - return new long[] { f3_s0_s0.hashValue(), f3_s0.hashValue(), f3_s1.hashValue(), f3_s2.hashValue(), f3_s3.hashValue(), f3_s4.hashValue(), f3_s5.hashValue(), f3_s6_s0.hashValue(), f3_s6.hashValue(), f3_s7.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct4() - { - Console.Write("Running SwiftStruct4: "); - F4_S0 f4_s0 = new F4_S0(36, 37, 38); - F4_S1_S0 f4_s1_s0 = new F4_S1_S0(39); - F4_S1 f4_s1 = new F4_S1(f4_s1_s0, 40.0f); - F4_S2_S0 f4_s2_s0 = new F4_S2_S0(41); - F4_S2 f4_s2 = new F4_S2(f4_s2_s0, 42); - F4_S3 f4_s3 = new F4_S3(43, 44, 45); - long result = NonFrozenStructsTests.swiftFunc4(unchecked((nint)7962207922494873063), new F4_S0(16887, 11193, 20997), unchecked((nuint)938043702598629976), 8692646626431098135, -16, 1244033228990732, new F4_S1(new F4_S1_S0(274421021), 7037264), 154, 1187166500, 1096514224, 7283010216047805604, new F4_S2(new F4_S2_S0(unchecked((nint)3285810526807361976)), unchecked((nint)2934841899954168407)), 3384, unchecked((nint)4857017836321530071), new F4_S3(9030480386017125399, 5466901523025762626, 3430278619936831574), 234522698); - return new long[] { f4_s0.hashValue(), f4_s1_s0.hashValue(), f4_s1.hashValue(), f4_s2_s0.hashValue(), f4_s2.hashValue(), f4_s3.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct5() - { - Console.Write("Running SwiftStruct5: "); - F5_S0 f5_s0 = new F5_S0(46); - long result = NonFrozenStructsTests.swiftFunc5(unchecked((nuint)425569624776371773), 8077063517132296390, 126, new F5_S0(unchecked((nuint)8032431538406335990))); - return new long[] { f5_s0.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct6() - { - Console.Write("Running SwiftStruct6: "); - F6_S0 f6_s0 = new F6_S0(47, 48, 49); - F6_S1 f6_s1 = new F6_S1(50, 51.0f); - F6_S2_S0 f6_s2_s0 = new F6_S2_S0(52.0); - F6_S2 f6_s2 = new F6_S2(f6_s2_s0, 53); - F6_S3 f6_s3 = new F6_S3(54.0, 55.0, 56); - F6_S4 f6_s4 = new F6_S4(57); - F6_S5 f6_s5 = new F6_S5(58); - long result = NonFrozenStructsTests.swiftFunc6(7742402881449217499, new F6_S0(158138445, unchecked((nint)4280990415451108676), 220), new F6_S1(unchecked((nint)7698928046973811162), 478730), unchecked((nuint)7348396082620937303), 76, 638113630, new F6_S2(new F6_S2_S0(55341051405503), 61378), 8235930, -20241, new F6_S3(318363825012010, 3586735152618866, 6630554942616673404), 46432, 744827194985602, 1973021571, new F6_S4(103), new F6_S5(-5345)); - return new long[] { f6_s0.hashValue(), f6_s1.hashValue(), f6_s2_s0.hashValue(), f6_s2.hashValue(), f6_s3.hashValue(), f6_s4.hashValue(), f6_s5.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct7() - { - Console.Write("Running SwiftStruct7: "); - F7_S0 f7_s0 = new F7_S0(59, 60); - F7_S1 f7_s1 = new F7_S1(61); - long result = NonFrozenStructsTests.swiftFunc7(6953928391541094904, unchecked((nint)2531714261502554653), 224, new F7_S0(14482, unchecked((nint)4704842847707480837)), new F7_S1(148), 659764805); - return new long[] { f7_s0.hashValue(), f7_s1.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct8() - { - Console.Write("Running SwiftStruct8: "); - F8_S0 f8_s0 = new F8_S0(62); - long result = NonFrozenStructsTests.swiftFunc8(48505, unchecked((nuint)8758330817072549915), 7130, 4163773298933598697, new F8_S0(1934119180), 2843311260726166700); - return new long[] { f8_s0.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct9() - { - Console.Write("Running SwiftStruct9: "); - F9_S0 f9_s0 = new F9_S0(63.0); - F9_S1 f9_s1 = new F9_S1(64); - long result = NonFrozenStructsTests.swiftFunc9(3214937834123081267, 6846768, new F9_S0(1713527158921541), 25670, new F9_S1(1650872599), 39910); - return new long[] { f9_s0.hashValue(), f9_s1.hashValue(), result }; - } - - public static long[] SwiftNonFrozenStruct10() - { - Console.Write("Running SwiftStruct10: "); - F10_S0 f10_s0 = new F10_S0(65, 66); - F10_S1 f10_s1 = new F10_S1(67.0f, 68, 69); - F10_S2 f10_s2 = new F10_S2(70, 71); - F10_S3 f10_s3 = new F10_S3(72.0f); - F10_S4 f10_s4 = new F10_S4(73); - long result = NonFrozenStructsTests.swiftFunc10(57914, 11968, new F10_S0(155502634291755209, 2096010440), 1373054541331378384, 2401784, -16, 9038689080810964859, 521869082023571496, 8919173990791765137, 4890513, 1113752036, 1477591037, 1463349953238439103, 7521124889381630793, new F10_S1(620783, 33, unchecked((nuint)1209731409858919135)), 1560688600815438014, new F10_S2(unchecked((nuint)2244178273746563479), 4252696983313269084), new F10_S3(6539550), new F10_S4(1264398289929487498)); - return new long[] { f10_s0.hashValue(), f10_s1.hashValue(), f10_s2.hashValue(), f10_s3.hashValue(), f10_s4.hashValue(), result }; - } - } -} diff --git a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs b/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs deleted file mode 100644 index c8f9736c953a..000000000000 --- a/src/Swift.Bindings/tests/NonFrozenStructs/NonFrozenStructsTests.cs +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using Xunit; - -namespace BindingsGeneration.Tests -{ - public class NonFrozenStructsTests : IClassFixture - { - private readonly TestFixture _fixture; - private static string _assemblyPath; - - public NonFrozenStructsTests(TestFixture fixture) - { - _fixture = fixture; - } - - public class TestFixture - { - static TestFixture() - { - InitializeResources(); - } - - private static void InitializeResources() - { - BindingsGenerator.GenerateBindings("NonFrozenStructs/NonFrozenStructsTests.abi.json", "NonFrozenStructs/"); - _assemblyPath = TestsHelper.Compile( - new string[] { "NonFrozenStructs/*.cs" }, - new string[] { }, - new string[] { }); - } - } - - [Fact] - public static void TestSwiftStruct0() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct0", new object[] { }); - Assert.Equal(-3555910212621330623, result[0]); - Assert.Equal(3232700585171816769, result[1]); - Assert.Equal(5405857218178297237, result[2]); - Assert.Equal(-5199645484972017144, result[3]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct1() - { - - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct1", new object[] { }); - Assert.Equal(-8001373452266497130, result[0]); - Assert.Equal(-5808561271200422464, result[1]); - Assert.Equal(619381321311063739, result[2]); - Assert.Equal(-5789188411070459345, result[3]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct2() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct2", new object[] { }); - Assert.Equal(-2644299808654375646, result[0]); - Assert.Equal(-5946857472632060272, result[1]); - Assert.Equal(-2996592682669871081, result[2]); - Assert.Equal(-5808559072177166042, result[3]); - Assert.Equal(8741931523650439060, result[4]); - Assert.Equal(5451771724251677586, result[5]); - Assert.Equal(-1831688667491861211, result[6]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct3() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct3", new object[] { }); - Assert.Equal(2183680504548519170, result[0]); - Assert.Equal(6464181192521079681, result[1]); - Assert.Equal(-3914014010231380795, result[2]); - Assert.Equal(5367593114012495226, result[3]); - Assert.Equal(-5127890789322606739, result[4]); - Assert.Equal(-1801544295733561908, result[5]); - Assert.Equal(9153003238137716468, result[6]); - Assert.Equal(-4315142132599941972, result[7]); - Assert.Equal(-1490133437166812017, result[8]); - Assert.Equal(-1699583181824442426, result[9]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct4() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct4", new object[] { }); - Assert.Equal(-5555791715238606502, result[0]); - Assert.Equal(7917312046649396258, result[1]); - Assert.Equal(7787216292523950588, result[2]); - Assert.Equal(-6752434813728457588, result[3]); - Assert.Equal(-664221457051710106, result[4]); - Assert.Equal(-1729670953176434449, result[5]); - Assert.Equal(5366279618472372586, result[6]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct5() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct5", new object[] { }); - Assert.Equal(-8984750220696046997, result[0]); - Assert.Equal(5832440388901373477, result[1]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct6() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct6", new object[] { }); - Assert.Equal(1692306587549742161, result[0]); - Assert.Equal(-1484226257450236447, result[1]); - Assert.Equal(-6229230135174619697, result[2]); - Assert.Equal(-3202371936141214966, result[3]); - Assert.Equal(631817796766569309, result[4]); - Assert.Equal(-5808600853619038060, result[5]); - Assert.Equal(584944617122307319, result[6]); - Assert.Equal(-8871753131984133391, result[7]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct7() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct7", new object[] { }); - Assert.Equal(1770792034096671794, result[0]); - Assert.Equal(-5808605251665550904, result[1]); - Assert.Equal(5963731324167739917, result[2]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct8() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct8", new object[] { }); - Assert.Equal(962290567653668427, result[0]); - Assert.Equal(1919194302322813426, result[1]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct9() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct9", new object[] { }); - Assert.Equal(-127835592947727486, result[0]); - Assert.Equal(5462998930071304245, result[1]); - Assert.Equal(-5878079645235476214, result[2]); - Console.WriteLine("OK"); - } - - [Fact] - public static void TestSwiftStruct10() - { - long[] result = (long[])TestsHelper.Execute(_assemblyPath, "Test.MainClass", "SwiftNonFrozenStruct10", new object[] { }); - Assert.Equal(-1058509415045616378, result[0]); - Assert.Equal(6725059428863802130, result[1]); - Assert.Equal(716752888238966276, result[2]); - Assert.Equal(5451770624740049375, result[3]); - Assert.Equal(4635659444355057900, result[4]); - Assert.Equal(-5714135075575530569, result[5]); - Console.WriteLine("OK"); - } - } -}