From 9485b2179bcd799971755694917129c3c518b335 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 31 Dec 2024 13:07:37 +0800 Subject: [PATCH 1/8] Update OGTupleType and add openGraphSPICompatibilityTestTarget --- Package.swift | 47 +++- .../{OGTupleType.swift => Tuple.swift} | 9 +- Sources/OpenGraphShims/GraphShims.swift | 2 - Sources/OpenGraph_SPI/OGBase.h | 1 + Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 230 ++++++++++++++++-- Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 66 ++++- Sources/OpenGraph_SPI/Runtime/OGTypeID.h | 6 +- Sources/OpenGraph_SPI/Util/assert.hpp | 5 +- .../GraphShims.swift | 2 - Tests/OpenGraphCompatibilityTests/README.md | 1 - .../Runtime/MetadataTests.swift | 74 ------ .../Runtime/TupleTypeTests.swift | 12 - .../GraphShims.swift | 37 +++ .../OpenGraph_SPICompatibilityTests/README.md | 7 + .../Runtime/MetadataTests.swift | 100 ++++++++ .../Runtime/TupleTypeTests.swift | 21 ++ 16 files changed, 483 insertions(+), 137 deletions(-) rename Sources/OpenGraph/Runtime/{OGTupleType.swift => Tuple.swift} (80%) create mode 100644 Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift create mode 100644 Tests/OpenGraph_SPICompatibilityTests/README.md create mode 100644 Tests/OpenGraph_SPICompatibilityTests/Runtime/MetadataTests.swift create mode 100644 Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift diff --git a/Package.swift b/Package.swift index 09e238e9..290d8d4b 100644 --- a/Package.swift +++ b/Package.swift @@ -144,6 +144,15 @@ let openGraphCompatibilityTestTarget = Target.testTarget( cSettings: sharedCSettings, swiftSettings: sharedSwiftSettings ) +let openGraphSPICompatibilityTestTarget = Target.testTarget( + name: "OpenGraph_SPICompatibilityTests", + dependencies: [ + .product(name: "Numerics", package: "swift-numerics"), + ], + exclude: ["README.md"], + cSettings: sharedCSettings, + swiftSettings: sharedSwiftSettings +) // MARK: - Package @@ -178,6 +187,7 @@ let package = Package( openGraphTestTarget, openGraphShimsTestTarget, openGraphCompatibilityTestTarget, + openGraphSPICompatibilityTestTarget, ], cxxLanguageStandard: .cxx17 ) @@ -192,6 +202,26 @@ let attributeGraphCondition = envEnable("OPENGRAPH_ATTRIBUTEGRAPH") #endif let useLocalDeps = envEnable("OPENGRAPH_USE_LOCAL_DEPS") +extension Target { + func addAGSettings() { + dependencies.append( + .product(name: "AttributeGraph", package: "DarwinPrivateFrameworks") + ) + var swiftSettings = swiftSettings ?? [] + swiftSettings.append(.define("OPENGRAPH_ATTRIBUTEGRAPH")) + self.swiftSettings = swiftSettings + } + + func addCompatibilitySettings() { + dependencies.append( + .product(name: "AttributeGraph", package: "DarwinPrivateFrameworks") + ) + var swiftSettings = swiftSettings ?? [] + swiftSettings.append(.define("OPENGRAPH_COMPATIBILITY_TEST")) + self.swiftSettings = swiftSettings + } +} + if attributeGraphCondition { let privateFrameworkRepo: Package.Dependency if useLocalDeps { @@ -200,12 +230,7 @@ if attributeGraphCondition { privateFrameworkRepo = Package.Dependency.package(url: "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", branch: "main") } package.dependencies.append(privateFrameworkRepo) - var swiftSettings: [SwiftSetting] = (openGraphShimsTarget.swiftSettings ?? []) - swiftSettings.append(.define("OPENGRAPH_ATTRIBUTEGRAPH")) - openGraphShimsTarget.swiftSettings = swiftSettings - openGraphShimsTarget.dependencies.append( - .product(name: "AttributeGraph", package: "DarwinPrivateFrameworks") - ) + openGraphShimsTarget.addAGSettings() let agVersion = Context.environment["DARWIN_PRIVATE_FRAMEWORKS_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024 package.platforms = switch agVersion { @@ -219,15 +244,11 @@ if attributeGraphCondition { let compatibilityTestCondition = envEnable("OPENGRAPH_COMPATIBILITY_TEST") if compatibilityTestCondition && attributeGraphCondition { - openGraphCompatibilityTestTarget.dependencies.append( - .product(name: "AttributeGraph", package: "DarwinPrivateFrameworks") - ) - - var swiftSettings: [SwiftSetting] = (openGraphCompatibilityTestTarget.swiftSettings ?? []) - swiftSettings.append(.define("OPENGRAPH_COMPATIBILITY_TEST")) - openGraphCompatibilityTestTarget.swiftSettings = swiftSettings + openGraphCompatibilityTestTarget.addCompatibilitySettings() + openGraphSPICompatibilityTestTarget.addCompatibilitySettings() } else { openGraphCompatibilityTestTarget.dependencies.append("OpenGraph") + openGraphSPICompatibilityTestTarget.dependencies.append("OpenGraph_SPI") } extension [Platform] { diff --git a/Sources/OpenGraph/Runtime/OGTupleType.swift b/Sources/OpenGraph/Runtime/Tuple.swift similarity index 80% rename from Sources/OpenGraph/Runtime/OGTupleType.swift rename to Sources/OpenGraph/Runtime/Tuple.swift index ed07c5b3..590d6fe2 100644 --- a/Sources/OpenGraph/Runtime/OGTupleType.swift +++ b/Sources/OpenGraph/Runtime/Tuple.swift @@ -1,17 +1,18 @@ // // OGTupleType.swift +// OpenGraph // -// -// +// Audited for iOS 18.0 +// Status: WIP public import OpenGraph_SPI @_silgen_name("OGTupleElementType") @inline(__always) -private func OGTupleElementType(_ tupleType: OGTupleType, index: Int) -> Metadata +private func OGTupleElementType(_ tupleType: TupleType, index: Int) -> Metadata // TODO -extension OGTupleType { +extension TupleType { public init(_ type: [Any.Type]) { fatalError("TODO") } diff --git a/Sources/OpenGraphShims/GraphShims.swift b/Sources/OpenGraphShims/GraphShims.swift index 1b1416cb..51419b57 100644 --- a/Sources/OpenGraphShims/GraphShims.swift +++ b/Sources/OpenGraphShims/GraphShims.swift @@ -19,8 +19,6 @@ public typealias OGGraphContext = AGGraphContext public typealias OGInputOptions = AGInputOptions public typealias OGSearchOptions = AGSearchOptions public typealias OGSubgraph = AGSubgraph -public typealias OGSwiftMetadata = AGSwiftMetadata -public typealias OGTupleType = AGTupleType public typealias OGTypeApplyOptions = AGTypeApplyOptions public typealias OGUniqueID = AGUniqueID public typealias OGValue = AGValue diff --git a/Sources/OpenGraph_SPI/OGBase.h b/Sources/OpenGraph_SPI/OGBase.h index 2d53aaa4..eaacdc5d 100644 --- a/Sources/OpenGraph_SPI/OGBase.h +++ b/Sources/OpenGraph_SPI/OGBase.h @@ -50,6 +50,7 @@ #include #define OG_ENUM CF_ENUM +#define OG_CLOSED_ENUM CF_CLOSED_ENUM #define OG_OPTIONS CF_OPTIONS #define OG_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN #define OG_EXTERN_C_END CF_EXTERN_C_END diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index e09d13d3..fcda8011 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -1,29 +1,231 @@ // // OGTupleType.cpp -// -// -// Created by Kyle on 2024/1/25. +// OpenGraph_SPI // +// Audited for iOS 18.0 +// Status: Complete #include "OGTupleType.h" +#include "metadata.hpp" +#include "../Util/assert.hpp" + +#ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED +#include +#endif -long OGTupleCount(OGTupleType tupleType) { - // If tupleType is not tupleType/#0x301, return 1 - // TODO - return 1; +OGTupleType OGNewTupleType(size_t count, const OGTypeID *elements) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + if (count == 1) { + return elements[0]; + } + auto metadata_elements = reinterpret_cast(elements); + const auto response = swift_getTupleTypeMetadata(MetadataState::Complete, count, metadata_elements, nullptr, nullptr); + if (response.State != MetadataState::Complete) { + OG::precondition_failure("invalid tuple type."); + } + return reinterpret_cast(response.Value); + #else + return nullptr; + #endif } -long OGTupleSize(OGTupleType tupleType) { - // TODO +size_t OGTupleCount(OGTupleType tuple_type) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + return 1; + } + auto tuple_metadata = reinterpret_cast(metadata); + return tuple_metadata->NumElements; + #else return 0; + #endif } -OGTypeID OGTupleElementType(OGTupleType tupleType, long index) { - // TODO +size_t OGTupleSize(OGTupleType tuple_type) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + return metadata->vw_size(); + #else + return 0; + #endif +} + +OGTypeID OGTupleElementType(OGTupleType tuple_type, size_t index) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + return reinterpret_cast(metadata); + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + return reinterpret_cast(element.Type); + #else return nullptr; + #endif } -long OGTupleElementOffset(OGTupleType tupleType, long index) { - // TODO - return 0; +size_t OGTupleElementSize(OGTupleType tuple_type, size_t index) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + return metadata->vw_size(); + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + return element.Type->vw_size(); + #else + return nullptr; + #endif +} + +size_t OGTupleElementOffset(OGTupleType tuple_type, size_t index) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + return 0; + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + return element.Offset; + #else + return nullptr; + #endif +} + +size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeID check_type) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + if (reinterpret_cast(metadata) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return 0; + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + if (reinterpret_cast(element.Type) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return element.Offset; + #else + return nullptr; + #endif +} + +void *update(void* dst, const void *src, const OG::swift::metadata * metadata, OGTupleTypeCopyMode mode) { + switch (mode) { + case OGTupleTypeCopyModeAssignCopy: + return metadata->vw_assignWithCopy(dst, src, metadata); + case OGTupleTypeCopyModeInitCopy: + return metadata->vw_initializeWithCopy(dst, src, metadata); + case OGTupleTypeCopyModeAssignTake: + return metadata->vw_assignWithTake(dst, src, metadata); + case OGTupleTypeCopyModeInitTake: + return metadata->vw_initializeWithTake(dst, src, metadata); + default: + OG::precondition_failure("unknown copy options: %d", mode); + } +} + +void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + if (reinterpret_cast(metadata) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return update(tuple_value, element_value, metadata, mode); + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + if (reinterpret_cast(element.Type) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return update((void *)((intptr_t)tuple_value + index), element_value, metadata, mode); + #else + return nullptr; + #endif +} + +void *OGTupleGetElement(OGTupleType tuple_type, const void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + if (reinterpret_cast(metadata) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return update(element_value, tuple_value, metadata, mode); + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + if (reinterpret_cast(element.Type) != check_type) { + OG::precondition_failure("element type mismatch"); + } + return update(element_value, (const void *)((intptr_t)tuple_value + index), metadata, mode); + #else + return nullptr; + #endif +} + +void OGTupleDestory(OGTupleType tuple_type, void *value) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + metadata->vw_destroy(value, metadata); + #endif +} + +void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + if (metadata->getKind() != swift::MetadataKind::Tuple) { + if (index != 0) { + OG::precondition_failure("index out of range: %d", index); + } + metadata->vw_destroy(value, metadata); + } + auto tuple_metadata = reinterpret_cast(metadata); + if (tuple_metadata->NumElements <= index) { + OG::precondition_failure("index out of range: %d", index); + } + auto element = tuple_metadata->getElement(unsigned(index)); + auto element_type = element.Type; + element_type->vw_destroy((intptr_t)value + index, element_type); + #endif } diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 3be7f040..9385ba77 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -1,9 +1,9 @@ // // OGTupleType.h -// -// -// Created by Kyle on 2024/1/25. +// OpenGraph_SPI // +// Audited for iOS 18.0 +// Status: Complete #ifndef OGTupleType_h #define OGTupleType_h @@ -11,25 +11,75 @@ #include "OGBase.h" #include "OGTypeID.h" -typedef const OGSwiftMetadata *OGTupleType OG_SWIFT_STRUCT; +OG_ASSUME_NONNULL_BEGIN + +typedef const OGSwiftMetadata *OGTupleType OG_SWIFT_STRUCT OG_SWIFT_NAME(TupleType); + +typedef OG_CLOSED_ENUM(uint32_t, OGTupleTypeCopyMode) { + OGTupleTypeCopyModeAssignCopy = 0, + OGTupleTypeCopyModeInitCopy = 1, + OGTupleTypeCopyModeAssignTake = 2, + OGTupleTypeCopyModeInitTake = 3 +} OG_SWIFT_NAME(TupleType.CopyMode); + +typedef struct OGUnsafeTuple { + OGTupleType type; + const void *value; +} OGUnsafeTuple OG_SWIFT_NAME(UnsafeTuple); + +typedef struct OGUnsafeMutableTuple { + OGTupleType type; + void *value; +} OGUnsafeMutableTuple OG_SWIFT_NAME(UnsafeMutableTuple); OG_EXTERN_C_BEGIN OG_EXPORT OG_REFINED_FOR_SWIFT -long OGTupleCount(OGTupleType tupleType) OG_SWIFT_NAME(getter:OGTupleType.count(self:)); +OGTupleType OGNewTupleType(size_t count, const OGTypeID _Nonnull * _Nonnull elements) OG_SWIFT_NAME(TupleType.init(count:elements:)); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +size_t OGTupleCount(OGTupleType tuple_type) OG_SWIFT_NAME(getter:TupleType.count(self:)); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +size_t OGTupleSize(OGTupleType tuple_type) OG_SWIFT_NAME(getter:TupleType.size(self:)); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +OGTypeID OGTupleElementType(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(TupleType.elementType(self:at:)); OG_EXPORT OG_REFINED_FOR_SWIFT -long OGTupleSize(OGTupleType tupleType) OG_SWIFT_NAME(getter:OGTupleType.size(self:)); +size_t OGTupleElementSize(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(TupleType.elementSize(self:at:)); OG_EXPORT OG_REFINED_FOR_SWIFT -OGTypeID OGTupleElementType(OGTupleType tupleType, long index); +size_t OGTupleElementOffset(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(TupleType.offset(self:at:)); OG_EXPORT OG_REFINED_FOR_SWIFT -long OGTupleElementOffset(OGTupleType tupleType, long index) OG_SWIFT_NAME(OGTupleType.offset(self:at:)); +size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeID check_type) OG_SWIFT_NAME(TupleType.offset(self:at:type:)); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +void *OGTupleGetElement(OGTupleType tuple_type, const void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +void OGTupleDestory(OGTupleType tuple_type, void *buffer) OG_SWIFT_NAME(TupleType.destory(self:_:)); + +OG_EXPORT +OG_REFINED_FOR_SWIFT +void OGTupleDestoryElement(OGTupleType tuple_type, void *buffer, size_t index) OG_SWIFT_NAME(TupleType.destory(self:_:at:)); OG_EXTERN_C_END + +OG_ASSUME_NONNULL_END + #endif /* OGTupleType_h */ diff --git a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h index 908812b2..87ae1129 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h @@ -3,7 +3,7 @@ // OpenGraph_SPI // // Audited for iOS 18.0 -// Status: WIP +// Status: Complete #ifndef OGTypeID_h #define OGTypeID_h @@ -14,11 +14,11 @@ OG_ASSUME_NONNULL_BEGIN typedef struct OGSwiftMetadata { -} OGSwiftMetadata; +} OGSwiftMetadata OG_SWIFT_NAME(_Metadata); typedef const OGSwiftMetadata *OGTypeID OG_SWIFT_STRUCT OG_SWIFT_NAME(Metadata); -typedef OG_ENUM(uint32_t, OGTypeKind) { +typedef OG_CLOSED_ENUM(uint32_t, OGTypeKind) { OGTypeKindNone, OGTypeKindClass, OGTypeKindStruct, diff --git a/Sources/OpenGraph_SPI/Util/assert.hpp b/Sources/OpenGraph_SPI/Util/assert.hpp index 37b28038..525187b8 100644 --- a/Sources/OpenGraph_SPI/Util/assert.hpp +++ b/Sources/OpenGraph_SPI/Util/assert.hpp @@ -1,9 +1,6 @@ // // assert.hpp -// -// -// Created by Kyle on 2024/1/21. -// +// OpenGraph_SPI #ifndef assert_hpp #define assert_hpp diff --git a/Tests/OpenGraphCompatibilityTests/GraphShims.swift b/Tests/OpenGraphCompatibilityTests/GraphShims.swift index fe6d87ec..c7f37fc0 100644 --- a/Tests/OpenGraphCompatibilityTests/GraphShims.swift +++ b/Tests/OpenGraphCompatibilityTests/GraphShims.swift @@ -19,8 +19,6 @@ public typealias OGGraphContext = AGGraphContext public typealias OGInputOptions = AGInputOptions public typealias OGSearchOptions = AGSearchOptions public typealias OGSubgraph = AGSubgraph -public typealias OGSwiftMetadata = AGSwiftMetadata -public typealias OGTupleType = AGTupleType public typealias OGTypeApplyOptions = AGTypeApplyOptions public typealias OGUniqueID = AGUniqueID public typealias OGValue = AGValue diff --git a/Tests/OpenGraphCompatibilityTests/README.md b/Tests/OpenGraphCompatibilityTests/README.md index ba8b5473..c9f43c50 100644 --- a/Tests/OpenGraphCompatibilityTests/README.md +++ b/Tests/OpenGraphCompatibilityTests/README.md @@ -3,6 +3,5 @@ Test public API of OpenGraph and run it against with AttributeGraph on Apple Platform. The current supported OS -- macOS 13 (CI Supported) - macOS 14 (CI Supported) - iOS 15 ~ 17 on Simulator (CI is not supported) diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/MetadataTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/MetadataTests.swift index 59eec2a7..4e1aef5b 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/MetadataTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/MetadataTests.swift @@ -24,50 +24,6 @@ struct MetadataTests { var b: Double { get } } - @Test(.enabled(if: swiftToolchainSupported)) - func kind() throws { - #expect(Metadata(T1.self).kind == .class) - #expect(Metadata(T2.self).kind == .struct) - #expect(Metadata(T3.self).kind == .enum) - - #expect(Metadata(Void?.self).kind == .optional) - #expect(Metadata(Int?.self).kind == .optional) - #expect(Metadata(T1?.self).kind == .optional) - #expect(Metadata((T1, T2)?.self).kind == .optional) - - #expect(Metadata(Void.self).kind == .tuple) - #expect(Metadata((Int, Double?).self).kind == .tuple) - #expect(Metadata((T1, T2, T3).self).kind == .tuple) - - #expect(Metadata((() -> Void).self).kind == .function) - - #expect(Metadata(P.self).kind == .existential) - #expect(Metadata((any P).self).kind == .existential) - - #expect(Metadata(P.Protocol.self).kind == .metatype) - #expect(Metadata(type(of: Int.self)).kind == .metatype) - } - - #if OPENGRAPH_SUPPORT_2024_API - @Test(.enabled(if: swiftToolchainSupported)) - func descriptor() { - let t1 = Metadata(T1.self).descriptor - let t2 = Metadata(T2.self).descriptor - let t3 = Metadata(T3.self).descriptor - let p = Metadata(P.self).descriptor - let optionalP = Metadata(P?.self).descriptor - - #expect(t1 != nil) - #expect(t2 != nil) - #expect(t3 != nil) - - #expect(p == nil) - #expect(optionalP != nil) - - #expect(t1 == Metadata(T1.self).descriptor) - } - #endif - @Test(.disabled(if: !compatibilityTestEnabled, "Metadata is not implemented")) func description() { #expect(Metadata(T1.self).description == "MetadataTests.T1") @@ -75,36 +31,6 @@ struct MetadataTests { #expect(Metadata(T3.self).description == "MetadataTests.T3") } - @Test(.enabled(if: swiftToolchainSupported)) - func nominalDescriptor() { - let t1 = Metadata(T1.self).nominalDescriptor - let t2 = Metadata(T2.self).nominalDescriptor - let t3 = Metadata(T3.self).nominalDescriptor - let p = Metadata(P.self).nominalDescriptor - let optionalP = Metadata(P?.self).nominalDescriptor - - #expect(t1 == nil) - #expect(t2 != nil) - #expect(t3 != nil) - #expect(p == nil) - #expect(optionalP != nil) - } - - @Test(.enabled(if: swiftToolchainSupported)) - func nominalDescriptorName() throws { - let t1 = Metadata(T1.self).nominalDescriptorName - let t2 = Metadata(T2.self).nominalDescriptorName - let t3 = Metadata(T3.self).nominalDescriptorName - let p = Metadata(P.self).nominalDescriptorName - let optionalP = Metadata(P?.self).nominalDescriptorName - - #expect(t1 == nil) - try #expect(String(cString: #require(t2)) == "T2") - try #expect(String(cString: #require(t3)) == "T3") - #expect(p == nil) - try #expect(String(cString: #require(optionalP)) == "Optional") - } - @Test(.disabled(if: !compatibilityTestEnabled, "Metadata is not implemented")) func forEachField() throws { for options in [OGTypeApplyOptions._1] { diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift index 3781d3cf..e7780c2a 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift @@ -6,16 +6,4 @@ import Testing @Suite(.disabled(if: !compatibilityTestEnabled, "OGTupleType is not implemented")) struct TupleTypeTests { - @Test - func example() { - let value = (3, 5.0) - let tupleType = OGTupleType(type(of: value)) - #expect(tupleType.count == 2) - #expect(tupleType.size == 16) - #expect(tupleType.type(at: 0) == Int.self) - #expect(tupleType.offset(at: 0) == 0) - - #expect(tupleType.type(at: 1) == Double.self) - #expect(tupleType.offset(at: 1) == 8) - } } diff --git a/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift b/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift new file mode 100644 index 00000000..c7f37fc0 --- /dev/null +++ b/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift @@ -0,0 +1,37 @@ +// +// GraphShims.swift +// OpenGraphCompatibilityTests + +#if OPENGRAPH_COMPATIBILITY_TEST +@_exported public import AttributeGraph +public typealias OGAttributeFlags = AGAttributeFlags +public typealias OGAttributeInfo = AGAttributeInfo +public typealias OGAttributeType = AGAttributeType +public typealias OGAttributeTypeFlags = AGAttributeTypeFlags +public typealias OGCachedValueOptions = AGCachedValueOptions +public typealias OGChangedValueFlags = AGChangedValueFlags +public typealias OGComparisonMode = AGComparisonMode +public typealias OGComparisonOptions = AGComparisonOptions +public typealias OGCounterQueryType = AGCounterQueryType +public typealias OGDebugServer = AGDebugServer +public typealias OGGraph = AGGraph +public typealias OGGraphContext = AGGraphContext +public typealias OGInputOptions = AGInputOptions +public typealias OGSearchOptions = AGSearchOptions +public typealias OGSubgraph = AGSubgraph +public typealias OGTypeApplyOptions = AGTypeApplyOptions +public typealias OGUniqueID = AGUniqueID +public typealias OGValue = AGValue +public typealias OGValueOptions = AGValueOptions +public typealias OGValueState = AGValueState +public let compatibilityTestEnabled = true +public let swiftToolchainSupported = true +#else +@_exported import OpenGraph +let compatibilityTestEnabled = false +#if OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED +public let swiftToolchainSupported = true +#else +public let swiftToolchainSupported = false +#endif +#endif diff --git a/Tests/OpenGraph_SPICompatibilityTests/README.md b/Tests/OpenGraph_SPICompatibilityTests/README.md new file mode 100644 index 00000000..39e18c3a --- /dev/null +++ b/Tests/OpenGraph_SPICompatibilityTests/README.md @@ -0,0 +1,7 @@ +## OpenGraphCompatibilityTests + +Test public API of OpenGraph_SPI and run it against with AttributeGraph on Apple Platform. + +The current supported OS +- macOS 14 (CI Supported) +- iOS 15 ~ 17 on Simulator (CI is not supported) diff --git a/Tests/OpenGraph_SPICompatibilityTests/Runtime/MetadataTests.swift b/Tests/OpenGraph_SPICompatibilityTests/Runtime/MetadataTests.swift new file mode 100644 index 00000000..86d2408d --- /dev/null +++ b/Tests/OpenGraph_SPICompatibilityTests/Runtime/MetadataTests.swift @@ -0,0 +1,100 @@ +// +// MetadataTests.swift +// OpenGraph_SPICompatibilityTests + +import Testing + +struct MetadataTests { + class T1 { + var a = 0 + var b: Double = 0 + } + + struct T2 { + var a: Int + var b: Double + } + + enum T3 { + case a, b + } + + protocol P { + var a: Int { get } + var b: Double { get } + } + + @Test(.enabled(if: swiftToolchainSupported)) + func kind() throws { + #expect(Metadata(T1.self).kind == .class) + #expect(Metadata(T2.self).kind == .struct) + #expect(Metadata(T3.self).kind == .enum) + + #expect(Metadata(Void?.self).kind == .optional) + #expect(Metadata(Int?.self).kind == .optional) + #expect(Metadata(T1?.self).kind == .optional) + #expect(Metadata((T1, T2)?.self).kind == .optional) + + #expect(Metadata(Void.self).kind == .tuple) + #expect(Metadata((Int, Double?).self).kind == .tuple) + #expect(Metadata((T1, T2, T3).self).kind == .tuple) + + #expect(Metadata((() -> Void).self).kind == .function) + + #expect(Metadata(P.self).kind == .existential) + #expect(Metadata((any P).self).kind == .existential) + + #expect(Metadata(P.Protocol.self).kind == .metatype) + #expect(Metadata(type(of: Int.self)).kind == .metatype) + } + + #if OPENGRAPH_SUPPORT_2024_API + @Test(.enabled(if: swiftToolchainSupported)) + func descriptor() { + let t1 = Metadata(T1.self).descriptor + let t2 = Metadata(T2.self).descriptor + let t3 = Metadata(T3.self).descriptor + let p = Metadata(P.self).descriptor + let optionalP = Metadata(P?.self).descriptor + + #expect(t1 != nil) + #expect(t2 != nil) + #expect(t3 != nil) + + #expect(p == nil) + #expect(optionalP != nil) + + #expect(t1 == Metadata(T1.self).descriptor) + } + #endif + + @Test(.enabled(if: swiftToolchainSupported)) + func nominalDescriptor() { + let t1 = Metadata(T1.self).nominalDescriptor + let t2 = Metadata(T2.self).nominalDescriptor + let t3 = Metadata(T3.self).nominalDescriptor + let p = Metadata(P.self).nominalDescriptor + let optionalP = Metadata(P?.self).nominalDescriptor + + #expect(t1 == nil) + #expect(t2 != nil) + #expect(t3 != nil) + #expect(p == nil) + #expect(optionalP != nil) + } + + @Test(.enabled(if: swiftToolchainSupported)) + func nominalDescriptorName() throws { + let t1 = Metadata(T1.self).nominalDescriptorName + let t2 = Metadata(T2.self).nominalDescriptorName + let t3 = Metadata(T3.self).nominalDescriptorName + let p = Metadata(P.self).nominalDescriptorName + let optionalP = Metadata(P?.self).nominalDescriptorName + + #expect(t1 == nil) + try #expect(String(cString: #require(t2)) == "T2") + try #expect(String(cString: #require(t3)) == "T3") + #expect(p == nil) + try #expect(String(cString: #require(optionalP)) == "Optional") + } +} diff --git a/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift new file mode 100644 index 00000000..249ccae3 --- /dev/null +++ b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift @@ -0,0 +1,21 @@ +// +// TupleTypeTests.swift +// OpenGraph_SPICompatibilityTests + +import Testing + +@Suite(.disabled(if: !compatibilityTestEnabled, "OGTupleType is not implemented")) +struct TupleTypeTests { + @Test + func example() { + let value = (3, 5.0) + let tupleType = TupleType(type(of: value)) + #expect(tupleType.count == 2) + #expect(tupleType.size == 16) + #expect(tupleType.type(at: 0) == Int.self) + #expect(tupleType.offset(at: 0) == 0) + + #expect(tupleType.type(at: 1) == Double.self) + #expect(tupleType.offset(at: 1) == 8) + } +} From b52e15996e4c88cccec88fee82dff735c8ac87bb Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 2 Jan 2025 00:11:04 +0800 Subject: [PATCH 2/8] Fix compile issue --- Package.swift | 2 +- Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 18 +++++---- .../{Runtime => }/CompareValuesTests.swift | 0 .../GraphShims.swift | 37 ------------------- .../Runtime/TupleTypeTests.swift | 16 +++----- 5 files changed, 16 insertions(+), 57 deletions(-) rename Tests/OpenGraphCompatibilityTests/{Runtime => }/CompareValuesTests.swift (100%) delete mode 100644 Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift diff --git a/Package.swift b/Package.swift index 290d8d4b..d25a0873 100644 --- a/Package.swift +++ b/Package.swift @@ -248,7 +248,7 @@ if compatibilityTestCondition && attributeGraphCondition { openGraphSPICompatibilityTestTarget.addCompatibilitySettings() } else { openGraphCompatibilityTestTarget.dependencies.append("OpenGraph") - openGraphSPICompatibilityTestTarget.dependencies.append("OpenGraph_SPI") + openGraphSPICompatibilityTestTarget.dependencies.append("OpenGraph") } extension [Platform] { diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index fcda8011..e8e2f628 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -137,16 +137,18 @@ size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeI #endif } -void *update(void* dst, const void *src, const OG::swift::metadata * metadata, OGTupleTypeCopyMode mode) { +void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleTypeCopyMode mode) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(const_cast(src_ptr)); switch (mode) { case OGTupleTypeCopyModeAssignCopy: - return metadata->vw_assignWithCopy(dst, src, metadata); + return metadata->vw_assignWithCopy(dst, src); case OGTupleTypeCopyModeInitCopy: - return metadata->vw_initializeWithCopy(dst, src, metadata); + return metadata->vw_initializeWithCopy(dst, src); case OGTupleTypeCopyModeAssignTake: - return metadata->vw_assignWithTake(dst, src, metadata); + return metadata->vw_assignWithTake(dst, src); case OGTupleTypeCopyModeInitTake: - return metadata->vw_initializeWithTake(dst, src, metadata); + return metadata->vw_initializeWithTake(dst, src); default: OG::precondition_failure("unknown copy options: %d", mode); } @@ -207,7 +209,7 @@ void *OGTupleGetElement(OGTupleType tuple_type, const void* tuple_value, size_t void OGTupleDestory(OGTupleType tuple_type, void *value) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); - metadata->vw_destroy(value, metadata); + metadata->vw_destroy(reinterpret_cast(value)); #endif } @@ -218,7 +220,7 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) { if (index != 0) { OG::precondition_failure("index out of range: %d", index); } - metadata->vw_destroy(value, metadata); + metadata->vw_destroy(reinterpret_cast(value)); } auto tuple_metadata = reinterpret_cast(metadata); if (tuple_metadata->NumElements <= index) { @@ -226,6 +228,6 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) { } auto element = tuple_metadata->getElement(unsigned(index)); auto element_type = element.Type; - element_type->vw_destroy((intptr_t)value + index, element_type); + element_type->vw_destroy(reinterpret_cast((intptr_t)value + index)); #endif } diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/CompareValuesTests.swift b/Tests/OpenGraphCompatibilityTests/CompareValuesTests.swift similarity index 100% rename from Tests/OpenGraphCompatibilityTests/Runtime/CompareValuesTests.swift rename to Tests/OpenGraphCompatibilityTests/CompareValuesTests.swift diff --git a/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift b/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift deleted file mode 100644 index c7f37fc0..00000000 --- a/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// GraphShims.swift -// OpenGraphCompatibilityTests - -#if OPENGRAPH_COMPATIBILITY_TEST -@_exported public import AttributeGraph -public typealias OGAttributeFlags = AGAttributeFlags -public typealias OGAttributeInfo = AGAttributeInfo -public typealias OGAttributeType = AGAttributeType -public typealias OGAttributeTypeFlags = AGAttributeTypeFlags -public typealias OGCachedValueOptions = AGCachedValueOptions -public typealias OGChangedValueFlags = AGChangedValueFlags -public typealias OGComparisonMode = AGComparisonMode -public typealias OGComparisonOptions = AGComparisonOptions -public typealias OGCounterQueryType = AGCounterQueryType -public typealias OGDebugServer = AGDebugServer -public typealias OGGraph = AGGraph -public typealias OGGraphContext = AGGraphContext -public typealias OGInputOptions = AGInputOptions -public typealias OGSearchOptions = AGSearchOptions -public typealias OGSubgraph = AGSubgraph -public typealias OGTypeApplyOptions = AGTypeApplyOptions -public typealias OGUniqueID = AGUniqueID -public typealias OGValue = AGValue -public typealias OGValueOptions = AGValueOptions -public typealias OGValueState = AGValueState -public let compatibilityTestEnabled = true -public let swiftToolchainSupported = true -#else -@_exported import OpenGraph -let compatibilityTestEnabled = false -#if OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED -public let swiftToolchainSupported = true -#else -public let swiftToolchainSupported = false -#endif -#endif diff --git a/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift index 249ccae3..85a767ce 100644 --- a/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift @@ -4,18 +4,12 @@ import Testing -@Suite(.disabled(if: !compatibilityTestEnabled, "OGTupleType is not implemented")) +@Suite(.enabled(if: swiftToolchainSupported)) struct TupleTypeTests { @Test - func example() { - let value = (3, 5.0) - let tupleType = TupleType(type(of: value)) - #expect(tupleType.count == 2) - #expect(tupleType.size == 16) - #expect(tupleType.type(at: 0) == Int.self) - #expect(tupleType.offset(at: 0) == 0) - - #expect(tupleType.type(at: 1) == Double.self) - #expect(tupleType.offset(at: 1) == 8) + func newTupleType() { + let elements: [Metadata] = [Metadata(Int.self), Metadata(Double.self), Metadata(String.self)] + let tupleType = TupleType(count: 3, elements: elements) + #expect(tupleType.rawValue == Metadata((Int, Double, String).self).rawValue) } } From 22658e7579a8dd80815a58212f99bc5666d18e81 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 2 Jan 2025 00:48:46 +0800 Subject: [PATCH 3/8] Update TupleTypeTests --- Sources/OpenGraph/Runtime/Tuple.swift | 39 -------------- Sources/OpenGraph/Runtime/TupleType.swift | 46 ++++++++++++++++ Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 14 ++--- Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 20 +++---- .../GraphShims.swift | 37 +++++++++++++ .../Runtime/TupleTypeTests.swift | 52 ++++++++++++++++++- 6 files changed, 150 insertions(+), 58 deletions(-) delete mode 100644 Sources/OpenGraph/Runtime/Tuple.swift create mode 100644 Sources/OpenGraph/Runtime/TupleType.swift create mode 100644 Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift diff --git a/Sources/OpenGraph/Runtime/Tuple.swift b/Sources/OpenGraph/Runtime/Tuple.swift deleted file mode 100644 index 590d6fe2..00000000 --- a/Sources/OpenGraph/Runtime/Tuple.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// OGTupleType.swift -// OpenGraph -// -// Audited for iOS 18.0 -// Status: WIP - -public import OpenGraph_SPI - -@_silgen_name("OGTupleElementType") -@inline(__always) -private func OGTupleElementType(_ tupleType: TupleType, index: Int) -> Metadata - -// TODO -extension TupleType { - public init(_ type: [Any.Type]) { - fatalError("TODO") - } - - public init(_ type: Any.Type) { - self.init(rawValue: unsafeBitCast(type, to: UnsafePointer.self)) - } - - public var type: Any.Type { - unsafeBitCast(rawValue, to: Any.Type.self) - } - - public var isEmpty: Bool { - count == 0 - } - - public var indices: Range { - 0 ..< count - } - - public func type(at index: Int) -> Any.Type { - OGTupleElementType(self, index: index).type - } -} diff --git a/Sources/OpenGraph/Runtime/TupleType.swift b/Sources/OpenGraph/Runtime/TupleType.swift new file mode 100644 index 00000000..568aeab7 --- /dev/null +++ b/Sources/OpenGraph/Runtime/TupleType.swift @@ -0,0 +1,46 @@ +// +// TupleType.swift +// OpenGraph +// +// Audited for iOS 18.0 +// Status: WIP + +public import OpenGraph_SPI + +extension TupleType { + public init(_ types: [Any.Type]) { + self.init(count: types.count, elements: types.map(Metadata.init)) + } + + public init(_ type: Any.Type) { + self.init(rawValue: unsafeBitCast(type, to: UnsafePointer.self)) + } + + public var type: Any.Type { + unsafeBitCast(rawValue, to: Any.Type.self) + } + + public var isEmpty: Bool { + count == 0 + } + + public var indices: Range { + 0 ..< count + } + + public func type(at index: Int) -> Any.Type { + elementType(at: index).type + } + + public func offset(at index: Int, as type: T.Type) -> Int { + elementOffset(at: index, type: Metadata(type)) + } + + public func setElement(in tupleValue: UnsafeMutableRawPointer, at index: Int, from srcValue: UnsafePointer, options: CopyOptions) { + __OGTupleSetElement(self, tupleValue, index, srcValue, Metadata(T.self), options) + } + + public func getElement(in tupleValue: UnsafeMutableRawPointer, at index: Int, to dstValue: UnsafeMutablePointer, options: CopyOptions) { + __OGTupleGetElement(self, tupleValue, index, dstValue, Metadata(T.self), options) + } +} diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index e8e2f628..b444d8df 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -137,24 +137,24 @@ size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeI #endif } -void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleTypeCopyMode mode) { +void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleCopyOptions mode) { auto dst = reinterpret_cast(dst_ptr); auto src = reinterpret_cast(const_cast(src_ptr)); switch (mode) { - case OGTupleTypeCopyModeAssignCopy: + case OGTupleCopyOptionsAssignCopy: return metadata->vw_assignWithCopy(dst, src); - case OGTupleTypeCopyModeInitCopy: + case OGTupleCopyOptionsInitCopy: return metadata->vw_initializeWithCopy(dst, src); - case OGTupleTypeCopyModeAssignTake: + case OGTupleCopyOptionsAssignTake: return metadata->vw_assignWithTake(dst, src); - case OGTupleTypeCopyModeInitTake: + case OGTupleCopyOptionsInitTake: return metadata->vw_initializeWithTake(dst, src); default: OG::precondition_failure("unknown copy options: %d", mode); } } -void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode) { +void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleCopyOptions mode) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); if (metadata->getKind() != swift::MetadataKind::Tuple) { @@ -180,7 +180,7 @@ void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, #endif } -void *OGTupleGetElement(OGTupleType tuple_type, const void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode) { +void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleCopyOptions mode) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); if (metadata->getKind() != swift::MetadataKind::Tuple) { diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 9385ba77..1ae409cd 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -15,12 +15,12 @@ OG_ASSUME_NONNULL_BEGIN typedef const OGSwiftMetadata *OGTupleType OG_SWIFT_STRUCT OG_SWIFT_NAME(TupleType); -typedef OG_CLOSED_ENUM(uint32_t, OGTupleTypeCopyMode) { - OGTupleTypeCopyModeAssignCopy = 0, - OGTupleTypeCopyModeInitCopy = 1, - OGTupleTypeCopyModeAssignTake = 2, - OGTupleTypeCopyModeInitTake = 3 -} OG_SWIFT_NAME(TupleType.CopyMode); +typedef OG_CLOSED_ENUM(uint32_t, OGTupleCopyOptions) { + OGTupleCopyOptionsAssignCopy = 0, + OGTupleCopyOptionsInitCopy = 1, + OGTupleCopyOptionsAssignTake = 2, + OGTupleCopyOptionsInitTake = 3 +} OG_SWIFT_NAME(TupleType.CopyOptions); typedef struct OGUnsafeTuple { OGTupleType type; @@ -56,19 +56,19 @@ size_t OGTupleElementSize(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(Tu OG_EXPORT OG_REFINED_FOR_SWIFT -size_t OGTupleElementOffset(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(TupleType.offset(self:at:)); +size_t OGTupleElementOffset(OGTupleType tuple_type, size_t index) OG_SWIFT_NAME(TupleType.elementOffset(self:at:)); OG_EXPORT OG_REFINED_FOR_SWIFT -size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeID check_type) OG_SWIFT_NAME(TupleType.offset(self:at:type:)); +size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeID check_type) OG_SWIFT_NAME(TupleType.elementOffset(self:at:type:)); OG_EXPORT OG_REFINED_FOR_SWIFT -void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode); +void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleCopyOptions mode); OG_EXPORT OG_REFINED_FOR_SWIFT -void *OGTupleGetElement(OGTupleType tuple_type, const void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleTypeCopyMode mode); +void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleCopyOptions mode); OG_EXPORT OG_REFINED_FOR_SWIFT diff --git a/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift b/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift new file mode 100644 index 00000000..c7f37fc0 --- /dev/null +++ b/Tests/OpenGraph_SPICompatibilityTests/GraphShims.swift @@ -0,0 +1,37 @@ +// +// GraphShims.swift +// OpenGraphCompatibilityTests + +#if OPENGRAPH_COMPATIBILITY_TEST +@_exported public import AttributeGraph +public typealias OGAttributeFlags = AGAttributeFlags +public typealias OGAttributeInfo = AGAttributeInfo +public typealias OGAttributeType = AGAttributeType +public typealias OGAttributeTypeFlags = AGAttributeTypeFlags +public typealias OGCachedValueOptions = AGCachedValueOptions +public typealias OGChangedValueFlags = AGChangedValueFlags +public typealias OGComparisonMode = AGComparisonMode +public typealias OGComparisonOptions = AGComparisonOptions +public typealias OGCounterQueryType = AGCounterQueryType +public typealias OGDebugServer = AGDebugServer +public typealias OGGraph = AGGraph +public typealias OGGraphContext = AGGraphContext +public typealias OGInputOptions = AGInputOptions +public typealias OGSearchOptions = AGSearchOptions +public typealias OGSubgraph = AGSubgraph +public typealias OGTypeApplyOptions = AGTypeApplyOptions +public typealias OGUniqueID = AGUniqueID +public typealias OGValue = AGValue +public typealias OGValueOptions = AGValueOptions +public typealias OGValueState = AGValueState +public let compatibilityTestEnabled = true +public let swiftToolchainSupported = true +#else +@_exported import OpenGraph +let compatibilityTestEnabled = false +#if OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED +public let swiftToolchainSupported = true +#else +public let swiftToolchainSupported = false +#endif +#endif diff --git a/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift index 85a767ce..2f6d1078 100644 --- a/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraph_SPICompatibilityTests/Runtime/TupleTypeTests.swift @@ -6,10 +6,58 @@ import Testing @Suite(.enabled(if: swiftToolchainSupported)) struct TupleTypeTests { + class T1 { + var a = 0 + var b: Double = 0 + } + + struct T2 { + var a: Int + var b: Double + } + + enum T3 { + case a, b + } + @Test func newTupleType() { - let elements: [Metadata] = [Metadata(Int.self), Metadata(Double.self), Metadata(String.self)] + let elements: [Metadata] = [Metadata(T1.self), Metadata(T2.self), Metadata(T3.self)] let tupleType = TupleType(count: 3, elements: elements) - #expect(tupleType.rawValue == Metadata((Int, Double, String).self).rawValue) + #expect(tupleType.rawValue == Metadata((T1, T2, T3).self).rawValue) + } + + @Test + func tupleCount() { + #expect(TupleType(T1.self).count == 1) + #expect(TupleType([T1.self, T2.self]).count == 2) + #expect(TupleType([T1.self, T2.self, T3.self]).count == 3) + } + + @Test + func tupleSize() { + #expect(TupleType(T1.self).size == 8) + #expect(TupleType([T1.self, T2.self]).size == 24) + #expect(TupleType([T1.self, T2.self, T3.self]).size == 25) + } + + @Test + func tupleElement() { + let tupleType = TupleType([T1.self, T2.self, T3.self]) + #expect(tupleType.elementType(at: 0) == Metadata(T1.self)) + #expect(tupleType.elementType(at: 1) == Metadata(T2.self)) + #expect(tupleType.elementType(at: 2) == Metadata(T3.self)) + + #expect(tupleType.elementSize(at: 0) == 8) + #expect(tupleType.elementSize(at: 1) == 16) + #expect(tupleType.elementSize(at: 2) == 1) + + #expect(tupleType.elementOffset(at: 0) == 0) + #expect(tupleType.elementOffset(at: 1) == 8) + #expect(tupleType.elementOffset(at: 2) == 24) + + #expect(tupleType.elementOffset(at: 0, type: Metadata(T1.self)) == 0) + #expect(tupleType.elementOffset(at: 1, type: Metadata(T2.self)) == 8) + #expect(tupleType.elementOffset(at: 2, type: Metadata(T3.self)) == 24) } } From af59f18b3c68f79422549fb68eab92801a1b62bd Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 2 Jan 2025 01:44:29 +0800 Subject: [PATCH 4/8] Update TupleTypeTests --- Sources/OpenGraph/Runtime/TupleType.swift | 3 + Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 18 ++-- Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 16 +++- .../Runtime/TupleTypeTests.swift | 93 ++++++++++++++++++- 4 files changed, 116 insertions(+), 14 deletions(-) diff --git a/Sources/OpenGraph/Runtime/TupleType.swift b/Sources/OpenGraph/Runtime/TupleType.swift index 568aeab7..7f0fb59c 100644 --- a/Sources/OpenGraph/Runtime/TupleType.swift +++ b/Sources/OpenGraph/Runtime/TupleType.swift @@ -44,3 +44,6 @@ extension TupleType { __OGTupleGetElement(self, tupleValue, index, dstValue, Metadata(T.self), options) } } + +@_silgen_name("OGTupleWithBuffer") +public func withUnsafeTuple(of type: TupleType, count: Int, _ body: (UnsafeMutableTuple) -> ()) diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index b444d8df..d87aa437 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -137,10 +137,10 @@ size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeI #endif } -void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleCopyOptions mode) { +void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleCopyOptions options) { auto dst = reinterpret_cast(dst_ptr); auto src = reinterpret_cast(const_cast(src_ptr)); - switch (mode) { + switch (options) { case OGTupleCopyOptionsAssignCopy: return metadata->vw_assignWithCopy(dst, src); case OGTupleCopyOptionsInitCopy: @@ -150,11 +150,11 @@ void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * met case OGTupleCopyOptionsInitTake: return metadata->vw_initializeWithTake(dst, src); default: - OG::precondition_failure("unknown copy options: %d", mode); + OG::precondition_failure("unknown copy options: %d", options); } } -void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleCopyOptions mode) { +void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleCopyOptions options) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); if (metadata->getKind() != swift::MetadataKind::Tuple) { @@ -164,7 +164,7 @@ void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, if (reinterpret_cast(metadata) != check_type) { OG::precondition_failure("element type mismatch"); } - return update(tuple_value, element_value, metadata, mode); + return update(tuple_value, element_value, metadata, options); } auto tuple_metadata = reinterpret_cast(metadata); if (tuple_metadata->NumElements <= index) { @@ -174,13 +174,13 @@ void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, if (reinterpret_cast(element.Type) != check_type) { OG::precondition_failure("element type mismatch"); } - return update((void *)((intptr_t)tuple_value + index), element_value, metadata, mode); + return update((void *)(element.findIn(reinterpret_cast(tuple_value))), element_value, reinterpret_cast(element.Type), options); #else return nullptr; #endif } -void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleCopyOptions mode) { +void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, void *element_value, OGTypeID check_type, OGTupleCopyOptions options) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); if (metadata->getKind() != swift::MetadataKind::Tuple) { @@ -190,7 +190,7 @@ void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, if (reinterpret_cast(metadata) != check_type) { OG::precondition_failure("element type mismatch"); } - return update(element_value, tuple_value, metadata, mode); + return update(element_value, tuple_value, metadata, options); } auto tuple_metadata = reinterpret_cast(metadata); if (tuple_metadata->NumElements <= index) { @@ -200,7 +200,7 @@ void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, if (reinterpret_cast(element.Type) != check_type) { OG::precondition_failure("element type mismatch"); } - return update(element_value, (const void *)((intptr_t)tuple_value + index), metadata, mode); + return update(element_value, (const void *)(element.findIn(reinterpret_cast(tuple_value))), reinterpret_cast(element.Type), options); #else return nullptr; #endif diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 1ae409cd..0d1dc65b 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -22,15 +22,19 @@ typedef OG_CLOSED_ENUM(uint32_t, OGTupleCopyOptions) { OGTupleCopyOptionsInitTake = 3 } OG_SWIFT_NAME(TupleType.CopyOptions); -typedef struct OGUnsafeTuple { +struct OGUnsafeTuple { OGTupleType type; const void *value; -} OGUnsafeTuple OG_SWIFT_NAME(UnsafeTuple); +} OG_SWIFT_NAME(UnsafeTuple); -typedef struct OGUnsafeMutableTuple { +typedef struct OGUnsafeTuple OGUnsafeTuple; + +struct OGUnsafeMutableTuple { OGTupleType type; void *value; -} OGUnsafeMutableTuple OG_SWIFT_NAME(UnsafeMutableTuple); +} OG_SWIFT_NAME(UnsafeMutableTuple); + +typedef struct OGUnsafeMutableTuple OGUnsafeMutableTuple; OG_EXTERN_C_BEGIN @@ -78,6 +82,10 @@ OG_EXPORT OG_REFINED_FOR_SWIFT void OGTupleDestoryElement(OGTupleType tuple_type, void *buffer, size_t index) OG_SWIFT_NAME(TupleType.destory(self:_:at:)); +OG_EXPORT +OG_REFINED_FOR_SWIFT +void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (*_Nullable function)(const void * _Nullable context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void * _Nullable context); + OG_EXTERN_C_END OG_ASSUME_NONNULL_END diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift index e7780c2a..67fb7002 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift @@ -4,6 +4,97 @@ import Testing -@Suite(.disabled(if: !compatibilityTestEnabled, "OGTupleType is not implemented")) +@Suite(.enabled(if: swiftToolchainSupported)) struct TupleTypeTests { + class T1 { + var a = 0 + var b: Double = 0 + } + + struct T2 { + var a: Int = 0 + var b: Double = 0 + } + + enum T3 { + case a, b + } + + @Test + func initType() { + #expect(TupleType(T1.self).rawValue == Metadata(T1.self).rawValue) + #expect(TupleType([T1.self, T2.self]).rawValue == Metadata((T1, T2).self).rawValue) + #expect(TupleType([T1.self, T2.self, T3.self]).rawValue == Metadata((T1, T2, T3).self).rawValue) + } + + + @Test + func type() { + #expect(TupleType([T1.self, T2.self, T3.self]).type == (T1, T2, T3).self) + } + + @Test(arguments:[ + (TupleType(Void.self), true, 0 ..< 0), + (TupleType(T1.self), false, 0 ..< 1), + (TupleType([T1.self, T2.self]), false, 0 ..< 2), + ]) + func collectionAPI(tupleType: TupleType, expectedIsEmpty: Bool, expectedIndices: Range) { + #expect(tupleType.isEmpty == expectedIsEmpty) + #expect(tupleType.indices == expectedIndices) + } + + @Test + func elementTypeAndOffset() { + let tupleType = TupleType([T1.self, T2.self, T3.self]) + #expect(tupleType.type(at: 0) == T1.self) + #expect(tupleType.type(at: 1) == T2.self) + #expect(tupleType.type(at: 2) == T3.self) + + #expect(tupleType.offset(at: 0, as: T1.self) == 0) + #expect(tupleType.offset(at: 1, as: T2.self) == 8) + #expect(tupleType.offset(at: 2, as: T3.self) == 24) + } + + @Test + func getAndSetElement() { + let tupleType = TupleType([T1.self, T2.self]) + var tuple = (T1(), T2()) + #expect(tuple.0.a == 0) + #expect(tuple.0.b == 0) + #expect(tuple.1.a == 0) + #expect(tuple.1.b == 0) + + var newT1 = T1() + newT1.a = 1 + var newT2 = T2(a: 2) + + withUnsafeMutablePointer(to: &tuple) { tuplePointer in + withUnsafePointer(to: newT1) { + tupleType.setElement(in: tuplePointer, at: 0, from: $0, options: .assignCopy) + } + #expect(tuplePointer.pointee.0.a == 1) + #expect(tuplePointer.pointee.1.a == 0) + withUnsafePointer(to: newT2) { + tupleType.setElement(in: tuplePointer, at: 1, from: $0, options: .assignCopy) + } + #expect(tuplePointer.pointee.0.a == 1) + #expect(tuplePointer.pointee.1.a == 2) + } + + tuple.0.a = 3 + tuple.1.a = 4 + + withUnsafeMutablePointer(to: &tuple) { tuplePointer in + withUnsafeMutablePointer(to: &newT1) { + tupleType.getElement(in: tuplePointer, at: 0, to: $0, options: .assignCopy) + } + #expect(newT1.a == 3) + #expect(newT2.a == 2) + + withUnsafeMutablePointer(to: &newT2) { + tupleType.getElement(in: tuplePointer, at: 1, to: $0, options: .assignCopy) + } + #expect(newT2.a == 4) + } + } } From ab513e2978b98b8af1c35e90ed71bfbedc00eff4 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 2 Jan 2025 02:24:40 +0800 Subject: [PATCH 5/8] Add UnsafeMutableTupleTests --- Sources/OpenGraph/Runtime/Metadata.swift | 2 +- Sources/OpenGraph/Runtime/TupleType.swift | 98 +++++++++++++++++-- Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 12 +-- Sources/OpenGraph_SPI/Runtime/OGTypeID.h | 4 +- .../Runtime/TupleTypeTests.swift | 43 ++++++++ 5 files changed, 139 insertions(+), 20 deletions(-) diff --git a/Sources/OpenGraph/Runtime/Metadata.swift b/Sources/OpenGraph/Runtime/Metadata.swift index 7ff22017..422fce89 100644 --- a/Sources/OpenGraph/Runtime/Metadata.swift +++ b/Sources/OpenGraph/Runtime/Metadata.swift @@ -27,7 +27,7 @@ extension Metadata: Swift.Hashable, Swift.CustomStringConvertible { @inlinable @inline(__always) public init(_ type: Any.Type) { - self.init(rawValue: unsafeBitCast(type, to: UnsafePointer.self)) + self.init(rawValue: unsafeBitCast(type, to: UnsafePointer<_Metadata>.self)) } @inlinable diff --git a/Sources/OpenGraph/Runtime/TupleType.swift b/Sources/OpenGraph/Runtime/TupleType.swift index 7f0fb59c..07f90b0d 100644 --- a/Sources/OpenGraph/Runtime/TupleType.swift +++ b/Sources/OpenGraph/Runtime/TupleType.swift @@ -7,27 +7,24 @@ public import OpenGraph_SPI +// MARK: TupleType + extension TupleType { public init(_ types: [Any.Type]) { self.init(count: types.count, elements: types.map(Metadata.init)) } public init(_ type: Any.Type) { - self.init(rawValue: unsafeBitCast(type, to: UnsafePointer.self)) + self.init(rawValue: unsafeBitCast(type, to: UnsafePointer<_Metadata>.self)) } + public var isEmpty: Bool { count == 0 } + public var indices: Range { 0 ..< count } + public var type: Any.Type { unsafeBitCast(rawValue, to: Any.Type.self) } - public var isEmpty: Bool { - count == 0 - } - - public var indices: Range { - 0 ..< count - } - public func type(at index: Int) -> Any.Type { elementType(at: index).type } @@ -47,3 +44,86 @@ extension TupleType { @_silgen_name("OGTupleWithBuffer") public func withUnsafeTuple(of type: TupleType, count: Int, _ body: (UnsafeMutableTuple) -> ()) + +// MARK: - UnsafeTuple + +extension UnsafeTuple { + public var count: Int { type.count } + public var isEmpty: Bool { type.isEmpty } + public var indices: Range { type.indices } + + public func address(as _: T.Type = T.self) -> UnsafePointer { + value.assumingMemoryBound(to: T.self) + } + + public func address(of index: Int, as _: T.Type = T.self) -> UnsafePointer { + value.advanced(by: type.elementOffset(at: index, type: Metadata(T.self))) + .assumingMemoryBound(to: T.self) + } + + public subscript() -> T { + unsafeAddress { address(as: T.self) } + } + + public subscript(_ index: Int) -> T { + unsafeAddress { address(of: index, as: T.self) } + } +} + +// MARK: - UnsafeMutableTuple + +@_silgen_name("swift_slowAlloc") +private func slowAlloc(_ size: Int, _ alignMask: Int) -> UnsafeMutableRawPointer + +@_silgen_name("swift_slowDealloc") +private func slowDealloc(_ ptr: UnsafeMutableRawPointer, _ size: Int, _ alignMask: Int) + +extension UnsafeMutableTuple { + public init(with tupleType: TupleType) { + self.init(type: tupleType, value: slowAlloc(tupleType.size, -1)) + } + + public func initialize(at index: Int, to element: T) { + withUnsafePointer(to: element) { elementPointer in + type.setElement(in: value, at: index, from: elementPointer, options: .initCopy) + } + } + + public func deinitialize() { + type.destory(value) + } + + public func deinitialize(at index: Int) { + type.destory(value, at: index) + } + + public func deallocate(initialized: Bool) { + if initialized { + deinitialize() + } + slowDealloc(value, -1, -1) + } + + public var count: Int { type.count } + public var isEmpty: Bool { type.isEmpty } + public var indices: Range { type.indices } + + public func address(as _: T.Type = T.self) -> UnsafeMutablePointer { + value.assumingMemoryBound(to: T.self) + } + + public func address(of index: Int, as _: T.Type = T.self) -> UnsafeMutablePointer { + value.advanced(by: type.elementOffset(at: index, type: Metadata(T.self))) + .assumingMemoryBound(to: T.self) + } + + public subscript() -> T { + unsafeAddress { UnsafePointer(address(as: T.self)) } + unsafeMutableAddress { address(as: T.self) } + } + + public subscript(_ index: Int) -> T { + unsafeAddress { UnsafePointer(address(of: index, as: T.self)) } + unsafeMutableAddress { address(of: index, as: T.self) } + } +} diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 0d1dc65b..9567db9f 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -22,19 +22,15 @@ typedef OG_CLOSED_ENUM(uint32_t, OGTupleCopyOptions) { OGTupleCopyOptionsInitTake = 3 } OG_SWIFT_NAME(TupleType.CopyOptions); -struct OGUnsafeTuple { +typedef struct OG_SWIFT_NAME(UnsafeTuple) OGUnsafeTuple { OGTupleType type; const void *value; -} OG_SWIFT_NAME(UnsafeTuple); +} OGUnsafeTuple; -typedef struct OGUnsafeTuple OGUnsafeTuple; - -struct OGUnsafeMutableTuple { +typedef struct OG_SWIFT_NAME(UnsafeMutableTuple) OGUnsafeMutableTuple { OGTupleType type; void *value; -} OG_SWIFT_NAME(UnsafeMutableTuple); - -typedef struct OGUnsafeMutableTuple OGUnsafeMutableTuple; +} OGUnsafeMutableTuple; OG_EXTERN_C_BEGIN diff --git a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h index 87ae1129..cd014285 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h @@ -13,8 +13,8 @@ OG_ASSUME_NONNULL_BEGIN -typedef struct OGSwiftMetadata { -} OGSwiftMetadata OG_SWIFT_NAME(_Metadata); +typedef struct OG_SWIFT_NAME(_Metadata) OGSwiftMetadata { +} OGSwiftMetadata ; typedef const OGSwiftMetadata *OGTypeID OG_SWIFT_STRUCT OG_SWIFT_NAME(Metadata); diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift index 67fb7002..c4327ea3 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift @@ -98,3 +98,46 @@ struct TupleTypeTests { } } } + +@Suite(.enabled(if: swiftToolchainSupported)) +struct UnsafeTupleTests { +} + +@Suite(.enabled(if: swiftToolchainSupported)) +struct UnsafeMutableTupleTests { + class T1 { + var a = 0 + var b: Double = 0 + } + + struct T2 { + var a: Int = 0 + var b: Double = 0 + } + + enum T3 { + case a, b + } + + @Test + func initialize() { + let mutableTuple = UnsafeMutableTuple(with: TupleType([T1.self, T2.self])) + + #expect(mutableTuple.count == 2) + #expect(mutableTuple.isEmpty == false) + + let t1 = T1() + t1.a = 1 + let t2 = T2(a: 2) + mutableTuple.initialize(at: 0, to: t1) + mutableTuple.initialize(at: 1, to: t2) + + let retrievedT1: T1 = mutableTuple[0] + let retrievedT2: T2 = mutableTuple[1] + + #expect(retrievedT1.a == 1) + #expect(retrievedT2.a == 2) + + mutableTuple.deinitialize() + } +} From 2e7ac933e3e82f35286eadf0a2973368ea103a3b Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 3 Jan 2025 03:08:04 +0800 Subject: [PATCH 6/8] add withUnsafeTuple implementation --- Sources/OpenGraph/Runtime/TupleType.swift | 14 +++++--- Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 24 ++++++++++++++ Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 2 +- Sources/OpenGraph_SPI/Runtime/OGTypeID.h | 2 +- .../Runtime/TupleTypeTests.swift | 33 +++++++++++-------- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/Sources/OpenGraph/Runtime/TupleType.swift b/Sources/OpenGraph/Runtime/TupleType.swift index 07f90b0d..c7bfdf53 100644 --- a/Sources/OpenGraph/Runtime/TupleType.swift +++ b/Sources/OpenGraph/Runtime/TupleType.swift @@ -53,7 +53,10 @@ extension UnsafeTuple { public var indices: Range { type.indices } public func address(as _: T.Type = T.self) -> UnsafePointer { - value.assumingMemoryBound(to: T.self) + guard type.type == T.self else { + preconditionFailure() + } + return value.assumingMemoryBound(to: T.self) } public func address(of index: Int, as _: T.Type = T.self) -> UnsafePointer { @@ -109,7 +112,10 @@ extension UnsafeMutableTuple { public var indices: Range { type.indices } public func address(as _: T.Type = T.self) -> UnsafeMutablePointer { - value.assumingMemoryBound(to: T.self) + guard type.type == T.self else { + preconditionFailure() + } + return value.assumingMemoryBound(to: T.self) } public func address(of index: Int, as _: T.Type = T.self) -> UnsafeMutablePointer { @@ -119,11 +125,11 @@ extension UnsafeMutableTuple { public subscript() -> T { unsafeAddress { UnsafePointer(address(as: T.self)) } - unsafeMutableAddress { address(as: T.self) } + nonmutating unsafeMutableAddress { address(as: T.self) } } public subscript(_ index: Int) -> T { unsafeAddress { UnsafePointer(address(of: index, as: T.self)) } - unsafeMutableAddress { address(of: index, as: T.self) } + nonmutating unsafeMutableAddress { address(of: index, as: T.self) } } } diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index d87aa437..754d8afc 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -231,3 +231,27 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) { element_type->vw_destroy(reinterpret_cast((intptr_t)value + index)); #endif } + +void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (* function)(const OGUnsafeMutableTuple mutableTuple, const void * context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void *context) { + #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED + auto metadata = reinterpret_cast(tuple_type); + auto buffer_size = metadata->vw_stride() * count; + OGUnsafeMutableTuple tuple; + tuple.type = tuple_type; + if (buffer_size <= 0x1000) { + char buffer[buffer_size]; + bzero(buffer, buffer_size); + // NOTE: If you use buffer out of the scope, the stack may be malformed. + // So we need to call function in this scope. + function(tuple, context); + } else { + void *buffer = malloc_type_malloc(buffer_size, 0x100004077774924); + if (buffer == nullptr) { + OG::precondition_failure("memory allocation failure"); + } + tuple.value = buffer; + function(tuple, context); + free(buffer); + } + #endif +} diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 9567db9f..74a1e757 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -80,7 +80,7 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *buffer, size_t index) O OG_EXPORT OG_REFINED_FOR_SWIFT -void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (*_Nullable function)(const void * _Nullable context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void * _Nullable context); +void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (* function)(const OGUnsafeMutableTuple mutableTuple, const void * context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void *context); OG_EXTERN_C_END diff --git a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h index cd014285..48301991 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTypeID.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTypeID.h @@ -14,7 +14,7 @@ OG_ASSUME_NONNULL_BEGIN typedef struct OG_SWIFT_NAME(_Metadata) OGSwiftMetadata { -} OGSwiftMetadata ; +} OGSwiftMetadata; typedef const OGSwiftMetadata *OGTypeID OG_SWIFT_STRUCT OG_SWIFT_NAME(Metadata); diff --git a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift index c4327ea3..1b15b4fe 100644 --- a/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift @@ -99,24 +99,32 @@ struct TupleTypeTests { } } -@Suite(.enabled(if: swiftToolchainSupported)) -struct UnsafeTupleTests { -} - @Suite(.enabled(if: swiftToolchainSupported)) struct UnsafeMutableTupleTests { class T1 { var a = 0 - var b: Double = 0 } struct T2 { - var a: Int = 0 - var b: Double = 0 + var a = 0 } - enum T3 { - case a, b + @Test + func buffer() { + withUnsafeTuple(of: TupleType([T1.self, T2.self]), count: 1) { mutableTuple in + let ref = T1() + ref.a = 1 + mutableTuple.initialize(at: 0, to: ref) + mutableTuple.initialize(at: 1, to: T2(a: 2)) + + let tuple = UnsafeTuple(type: mutableTuple.type, value: mutableTuple.value) + let t1 = tuple[0] as T1 + let t2 = tuple[1] as T2 + + #expect(t1 === ref) + #expect(t1.a == 1) + #expect(t2.a == 2) + } } @Test @@ -131,12 +139,9 @@ struct UnsafeMutableTupleTests { let t2 = T2(a: 2) mutableTuple.initialize(at: 0, to: t1) mutableTuple.initialize(at: 1, to: t2) - - let retrievedT1: T1 = mutableTuple[0] - let retrievedT2: T2 = mutableTuple[1] - #expect(retrievedT1.a == 1) - #expect(retrievedT2.a == 2) + #expect((mutableTuple[0] as T1).a == 1) + #expect((mutableTuple[1] as T2).a == 2) mutableTuple.deinitialize() } From b39f1bfedd2e282097d8d0cd78ddb482239ee666 Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 3 Jan 2025 03:10:41 +0800 Subject: [PATCH 7/8] Fix destroy typo and update dependency --- Package.resolved | 4 ++-- Sources/OpenGraph/Runtime/TupleType.swift | 4 ++-- Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 4 ++-- Sources/OpenGraph_SPI/Runtime/OGTupleType.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Package.resolved b/Package.resolved index cf245961..af8a94a9 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "541a191769e45d8d8acb1b48a687231b967da208924053878dcedf8652ae1c99", + "originHash" : "aa0fd2e35b551c5a0558c96a63275f3b05620dac86f000f4bc0c1db36eddbed0", "pins" : [ { "identity" : "darwinprivateframeworks", @@ -7,7 +7,7 @@ "location" : "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", "state" : { "branch" : "main", - "revision" : "97476edc16f5f635fa275150012bc2facc942794" + "revision" : "cab10e11f4ad918b3556b5ccaddd0aabb4cd8652" } }, { diff --git a/Sources/OpenGraph/Runtime/TupleType.swift b/Sources/OpenGraph/Runtime/TupleType.swift index c7bfdf53..e8f296ff 100644 --- a/Sources/OpenGraph/Runtime/TupleType.swift +++ b/Sources/OpenGraph/Runtime/TupleType.swift @@ -93,11 +93,11 @@ extension UnsafeMutableTuple { } public func deinitialize() { - type.destory(value) + type.destroy(value) } public func deinitialize(at index: Int) { - type.destory(value, at: index) + type.destroy(value, at: index) } public func deallocate(initialized: Bool) { diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index 754d8afc..7b174f2b 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -206,14 +206,14 @@ void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, #endif } -void OGTupleDestory(OGTupleType tuple_type, void *value) { +void OGTupleDestroy(OGTupleType tuple_type, void *value) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); metadata->vw_destroy(reinterpret_cast(value)); #endif } -void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) { +void OGTupleDestroyElement(OGTupleType tuple_type, void *value, size_t index) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED auto metadata = reinterpret_cast(tuple_type); if (metadata->getKind() != swift::MetadataKind::Tuple) { diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h index 74a1e757..3b7016eb 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.h +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.h @@ -72,11 +72,11 @@ void *OGTupleGetElement(OGTupleType tuple_type, void* tuple_value, size_t index, OG_EXPORT OG_REFINED_FOR_SWIFT -void OGTupleDestory(OGTupleType tuple_type, void *buffer) OG_SWIFT_NAME(TupleType.destory(self:_:)); +void OGTupleDestroy(OGTupleType tuple_type, void *buffer) OG_SWIFT_NAME(TupleType.destroy(self:_:)); OG_EXPORT OG_REFINED_FOR_SWIFT -void OGTupleDestoryElement(OGTupleType tuple_type, void *buffer, size_t index) OG_SWIFT_NAME(TupleType.destory(self:_:at:)); +void OGTupleDestroyElement(OGTupleType tuple_type, void *buffer, size_t index) OG_SWIFT_NAME(TupleType.destroy(self:_:at:)); OG_EXPORT OG_REFINED_FOR_SWIFT From fa3e87f8765be3328fa02a0b18c6f35f13d0aa0d Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 3 Jan 2025 03:15:10 +0800 Subject: [PATCH 8/8] Fix CI issue --- Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp index 7b174f2b..6cdecc8d 100644 --- a/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp +++ b/Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp @@ -87,7 +87,7 @@ size_t OGTupleElementSize(OGTupleType tuple_type, size_t index) { auto element = tuple_metadata->getElement(unsigned(index)); return element.Type->vw_size(); #else - return nullptr; + return 0; #endif } @@ -107,7 +107,7 @@ size_t OGTupleElementOffset(OGTupleType tuple_type, size_t index) { auto element = tuple_metadata->getElement(unsigned(index)); return element.Offset; #else - return nullptr; + return 0; #endif } @@ -133,10 +133,11 @@ size_t OGTupleElementOffsetChecked(OGTupleType tuple_type, size_t index, OGTypeI } return element.Offset; #else - return nullptr; + return 0; #endif } +#ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * metadata, OGTupleCopyOptions options) { auto dst = reinterpret_cast(dst_ptr); auto src = reinterpret_cast(const_cast(src_ptr)); @@ -153,6 +154,7 @@ void *update(void* dst_ptr, const void *src_ptr, const OG::swift::metadata * met OG::precondition_failure("unknown copy options: %d", options); } } +#endif void *OGTupleSetElement(OGTupleType tuple_type, void* tuple_value, size_t index, const void *element_value, OGTypeID check_type, OGTupleCopyOptions options) { #ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED